#include <Arduino.h>
#define RS_PIN PB11
#define EN_PIN PA12
#define D4_PIN PA7
#define D5_PIN PA4
#define D6_PIN PA5
#define D7_PIN PA6
enum Mode { IDLE_MODE, GSM_SIM, GPS_SIM, BLE_SIM };
Mode activeMode = IDLE_MODE;
uint32_t lastBlinkTime = 0;
uint32_t lastDataTime = 0;
const uint32_t DATA_UPDATE_MS = 2000;
char cmdBuffer[64];
void lcdWriteNibble(uint8_t nibble, uint8_t rsMode) {
digitalWrite(RS_PIN, rsMode);
digitalWrite(D4_PIN, (nibble >> 0) & 1);
digitalWrite(D5_PIN, (nibble >> 1) & 1);
digitalWrite(D6_PIN, (nibble >> 2) & 1);
digitalWrite(D7_PIN, (nibble >> 3) & 1);
digitalWrite(EN_PIN, 1);
delayMicroseconds(2);
digitalWrite(EN_PIN, 0);
delayMicroseconds(50);
}
void lcdSendByte(uint8_t byteVal, uint8_t rsMode) {
lcdWriteNibble(byteVal >> 4, rsMode);
lcdWriteNibble(byteVal & 0x0F, rsMode);
}
void lcdCmd(uint8_t command) {
lcdSendByte(command, 0);
}
void lcdData(uint8_t data) {
lcdSendByte(data, 1);
}
void lcdSetup() {
pinMode(RS_PIN, OUTPUT);
pinMode(EN_PIN, OUTPUT);
pinMode(D4_PIN, OUTPUT);
pinMode(D5_PIN, OUTPUT);
pinMode(D6_PIN, OUTPUT);
pinMode(D7_PIN, OUTPUT);
delay(45);
lcdCmd(0x33);
delay(6);
lcdCmd(0x32);
delayMicroseconds(160);
lcdCmd(0x28);
delayMicroseconds(160);
lcdCmd(0x0C);
delayMicroseconds(160);
lcdCmd(0x06);
delayMicroseconds(160);
lcdCmd(0x01);
delay(3);
}
void lcdReset() {
lcdCmd(0x01);
delay(3);
}
void lcdPosition(uint8_t x, uint8_t y) {
const uint8_t rowAddr[] = {0x00, 0x40, 0x14, 0x54};
if (y > 3) y = 3;
lcdCmd(0x80 | (x + rowAddr[y]));
}
void lcdOutput(const char* str) {
while (*str) lcdData(*str++);
}
void lcdDisplay(const char* line0, const char* line1 = NULL, const char* line2 = NULL, const char* line3 = NULL) {
lcdReset();
lcdPosition(0, 0);
lcdOutput(line0);
if (line1 && *line1) {
lcdPosition(0, 1);
lcdOutput(line1);
}
if (line2 && *line2) {
lcdPosition(0, 2);
lcdOutput(line2);
}
if (line3 && *line3) {
lcdPosition(0, 3);
lcdOutput(line3);
}
}
void simGSM() {
const char* smsMsg = "GSM::+79161234567::\"STM32 GSM Test\"";
Serial.println(smsMsg);
lcdDisplay("GSM SMS Received", "From: +79161234567", "Text: STM32 GSM", "Test Message");
}
void simGPS() {
const char* nmeaMsg = "GPS:$GPRMC,093000.00,A,5544.1234,N,03736.9876,E,18.5,290.3,150124,003.2,W*78";
Serial.println(nmeaMsg);
lcdDisplay("GPS Coordinates", "55.73539N 37.61646E", "Speed: 18.5 kn", "Status: Active");
}
void simBLE() {
uint8_t tempC = 22 + (millis() >> 10) % 8;
uint8_t humidity = 60 + (millis() >> 9) % 15;
uint16_t pressure = 1013 + (millis() >> 8) % 10;
char sensorData[60];
snprintf(sensorData, sizeof(sensorData),
"BLE::T:%dC::H:%d%%::P:%dhPa", tempC, humidity, pressure);
Serial.println(sensorData);
char line2[21], line3[21];
snprintf(line2, sizeof(line2), "T:%dC H:%d%%", tempC, humidity);
snprintf(line3, sizeof(line3), "Pressure: %d hPa", pressure);
lcdDisplay("BLE Sensor Data", line2, line3, "");
}
void setup() {
Serial.begin(115200);
lcdSetup();
lcdDisplay("Embedded Systems", "Lab Work #6", "GSM/GPS/BLE Sim", "By Student");
Serial.println("=== STM32 Wireless Sim ===");
Serial.println("Available commands:");
Serial.println(" GSM - SMS simulation");
Serial.println(" GPS - Navigation data");
Serial.println(" BLE - Sensor data");
Serial.println(" OFF - Stop simulation");
}
void loop() {
uint32_t currentTime = millis();
if (Serial.available()) {
uint8_t bytesRead = Serial.readBytesUntil('\n', cmdBuffer, sizeof(cmdBuffer) - 1);
cmdBuffer[bytesRead] = 0;
for (uint8_t i = 0; cmdBuffer[i]; i++) {
if (cmdBuffer[i] == '\r') cmdBuffer[i] = 0;
}
if (strcasecmp(cmdBuffer, "GSM") == 0) {
activeMode = GSM_SIM;
lcdDisplay("GSM Mode Active", "SMS Simulation", "UART: 9600 baud", "Ready...");
lastDataTime = currentTime;
Serial.println("[OK] GSM simulation started");
}
else if (strcasecmp(cmdBuffer, "GPS") == 0) {
activeMode = GPS_SIM;
lcdDisplay("GPS Mode Active", "NMEA Data Stream", "Format: GPRMC", "Satellites: 8");
lastDataTime = currentTime;
Serial.println("[OK] GPS simulation started");
}
else if (strcasecmp(cmdBuffer, "BLE") == 0) {
activeMode = BLE_SIM;
lcdDisplay("BLE Mode Active", "Sensor Monitoring", "Update: 2s", "Advertising...");
lastDataTime = currentTime;
Serial.println("[OK] BLE simulation started");
}
else if (strcasecmp(cmdBuffer, "OFF") == 0 || strcasecmp(cmdBuffer, "STOP") == 0) {
activeMode = IDLE_MODE;
lcdDisplay("System Idle", "Send command:", "GSM, GPS, BLE", "to start");
Serial.println("[OK] Simulation stopped");
}
}
if (activeMode != IDLE_MODE && currentTime - lastDataTime >= DATA_UPDATE_MS) {
lastDataTime = currentTime;
switch (activeMode) {
case GSM_SIM: simGSM(); break;
case GPS_SIM: simGPS(); break;
case BLE_SIM: simBLE(); break;
default: break;
}
}
delay(8);
}