Arduino Uno WeatherStation GSM Problem

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);
}

Welcome to the forum

It is unlikely that anyone will be able to provide help without seeing your sketch

Please post your full sketch, using code tags when you do

Posting your code using code tags prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination

In my experience the easiest way to tidy up the code and add the code tags is as follows

Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

Some things are not clean but unlikely to be your main problem:

Doing logical comparisons with floats can yield unexpected results because of their internal representation.

I suggest that you start by trying to create a minimal program just to read an incoming SMS message and print it to the serial console. Ideally the variable names and the comments would be in English.

I have only experimented with a GSM module once so far, but I definitely learned one thing: they really need a solid power supply. Otherwise, debugging the software is almost pointless because unstable supply voltage can cause all kinds of strange behavior.

Just a tip.

I have two separate lm2956 buck converters. One is making 7.5V for Arduino Uno and other one is making 5V (maybe 4.998V) for GSM module.

Do the 2 converters have common GND connections with one another ?

Yes

I have changed that and still no answer on STATUS command.

When I debug the code I get this in serial monitor:

Primljena poruka:
AT+CMGF=1
OK
AT+CMGL="ALL"
+CMGL: 1,"REC UNREAD","+3816977

Like it cant get whole number

As I already wrote, I only experimented with GSM modules once quite a while ago, so take this more as practical experience than as deep GSM expertise. But I remember three things quite clearly:

  1. Power supply really matters (we already discussed that).
  2. Some strange problems could be reproducibly eliminated simply by using a Mega instead of an Uno.
  3. HardwareSerial was much more reliable than SoftwareSerial.

The truncated SMS output you posted now actually reminds me a bit of the kind of strange behavior I saw back then with SoftwareSerial on an Uno.

Maybe worth trying before going deeper and deeper down the rabbit hole.