I've modified my sketch to make it less verbose and added GoForSmoke's routines.
Upon powering the device, the modem boots until it is able to receive commands, then receives commands to make it ready to handle text messages and notifies the user when it is ready. Light an LED by texting "ON" and vice-versa. Send "Temp" to receive the word "DHT11", which in the future will be the temperature and humidity values from a DHT11 module.
I will try to include a sleep mode, low battery alert and use a ultrasonic anemometer as sensor.
Your suggestions will be appreciated.
/*-----------------------------------------------------------------------------------------
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 word "DHT11"
-------------------------------------------------------------------------------------------
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
// hold what's available through the serial port
int ch = 0;
String val = "";
String phone = "+351xxxYYYzzz"; // replace with sender phone number
String text = "";
const unsigned long baudrate = 38400; // baudrate for both Hardware Serial and Software Serial
boolean triggerInitModem = false;
boolean triggerSMS = false;
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() {
if (mySerial.available()) // listen to the module
{
ReadChar(); // read and hold incoming data
if (val.indexOf("+PBREADY") > -1) // modem is ready to receive AT commands to enable handling text messages
{
triggerInitModem = true;
}
if (val.indexOf("+CMT") > -1) // an SMS has been received
{
if (val.indexOf(phone) > -1) // by a known phone number
{
handleSMS(); // do something according to text message content
}
}
val = ""; // clear what val was holding and let's listen for more
}
if (triggerInitModem == true) InitModem();
if (triggerSMS == true) SendSMS(text, phone);
}
void ReadChar() {
while (mySerial.available()) {
ch = mySerial.read();
val += char(ch);
delay(1);
Serial.println(val);
}
}
void handleSMS() {
if (val.indexOf("On") > -1)
{
digitalWrite(redLED, HIGH);
text = "redLED ON";
triggerSMS = true;
}
if (val.indexOf("Off") > -1)
{
digitalWrite(redLED, LOW);
text = "redLED OFF";
triggerSMS = true;
}
if (val.indexOf("Temp") > -1)
{
text = "DHT11";
triggerSMS = true;
}
}
void InitModem() {
static word startTimer, waitTimer; // waitTimer > 0 causes the timer to run, good up to 65 second intervals
static byte procState;
if ( waitTimer > 0 )
{
if ( word( millis() ) - startTimer < waitTimer ) return; // time is not up yet
else waitTimer = 0; // and on to the switch-case
}
switch ( procState )
{
case 0 :
mySerial.println("AT+CMGF=1"); // Set the module message mode, set either at 0 or 1 : 0 = PDU / 1 = Text mode.
procState = 1; // run case 2 next time
waitTimer = 2000;
startTimer = millis();
break;
case 1 :
mySerial.println("AT+CSCS=\"GSM\""); // Set the character sets : “GSM” = default alphabet (GSM03.38.6.2.1)
procState = 2; // run case 3 next time
waitTimer = 2000;
startTimer = millis();
break;
case 2 :
mySerial.println("AT+CMGD=1,4"); // Delete all messages so there are no conflicts with accidentally unread or stored SMS
procState = 3; // run case 1 next time
waitTimer = 2000;
startTimer = millis();
break;
case 3 :
mySerial.println("AT+CNMI=2,2,0,0,0"); // Set message indication Format, AT+CNMI=[<mode>[,<mt>[,<bm>[,<ds>[,<bfr>]]]]]
procState = 0; // run case 4 next time
waitTimer = 2000;
startTimer = millis();
digitalWrite(greenLED, HIGH); // signal InitModem finished, modem ready to receive commands
text = "Module Active";
triggerSMS = true;
triggerInitModem = false;
break;
}
}
void SendSMS(String text, String phone) {
static word startTimer, waitTimer; // waitTimer > 0 causes the timer to run, good up to 65 second intervals
static byte procState;
if ( waitTimer > 0 )
{
if ( word( millis() ) - startTimer < waitTimer ) return; // time is not up yet
else waitTimer = 0; // and on to the switch-case
}
switch ( procState )
{
case 0 :
mySerial.println("AT+CMGF=1"); // Set SMS Text Mode
procState = 1; // run case 1 next time
waitTimer = 2000;
startTimer = millis();
break;
case 1 :
mySerial.println("AT+CSCS=\"GSM\""); //
procState = 2; // run case 2 next time
waitTimer = 2000;
startTimer = millis();
break;
case 2 :
mySerial.println("AT+CMGS=\"" + phone + "\""); // send to desired phone
procState = 3; // run case 3 next time
waitTimer = 2000;
startTimer = millis();
break;
case 3 :
mySerial.print("\"" + text + "\""); // containing desired text
procState = 4; // run case 4 next time
waitTimer = 2000;
startTimer = millis();
break;
case 4 :
mySerial.print((char)26); // signals end of text message
procState = 0; // run case 0 next time
waitTimer = 2000;
startTimer = millis();
triggerSMS = false;
break;
}
}