From 0cdd8f5539254dcff508d80393be745662329964 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Thu, 13 Jun 2019 14:13:03 +0100
Subject: [PATCH] Implement GPS & microSD card functionality, but it's not
 finished or tested yet.

---
 iot/main/gps.c       |  6 ------
 iot/main/gps.cpp     | 27 +++++++++++++++++++++++++++
 iot/main/gps.h       | 12 +++++++++++-
 iot/main/main.ino    |  6 +++++-
 iot/main/random.h    |  1 +
 iot/main/settings.h  |  4 +++-
 iot/main/storage.c   | 17 -----------------
 iot/main/storage.cpp | 33 +++++++++++++++++++++++++++++++++
 8 files changed, 80 insertions(+), 26 deletions(-)
 delete mode 100644 iot/main/gps.c
 create mode 100644 iot/main/gps.cpp
 create mode 100644 iot/main/random.h
 delete mode 100644 iot/main/storage.c
 create mode 100644 iot/main/storage.cpp

diff --git a/iot/main/gps.c b/iot/main/gps.c
deleted file mode 100644
index d13e9c1..0000000
--- a/iot/main/gps.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "gps.h"
-#include "settings.h"
-
-void gps_begin() {
-	serial_gps.begin(BAUD_GPS);
-}
diff --git a/iot/main/gps.cpp b/iot/main/gps.cpp
new file mode 100644
index 0000000..52cf6a6
--- /dev/null
+++ b/iot/main/gps.cpp
@@ -0,0 +1,27 @@
+#include "gps.h"
+#include "settings.h"
+
+void gps_begin() {
+	serial_gps.begin(BAUD_GPS);
+}
+
+TinyGPSLocation gps_location() {
+	Serial.print("[gps] Getting location: ");
+	while(serial_gps.available() > 0) {
+		if(!gps.encode(serial_gps.read()))
+			continue;
+		
+		if(!gps.location.isValid() || gis.location.isUpdated()) {
+			Serial.print(".");
+			delay(100);
+			continue;
+		}
+		
+		Serial.println("ok");
+		return gps.location;
+	}
+}
+
+void gps_end() {
+	Serial.println(F("[warning] Putting the GPS device to sleep isn't implemented yet."));
+}
diff --git a/iot/main/gps.h b/iot/main/gps.h
index 95d8c39..b1b4e4d 100644
--- a/iot/main/gps.h
+++ b/iot/main/gps.h
@@ -22,4 +22,14 @@ void gps_begin();
  * May take a moment, as the GPS device needs time to acquire a satellite fix.
  * @return TinyGPSLocation	The current location.
  */
-TinyGPSLocation get_location();
+TinyGPSLocation gps_location();
+
+/**
+ * Ends the connection to the GPS device and puts it to sleep in order to save 
+ * power.
+ * Note that the GPS device is connected directly to the power management 
+ * system and so doesn't get turned off after each measurement, as it takes 
+ * ~30s to reacquire a lock when it first starts up - hence why we put it to 
+ * sleep instead.
+ */
+void gps_end();
diff --git a/iot/main/main.ino b/iot/main/main.ino
index 584c802..e4cd59e 100644
--- a/iot/main/main.ino
+++ b/iot/main/main.ino
@@ -1,4 +1,5 @@
 #include <Arduino.h>
+#include <TinyGPS++.h>
 
 #include "settings.h"
 #include "gps.h"
@@ -7,10 +8,13 @@ void setup() {
 	Serial.begin(BAUD_PC);
 	
 	gps_begin();
+	TinyGPSLocation loc = get_location();
+	gps_end();
+	
+	Serial.print("[main] Location: ("); Serial.print(loc.longitude()); Serial.print(", "); Serial.print(loc.latitude()); Serial.println();
 	
 	
 	
-	get_location();
 }
 
 void loop() {
diff --git a/iot/main/random.h b/iot/main/random.h
new file mode 100644
index 0000000..6f70f09
--- /dev/null
+++ b/iot/main/random.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/iot/main/settings.h b/iot/main/settings.h
index 982d2c2..f487a2b 100644
--- a/iot/main/settings.h
+++ b/iot/main/settings.h
@@ -29,5 +29,7 @@
 ////////// microSD Card //////////
 //////////////////////////////////
 
-// 
+// The chip select pin that activates the connection to the microSD card over SPI.
 #define	PIN_SD_SPI_CHIP_SELECT	3
+
+#define SD_FILENAME	"data.tsv"
diff --git a/iot/main/storage.c b/iot/main/storage.c
deleted file mode 100644
index 75d1196..0000000
--- a/iot/main/storage.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <Arduino.h>
-#include <SD.h>
-
-#include "settings.h"
-
-void store_init() {
-	pinMode(PIN_SPI_CHIP_SELECT, OUTPUT);
-	
-	if(!SD.begin(PIN_SPI_DATA)) {
-		Serial.println("Error: Failed to initialise connection to microSD card");
-		while(true) { delay(1); } // Pseudo-halt, but uses delay() to ensure we keep passing back control to allow easy re-programming
-	}
-}
-
-void store_reading(uint32_t id, TinyGPSLocation location) {
-	File handle;
-}
diff --git a/iot/main/storage.cpp b/iot/main/storage.cpp
new file mode 100644
index 0000000..d6b498a
--- /dev/null
+++ b/iot/main/storage.cpp
@@ -0,0 +1,33 @@
+#include <Arduino.h>
+#include <SD.h>
+
+#include "settings.h"
+
+void store_init() {
+	// NOTE: If this doesn't work, then we need to use pinMode() & specify the data pin here instead.
+	if(!SD.begin(PIN_SD_SPI_CHIP_SELECT)) {
+		Serial.println(F("Error: Failed to initialise connection to microSD card"));
+		while(true) { delay(1); } // Pseudo-halt, but uses delay() to ensure we keep passing back control to allow easy re-programming
+	}
+}
+
+void store_reading(uint32_t id, TinyGPSLocation location) {
+	// Open the file to  write the data to. If it doesn't exist it will be created.
+	// Unlike elsewhere, FILE_WRITE opens the file with the cursor starting at the end, so it's basically actually equivalent to FILE_APPEND that we use in other environments. Confusing, I know.
+	File handle = SD.open(SD_FILENAME, FILE_WRITE);
+	
+	handle.print(id);
+	handle.print("\t");
+	
+	handle.print(location.longitude());
+	handle.print("\t");
+	
+	handle.print(location.latitude());
+	handle.println();
+	
+	handle.close();
+}
+
+void store_close() {
+	SD.end();
+}
