diff --git a/projects/IoTBoardCode/Waspmote/SWX/SWX3.pde b/projects/IoTBoardCode/Waspmote/SWX/SWX3.pde new file mode 100644 index 00000000..306ccc27 --- /dev/null +++ b/projects/IoTBoardCode/Waspmote/SWX/SWX3.pde @@ -0,0 +1,447 @@ +/* + // TODO: Update + | A | B | C | D | E | F | + |-----------------------| + BME280 | | | | | X | | + CO | | | | | | X | + CH4 | | | | X | | | + |-----------------------| +*/ +#include +#include +#include +// choose socket (SELECT USER'S SOCKET) +/////////////////////////////////////// +const uint8_t lora_socket = SOCKET0; +/////////////////////////////////////// + +//==================================================================== +// INSTANCE DEFINITION +//==================================================================== +//[Sensor Class] [Sensor Name] [Selected socket] +VegaPuls_C21 mySensor(XTR_SOCKET_A); +Aqualabo_PHEHT myPHEHT_B(XTR_SOCKET_B); +Aqualabo_C4E myC4E_C(XTR_SOCKET_C); +Aqualabo_MES5 myMES5_D(XTR_SOCKET_D); +Aqualabo_OPTOD myOPTOD_E(XTR_SOCKET_E); + +//==================================================================== +// MOTE_ID +//=================================================================== +// Default device name +// TODO: Change +char *MOTE_ID = "SWX3"; + +//==================================================================== +// PARAMETERS FOR SD CARD +//=================================================================== + +char SD_FILENAME[] = "IOTDATA.TXT"; + +//==================================================================== +// PARAMETERS TO CONFIGURE 4G RADIO +//=================================================================== +// TODO: Check +char apn[] = "broadband"; +char login[] = ""; +char password[] = ""; +char PIN[] = ""; + +// SERVER settings +/////////////////////////////////////// +// TODO: Check/update +char host[] = "82.78.81.178"; +uint16_t port = 80; +/////////////////////////////////////// + +// battery control variables +uint8_t battery; +// other variables +uint8_t error; +uint8_t error_flag; +int8_t cont; +uint8_t connection_status; + +///////////////////////////////////////////////// +// Define measurement variables +//////////////////////////////////////////////// +// TODO: Add variables + +int status; + +///////////////////////////////////////////////// +// Global flags (do not change until you know what are you doing +//////////////////////////////////////////////// +bool NTP_IS_SYNC = false;; + +/* + Writes the frame to the SD card usind the following format: + When RTC is okay (set) + +\t\t\t + When RTC is not set + -\t\t*\t + Uses NTP_IS_SYNC to see if the RTC is set. + Returns true if the write is succesful. +*/ +bool writeSD(void) { + bool ok = true; + USB.println(F("--------------- Start of writeSD ------------------------")); + uint8_t sd_status = 0; + char epoch_time_str[16]; + char millis_str[16]; + + // Start SD + SD.ON(); + + // Open file + SdFile file; + sd_status = SD.openFile(SD_FILENAME, &file, O_APPEND | O_CREAT | O_RDWR); + if (sd_status == 1) { + USB.println(F("Succesfully oppened file")); + } else { + USB.println(F("Failed to open file.")); + return false; + } + + // Add newline + ok &= file.write("\n") > 0; + + if (NTP_IS_SYNC == true) { + USB.println(F("NTP is set - I will write the real time on the SD card.")); + ok &= file.write("+\t") > 0; + } else { + USB.println(F("No NTP was synced. No time available :(")); + ok &= file.write("-\t") > 0; + } + + ltoa(millis(), millis_str, 10); + ok &= file.write(millis_str) > 0; + ok &= file.write("\t") > 0; + + // Write epoch time (or *) + if (NTP_IS_SYNC) { + ltoa(RTC.getEpochTime(), epoch_time_str, 10); + ok &= file.write(epoch_time_str) > 0; + } else { + ok &= file.write("*") > 0; + } + + // Write \t before frame + ok &= file.write("\t") > 0; + + ok &= file.write(frame.buffer, frame.length) > 0; + + if (ok) { + USB.println(F("All write operation were succesful")); + } else { + USB.println(F("Some errors when writting.")); + } + // Close the file + SD.closeFile(&file); + + // Stop SD + SD.OFF(); + USB.println(F("--------------- End of writeSD ------------------------")); + return ok; +} + +//==================================================================== +// Measure the sensors +//==================================================================== +void readSensors() { + delay(100); + + // TODO: Read sensors + USB.println(F("****************************************")); + + /////////////////////////////////////////// + // 1. Read the sensors + /////////////////////////////////////////// + + // Socket E sensor + // Turn ON the sensor + myOPTOD_E.ON(); + // Read the sensor + myOPTOD_E.read(); + // Turn off the sensor + myOPTOD_E.OFF(); + + // Socket D sensor + // Turn ON the sensor + myMES5_D.ON(); + // Read the sensor + myMES5_D.read(); + // Turn off the sensor and the heater + myMES5_D.OFF(); + + // Socket C sensor + // Turn ON the sensor + myC4E_C.ON(); + // Read the sensor + myC4E_C.read(); + // Turn off the sensor and the heater + myC4E_C.OFF(); + + // Socket B sensor + // Turn ON the sensor + myPHEHT_B.ON(); + // Read the sensor + myPHEHT_B.read(); + // Turn off the sensor + myPHEHT_B.OFF(); + + //Socket A sensor Radar VegaPuls + // Turn ON the sensor + mySensor.ON(); + // Read the sensor + mySensor.read(); + // Turn off the sensor + mySensor.OFF(); + + USB.print(F("radar data mySensor.VegaPulsC21.distance: ")); + USB.println(mySensor.VegaPulsC21.distance); + USB.print(F("radar data mySensor_A.VegaPulsC21.stage: ")); + USB.println(mySensor.VegaPulsC21.stage); + USB.println(F(" ")); + + + USB.println(F("... *************************************")); +} + +//==================================================================== +// Create a Data Frame Lorawan +//==================================================================== +void CreateDataFrame(uint8_t frame_type) { + USB.println(F("..CREATING FRAME PROCESS ")); + + frame.createFrame(frame_type, MOTE_ID); + frame.addTimestamp(); + // set frame fields (Sensors Values) + // frame.createFrame(BINARY, node_ID); // frame2 + frame.setFrameType(INFORMATION_FRAME_WTR_XTR); + frame.addSensor(SENSOR_BAT, PWR.getBatteryLevel()); +// frame.addSensor(SENSOR_TIME, RTC.getTimestamp()); +// USB.println(F("..error1 ")); + + // add Socket B sensor values + frame.addSensor(WTRX_PHEHT_TC2_B, myPHEHT_B.sensorPHEHT.temperature); + frame.addSensor(WTRX_PHEHT_PH_B, myPHEHT_B.sensorPHEHT.pH); + frame.addSensor(WTRX_PHEHT_PM_B, myPHEHT_B.sensorPHEHT.pHMV); + frame.addSensor(WTRX_PHEHT_RX_B, myPHEHT_B.sensorPHEHT.redox); + // add Socket E sensor values + frame.addSensor(WTRX_OPTOD_TC1_E, myOPTOD_E.sensorOPTOD.temperature); + frame.addSensor(WTRX_OPTOD_OS_E, myOPTOD_E.sensorOPTOD.oxygenSAT); + frame.addSensor(WTRX_OPTOD_OM_E, myOPTOD_E.sensorOPTOD.oxygenMGL); + frame.addSensor(WTRX_OPTOD_OP_E, myOPTOD_E.sensorOPTOD.oxygenPPM); + + // add Socket D sensor values + frame.addSensor(WTRX_MES5_TC6_D, myMES5_D.sensorMES5.temperature); + frame.addSensor(WTRX_MES5_SB_D, myMES5_D.sensorMES5.sludgeBlanket); + frame.addSensor(WTRX_MES5_SS_D, myMES5_D.sensorMES5.suspendedSolids); + frame.addSensor(WTRX_MES5_TF_D, myMES5_D.sensorMES5.turbidityFAU); + + // add Socket C sensor values + frame.addSensor(WTRX_C4E_TC3_C, myC4E_C.sensorC4E.temperature); + frame.addSensor(WTRX_C4E_CN_C, myC4E_C.sensorC4E.conductivity); + frame.addSensor(WTRX_C4E_SA_C, myC4E_C.sensorC4E.salinity); + frame.addSensor(WTRX_C4E_TD_C, myC4E_C.sensorC4E.totalDissolvedSolids); + frame.addSensor(WTRX_C21_DIS_A, mySensor.VegaPulsC21.distance); //distanta pana la apa + frame.showFrame(); +} + +//==================================================================== +// Configure 4G module +//==================================================================== +void set4G() { + ////////////////////////////////////////////////// + // 1. sets operator parameters + ////////////////////////////////////////////////// + USB.println("SETTING 4G PARAMETERS..."); + _4G.set_APN(apn, login, password); + + ////////////////////////////////////////////////// + // 2. Show APN settings via USB port + ////////////////////////////////////////////////// + _4G.show_APN(); + + ////////////////////////////////////////////////// + // 4. set PIN + ////////////////////////////////////////////////// + if (!strcmp(PIN, "")) + return; + + USB.println(F("Setting PIN code...")); + if (_4G.enterPIN(PIN) == 0) { + USB.println(F("PIN code accepted")); + } else { + USB.println(F("PIN code incorrect")); + } +} + +//==================================================================== +// Set time from 4G +//==================================================================== +void setTime4G() { + USB.println(F("Setting time from 4G....")); + error = _4G.ON(); + + if (error == 0) { + USB.println(F("4G module ready...")); + + //////////////////////////////////////////////// + // Check connection to network and continue + //////////////////////////////////////////////// + connection_status = _4G.checkDataConnection(30); + delay(5000); + ////////////////////////////////////////////////// + // 3. set time + ////////////////////////////////////////////////// + if (connection_status == 0) { + if (_4G.setTimeFrom4G() == 0) { + USB.println(F("Succesufully set time from 4G")); + NTP_IS_SYNC = true; + } else { + USB.println(F("Failed to get time from 4G")); + } + } + } else { + // Problem with the communication with the 4G module + USB.println(F("4G module not started")); + USB.print(F("Error code: ")); + USB.println(error, DEC); + } + //////////////////////////////////////////////// + // 4. Powers off the 4G module + //////////////////////////////////////////////// + USB.println(F("Switch OFF 4G module\n")); + _4G.OFF(); +} + +//==================================================================== +// Send Data Frame 4G +//==================================================================== +void send4G() { + + error = _4G.ON(); + + if (error == 0) { + USB.println(F("4G module ready...")); + + //////////////////////////////////////////////// + // Check connection to network and continue + //////////////////////////////////////////////// + connection_status = _4G.checkDataConnection(30); + delay(5000); + + //////////////////////////////////////////////// + // 3. Send to Meshlium + //////////////////////////////////////////////// + USB.print(F("Sending the frame...")); + error = _4G.sendFrameToMeshlium(host, port, frame.buffer, frame.length); + + // check the answer + if (error == 0) { + USB.print(F("Done. HTTP code: ")); + USB.println(_4G._httpCode); + USB.print("Server response: "); + USB.println(_4G._buffer, _4G._length); + } else { + USB.print(F("Failed. Error code: ")); + USB.println(error, DEC); + } + } else { + // Problem with the communication with the 4G module + USB.println(F("4G module not started")); + USB.print(F("Error code: ")); + USB.println(error, DEC); + } + + //////////////////////////////////////////////// + // 4. Powers off the 4G module + //////////////////////////////////////////////// + USB.println(F("Switch OFF 4G module\n")); + _4G.OFF(); +} + +void setup() { + uint8_t error; + + // Turn ON the USB and print a start message + USB.ON(); + delay(100); + USB.println(F("\n*****************************************************")); + USB.print(F("BEIA ")); + USB.println(MOTE_ID); + USB.println(F("*****************************************************")); + + // Init RTC + RTC.ON(); + + // Set 4G + set4G(); + + // Set time from 4G + setTime4G(); + + // Getting time + USB.print(F("Time [Day of week, YY/MM/DD, hh:mm:ss]: ")); + USB.println(RTC.getTime()); +} + +void loop() { + // New iteration + USB.ON(); + USB.println(F("\n*****************************************************")); + USB.print(F("New iteration for BEIA ")); + USB.println(MOTE_ID); + USB.println(F("*****************************************************")); + + // Turn on RTC and get starting time + RTC.ON(); + + // Check battery level + battery = PWR.getBatteryLevel(); + USB.print(F("Battery level: ")); + USB.println(battery, DEC); + + // Step 1: Read suitable sensors + readSensors(); + + // Step 2: Create data Frame + USB.println("Create ASCII Frame"); + CreateDataFrame(ASCII); + + // Step 3: Save on SD card + writeSD(); + + // Step 4: If enough battery, send data + if (battery >= 30) { + + if (!NTP_IS_SYNC) { + USB.println("Time not set... retry..."); + setTime4G(); + } + + // Step 4.1: Send using 4G + CreateDataFrame(BINARY); + send4G(); + } else { + USB.println(F("Skip seding data... battery under 30%")); + } + + USB.println(F("---------------------------------")); + USB.println(F("...Enter deep sleep mode 15 min")); + PWR.deepSleep("00:00:15:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF); + USB.ON(); + USB.print(F("...wake up!! Date: ")); + USB.println(RTC.getTime()); + + RTC.setWatchdog(720); // 12h in minutes + USB.print(F("...Watchdog :")); + USB.println(RTC.getWatchdog()); + USB.println(F("****************************************")); +} + +//*********************************************************************************************** +// END OF THE SKETCH +//*********************************************************************************************** \ No newline at end of file diff --git a/projects/IoTBoardCode/Waspmote/SmartSense/Sense1.pde b/projects/IoTBoardCode/Waspmote/SmartSense/Sense1.pde new file mode 100644 index 00000000..44eb179d --- /dev/null +++ b/projects/IoTBoardCode/Waspmote/SmartSense/Sense1.pde @@ -0,0 +1,748 @@ +/* + + | A | B | C | D | E | F | + |-----------------------| + BME280 | | | | | X | | + CO | | | X | | | | + SO2 | | X | | | | | + O3 | X | | | | | | + NO2 | | | | | | X | + PM | | | | X | | | + |-----------------------| + + +*/ +#include +#include +#include +#include +#include + +//#include "INIRCH4.h" + +// choose socket (SELECT USER'S SOCKET) +/////////////////////////////////////// +const uint8_t lora_socket = SOCKET0; +/////////////////////////////////////// + +//==================================================================== +// INSTANCE DEFINITION +//==================================================================== +bmeGasesSensor bme; +Gas gas_O3(SOCKET_A); +Gas gas_SO2(SOCKET_B); +Gas gas_CO(SOCKET_C); +Gas gas_NO2(SOCKET_F); + +//INIRCH4 CH4 = INIRCH4(); + +//==================================================================== +// PARAMETERS TO CONFIGURE LORAWAN RADIO +//=================================================================== +// Device EUI for +char DEVICE_EUI[] = "0004A30B00EF2997"; +// Default Application kEY +char APP_KEY[] = "C79671FEC0500D5713C7A9887CC43889"; +// Default Application Eui +char APP_EUI[] = "0004A30B00EF2997"; +/* + SERIAL ID DEV EUI=APP EUI APP KEY +Sense1 48151CE819623C3F 0004A30B00EF2997 C79671FEC0500D5713C7A9887CC43889 +Sense 10 5C0A1CE819623C97 0004A30B00EEDBEA E7688BD6F5E3F51B3E896F164141AE3B +Sense 11 6424BAC2CB018069 0004A30B00EF5BD0 348019C95BE9EBA0B4B352FF8ED39730 +Sense 12 29331CE819623CC9 0004A30B00EF0CC9 2FBE14E6202DD27CDE42EEF9183D3353 +Sense 3 191644E819623CEE 0004A30B00EEA8EB 295A46A6A1732A5E0F56E2FAFF535A7B +Sense 14 325044E819623C43 0004A30B00EF4462 958C164C0C98B89EB5190C735FC60436 +Sense 13 0A5E1CE819623C81 0004A30B00EF450F D09922CFF6F832D0E11B377B1ED05073 +Sense 15 245B1CE819623C8B 0004A30B00EEF090 C787B5C828F19651F3111AC9382B82BA +Sense 4 6B5E1CE819623CBA 0004A30B00EED058 E0F0961ED3392F701B91C0BACADA3592 +Sense 5 4A7C1CE819623CAD 0004A30B00EF0E15 11E8770BA537AF5E8F3CD11CEB090544 +Sense2 2B4D1CE819623C1A 0004A30B00EEA4F3 CF14118DB3977592419A809272B4B898 +Sense16 3F6EBAC2CB018018 0004A30B00EF30A0 F9EDE84742753A02E3B71F219303B391 +Sense 6 7D511CE819623C35 0004A30B00EF0EB5 CF5EB8BAEFA890C8FACBF734C102A88E +Sense 7 106A1CE819623C00 0004A30B00EEF6F0 96E5FC154607403C433BCF1085E8F62B +Sense 8 54281CE819623C14 0004A30B00EEF51C 43157B30A446186FB32D978991A8CB78 +Sense 9 25281CE819623CFC 0004A30B00EEDABA 5EAE95B0C5A341DCA78A28D4F805AA26 +*/ +// Default port +uint8_t PORT = 3; +// Default device name +char *MOTE_ID = "SENSE1"; + +//==================================================================== +// PARAMETERS FOR SD CARD +//=================================================================== + +char SD_FILENAME[] = "IOTDATA.TXT"; + +//==================================================================== +// PARAMETERS TO CONFIGURE 4G RADIO +//=================================================================== +char apn[] = "broadband"; +char login[] = ""; +char password[] = ""; +char PIN[] = ""; + +// SERVER settings +/////////////////////////////////////// +char host[] = "82.78.81.178"; +uint16_t port = 80; +/////////////////////////////////////// + +// battery control variables +uint8_t battery; +// other variables +uint8_t error; +uint8_t error_flag; +int8_t cont; +uint8_t connection_status; + +///////////////////////////////////////////////// +// Define measurement variables +//////////////////////////////////////////////// +float concentration_O3, concentration_SO2, concentration_NO2, concentration_CO; // Stores the concentration level in ppm +float temperature; // Stores the temperature in ºC +float humidity; // Stores the realitve humidity in %RH +float pressure; // Stores the pressure in Pa +int status; + +///////////////////////////////////////////////// +// Global flags (do not change until you know what are you doing +//////////////////////////////////////////////// +bool NTP_IS_SYNC = false; +bool LW_IS_SET = false; + +/* + * Writes the frame to the SD card usind the following format: + * When RTC is okay (set) + * +\t\t\t + * When RTC is not set + * -\t\t*\t + * Uses NTP_IS_SYNC to see if the RTC is set. + * Returns true if the write is succesful. + */ +bool writeSD(void) { + bool ok = true; + USB.println(F("--------------- Start of writeSD ------------------------")); + uint8_t sd_status = 0; + char epoch_time_str[16]; + char millis_str[16]; + + // Start SD + SD.ON(); + + // Open file + SdFile file; + sd_status = SD.openFile(SD_FILENAME, &file, O_APPEND | O_CREAT | O_RDWR); + if (sd_status == 1) { + USB.println(F("Succesfully oppened file")); + } else { + USB.println(F("Failed to open file.")); + return false; + } + + // Add newline + ok &= file.write("\n") > 0; + + if (NTP_IS_SYNC == true) { + USB.println(F("NTP is set - I will write the real time on the SD card.")); + ok &= file.write("+\t") > 0; + } else { + USB.println(F("No NTP was synced. No time available :(")); + ok &= file.write("-\t") > 0; + } + + ltoa(millis(), millis_str, 10); + ok &= file.write(millis_str) > 0; + ok &= file.write("\t") > 0; + + // Write epoch time (or *) + if (NTP_IS_SYNC) { + ltoa(RTC.getEpochTime(), epoch_time_str, 10); + ok &= file.write(epoch_time_str) > 0; + } else { + ok &= file.write("*") > 0; + } + + // Write \t before frame + ok &= file.write("\t") > 0; + + ok &= file.write(frame.buffer, frame.length) > 0; + + if (ok) { + USB.println(F("All write operation were succesful")); + } else { + USB.println(F("Some errors when writting.")); + } + // Close the file + SD.closeFile(&file); + + // Stop SD + SD.OFF(); + USB.println(F("--------------- End of writeSD ------------------------")); + return ok; +} + +//==================================================================== +// Measure the sensors +//==================================================================== +void readSensors() +{ + USB.println(F("MEASURING SENSORS")); + delay(100); + + // Reading BME + bme.ON(); + + temperature = bme.getTemperature(); + humidity = bme.getHumidity(); + pressure = bme.getPressure(); + + bme.OFF(); + USB.println(F("****************************************")); + + // Read sensors + // ************************* + //Reading electrochemical sensors + gas_O3.ON(); + gas_SO2.ON(); + gas_CO.ON(); + gas_NO2.ON(); + + USB.println(F("... Enter deep sleep mode 4 minutes to warm up sensors")); +// PWR.deepSleep("00:00:04:00", RTC_OFFSET, RTC_ALM1_MODE1, SENSOR_ON); + + concentration_O3 = gas_O3.getConc(temperature); + concentration_SO2 = gas_SO2.getConc(temperature); + concentration_NO2 = gas_NO2.getConc(temperature); + concentration_CO = gas_CO.getConc(temperature); + + gas_O3.OFF(); + gas_SO2.OFF(); + gas_CO.OFF(); + gas_NO2.OFF(); + + PM.ON(); + + //Reading Particle matter + USB.print("...Reading PM sensor..."); + status = PM.getPM(8000, 5000); + if (status == 1) + { + USB.println(F(" OK")); + } + else + { + USB.println(F(" Error")); + } + //OFF PARTICLE SENSOR + PM.OFF(); + + USB.println(F("****************************************")); + + + //////////////////////////// + //SHOWING RESULTS OF THE MEASURENMENTS + //////////////////////////// + //BME280 measure + USB.println(F("... MEASUREMENT RESULTS...")); + USB.println(F("... *************************************")); + USB.print(F("... Ambient temperature --> ")); + USB.print(temperature); + USB.println(F(" ºC")); + USB.print(F("... Ambient Humidity --> ")); + USB.print(humidity); + USB.println(F(" %")); + USB.print(F("... Ambient pressure --> ")); + USB.print(pressure); + USB.println(F(" Pa")); + + //Electrochemical sensor measure + USB.print(F("... O3 concentration: ")); + USB.print(concentration_O3); + USB.println(F(" ppm")); + USB.print(F("... SO2 concentration: ")); + USB.print(concentration_SO2); + USB.println(F(" ppm")); + USB.print(F("... NO2 concentration: ")); + USB.print(concentration_NO2); + USB.println(F(" ppm")); + USB.print(F("... CO concentration: ")); + USB.print(concentration_CO); + USB.println(F(" ppm")); + + //Particle matter measure + USB.print(F("...PM 1: ")); + USB.print(PM._PM1); + USB.println(F(" ug/m3")); + USB.print(F("...PM 2.5: ")); + USB.print(PM._PM2_5); + USB.println(F(" ug/m3")); + USB.print(F("...PM 10: ")); + USB.print(PM._PM10); + USB.println(F(" ug/m3")); + USB.println(F("... *************************************")); + +} + +//==================================================================== +// Create a Data Frame Lorawan +//==================================================================== +void CreateDataFrame(uint8_t frame_type) { + USB.println(F("..CREATING LoRAWAN FRAME PROCESS ")); + frame.createFrame(ASCII, MOTE_ID); + // set frame fields (Sensors Values) + frame.addSensor(SENSOR_BAT, battery); + frame.addSensor(SENSOR_GASES_PRO_TC, temperature); + frame.addSensor(SENSOR_GASES_PRO_HUM, humidity); + frame.addSensor(SENSOR_GASES_PRO_PRES, pressure); + + + //Electrochemical snsors + frame.addSensor(SENSOR_GASES_PRO_O3, concentration_O3); + frame.addSensor(SENSOR_GASES_PRO_SO2, concentration_SO2); + frame.addSensor(SENSOR_GASES_PRO_NO2, concentration_NO2); + frame.addSensor(SENSOR_GASES_PRO_CO, concentration_CO); + + //particle matter + frame.addSensor(SENSOR_GASES_PRO_PM1, PM._PM1); + frame.addSensor(SENSOR_GASES_PRO_PM2_5, PM._PM2_5); + frame.addSensor(SENSOR_GASES_PRO_PM10, PM._PM10); + +// //Step 3: send a Libelium frame to the Multitech +// SendDataLW(); + frame.showFrame(); +} +//==================================================================== +// Send Data Frame lorawan +//==================================================================== +void SendDataLW(void) { + uint8_t tx_error, error; + USB.println(); + USB.println(F("SENDING LORAWAN DATA PROCESS")); + + /////////////////////////////////////////// + // 2.2 Send frame using LoRaWAN + // 2.2.1. Switch on + error = LoRaWAN.ON(SOCKET0); + // Check status + if (error == 0) { + USB.println(F("...Switch ON OK")); + } else { + USB.print(F("... Switch ON error = ")); + USB.println(error, DEC); + } + // 2.2.2. Join network + error = LoRaWAN.joinABP(); + if (error == 0) { + USB.println(F("...Join network OK")); + + // 2.2.3. Send confirmed packet + + LoRaWAN.getDownCounter(); + LoRaWAN.getUpCounter(); + error = LoRaWAN.sendUnconfirmed(PORT, frame.buffer, frame.length); + LoRaWAN.getDownCounter(); + LoRaWAN.getUpCounter(); + + // Error messages: + /* + '6' : Module hasn't joined a network + '5' : Sending error + '4' : Error with data length + '2' : Module didn't response + '1' : Module communication error + */ + // Check status + if (error == 0) { + USB.println(F("... Send Unconfirmed packet OK")); + } else { + USB.print(F("...Send Unconfirmed packet error = ")); + USB.println(error, DEC); + error_flag = 1; + cont++; + } + } else { + USB.print(F("...Join network error = ")); + USB.println(error, DEC); + } + + // 2.2.4. Switch off + error = LoRaWAN.OFF(lora_socket); + if (error == 0) { + USB.println(F("... Switch OFF OK")); + } else { + USB.print(F("...Switch OFF error = ")); + USB.println(error, DEC); + } +} +//==================================================================== +// Configure LoRaWAN module +//==================================================================== +void set868(void) { + + // 1. switch on + USB.println(F("CONFIGURE LORAWAN MODULE")); + USB.println(F("... 0.1 Configure module")); + + error = LoRaWAN.ON(lora_socket); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.1 Switch ON OK")); + } else { + USB.print(F("....... 0.1.1 Switch ON error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // 2. Reset to factory default values + + error = LoRaWAN.factoryReset(); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.2 Reset to factory default values OK")); + } else { + USB.print(F("....... 0.1.2 Reset to factory error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // 3. Set Device EUI + error = LoRaWAN.setDeviceEUI(DEVICE_EUI); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.3 Set Device EUI OK")); + } else { + USB.print(F("....... 0.1.3 Set Device EUI error = ")); + USB.println(error, DEC); + goto set868_end; + } + + ////////////////////////////////////////////// + // 4. Set Application EUI + ////////////////////////////////////////////// + + error = LoRaWAN.setAppEUI(APP_EUI); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.4 Application EUI set OK")); + } else { + USB.print(F("....... 0.1.4 Application EUI set error = ")); + USB.println(error, DEC); + goto set868_end; + } + + ////////////////////////////////////////////// + // 5. Set Application Session Key + ////////////////////////////////////////////// + + error = LoRaWAN.setAppKey(APP_KEY); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.5 Application Key set OK")); + } else { + USB.print(F("....... 0.1.5 Application Key set error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // 7. Set retransmissions for uplink confirmed packet + // set retries + error = LoRaWAN.setRetries(7); + + // Check status + if (error == 0) { + USB.println( + F("....... 0.1.7 Set Retransmissions for uplink confirmed packet OK")); + } else { + USB.print(F("....... 0.1.7 Set Retransmissions for uplink confirmed " + "packet error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // 13. Set Adaptive Data Rate (recommended) + // set ADR + error = LoRaWAN.setADR("on"); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.9 Set Adaptive data rate status to on OK")); + } else { + USB.print(F("....... 0.1.9 Set Adaptive data rate status to on error = ")); + USB.println(error, DEC); + goto set868_end; + } + + error = LoRaWAN.setDataRate(4); + + // Check status + if (error == 0) { + USB.println(F("..............Data rate set OK")); + } else { + USB.print(F("2. Data rate set error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // 14. Set Automatic Reply + // set AR + error = LoRaWAN.setAR("on"); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.10 Set automatic reply status to on OK")); + } else { + USB.print(F("....... 0.1.10 Set automatic reply status to on error = ")); + USB.println(error, DEC); + goto set868_end; + } + + ///////////////////////////////////////////////// + // 6. Join OTAA to negotiate keys with the server + ///////////////////////////////////////////////// + + error = LoRaWAN.joinOTAA(); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.11 Join network OK")); + } else { + USB.print(F("....... 0.1.11 Join network error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // 15. Save configuration + + error = LoRaWAN.saveConfig(); + + // Check status + if (error == 0) { + USB.println(F("....... 0.1.12 Save configuration OK\n")); + } else { + USB.print(F("....... 0.1.12 Save configuration error = ")); + USB.println(error, DEC); + goto set868_end; + } + + // Set the flag which says the LW was set + LW_IS_SET = true; + + set868_end: + USB.println("Switching LoRa Module OFF"); + LoRaWAN.OFF(lora_socket); +} + +////==================================================================== +//// Configure 4G module +////==================================================================== +//void set4G() { +// ////////////////////////////////////////////////// +// // 1. sets operator parameters +// ////////////////////////////////////////////////// +// USB.println("SETTING 4G PARAMETERS..."); +// _4G.set_APN(apn, login, password); +// +// ////////////////////////////////////////////////// +// // 2. Show APN settings via USB port +// ////////////////////////////////////////////////// +// _4G.show_APN(); +// +// ////////////////////////////////////////////////// +// // 4. set PIN +// ////////////////////////////////////////////////// +// if(!strcmp(PIN, "")) +// return; +// +// USB.println(F("Setting PIN code...")); +// if (_4G.enterPIN(PIN) == 0) { +// USB.println(F("PIN code accepted")); +// } else { +// USB.println(F("PIN code incorrect")); +// } +//} + +//==================================================================== +// Set time from 4G +//==================================================================== +//void setTime4G() { +// USB.println(F("Setting time from 4G....")); +// error = _4G.ON(); +// +// if (error == 0) { +// USB.println(F("4G module ready...")); +// +// //////////////////////////////////////////////// +// // Check connection to network and continue +// //////////////////////////////////////////////// +// connection_status = _4G.checkDataConnection(30); +// delay(5000); +// ////////////////////////////////////////////////// +// // 3. set time +// ////////////////////////////////////////////////// +// if (connection_status == 0) { +// if (_4G.setTimeFrom4G() == 0) { +// USB.println(F("Succesufully set time from 4G")); +// NTP_IS_SYNC = true; +// } else { +// USB.println(F("Failed to get time from 4G")); +// } +// } +// } else { +// // Problem with the communication with the 4G module +// USB.println(F("4G module not started")); +// USB.print(F("Error code: ")); +// USB.println(error, DEC); +// } +// //////////////////////////////////////////////// +// // 4. Powers off the 4G module +// //////////////////////////////////////////////// +// USB.println(F("Switch OFF 4G module\n")); +// _4G.OFF(); +//} + +////==================================================================== +//// Send Data Frame 4G +////==================================================================== +//void send4G() { +// +// error = _4G.ON(); +// +// if (error == 0) { +// USB.println(F("4G module ready...")); +// +// //////////////////////////////////////////////// +// // Check connection to network and continue +// //////////////////////////////////////////////// +// connection_status = _4G.checkDataConnection(30); +// delay(5000); +// +// //////////////////////////////////////////////// +// // 3. Send to Meshlium +// //////////////////////////////////////////////// +// USB.print(F("Sending the frame...")); +// error = _4G.sendFrameToMeshlium(host, port, frame.buffer, frame.length); +// +// // check the answer +// if (error == 0) { +// USB.print(F("Done. HTTP code: ")); +// USB.println(_4G._httpCode); +// USB.print("Server response: "); +// USB.println(_4G._buffer, _4G._length); +// } else { +// USB.print(F("Failed. Error code: ")); +// USB.println(error, DEC); +// } +// } else { +// // Problem with the communication with the 4G module +// USB.println(F("4G module not started")); +// USB.print(F("Error code: ")); +// USB.println(error, DEC); +// } +// +// //////////////////////////////////////////////// +// // 4. Powers off the 4G module +// //////////////////////////////////////////////// +// USB.println(F("Switch OFF 4G module\n")); +// _4G.OFF(); +//} + +void setup() { + uint8_t error; + + // Turn ON the USB and print a start message + USB.ON(); + delay(100); + USB.println(F("\n*****************************************************")); + USB.print(F("BEIA ")); + USB.println(MOTE_ID); + USB.println(F("*****************************************************")); + + // Init RTC + RTC.ON(); + + // Function to configurate LoraWan module + set868(); + + // Set 4G + //set4G(); + + // Set time from 4G + //setTime4G(); + + // Getting time + USB.print(F("Time [Day of week, YY/MM/DD, hh:mm:ss]: ")); + USB.println(RTC.getTime()); +} + +void loop() { + // New iteration + USB.ON(); + USB.println(F("\n*****************************************************")); + USB.print(F("New iteration for BEIA ")); + USB.println(MOTE_ID); + USB.println(F("*****************************************************")); + + // Turn on RTC and get starting time + RTC.ON(); + + // Check battery level + battery = PWR.getBatteryLevel(); + USB.print(F("Battery level: ")); + USB.println(battery, DEC); + + // Step 1: Read suitable sensors + readSensors(); + + // Step 2: Create data Frame + USB.println("Create ASCII Frame"); + CreateDataFrame(ASCII); + + // Step 3: Save on SD card + writeSD(); + + // Step 4: If enough battery, send data + if (battery >= 30) { +/* + if (!NTP_IS_SYNC) { + USB.println("Time not set... retry..."); + setTime4G(); + } +*/ + if (!LW_IS_SET) { + USB.println(F("LW is not set.... retry.....")); + set868(); + } + + // Step 4.1: Send using LoRa WAN + SendDataLW(); + + // Step 4.2: Send using 4G + //send4G(); + } else { + USB.println(F("Skip seding data... battery under 30%")); + } + + USB.println(F("---------------------------------")); + USB.println(F("...Enter deep sleep mode 15 min")); + PWR.deepSleep("00:00:18:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF); + USB.ON(); + USB.print(F("...wake up!! Date: ")); + USB.println(RTC.getTime()); + + RTC.setWatchdog(720); // 12h in minutes + USB.print(F("...Watchdog :")); + USB.println(RTC.getWatchdog()); + USB.println(F("****************************************")); +} + +//*********************************************************************************************** +// END OF THE SKETCH +//*********************************************************************************************** + diff --git a/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/images/serialout_NO2.png b/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/images/serialout_NO2.png new file mode 100644 index 00000000..725ef45d Binary files /dev/null and b/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/images/serialout_NO2.png differ diff --git a/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/images/serialout_SO2.png b/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/images/serialout_SO2.png new file mode 100644 index 00000000..56fb2eb3 Binary files /dev/null and b/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/images/serialout_SO2.png differ diff --git a/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/readme.md b/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/readme.md new file mode 100644 index 00000000..5ed65457 --- /dev/null +++ b/projects/IoTBoardCode/Waspmote/TestingSensors/SCP1/readme.md @@ -0,0 +1,174 @@ +## Tested the TeleContact gas and temperature sensors + +- Temperature sensor +- SO2 sensor +- NO2 sensor +- used the SCP1 Plug and Sense station + +### Code used + +``` +/* + ------------ [SCP_v30_01] - Electrochemical gas sensors -------------- + + Explanation: This is the basic code to manage and read an electrochemical + gas sensor with Smart Cities PRO board. Electrochemical sensor list: + - CO + - O2 + - O3 + - NO + - NO2 + - SO2 + - NH3 + - H2 + - H2S + - HCl + - HCN + - PH3 + - ETO + - Cl2 + + Copyright (C) 2017 Libelium Comunicaciones Distribuidas S.L. + http://www.libelium.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Version: 3.2 + Design: David Gascón + Implementation: Alejandro Gállego +*/ + +#include + + +/* + Define object for sensor: gas_sensor + Input to choose board socket. + Waspmote OEM. Possibilities for this sensor: + - SOCKET_1 + - SOCKET_3 + - SOCKET_5 + P&S! Possibilities for this sensor: + - SOCKET_B + - SOCKET_C + - SOCKET_F +*/ +Gas gas_sensor(SOCKET_C); + +/* + Waspmote OEM. Possibilities for this sensor: + - SOCKET_1 + - SOCKET_2 + - SOCKET_3 + - SOCKET_4 + - SOCKET_5 + P&S! Possibilities for this sensor: + - SOCKET_A + - SOCKET_B + - SOCKET_C + - SOCKET_E + - SOCKET_F +*/ +bmeCitiesSensor bme(SOCKET_E); + + +// variables +float concentration; // Stores the concentration level in ppm +float temperature; // Stores the temperature in ºC +float humidity; // Stores the realitve humidity in %RH +float pressure; // Stores the pressure in Pa + + +void setup() +{ + USB.println(F("Electrochemical gas sensor example")); + USB.println(F("A BME sensor in socket A is also required")); +} + + +void loop() +{ + + /////////////////////////////////////////// + // 1. Read Temperature, humidity and pressure sensor (BME) + /////////////////////////////////////////// + + // switch off gas sensor for better performance + gas_sensor.OFF(); + // switch on BME sensor (temperature, humidity and pressure) + bme.ON(); + + // Read enviromental variables + temperature = bme.getTemperature(); + humidity = bme.getHumidity(); + pressure = bme.getPressure(); + + // switch off BME sensor (temperature, humidity and pressure) + bme.OFF(); + // switch on gas sensor again + gas_sensor.ON(); + + + /////////////////////////////////////////// + // 2. Read gas sensor + /////////////////////////////////////////// + + // Wait heating time + // some sensors demand at least one minute + // of heating time after switching them on + USB.println(F("Enter deep sleep mode to wait for electrochemical heating time...")); + PWR.deepSleep("00:00:02:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); + USB.ON(); + USB.println(F("wake up!!")); + + // Read the electrochemical sensor and compensate with the temperature internally + concentration = gas_sensor.getConc(temperature); + + // And print the values via USB + USB.println(F("***************************************")); + USB.print(F("Gas concentration: ")); + USB.printFloat(concentration, 3); + USB.println(F(" ppm")); + USB.print(F("Temperature: ")); + USB.printFloat(temperature, 3); + USB.println(F(" Celsius degrees")); + USB.print(F("RH: ")); + USB.printFloat(humidity, 3); + USB.println(F(" %")); + USB.print(F("Pressure: ")); + USB.printFloat(pressure, 3); + USB.println(F(" Pa")); + USB.println(F("***************************************")); + + + /////////////////////////////////////////// + // 3. Sleep + /////////////////////////////////////////// + + // Go to deepsleep + // After 2 minutes, Waspmote wakes up thanks to the RTC Alarm + USB.println(F("Enter deep sleep mode")); + PWR.deepSleep("00:00:02:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); + USB.ON(); + USB.println(F("wake up!!")); + +} + +``` +### Output +SO2 sensor readings +

