Hello everyone Recently started a project with SIM800L. The logic is that:
When the MQ2 sensor is triggered, Sim800l calls the first specified number, if he did not pick up the phone, then calls the first number again. If you haven't picked up the phone yet, then call the second number.
If you reject the call on the first call, the Sim800l must repeat the call.
But there is one problem.
After receiving a response from Sim800l, the code does not respond to this.
That is, if sim800h sends a response "NO CARRIER", the code does nothing. If you manually write "NO CARRIER" in Serial, the code will work. Please tell me what this is related to)
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
constexpr byte mq2Pin {A0}; // GPIO for MQ2 Sensor
enum class State {CHECK, CALLED1, CALLED2, CALLED3, CALLED4} state; // states for the finite state machine
enum Response {SUCCESS, UNKNOWN, NOTHING}; // Response codes from the serial parser
#include <SoftwareSerial.h>
SoftwareSerial SIM800(0, 2);
const char contact[][12]
{
"77754255040",
"77476138950"
};
void callNumber(byte index)
{
Serial.print(F("call ")); Serial.println(contact[index]);
SIM800.print("ATD+");
SIM800.print(contact[index]);
SIM800.println(";");
}
void setup() {
Serial.begin(9600);
SIM800.begin(9600);
Serial.println(F("\n<Arduino is ready>"));
pinMode(mq2Pin, INPUT);
}
void loop() {
recvWithEndMarker();
int result = -1;
int sensorValue = 0;
switch (state)
{
case State::CHECK :
result = showNewData(); // this will show and delete incoming characters
sensorValue = analogRead(mq2Pin);
if (sensorValue > 400)
{
Serial.println(F("Sensor fired"));
callNumber(0);
state = State::CALLED1;
Serial.println(F("jump to CALLED1"));
}
break;
case State::CALLED1 :
result = showNewData();
if (result == Response::SUCCESS)
{
Serial.println(F("call was SUCCESS"));
state = State::CHECK;
Serial.println(F("jump to CHECK"));
}
else if (result == Response::UNKNOWN)
{
callNumber(0);
state = State::CALLED2;
Serial.println(F("jump to CALLED2"));
}
break;
case State::CALLED2 :
result = showNewData();
if (result == Response::SUCCESS)
{
Serial.println(F("call was SUCCESS"));
state = State::CHECK;
Serial.println(F("jump to CHECK"));
}
else if (result == Response::UNKNOWN)
{
callNumber(0);
state = State::CALLED3;
Serial.println(F("jump to CALLED3"));
}
break;
case State::CALLED3 :
result = showNewData();
if (result == Response::SUCCESS)
{
Serial.println(F("call was SUCCESS"));
state = State::CHECK;
Serial.println(F("jump to CHECK"));
}
else if (result == Response::UNKNOWN)
{
callNumber(1);
state = State::CALLED4;
Serial.println(F("jump to CALLED4"));
}
break;
case State::CALLED4 :
result = showNewData();
if (result == Response::SUCCESS)
{
Serial.println(F("call was SUCCESS"));
state = State::CHECK;
Serial.println(F("jump to CHECK"));
}
else if (result == Response::UNKNOWN)
{
callNumber(1);
state = State::CHECK; // tried all contacts two times, back to check the sensor
Serial.println(F("jump back to CHECK"));
}
break;
}
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема...
Serial.write(SIM800.read()); // ...и выводим их в Serial
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
}
int showNewData() {
if (newData == true) {
Serial.print(F("<in>"));
Serial.println(receivedChars);
newData = false;
if (!strcmp(receivedChars, "BUSY"))
{
return Response::SUCCESS; // sucessful
}
if (!strcmp(receivedChars, "NO CARRIER"))
{
return Response::UNKNOWN; // sucessful
}
if (!strcmp(receivedChars, "ERROR"))
{
return Response::SUCCESS; // sucessful
}
if (!strcmp(receivedChars, "OK"))
{
return Response::NOTHING; // sucessful
}
return Response::NOTHING;
}
return Response::NOTHING;
}

Logic Diagram. Please help me solve this. Thanks!