Final MKRFOX1200 sketch
Contents
ETSI (European) regulations say that devices can emit 1% of the time on the public band (868MHz) over the course of 1 hour. That’s a total of 6 Sigfox messages of 12 bytes per hour. In order to prevent being blacklisted on the Sigfox network, we need to make sure that we don’t exceed this limit. The Wait()
function in the demo sketch makes sure that only one message is sent after every 15 minutes.
As a coincidance, the longitude, latitude and altitude float values in the gpscoord structure consume exactly 12 bytes, which is also the upper size limit of a data packet allowed to be sent into Sigfox. These 12 bytes are reassembled into three individual float values according to the Device Type setup we did in chapter “Sigfox Callback Edition” paragraph “Custom Payload Config”.
#include <SigFox.h> #include <ArduinoLowPower.h> #include <TinyGPS.h> #define WAITING_TIME 15 #define GPS_INFO_BUFFER_SIZE 128 TinyGPS gps; //GPS data variables int year; byte month, day, hour, minute, second, hundredths; unsigned long chars; unsigned short sentences, failed_checksum; char GPS_info_char; char GPS_info_buffer[GPS_INFO_BUFFER_SIZE]; // GPS coordinate structure, 12 bytes size on 32 bits platforms struct gpscoord { float a_latitude; // 4 bytes float a_longitude; // 4 bytes float a_altitude; // 4 bytes }; float latitude = 0.0f; float longitude = 0.0f; float altitud = 0; void Wait(int m, bool s) { //m minutes to wait //s slow led pulses Serial.print("Waiting: "); Serial.print(m); Serial.println(" min."); digitalWrite(LED_BUILTIN, LOW); if (s) { int seg = m * 30; for (int i = 0; i < seg; i++) { digitalWrite(LED_BUILTIN, HIGH); //LED on delay(1000); digitalWrite(LED_BUILTIN, LOW); //LED off delay(1000); } } else { int seg = m * 15; // 15 * (1000ms + 3000ms) = 60sec = 1 minute for (int i = 0; i < seg; i++) { digitalWrite(LED_BUILTIN, HIGH); //LED on delay(1000); digitalWrite(LED_BUILTIN, LOW); //LED off delay(3000); } } } void SendSigfox(String data) { Serial.print("Sending: "); Serial.println(data); if (data.length() > 12) { Serial.println("Message too long, only first 12 bytes will be sent"); } // Remove EOL //data.trim(); // Start the module SigFox.begin(); // Wait after first configuration delay(50); // Clears all pending interrupts SigFox.status(); delay(100); SigFox.beginPacket(); SigFox.print(data); SigFox.endPacket(); SigFox.end(); } /* Converts GPS float data to Char data */ String ConvertGPSdata(const void* data, uint8_t len) { uint8_t* bytes = (uint8_t*)data; String s ; for (uint8_t i = len - 1; i < len; --i) { if (bytes[i] < 12) { s.concat(byte(0)); // Not tested } else { s.concat(char(bytes[i])); } } return s; } String GetGPSpositon() { String pos; while (Serial1.available()) { GPS_info_char = Serial1.read(); if (gps.encode(GPS_info_char)) { gps.f_get_position(&latitude, &longitude); altitud = gps.altitude() / 100; // Store coordinates into dedicated structure gpscoord coords = {altitud, longitude, latitude}; gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths); gps.stats(&chars, &sentences, &failed_checksum); pos = ConvertGPSdata(&coords, sizeof(gpscoord)); return pos; } } } void setup() { Serial.begin(9600); while (!Serial) {} Serial.println("Serial Connected"); //Serial1 connection to GPS. Serial1.begin(9600); while (!Serial1) {} if (!SigFox.begin()) { Serial.println("Shield error or not present!"); return; } SigFox.end(); // Send the module to sleep } void loop() { String position_data; position_data = GetGPSpositon(); SendSigfox(position_data); Serial.println("Data Sent !"); Wait(WAITING_TIME, false); }
See also https://www.hackster.io/jgallar/gps-tracker-with-arduino-mkr-fox-1200-104012