I've interfaced a GSM module with an Arduino to communicate with my phone. At this point I can switch an LED by texting "On/Off" and receive a text with temperature/humidity values from a DHT11 sensor by texting "Temp" (the code below is a simplified testing version that only sends back a constant integer).
The code is working but I would like to ask for your suggestions to make it more robust and less verbose before I move forward. I would also like to get rid of delay() by using a function that reads the OK sent by the modem (after an AT command is successfully handled), before the next AT command is issued.
The following site lets readers edit the code:
Hastebin creates a duplicate after editing:
https://hastebin.com/axuxatosoh.cpp
Traditional pasting:
/*-----------------------------------------------------------------------------------------
Modified version of http://arduino.ru/forum/apparatnye-voprosy/datchiki-temperatury-ds18b20
*******************************************************************************************
Light LED with SMS "On" and vice-versa, "Temp" to receive SMS with the number of the sender
(TODO replace with variable holding sensor data)
-------------------------------------------------------------------------------------------
M590E GSM Module working voltage always above 3.5V and under 4.2V
Use 3.3V level-shifter for Tx/Rx when using 5V Arduino
Short Gnd and Boot pins to auto-boot on power ON
-----------------------------------------------------------------------------------------*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 4); // RX, TX
int greenLED = 7; // ON when startup procedure is over // modem is ready to handle text messages
int yellowLED = 8; // SMS triggered with "On" or "Off"
int redLED = 9; // extra LED for testing
boolean startup_sequence = true; // flag startup sequence must take place
// hold what's available through the serial port
int ch = 0;
String val = "";
String master = "+************"; //replace with sender phone number
const unsigned long baudrate = 38400; // baudrate for both Hardware Serial and Software Serial
//SMS sending function
void sms(String text, String phone) {
mySerial.print("AT+CMGD=1,4\n\r"); // Delete all messages so there are no conflicts with accidentally unread or stored SMS
delay(1000);
mySerial.println("AT+CMGS=\"" + phone + "\""); // send to desired phone
delay(1000);
mySerial.print("\"" + text + "\""); // containing desired text
delay(1000);
mySerial.print((char)26); // signals end of text message
delay(2000);
}
void setup()
{
mySerial.begin(baudrate); // Set the baudrate of the GSM/GPRS Module.
Serial.begin(baudrate); // Set the baudrate of the serial monitor, start serial port at 38400 bps
pinMode(greenLED, OUTPUT);
pinMode(yellowLED, OUTPUT);
pinMode(redLED, OUTPUT);
}
void loop()
{
// do nothing else until we receive +PBREADY from the modem, which signals it's ready to receive AT commands
while (startup_sequence == true)
{
if (mySerial.available()) // listen to the module
{
delay(200);
ReadChar(); // read and hold incoming data
if (val.indexOf("+PBREADY") > -1) // mode is ready receive AT commands to enable handling text messages
{
Serial.println(val); // for debugging
InitModem(); // contains flag indicating startup_sequence has taken place
} else {
Serial.println(val);
}
}
val = ""; // clear val and move on
}
// startup sequence has taken place, let's listen for SMS
if (mySerial.available())
{
delay(200);
ReadChar();
Serial.println(val);
if (val.indexOf("+CMT") > -1) // an SMS has been received
{
if (val.indexOf(master) > -1) // by a known phone number
{
handleSMS(); // do something according to text message content
}
}
else {
Serial.println(val); // not an SMS, print it to Serial Monitor
}
val = ""; // clear what val was holding and let's listen for more
}
}
void InitModem()
{
mySerial.print("AT+CMGD=1,4\n\r"); // Delete all messages so there are no conflicts with accidentally unread or stored SMS
delay(1000);
mySerial.print("AT+CMGF=1\n\r"); // Set the module message mode, set either at 0 or 1 : 0 = PDU / 1 = Text mode.
delay(1000);
mySerial.print("AT+CSCS=\"GSM\"\r"); // Set the character sets : “GSM” = default alphabet (GSM03.38.6.2.1)
delay(1000);
mySerial.print("AT+CNMI=2,2,0,0,0\n\r"); // Set message indication Format, AT+CNMI=[<mode>[,<mt>[,<bm>[,<ds>[,<bfr>]]]]]
// Where <mode> = 2: under On-line State, message indication code is cashed in module. When
// processing released, output indication code through serial port. Under its state,
// display indication code on terminal equipment directly.
// Where <mt> = 1: the message content is not displayed directly but storaged.
// Where <mt> = 2: the message content is displayed directly but not storaged.
delay(1000);
digitalWrite(greenLED, HIGH); // signal InitModem finished, modem ready to receive commands
sms(String("Module Active"), String(master));
delay(2000);
startup_sequence = false;
}
void ReadChar()
{
while (mySerial.available())
{
ch = mySerial.read();
val += char(ch);
delay(50);
}
}
void handleSMS()
{
if (val.indexOf("On") > -1)
{
digitalWrite(redLED, HIGH);
}
if (val.indexOf("Off") > -1)
{
digitalWrite(redLED, LOW);
}
if (val.indexOf("Temp") > -1)
{
sms(String("T1=" + String(master) + ", T2=" + String(master)), String(master));
}
}
/*-----------------------------------------------------------------------------------------
// ****************************************************************************************
// TODO replace delay() with function that waits for OK after an AT command has been issued
// before issuing the next one.
// http://arduino.ru/forum/apparatnye-voprosy/ne-rabotaet-neoway-m590?page=3#comment-183631
// ****************************************************************************************
String line; // это где-то глобально объяви
void GotLineFromNeoway(const String& line)
{
// Received a response line from Neoway. Any answers come in the form of
// either one or several lines, so that the unit we need
// operate - it is the string
// if(line == F("ERROR")) // error
// if(line == F("OK")) // all OK
// if(line.startsWith(F("+CMT"))) // SMS has arrived
}
char ch;
while(Serial.available())
{
ch = Serial.read();
if(ch == '\r') continue;
if(ch == '\n') { GotLineFromNeoway(line); line = ""; }
else
line += ch;
}
----------------------------------------------------------------------------------------*/
Thank you in advance,
Francisco

