Smart environment PRO

From AMTech WikiDocs
Jump to: navigation, search

Smart environment PRO

  • id Gases_PRO 19
  • Bridge waspmote following sensors read to to IoT DAP
  1. Device Temperature IN_TEMP
  2. Battery level BAT
  3. Acceleromete X,Y,Z ACC
  4. Chlorine GP_CL2
  5. Carbon Monoxide GP_CO
  6. Ethylene Oxide GP_ETO
  7. Hydrogen GP_H2
  8. Hydrogen Sulphide GP_H2S
  9. Hydrogen Chloride GP_HCL
  10. Hydrogen Cyanide GP_HCN
  11. Ammonia GP_NH3
  12. Nitrogen Monoxide GP_NO
  13. Nitrogen GP_NO2
  14. Oxygen GP_O2
  15. Phospine GP_PH3
  16. Sulfur GP_SO2
  17. Methane GP_CH4
  18. Ozone GP_O3
  19. Carbon Dioxide GP_CO2
  20. Temperature Celsius GP_TC
  21. Temperature Fahrenheit GP_TF
  22. Humidity GP_HUM
  23. 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);
}