SIM800 + Arduino Alarm System

Hi,

I am working on a project that involves, a Sim800C Module connected to an ATmega328(Same chip as Arduino UNO, Nano) using Hardware Serial. 3 Sensors which are a flame Sensor, Gas Sensor, and a Motion Sensor. As outputs, I have an Led and a buzzer. I fabricated a PCB online and soldered all the components.

When I uploaded the simple GSM example the SIM800 Module connects successfully and I am able to control an led on and off. I noticed that the led has a very small delay when pressing the button on the app and it lighting up. But that is to be expected since it is not a fast connection. When I upload a more complex code the buttons do not work most of the time and to turn the same led using the Button on the app I have to press the button repeatedly for it to turn on and off. It is acting like the ATmega328 is freezing. Blynk does not disconnect but no buttons work.

I also tried the same code (with esp8266 specific libraries) and it worked normally and instantly. After this I am 99% sure that this is because of the Chip but I just wanted to be sure before I scrap the GSM connection and opt for Wifi.

Sorry If I missed any info.

Regards,
Clayton

I have attached pictures of my Schematic, and both the Simple Code and the Alarm system Code


Schematic


Simple GSM Connection Code

// Select your modem:
#define TINY_GSM_MODEM_SIM800

#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>

// Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial

// Your GPRS credentials
// Leave empty, if missing user or pass
const char apn[]  = "RTGsurfing";
const char user[] = "";
const char pass[] = "";

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
const char auth[] = "VCalXXXXXXXXXXXXXXXXXIKwP";

TinyGsm modem(SerialAT);

void setup()
{
  pinMode(5, OUTPUT); //Testing Led
   digitalWrite( 5, 1);
   delay(500);
   digitalWrite(5, 0);
   delay(500);
   digitalWrite(5, 1);
   delay(500);
   digitalWrite(5, 0);
   
  // Set GSM module baud rate
  SerialAT.begin(115200);
  delay(3000);

  modem.restart();

  Blynk.begin(auth, modem, apn, user, pass);
}

BLYNK_WRITE(V20) // At global scope (not inside of the function)
{
  if ( param.asInt() == 1 )
  {
    digitalWrite(5, HIGH);

  }
  else
  {
    digitalWrite(5, LOW);
  }
}


void loop()
{
  Blynk.run();
}

Alarm System Code

#define TINY_GSM_MODEM_SIM800
#define BLYNK_HEARTBEAT 90
#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>

// Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial

int MAX_VALUE_GAS = 800; //0 - 1023
int MAX_VALUE_FLAME = 400; //0 - 255
const long TIMEOUT_DELAY = 10000;

const char apn[]  = "RTGsurfing";
const char user[] = "";
const char pass[] = "";

const char auth[] = "40xxxxxxxxxxxxxxxxxxxx2";

TinyGsm modem(SerialAT);


BlynkTimer timer;
//********************************************************
//Outputs
byte led_pin  = 13;
byte buzzer_pin = 12;
//Input Pins
byte gas_pin = 0;
byte flame_pin = 1;
byte motion_pin = 2;

bool flameBTN = 0;
bool motionBTN = 0;
bool gasBTN = 0;
bool test = 0;
bool armBTN = 0;

bool motionDetected = 0;
bool flameDetected = 0;
bool gasDetected = 0;

bool alert = 0;

byte message = 0;
byte lastMessage = 1;

bool ledState = LOW;

unsigned long previousMillis = 0;
unsigned long currentMillis  = 0;
const long interval = 1000;

WidgetLCD lcd(V6); //The LCD Widget on the device

void setup()
{
  pinMode(5, OUTPUT);
   digitalWrite(5, 1);
   delay(500);
   digitalWrite(5, 0);
   delay(500);
   digitalWrite(5, 1);
  pinMode(led_pin, OUTPUT);
  pinMode(buzzer_pin, OUTPUT);

  // Set GSM module baud rate
  SerialAT.begin(115200);
  delay(3000);

 modem.restart();
 Blynk.begin(auth, modem, apn, user, pass);
  Blynk.syncAll();
  lcd.clear();

  attachInterrupt(digitalPinToInterrupt(motion_pin), motionLoop, CHANGE);

  timer.setInterval(3000L, control);
}

BLYNK_WRITE(V20) // At global scope (not inside of the function)
{
  if ( param.asInt() == 1 )
  {
digitalWrite(5, HIGH);

  }
  else
  {
digitalWrite(5, LOW);
  }
}

