Flotsam / Full-Project

Dependencies:   GPSLibrary GSM mbed-modifed Storage_Library Temp_Library Wakeup pH_Sensor

Files at this revision

API Documentation at this revision

Comitter:
tomli
Date:
Wed Nov 18 18:45:50 2015 +0000
Parent:
9:b6e9751fbcba
Child:
11:cc22917d6634
Commit message:
Now saves data as structs and sends information to website

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Nov 09 20:00:42 2015 +0000
+++ b/main.cpp	Wed Nov 18 18:45:50 2015 +0000
@@ -19,11 +19,30 @@
 #define PH_TX PC_10
 #define PH_RX PC_11
 
+#define TMP_ANALOG A0
+#define ADC_CONVERSION 3.3/5.0
+AnalogIn temperature(TMP_ANALOG);
+
+#define READINGSIZE sizeof(struct reading)
+#define URL "http://requestb.in/um8rhrum"
+
 // Cellular communication global variables
 Adafruit_FONA fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI);
 Serial pcSerial(USBTX, USBRX);
 DigitalOut key(FONA_KEY);
 
+struct reading {
+    float temperature;
+    float pH;
+    float latitude;     //Signed positive if N, negative if S
+    float longitude;    //Signed positive if E, negative if W
+    uint8_t day;
+    uint8_t month;
+    uint8_t year;
+    uint8_t hour;
+    uint8_t minutes;
+};
+
 // GPS global variables
 char c; //when read via Adafruit_GPS::read(), the class returns single character stored here
 Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info?
@@ -38,6 +57,8 @@
 bool sensor_stringcomplete = false;
 float pH;
 
+struct reading lastReadingBuffer;
+
 void setupPCSerial() {
     pcSerial.baud(115200);
     pcSerial.printf("\n\n PC Serial connection established at 115200 baud.\n");
@@ -95,7 +116,9 @@
         }
         printf("] ...sensor string received!\n");
         sensor_stringcomplete = true;
-        pH = atof(sensorstring.c_str());                      //convert the string to a floating point number so it can be evaluated by the Arduino
+        printf(sensorstring.c_str());
+        // +1 is to get rid of control character
+        pH = atof(sensorstring.c_str()+1);                      //convert the string to a floating point number so it can be evaluated by the Arduino
 
         if (pH >= 7.0) {                                  //if the pH is greater than or equal to 7.0
             printf("high\n");                         //print "high" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string
@@ -138,7 +161,23 @@
             pcSerial.printf("Date: %d/%d/20%d\n", myGPS.day, myGPS.month, myGPS.year);
             pcSerial.printf("Fix: %d\n", (int) myGPS.fix);
             pcSerial.printf("Quality: %d\n", (int) myGPS.fixquality);
+            
+            lastReadingBuffer.hour = myGPS.hour;
+            lastReadingBuffer.minutes = myGPS.minute;
+            lastReadingBuffer.day = myGPS.day;
+            lastReadingBuffer.month = myGPS.month;
+            lastReadingBuffer.year = myGPS.year;
+            lastReadingBuffer.latitude = 0.0;
+            lastReadingBuffer.longitude = 0.0;
             if (myGPS.fix) {
+                float mylatitude = myGPS.latitude;
+                if(myGPS.lat == 'S')
+                    mylatitude *= -1;
+                float mylongitude = myGPS.longitude;
+                if(myGPS.lon == 'W')
+                    mylongitude *= -1;
+                lastReadingBuffer.latitude = mylatitude;
+                lastReadingBuffer.longitude = mylongitude;
                 pcSerial.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon);
                 pcSerial.printf("Speed: %5.2f knots\n", myGPS.speed);
                 pcSerial.printf("Angle: %5.2f\n", myGPS.angle);
@@ -174,17 +213,29 @@
     key.write(1);
 }
 
+//Found this online and it claims that it resets ADC to work after deepsleep \_O_/
+void resetADC()
+{
+    // Enable the HSI (to clock the ADC)
+    RCC_OscInitTypeDef RCC_OscInitStruct;
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+    RCC_OscInitStruct.HSIState       = RCC_HSI_ON;
+    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE;
+    HAL_RCC_OscConfig(&RCC_OscInitStruct);  
+}
+
 void enterSleep(int msec)
 {
     if(msec > 0) WakeUp::set_ms(msec);
     deepsleep();
+    resetADC();
 }
 
