Skip to content

Instantly share code, notes, and snippets.

@IdrisCytron
Created September 8, 2020 05:02
Show Gist options
  • Save IdrisCytron/57ab93b84b7ed41c2f9f697258fa819f to your computer and use it in GitHub Desktop.
Save IdrisCytron/57ab93b84b7ed41c2f9f697258fa819f to your computer and use it in GitHub Desktop.
Monitor Temperature Humidity Through SMS Using M5Stack and SIM800L
/*
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