Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: GPSLibrary GSM mbed-modifed Storage_Library Temp_Library Wakeup pH_Sensor
Revision 10:01bbf4f1c250, committed 2015-11-18
- 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;