MKR1400 GSM save data connection

Hey!

I am using a Arduino MKR 1400 with GSM, reading a dht22 sensor and transfer the values (humidity and temperature as strings) every 6hours. I have 3 virtual buttons to control a relay.
My dashboard in Blynk-App has

  • 2x Buttons
  • 1x Timer
  • 1x Led
  • 2x Labeled Values
  • 1x Superchart (reading 2x Virtual Values from DHT22 and 1x Digital Value response)

I have read a lot in the forum about heartbeat to the blynk server, but unfortunately i see, if debugging blynk-connection, in the serial-console a send and recieve package every 1min.
The code works, but i want to save data consumption and don´t know how the sending of http api would save gsm data.

If i define the heartbeat to a different value than 10 there is no other transfer time while debugging, it is still 1min.

This is my code

#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_DEBUG        // Optional, this enables more detailed prints
#define BLYNK_PRINT SerialUSB

#include <SPI.h>
#include <MKRGSM.h>
#include <BlynkSimpleMKRGSM.h>

// Set Blynk heartbeat interval.
// Each heartbeat uses ~90 bytes of data.
#define BLYNK_HEARTBEAT 10   //was 10 [sek]; 300 = 5min; 1800 = 30min; 86400 =24h

GSMClient client;
GPRS gprs;
GSM gsmAccess;
#include <DHT.h>

char auth[] = "auth_token";
char pin[]  = "";
char apn[]  = "TM"; //hologram oder pepper oder TM
char user[] = "";
char pass[] = "";

#define DHTPIN 2          // What digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22, AM2302, AM2321
DHT dht(DHTPIN, DHTTYPE);

#if defined(ARDUINO_ARCH_AVR)
#define SERIAL  Serial

#elif defined(ARDUINO_ARCH_SAMD) ||  defined(ARDUINO_ARCH_SAM)
#define SERIAL  SerialUSB
#else
#define SERIAL  Serial
#endif

int period = 60000; //10min
unsigned long time_now = 0;

/*****************************************************************************************/

void sendSensor()
{
  int h = dht.readHumidity();
  int t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    SerialUSB.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more than 10 values per second.
  Blynk.virtualWrite(V10, h);
  Blynk.virtualWrite(V11, t);

}

/*****************************************************************************************/
// Select your pin with physical button
const int btnPin = 1;

WidgetLED led3(V3);

BlynkTimer timer;

// V3 LED Widget represents the physical button state
boolean btnState = false;

/*****************************************************************************************/

void buttonLedWidget()
{
  // Read button
  boolean isPressed = (digitalRead(btnPin) == LOW);

  // If state has changed...
  if (isPressed != btnState) {
    if (isPressed) {
      led3.on();
    } else {
      led3.off();
    }
    btnState = isPressed;
  }
}

/*****************************************************************************************/

int relais_ein = 3;
int relais_state = 0;
const int led = 6;
int automatik; //V0
int hand;      //V4
int zeit;      //V1


/*****************************************************************************************/

int ReCnctFlag;  // Reconnection Flag
int ReCnctCount = 0;  // Reconnection counter

/*****************************************************************************************/
//Timer Widget digital inputs für die Verriegelung wenn dann Automatik//Zeit,- siehe loop
BLYNK_WRITE(V0)
{
  automatik = param.asInt(); // assigning incoming value from pin V0 to a variable
}


BLYNK_WRITE(V4)
{
  hand = param.asInt(); // assigning incoming value from pin V4 to a variable
  // process received value
}

BLYNK_WRITE(V1)
{
  zeit = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, gsmAccess, gprs, client, pin, apn, user, pass);
  Blynk.connect();
  
    // Setup physical button pin (active low)
  pinMode(btnPin, INPUT_PULLUP);
  pinMode(relais_ein, OUTPUT);
  pinMode(led, OUTPUT);

  dht.begin();
  timer.setInterval(5000L, buttonLedWidget);
  // Setup a function to be called every 6 hours
  timer.setInterval(21600000L, sendSensor); //1000L 1x per Sekunde, 1800 000L für 30min , 21 600 000L für 6h

  millis();
}
/*****************************************************************************************/
void loop()
{
  Blynk.run();
  timer.run();
/* if (Blynk.connected()) {  // If connected run as normal
    Blynk.run();
    Blynk.syncAll();
  } else if (ReCnctFlag == 0) {  // If NOT connected and not already trying to reconnect, set timer to try to reconnect in 30 seconds
    ReCnctFlag = 1;  // Set reconnection Flag
    Serial.println("Starting reconnection timer in 30 seconds...");
    timer.setTimeout(30000L, []() {  // Lambda Reconnection Timer Function
      ReCnctFlag = 0;  // Reset reconnection Flag
      ReCnctCount++;  // Increment reconnection Counter
      Serial.print("Attempting reconnection #");
      Serial.println(ReCnctCount);
  Blynk.begin(auth, gsmAccess, gprs, client, pin, apn, user, pass);
      Blynk.connect();  // Try to reconnect to the server
      
      });  // END Timer Function
  }*/

/*****************************************************************************************/
  if((hand == LOW) && (automatik == LOW) || (automatik == HIGH) && (zeit == HIGH)){
    digitalWrite(relais_ein, LOW);
  }
  if((hand == HIGH) && (automatik == LOW) || (automatik == HIGH) && (zeit == LOW)){
    digitalWrite(relais_ein, HIGH);
  }



/*****************************************************************************************/

  if(millis() >= time_now + period)
  {
        time_now += period;

    float temp_hum_val[2] = {0};
    if(!dht.readTempAndHumidity(temp_hum_val)){
        SERIAL.print("Humidity: "); 
        SERIAL.print(temp_hum_val[0]);
        SERIAL.print(" %\t");
        SERIAL.print("Temperature: "); 
        SERIAL.print(temp_hum_val[1]);
        SERIAL.println(" *C");
        SERIAL.print("hand: ");
        SERIAL.println(hand);
        SERIAL.print("autom: ");
        SERIAL.println(automatik);
        SERIAL.print("relais: ");
        SERIAL.println(digitalRead(relais_ein));

    }}

      relais_state = digitalRead(relais_ein);

  // Onboard-LED Pin6
  if (relais_state == LOW) {
    // turn LED on:
    digitalWrite(led, HIGH);
  } else {
    // turn LED off:
    digitalWrite(led, LOW);
  }



Here is my serial-debug

15:58:04.204 -> [10857] Connecting to TM ...
15:58:06.752 -> [13385] Connected to GPRS
15:58:06.752 -> [13386] Connecting to blynk-cloud.com:80
15:58:07.596 -> [14230] <[1D|00|01|00] k43r24gmTEqGuyFNSIAbcyBXPRjQk1Zj
15:58:07.783 -> [14436] >[00|00|01|00|C8]
15:58:07.783 -> [14441] Ready (ping: 183ms).
15:58:07.783 -> [14442] Free RAM: 25903
15:58:07.877 -> [14525] <[11|00|02|00]Xver[00]0.6.1[00]h-beat[00]60[00]buff-in[00]1024[00]dev[00]MKR GSM 1400[00]con[00]MKRGSM[00]build[00]Sep 14 2020 15:57:45[00]
15:58:12.783 -> [19441] Connecting to blynk-cloud.com:80
15:58:13.533 -> [20172] <[1D|00|01|00] [auth_token]
15:58:13.908 -> [20561] >[00|00|01|00|C8]
15:58:13.908 -> [20566] Ready (ping: 367ms).
15:58:13.908 -> [20568] Free RAM: 25315
15:58:14.002 -> [20649] <[11|00|02|00]Xver[00]0.6.1[00]h-beat[00]60[00]buff-in[00]1024[00]dev[00]MKR GSM 1400[00]con[00]MKRGSM[00]build[00]Sep 14 2020 15:57:45[00]
15:58:14.236 -> [20878] >[00|00|02|00|C8] //i guess here is the hardware requesting pin states
15:58:19.170 -> [25836] <[14|00|03|00|08]vw[00]3[00]255 // these are the pin states
15:58:53.886 -> Humidity: 73.50 %	Temperature: 24.20 *C // i call the virtual pins every min in serial
15:58:53.886 -> hand: 0
15:58:53.886 -> autom: 0
15:58:53.886 -> relais: 0
15:59:14.345 -> [80993] <[06|00|04|00|00] // what is this?- happening every 1 min
15:59:15.376 -> [82043] >[00|00|04|00|C8] // what is this?- happening every 1 min
15:59:53.892 -> Humidity: 73.70 %	Temperature: 24.20 *C
15:59:53.892 -> hand: 0
15:59:53.892 -> autom: 0
15:59:53.892 -> relais: 0
16:00:14.483 -> [141122] <[06|00|05|00|00]
16:00:15.673 -> [142300] >[00|00|05|00|C8]
16:00:53.876 -> Humidity: 73.60 %	Temperature: 24.20 *C
16:00:53.923 -> hand: 0
16:00:53.923 -> autom: 0
16:00:53.923 -> relais: 0
16:01:14.627 -> [201252] <[06|00|06|00|00]
16:01:15.705 -> [202351] >[00|00|06|00|C8]

Here is my dashboard

Thank you for reading!
What can i do to save gsm data consumption? (I am now at calculated 7,7MB in 31Days and want to get under 1MB, because of dataplan)
Thank you for this great piece of software!

Ok i have found a little bug in my code, connecting to blynk server two times in

void setup ()
  Blynk.begin(auth, gsmAccess, gprs, client, pin, apn, user, pass);
//  Blynk.connect(); //this connects to blynk, same does Blynk.run in the loop

Second point about heartbeat, i have found the heartbeat which could not be changed in “Arduino\libraries\Blynk\src\Adapters\BlynkArduinoGSM.h” line 18:

#define BLYNK_HEARTBEAT 600 /*original 60*/

Tried 10mins heartbeat now, it works so far, no disconnect message in the app.

Not sure if it is a Blynk-BUG, that definition is not possible in code.

EDIT: i previously forgot to say, i have disabled offline notification in the app.
I have now set the heartbeat to 6hours, but it would great to turn heartbeat completely off, because for the server it would be the same if the command comes from the heartbeat or value send.

Hey, there were several disconnects from the server at various times, the shortest was after about 1hour, the longest was about 6hours.
I am now experimenting with 1hour heartbeat and the connection is still there after a night of testing.
I was also looking at some GSM disconnect threads in the arduino forum, where people mentioned, disconnects could come from the provider because of no sent data.
Still figuring out and will keep this thread up to date if I find a solution.

With 1hour heartbeat, the MKR 1400 does really well.

There is still a little issue, the communication restarts once a day (or less, the longest on time was 2,5 days, yet).

Not sure if I should set a higher server response time, because there was no incoming communication from the server to the arduino several times, - after the third ping without response (or so) the reconnection goes on, from that point server communication is OK, again.

The machine is not in house for other testing now.

Heartbeat less than 1 hour would work, I guess.
Signalstrengh with the original arduino antenna was high, but there were still some reconnects.
Now I have bought a room antenna which should be mounted on the window.

It seems to me that there are a little less reconnects, but it is hard to say, - it’s just a feeling.
With a longer heartbeat, there are as many reconnects as with the original antenna.

Overall I guess the reconnects/disconnects come from the cellular network.