BLYNK_WRITE(V0) // At global scope (not inside of the function)
{
  if ( param.asInt() == 1 )
  {
armBTN = true;
lcd.print(0, 0, "Armed   ");
  }
}

BLYNK_WRITE(V1) // At global scope (not inside of the function)
{
  if (param.asInt() == 1 )
  {
armBTN = false;
lcd.print(0, 0, "Disarmed");
  }
}

BLYNK_WRITE(V2) // At global scope (not inside of the function)
{
  if (param.asInt() == 1)
  {
motionBTN = true;
  }
  else
  {
motionBTN = false;
  }
}

BLYNK_WRITE(V3) //
{
  if (param.asInt() == 1)
  {
flameBTN = true;
  }
  else
  {
flameBTN = false;
  }
}

BLYNK_WRITE(V4) // At global scope (not inside of the function)
{
  if (param.asInt() == 1)
  {
gasBTN = true;
  }
  else
  {
gasBTN = false;
  }
}

BLYNK_WRITE(V5) // At global scope (not inside of the function)
{
  if (param.asInt() == 1)
  {
test = true;
  }
  else
  {
test = false;
  }
}

void motionLoop() { //runs everytime the Motion Sensor detects a change
  if (digitalRead(motion_pin) == false) { //when a motion is detected
motionDetected = true; //Sets the motionDetected varible true
  } else {
motionDetected = false; //Sets the motionDetected varible false
  }

}

void control() { //this loop runs every 100ms

  if (analogRead(gas_pin) > MAX_VALUE_GAS) { //When gas is detected set the variable
gasDetected = true; //to true
  } else if (analogRead(gas_pin) < MAX_VALUE_GAS) {
gasDetected = false; //to false
  }

  if (analogRead(flame_pin) > MAX_VALUE_FLAME) { //When a flame is detected set the variable
flameDetected = true;// to true
  } else if (analogRead(flame_pin) < MAX_VALUE_FLAME) {
flameDetected = false; //to flase
  }

  if (test == 1) { // when the test button is pressed the programm turns on the led and the buzzer until turned off
message = 4; //sets message variable to 4
  }
  else if (armBTN == 1) { //if the system is armed
if (motionBTN == 1 && motionDetected == 1) { //if motion button is turned on and motion was detected
  message = 1;//set the variable to 1
} else if (flameBTN == 1 && flameDetected == 1) { //if flame button is turned on and a flame was detected
  message = 2; //set the variable to 2
} else if (gasBTN == 1 && gasDetected == 1) { //if gas button is turned on and gas was detected
  message = 3; //set the variable to 3
}
  } else if (armBTN == 0) {
message = 0; //if the system is not active set the varibale to 0

  }

  if (message != lastMessage) {// used to make the message and the lcd update once
lcd.clear(); //clears the display
switch (message) {
  case 0: lcd.print(0, 0, "Disarmed");
    alert = 0; //turns on the buzzer and led
    break;
  case 1: lcd.print(0, 0, "Armed   ");//Updates the display
    lcd.print(0, 1, "Motion Detected"); //Motion Detected
    Blynk.notify("Motion Detected!"); //Sends the notification
    alert = 1; //turns on the buzzer and led
    break;
  case 2: lcd.print(0, 0, "Armed   "); //Updates the display
    lcd.print(0, 1, "Flame Detected"); //Flame Detected
    Blynk.notify("Flame Detected!"); //Sends the notification
    alert = 1; //turns on the buzzer and led
    break;
  case 3: lcd.print(0, 0, "Armed   ");//Updates the display
    lcd.print(0, 1, "Gas Detected"); //Gas Detected
    alert = 1; //turns on the buzzer and led
    Blynk.notify("Gas Detected!"); //Sends the notification
    break;
  case 4: lcd.print(0, 0, "Armed   "); //Updates the display
    lcd.print(0, 0, "Test"); //test
    alert = 1;//turns on the buzzer and led
    break;
  default: //Nothing matched
    break;
}
lastMessage = message;
  }
}


void loop()
{

  if (alert == 1) { //turns the buzer and led on and off every 1 second
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {

  previousMillis = currentMillis;
  if (ledState == LOW) {
    ledState = HIGH;
  } else {
    ledState = LOW;
  }
}
digitalWrite(led_pin, ledState); //turnm
digitalWrite(buzzer_pin, HIGH);
  } else {
previousMillis = currentMillis;
digitalWrite(led_pin, LOW);
digitalWrite(buzzer_pin, LOW);
  }
  timer.run();
  Blynk.run();
}

You’re doing far too much in your void loop. Read this:

Pete.

1 Like