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: ESP8266_AT NCP5623BMUTBG mbed ADS1115 AOD_Calculation BME280 PMS5003 SunPosition CAM_M8
main.cpp
00001 #include "mbed.h" 00002 #include "NCP5623BMUTBG.h" 00003 #include "ESP8266_AT.h" 00004 #include "SunPosition.h" 00005 #include "AOD_Calculation.h" 00006 #include "Adafruit_ADS1015.h" 00007 #include "BME280.h" 00008 #include "CAM_M8.h" 00009 00010 ///////////////////////////////////////////// 00011 //LED colors 00012 ///////////////////////////////////////////// 00013 #define M_SET_LED_OFF() RGB_LED.set_led(0,0,0) 00014 #define M_SET_LED_RED() RGB_LED.set_led(1,0,0) 00015 #define M_SET_LED_GREEN() RGB_LED.set_led(0,1,0) 00016 #define M_SET_LED_BLUE() RGB_LED.set_led(0,0,1) 00017 #define M_SET_LED_MAGENTA() RGB_LED.set_led(1,0,1) 00018 #define M_SET_LED_YELLOW() RGB_LED.set_led(1,1,0) 00019 #define M_SET_LED_CYAN() RGB_LED.set_led(0,1,1) 00020 #define M_SET_LED_WHITE() RGB_LED.set_led(1,1,1) 00021 00022 ///////////////////////////////////////////// 00023 //Define core buses and pin states. 00024 ///////////////////////////////////////////// 00025 I2C i2c(PB_9, PB_8);//(D14, D15); SDA,SCL 00026 Serial pc(USBTX, USBRX); 00027 DigitalOut pumps(PA_9, 0);//(D8, 0); 00028 DigitalOut pbKill(PC_12, 1); // Digital input pin that conncect to the LTC2950 battery charger used to shutdown the UPAS 00029 DigitalIn nINT(PA_15); //Connected but currently unused is a digital ouput pin from LTC2950 battery charger. http://cds.linear.com/docs/en/datasheet/295012fd.pdf 00030 NCP5623BMUTBG RGB_LED(PB_9, PB_8); //(D14, D15); 00031 00032 ///////////////////////////////////////////// 00033 //RN4677 BT/BLE Module 00034 ///////////////////////////////////////////// 00035 Serial ble(PB_10, PB_11); 00036 DigitalOut bleRTS(PB_14, 0); 00037 DigitalOut bleCTS(PB_13, 0); 00038 DigitalOut BT_IRST(PC_8, 0); 00039 DigitalOut BT_SW(PA_12, 0); 00040 00041 ///////////////////////////////////////////// 00042 //Analog to Digital Converter 00043 ///////////////////////////////////////////// 00044 DigitalIn ADS_ALRT(PA_10); //Connected but currently unused. (ADS1115) http://www.ti.com/lit/ds/symlink/ads1115.pdf 00045 00046 ///////////////////////////////////////////// 00047 //Battery, Charger, & Supply Monitoring 00048 ///////////////////////////////////////////// 00049 DigitalIn LTCALT(PB_2); //High for normal operation. Low when a threshold is exceeded for Voltage, gas gauge, or temp 00050 DigitalIn bcs1(PC_9); //Batt charging if High. (BQ24100)[U23] 00051 DigitalIn bcs2(PA_8); //Charge complete if High. (BQ24100)[U23] 00052 DigitalIn bc_npg(PB_1); //Power to the charge controller. (BQ24100)[U23] 00053 DigitalIn SW3flt(PC_4); //When EN = 0 pin is HIGH, When EN = 1, LOW can be current limit, thermal limit, or UVLO. 00054 00055 ///////////////////////////////////////////// 00056 //Sensirion SDP3X(s) 00057 ///////////////////////////////////////////// 00058 DigitalIn SDP3Xflt(PC_0); 00059 DigitalIn SDP3XAltflt(PB_7); 00060 00061 ///////////////////////////////////////////// 00062 //Accelerometer and Magnometer 00063 ///////////////////////////////////////////// 00064 DigitalOut iNemoEnable(PA_1, 0); 00065 DigitalIn iNemoReady(PB_0); 00066 DigitalIn iNemoInt1(PC_5); 00067 DigitalIn iNemoInt2(PC_6); 00068 DigitalIn iNemoInt3(PC_7); 00069 00070 ///////////////////////////////////////////// 00071 //UV and Visible Light Sensor 00072 ///////////////////////////////////////////// 00073 00074 ///////////////////////////////////////////// 00075 //GPS 00076 ///////////////////////////////////////////// 00077 DigitalOut gpsEN(PB_15, 0); 00078 CAM_M8 gps(PB_9, PB_8,(0x84)); 00079 uint8_t gpsBTState = 1; 00080 uint8_t meState = 0; 00081 DigitalIn gpsENFault(PB_12); //When EN = 0 pin is HIGH, When EN = 1, LOW can be current limit, thermal limit, or UVLO. 00082 00083 00084 ///////////////////////////////////////////// 00085 //SD Card 00086 ///////////////////////////////////////////// 00087 DigitalIn sdCD(PA_11); 00088 DigitalOut sdClk(PB_3,0 ); 00089 DigitalIn sdMISO(PB_4); 00090 DigitalOut sdMOSI(PB_5, 0); 00091 DigitalOut sdCS(PB_6, 1); 00092 00093 DigitalIn pbIso(PA_0); 00094 DigitalOut hFault1(PA_7, 0); 00095 DigitalOut hFault2(PA_6, 0); 00096 DigitalOut hFault3(PA_5, 0); 00097 DigitalOut hFault4(PA_4, 0); 00098 00099 DigitalOut wifiNReset(PC_1, 0); 00100 DigitalOut wifiEnable(PC_2, 0); 00101 DigitalOut qdEnable(PC_3, 0); 00102 DigitalIn qdFault(PC_13); 00103 00104 ///////////////////////////////////////////// 00105 //AOD Objects 00106 ///////////////////////////////////////////// 00107 SunPosition sun; 00108 AOD_Calculation aod_440; 00109 AOD_Calculation aod_870; 00110 AOD_Calculation aod_680; 00111 AOD_Calculation aod_520; 00112 Adafruit_ADS1115 ads_sun(&i2c, ADS1015_ADDRESS_VDD); //Adress pin connected to 3.3V 00113 BME280 bme(PB_9, PB_8, 0xEC); //(D14, D15); 00114 00115 ESP8266_AT esp(PC_10, PC_11); 00116 00117 Timer t; 00118 00119 char ssid[] = "w212lab"; 00120 char password[] = "testarduino"; 00121 //char ssid[] = "VOLTAR"; 00122 //char password[] = "CedhCedh"; 00123 00124 char server[] = "api.thingspeak.com"; 00125 char apiKey[] = "32QVSK5INPPAVIV0"; 00126 char conn_type[] = "TCP"; 00127 00128 // For selecting the WiFi UART 00129 const int addr = 0x3F << 1; 00130 char aod_sel_5on[1]; 00131 char aod_sel_5off[1]; 00132 char plant_sel[1]; 00133 00134 //GPS Variables 00135 bool gpsReady = 0; 00136 uint8_t gpsquality = 0; 00137 uint8_t gpssatellites = 0; 00138 double gpsspeed = 0.0; 00139 //double gpscourse = 0.0; 00140 double gpslatitude = 0.0; 00141 double gpslongitude = 0.0; 00142 float gpsaltitude = 0.0; 00143 bool ledOn = 1; 00144 00145 //AOD Variables 00146 //Globals for sun calulation input 00147 long gpsTime; 00148 long gpsDate; 00149 int year; 00150 int month; 00151 int day; 00152 int hour; 00153 int minute; 00154 double second; 00155 00156 double latitude = 40.5853; 00157 double longitude = -105.0844; 00158 double altitude = 1525; 00159 double temperature; 00160 double pressure; 00161 double humidity; 00162 00163 //Globals for sun calculation output 00164 double zenith; 00165 double azimuth; 00166 double radius; 00167 00168 //Constants 00169 const double time_zone = 0; //GPS gets Greenwich time 00170 const double delta_t = 68; //This parameter will be roughly constant this year 00171 const double slope = 30; 00172 const double azm_rotation = 10; 00173 00174 //AOD CALCULATION 00175 //AOD Calculation Constants 00176 const double lambda_440 = 0.440; 00177 const double lambda_520 = 0.520; 00178 const double lambda_680 = 0.680; 00179 const double lambda_870 = 0.870; 00180 const double CO2_ppv = 0.00036; 00181 const double v0_440 = 0.975524; 00182 const double v0_520 = 1.412519; 00183 const double v0_680 = 1.659305; 00184 const double v0_870 = 1.178819; 00185 const double vd = 0.001225; 00186 const double oz_coeff_440 = 0.0029; 00187 const double oz_coeff_520 = 0.0481; 00188 const double oz_coeff_680 = 0.0361; 00189 const double oz_coeff_870 = 0.0013; 00190 00191 //Voltage from light detector 00192 double v870; //Voltage read from 870nm photodiode 00193 double v_raw870; //Raw analog output from 870nm photodiode 00194 double v680; //Voltage read from 680nm photodiode 00195 double v_raw680; //Raw analog output from 680nm photodiode 00196 double v520; //Voltage read from 520nm photodiode 00197 double v_raw520; //Raw analog output from 520nm photodiode 00198 double v440; //Voltage read from 440nm photodiode 00199 double v_raw440; //Raw analog output from 440nm photodiode 00200 double AOD_870; 00201 double AOD_680; 00202 double AOD_520; 00203 double AOD_440; 00204 00205 //AOD functions 00206 void getAODs(); 00207 00208 ////////////////////////////////////////////////////////////// 00209 //Main Function 00210 ////////////////////////////////////////////////////////////// 00211 int main() 00212 { 00213 pc.baud(115200); 00214 RGB_LED.set_led(1, 0, 1); 00215 wait(1); 00216 00217 gpsEN = 1; // Enable the GPS 00218 wait(1); 00219 00220 // Get the GPS time 00221 gps.read_gps(); 00222 gpsTime = (long)gps.utc; 00223 gpsDate = (long)gps.date; 00224 pc.printf("Date: %d, Time: %d\r\n", gpsTime, gpsDate); 00225 int gpsfixWait = 0; 00226 // Wait until gps time is set 00227 if(gpsTime==0&&gpsDate==0){ 00228 //gasG.resetMax(); 00229 gps.resetGPS(); 00230 wait(1); 00231 while(gpsquality == 0){ 00232 gps.read_gps(); 00233 gpsTime = (long)gps.utc; 00234 gpsDate = (long)gps.date; 00235 gpsquality = gps.quality; 00236 00237 if(ledOn == 1) { 00238 M_SET_LED_OFF(); 00239 ledOn = 0; 00240 } 00241 else{ 00242 if(gpsquality==0){ 00243 M_SET_LED_MAGENTA(); 00244 }else{ 00245 M_SET_LED_YELLOW(); 00246 } 00247 ledOn = 1; 00248 } 00249 00250 wait(1); 00251 if(gpsquality==1){ 00252 gpsfixWait++; 00253 }else{ 00254 gpsfixWait = 0; 00255 } 00256 } 00257 } 00258 00259 aod_sel_5on[0] = 0xCB; 00260 aod_sel_5off[0] = 0xC9; 00261 plant_sel[0] = 0xCF; 00262 00263 RGB_LED.set_led(1, 1, 1); 00264 i2c.write(addr, aod_sel_5on, 1); 00265 pc.printf("Plantower off\r\n"); 00266 wait(1); 00267 00268 //Enable the WiFi chip 00269 RGB_LED.set_led(0, 1, 1); // Light LED so we know something is happening 00270 wifiEnable = 1; // Enable power to the WiFi while in reset, and wait a short while 00271 wait_ms(100); 00272 wifiNReset = 1; // Now de-assert the reset signal 00273 RGB_LED.set_led(1, 1, 0); // Color change of LED to indicate something is happening. 00274 wait(3); 00275 00276 RGB_LED.set_led(0, 1, 0); 00277 esp.check_esp(); 00278 esp.version_info(); 00279 esp.software_reset(); 00280 00281 esp.command_echo_mode(ESP_ECHO_ON); 00282 esp.set_wifi_mode(ESP_DUAL_CONFIG); 00283 esp.enable_multiple_connections(); 00284 00285 esp.create_tcp_server(80); 00286 00287 //esp.set_server_timeout(5); 00288 00289 esp.list_access_points(); 00290 esp.wifi_connect(ssid, password); 00291 esp.check_ap(); 00292 esp.get_ip(); 00293 00294 char someArray[160]; 00295 00296 t.start(); 00297 while(1) 00298 { 00299 RGB_LED.set_led(0, 0, 1); 00300 if(t.read()>15)//if 15 seconds passed 00301 { 00302 t.reset();//reset timer 00303 00304 RGB_LED.set_led(1, 1, 1); 00305 00306 //get the AOD 00307 getAODs(); 00308 00309 //send data to thingspeak 00310 sprintf(someArray,"GET https://api.thingspeak.com/update?api_key=32QVSK5INPPAVIV0&field1=%.2f&field2=%.2f&field3=%.2f&field4=%.2f&field5=%.2f&field6=%.2f&field7=%.2f\r\n\r\n",AOD_440,AOD_520,AOD_680,AOD_870,temperature,pressure,humidity); 00311 00312 esp.delete_tcp_server(); 00313 esp.establish_connection(0, conn_type, server, 80); 00314 esp.send_data_tcp(0, someArray); 00315 esp.close_connection(0); 00316 esp.create_tcp_server(80); 00317 pc.printf("%s\r\n", someArray); 00318 } 00319 } 00320 } 00321 00322 void getAODs() 00323 { 00324 gps.read_gps(); 00325 00326 gpsTime = (long)gps.utc; 00327 gpsDate = (long)gps.date; 00328 00329 minute = (int)(floor((float)(gpsTime - (uint8_t)(floor((float)gpsTime/10000))*10000)/100)); // 0-59 00330 second = (double)(floor(((float)gpsTime - 100*(floor((float)gpsTime/100)))));//0; //(uint8_t)(floor(((float)gpsTime - 100*(floor((float)gpsTime/100))))); // 0-59 00331 hour = (int)(floor((float)gpsTime/10000)); // 0-23 00332 day = (int)(floor((float)gpsDate/10000)); // 1-31 00333 month = (uint8_t)(floor((float)(gpsDate - day*10000)/100)); // 0-11 00334 year = 1900 + (uint8_t)(100+floor(((float)gpsDate - 100*(floor((float)gpsDate/100))))); // year since 1900 (116 = 2016)//100+16 00335 00336 temperature = bme.getTemperature(); 00337 pressure = bme.getPressure(temperature); 00338 humidity = bme.getHumidity(); 00339 00340 sun.setValues(year, month, day, hour, minute, second, time_zone, delta_t, latitude, longitude, altitude, temperature, pressure, slope, azm_rotation); 00341 sun.findSun(); 00342 zenith = sun.getZenith(); 00343 radius = sun.getRadius(); 00344 00345 //Read the light detectors 00346 v_raw870 = (double)ads_sun.readADC_SingleEnded(A3_GAIN_TWO); //Channel A3 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV 00347 v870 = (v_raw870*0.0625)/(1000); //Converts to a voltage 00348 00349 v_raw680 = (double)ads_sun.readADC_SingleEnded(A2_GAIN_TWO); //Channel A2 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV 00350 v680 = (v_raw680*0.0625)/(1000); //Converts to a voltage 00351 00352 v_raw520 = (double)ads_sun.readADC_SingleEnded(A1_GAIN_TWO); //Channel A1 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV 00353 v520 = (v_raw520*0.0625)/(1000); //Converts to a voltage 00354 00355 v_raw440 = (double)ads_sun.readADC_SingleEnded(A0_GAIN_TWO); //Channel A1 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV 00356 v440 = (v_raw520*0.0625)/(1000); //Converts to a voltage 00357 00358 //Calculate the AOD for all channels 00359 aod_870.setAODInputs(longitude, latitude, altitude, lambda_870, CO2_ppv, pressure, month, day, oz_coeff_870, v0_870, vd, v870, radius, zenith); 00360 aod_870.opticalDepth(); 00361 AOD_870 = aod_870.getAOD(); 00362 00363 aod_680.setAODInputs(longitude, latitude, altitude, lambda_680, CO2_ppv, pressure, month, day, oz_coeff_680, v0_680, vd, v680, radius, zenith); 00364 aod_680.opticalDepth(); 00365 AOD_680 = aod_680.getAOD(); 00366 00367 aod_520.setAODInputs(longitude, latitude, altitude, lambda_520, CO2_ppv, pressure, month, day, oz_coeff_520, v0_520, vd, v520, radius, zenith); 00368 aod_520.opticalDepth(); 00369 AOD_520 = aod_520.getAOD(); 00370 00371 aod_440.setAODInputs(longitude, latitude, altitude, lambda_440, CO2_ppv, pressure, month, day, oz_coeff_440, v0_440, vd, v440, radius, zenith); 00372 aod_440.opticalDepth(); 00373 AOD_440 = aod_440.getAOD(); 00374 }
Generated on Thu Jul 21 2022 00:20:44 by
1.7.2