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
main.cpp@7:92f2d8c79565, 2015-11-09 (annotated)
- Committer:
- kbaichoo
- Date:
- Mon Nov 09 19:35:59 2015 +0000
- Revision:
- 7:92f2d8c79565
- Parent:
- 6:10b0ff2803e5
got deep sleep working to get the ADC clock back
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ptcrews | 1:83d3982f32d5 | 1 | #include "Adafruit_FONA.h" |
| ptcrews | 2:8de680cf7a19 | 2 | #include "WakeUp.h" |
| ptcrews | 1:83d3982f32d5 | 3 | #include "mbed.h" |
| tomli | 5:e180c73f4f70 | 4 | #include "MBed_Adafruit_GPS.h" |
| tomli | 5:e180c73f4f70 | 5 | #include <string> |
| ptcrews | 1:83d3982f32d5 | 6 | |
| ptcrews | 1:83d3982f32d5 | 7 | #define FONA_TX D8 |
| ptcrews | 1:83d3982f32d5 | 8 | #define FONA_RX D2 |
| ptcrews | 1:83d3982f32d5 | 9 | #define FONA_RST D3 |
| ptcrews | 1:83d3982f32d5 | 10 | #define FONA_RI D4 |
| ptcrews | 1:83d3982f32d5 | 11 | #define FONA_KEY D5 |
| ptcrews | 1:83d3982f32d5 | 12 | |
| tomli | 5:e180c73f4f70 | 13 | #define GPS_TX D6 |
| tomli | 5:e180c73f4f70 | 14 | #define GPS_RX PB_11 |
| tomli | 5:e180c73f4f70 | 15 | |
| tomli | 5:e180c73f4f70 | 16 | #define PH_TX PC_10 |
| tomli | 5:e180c73f4f70 | 17 | #define PH_RX PC_11 |
| tomli | 5:e180c73f4f70 | 18 | |
| kbaichoo | 6:10b0ff2803e5 | 19 | #define TMP_ANALOG A0 |
| kbaichoo | 6:10b0ff2803e5 | 20 | #define ADC_CONVERSION 3.3/5.0 |
| ptcrews | 1:83d3982f32d5 | 21 | Adafruit_FONA fona(FONA_TX, FONA_RX, FONA_RST, FONA_RI); |
| ptcrews | 1:83d3982f32d5 | 22 | Serial pcSerial(USBTX, USBRX); |
| ptcrews | 1:83d3982f32d5 | 23 | DigitalOut key(FONA_KEY); |
| kbaichoo | 6:10b0ff2803e5 | 24 | AnalogIn temperature(TMP_ANALOG); |
| ptcrews | 1:83d3982f32d5 | 25 | |
| tomli | 5:e180c73f4f70 | 26 | // GPS |
| tomli | 5:e180c73f4f70 | 27 | char c; //when read via Adafruit_GPS::read(), the class returns single character stored here |
| tomli | 5:e180c73f4f70 | 28 | Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info? |
| tomli | 5:e180c73f4f70 | 29 | const int refresh_Time = 2000; //refresh time in ms |
| tomli | 5:e180c73f4f70 | 30 | Serial gps_Serial(GPS_TX, GPS_RX); // Serial object for GPS |
| tomli | 5:e180c73f4f70 | 31 | Adafruit_GPS myGPS(&gps_Serial); |
| tomli | 5:e180c73f4f70 | 32 | |
| tomli | 5:e180c73f4f70 | 33 | |
| tomli | 5:e180c73f4f70 | 34 | |
| tomli | 5:e180c73f4f70 | 35 | // pH sensor |
| tomli | 5:e180c73f4f70 | 36 | Serial ph_Serial (PH_TX, PH_RX); |
| tomli | 5:e180c73f4f70 | 37 | string sensorstring = ""; |
| tomli | 5:e180c73f4f70 | 38 | bool input_stringcomplete = false; |
| tomli | 5:e180c73f4f70 | 39 | bool sensor_stringcomplete = false; |
| tomli | 5:e180c73f4f70 | 40 | float pH; |
| tomli | 5:e180c73f4f70 | 41 | |
| tomli | 5:e180c73f4f70 | 42 | void setupPCSerial() { |
| tomli | 5:e180c73f4f70 | 43 | //pcSerial.baud(9600); // This is what the pH sensor used to have. |
| tomli | 5:e180c73f4f70 | 44 | pcSerial.baud(115200); |
| tomli | 5:e180c73f4f70 | 45 | pcSerial.printf("\n\nConnection established at 115200 baud...\n"); |
| tomli | 5:e180c73f4f70 | 46 | } |
| tomli | 5:e180c73f4f70 | 47 | |
| tomli | 5:e180c73f4f70 | 48 | void setupPH() { |
| tomli | 5:e180c73f4f70 | 49 | ph_Serial.baud(9600); |
| tomli | 5:e180c73f4f70 | 50 | printf("Disabling continous mode.\n"); |
| tomli | 5:e180c73f4f70 | 51 | if(ph_Serial.writeable() <= 0) printf("Not writable\n"); |
| tomli | 5:e180c73f4f70 | 52 | // disable continuous mode |
| tomli | 5:e180c73f4f70 | 53 | ph_Serial.printf("C,0"); |
| tomli | 5:e180c73f4f70 | 54 | ph_Serial.printf("%c", '\r'); |
| tomli | 5:e180c73f4f70 | 55 | printf("Waiting five seconds... "); |
| tomli | 5:e180c73f4f70 | 56 | wait(5); |
| tomli | 5:e180c73f4f70 | 57 | printf("done\n"); |
| tomli | 5:e180c73f4f70 | 58 | } |
| tomli | 5:e180c73f4f70 | 59 | |
| tomli | 5:e180c73f4f70 | 60 | void setupGPS() { |
| tomli | 5:e180c73f4f70 | 61 | myGPS.begin(9600); |
| tomli | 5:e180c73f4f70 | 62 | myGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //these commands are defined in MBed_Adafruit_GPS.h; a link is provided there for command creation |
| tomli | 5:e180c73f4f70 | 63 | myGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); |
| tomli | 5:e180c73f4f70 | 64 | myGPS.sendCommand(PGCMD_ANTENNA); |
| tomli | 5:e180c73f4f70 | 65 | wait(1); |
| tomli | 5:e180c73f4f70 | 66 | refresh_Timer.start(); //starts the clock on the timer |
| tomli | 5:e180c73f4f70 | 67 | printf("setupGPS seems to be fine\n"); |
| tomli | 5:e180c73f4f70 | 68 | } |
| tomli | 5:e180c73f4f70 | 69 | |
| tomli | 5:e180c73f4f70 | 70 | void setup() { |
| tomli | 5:e180c73f4f70 | 71 | printf("\n=====\nSetup in Full Project\n"); |
| tomli | 5:e180c73f4f70 | 72 | setupPCSerial(); |
| tomli | 5:e180c73f4f70 | 73 | setupPH(); |
| tomli | 5:e180c73f4f70 | 74 | setupGPS(); |
| tomli | 5:e180c73f4f70 | 75 | } |
| tomli | 5:e180c73f4f70 | 76 | |
| tomli | 5:e180c73f4f70 | 77 | // Send default message to pH sensor, asking for data. |
| tomli | 5:e180c73f4f70 | 78 | void pHRequest() { |
| tomli | 5:e180c73f4f70 | 79 | printf("Sending pH request...\n"); |
| tomli | 5:e180c73f4f70 | 80 | if(ph_Serial.writeable() <= 0) printf("Not writable\n"); |
| tomli | 5:e180c73f4f70 | 81 | // request one reading |
| tomli | 5:e180c73f4f70 | 82 | ph_Serial.printf("R"); |
| tomli | 5:e180c73f4f70 | 83 | ph_Serial.printf("%c", '\r'); |
| tomli | 5:e180c73f4f70 | 84 | } |
| tomli | 5:e180c73f4f70 | 85 | |
| tomli | 5:e180c73f4f70 | 86 | void pHRead() { |
| tomli | 5:e180c73f4f70 | 87 | printf("Reading pH information.\n"); |
| tomli | 5:e180c73f4f70 | 88 | if (ph_Serial.readable() > 0) { //if we see that the Atlas Scientific product has sent a character. |
| tomli | 5:e180c73f4f70 | 89 | printf("Receiving sensor string... ["); |
| tomli | 5:e180c73f4f70 | 90 | char inchar; |
| tomli | 5:e180c73f4f70 | 91 | while((inchar = (char)ph_Serial.getc()) != '\r') { |
| tomli | 5:e180c73f4f70 | 92 | sensorstring += inchar; |
| tomli | 5:e180c73f4f70 | 93 | printf("%c", inchar); |
| tomli | 5:e180c73f4f70 | 94 | } |
| tomli | 5:e180c73f4f70 | 95 | printf("] ...sensor string received!\n"); |
| tomli | 5:e180c73f4f70 | 96 | sensor_stringcomplete = true; |
| tomli | 5:e180c73f4f70 | 97 | pH = atof(sensorstring.c_str()); //convert the string to a floating point number so it can be evaluated by the Arduino |
| tomli | 5:e180c73f4f70 | 98 | |
| tomli | 5:e180c73f4f70 | 99 | if (pH >= 7.0) { //if the pH is greater than or equal to 7.0 |
| tomli | 5:e180c73f4f70 | 100 | printf("high\n"); //print "high" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string |
| tomli | 5:e180c73f4f70 | 101 | } |
| tomli | 5:e180c73f4f70 | 102 | |
| tomli | 5:e180c73f4f70 | 103 | if (pH <= 6.999) { //if the pH is less than or equal to 6.999 |
| tomli | 5:e180c73f4f70 | 104 | printf("low\n"); //print "low" this is demonstrating that the Arduino is evaluating the pH as a number and not as a string |
| tomli | 5:e180c73f4f70 | 105 | } |
| tomli | 5:e180c73f4f70 | 106 | |
| tomli | 5:e180c73f4f70 | 107 | //ph_Serial.printf("SLEEP"); |
| tomli | 5:e180c73f4f70 | 108 | //ph_Serial.printf("%c", '\r'); |
| tomli | 5:e180c73f4f70 | 109 | |
| tomli | 5:e180c73f4f70 | 110 | sensorstring = ""; //clear the string: |
| tomli | 5:e180c73f4f70 | 111 | sensor_stringcomplete = false; //reset the flag used to tell if we have received a completed string from the Atlas Scientific product |
| tomli | 5:e180c73f4f70 | 112 | } else { |
| tomli | 5:e180c73f4f70 | 113 | printf("pH sensor is not readable\n"); |
| tomli | 5:e180c73f4f70 | 114 | } |
| tomli | 5:e180c73f4f70 | 115 | } |
| tomli | 5:e180c73f4f70 | 116 | |
| kbaichoo | 6:10b0ff2803e5 | 117 | //function to get both the |
| kbaichoo | 6:10b0ff2803e5 | 118 | double AD22100K_AI_value_to_Celsius() { // Convert Analog-input value to temperature |
| kbaichoo | 6:10b0ff2803e5 | 119 | //1023 is to scale it up to the arduino read values. |
| kbaichoo | 6:10b0ff2803e5 | 120 | float voltage = (int)((temperature.read() * ADC_CONVERSION) * 1023); |
| kbaichoo | 6:10b0ff2803e5 | 121 | |
| kbaichoo | 6:10b0ff2803e5 | 122 | float temperatureValue = (voltage * 0.217226044) - 61.1111111; // conversion factor simplified. |
| kbaichoo | 6:10b0ff2803e5 | 123 | pcSerial.printf("AI_Val: %f\n", temperatureValue); |
| kbaichoo | 6:10b0ff2803e5 | 124 | return temperatureValue; // 22.5 mV / °C; Ratiometric measurement, conversion valid for 5 V! |
| kbaichoo | 6:10b0ff2803e5 | 125 | } |
| kbaichoo | 7:92f2d8c79565 | 126 | |
| kbaichoo | 7:92f2d8c79565 | 127 | //Found this online and it claims that it resets ADC to work after deepsleep \_O_/ |
| kbaichoo | 7:92f2d8c79565 | 128 | void resetADC() |
| kbaichoo | 7:92f2d8c79565 | 129 | { |
| kbaichoo | 7:92f2d8c79565 | 130 | // Enable the HSI (to clock the ADC) |
| kbaichoo | 7:92f2d8c79565 | 131 | RCC_OscInitTypeDef RCC_OscInitStruct; |
| kbaichoo | 7:92f2d8c79565 | 132 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; |
| kbaichoo | 7:92f2d8c79565 | 133 | RCC_OscInitStruct.HSIState = RCC_HSI_ON; |
| kbaichoo | 7:92f2d8c79565 | 134 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; |
| kbaichoo | 7:92f2d8c79565 | 135 | HAL_RCC_OscConfig(&RCC_OscInitStruct); |
| kbaichoo | 7:92f2d8c79565 | 136 | } |
| kbaichoo | 6:10b0ff2803e5 | 137 | |
| tomli | 5:e180c73f4f70 | 138 | // n_queries is the number of times we query the GPS. We need something like 23000 characters. |
| tomli | 5:e180c73f4f70 | 139 | void GPSRead(int n_queries) { |
| tomli | 5:e180c73f4f70 | 140 | pcSerial.printf("\n"); |
| tomli | 5:e180c73f4f70 | 141 | for (int i = 0; i < n_queries; i++) { |
| tomli | 5:e180c73f4f70 | 142 | c = myGPS.read(); //queries the GPS |
| tomli | 5:e180c73f4f70 | 143 | |
| tomli | 5:e180c73f4f70 | 144 | if (c) { pcSerial.printf("%c", c); } //this line will echo the GPS data if not paused |
| tomli | 5:e180c73f4f70 | 145 | |
| tomli | 5:e180c73f4f70 | 146 | //check if we recieved a new message from GPS, if so, attempt to parse it, |
| tomli | 5:e180c73f4f70 | 147 | if ( myGPS.newNMEAreceived() ) { |
| tomli | 5:e180c73f4f70 | 148 | if ( !myGPS.parse(myGPS.lastNMEA()) ) { |
| tomli | 5:e180c73f4f70 | 149 | continue; |
| tomli | 5:e180c73f4f70 | 150 | } |
| tomli | 5:e180c73f4f70 | 151 | } |
| tomli | 5:e180c73f4f70 | 152 | |
| tomli | 5:e180c73f4f70 | 153 | //check if enough time has passed to warrant printing GPS info to screen |
| tomli | 5:e180c73f4f70 | 154 | //note if refresh_Time is too low or pcSerial.baud is too low, GPS data may be lost during printing |
| tomli | 5:e180c73f4f70 | 155 | if (refresh_Timer.read_ms() >= refresh_Time) { |
| tomli | 5:e180c73f4f70 | 156 | refresh_Timer.reset(); |
| tomli | 5:e180c73f4f70 | 157 | pcSerial.printf("Time: %d:%d:%d.%u\n", myGPS.hour, myGPS.minute, myGPS.seconds, myGPS.milliseconds); |
| tomli | 5:e180c73f4f70 | 158 | pcSerial.printf("Date: %d/%d/20%d\n", myGPS.day, myGPS.month, myGPS.year); |
| tomli | 5:e180c73f4f70 | 159 | pcSerial.printf("Fix: %d\n", (int) myGPS.fix); |
| tomli | 5:e180c73f4f70 | 160 | pcSerial.printf("Quality: %d\n", (int) myGPS.fixquality); |
| tomli | 5:e180c73f4f70 | 161 | if (myGPS.fix) { |
| tomli | 5:e180c73f4f70 | 162 | pcSerial.printf("Location: %5.2f%c, %5.2f%c\n", myGPS.latitude, myGPS.lat, myGPS.longitude, myGPS.lon); |
| tomli | 5:e180c73f4f70 | 163 | pcSerial.printf("Speed: %5.2f knots\n", myGPS.speed); |
| tomli | 5:e180c73f4f70 | 164 | pcSerial.printf("Angle: %5.2f\n", myGPS.angle); |
| tomli | 5:e180c73f4f70 | 165 | pcSerial.printf("Altitude: %5.2f\n", myGPS.altitude); |
| tomli | 5:e180c73f4f70 | 166 | pcSerial.printf("Satellites: %d\n", myGPS.satellites); |
| tomli | 5:e180c73f4f70 | 167 | } |
| tomli | 5:e180c73f4f70 | 168 | } |
| tomli | 5:e180c73f4f70 | 169 | } |
| tomli | 5:e180c73f4f70 | 170 | pcSerial.printf("\n"); |
| tomli | 5:e180c73f4f70 | 171 | } |
| tomli | 5:e180c73f4f70 | 172 | |
| ptcrews | 3:6afcf4f3b2aa | 173 | void setupGSM() |
| ptcrews | 3:6afcf4f3b2aa | 174 | { |
| ptcrews | 3:6afcf4f3b2aa | 175 | printf("Starting FONA\n"); |
| ptcrews | 3:6afcf4f3b2aa | 176 | while(!fona.begin(9600)) { |
| ptcrews | 3:6afcf4f3b2aa | 177 | printf("Cannot find FONA\n"); |
| ptcrews | 3:6afcf4f3b2aa | 178 | wait(1); |
| ptcrews | 3:6afcf4f3b2aa | 179 | } |
| ptcrews | 3:6afcf4f3b2aa | 180 | fona.begin(9600); |
| ptcrews | 3:6afcf4f3b2aa | 181 | fona.setGPRSNetworkSettings("pwg", "", ""); |
| ptcrews | 3:6afcf4f3b2aa | 182 | bool enable = false; |
| ptcrews | 3:6afcf4f3b2aa | 183 | while(enable != true) { |
| ptcrews | 3:6afcf4f3b2aa | 184 | fona.enableGPRS(true); |
| ptcrews | 3:6afcf4f3b2aa | 185 | fona.enableGPRS(false); |
| ptcrews | 3:6afcf4f3b2aa | 186 | enable = fona.enableGPRS(true); |
| ptcrews | 3:6afcf4f3b2aa | 187 | } |
| ptcrews | 3:6afcf4f3b2aa | 188 | } |
| ptcrews | 3:6afcf4f3b2aa | 189 | |
| ptcrews | 2:8de680cf7a19 | 190 | void changeGSMPowerState() |
| ptcrews | 1:83d3982f32d5 | 191 | { |
| ptcrews | 1:83d3982f32d5 | 192 | key.write(0); |
| ptcrews | 1:83d3982f32d5 | 193 | wait(2); |
| ptcrews | 1:83d3982f32d5 | 194 | key.write(1); |
| ptcrews | 1:83d3982f32d5 | 195 | } |
| ptcrews | 1:83d3982f32d5 | 196 | |
| ptcrews | 3:6afcf4f3b2aa | 197 | void enterSleep(int msec) |
| ptcrews | 3:6afcf4f3b2aa | 198 | { |
| ptcrews | 2:8de680cf7a19 | 199 | if(msec > 0) WakeUp::set_ms(msec); |
| ptcrews | 2:8de680cf7a19 | 200 | deepsleep(); |
| kbaichoo | 7:92f2d8c79565 | 201 | resetADC(); |
| ptcrews | 2:8de680cf7a19 | 202 | } |
| ptcrews | 3:6afcf4f3b2aa | 203 | |
| tomli | 5:e180c73f4f70 | 204 | bool sendDataOverHTTP(char* url, char* data) |
| ptcrews | 3:6afcf4f3b2aa | 205 | { |
| ptcrews | 3:6afcf4f3b2aa | 206 | uint16_t statuscode; |
| ptcrews | 3:6afcf4f3b2aa | 207 | int16_t length; |
| ptcrews | 3:6afcf4f3b2aa | 208 | if (!fona.HTTP_POST_start(url, "text/plain", (uint8_t *) data, strlen(data), &statuscode, (uint16_t *)&length)) { |
| ptcrews | 3:6afcf4f3b2aa | 209 | pcSerial.printf("Failed!\r\n"); |
| ptcrews | 3:6afcf4f3b2aa | 210 | return false; |
| ptcrews | 3:6afcf4f3b2aa | 211 | } |
| ptcrews | 3:6afcf4f3b2aa | 212 | while (length > 0) { |
| ptcrews | 3:6afcf4f3b2aa | 213 | while (fona.readable()) { |
| ptcrews | 3:6afcf4f3b2aa | 214 | char c = fona.getc(); |
| ptcrews | 3:6afcf4f3b2aa | 215 | pcSerial.putc(c); |
| ptcrews | 3:6afcf4f3b2aa | 216 | length--; |
| ptcrews | 3:6afcf4f3b2aa | 217 | if (! length) break; |
| ptcrews | 3:6afcf4f3b2aa | 218 | } |
| ptcrews | 3:6afcf4f3b2aa | 219 | } |
| ptcrews | 3:6afcf4f3b2aa | 220 | pcSerial.printf("\r\n****\r\n"); |
| ptcrews | 3:6afcf4f3b2aa | 221 | fona.HTTP_POST_end(); |
| ptcrews | 3:6afcf4f3b2aa | 222 | return true; |
| ptcrews | 3:6afcf4f3b2aa | 223 | } |
| ptcrews | 2:8de680cf7a19 | 224 | |
| ptcrews | 1:83d3982f32d5 | 225 | int main() |
| ptcrews | 1:83d3982f32d5 | 226 | { |
| tomli | 5:e180c73f4f70 | 227 | setup(); |
| ptcrews | 2:8de680cf7a19 | 228 | changeGSMPowerState(); |
| ptcrews | 3:6afcf4f3b2aa | 229 | setupGSM(); |
| ptcrews | 3:6afcf4f3b2aa | 230 | //sendDataOverHTTP("http://requestb.in/10pbl2i1", "testing"); |
| ptcrews | 3:6afcf4f3b2aa | 231 | |
| ptcrews | 2:8de680cf7a19 | 232 | changeGSMPowerState(); |
| tomli | 5:e180c73f4f70 | 233 | while (true) { |
| tomli | 5:e180c73f4f70 | 234 | printf("~~~~~[pH]~~~~~\n"); |
| tomli | 5:e180c73f4f70 | 235 | pHRequest(); |
| tomli | 5:e180c73f4f70 | 236 | pHRead(); |
| tomli | 5:e180c73f4f70 | 237 | wait(1); |
| tomli | 5:e180c73f4f70 | 238 | printf("~~~~~[GPS]~~~~\n"); |
| tomli | 5:e180c73f4f70 | 239 | |
| tomli | 5:e180c73f4f70 | 240 | GPSRead(300000); |
| tomli | 5:e180c73f4f70 | 241 | wait(1); |
| tomli | 5:e180c73f4f70 | 242 | } |
| ptcrews | 1:83d3982f32d5 | 243 | |
| ptcrews | 1:83d3982f32d5 | 244 | return 0; |
| ptcrews | 1:83d3982f32d5 | 245 | } |