Difference between revisions of "Smart environment PRO"
From AMTech WikiDocs
(Created page with "=== Smart environment PRO === *Supports the following sensors") |
|||
(9 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=== Smart environment PRO === | === Smart environment PRO === | ||
− | * | + | *id Gases_PRO 19 |
+ | *Bridge waspmote following sensors read to to IoT DAP | ||
+ | #Device Temperature IN_TEMP | ||
+ | #Battery level BAT | ||
+ | #Acceleromete X,Y,Z ACC | ||
+ | #Chlorine GP_CL2 | ||
+ | #Carbon Monoxide GP_CO | ||
+ | #Ethylene Oxide GP_ETO | ||
+ | #Hydrogen GP_H2 | ||
+ | #Hydrogen Sulphide GP_H2S | ||
+ | #Hydrogen Chloride GP_HCL | ||
+ | #Hydrogen Cyanide GP_HCN | ||
+ | #Ammonia GP_NH3 | ||
+ | #Nitrogen Monoxide GP_NO | ||
+ | #Nitrogen GP_NO2 | ||
+ | #Oxygen GP_O2 | ||
+ | #Phospine GP_PH3 | ||
+ | #Sulfur GP_SO2 | ||
+ | #Methane GP_CH4 | ||
+ | #Ozone GP_O3 | ||
+ | #Carbon Dioxide GP_CO2 | ||
+ | #Temperature Celsius GP_TC | ||
+ | #Temperature Fahrenheit GP_TF | ||
+ | #Humidity GP_HUM | ||
+ | #Pressure GP_PRES | ||
+ | * Edge Intelligence | ||
+ | **[[Smoothing_observations|Smoothing observations]] | ||
+ | * Placeholders (See [[Sensor%27s_network#Placeholders_substitution|Placeholders]]) | ||
+ | ** #{waspmoteName} waspmote model name | ||
+ | ** #{waspmoteId} waspmote model numeric unique identifier | ||
+ | ** #{blePeripheralUuid} ble unique id identifier | ||
+ | |||
+ | * Produced observations (see /amtech/linkeddata/types/composite/observation) | ||
+ | ** /amtech/linkeddata/types/composite/observation/waspmoteSmartEnvironment | ||
+ | |||
+ | *[https://www.arduino.cc/en/tutorial/sketch Arduino sketch] for Smart environment PRO configure with following sensors | ||
+ | **SENSOR_ACC ,SENSOR_BAT, SENSOR_IN_TEMP , SENSOR_GP_TC, SENSOR_GP_HUM, SENSOR_GP_PRES, SENSOR_GP_CH4, SENSOR_GP_NO2, SENSOR_GP_O2, SENSOR_GP_CO | ||
+ | <syntaxhighlight lang="c"> | ||
+ | /* | ||
+ | * ------Waspmote starting program------ | ||
+ | * | ||
+ | * Explanation: Send basic parameters through the corresponding | ||
+ | * XBee module. | ||
+ | * For other communication modules please use on line code generator. | ||
+ | * | ||
+ | * Copyright (C) 2015 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 <http://www.gnu.org/licenses/>. | ||
+ | */ | ||
+ | |||
+ | // Include libraries | ||
+ | #include <WaspFrame.h> | ||
+ | #include <WaspBLE.h> | ||
+ | #include <WaspSensorGas_Pro.h> | ||
+ | // Define the Waspmote default ID | ||
+ | char deviceName[] = "WBLE"; | ||
+ | // Variable to store advertisement data | ||
+ | uint8_t advData[31]; | ||
+ | char sv[32]; | ||
+ | // Define the authentication key | ||
+ | char key_access[] = "LIBELIUM"; | ||
+ | uint8_t flag =0; | ||
+ | |||
+ | Gas O2(SOCKET_A); | ||
+ | Gas CH4(SOCKET_B); | ||
+ | Gas NO2(SOCKET_C); | ||
+ | Gas CO(SOCKET_F); | ||
+ | |||
+ | float o2_concentration; | ||
+ | float ch4_concentration; | ||
+ | float no2_concentration; | ||
+ | float co_concentration; | ||
+ | float temperature; | ||
+ | float humidity; | ||
+ | float pressure; | ||
+ | |||
+ | uint16_t aux = 0; | ||
+ | uint8_t msgNumber = 0; | ||
+ | |||
+ | #define AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xff; | ||
+ | #define Gases_PRO 19 | ||
+ | #define LIBELIUM_BLEID 0x88; | ||
+ | //#define TOTAL_SENSORS 10; | ||
+ | //#define SENSORS_MSG 5 | ||
+ | |||
+ | void showValue(float val, char *sensorName, int pos){ | ||
+ | memset(sv, 0x00, sizeof(sv)); | ||
+ | dtostrf(val,1,2,sv); | ||
+ | USB.printf("%s Valor = %s pos %d\n", sensorName, sv, pos); | ||
+ | |||
+ | } | ||
+ | |||
+ | void showACCValues( int x, int y, int z, int pos ){ | ||
+ | sprintf(sv, "%d,%d,%d",x, y, z ); | ||
+ | USB.printf("SENSOR_ACC Valor = %s pos %d\n", sv, pos); | ||
+ | } | ||
+ | |||
+ | |||
+ | /* | ||
+ | * AD_TYPE_MANUFACTURER_SPECIFIC_DATA (1) LIBELIUM_BLEID (1) Gases_PRO (1) TOTAL_SENSORS (1) SENSORS_MSG (1) | ||
+ | * SENSOR_ACC (1 + 6) SENSOR_BAT (1 + 1), SENSOR_IN_TEMP (1 + 4) , SENSOR_GP_TC (1 + 4 ) SENSOR_GP_HUM ( 1+ 4) [29] | ||
+ | */ | ||
+ | #define MSGADDITIONAL_SIZE 29; | ||
+ | int buildAdditionalSensors() | ||
+ | { | ||
+ | int ms = 0; ; | ||
+ | memset(advData, 0x00, sizeof(advData)); | ||
+ | advData[ms++]= MSGADDITIONAL_SIZE; | ||
+ | advData[ms++]= AD_TYPE_MANUFACTURER_SPECIFIC_DATA; | ||
+ | advData[ms++] = LIBELIUM_BLEID; | ||
+ | advData[ms++] = Gases_PRO; | ||
+ | //byte result = (byte)(number1 | (number2 << 4)); | ||
+ | advData[ms++] = (uint8_t)(10 | (5 <<4)); | ||
+ | advData[ms++] = msgNumber++; | ||
+ | showValue(msgNumber, "msgNumber", ms); | ||
+ | //1 SENSOR_ACC | ||
+ | advData[ms++] = SENSOR_ACC; | ||
+ | int x = ACC.getX(); | ||
+ | int y = ACC.getY(); | ||
+ | int z = ACC.getZ(); | ||
+ | memcpy( &advData[ms], &x, sizeof(int) ); | ||
+ | ms += sizeof(int); | ||
+ | memcpy( &advData[ms], &y, sizeof(int) ); | ||
+ | ms += sizeof(int); | ||
+ | memcpy( &advData[ms], &z, sizeof(int) ); | ||
+ | ms += sizeof(int); | ||
+ | showACCValues(x,y,z, ms); | ||
+ | //2S ENSOR_BAT | ||
+ | advData[ms++] = SENSOR_BAT; | ||
+ | uint8_t vuint = PWR.getBatteryLevel(); | ||
+ | memcpy( &advData[ms], &vuint, sizeof(uint8_t) ); | ||
+ | ms += sizeof(uint8_t); | ||
+ | showValue(vuint, "SENSOR_BAT", ms); | ||
+ | //3 SENSOR_IN_TEMP | ||
+ | advData[ms++] = SENSOR_IN_TEMP; | ||
+ | float vfloat = RTC.getTemperature(); | ||
+ | memcpy( &advData[ms], &vfloat, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(vfloat, "SENSOR_IN_TEMP", ms); | ||
+ | //4 SENSOR_GP_TC | ||
+ | advData[ms++] = SENSOR_GP_TC; | ||
+ | memcpy( &advData[ms], &temperature, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(temperature, "SENSOR_GP_TC", ms); | ||
+ | //5 SENSOR_GP_HUM | ||
+ | advData[ms++] = SENSOR_GP_HUM; | ||
+ | memcpy( &advData[ms], &humidity, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(humidity, "SENSOR_GP_HUM", ms); | ||
+ | return ms; | ||
+ | } | ||
+ | |||
+ | |||
+ | /* | ||
+ | * LIBELIUM_BLEID (1) Gases_PRO (1) TOTAL_SENSORS (1) SENSORS_MSG (1) SENSOR_GP_PRES ( 1+ 4) SENSOR_GP_CH4 ( 1+ 4) SENSOR_GP_NO2 ( 1+ 4) SENSOR_GP_O2 ( 1+ 4) SENSOR_GP_CO ( 1+ 4) [30] | ||
+ | */ | ||
+ | #define MSGSENSORS_SIZE 30 | ||
+ | int buildSensors() | ||
+ | { | ||
+ | int ms = 0; ; | ||
+ | memset(advData, 0x00, sizeof(advData)); | ||
+ | advData[ms++]= MSGSENSORS_SIZE; | ||
+ | advData[ms++]= AD_TYPE_MANUFACTURER_SPECIFIC_DATA; | ||
+ | advData[ms++] = LIBELIUM_BLEID; | ||
+ | advData[ms++] = Gases_PRO; | ||
+ | advData[ms++] = (uint8_t)(10 | (5 <<4)); | ||
+ | advData[ms++] = msgNumber++; | ||
+ | showValue(msgNumber, "msgNumber", ms); | ||
+ | //1 SENSOR_GP_PRES | ||
+ | advData[ms++] = SENSOR_GP_PRES; | ||
+ | memcpy( &advData[ms], &pressure, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(pressure, "SENSOR_GP_PRES", ms); | ||
+ | //2 SENSOR_GP_CH4 | ||
+ | advData[ms++] = SENSOR_GP_CH4; | ||
+ | memcpy( &advData[ms], &ch4_concentration, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(ch4_concentration, "SENSOR_GP_CH4", ms); | ||
+ | //3 SENSOR_GP_NO2 | ||
+ | advData[ms++] = SENSOR_GP_NO2; | ||
+ | memcpy( &advData[ms], &no2_concentration, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(no2_concentration, "SENSOR_GP_NO2", ms); | ||
+ | //4 SENSOR_GP_O2 | ||
+ | advData[ms++] = SENSOR_GP_O2; | ||
+ | memcpy( &advData[ms], &o2_concentration, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(o2_concentration, "SENSOR_GP_O2", ms); | ||
+ | //5 SENSOR_GP_CO | ||
+ | advData[ms++] = SENSOR_GP_CO; | ||
+ | memcpy( &advData[ms], &co_concentration, sizeof(float) ); | ||
+ | ms += sizeof(float); | ||
+ | showValue(co_concentration, "SENSOR_GP_CO", ms); | ||
+ | return ms; | ||
+ | } | ||
+ | |||
+ | void print_hex_memory(void *mem, int len) { | ||
+ | int i; | ||
+ | USB.printf("Len %d ==>", len); | ||
+ | unsigned char *p = (unsigned char *)mem; | ||
+ | for (i=0;i<len;i++) { | ||
+ | USB.printf("0x%02x ", p[i]); | ||
+ | if ((i%16==0) && i) | ||
+ | USB.printf("\n"); | ||
+ | } | ||
+ | USB.printf("\n"); | ||
+ | } | ||
+ | |||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | /////////////////////////////////////// | ||
+ | // Boards ON //////////////////// | ||
+ | /////////////////////////////////////// | ||
+ | PWR.setSensorPower(SENS_3V3, SENS_ON); | ||
+ | |||
+ | ///////////////////////////////// | ||
+ | // 2. Store key access in EEPROM | ||
+ | ///////////////////////////////// | ||
+ | Utils.setAuthKey(key_access); | ||
+ | |||
+ | ///////////////////////////////// | ||
+ | // 3. Set up RTC and ACC | ||
+ | ///////////////////////////////// | ||
+ | delay(500); | ||
+ | |||
+ | ///////////////////////////////// | ||
+ | // 8. Print module information | ||
+ | ///////////////////////////////// | ||
+ | USB.println(F("\nStarting program by default")); | ||
+ | |||
+ | USB.println(F("BLE module is plugged on socket 0:")); | ||
+ | |||
+ | USB.println(F(" Configuration:")); | ||
+ | |||
+ | RTC.ON(); | ||
+ | ACC.ON(); | ||
+ | |||
+ | O2.ON(); | ||
+ | CH4.ON(); | ||
+ | NO2.ON(); | ||
+ | CO.ON(); | ||
+ | |||
+ | PWR.deepSleep("00:00:00:03", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON); | ||
+ | |||
+ | ///////////////////////////////// | ||
+ | // 5. LEDs management | ||
+ | ///////////////////////////////// | ||
+ | Utils.setLED(LED0, LED_OFF); | ||
+ | Utils.setLED(LED1, LED_OFF); | ||
+ | for (int i = 0 ; i < 4 ; i++) | ||
+ | { | ||
+ | Utils.blinkLEDs(100); | ||
+ | } | ||
+ | |||
+ | // 0. Turn BLE module ON | ||
+ | BLE.ON(SOCKET0); | ||
+ | |||
+ | |||
+ | // Write the local attribute containing the device name | ||
+ | flag = BLE.writeLocalAttribute(3, deviceName); | ||
+ | |||
+ | if (flag == 0) | ||
+ | { | ||
+ | USB.println("Name written"); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | USB.print("Error writing. flag ="); | ||
+ | USB.println(flag, DEC); | ||
+ | } | ||
+ | |||
+ | |||
+ | // 2. Print MAC address | ||
+ | USB.print("BLE MAC is: "); | ||
+ | USB.println(BLE.getOwnMac()); | ||
+ | BLE.setConnectableMode(BLE_GAP_UNDIRECTED_CONNECTABLE); | ||
+ | |||
+ | // 1.8 Wake up again to allow receiving new commands. | ||
+ | //aux = BLE.wakeUp(); | ||
+ | //BLE.sleep(); | ||
+ | USB.println(F("===============================")); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | USB.println(F("==========start loop=====================")); | ||
+ | // set Green LED | ||
+ | Utils.setLED(LED1,LED_ON); | ||
+ | //read sensors | ||
+ | o2_concentration = O2.getConc(); | ||
+ | ch4_concentration = CH4.getConc(); | ||
+ | no2_concentration = NO2.getConc(); | ||
+ | co_concentration = CO.getConc(); | ||
+ | temperature = O2.getTemp(1); | ||
+ | humidity = O2.getHumidity(); | ||
+ | pressure = O2.getPressure(); | ||
+ | |||
+ | int len; | ||
+ | |||
+ | |||
+ | for (int i = 0 ; i < 2; i++) | ||
+ | { | ||
+ | if (msgNumber==0xff) | ||
+ | { | ||
+ | msgNumber= 0; | ||
+ | } | ||
+ | |||
+ | aux = BLE.wakeUp(); | ||
+ | /* NOTE 1: after turning BLE module ON, the default state | ||
+ | is non discoverable. | ||
+ | */ | ||
+ | /* NOTE 2: If you are currently advertising, then any changes | ||
+ | on the advertisement data will not take effect until you | ||
+ | stop and re-start advertising again. | ||
+ | */ | ||
+ | // 1.1 Make device no discoverable to stop advertisement. | ||
+ | aux = BLE.setDiscoverableMode(BLE_GAP_NON_DISCOVERABLE); | ||
+ | USB.println(F("\tA - Stop advertisements")); | ||
+ | |||
+ | // 1.2 Set advertisement interval of 100 ms and three channels | ||
+ | /* NOTE 3: intervals are specified in units of 625 uS | ||
+ | Example: 1000 ms / 0.625 = 1600 | ||
+ | */ | ||
+ | aux = BLE.setAdvParameters(1600, 1600, 7); | ||
+ | USB.println(F("\tB - Setting advertisement interval")); | ||
+ | |||
+ | if(i== 0){ | ||
+ | //Additional sensors | ||
+ | len = buildAdditionalSensors(); | ||
+ | }else{ | ||
+ | // 1.3 Set Advertisement with sensor read value. | ||
+ | len = buildSensors(); | ||
+ | } | ||
+ | BLE.setAdvData(BLE_GAP_ADVERTISEMENT, advData, len); | ||
+ | //BLE.setAdvData(BLE_GAP_SCAN_RESPONSE, advData, len); | ||
+ | |||
+ | USB.print(F("Advertisement = ")); | ||
+ | USB.println(F("\tC - Setting advertisements data to: ")); | ||
+ | print_hex_memory(&advData, len); | ||
+ | |||
+ | // 1.4 Set discoverable mode to user data to start advertising | ||
+ | // with custom data | ||
+ | aux = BLE.setDiscoverableMode(BLE_GAP_USER_DATA); | ||
+ | USB.println(F("\tD - Start advertisements")); | ||
+ | |||
+ | // 1.5 Go to sleep and but remain advertising to save power. | ||
+ | BLE.sleep(); | ||
+ | delay(1000); | ||
+ | } | ||
+ | |||
+ | |||
+ | USB.println(F("============end loop===================")); | ||
+ | |||
+ | //PWR.deepSleep("00:00:00:30", RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF); | ||
+ | //delay(1000); | ||
+ | } | ||
+ | </syntaxhighlight> |
Latest revision as of 13:12, 2 February 2018
Smart environment PRO
- id Gases_PRO 19
- Bridge waspmote following sensors read to to IoT DAP
- Device Temperature IN_TEMP
- Battery level BAT
- Acceleromete X,Y,Z ACC
- Chlorine GP_CL2
- Carbon Monoxide GP_CO
- Ethylene Oxide GP_ETO
- Hydrogen GP_H2
- Hydrogen Sulphide GP_H2S
- Hydrogen Chloride GP_HCL
- Hydrogen Cyanide GP_HCN
- Ammonia GP_NH3
- Nitrogen Monoxide GP_NO
- Nitrogen GP_NO2
- Oxygen GP_O2
- Phospine GP_PH3
- Sulfur GP_SO2
- Methane GP_CH4
- Ozone GP_O3
- Carbon Dioxide GP_CO2
- Temperature Celsius GP_TC
- Temperature Fahrenheit GP_TF
- Humidity GP_HUM
- Pressure GP_PRES
- Edge Intelligence
- Placeholders (See Placeholders)
- #{waspmoteName} waspmote model name
- #{waspmoteId} waspmote model numeric unique identifier
- #{blePeripheralUuid} ble unique id identifier
- Produced observations (see /amtech/linkeddata/types/composite/observation)
- /amtech/linkeddata/types/composite/observation/waspmoteSmartEnvironment
- Arduino sketch for Smart environment PRO configure with following sensors
- SENSOR_ACC ,SENSOR_BAT, SENSOR_IN_TEMP , SENSOR_GP_TC, SENSOR_GP_HUM, SENSOR_GP_PRES, SENSOR_GP_CH4, SENSOR_GP_NO2, SENSOR_GP_O2, SENSOR_GP_CO
/*
* ------Waspmote starting program------
*
* Explanation: Send basic parameters through the corresponding
* XBee module.
* For other communication modules please use on line code generator.
*
* Copyright (C) 2015 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 <http://www.gnu.org/licenses/>.
*/
// Include libraries
#include <WaspFrame.h>
#include <WaspBLE.h>
#include <WaspSensorGas_Pro.h>
// Define the Waspmote default ID
char deviceName[] = "WBLE";
// Variable to store advertisement data
uint8_t advData[31];
char sv[32];
// Define the authentication key
char key_access[] = "LIBELIUM";
uint8_t flag =0;
Gas O2(SOCKET_A);
Gas CH4(SOCKET_B);
Gas NO2(SOCKET_C);
Gas CO(SOCKET_F);
float o2_concentration;
float ch4_concentration;
float no2_concentration;
float co_concentration;
float temperature;
float humidity;
float pressure;
uint16_t aux = 0;
uint8_t msgNumber = 0;
#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xff;
#define Gases_PRO 19
#define LIBELIUM_BLEID 0x88;
//#define TOTAL_SENSORS 10;
//#define SENSORS_MSG 5
void showValue(float val, char *sensorName, int pos){
memset(sv, 0x00, sizeof(sv));
dtostrf(val,1,2,sv);
USB.printf("%s Valor = %s pos %d\n", sensorName, sv, pos);
}
void showACCValues( int x, int y, int z, int pos ){
sprintf(sv, "%d,%d,%d",x, y, z );
USB.printf("SENSOR_ACC Valor = %s pos %d\n", sv, pos);
}
/*
* AD_TYPE_MANUFACTURER_SPECIFIC_DATA (1) LIBELIUM_BLEID (1) Gases_PRO (1) TOTAL_SENSORS (1) SENSORS_MSG (1)
* SENSOR_ACC (1 + 6) SENSOR_BAT (1 + 1), SENSOR_IN_TEMP (1 + 4) , SENSOR_GP_TC (1 + 4 ) SENSOR_GP_HUM ( 1+ 4) [29]
*/
#define MSGADDITIONAL_SIZE 29;
int buildAdditionalSensors()
{
int ms = 0; ;
memset(advData, 0x00, sizeof(advData));
advData[ms++]= MSGADDITIONAL_SIZE;
advData[ms++]= AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
advData[ms++] = LIBELIUM_BLEID;
advData[ms++] = Gases_PRO;
//byte result = (byte)(number1 | (number2 << 4));
advData[ms++] = (uint8_t)(10 | (5 <<4));
advData[ms++] = msgNumber++;
showValue(msgNumber, "msgNumber", ms);
//1 SENSOR_ACC
advData[ms++] = SENSOR_ACC;
int x = ACC.getX();
int y = ACC.getY();
int z = ACC.getZ();
memcpy( &advData[ms], &x, sizeof(int) );
ms += sizeof(int);
memcpy( &advData[ms], &y, sizeof(int) );
ms += sizeof(int);
memcpy( &advData[ms], &z, sizeof(int) );
ms += sizeof(int);
showACCValues(x,y,z, ms);
//2S ENSOR_BAT
advData[ms++] = SENSOR_BAT;
uint8_t vuint = PWR.getBatteryLevel();
memcpy( &advData[ms], &vuint, sizeof(uint8_t) );
ms += sizeof(uint8_t);
showValue(vuint, "SENSOR_BAT", ms);
//3 SENSOR_IN_TEMP
advData[ms++] = SENSOR_IN_TEMP;
float vfloat = RTC.getTemperature();
memcpy( &advData[ms], &vfloat, sizeof(float) );
ms += sizeof(float);
showValue(vfloat, "SENSOR_IN_TEMP", ms);
//4 SENSOR_GP_TC
advData[ms++] = SENSOR_GP_TC;
memcpy( &advData[ms], &temperature, sizeof(float) );
ms += sizeof(float);
showValue(temperature, "SENSOR_GP_TC", ms);
//5 SENSOR_GP_HUM
advData[ms++] = SENSOR_GP_HUM;
memcpy( &advData[ms], &humidity, sizeof(float) );
ms += sizeof(float);
showValue(humidity, "SENSOR_GP_HUM", ms);
return ms;
}
/*
* LIBELIUM_BLEID (1) Gases_PRO (1) TOTAL_SENSORS (1) SENSORS_MSG (1) SENSOR_GP_PRES ( 1+ 4) SENSOR_GP_CH4 ( 1+ 4) SENSOR_GP_NO2 ( 1+ 4) SENSOR_GP_O2 ( 1+ 4) SENSOR_GP_CO ( 1+ 4) [30]
*/
#define MSGSENSORS_SIZE 30
int buildSensors()
{
int ms = 0; ;
memset(advData, 0x00, sizeof(advData));
advData[ms++]= MSGSENSORS_SIZE;
advData[ms++]= AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
advData[ms++] = LIBELIUM_BLEID;
advData[ms++] = Gases_PRO;
advData[ms++] = (uint8_t)(10 | (5 <<4));
advData[ms++] = msgNumber++;
showValue(msgNumber, "msgNumber", ms);
//1 SENSOR_GP_PRES
advData[ms++] = SENSOR_GP_PRES;
memcpy( &advData[ms], &pressure, sizeof(float) );
ms += sizeof(float);
showValue(pressure, "SENSOR_GP_PRES", ms);
//2 SENSOR_GP_CH4
advData[ms++] = SENSOR_GP_CH4;
memcpy( &advData[ms], &ch4_concentration, sizeof(float) );
ms += sizeof(float);
showValue(ch4_concentration, "SENSOR_GP_CH4", ms);
//3 SENSOR_GP_NO2
advData[ms++] = SENSOR_GP_NO2;
memcpy( &advData[ms], &no2_concentration, sizeof(float) );
ms += sizeof(float);
showValue(no2_concentration, "SENSOR_GP_NO2", ms);
//4 SENSOR_GP_O2
advData[ms++] = SENSOR_GP_O2;
memcpy( &advData[ms], &o2_concentration, sizeof(float) );
ms += sizeof(float);
showValue(o2_concentration, "SENSOR_GP_O2", ms);
//5 SENSOR_GP_CO
advData[ms++] = SENSOR_GP_CO;
memcpy( &advData[ms], &co_concentration, sizeof(float) );
ms += sizeof(float);
showValue(co_concentration, "SENSOR_GP_CO", ms);
return ms;
}
void print_hex_memory(void *mem, int len) {
int i;
USB.printf("Len %d ==>", len);
unsigned char *p = (unsigned char *)mem;
for (i=0;i<len;i++) {
USB.printf("0x%02x ", p[i]);
if ((i%16==0) && i)
USB.printf("\n");
}
USB.printf("\n");
}
void setup()
{
///////////////////////////////////////
// Boards ON ////////////////////
///////////////////////////////////////
PWR.setSensorPower(SENS_3V3, SENS_ON);
/////////////////////////////////
// 2. Store key access in EEPROM
/////////////////////////////////
Utils.setAuthKey(key_access);
/////////////////////////////////
// 3. Set up RTC and ACC
/////////////////////////////////
delay(500);
/////////////////////////////////
// 8. Print module information
/////////////////////////////////
USB.println(F("\nStarting program by default"));
USB.println(F("BLE module is plugged on socket 0:"));
USB.println(F(" Configuration:"));
RTC.ON();
ACC.ON();
O2.ON();
CH4.ON();
NO2.ON();
CO.ON();
PWR.deepSleep("00:00:00:03", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON);
/////////////////////////////////
// 5. LEDs management
/////////////////////////////////
Utils.setLED(LED0, LED_OFF);
Utils.setLED(LED1, LED_OFF);
for (int i = 0 ; i < 4 ; i++)
{
Utils.blinkLEDs(100);
}
// 0. Turn BLE module ON
BLE.ON(SOCKET0);
// Write the local attribute containing the device name
flag = BLE.writeLocalAttribute(3, deviceName);
if (flag == 0)
{
USB.println("Name written");
}
else
{
USB.print("Error writing. flag =");
USB.println(flag, DEC);
}
// 2. Print MAC address
USB.print("BLE MAC is: ");
USB.println(BLE.getOwnMac());
BLE.setConnectableMode(BLE_GAP_UNDIRECTED_CONNECTABLE);
// 1.8 Wake up again to allow receiving new commands.
//aux = BLE.wakeUp();
//BLE.sleep();
USB.println(F("==============================="));
}
void loop()
{
USB.println(F("==========start loop====================="));
// set Green LED
Utils.setLED(LED1,LED_ON);
//read sensors
o2_concentration = O2.getConc();
ch4_concentration = CH4.getConc();
no2_concentration = NO2.getConc();
co_concentration = CO.getConc();
temperature = O2.getTemp(1);
humidity = O2.getHumidity();
pressure = O2.getPressure();
int len;
for (int i = 0 ; i < 2; i++)
{
if (msgNumber==0xff)
{
msgNumber= 0;
}
aux = BLE.wakeUp();
/* NOTE 1: after turning BLE module ON, the default state
is non discoverable.
*/
/* NOTE 2: If you are currently advertising, then any changes
on the advertisement data will not take effect until you
stop and re-start advertising again.
*/
// 1.1 Make device no discoverable to stop advertisement.
aux = BLE.setDiscoverableMode(BLE_GAP_NON_DISCOVERABLE);
USB.println(F("\tA - Stop advertisements"));
// 1.2 Set advertisement interval of 100 ms and three channels
/* NOTE 3: intervals are specified in units of 625 uS
Example: 1000 ms / 0.625 = 1600
*/
aux = BLE.setAdvParameters(1600, 1600, 7);
USB.println(F("\tB - Setting advertisement interval"));
if(i== 0){
//Additional sensors
len = buildAdditionalSensors();
}else{
// 1.3 Set Advertisement with sensor read value.
len = buildSensors();
}
BLE.setAdvData(BLE_GAP_ADVERTISEMENT, advData, len);
//BLE.setAdvData(BLE_GAP_SCAN_RESPONSE, advData, len);
USB.print(F("Advertisement = "));
USB.println(F("\tC - Setting advertisements data to: "));
print_hex_memory(&advData, len);
// 1.4 Set discoverable mode to user data to start advertising
// with custom data
aux = BLE.setDiscoverableMode(BLE_GAP_USER_DATA);
USB.println(F("\tD - Start advertisements"));
// 1.5 Go to sleep and but remain advertising to save power.
BLE.sleep();
delay(1000);
}
USB.println(F("============end loop==================="));
//PWR.deepSleep("00:00:00:30", RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF);
//delay(1000);
}