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"