Created
September 8, 2020 05:02
-
-
Save IdrisCytron/57ab93b84b7ed41c2f9f697258fa819f to your computer and use it in GitHub Desktop.
Monitor Temperature Humidity Through SMS Using M5Stack and SIM800L
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Project: Monitor Temperature Humidity Through SMS Using M5Stack and SIM800L | |
Board: M5Stack-Core-ESP32 | |
Connections: | |
ESP32 | SIM800L | |
IO17 - RX | |
IO16 - TX | |
IO5 - RST | |
External libraries: | |
- M5Stack V0.3.0 (Manager) | |
- Adafruit FONA V1.3.8 (Manager) | |
- ClosedCube SHT31D V1.5.1 (Manager) | |
*/ | |
#include <M5Stack.h> | |
#include <Wire.h> | |
#include "ClosedCube_SHT31D.h" | |
#include "Adafruit_FONA.h" | |
ClosedCube_SHT31D sht3xd; | |
#define SIM800L_RX 17 | |
#define SIM800L_TX 16 | |
#define SIM800L_RST 5 | |
char replybuffer[255]; | |
HardwareSerial *sim800lSerial = &Serial1; | |
Adafruit_FONA sim800l = Adafruit_FONA(SIM800L_RST); | |
uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0); | |
#define BUTTONA 39 | |
#define BUTTONB 38 | |
#define BUTTONC 37 | |
#define SPEAKER 25 | |
#define NOTE_C4 262 | |
#define NOTE_D4 294 | |
#define NOTE_G4 392 | |
#define NOTE_A4 440 | |
#define playReadyMelody() playTone(melody1, melody1Dur, 2) | |
#define playSMSReceived() playTone(melody2, melody2Dur, 1) | |
#define playButton2() playTone(melody3, melody3Dur, 1) | |
#define playBatteryWeak() playTone(melody4, melody1Dur, 2) | |
int melody1[] = {NOTE_C4, NOTE_G4}; | |
int melody1Dur[] = {12, 8}; | |
int melody2[] = {NOTE_A4}; | |
int melody2Dur[] = {8}; | |
int melody3[] = {NOTE_D4}; | |
int melody3Dur[] = {8}; | |
int melody4[] = {NOTE_G4, NOTE_C4}; | |
int melody4Dur[] = {12, 8}; | |
String smsString = ""; | |
void setup() | |
{ | |
pinMode(BUTTONA, INPUT_PULLUP); | |
pinMode(BUTTONB, INPUT_PULLUP); | |
pinMode(BUTTONC, INPUT_PULLUP); | |
pinMode(SPEAKER, OUTPUT); | |
M5.begin(); | |
M5.Power.begin(); | |
Serial.begin(115200); | |
Serial.println(F("ESP32 with GSM SIM800L")); | |
Serial.println(F("Initializing....(May take more than 10 seconds)")); | |
M5.Lcd.clear(BLACK); | |
M5.Lcd.setTextSize(2); | |
M5.Lcd.setTextColor(RED); | |
M5.Lcd.setCursor(0, 0); | |
M5.Lcd.print("** M5STACK SIM800L DEMO **"); | |
M5.Lcd.setTextColor(WHITE); | |
M5.Lcd.setCursor(0, 30); | |
M5.Lcd.print("Temperature (celsius):"); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 50); | |
M5.Lcd.print("---"); | |
M5.Lcd.setTextColor(WHITE); | |
M5.Lcd.setCursor(0, 80); | |
M5.Lcd.print("Humidity (%RH):"); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 100); | |
M5.Lcd.print("---"); | |
M5.Lcd.setTextColor(WHITE); | |
M5.Lcd.setCursor(0, 130); | |
M5.Lcd.print("Status:"); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 150); | |
M5.Lcd.print("Initialize GSM (10 sec)"); | |
M5.Lcd.setTextColor(WHITE); | |
M5.Lcd.setCursor(0, 180); | |
M5.Lcd.print("Message:"); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 200); | |
M5.Lcd.print("---"); | |
Wire.begin(); | |
sht3xd.begin(0x44); // I2C address: 0x44 or 0x45 | |
Serial.print("Serial #"); | |
Serial.println(sht3xd.readSerialNumber()); | |
delay(10000); | |
// Make it slow so its easy to read! | |
sim800lSerial->begin(115200, SERIAL_8N1, SIM800L_TX, SIM800L_RX); | |
if (!sim800l.begin(*sim800lSerial)) { | |
Serial.println(F("Couldn't find GSM SIM800L")); | |
while (1); | |
} | |
Serial.println(F("GSM SIM800L is OK")); | |
char imei[16] = {0}; // MUST use a 16 character buffer for IMEI! | |
uint8_t imeiLen = sim800l.getIMEI(imei); | |
if (imeiLen > 0) { | |
Serial.print("SIM card IMEI: "); Serial.println(imei); | |
} | |
// Set up the FONA to send a +CMTI notification | |
// when an SMS is received | |
sim800lSerial->print("AT+CNMI=2,1\r\n"); | |
Serial.println("GSM SIM800L Ready!"); | |
M5.Lcd.fillRect(0, 150, 320, 20, BLACK); | |
M5.Lcd.setTextColor(GREEN); | |
M5.Lcd.setCursor(0, 150); | |
M5.Lcd.print("GSM SIM800L Ready!"); | |
if (sht3xd.periodicStart(SHT3XD_REPEATABILITY_HIGH, SHT3XD_FREQUENCY_10HZ) != SHT3XD_NO_ERROR) { | |
Serial.println("[ERROR] Cannot start periodic mode"); | |
} | |
playReadyMelody(); | |
} | |
long prevMillis = 0; | |
int interval = 1000; | |
char sim800lNotificationBuffer[64]; //for notifications from the FONA | |
char smsBuffer[250]; | |
boolean clearStatus = false; | |
int count = 0; | |
String dataText = ""; | |
void loop() | |
{ | |
if (millis() - prevMillis > interval) { | |
prevMillis = millis(); | |
printResult("Periodic Mode", sht3xd.periodicFetchData()); | |
if (clearStatus) { | |
count++; | |
if (count == 5) { | |
count = 0; | |
clearStatus = false; | |
M5.Lcd.fillRect(0, 150, 320, 20, BLACK); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 150); | |
M5.Lcd.print("---"); | |
M5.Lcd.fillRect(0, 200, 320, 40, BLACK); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 200); | |
M5.Lcd.print("---"); | |
} | |
} | |
} | |
if (digitalRead(BUTTONA) == LOW) { | |
} | |
if (digitalRead(BUTTONB) == LOW) { | |
} | |
if (digitalRead(BUTTONC) == LOW) { | |
} | |
char* bufPtr = sim800lNotificationBuffer; //handy buffer pointer | |
if (sim800l.available()) { | |
int slot = 0; // this will be the slot number of the SMS | |
int charCount = 0; | |
// Read the notification into fonaInBuffer | |
do { | |
*bufPtr = sim800l.read(); | |
Serial.write(*bufPtr); | |
delay(1); | |
} while ((*bufPtr++ != '\n') && (sim800l.available()) && (++charCount < (sizeof(sim800lNotificationBuffer)-1))); | |
//Add a terminal NULL to the notification string | |
*bufPtr = 0; | |
//Scan the notification string for an SMS received notification. | |
// If it's an SMS message, we'll get the slot number in 'slot' | |
if (1 == sscanf(sim800lNotificationBuffer, "+CMTI: \"SM\",%d", &slot)) { | |
Serial.print("slot: "); Serial.println(slot); | |
char callerIDbuffer[32]; //we'll store the SMS sender number in here | |
// Retrieve SMS sender address/phone number. | |
if (!sim800l.getSMSSender(slot, callerIDbuffer, 31)) { | |
Serial.println("Didn't find SMS message in slot!"); | |
} | |
Serial.print(F("FROM: ")); Serial.println(callerIDbuffer); | |
M5.Lcd.fillRect(0, 150, 320, 20, BLACK); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 150); | |
M5.Lcd.print("Receive SMS..."); | |
// Retrieve SMS value. | |
uint16_t smslen; | |
// Pass in buffer and max len! | |
if (sim800l.readSMS(slot, smsBuffer, 250, &smslen)) { | |
smsString = String(smsBuffer); | |
Serial.println(smsString); | |
M5.Lcd.fillRect(0, 200, 320, 20, BLACK); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 200); | |
M5.Lcd.print(smsString); | |
playSMSReceived(); | |
} | |
if (smsString == "DATA") { | |
Serial.println("Sending data..."); | |
delay(100); | |
char dataTextArray[dataText.length()+1]; | |
dataText.toCharArray(dataTextArray, dataText.length()+1); | |
// Send SMS for status | |
if (!sim800l.sendSMS(callerIDbuffer, dataTextArray)) { | |
Serial.println(F("Failed")); | |
} else { | |
Serial.println(F("Sent!")); | |
} | |
} | |
else { | |
Serial.println("Invalid command!"); | |
delay(100); | |
// Send SMS for status | |
if (!sim800l.sendSMS(callerIDbuffer, "Invalid command!")) { | |
Serial.println(F("Failed")); | |
} else { | |
Serial.println(F("Sent!")); | |
} | |
} | |
while (1) { | |
if (sim800l.deleteSMS(slot)) { | |
Serial.println(F("OK!")); | |
break; | |
} | |
else { | |
Serial.print(F("Couldn't delete SMS in slot ")); Serial.println(slot); | |
sim800l.print(F("AT+CMGD=?\r\n")); | |
} | |
} | |
clearStatus = true; | |
} | |
} | |
} | |
const int FREQUENCY = 2000; | |
const int CHANNEL = 0; | |
const int RESOLUTION = 8; | |
void playTone(int *melody, int *melodyDur, int notesLength) | |
{ | |
for (int i = 0; i < notesLength; i++) { | |
ledcAttachPin(SPEAKER, CHANNEL); | |
int noteDuration = 1000 / melodyDur[i]; | |
ledcWriteTone(CHANNEL, melody[i]); | |
int pauseBetweenNotes = noteDuration * 1.30; | |
delay(pauseBetweenNotes); | |
ledcDetachPin(SPEAKER); | |
ledcWrite(CHANNEL, 0); | |
} | |
} | |
void printResult(String text, SHT31D result) | |
{ | |
if (result.error == SHT3XD_NO_ERROR) { | |
Serial.println(text); | |
dataText = ""; | |
dataText = "Temperature = "; | |
dataText += result.t; | |
dataText += "C\n"; | |
dataText += "Humidity = "; | |
dataText += result.rh; | |
dataText += "%"; | |
Serial.println(dataText); | |
M5.Lcd.fillRect(0, 50, 320, 20, BLACK); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 50); | |
M5.Lcd.print(result.t); | |
M5.Lcd.fillRect(0, 100, 320, 20, BLACK); | |
M5.Lcd.setTextColor(YELLOW); | |
M5.Lcd.setCursor(0, 100); | |
M5.Lcd.print(result.rh); | |
} | |
else { | |
Serial.print(text); | |
Serial.print(": [ERROR] Code #"); | |
Serial.println(result.error); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment