NB Signal strength tracker - how to cache information while no connectivity

Components: MKR 1500 NB + MKR GPS shield
I am working on a NB signal strength tracker:

  1. get GPS point
  2. measure signal strength
  3. send information to server (JSON + MQTT)

The problem is that since the signal I am measuring is the same as I am using for transmission I am not able to assess areas without coverage. Thus the idea is to have a caching for the time no transmission is possible.

(for posting I have simplified and cleaned the code here below, not sure if it now works, but it should give the idea.)

// libraries
#include <MKRNB.h>
#include <Arduino_MKRGPS.h>
#include <TinyGPS.h>
#include <ArduinoMqttClient.h>
#include <ArduinoJson.h>


#include "arduino_secrets.h" 

const char* APN = SECRET_APN;
const char* broker = SECRET_BROKER;
int port = SECRET_PORT; 

// initialize the library instance
NBClient client; //NBSSLClient client;
MqttClient mqttClient(client);
GPRS gprs;
NB nbAccess(true);     // include a 'true' parameter to enable debugging
NBScanner scannerNetworks;
NBModem modemTest;
TinyGPS gps;

// Save data variables

String errortext = "ERROR";
String pubTop = "boomJson";
String subTop = "control";

int sig;
String car;
int rat;

unsigned long epo;
int dist = 100; // measure every 'dist' meters
float la0 = 0;
float lg0 = 0;

float la;
float lg;
float alt;
float kmh;
int   sat;

struct Config {
  byte pubQos = 1;
  byte subQos = 1;
 //byte wilQos = 1;
  String ICCID;
  String carrier;
  String simid;
  String IMEI;
Config config; //make global

void setup() {

  // initialize serial communications and wait for port to open:

  // Start module
  bool connected = false;
  while (!connected) 
    MODEM.begin(true); // true to restart the modem

    while (!MODEM.noop());

    if ((nbAccess.begin(PINNUMBER,APN) == NB_READY) && (gprs.attachGPRS() == GPRS_READY)) 
      connected = true;
    } else 

  config.ICCID   = modemTest.getICCID();
  config.carrier = config.ICCID.substring(0,6);
  config.IMEI    = modemTest.getIMEI();
  config.simid   = config.IMEI.substring(6);
  pubTop = pubTop + "/" + config.carrier + "/" + config.simid;  
    mqttClient.connect(broker, port);

  if (!GPS.begin()) { // GPS_MODE_SHIELD
    Serial.println("Failed to initialize GPS!");
    while (1);

void loop() {

    epo = GPS.getTime();
    la  = GPS.latitude();
    lg  = GPS.longitude();
    alt = GPS.altitude();
    kmh = GPS.speed();
    sat = GPS.satellites();

  float distance_in_meters = gps.distance_between(la, lg, la0, lg0);

  if(distance_in_meters > dist) // measure and send only if 'dist' to the last point is > 100 m
    sig = scannerNetworks.getSignalStrength().toInt();
    car = scannerNetworks.getCurrentCarrier();
    StaticJsonDocument<212> msg;
    msg["sig"] = sig;
    msg["car"] = car; 
    msg["lat"] = la;  
    msg["lon"] = lg;
    msg["alt"] = alt;
    msg["kmh"] = kmh;
    msg["sat"] = sat;
    msg["epo"] = epo;
// do the transmission only if we have connectivity, if not cache/store and continue to measure and send the entire package as soon as connectivity is available again.
    mqttClient.beginMessage(pubTop, false, config.pubQos);   
    serializeJson(msg, mqttClient);  

   // safe latest point location
   la0 = la; 
   lg0 = lg;

  } else

I am now not sure on how to handle that. i.e. a growing number of msg0, msg1,msg2 ... msgN. and than a for() loop to send the accumulated msg's. or to have a msg["sig"] = sig0,sig1...; kind of solution? But that would make the parsing at servers side a bit more difficult...

Any suggestions?
Thanks Matteo

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.