Monitor Temperature Humidity via SMS Using M5Stack and SIM800L

Did you know that you can add on modules (stacking) to your M5Stack Core?

Introduction

Did you know that you can add on modules (stacking) to your M5Stack Core? For this tutorial, I will show you how to monitor temperature and humidity via SMS using M5Stack and SIM800L module. SIM800L is a cellular phone module (GSM/GPRS) and only compatible with 2G network. If you want to integrate a cellular module into your design with voice, text and SMS, you can consider this setup!

Video

This tutorial shows how to monitor temperature and humidity via SMS using M5Stack and SIM800L module.

Hardware Preparation

This is the list of items used in the video.

Sample Program

This is Arduino sample code to monitor temperature and humidity via SMS using M5Stack. Please install following library through Library Manager.

  • M5Stack V0.3.0
  • Adafruit FONA V1.3.8
  • ClosedCube SHT31D V1.5.1
/*
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);
}
}

Thank You

References:

Thanks for reading this tutorial. If you have any technical inquiries, please post at Cytron Technical Forum.

Please be reminded, this tutorial is prepared for you to try and learn.
You are encouraged to improve the code for better application.

Leave a Comment

Your email address will not be published.

Share this Tutorial

Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest
Share on facebook
Share on whatsapp
Share on email
Share on print
Share on twitter
Share on pinterest

Latest Tutorial

Send Data to Firebase Using Arduino Uno WiFi Rev2
Simple Alarm System Using Maker Nano
Program Cucumber ESP32-S2 Using CircuitPython
Face Recognition Using OpenCV on Raspberry Pi 400
Turned Your Tablet as a Display for the Raspberry Pi 400
Scroll to Top