Arduino is not sending data to MQTT Server using SIM800C in Low power mode

Hello All,

I’m building a project where I want to send sensor data to MQTT server using SIM800C GSM module. I was able to send data to MQTT server using ElementzOnline library. Now, I want to send data periodically in low power mode. But, when I try with below code, I’m unable to publish data to MQTT server. As soon as TCP connection established, arduino is going to sleep mode. After woke up it is running the remaining portion of the code. Like this it is taking 3 to 4 iterations (sometimes even more) to publish the data to MQTT server.

Now, my question is why I’m unable to send the data to MQTT server in the first iteration itself.

Kindly help me to complete my project. Great thanks !!

#include "GSM_MQTT.h"
#include <SoftwareSerial.h>
#include <Wire.h> 
#include <DS3231.h> 
#include <LowPower.h>

String MQTT_HOST = "MQTT Host Name";
String MQTT_APN = "internet";
String MQTT_PORT = "MQTT Port Number";

DS3231 RTC;                     // create RTC object for DS3231
static DateTime interruptTime;  // next interrupt time  
 
char timestampChar[20];  // should handle yyyy/mm/dd hh:mm:ss and null terminator 

void GSM_MQTT::AutoConnect(void)
{
  connect("qwerty", 0, 0, "", "", 1, 0, 0, 0, "", "");  
}

void GSM_MQTT::OnConnect(void)
{
  publish(0, 0, 0, _generateMessageID(), "/topicName", "Hello");
}

GSM_MQTT MQTT(20);  // 20 is the keepalive duration in seconds

void setup()
{
  pinMode(13, OUTPUT);  // debug led 

  // rtc, irq 
  Wire.begin();
  RTC.begin();
  
  pinMode(2, INPUT_PULLUP);  // initialize INT0 (D2 on the most Arduino's) to accept external interrupts
  DateTime start = RTC.now(); 
  // add x seconds (interval time) to start time
  interruptTime = DateTime (start.get() + 180); 
}

void loop()
{
  // do other things here, e.g. reading sensors  

  MQTT.begin();
  delay(100);
  MQTT.processing();
  delay(100);
  MQTT.OnConnect();

  // blink LED to indicate sensor reading is done
  digitalWrite(13, HIGH);
  Serial.flush();  // flush serial before sleeping 
  LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF); // delay 60 ms 
  digitalWrite(13, LOW);
    
  // prepare next interrupt time
  RTC.clearINTStatus();  // this function call is a must to bring INT pin high after an interrupt
  RTC.enableInterrupts(interruptTime.hour(),interruptTime.minute(),interruptTime.second());  // set the interrupt (h,m,s)
  attachInterrupt(0, wakeUp, LOW);  // enable INT0, required to handle level triggered interrupts
  
  // debug
  Serial.print("\nSleeping ... ");
  Serial.flush();  // flush serial before sleeping 
  // power down with ADC and BOD disabled
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); 
  // waiting for the next interrupt 
  
  // wakeup
  detachInterrupt(0); 
  // calculate next interrupt time 
  interruptTime = DateTime(interruptTime.get() + 180);  
  
  delay(10); // this delay is required to allow CPU to stabilize
  Serial.println("Awake from sleep.\n");
}

// timestamp 
void getTimestamp() {   
  DateTime currentTime = RTC.now();  // get the current date-time   
  snprintf(timestampChar, sizeof(timestampChar), "%d/%02d/%02d %02d:%02d:%02d", currentTime.year(), currentTime.month(), currentTime.date(), currentTime.hour(), currentTime.minute(), currentTime.second());  // write to char array 
}


// interrupt service routine for external interrupt on INT0 triggered from RTC
// keep this as short as possible, possibly avoid using function calls
void wakeUp() {
   // handler for the pin interrupt
}

GSM_MQTT.cpp (24.2 KB)

GSM_MQTT.h (5.15 KB)