Test code to interface AOD UPAS with IoT provider.
Dependencies: ESP8266_AT NCP5623BMUTBG mbed ADS1115 AOD_Calculation BME280 PMS5003 SunPosition CAM_M8
main.cpp
- Committer:
- eawendtjr
- Date:
- 2017-12-06
- Revision:
- 6:aeb0015d6632
- Parent:
- 5:513617961138
File content as of revision 6:aeb0015d6632:
#include "mbed.h" #include "NCP5623BMUTBG.h" #include "ESP8266_AT.h" #include "SunPosition.h" #include "AOD_Calculation.h" #include "Adafruit_ADS1015.h" #include "BME280.h" #include "CAM_M8.h" ///////////////////////////////////////////// //LED colors ///////////////////////////////////////////// #define M_SET_LED_OFF() RGB_LED.set_led(0,0,0) #define M_SET_LED_RED() RGB_LED.set_led(1,0,0) #define M_SET_LED_GREEN() RGB_LED.set_led(0,1,0) #define M_SET_LED_BLUE() RGB_LED.set_led(0,0,1) #define M_SET_LED_MAGENTA() RGB_LED.set_led(1,0,1) #define M_SET_LED_YELLOW() RGB_LED.set_led(1,1,0) #define M_SET_LED_CYAN() RGB_LED.set_led(0,1,1) #define M_SET_LED_WHITE() RGB_LED.set_led(1,1,1) ///////////////////////////////////////////// //Define core buses and pin states. ///////////////////////////////////////////// I2C i2c(PB_9, PB_8);//(D14, D15); SDA,SCL Serial pc(USBTX, USBRX); DigitalOut pumps(PA_9, 0);//(D8, 0); DigitalOut pbKill(PC_12, 1); // Digital input pin that conncect to the LTC2950 battery charger used to shutdown the UPAS 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 NCP5623BMUTBG RGB_LED(PB_9, PB_8); //(D14, D15); ///////////////////////////////////////////// //RN4677 BT/BLE Module ///////////////////////////////////////////// Serial ble(PB_10, PB_11); DigitalOut bleRTS(PB_14, 0); DigitalOut bleCTS(PB_13, 0); DigitalOut BT_IRST(PC_8, 0); DigitalOut BT_SW(PA_12, 0); ///////////////////////////////////////////// //Analog to Digital Converter ///////////////////////////////////////////// DigitalIn ADS_ALRT(PA_10); //Connected but currently unused. (ADS1115) http://www.ti.com/lit/ds/symlink/ads1115.pdf ///////////////////////////////////////////// //Battery, Charger, & Supply Monitoring ///////////////////////////////////////////// DigitalIn LTCALT(PB_2); //High for normal operation. Low when a threshold is exceeded for Voltage, gas gauge, or temp DigitalIn bcs1(PC_9); //Batt charging if High. (BQ24100)[U23] DigitalIn bcs2(PA_8); //Charge complete if High. (BQ24100)[U23] DigitalIn bc_npg(PB_1); //Power to the charge controller. (BQ24100)[U23] DigitalIn SW3flt(PC_4); //When EN = 0 pin is HIGH, When EN = 1, LOW can be current limit, thermal limit, or UVLO. ///////////////////////////////////////////// //Sensirion SDP3X(s) ///////////////////////////////////////////// DigitalIn SDP3Xflt(PC_0); DigitalIn SDP3XAltflt(PB_7); ///////////////////////////////////////////// //Accelerometer and Magnometer ///////////////////////////////////////////// DigitalOut iNemoEnable(PA_1, 0); DigitalIn iNemoReady(PB_0); DigitalIn iNemoInt1(PC_5); DigitalIn iNemoInt2(PC_6); DigitalIn iNemoInt3(PC_7); ///////////////////////////////////////////// //UV and Visible Light Sensor ///////////////////////////////////////////// ///////////////////////////////////////////// //GPS ///////////////////////////////////////////// DigitalOut gpsEN(PB_15, 0); CAM_M8 gps(PB_9, PB_8,(0x84)); uint8_t gpsBTState = 1; uint8_t meState = 0; DigitalIn gpsENFault(PB_12); //When EN = 0 pin is HIGH, When EN = 1, LOW can be current limit, thermal limit, or UVLO. ///////////////////////////////////////////// //SD Card ///////////////////////////////////////////// DigitalIn sdCD(PA_11); DigitalOut sdClk(PB_3,0 ); DigitalIn sdMISO(PB_4); DigitalOut sdMOSI(PB_5, 0); DigitalOut sdCS(PB_6, 1); DigitalIn pbIso(PA_0); DigitalOut hFault1(PA_7, 0); DigitalOut hFault2(PA_6, 0); DigitalOut hFault3(PA_5, 0); DigitalOut hFault4(PA_4, 0); DigitalOut wifiNReset(PC_1, 0); DigitalOut wifiEnable(PC_2, 0); DigitalOut qdEnable(PC_3, 0); DigitalIn qdFault(PC_13); ///////////////////////////////////////////// //AOD Objects ///////////////////////////////////////////// SunPosition sun; AOD_Calculation aod_440; AOD_Calculation aod_870; AOD_Calculation aod_680; AOD_Calculation aod_520; Adafruit_ADS1115 ads_sun(&i2c, ADS1015_ADDRESS_VDD); //Adress pin connected to 3.3V BME280 bme(PB_9, PB_8, 0xEC); //(D14, D15); ESP8266_AT esp(PC_10, PC_11); Timer t; char ssid[] = "w212lab"; char password[] = "testarduino"; //char ssid[] = "VOLTAR"; //char password[] = "CedhCedh"; char server[] = "api.thingspeak.com"; char apiKey[] = "32QVSK5INPPAVIV0"; char conn_type[] = "TCP"; // For selecting the WiFi UART const int addr = 0x3F << 1; char aod_sel_5on[1]; char aod_sel_5off[1]; char plant_sel[1]; //GPS Variables bool gpsReady = 0; uint8_t gpsquality = 0; uint8_t gpssatellites = 0; double gpsspeed = 0.0; //double gpscourse = 0.0; double gpslatitude = 0.0; double gpslongitude = 0.0; float gpsaltitude = 0.0; bool ledOn = 1; //AOD Variables //Globals for sun calulation input long gpsTime; long gpsDate; int year; int month; int day; int hour; int minute; double second; double latitude = 40.5853; double longitude = -105.0844; double altitude = 1525; double temperature; double pressure; double humidity; //Globals for sun calculation output double zenith; double azimuth; double radius; //Constants const double time_zone = 0; //GPS gets Greenwich time const double delta_t = 68; //This parameter will be roughly constant this year const double slope = 30; const double azm_rotation = 10; //AOD CALCULATION //AOD Calculation Constants const double lambda_440 = 0.440; const double lambda_520 = 0.520; const double lambda_680 = 0.680; const double lambda_870 = 0.870; const double CO2_ppv = 0.00036; const double v0_440 = 0.975524; const double v0_520 = 1.412519; const double v0_680 = 1.659305; const double v0_870 = 1.178819; const double vd = 0.001225; const double oz_coeff_440 = 0.0029; const double oz_coeff_520 = 0.0481; const double oz_coeff_680 = 0.0361; const double oz_coeff_870 = 0.0013; //Voltage from light detector double v870; //Voltage read from 870nm photodiode double v_raw870; //Raw analog output from 870nm photodiode double v680; //Voltage read from 680nm photodiode double v_raw680; //Raw analog output from 680nm photodiode double v520; //Voltage read from 520nm photodiode double v_raw520; //Raw analog output from 520nm photodiode double v440; //Voltage read from 440nm photodiode double v_raw440; //Raw analog output from 440nm photodiode double AOD_870; double AOD_680; double AOD_520; double AOD_440; //AOD functions void getAODs(); ////////////////////////////////////////////////////////////// //Main Function ////////////////////////////////////////////////////////////// int main() { pc.baud(115200); RGB_LED.set_led(1, 0, 1); wait(1); gpsEN = 1; // Enable the GPS wait(1); // Get the GPS time gps.read_gps(); gpsTime = (long)gps.utc; gpsDate = (long)gps.date; pc.printf("Date: %d, Time: %d\r\n", gpsTime, gpsDate); int gpsfixWait = 0; // Wait until gps time is set if(gpsTime==0&&gpsDate==0){ //gasG.resetMax(); gps.resetGPS(); wait(1); while(gpsquality == 0){ gps.read_gps(); gpsTime = (long)gps.utc; gpsDate = (long)gps.date; gpsquality = gps.quality; if(ledOn == 1) { M_SET_LED_OFF(); ledOn = 0; } else{ if(gpsquality==0){ M_SET_LED_MAGENTA(); }else{ M_SET_LED_YELLOW(); } ledOn = 1; } wait(1); if(gpsquality==1){ gpsfixWait++; }else{ gpsfixWait = 0; } } } aod_sel_5on[0] = 0xCB; aod_sel_5off[0] = 0xC9; plant_sel[0] = 0xCF; RGB_LED.set_led(1, 1, 1); i2c.write(addr, aod_sel_5on, 1); pc.printf("Plantower off\r\n"); wait(1); //Enable the WiFi chip RGB_LED.set_led(0, 1, 1); // Light LED so we know something is happening wifiEnable = 1; // Enable power to the WiFi while in reset, and wait a short while wait_ms(100); wifiNReset = 1; // Now de-assert the reset signal RGB_LED.set_led(1, 1, 0); // Color change of LED to indicate something is happening. wait(3); RGB_LED.set_led(0, 1, 0); esp.check_esp(); esp.version_info(); esp.software_reset(); esp.command_echo_mode(ESP_ECHO_ON); esp.set_wifi_mode(ESP_DUAL_CONFIG); esp.enable_multiple_connections(); esp.create_tcp_server(80); //esp.set_server_timeout(5); esp.list_access_points(); esp.wifi_connect(ssid, password); esp.check_ap(); esp.get_ip(); char someArray[160]; t.start(); while(1) { RGB_LED.set_led(0, 0, 1); if(t.read()>15)//if 15 seconds passed { t.reset();//reset timer RGB_LED.set_led(1, 1, 1); //get the AOD getAODs(); //send data to thingspeak 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); esp.delete_tcp_server(); esp.establish_connection(0, conn_type, server, 80); esp.send_data_tcp(0, someArray); esp.close_connection(0); esp.create_tcp_server(80); pc.printf("%s\r\n", someArray); } } } void getAODs() { gps.read_gps(); gpsTime = (long)gps.utc; gpsDate = (long)gps.date; minute = (int)(floor((float)(gpsTime - (uint8_t)(floor((float)gpsTime/10000))*10000)/100)); // 0-59 second = (double)(floor(((float)gpsTime - 100*(floor((float)gpsTime/100)))));//0; //(uint8_t)(floor(((float)gpsTime - 100*(floor((float)gpsTime/100))))); // 0-59 hour = (int)(floor((float)gpsTime/10000)); // 0-23 day = (int)(floor((float)gpsDate/10000)); // 1-31 month = (uint8_t)(floor((float)(gpsDate - day*10000)/100)); // 0-11 year = 1900 + (uint8_t)(100+floor(((float)gpsDate - 100*(floor((float)gpsDate/100))))); // year since 1900 (116 = 2016)//100+16 temperature = bme.getTemperature(); pressure = bme.getPressure(temperature); humidity = bme.getHumidity(); sun.setValues(year, month, day, hour, minute, second, time_zone, delta_t, latitude, longitude, altitude, temperature, pressure, slope, azm_rotation); sun.findSun(); zenith = sun.getZenith(); radius = sun.getRadius(); //Read the light detectors v_raw870 = (double)ads_sun.readADC_SingleEnded(A3_GAIN_TWO); //Channel A3 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV v870 = (v_raw870*0.0625)/(1000); //Converts to a voltage v_raw680 = (double)ads_sun.readADC_SingleEnded(A2_GAIN_TWO); //Channel A2 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV v680 = (v_raw680*0.0625)/(1000); //Converts to a voltage v_raw520 = (double)ads_sun.readADC_SingleEnded(A1_GAIN_TWO); //Channel A1 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV v520 = (v_raw520*0.0625)/(1000); //Converts to a voltage v_raw440 = (double)ads_sun.readADC_SingleEnded(A0_GAIN_TWO); //Channel A1 | 1x gain | +/-4.096V | 1 bit = 2mV | 0.125mV v440 = (v_raw520*0.0625)/(1000); //Converts to a voltage //Calculate the AOD for all channels aod_870.setAODInputs(longitude, latitude, altitude, lambda_870, CO2_ppv, pressure, month, day, oz_coeff_870, v0_870, vd, v870, radius, zenith); aod_870.opticalDepth(); AOD_870 = aod_870.getAOD(); aod_680.setAODInputs(longitude, latitude, altitude, lambda_680, CO2_ppv, pressure, month, day, oz_coeff_680, v0_680, vd, v680, radius, zenith); aod_680.opticalDepth(); AOD_680 = aod_680.getAOD(); aod_520.setAODInputs(longitude, latitude, altitude, lambda_520, CO2_ppv, pressure, month, day, oz_coeff_520, v0_520, vd, v520, radius, zenith); aod_520.opticalDepth(); AOD_520 = aod_520.getAOD(); aod_440.setAODInputs(longitude, latitude, altitude, lambda_440, CO2_ppv, pressure, month, day, oz_coeff_440, v0_440, vd, v440, radius, zenith); aod_440.opticalDepth(); AOD_440 = aod_440.getAOD(); }