-bool sendDataOverHTTP(char* url, char* data)
+bool sendDataOverHTTP(char* url, uint8_t* data, int dlength)
 {
     uint16_t statuscode;
     int16_t length;
-    if (!fona.HTTP_POST_start(url, "text/plain", (uint8_t *) data, strlen(data), &statuscode, (uint16_t *)&length)) {
+    if (!fona.HTTP_POST_start(url, "text/plain", data, dlength, &statuscode, (uint16_t *)&length)) {
         pcSerial.printf("Failed!\r\n");
         return false;
     }
@@ -201,6 +252,88 @@
     return true;
 }
 
+//define where the EEPROM begins
+#define stadr 0x08080000
+
+//Our current offset in the EEPROM
+int offset = 0;
+int roffset = 0;
+
+//This function writes a byte of data to the EEPROM at the appropriate location.
+//This is called by my writeEEPROMbytes.
+//Use this if you want to write a single byte.
+HAL_StatusTypeDef writeEEPROMByte(uint8_t data)
+ {
+    HAL_StatusTypeDef  status;
+    int address = offset + stadr;
+    offset++;
+    HAL_FLASHEx_DATAEEPROM_Unlock();  //Unprotect the EEPROM to allow writing
+    status = HAL_FLASHEx_DATAEEPROM_Program(TYPEPROGRAMDATA_BYTE, address, data);
+    HAL_FLASHEx_DATAEEPROM_Lock();  // Reprotect the EEPROM
+    return status;
+}
+
+//This function takes an array of bytes and its size and writes them to the EEPROM
+//Use this if you want to write a lot of bytes.
+void writeEEPROMbytes(uint8_t* data, uint8_t size)
+{
+    for(int i = 0; i < size; i++)
+    {
+        writeEEPROMByte(data[i]);
+    }
+}
+
+//This function reads a byte of data from the EEPROM at the offset passed in.
+//This is called by my getEEPROM function
+uint8_t readEEPROMByte(uint32_t off) {
+    uint8_t tmp = 0;
+    off = off + stadr;
+    tmp = *(__IO uint32_t*)off;
+    
+    return tmp;
+}
+
+//Call this function when you have sent all the data in the EEPROM through GSM
+//It just resets the offset to 0 so we start writing from the start.
+void resetEEPROM()
+{
+    offset = 0;
+}
+
+//This takes an array of bytes an fills it with our entire EEPROM
+//Call this function when you want to send the data over GSM
+void getEEPROM(uint8_t *ptr)
+{
+    int nbytes = offset;
+    printf("The number of bytes in the EEPROM is %d\n", nbytes);
+    for(int i = 0; i < nbytes; i++)
+    {
+        ptr[i] = readEEPROMByte(i);
+    }
+    //printf("WARNING DEBUG CODE BREAKS THINGS");
+    //roffset += nbytes;
+    return;
+}
+
+//function to get both the 
+float AD22100K_AI_value_to_Celsius() {                                               // Convert Analog-input value to temperature
+  //1023 is to scale it up to the arduino read values.
+  float voltage = (int)((temperature.read() * ADC_CONVERSION) * 1023);
+   
+  float temperatureValue = (voltage * 0.217226044) - 61.1111111; // conversion factor simplified.
+  pcSerial.printf("AI_Val: %f\n", temperatureValue);
+  lastReadingBuffer.temperature = temperatureValue;
+  return temperatureValue;       // 22.5 mV / °C; Ratiometric measurement, conversion valid for 5 V!
+}
+
+bool sendDataToURL(uint8_t* data, int nreadings)
+{
+    changeGSMPowerState();
+    setupGSM();
+    bool res = sendDataOverHTTP(URL, data, nreadings * READINGSIZE);
+    changeGSMPowerState();    
+    return res;
+}
 
 // In the final version of this code:
 // We wake up ten times an hour to record information from our sensors.
@@ -215,7 +348,7 @@
 //  - pH sensor?
 //    There's a sleep command
 //  - Temperature sensor?
-//
+//    Should automatically switch on / off when the nucleo enters deep sleep mode.
 //  - GSM?
 //    The enable pin is modified by changeGSMPowerStat();
 // TODO: Web communication
@@ -224,21 +357,68 @@
 int main()
 {
     setup();
-    
-    changeGSMPowerState();
-    setupGSM();
-    //sendDataOverHTTP("http://requestb.in/10pbl2i1", "testing");
-    
-    changeGSMPowerState();
+    int nreadings = 0;
+    bool toSend = false;
     while (true) {
         printf("~~~~~[pH]~~~~~\n");
         pHRequest();
         pHRead();
+        lastReadingBuffer.pH = pH;
         wait(1);
-        printf("~~~~~[GPS]~~~~\n");
-        
+        printf("~~~~~[GPS]~~~~~\n");
         GPSRead(300000);
         wait(1);
+        printf("~~~~~[Temperature]~~~~~\n");
+        AD22100K_AI_value_to_Celsius();
+        wait(1);
+        writeEEPROMbytes((uint8_t *) &lastReadingBuffer, READINGSIZE);
+        nreadings++;
+        if(nreadings == 1)
+            toSend = true;
+        if(toSend) {
+            struct reading* data = new struct reading[nreadings];
+            getEEPROM((uint8_t*) data);
+            for(int i = 0; i < nreadings; i++)
+            {
+                for (int j = 0; j < READINGSIZE; j++) {
+                    char current_character = ((char*) (data + i))[j];
+                    for (int k = 7; k >= 0; k--) {
+                        char mask = 1;
+                        mask = mask << k;
+                        if (mask & current_character) {
+                            printf("1");
+                        } else {
+                            printf("0");
+                        }
+                    }    
+                    printf("%c\n", current_character);
+                }
+                printf("pH is %f\n", data[i].pH);
+                printf("Temperature is %f\n", data[i].temperature);
+            }
+            printf("HERE\n");
+            bool res = sendDataToURL((uint8_t*) data, nreadings);   
+            if(res) {
+                toSend = false;
+                nreadings = 0;
+                resetEEPROM();
+            }
+            delete[] data;
+        }
+        /*
+        printf("Reading Size is %d\n", READINGSIZE);
+        printf("ROM Latitude: %f\n", verifier.latitude);
+        printf("ROM Longitude: %f\n", verifier.longitude);
+        printf("ROM pH: %f\n", verifier.pH);
+        printf("ROM Temperature: %f\n", verifier.temperature);
+        printf("ROM Day: %d\n", verifier.day);
+        printf("ROM Month: %d\n", verifier.month);
+        printf("ROM Year: %d\n", verifier.year);
+        printf("ROM Hour: %d\n", verifier.hour);
+        printf("ROM Minutes: %d\n", verifier.minutes);
+        */
+        wait(2);
+        enterSleep(10000);
     }
 
     return 0;