Hi everyone,
I'm building a simple monitoring system using Arduino Uno, DS18B20 temperature sensor, DHT11 humidity sensor, and a SIM800L GSM module. The system works great for sending automatic alarm SMS when temperature drops below a threshold but I can't get it to respond to an incoming STATUS request.
What works:
-
SIM800L initializes fine (AT → OK)
-
Automatic alarm SMS sends successfully when temperature threshold is triggered
-
Arduino sleeps between cycles using watchdog timer
What doesn't work:
-
When I send an SMS with the text "STATUS" to the SIM card number, the Arduino never replies
-
No response at all, even after waiting several minutes
Setup:
-
Arduino Uno
-
SIM800L EVB (no RI pin available on this board)
-
DS18B20 on D2, DHT11 on D3
-
SIM800L TX → D10, SIM800L RX → D11
-
Powered from 12V battery through LM2596 buck converter stepped down to 5.0V for SIM800L
-
Yettel prepaid SIM (2G network confirmed available)
How it's supposed to work:
-
Arduino wakes up every minute via watchdog timer
-
Checks inbox using AT+CMGL=4
-
If "STATUS" is found in any message, replies with current temperature and humidity
-
Deletes all messages after reading (AT+CMGD=1,4)
What I've tried:
-
AT+CMGL=4 instead of AT+CMGL="ALL" (Also tried REC UNREAD)
-
Flushing the serial buffer before reading inbox
-
Increasing delays after AT+CMGL to 3000ms
-
Sending STATUS without quotes, all caps
I'm attaching the full code below. The alarm SMS part works so I know the SIM800L is registered on the network and can send messages. The issue seems to be specifically with reading incoming messages.
Any ideas what could be wrong? Is there something with how SIM800L handles incoming SMS storage that I might be missing?
Thanks!
//#include <Wire.h>
// ============================================================
// VOCNJAK MONITORING SISTEM
// Arduino Uno + DS18B20 + DHT11 + SIM800L
// ============================================================
// Biblioteke potrebne (instaliraj u Arduino IDE):
// - OneWire (by Paul Stoffregen)
// - DallasTemperature (by Miles Burton)
// - DHT sensor library (by Adafruit)
// SoftwareSerial je ugradjena, ne treba instalacija.
// ============================================================
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>
#include <SoftwareSerial.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
// ---- PINOVI ------------------------------------------------
#define DS18B20_PIN 2 // DS18B20 DATA zuta zica -> D2
#define DHT_PIN 3 // DHT11 DATA pin -> D3
#define SIM_RX_PIN 10 // SIM800L TX -> Arduino D10
#define SIM_TX_PIN 11 // SIM800L RX -> Arduino D11 (preko delitelja!)
// ---- PODESAVANJA -------------------------------------------
#define DHT_TYPE DHT11
#define TEMP_ALARM 5 // Alarm ispod ove temperature (stepeni C)
#define BROJ_TELEFONA "Xxxxxxxx" // <-- UNESI SVOJ BROJ OVDE!
#define INTERVAL_MIN 1 // Merenje svakih N minuta
#define INTERVAL_SMS 1 // Provera inboxa svakih N minuta
// ---- OBJEKTI -----------------------------------------------
OneWire oneWire(DS18B20_PIN);
DallasTemperature tempSenzor(&oneWire);
DHT dht(DHT_PIN, DHT_TYPE);
SoftwareSerial sim(SIM_RX_PIN, SIM_TX_PIN);
// ---- GLOBALNE VARIJABLE ------------------------------------
volatile int wdtBrojac = 0;
bool alarmPoslan = false;
float poslednjaVlaznost = 0;
float poslednjaTemp = 0;
int smsBrojac = 0; // Broji minute od poslednje SMS provere
// ============================================================
// WATCHDOG INTERRUPT (budi se svakih 8 sekundi)
// ============================================================
ISR(WDT_vect) {
wdtBrojac++;
}
// ============================================================
// DEEP SLEEP FUNKCIJA
// ============================================================
void deepSleep(int minuta) {
int ciklusi = (minuta * 60) / 8;
wdtBrojac = 0;
MCUSR &= ~(1 << WDRF);
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = (1 << WDIE) | (1 << WDP3) | (1 << WDP0);
while (wdtBrojac < ciklusi) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
sleep_disable();
}
WDTCSR |= (1 << WDCE) | (1 << WDE);
WDTCSR = 0x00;
}
// ============================================================
// SIM800L HELPER FUNKCIJE
// ============================================================
// Ispraznimo serijski bafer (bacimo sve sto ceka)
void isprazniBuffer() {
while (sim.available()) sim.read();
}
// Cekaj odgovor i sacuvaj ga u string (umesto da samo ispisujemo i bacimo)
String cekajOdgovorStr(int ms) {
String odgovor = "";
long kraj = millis() + ms;
while (millis() < kraj) {
while (sim.available()) {
char c = sim.read();
odgovor += c;
}
}
if (odgovor.length() > 0) {
Serial.print(odgovor);
}
return odgovor;
}
bool inicijalizujSIM() {
Serial.println(F(">> Inicijalizujem SIM800L..."));
for (int i = 0; i < 5; i++) {
isprazniBuffer();
sim.println(F("AT"));
delay(500);
String odg = cekajOdgovorStr(500);
if (odg.indexOf("OK") >= 0) {
Serial.println(F(">> SIM800L: OK"));
break;
}
if (i == 4) {
Serial.println(F(">> SIM800L: GRESKA - ne reaguje!"));
return false;
}
}
sim.println(F("AT+CMGF=1"));
cekajOdgovorStr(500);
sim.println(F("AT+CSCS=\"GSM\""));
cekajOdgovorStr(500);
sim.println(F("AT+CSQ"));
cekajOdgovorStr(500);
return true;
}
bool posaljiSMS(String poruka) {
Serial.println(F(">> Saljem SMS..."));
Serial.println(poruka);
sim.println(F("AT+CMGF=1"));
delay(300);
sim.print(F("AT+CMGS=\""));
sim.print(BROJ_TELEFONA);
sim.println(F("\""));
delay(300);
sim.print(poruka);
delay(100);
sim.write(26);
// Sacekaj odgovor i proveri uspeh
String odg = cekajOdgovorStr(5000);
if (odg.indexOf("OK") >= 0 || odg.indexOf("+CMGS") >= 0) {
Serial.println(F(">> SMS poslan uspesno!"));
return true;
} else {
Serial.println(F(">> SMS GRESKA!"));
return false;
}
}
// ============================================================
// NOVA FUNKCIJA — provera inboxa za STATUS upit
// ============================================================
String proveriSMS() {
isprazniBuffer();
Serial.println(F(">> Proveravam inbox..."));
sim.println(F("AT+CMGF=1"));
delay(300);
// *** FIX: U tekstualnom rezimu koristi "ALL" umesto broja 4 ***
sim.println(F("AT+CMGL=\"ALL\""));
delay(3000);
String odgovor = "";
long kraj = millis() + 4000;
while (millis() < kraj) {
while (sim.available()) {
char c = sim.read();
odgovor += c;
}
}
// Nema poruka
if (odgovor.indexOf("+CMGL") < 0) {
Serial.println(F(">> Inbox prazan."));
return "";
}
Serial.println(F(">> Primljena poruka:"));
Serial.println(odgovor);
// Obrisi sve poruke da ne pune memoriju SIM kartice
sim.println(F("AT+CMGD=1,4"));
delay(500);
// Prepoznaj STATUS komandu (case-insensitive)
String upper = odgovor;
upper.toUpperCase();
if (upper.indexOf("STATUS") >= 0) {
return "STATUS";
}
return "";
}
// ============================================================
// CITANJE SENZORA
// ============================================================
float ocitajTemperaturu() {
tempSenzor.requestTemperatures();
float t = tempSenzor.getTempCByIndex(0);
if (t == DEVICE_DISCONNECTED_C || t == -127.0) {
Serial.println(F(">> DS18B20 GRESKA - proveri konekciju!"));
return -99.0;
}
return t;
}
float ocitajVlaznost() {
float v = dht.readHumidity();
if (isnan(v)) {
Serial.println(F(">> DHT11 GRESKA - proveri konekciju!"));
return -1.0;
}
return v;
}
// ============================================================
// SETUP
// ============================================================
void setup() {
Serial.begin(9600);
sim.begin(9600);
Serial.println(F("===================================="));
Serial.println(F(" VOCNJAK MONITORING - START"));
Serial.println(F("===================================="));
tempSenzor.begin();
dht.begin();
delay(2000);
// Prvo merenje odmah po startu
Serial.println(F(">> Prvo merenje..."));
poslednjaTemp = ocitajTemperaturu();
poslednjaVlaznost = ocitajVlaznost();
Serial.print(F(">> Temperatura: "));
Serial.print(poslednjaTemp);
Serial.println(F(" C"));
Serial.print(F(">> Vlaznost: "));
Serial.print(poslednjaVlaznost);
Serial.println(F(" %"));
// Obrisi stare poruke iz inboxa pri startu
if (inicijalizujSIM()) {
sim.println(F("AT+CMGD=1,4"));
cekajOdgovorStr(500);
}
}
// ============================================================
// GLAVNI LOOP
// ============================================================
void loop() {
// 1. UZMI MERENJA
float temperatura = ocitajTemperaturu();
float vlaznost = ocitajVlaznost();
if (temperatura != -99.0) poslednjaTemp = temperatura;
if (vlaznost != -1.0) poslednjaVlaznost = vlaznost;
Serial.println(F("------------------------------------"));
Serial.print(F("Temp: "));
Serial.print(poslednjaTemp, 1);
Serial.println(F(" C"));
Serial.print(F("Vlaznost: "));
Serial.print(poslednjaVlaznost, 1);
Serial.println(F(" %"));
Serial.print(F("Alarm: "));
Serial.println(alarmPoslan ? F("DA (cekam oporavak)") : F("NE"));
// 2. PROVERI ALARM
if (poslednjaTemp != -99.0) {
if (poslednjaTemp < TEMP_ALARM && !alarmPoslan) {
Serial.println(F(">> ALARM! Temperatura iznad granice!"));
if (inicijalizujSIM()) {
String poruka = "UPOZORENJE VOCNJAK!\n";
poruka += "Temperatura: ";
poruka += String(poslednjaTemp, 1);
poruka += " C\n";
poruka += "Vlaznost: ";
poruka += String(poslednjaVlaznost, 1);
poruka += " %\n";
poruka += "Opasnost od mraza!";
if (posaljiSMS(poruka)) alarmPoslan = true;
}
}
if (poslednjaTemp >= (TEMP_ALARM + 2.0) && alarmPoslan) {
alarmPoslan = false;
Serial.println(F(">> Temperatura normalna, alarm resetovan."));
if (inicijalizujSIM()) {
String poruka = "Vocnjak OK\n";
poruka += "Temperatura: ";
poruka += String(poslednjaTemp, 1);
poruka += " C\n";
poruka += "Opasnost od mraza prosla.";
posaljiSMS(poruka);
}
}
}
// 3. PROVERI INBOX za STATUS upit (svakih INTERVAL_SMS minuta)
smsBrojac++;
Serial.print(F(">> SMS provera za: "));
Serial.print(smsBrojac);
Serial.print(F("/"));
Serial.println(INTERVAL_SMS);
if (smsBrojac >= INTERVAL_SMS) {
smsBrojac = 0;
if (inicijalizujSIM()) {
String komanda = proveriSMS();
if (komanda == "STATUS") {
Serial.println(F(">> STATUS upit primljen!"));
String odgovor = "VOCNJAK STATUS\n";
odgovor += "Temperatura: ";
odgovor += String(poslednjaTemp, 1);
odgovor += " C\n";
odgovor += "Vlaznost: ";
odgovor += String(poslednjaVlaznost, 1);
odgovor += " %\n";
if (poslednjaTemp > TEMP_ALARM) {
odgovor += "UPOZORENJE: Opasnost od mraza!";
} else {
odgovor += "Stanje: Normalno";
}
posaljiSMS(odgovor);
}
}
}
// 4. SPAVAJ do sledeceg merenja
Serial.print(F(">> Spavam "));
Serial.print(INTERVAL_MIN);
Serial.println(F(" minuta..."));
Serial.flush();
deepSleep(INTERVAL_MIN);
}