diff --git a/MQTT_GPS/MQTT_GPS.ino b/MQTT_GPS/MQTT_GPS.ino index 5f77f116b5229b7990af676d871d8df8702991cf..b1817dbb0dbf4607588fd62ebb597bd813b00edd 100644 --- a/MQTT_GPS/MQTT_GPS.ino +++ b/MQTT_GPS/MQTT_GPS.ino @@ -50,6 +50,7 @@ void setup() { setup_wifi(); // Initialize WiFi client.setServer(mqtt_server, 1883); // Initialize MQTT connection client.setCallback(callback); + delay(15000); } void loop() { @@ -183,22 +184,16 @@ void printMacAddress(byte mac[]) { } void setup_wifi(){ - char wifi_init_cnt_lmt = 30; + char wifi_init_cnt_lmt = 50; char wifi_init_ctr = 0; - WiFi.setTimeout(5000); - - if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed!"); - return; - } + WiFi.setTimeout(15000); Serial.print("\nConnecting to "); Serial.println(ssid); WiFi.begin(ssid, pass); while( (WiFi.status() != WL_CONNECTED) && (wifi_init_ctr++ < wifi_init_cnt_lmt) ){ - Serial.print("."); - delay(500); // Try to connect to WiFi. Limited number of attempts before time out + Serial.print("."); delay(500); // Try to connect to WiFi. Limited number of attempts before time out } if (status == WL_CONNECTED){ // Connection succeeded @@ -213,19 +208,28 @@ void setup_wifi(){ } void mqtt_pub(){ - String mqtt_timstmp, yr, mh, dy, hr, mn, sc, lt, ln; - char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; + String mqtt_timstmp, lt, ln, al; + char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; + char yr[5], mh[3], dy[3], hr[3], mn[3], sc[3]; if (gps_fix_flg) { /* Publish time stamp */ - yr = GPS.year; - mh = ( (GPS.month < 10) ? (0 + GPS.month) : GPS.month); - dy = ( (GPS.day < 10) ? (0 + GPS.day) : GPS.day); - hr = ( (GPS.hour < 10) ? (0 + GPS.hour) : GPS.hour); - mn = ( (GPS.minute < 10) ? (0 + GPS.minute) : GPS.minute); - sc = ( (GPS.seconds < 10) ? (0 + GPS.seconds) : GPS.seconds); - mqtt_timstmp = "20" + yr + "/" + mh + "/" + dy + " - " + hr + ":" + mn + ":" + sc; - mqtt_timstmp.toCharArray(time_stmp,30); + sprintf(yr, "20%d", GPS.year); + //yr = GPS.year; + if (GPS.month < 10) { sprintf(mh, "0%d", GPS.month); + } else { itoa(GPS.month,mh,10); } + if (GPS.day < 10) { sprintf(dy, "0%d", GPS.day); + } else { itoa(GPS.day,dy,10); } + if (GPS.hour < 10) { sprintf(hr, "0%d", GPS.hour); + } else { itoa(GPS.hour,hr,10); } + if (GPS.minute < 10) { sprintf(mn, "0%d", GPS.minute); + } else { itoa(GPS.minute,mn,10); } + if (GPS.seconds < 10) { sprintf(sc, "0%d", GPS.seconds); + } else { itoa(GPS.seconds,sc,10); } + sprintf(time_stmp, "%s/%s/%s - %s:%s:%s", yr, mh, dy, hr, mn, sc); + //sc = ( (GPS.seconds < 10) ? (0 + GPS.seconds) : GPS.seconds); + //mqtt_timstmp += "20" + yr + "/" + mh + "/" + dy + " - " + hr + ":" + mn + ":" + sc; + //mqtt_timstmp.toCharArray(time_stmp,30); client.publish("efss/GPS/Timestamp",time_stmp); /* Publish quality data */ @@ -238,12 +242,25 @@ void mqtt_pub(){ client.publish("efss/GPS/Satellites",sat); /* Publish location data */ + /* sprintf(pos_lat, "%.4f %c", GPS.latitude, GPS.lat); sprintf(pos_lon, "%.4f %c", GPS.longitude, GPS.lon); sprintf(pos_alt, "%.2f", GPS.altitude); + */ - client.publish("efss/GPS/Latitude",pos_lat); + ln = GPS.longitude; ln.concat(GPS.lon); + while ( ln.charAt(5) != '.'){ln = '0' + ln;} + ln.toCharArray(pos_lon,10); client.publish("efss/GPS/Longitude",pos_lon); + + lt = GPS.latitude; lt.concat(GPS.lat); + while ( lt.charAt(5) != '.'){lt = '0' + lt;} + lt.toCharArray(pos_lat,10); + client.publish("efss/GPS/Latitude",pos_lat); + + al = GPS.altitude; + while ( al.charAt(4) != '.'){al = '0' + al;} + al.toCharArray(pos_alt,10); client.publish("efss/GPS/Altitude",pos_alt); Serial.println("published"); diff --git a/SD_GPS/SD_GPS.ino b/SD_GPS/SD_GPS.ino index fa60c933897272ebf7b0162f9f9587d55e9ae0de..f8811bf62d03a237364ccd7d3313aeb88c508890 100644 --- a/SD_GPS/SD_GPS.ino +++ b/SD_GPS/SD_GPS.ino @@ -2,10 +2,12 @@ Example based on Adafruit's GPS library and PubSubClient library */ #include <SPI.h> +#include <SD.h> #include <WiFiNINA.h> #include <Adafruit_GPS.h> #include <PubSubClient.h> #include "arduino_secrets.h" +#include "Wifi_Dat.h" // Refer to Serial1 as GPSSerial #define GPSSerial Serial1 @@ -15,52 +17,57 @@ uint32_t timer = millis(); // Connect to the GPS on the hardware port Adafruit_GPS GPS(&GPSSerial); -bool wifi_init_flg = 0; // Set flag after first WiFi connection -bool gps_fix_flg = 0; // Set flag after first receiving a fix -char ssid[] = SECRET_SSID; // network SSID (name) -char pass[] = SECRET_PASS; // network password (use for WPA, or use as key for WEP) -int status = WL_IDLE_STATUS; // the WiFi radio's status -const char mqtt_server[] = "srv03183.soton.ac.uk"; - -// WiFi and MQTT clients -WiFiClient wifiClient; -PubSubClient client(wifiClient); - -void callback(char* topic, byte* payload, unsigned int length) { - Serial.print("Message arrived ["); - Serial.print(topic); - Serial.print("] "); - for (int i=0;i<length;i++) { - Serial.print((char)payload[i]); - } - Serial.println(); -} +// SD card information +File myFile; void setup() { + /* Initialize PC serial */ + Serial.begin(115200); //Initialize serial and wait for port to open: + while (!Serial); // Wait for Serial to be ready + Serial.println("\nHello there! My name is Annie Tracey, the animal tracker"); + /* Initialize GPS module */ GPSSerial.begin(9600); while (!GPSSerial); GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); // Set to RMC only GPS.sendCommand(PMTK_SET_NMEA_UPDATE_200_MILLIHERTZ); // Set the update rate GPS.sendCommand(PGCMD_ANTENNA); // Request updates on antenna status + Serial.println("GPS initialization done!"); + + /*Initialize SD card */ + if (!SD.begin(10)) { + Serial.println("SD card initialization failed!"); + while (1); + } + Serial.println("SD card initialization done!"); + SD.remove("gpslog.txt"); + myFile = SD.open("gpslog.txt", FILE_WRITE); +/* + // if the file opened okay, write to it: + if (myFile) { + Serial.print("Writing to gpslog.txt..."); + myFile.println("test"); + // close the file: + myFile.close(); + Serial.println("done."); + } else { + // if the file didn't open, print an error: + Serial.println("error opening gpslog.txt"); + } +*/ /* WiFi + MQTT initialization */ - Serial.begin(115200); //Initialize serial and wait for port to open: - while (!Serial); // Wait for Serial to be ready setup_wifi(); // Initialize WiFi client.setServer(mqtt_server, 1883); // Initialize MQTT connection client.setCallback(callback); delay(15000); } -void loop() { - char rcnct_ctr = 0; - char rcnct_ctr_lmt = 6; - +void loop() { char c = GPS.read(); // read data from the GPS in the 'main loop' if (GPS.newNMEAreceived()) { if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false - return; // we can fail to parse a sentence in which case we should just wait for another + return; // we can fail to parse a sentence in which case we should just wait for another } // approximately every 9 seconds or so, print out the current stats @@ -68,36 +75,64 @@ void loop() { timer = millis(); // reset the timer /* Process GPS data */ - parseGPSdata(); + //parseGPSdata(); - if (status != WL_CONNECTED) { - Serial.print("\nNot connected to WiFi\nAttempting reconnection"); - status = WiFi.begin(ssid, pass); - while( (WiFi.status() != WL_CONNECTED) && ( rcnct_ctr++ < rcnct_ctr_lmt) ){ - Serial.print("."); - delay(500); - } - if (status == WL_CONNECTED){ - Serial.println("\nConnected to WiFi"); - if (!client.connected()) { - mqtt_reconnect(); - } - else if (client.connect("arduinoClient")) { - mqtt_pub(); - } - } - else{ - WiFi.end(); - } - } - else if (status == WL_CONNECTED){ - Serial.println("\nConnected to WiFi"); - if (!client.connected()) { - mqtt_reconnect(); - } - else if (client.connect("arduinoClient")) { - mqtt_pub(); - } + /* Store Data in the SD card */ + storeGPSdata(); + + /* Reconnect to WiFi */ + //mainWifiLoop(); + } +} + +void storeGPSdata(){ + char sd_word[60]; + String tmp_word; + + String mqtt_timstmp, lt, ln, al; + char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; + char yr[5], mh[3], dy[3], hr[3], mn[3], sc[3]; + + if (GPS.fix) { + myFile = SD.open("gpslog.txt", FILE_WRITE); + if (myFile) { + Serial.print("Writing to SD card..."); + + // Compose timestamp + sprintf(yr, "20%d", GPS.year); + //yr = GPS.year; + if (GPS.month < 10) { sprintf(mh, "0%d", GPS.month); + } else { itoa(GPS.month,mh,10); } + if (GPS.day < 10) { sprintf(dy, "0%d", GPS.day); + } else { itoa(GPS.day,dy,10); } + if (GPS.hour < 10) { sprintf(hr, "0%d", GPS.hour); + } else { itoa(GPS.hour,hr,10); } + if (GPS.minute < 10) { sprintf(mn, "0%d", GPS.minute); + } else { itoa(GPS.minute,mn,10); } + if (GPS.seconds < 10) { sprintf(sc, "0%d", GPS.seconds); + } else { itoa(GPS.seconds,sc,10); } + sprintf(time_stmp, "%s/%s/%s - %s:%s:%s", yr, mh, dy, hr, mn, sc); + + // Compose location + ln = GPS.longitude; ln.concat(GPS.lon); + while ( ln.charAt(5) != '.'){ln = '0' + ln;} + ln.toCharArray(pos_lon,10); + lt = GPS.latitude; lt.concat(GPS.lat); + while ( lt.charAt(5) != '.'){lt = '0' + lt;} + lt.toCharArray(pos_lat,10); + al = GPS.altitude; + while ( al.charAt(4) != '.'){al = '0' + al;} + al.toCharArray(pos_alt,10); + + // Compose final word + sprintf(sd_word,"%s,%d,%d,%d,%s,%s,%s", time_stmp, GPS.fix, GPS.fixquality, GPS.satellites, pos_lon, pos_lat, pos_alt); + myFile.println(sd_word); + + // close the file: + myFile.close(); + Serial.println("done."); + } else { + Serial.println("error opening file"); // if the file didn't open, print an error: } } } @@ -135,149 +170,3 @@ void parseGPSdata() { if (GPS.seconds < 10) { Serial.print('0'); } Serial.println(GPS.seconds, DEC); Serial.println("No GPS fix"); } } - -void printWifiData() { - // print your board's IP address: - IPAddress ip = WiFi.localIP(); - Serial.print("IP Address: "); Serial.println(ip); // Serial.println(ip); - - // print your MAC address: - byte mac[6]; - WiFi.macAddress(mac); - Serial.print("MAC address: "); printMacAddress(mac); -} - -void printCurrentNet() { - // print the SSID of the network you're attached to: - Serial.print("SSID: "); - Serial.println(WiFi.SSID()); - - // print the MAC address of the router you're attached to: - byte bssid[6]; - WiFi.BSSID(bssid); - Serial.print("BSSID: "); - printMacAddress(bssid); - - // print the received signal strength: - long rssi = WiFi.RSSI(); - Serial.print("signal strength (RSSI):"); - Serial.println(rssi); - - // print the encryption type: - byte encryption = WiFi.encryptionType(); - Serial.print("Encryption Type:"); - Serial.println(encryption, HEX); - Serial.println(); -} - -void printMacAddress(byte mac[]) { - for (int i = 5; i >= 0; i--) { - if (mac[i] < 16) { - Serial.print("0"); - } - Serial.print(mac[i], HEX); - if (i > 0) { - Serial.print(":"); - } - } - Serial.println(); -} - -void setup_wifi(){ - char wifi_init_cnt_lmt = 50; - char wifi_init_ctr = 0; - - WiFi.setTimeout(15000); - - Serial.print("\nConnecting to "); Serial.println(ssid); - WiFi.begin(ssid, pass); - - while( (WiFi.status() != WL_CONNECTED) && (wifi_init_ctr++ < wifi_init_cnt_lmt) ){ - Serial.print("."); delay(500); // Try to connect to WiFi. Limited number of attempts before time out - } - - if (status == WL_CONNECTED){ // Connection succeeded - randomSeed(micros()); - Serial.println("\nWiFi connected"); - printCurrentNet(); - printWifiData(); - }else if (WiFi.status() != WL_CONNECTED){ // Connection timed out - Serial.print("\nTimed out. Could not connect to "); Serial.println(ssid); - WiFi.end(); - } -} - -void mqtt_pub(){ - String mqtt_timstmp, lt, ln, al; - char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; - char yr[5], mh[3], dy[3], hr[3], mn[3], sc[3]; - - if (gps_fix_flg) { - /* Publish time stamp */ - sprintf(yr, "20%d", GPS.year); - //yr = GPS.year; - if (GPS.month < 10) { sprintf(mh, "0%d", GPS.month); - } else { itoa(GPS.month,mh,10); } - if (GPS.day < 10) { sprintf(dy, "0%d", GPS.day); - } else { itoa(GPS.day,dy,10); } - if (GPS.hour < 10) { sprintf(hr, "0%d", GPS.hour); - } else { itoa(GPS.hour,hr,10); } - if (GPS.minute < 10) { sprintf(mn, "0%d", GPS.minute); - } else { itoa(GPS.minute,mn,10); } - if (GPS.seconds < 10) { sprintf(sc, "0%d", GPS.seconds); - } else { itoa(GPS.seconds,sc,10); } - sprintf(time_stmp, "%s/%s/%s - %s:%s:%s", yr, mh, dy, hr, mn, sc); - //sc = ( (GPS.seconds < 10) ? (0 + GPS.seconds) : GPS.seconds); - //mqtt_timstmp += "20" + yr + "/" + mh + "/" + dy + " - " + hr + ":" + mn + ":" + sc; - //mqtt_timstmp.toCharArray(time_stmp,30); - client.publish("efss/GPS/Timestamp",time_stmp); - - /* Publish quality data */ - sprintf(ant_fix, "%d", GPS.fix); - sprintf(qlty, "%d", GPS.fixquality); - sprintf(sat, "%d", GPS.fixquality); - - client.publish("efss/GPS/Fix",ant_fix); - client.publish("efss/GPS/Fix quality",qlty); - client.publish("efss/GPS/Satellites",sat); - - /* Publish location data */ - /* - sprintf(pos_lat, "%.4f %c", GPS.latitude, GPS.lat); - sprintf(pos_lon, "%.4f %c", GPS.longitude, GPS.lon); - sprintf(pos_alt, "%.2f", GPS.altitude); - */ - - ln = GPS.longitude; ln.concat(GPS.lon); - while ( ln.charAt(5) != '.'){ln = '0' + ln;} - ln.toCharArray(pos_lon,10); - client.publish("efss/GPS/Longitude",pos_lon); - - lt = GPS.latitude; lt.concat(GPS.lat); - while ( lt.charAt(5) != '.'){lt = '0' + lt;} - lt.toCharArray(pos_lat,10); - client.publish("efss/GPS/Latitude",pos_lat); - - al = GPS.altitude; - while ( al.charAt(4) != '.'){al = '0' + al;} - al.toCharArray(pos_alt,10); - client.publish("efss/GPS/Altitude",pos_alt); - - Serial.println("published"); - } -} - -void mqtt_reconnect() { - char rcnct_ctr = 0; - char rcnct_ctr_lmt = 3; - - while ( (!client.connected()) && ( rcnct_ctr++ < rcnct_ctr_lmt) ) { - Serial.println("Attempting MQTT connection..."); - if (client.connect("arduinoClient")) { // Connection succeeded. Publish info - mqtt_pub(); - } else { // Connection failed. Wait before reattempting - Serial.print("failed, rc="); Serial.print(client.state()); - delay(800); - } - } -} diff --git a/SD_GPS/Wifi_Dat.h b/SD_GPS/Wifi_Dat.h new file mode 100644 index 0000000000000000000000000000000000000000..f5dc40f325bc9873ed1eeb1b0270e3440c9d6621 --- /dev/null +++ b/SD_GPS/Wifi_Dat.h @@ -0,0 +1,18 @@ +extern void callback(char* topic, byte* payload, unsigned int length); +extern void printWifiData(); +extern void printCurrentNet(); +extern void printMacAddress(byte mac[]); +extern void setup_wifi(); +extern void mqtt_pub(); +extern void mqtt_reconnect(); +extern void mainWifiLoop (); + +extern bool wifi_init_flg; // Set flag after first WiFi connection +extern bool gps_fix_flg; // Set flag after first receiving a fix +extern char ssid[]; // network SSID (name) +extern char pass[]; // network password (use for WPA, or use as key for WEP) +extern int status; // the WiFi radio's status +extern const char mqtt_server[]; + +//extern WiFiClient wifiClient; +extern PubSubClient client; diff --git a/SD_GPS/Wifi_Fcn.cpp b/SD_GPS/Wifi_Fcn.cpp new file mode 100644 index 0000000000000000000000000000000000000000..61aa66e6a2c41318c41ec3847f5654df6e319f9d --- /dev/null +++ b/SD_GPS/Wifi_Fcn.cpp @@ -0,0 +1,204 @@ +#include <SPI.h> +#include <WiFiNINA.h> +#include <Adafruit_GPS.h> +#include <PubSubClient.h> +#include "arduino_secrets.h" +#include "Wifi_Dat.h" + +bool wifi_init_flg = 0; // Set flag after first WiFi connection +bool gps_fix_flg = 0; // Set flag after first receiving a fix +char ssid[] = SECRET_SSID; // network SSID (name) +char pass[] = SECRET_PASS; // network password (use for WPA, or use as key for WEP) +int status = WL_IDLE_STATUS; // the WiFi radio's status +const char mqtt_server[] = "srv03183.soton.ac.uk"; + +// WiFi and MQTT clients +WiFiClient wifiClient; +PubSubClient client(wifiClient); + +//Adafruit_GPS GPS(&GPSSerial); +extern Adafruit_GPS GPS; + +void callback(char* topic, byte* payload, unsigned int length) { + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + for (int i=0;i<length;i++) { + Serial.print((char)payload[i]); + } + Serial.println(); +} + +void mainWifiLoop (){ + char rcnct_ctr = 0; + char rcnct_ctr_lmt = 6; + + if (status != WL_CONNECTED) { + Serial.print("\nNot connected to WiFi\nAttempting reconnection"); + status = WiFi.begin(ssid, pass); + while( (WiFi.status() != WL_CONNECTED) && ( rcnct_ctr++ < rcnct_ctr_lmt) ){ + Serial.print("."); + delay(500); + } + if (status == WL_CONNECTED){ + Serial.println("\nConnected to WiFi"); + if (!client.connected()) { + mqtt_reconnect(); + } + else if (client.connect("arduinoClient")) { + mqtt_pub(); + } + } + else{ + WiFi.end(); + Serial.print("\n"); + } + } + else if (status == WL_CONNECTED){ + Serial.println("\nConnected to WiFi"); + if (!client.connected()) { + mqtt_reconnect(); + } + else if (client.connect("arduinoClient")) { + mqtt_pub(); + } + } +} + +void printWifiData() { + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); Serial.println(ip); // Serial.println(ip); + + // print your MAC address: + byte mac[6]; + WiFi.macAddress(mac); + Serial.print("MAC address: "); printMacAddress(mac); +} + +void printCurrentNet() { + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print the MAC address of the router you're attached to: + byte bssid[6]; + WiFi.BSSID(bssid); + Serial.print("BSSID: "); + printMacAddress(bssid); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.println(rssi); + + // print the encryption type: + byte encryption = WiFi.encryptionType(); + Serial.print("Encryption Type:"); + Serial.println(encryption, HEX); + Serial.println(); +} + +void printMacAddress(byte mac[]) { + for (int i = 5; i >= 0; i--) { + if (mac[i] < 16) { + Serial.print("0"); + } + Serial.print(mac[i], HEX); + if (i > 0) { + Serial.print(":"); + } + } + Serial.println(); +} + +void setup_wifi(){ + char wifi_init_cnt_lmt = 10; + char wifi_init_ctr = 0; + + WiFi.setTimeout(15000); + + Serial.print("\nConnecting to "); Serial.println(ssid); + WiFi.begin(ssid, pass); + + while( (WiFi.status() != WL_CONNECTED) && (wifi_init_ctr++ < wifi_init_cnt_lmt) ){ + Serial.print("."); delay(500); // Try to connect to WiFi. Limited number of attempts before time out + } + + if (WiFi.status() == WL_CONNECTED){ // Connection succeeded + randomSeed(micros()); + Serial.println("\nWiFi connected"); + printCurrentNet(); + printWifiData(); + }else if (WiFi.status() != WL_CONNECTED){ // Connection timed out + Serial.print("\nTimed out. Could not connect to "); Serial.println(ssid); + WiFi.end(); + } +} + + + +void mqtt_reconnect() { + char rcnct_ctr = 0; + char rcnct_ctr_lmt = 3; + + while ( (!client.connected()) && ( rcnct_ctr++ < rcnct_ctr_lmt) ) { + Serial.println("Attempting MQTT connection..."); + if (client.connect("arduinoClient")) { // Connection succeeded. Publish info + mqtt_pub(); + } else { // Connection failed. Wait before reattempting + Serial.print("failed, rc="); Serial.print(client.state()); + delay(800); + } + } +} + +void mqtt_pub(){ + String mqtt_timstmp, lt, ln, al; + char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; + char yr[5], mh[3], dy[3], hr[3], mn[3], sc[3]; + + if (gps_fix_flg) { + /* Publish time stamp */ + sprintf(yr, "20%d", GPS.year); + //yr = GPS.year; + if (GPS.month < 10) { sprintf(mh, "0%d", GPS.month); + } else { itoa(GPS.month,mh,10); } + if (GPS.day < 10) { sprintf(dy, "0%d", GPS.day); + } else { itoa(GPS.day,dy,10); } + if (GPS.hour < 10) { sprintf(hr, "0%d", GPS.hour); + } else { itoa(GPS.hour,hr,10); } + if (GPS.minute < 10) { sprintf(mn, "0%d", GPS.minute); + } else { itoa(GPS.minute,mn,10); } + if (GPS.seconds < 10) { sprintf(sc, "0%d", GPS.seconds); + } else { itoa(GPS.seconds,sc,10); } + sprintf(time_stmp, "%s/%s/%s - %s:%s:%s", yr, mh, dy, hr, mn, sc); + client.publish("efss/GPS/Timestamp",time_stmp); + + /* Publish quality data */ + sprintf(ant_fix, "%d", GPS.fix); + sprintf(qlty, "%d", GPS.fixquality); + sprintf(sat, "%d", GPS.satellites); + + client.publish("efss/GPS/Fix",ant_fix); + client.publish("efss/GPS/Fix quality",qlty); + client.publish("efss/GPS/Satellites",sat); + + ln = GPS.longitude; ln.concat(GPS.lon); + while ( ln.charAt(5) != '.'){ln = '0' + ln;} + ln.toCharArray(pos_lon,10); + client.publish("efss/GPS/Longitude",pos_lon); + + lt = GPS.latitude; lt.concat(GPS.lat); + while ( lt.charAt(5) != '.'){lt = '0' + lt;} + lt.toCharArray(pos_lat,10); + client.publish("efss/GPS/Latitude",pos_lat); + + al = GPS.altitude; + while ( al.charAt(4) != '.'){al = '0' + al;} + al.toCharArray(pos_alt,10); + client.publish("efss/GPS/Altitude",pos_alt); + + Serial.println("published"); + } +} diff --git a/SD_GPS_MQTT/SD_GPS_MQTT.ino b/SD_GPS_MQTT/SD_GPS_MQTT.ino new file mode 100644 index 0000000000000000000000000000000000000000..ef9a6330762b41f3573803df830daa0a6010825a --- /dev/null +++ b/SD_GPS_MQTT/SD_GPS_MQTT.ino @@ -0,0 +1,174 @@ +/* +Example based on Adafruit's GPS library and PubSubClient library +*/ +#include <SPI.h> +#include <SD.h> +#include <WiFiNINA.h> +#include <Adafruit_GPS.h> +#include <PubSubClient.h> +#include "arduino_secrets.h" +#include "Wifi_Dat.h" + +// Refer to Serial1 as GPSSerial +#define GPSSerial Serial1 + +uint32_t timer = millis(); + +// Connect to the GPS on the hardware port +Adafruit_GPS GPS(&GPSSerial); + +// SD card information +File myFile; + +void setup() { + /* Initialize PC serial */ + Serial.begin(115200); //Initialize serial and wait for port to open: + while (!Serial); // Wait for Serial to be ready + Serial.println("\nHello there! My name is Annie Tracey, the animal tracker"); + + /* Initialize GPS module */ + GPSSerial.begin(9600); + while (!GPSSerial); + GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY); // Set to RMC only + GPS.sendCommand(PMTK_SET_NMEA_UPDATE_200_MILLIHERTZ); // Set the update rate + GPS.sendCommand(PGCMD_ANTENNA); // Request updates on antenna status + Serial.println("GPS initialization done!"); + + /*Initialize SD card */ + if (!SD.begin(10)) { + Serial.println("SD card initialization failed!"); + while (1); + } + Serial.println("SD card initialization done!"); + SD.remove("gpslog.txt"); + myFile = SD.open("gpslog.txt", FILE_READ); + myFile.close(); + +/* + // if the file opened okay, write to it: + if (myFile) { + Serial.print("Writing to gpslog.txt..."); + myFile.println("test"); + // close the file: + myFile.close(); + Serial.println("done."); + } else { + // if the file didn't open, print an error: + Serial.println("error opening gpslog.txt"); + } +*/ + + /* WiFi + MQTT initialization */ + setup_wifi(); // Initialize WiFi + client.setServer(mqtt_server, 1883); // Initialize MQTT connection + client.setCallback(callback); + delay(15000); +} + +void loop() { + char c = GPS.read(); // read data from the GPS in the 'main loop' + if (GPS.newNMEAreceived()) { + if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false + return; // we can fail to parse a sentence in which case we should just wait for another + } + + // approximately every 9 seconds or so, print out the current stats + if (millis() - timer > 9000) { + timer = millis(); // reset the timer + + /* Process GPS data */ + //parseGPSdata(); + + /* Store Data in the SD card */ + storeGPSdata(); + + /* Reconnect to WiFi */ + //mainWifiLoop(); + } +} + +void storeGPSdata(){ + char sd_word[60]; + String tmp_word; + + String mqtt_timstmp, lt, ln, al; + char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; + char yr[5], mh[3], dy[3], hr[3], mn[3], sc[3]; + + if (GPS.fix) { + myFile = SD.open("gpslog.txt", FILE_WRITE); + if (myFile) { + Serial.print("Writing to SD card..."); + + // Compose timestamp + sprintf(yr, "20%d", GPS.year); + //yr = GPS.year; + if (GPS.month < 10) { sprintf(mh, "0%d", GPS.month); + } else { itoa(GPS.month,mh,10); } + if (GPS.day < 10) { sprintf(dy, "0%d", GPS.day); + } else { itoa(GPS.day,dy,10); } + if (GPS.hour < 10) { sprintf(hr, "0%d", GPS.hour); + } else { itoa(GPS.hour,hr,10); } + if (GPS.minute < 10) { sprintf(mn, "0%d", GPS.minute); + } else { itoa(GPS.minute,mn,10); } + if (GPS.seconds < 10) { sprintf(sc, "0%d", GPS.seconds); + } else { itoa(GPS.seconds,sc,10); } + sprintf(time_stmp, "%s/%s/%s - %s:%s:%s", yr, mh, dy, hr, mn, sc); + + // Compose location + ln = GPS.longitude; ln.concat(GPS.lon); + while ( ln.charAt(5) != '.'){ln = '0' + ln;} + ln.toCharArray(pos_lon,10); + lt = GPS.latitude; lt.concat(GPS.lat); + while ( lt.charAt(5) != '.'){lt = '0' + lt;} + lt.toCharArray(pos_lat,10); + al = GPS.altitude; + while ( al.charAt(4) != '.'){al = '0' + al;} + al.toCharArray(pos_alt,10); + + // Compose final word + sprintf(sd_word,"%s,%d,%d,%d,%s,%s,%s", time_stmp, GPS.fix, GPS.fixquality, GPS.satellites, pos_lon, pos_lat, pos_alt); + myFile.println(sd_word); + + // close the file: + myFile.close(); + Serial.println("done."); + } else { + Serial.println("error opening file"); // if the file didn't open, print an error: + } + } +} + +void parseGPSdata() { + if (GPS.fix) { + gps_fix_flg = 1; // If there has been at least one fix, set flag + + /* Print date */ + Serial.print("\nDate: "); Serial.print(GPS.day, DEC); + Serial.print('/'); Serial.print(GPS.month, DEC); + Serial.print("/20"); Serial.println(GPS.year, DEC); + + /* Print time */ + Serial.print("Time: "); + if (GPS.hour < 10) { Serial.print('0'); } Serial.print(GPS.hour, DEC); Serial.print(':'); + if (GPS.minute < 10) { Serial.print('0'); } Serial.print(GPS.minute, DEC); Serial.print(':'); + if (GPS.seconds < 10) { Serial.print('0'); } Serial.println(GPS.seconds, DEC); + + /* Print fix */ + Serial.print("Fix: "); Serial.print((int)GPS.fix); + Serial.print(" quality: "); Serial.println((int)GPS.fixquality); + Serial.print("Satellites: "); Serial.println((int)GPS.satellites); + + /* print location */ + Serial.print("Location: "); Serial.print(GPS.latitude, 4); Serial.print(GPS.lat); + Serial.print(", "); Serial.print(GPS.longitude, 4); Serial.println(GPS.lon); + Serial.print("Altitude: "); Serial.println(GPS.altitude); + } + else { + /* Print time */ + Serial.print("\n\nTime: "); + if (GPS.hour < 10) { Serial.print('0'); } Serial.print(GPS.hour, DEC); Serial.print(':'); + if (GPS.minute < 10) { Serial.print('0'); } Serial.print(GPS.minute, DEC); Serial.print(':'); + if (GPS.seconds < 10) { Serial.print('0'); } Serial.println(GPS.seconds, DEC); Serial.println("No GPS fix"); + } +} diff --git a/SD_GPS_MQTT/Wifi_Dat.h b/SD_GPS_MQTT/Wifi_Dat.h new file mode 100644 index 0000000000000000000000000000000000000000..f5dc40f325bc9873ed1eeb1b0270e3440c9d6621 --- /dev/null +++ b/SD_GPS_MQTT/Wifi_Dat.h @@ -0,0 +1,18 @@ +extern void callback(char* topic, byte* payload, unsigned int length); +extern void printWifiData(); +extern void printCurrentNet(); +extern void printMacAddress(byte mac[]); +extern void setup_wifi(); +extern void mqtt_pub(); +extern void mqtt_reconnect(); +extern void mainWifiLoop (); + +extern bool wifi_init_flg; // Set flag after first WiFi connection +extern bool gps_fix_flg; // Set flag after first receiving a fix +extern char ssid[]; // network SSID (name) +extern char pass[]; // network password (use for WPA, or use as key for WEP) +extern int status; // the WiFi radio's status +extern const char mqtt_server[]; + +//extern WiFiClient wifiClient; +extern PubSubClient client; diff --git a/SD_GPS_MQTT/Wifi_Fcn.cpp b/SD_GPS_MQTT/Wifi_Fcn.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9a3d120069088a12382745ed6b1a2553412398ca --- /dev/null +++ b/SD_GPS_MQTT/Wifi_Fcn.cpp @@ -0,0 +1,195 @@ +#include <SPI.h> +#include <SD.h> +#include <WiFiNINA.h> +#include <Adafruit_GPS.h> +#include <PubSubClient.h> +#include "arduino_secrets.h" +#include "Wifi_Dat.h" + +bool wifi_init_flg = 0; // Set flag after first WiFi connection +bool gps_fix_flg = 0; // Set flag after first receiving a fix +char ssid[] = SECRET_SSID; // network SSID (name) +char pass[] = SECRET_PASS; // network password (use for WPA, or use as key for WEP) +int status = WL_IDLE_STATUS; // the WiFi radio's status +const char mqtt_server[] = "srv03183.soton.ac.uk"; + +// WiFi and MQTT clients +WiFiClient wifiClient; +PubSubClient client(wifiClient); + +//Adafruit_GPS GPS(&GPSSerial); +extern Adafruit_GPS GPS; + +void callback(char* topic, byte* payload, unsigned int length) { + Serial.print("Message arrived ["); + Serial.print(topic); + Serial.print("] "); + for (int i=0;i<length;i++) { + Serial.print((char)payload[i]); + } + Serial.println(); +} + +void mainWifiLoop (){ + char rcnct_ctr = 0; + char rcnct_ctr_lmt = 6; + + if (status != WL_CONNECTED) { + Serial.print("\nNot connected to WiFi\nAttempting reconnection"); + status = WiFi.begin(ssid, pass); + while( (WiFi.status() != WL_CONNECTED) && ( rcnct_ctr++ < rcnct_ctr_lmt) ){ + Serial.print("."); + delay(500); + } + if (status == WL_CONNECTED){ + Serial.println("\nConnected to WiFi"); + if (!client.connected()) { + mqtt_reconnect(); + } + else if (client.connect("arduinoClient")) { + mqtt_pub(); + } + } + else{ + WiFi.end(); + Serial.print("\n"); + } + } + else if (status == WL_CONNECTED){ + Serial.println("\nConnected to WiFi"); + if (!client.connected()) { + mqtt_reconnect(); + } + else if (client.connect("arduinoClient")) { + mqtt_pub(); + } + } +} + +void printWifiData() { + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); Serial.println(ip); // Serial.println(ip); + + // print your MAC address: + byte mac[6]; + WiFi.macAddress(mac); + Serial.print("MAC address: "); printMacAddress(mac); +} + +void printCurrentNet() { + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print the MAC address of the router you're attached to: + byte bssid[6]; + WiFi.BSSID(bssid); + Serial.print("BSSID: "); + printMacAddress(bssid); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.println(rssi); + + // print the encryption type: + byte encryption = WiFi.encryptionType(); + Serial.print("Encryption Type:"); + Serial.println(encryption, HEX); + Serial.println(); +} + +void printMacAddress(byte mac[]) { + for (int i = 5; i >= 0; i--) { + if (mac[i] < 16) { + Serial.print("0"); + } + Serial.print(mac[i], HEX); + if (i > 0) { + Serial.print(":"); + } + } + Serial.println(); +} + +void setup_wifi(){ + char wifi_init_cnt_lmt = 10; + char wifi_init_ctr = 0; + + WiFi.setTimeout(15000); + + Serial.print("\nConnecting to "); Serial.println(ssid); + WiFi.begin(ssid, pass); + + while( (WiFi.status() != WL_CONNECTED) && (wifi_init_ctr++ < wifi_init_cnt_lmt) ){ + Serial.print("."); delay(500); // Try to connect to WiFi. Limited number of attempts before time out + } + + if (WiFi.status() == WL_CONNECTED){ // Connection succeeded + randomSeed(micros()); + Serial.println("\nWiFi connected"); + printCurrentNet(); + printWifiData(); + }else if (WiFi.status() != WL_CONNECTED){ // Connection timed out + Serial.print("\nTimed out. Could not connect to "); Serial.println(ssid); + WiFi.end(); + } +} + + + +void mqtt_reconnect() { + char rcnct_ctr = 0; + char rcnct_ctr_lmt = 3; + + while ( (!client.connected()) && ( rcnct_ctr++ < rcnct_ctr_lmt) ) { + Serial.println("Attempting MQTT connection..."); + if (client.connect("arduinoClient")) { // Connection succeeded. Publish info + mqtt_pub(); + } else { // Connection failed. Wait before reattempting + Serial.print("failed, rc="); Serial.print(client.state()); + delay(800); + } + } +} + +void mqtt_pub(){ + String mqtt_timstmp, lt, ln, al; + char time_stmp[30], ant_fix[5], sat[5], qlty[5], pos_lat[10], pos_lon[10], pos_alt[10]; + char yr[5], mh[3], dy[3], hr[3], mn[3], sc[3]; + char c; + int char_ctr = 0, buf_ctr = 0; + char buff[7][60]; + + File dataFile = SD.open("gpslog.txt"); + + if (dataFile) { + while (dataFile.available()) { + c = dataFile.read(); + if (c != '\n'){ // Current line continues continues + if (c != ','){ // Current word continues + buff[buf_ctr][char_ctr++] = c; // Append newly read char to string + } else { // Word finished. Move to next word + char_ctr = 0; buf_ctr++; + } + } + else{ // Line finished. Flush to MQTT + char_ctr = 0; buf_ctr = 0; + client.publish("efss/GPS/Timestamp", buff[0]); + client.publish("efss/GPS/Fix", buff[1]); + client.publish("efss/GPS/Fix quality", buff[2]); + client.publish("efss/GPS/Satellites", buff[3]); + client.publish("efss/GPS/Longitude", buff[4]); + client.publish("efss/GPS/Latitude", buff[5]); + client.publish("efss/GPS/Altitude", buff[6]); + } + } + dataFile.close(); + } + // if the file isn't open, pop up an error: + else { + Serial.println("error opening datalog.txt"); + } + Serial.println("Published to MQTT"); +} diff --git a/SD_GPS_MQTT/arduino_secrets.h b/SD_GPS_MQTT/arduino_secrets.h new file mode 100644 index 0000000000000000000000000000000000000000..23105979fa2798039627941039aaeaf2280a59cf --- /dev/null +++ b/SD_GPS_MQTT/arduino_secrets.h @@ -0,0 +1,10 @@ +/* Home WiFi */ +/* +#define SECRET_SSID "VM2774564" +#define SECRET_PASS "vm2Lmbpjd8mx" +*/ + +/* Uni WiFi */ +/**/ +#define SECRET_SSID "SOTON-IoT" +#define SECRET_PASS "zANxkRvZHZYg"