+ +NO2 sensor readings +

\ No newline at end of file diff --git a/projects/MultiScale/README.md b/projects/MultiScale/README.md new file mode 100644 index 00000000..41a34d39 --- /dev/null +++ b/projects/MultiScale/README.md @@ -0,0 +1,25 @@ +# Libelium_Cloud + +MultiScale P&S stations +Model: Waspmote Plug&Sense! 4G EU/BR - Smart Water Ions - ID: 66641CEB19623C42 +Model: Waspmote Plug&Sense! 4G EU/BR - Smart Water - ID: 444FB2C2CB0180A8 +Model: Waspmote Plug&Sense! 4G EU/BR - Smart Agriculture Xtreme - ID: 603F18FDC337DEB1 +Model: Meshlium Scanner 4G AP EU - ID: 21347114350007 - WiFi AP ESSID: meshlium716c + + +

1. Libelium Cloud

+The Libelium devices are registered in the Libelium Cloud platform. +Link here https://cloud.libelium.com/app/home + +

+
+ +

2. SmartData System platform

+The Smart Agro Xtreme station is already registered in the platform, should be configured to send data in to SmartData platform. +Link here https://app.smartdatasystem.es/?target=auth + +

+
+ + + diff --git a/projects/MultiScale/SAX2.pde b/projects/MultiScale/SAX2.pde new file mode 100644 index 00000000..cc1a1c60 --- /dev/null +++ b/projects/MultiScale/SAX2.pde @@ -0,0 +1,430 @@ +/* + Possible sockets for this sensor is: + - XTR_SOCKET_E _________ + |---------| + | A B C | + |_D__E__F_| +*/ +#include +#include +#include + +// choose socket (SELECT USER'S SOCKET) +/////////////////////////////////////// +const uint8_t lora_socket = SOCKET0; +/////////////////////////////////////// + +//==================================================================== +// INSTANCE DEFINITION +//==================================================================== +//[Sensor Class] [Sensor Name] [Selected socket] +DatasolMET mySensor; + +//==================================================================== +// MOTE_ID +//=================================================================== +// Default device name +// TODO: Change +char *MOTE_ID = "SAX2"; + +//==================================================================== +// PARAMETERS FOR SD CARD +//=================================================================== + +char SD_FILENAME[] = "IOTDATA.TXT"; + +//==================================================================== +// PARAMETERS TO CONFIGURE 4G RADIO +//=================================================================== +// TODO: Check +char apn[] = "broadband"; +char login[] = ""; +char password[] = ""; +char PIN[] = ""; + +// SERVER settings +/////////////////////////////////////// +// TODO: Check/update +char host[] = "82.78.81.178"; +uint16_t port = 80; +/////////////////////////////////////// + +// battery control variables +uint8_t battery; +// other variables +uint8_t error; +uint8_t error_flag; +int8_t cont; +uint8_t connection_status; + +///////////////////////////////////////////////// +// Define measurement variables +//////////////////////////////////////////////// +// TODO: Add variables + +int status; + +///////////////////////////////////////////////// +// Global flags (do not change until you know what are you doing +//////////////////////////////////////////////// +bool NTP_IS_SYNC = false;; + +/* + Writes the frame to the SD card usind the following format: + When RTC is okay (set) + +\t\t\t + When RTC is not set + -\t\t*\t + Uses NTP_IS_SYNC to see if the RTC is set. + Returns true if the write is succesful. +*/ +bool writeSD(void) { + bool ok = true; + USB.println(F("--------------- Start of writeSD ------------------------")); + uint8_t sd_status = 0; + char epoch_time_str[16]; + char millis_str[16]; + + // Start SD + SD.ON(); + + // Open file + SdFile file; + sd_status = SD.openFile(SD_FILENAME, &file, O_APPEND | O_CREAT | O_RDWR); + if (sd_status == 1) { + USB.println(F("Succesfully oppened file")); + } else { + USB.println(F("Failed to open file.")); + return false; + } + + // Add newline + ok &= file.write("\n") > 0; + + if (NTP_IS_SYNC == true) { + USB.println(F("NTP is set - I will write the real time on the SD card.")); + ok &= file.write("+\t") > 0; + } else { + USB.println(F("No NTP was synced. No time available :(")); + ok &= file.write("-\t") > 0; + } + + ltoa(millis(), millis_str, 10); + ok &= file.write(millis_str) > 0; + ok &= file.write("\t") > 0; + + // Write epoch time (or *) + if (NTP_IS_SYNC) { + ltoa(RTC.getEpochTime(), epoch_time_str, 10); + ok &= file.write(epoch_time_str) > 0; + } else { + ok &= file.write("*") > 0; + } + + // Write \t before frame + ok &= file.write("\t") > 0; + + ok &= file.write(frame.buffer, frame.length) > 0; + + if (ok) { + USB.println(F("All write operation were succesful")); + } else { + USB.println(F("Some errors when writting.")); + } + // Close the file + SD.closeFile(&file); + + // Stop SD + SD.OFF(); + USB.println(F("--------------- End of writeSD ------------------------")); + return ok; +} + +//==================================================================== +// Measure the sensors +//==================================================================== +void readSensors() { + delay(100); + + // TODO: Read sensors + USB.println(F("****************************************")); + + /////////////////////////////////////////// + // 1. Read the sensors + /////////////////////////////////////////// + // 1. Turn ON the sensor + mySensor.ON(); + + // 2. Read the sensor + /* + Note: read() function does not directly return sensor values. + They are stored in the class vector variables defined for that purpose. + Values are available as a float value + */ + mySensor.read(); + + // 3. Turn off the sensor + mySensor.OFF(); + + // 4. Print information + USB.println(F("---------------------------")); + USB.println(F("Datasol MET")); + USB.print(F("Measured radiation: ")); + USB.print(mySensor.sensorDatasolMET.radiation); + USB.println(F(" W/m2")); + USB.print(F("Semi-cell 1 radiation: ")); + USB.print(mySensor.sensorDatasolMET.semicell1Radiation); + USB.println(F(" W/m2")); + USB.print(F("Semi-cell 2 radiation: ")); + USB.print(mySensor.sensorDatasolMET.semicell2Radiation); + USB.println(F(" W/m2")); + USB.print(F("Environment temperature: ")); + USB.printFloat(mySensor.sensorDatasolMET.environmentTemperature, 1); + USB.println(F(" degrees Celsius")); + USB.print(F("Panel temperature: ")); + USB.printFloat(mySensor.sensorDatasolMET.panelTemperature, 1); + USB.println(F(" degrees Celsius")); + USB.print(F("Peak sun hours: ")); + USB.printFloat(mySensor.sensorDatasolMET.peakSunHours, 2); + USB.println(F(" hours")); + USB.print(F("Necessary cleaning notice: ")); + USB.println(mySensor.sensorDatasolMET.necessaryCleaningNotice); + USB.print(F("Wind speed: ")); + USB.printFloat(mySensor.sensorDatasolMET.windSpeed, 1); + USB.println(F(" m/s")); + USB.println(F("---------------------------\n")); + + delay(5000); + + USB.println(F("... *************************************")); +} + +//==================================================================== +// Create a Data Frame Lorawan +//==================================================================== +void CreateDataFrame(uint8_t frame_type) { + USB.println(F("..CREATING FRAME PROCESS ")); + + frame.createFrame(frame_type, MOTE_ID); + frame.addTimestamp(); + // set frame fields (Sensors Values) + // frame.createFrame(BINARY, node_ID); // frame2 + frame.setFrameType(INFORMATION_FRAME_AGR_XTR); + + frame.addSensor(SENSOR_BAT, PWR.getBatteryLevel()); + // frame.addSensor(SENSOR_TIME, RTC.getTimestamp()); + frame.addSensor(AGRX_DATASOL_RAD, mySensor.sensorDatasolMET.radiation); + frame.addSensor(AGRX_DATASOL_SC1_RAD, mySensor.sensorDatasolMET.semicell1Radiation); + frame.addSensor(AGRX_DATASOL_SC2_RAD, mySensor.sensorDatasolMET.semicell2Radiation); + frame.addSensor(AGRX_DATASOL_ETC, mySensor.sensorDatasolMET.environmentTemperature, 1); + frame.addSensor(AGRX_DATASOL_PTC, mySensor.sensorDatasolMET.panelTemperature, 1); + frame.addSensor(AGRX_DATASOL_PSH, mySensor.sensorDatasolMET.peakSunHours, 2); + frame.addSensor(AGRX_DATASOL_NCN, mySensor.sensorDatasolMET.necessaryCleaningNotice); + + //#define AGRX_DATASOL_RAD 95 + //#define AGRX_DATASOL_SC1_RAD 96 + //#define AGRX_DATASOL_SC2_RAD 97 + //#define AGRX_DATASOL_ETC 98 + //#define AGRX_DATASOL_PTC 99 + //#define AGRX_DATASOL_WSP 100 + //#define AGRX_DATASOL_PSH 101 + //#define AGRX_DATASOL_NCN + frame.showFrame(); +} + +//==================================================================== +// Configure 4G module +//==================================================================== +void set4G() { + ////////////////////////////////////////////////// + // 1. sets operator parameters + ////////////////////////////////////////////////// + USB.println("SETTING 4G PARAMETERS..."); + _4G.set_APN(apn, login, password); + + ////////////////////////////////////////////////// + // 2. Show APN settings via USB port + ////////////////////////////////////////////////// + _4G.show_APN(); + + ////////////////////////////////////////////////// + // 4. set PIN + ////////////////////////////////////////////////// + if (!strcmp(PIN, "")) + return; + + USB.println(F("Setting PIN code...")); + if (_4G.enterPIN(PIN) == 0) { + USB.println(F("PIN code accepted")); + } else { + USB.println(F("PIN code incorrect")); + } +} + +//==================================================================== +// Set time from 4G +//==================================================================== +void setTime4G() { + USB.println(F("Setting time from 4G....")); + error = _4G.ON(); + + if (error == 0) { + USB.println(F("4G module ready...")); + + //////////////////////////////////////////////// + // Check connection to network and continue + //////////////////////////////////////////////// + connection_status = _4G.checkDataConnection(30); + delay(5000); + ////////////////////////////////////////////////// + // 3. set time + ////////////////////////////////////////////////// + if (connection_status == 0) { + if (_4G.setTimeFrom4G() == 0) { + USB.println(F("Succesufully set time from 4G")); + NTP_IS_SYNC = true; + } else { + USB.println(F("Failed to get time from 4G")); + } + } + } else { + // Problem with the communication with the 4G module + USB.println(F("4G module not started")); + USB.print(F("Error code: ")); + USB.println(error, DEC); + } + //////////////////////////////////////////////// + // 4. Powers off the 4G module + //////////////////////////////////////////////// + USB.println(F("Switch OFF 4G module\n")); + _4G.OFF(); +} + +//==================================================================== +// Send Data Frame 4G +//==================================================================== +void send4G() { + + error = _4G.ON(); + + if (error == 0) { + USB.println(F("4G module ready...")); + + //////////////////////////////////////////////// + // Check connection to network and continue + //////////////////////////////////////////////// + connection_status = _4G.checkDataConnection(30); + delay(5000); + + //////////////////////////////////////////////// + // 3. Send to Meshlium + //////////////////////////////////////////////// + USB.print(F("Sending the frame...")); + error = _4G.sendFrameToMeshlium(host, port, frame.buffer, frame.length); + + // check the answer + if (error == 0) { + USB.print(F("Done. HTTP code: ")); + USB.println(_4G._httpCode); + USB.print("Server response: "); + USB.println(_4G._buffer, _4G._length); + } else { + USB.print(F("Failed. Error code: ")); + USB.println(error, DEC); + } + } else { + // Problem with the communication with the 4G module + USB.println(F("4G module not started")); + USB.print(F("Error code: ")); + USB.println(error, DEC); + } + + //////////////////////////////////////////////// + // 4. Powers off the 4G module + //////////////////////////////////////////////// + USB.println(F("Switch OFF 4G module\n")); + _4G.OFF(); +} + +void setup() { + uint8_t error; + + // Turn ON the USB and print a start message + USB.ON(); + delay(100); + USB.println(F("\n*****************************************************")); + USB.print(F("BEIA ")); + USB.println(MOTE_ID); + USB.println(F("*****************************************************")); + + // Init RTC + RTC.ON(); + + // Set 4G + set4G(); + + // Set time from 4G + setTime4G(); + + // Getting time + USB.print(F("Time [Day of week, YY/MM/DD, hh:mm:ss]: ")); + USB.println(RTC.getTime()); +} + +void loop() { + // New iteration + USB.ON(); + USB.println(F("\n*****************************************************")); + USB.print(F("New iteration for BEIA ")); + USB.println(MOTE_ID); + USB.println(F("*****************************************************")); + + // Turn on RTC and get starting time + RTC.ON(); + + // Check battery level + battery = PWR.getBatteryLevel(); + USB.print(F("Battery level: ")); + USB.println(battery, DEC); + + // Step 1: Read suitable sensors + readSensors(); + + // Step 2: Create data Frame + USB.println("Create ASCII Frame"); + CreateDataFrame(ASCII); + + // Step 3: Save on SD card + writeSD(); + + // Step 4: If enough battery, send data + if (battery >= 30) { + + if (!NTP_IS_SYNC) { + USB.println("Time not set... retry..."); + setTime4G(); + } + + // Step 4.1: Send using 4G + CreateDataFrame(BINARY); + send4G(); + } else { + USB.println(F("Skip seding data... battery under 30%")); + } + + USB.println(F("---------------------------------")); + USB.println(F("...Enter deep sleep mode 30 min")); + PWR.deepSleep("00:00:30:00", RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF); + USB.ON(); + USB.print(F("...wake up!! Date: ")); + USB.println(RTC.getTime()); + + RTC.setWatchdog(720); // 12h in minutes + USB.print(F("...Watchdog :")); + USB.println(RTC.getWatchdog()); + USB.println(F("****************************************")); +} + +//*********************************************************************************************** +// END OF THE SKETCH +//*********************************************************************************************** \ No newline at end of file diff --git a/projects/MultiScale/images/LibeliumCloud.png b/projects/MultiScale/images/LibeliumCloud.png new file mode 100644 index 00000000..bd218e42 Binary files /dev/null and b/projects/MultiScale/images/LibeliumCloud.png differ diff --git a/projects/MultiScale/images/SmartDataSystem.png b/projects/MultiScale/images/SmartDataSystem.png new file mode 100644 index 00000000..5226a6c0 Binary files /dev/null and b/projects/MultiScale/images/SmartDataSystem.png differ diff --git a/projects/MultiScale/images/devicesmeniu.png b/projects/MultiScale/images/devicesmeniu.png new file mode 100644 index 00000000..32223ab2 Binary files /dev/null and b/projects/MultiScale/images/devicesmeniu.png differ diff --git a/projects/MultiScale/images/maindashboard.png b/projects/MultiScale/images/maindashboard.png new file mode 100644 index 00000000..4c82769a Binary files /dev/null and b/projects/MultiScale/images/maindashboard.png differ