Blinking Led Using Timer Freezes During Communication with GSM Modem

I have tried searching for a solution to this, but I cant seem to find any similar threads!

I am currently (successfully) blinking an LED using the timer technique as described in the Blink Without Delay example (https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay)

The problem is that in my main loop, I am also calling a function which uploads some data to my webserver using the SIM800 GSM module. The communication to this module happens by sending it AT commands over the UART. Since there are a series of commands that have to be sent in sequence, this essentially becomes a blocking function. It takes about 10 seconds to complete this task.

The problem is that while this is happening, my LED (obviously) stops blinking. It gets stuck in either a HIGH or LOW state, and stays like that until the function communicating with the SIM800 is completed.

I cant seem to think of any way round this. I would like to have my LED blink even while the communication with the SIM800 is happening.

Is there any solution?

Thanks!

Put your led blinking code (the code lines that check millis() and switch the led on/off) into a new function. Call this function after each individual piece of data is sent to the GSM modem, as well as somewhere at the top or bottom of loop().

Got it. Thanks!

It’s a bit clumsy but kind of works. Since some of the modem commands take about 2 seconds to respond, the led blink rate changes at these points (should be 2 Hz) but it is better then the current situation.

I was wondering if there was some way to use an interrupt to run this led blinking function at regular intervals?

Thanks.

Perhaps, but if any of the modern commands are time-critical, interrupts are probably disabled.

If you post your code, it would certainly help us to help you. Read the forum sticky post to find out how.

Hi PaulRB. Apologies for the delay. I was stuck with my regular job and did not have time to play with my Arduino.

I am posting the simplified (relevant) code below. When the uploadGprs() function is not running, my led blinks perfectly. As soon as this function starts, the led blinking stops, because the arduino is busy running the uploadGprs code, and does not get a chance to update the LED.

The uploadGprs uses the ArduinoSIM800L library to communicate with the GPRS model via the UART using simple AT commands. However, it does wait for about 2 seconds between commands giving the modem time to respond. The entire function takes about 15 seconds to complete, during which time the LED does not blink.

I will appreciate any suggestions to get round this. Thanks!

#include <Http.h> // ArduinoSIM800L library

// typedef for tast scheduling
struct t  {
    unsigned long tStart;
    unsigned long tTimeout;
};

// define pins
int pinLedGprs = 5;
int pinGprsRx = 16;
int pinGprsTx = 17;
int pinGprsRst = 23;

// define led states
int stateLedGprs = LOW;

// led blink rates
unsigned long blinkFast = 100;
unsigned long blinkSlow = 500;
unsigned long blinkOff = 0;

// task timers
t t_blinkLedGprs = {0, blinkFast};
t t_gprsUpload = {0, 60000}; // run every 60 seconds

// sim800
HTTP* sim800;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(pinLedGprs, OUTPUT);
  sim800 = new HTTP(9600, pinGprsRx, pinGprsTx, pinGprsRst);
  Serial.println("=== STARTING APPLICATION ===");
}

void loop() {

  // task to upload the gprs data
  if (tCheck(&t_gprsUpload)) {
    Serial.println("*** Starting GPRS UPLOAD function ***");
    gprsUpload();
    tRun(&t_gprsUpload);
  }
  
  
  // task. set led state
  if ( t_blinkLedGprs.tTimeout > 0) {
    if (tCheck(&t_blinkLedGprs)) {
      stateLedGprs = !stateLedGprs;
      tRun(&t_blinkLedGprs);
    } 
  } else {
    stateLedGprs = HIGH;
  }

  // update the led state
  digitalWrite(pinLedGprs, stateLedGprs);
}

void gprsUpload(void) {

  const char* jsonData = "{\"test\"}"; 
  
  char response[2048];
  Result result;

  sim800->configureBearer("airtelgprs.com");
  result = sim800->connect();

  result = sim800->post("http://my.web.api/", jsonData, response);
  if (result == SUCCESS) {
    // Set the status led.
    t_blinkLedGprs.tTimeout = blinkOff;
    Serial.println("Successfully posted to api.");
    Serial.println(response);
  } else {
    Serial.println("Error in posting to api.");
    t_blinkLedGprs.tTimeout = blinkSlow;
    Serial.println(response);
  } 
  sim800->disconnect();
}

// used to periodically check task run timer status.
bool tCheck (struct t *t ) {
  
  if (millis() > t->tStart + t->tTimeout) {
    return true;
  } else {
    return false;
  }
 
}

// used to set when the task was last run.
void tRun (struct t *t) {
    t->tStart = millis();
}

I agree there is not much you can do to make your led blink more regularly, short of modifying the library.