Wai Yung
Published © LGPL

A Community Data Driven Air Quality Monitoring System

My system rely on community data collection. Each user has a smog / air quality monitoring system and share collected data via Bluetooth.

ExpertWork in progressOver 3 days1,799
A Community Data Driven Air Quality Monitoring System

Things used in this project

Hardware components

Arduino 101
Arduino 101
×2
SparkFun Air Quality CCS811
×1
SparkFun Level Shifting microSD Breakout
×1
Resistor 10k ohm
Resistor 10k ohm
×2
Resistor 2.21k ohm
Resistor 2.21k ohm
You can use 3.3k also
×2
SparkFun MicroSD Card with Adapter 8GB
×1
Jumper wires (generic)
Jumper wires (generic)
×20

Story

Read more

Schematics

BLE Central and Bridge Architecture

This presentation illustrate the application, architecture, data flow, and building of the system

Prototpye of BLE Central View1

Prototpye of BLE Central View2

Prototpye of BLE Central View3

Prototpye of BLE Central View4

Code

BLE Central

Arduino
BLE Central + VOC Sensor + SD Card
/*
    2017 Co-Making the Future Contest Entry
    Arduino 101
    BLE Center Service = Predefined BLE Service = "Environmental Sensing"
    Environmental Sensing UUID = 0x181A
    Last revised 2017-06-23 Wai Yung
 */


#include <CurieBLE.h>
#include <SparkFunCCS811.h>
#include <SPI.h>
#include <SD.h>


#define WY_ServiceName                  "AirQQQ_181A"
#define WY_ServiceUUID                  "181A"
#define NumOfByte_TxTx                  4               // Maximum 20 bytes
#define NumOfByte_RxRx                  NumOfByte_TxTx
#define TxTxIntervalMilliSecond_Debug   10000           // 10 Seconds interval = Debug
#define TxTxIntervalMilliSecond_Default 60000           // 60 Seconds interval = Default
#define NoDataOffset                    0
#define Working_SerialBaudRate          115200

#define Delay_Rx2Tx                     1000
#define Delay_BLEScan                   3000
#define Delay_VocSensor                 500
#define Delay_SdCard                    1000

#define Delay_Short                     1000
#define Delay_Medium                    6000
#define Delay_Long                      8000

#define CCS811_ADDR                     0x5B


/*
    1.   Predefined BLE 16 bit UUID 0x181A
    2.   Reference1 = www.bluetooth.com/specifications/gatt/services
         Reference2 = learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt
         Reference3 = github.com/sparkfun/CCS811_Air_Quality_Breakout/blob/master/Libraries/Arduino/examples/BasicReadings/BasicReadings.ino
    3.   Last revised 2017-06-23 Wai Yung
 */


BLEService            WY_Service        (WY_ServiceUUID);
BLELongCharacteristic WY_Characteristic (WY_ServiceUUID, BLERead | BLEWrite | BLENotify);

CCS811                VocSensor         (CCS811_ADDR);

File                  VocSensorDataFile;


const long     Pre_Register_Write                   = 0x20000000L;
const long     Pre_Register_Read                    = 0x40000000L;

const long     Pre_SensorData_CO2                   = 0xE0000000L;
const long     Pre_SensorData_TVOC                  = 0xF0000000L;

const long     Cmd_DoNothing                        = 0x00000000L;

const long     Cmd_LedBuiltin_On                    = 0x00000001L;
const long     Cmd_LedBuiltin_Off                   = 0x00000002L;
const long     Cmd_LedBuiltin_Toggle                = 0x00000003L;
const long     Cmd_LedBuiltin_Blink                 = 0x00000004L;
const long     Cmd_LedBuiltin_Read                  = 0x00000005L;
const long     Cmd_Streaming_Start                  = 0x00000006L;
const long     Cmd_Streaming_Stop                   = 0x10000006L;

const long     Cmd_WR2Reg_StreamingInterval_Debug   = 0x00000010L | Pre_Register_Write;
const long     Cmd_WR2Reg_StreamingInterval_Default = 0x00000020L | Pre_Register_Write;

      long     s32TxTx           = Cmd_DoNothing;
      long     s32RxRx           = Cmd_DoNothing;
      
      short    u16RxRxLength     = 0;
      
      bool     booIsTxTxNow      = false;

      uint16_t u16VocSensor_CO2  = 0;  // VocSensor data = 16 unsigned
      uint16_t u16VocSensor_TVOC = 0;  // VocSensor data = 16 unsigned

      uint32_t u32VocSensor_CO2  = 0;  // BLE Tx    data = 32 unsigned
      uint32_t u32VocSensor_TVOC = 0;  // BLE Tx    data = 32 unsigned

      uint32_t u32NewMilliSecond = millis ();
      uint32_t u32OldMilliSecond = millis ();

      uint32_t u32Reg_StreamingInterval = TxTxIntervalMilliSecond_Default;  // Default, can be changed via BLE command


void WY_ToggleLed ()
{
    bool booStatus = digitalRead (LED_BUILTIN);

    booStatus = !booStatus;

    digitalWrite (LED_BUILTIN, booStatus);
}


void WY_BlinkLed ()
{
    bool booStatus = digitalRead (LED_BUILTIN);

    booStatus = !booStatus;  digitalWrite (LED_BUILTIN, booStatus);  delay (100);
    booStatus = !booStatus;  digitalWrite (LED_BUILTIN, booStatus);
}


void WY_ReadLed ()
{
    bool booStatus = digitalRead (LED_BUILTIN);

    if (booStatus == true) WY_Characteristic.setValue (0x00000001);
    else                   WY_Characteristic.setValue (0x00000000);
}


void setup ()
{
    Serial.begin (Working_SerialBaudRate);
    pinMode (LED_BUILTIN, OUTPUT);

    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);


    CCS811Core::status VocSensorReturnCode = VocSensor.begin();

    if (VocSensorReturnCode != CCS811Core::SENSOR_SUCCESS)
    {
        Serial.println (F("CCS811Core .begin() returned with an error"));

        while (1)
        {
            WY_BlinkLed ();
        }
    }


    Serial.println (F("BLE Start now"));

    BLE.begin ();                                      // Step1 = Begin initialization
    BLE.setLocalName             (WY_ServiceName);     // Step2 = Set advertised local name and service UUID:
    BLE.setAdvertisedService     (WY_Service);         // Step3 = Set advertised service
    WY_Service.addCharacteristic (WY_Characteristic);  // Step4 = Add characteristic to the service
    BLE.addService               (WY_Service);         // Step5 = Add service
    WY_Characteristic.setValue   (s32TxTx);            // Step6 = Set initial value for the characeristic:
    BLE.advertise ();                                  // Step7 = Start advertising

    Serial.println (F("AirQuality Peripheral"));
}


void loop ()
{
    BLEDevice The_BLE_Central = BLE.central ();  // Listen for BLE peripherals to connect

    delay (Delay_Short);

    if (The_BLE_Central)  // If a central is connected to peripheral
    {
        Serial.print   (F("Connected to central, MAC = "));  // Display the central MAC address
        Serial.println (The_BLE_Central.address ());

        while (The_BLE_Central.connected ())  // While BLE central is still connected to peripheral
        {
            // If the remote device write to the characteristic,
            // Use the value to control the LED
            //
            if (WY_Characteristic.written ())
            {
                u16RxRxLength = WY_Characteristic.valueLength ();
                      s32RxRx = WY_Characteristic.value ();

                Serial.print   (F("u16RxRxLength = "));
                Serial.println (u16RxRxLength, DEC);

                Serial.print   (F("s32RxRx = "));
                Serial.println (s32RxRx, DEC);

                if      (s32RxRx == Cmd_LedBuiltin_On)                    {digitalWrite (LED_BUILTIN, HIGH);}
                else if (s32RxRx == Cmd_LedBuiltin_Off)                   {digitalWrite (LED_BUILTIN, LOW);}
                else if (s32RxRx == Cmd_LedBuiltin_Toggle)                {WY_ToggleLed ();}
                else if (s32RxRx == Cmd_LedBuiltin_Blink)                 {WY_BlinkLed  ();}
                else if (s32RxRx == Cmd_LedBuiltin_Read)                  {WY_ReadLed   ();}

                else if (s32RxRx == Cmd_Streaming_Start)                  {booIsTxTxNow = true;}
                else if (s32RxRx == Cmd_Streaming_Stop)                   {booIsTxTxNow = false;}

                else if (s32RxRx == Cmd_WR2Reg_StreamingInterval_Debug)   {u32Reg_StreamingInterval = TxTxIntervalMilliSecond_Debug;}
                else if (s32RxRx == Cmd_WR2Reg_StreamingInterval_Default) {u32Reg_StreamingInterval = TxTxIntervalMilliSecond_Default;}
            }

            // If BLE Central BLE Pherial is connected, device need to take measurement
            //
            u32NewMilliSecond = millis ();

            if (u32NewMilliSecond - u32OldMilliSecond >= u32Reg_StreamingInterval)
            {
                u32OldMilliSecond = u32NewMilliSecond;

                if (VocSensor.dataAvailable ())
                {
                    //  If so, have the sensor read and calculate the results
                    //
                    VocSensor.readAlgorithmResults ();
  
                    delay (Delay_VocSensor);
  
                    u16VocSensor_CO2  = VocSensor.getCO2  ();
                    u16VocSensor_TVOC = VocSensor.getTVOC ();
  
                    u32VocSensor_CO2  = ((uint32_t) u16VocSensor_CO2)  & 0x0000FFFFL;  // 16 bit to 32 bit Extension
                    u32VocSensor_TVOC = ((uint32_t) u16VocSensor_TVOC) & 0x0000FFFFL;  // 16 bit to 32 bit Extension
  
                    u32VocSensor_CO2  = u32VocSensor_CO2  | Pre_SensorData_CO2;        // Add prefix
                    u32VocSensor_TVOC = u32VocSensor_TVOC | Pre_SensorData_TVOC;       // Add prefix
                }

                if (booIsTxTxNow == true)
                {
                    if (WY_Characteristic.setValue (u32VocSensor_CO2) == false)
                    {
                        Serial.println (F("Characteristic.setValue u32VocSensor_CO2 FAILED"));
                    }

                    delay (Delay_VocSensor);

                    if (WY_Characteristic.setValue (u32VocSensor_TVOC) == false)
                    {
                        Serial.println (F("Characteristic.setValue u32VocSensor_TVOC FAILED"));
                    }

                    if (!SD.begin ())
                    {
                        Serial.println (F("SD Card is not present"));
                    }
                    
                    delay (Delay_SdCard);
                    
                    VocSensorDataFile = SD.open ("VocData.txt", FILE_WRITE);
                    
                    if (VocSensorDataFile)
                    {
                        VocSensorDataFile.print   (u32VocSensor_CO2,  DEC);  // 1.  VOC Sensor CO2  raw reading
                        VocSensorDataFile.print   (", ");                    // 2.  Comma separated
                        VocSensorDataFile.println (u32VocSensor_TVOC, DEC);  // 3.  VOC Sensor TVOC raw reading + new line

                        VocSensorDataFile.close();
                    }

                    WY_ToggleLed ();
                }
            }
        }

        booIsTxTxNow = false;
        s32TxTx      = Cmd_DoNothing;

        Serial.print   (F("Disconnected from central, MAC = "));  // If BLE central disconnect, display central MAC
        Serial.println (The_BLE_Central.address ());
    }


    // If BLE Central BLE Pherial not connected, still need to take measurement
    //
    u32NewMilliSecond = millis ();
  
    if (u32NewMilliSecond - u32OldMilliSecond >= u32Reg_StreamingInterval)
    {
        u32OldMilliSecond = u32NewMilliSecond;

        if (VocSensor.dataAvailable ())
        {
            //  If so, have the sensor read and calculate the results
            //
            VocSensor.readAlgorithmResults ();
            
            delay (Delay_VocSensor);
            
            u16VocSensor_CO2  = VocSensor.getCO2  ();
            u16VocSensor_TVOC = VocSensor.getTVOC ();
            
            u32VocSensor_CO2  = ((uint32_t) u16VocSensor_CO2)  & 0x0000FFFFL;  // 16 bit to 32 bit Extension
            u32VocSensor_TVOC = ((uint32_t) u16VocSensor_TVOC) & 0x0000FFFFL;  // 16 bit to 32 bit Extension
            
            u32VocSensor_CO2  = u32VocSensor_CO2  | Pre_SensorData_CO2;        // Add prefix
            u32VocSensor_TVOC = u32VocSensor_TVOC | Pre_SensorData_TVOC;       // Add prefix
            
            if (WY_Characteristic.setValue (u32VocSensor_CO2) == false)
            {
                Serial.println (F("Characteristic.setValue u32VocSensor_CO2 FAILED"));
            }
            
            delay (Delay_VocSensor);
            
            if (WY_Characteristic.setValue (u32VocSensor_TVOC) == false)
            {
                Serial.println (F("Characteristic.setValue u32VocSensor_TVOC FAILED"));
            }
            
            if (!SD.begin ())
            {
                Serial.println (F("SD Card is not present"));
            }
            
            delay (Delay_SdCard);
            
            VocSensorDataFile = SD.open ("VocData.txt", FILE_WRITE);
            
            if (VocSensorDataFile)
            {
                VocSensorDataFile.print   (u32VocSensor_CO2,  DEC);  // 1.  VOC Sensor CO2  raw reading
                VocSensorDataFile.print   (", ");                    // 2.  Comma separated
                VocSensorDataFile.println (u32VocSensor_TVOC, DEC);  // 3.  VOC Sensor TVOC raw reading + new line
                
                VocSensorDataFile.close ();
            }
        }
    }


    delay (Delay_Medium);
    Serial.println (F("BLE Central ready to connect again"));
}

BLE Bridge Sketch

Arduino
BLE Bridge only. Download this sketch to a second Arduino 101, connect to PC, open terminal at 115200, enter commands
/*
    2017 Co-Making the Future Contest Entry
    Arduino 101
    Serial-to-BLE Bridge
    Last revised 2017-06-23 Wai Yung
 */


/*
    Reference1 = www.bluetooth.com/specifications/gatt/services
    Reference2 = learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt
 */


#include <CurieBLE.h>


#define WaiYung_ServiceName             "AirQQQ_181A"
#define WaiYung_ServiceUUID             "181A"
#define NumOfByte_TxTx                  4               // Maximum 20 bytes
#define NumOfByte_RxRx                  NumOfByte_TxTx
#define TxTxIntervalMilliSecond_Debug   10000           // 10 Seconds interval = Debug
#define TxTxIntervalMilliSecond_Default 60000           // 60 Seconds interval = Default
#define NoDataOffset                    0
#define Working_SerialBaudRate          115200

#define Delay_Rx2Tx                     1000
#define Delay_BLEScan                   3000
#define Delay_SdCard                    1000

#define Delay_Short                     1000
#define Delay_Medium                    6000
#define Delay_Long                      8000


const byte      Pre_SensorData_CO2                      = 0xE0;
const byte      Pre_SensorData_TVOC                     = 0xF0;

const byte      Cmd_DoNothing                       [4] = {0x00, 0x00, 0x00, 0x00};

const byte      Cmd_LedBuiltin_On                   [4] = {0x01, 0x00, 0x00, 0x00};
const byte      Cmd_LedBuiltin_Off                  [4] = {0x02, 0x00, 0x00, 0x00};
const byte      Cmd_LedBuiltin_Toggle               [4] = {0x03, 0x00, 0x00, 0x00};
const byte      Cmd_LedBuiltin_Blink                [4] = {0x04, 0x00, 0x00, 0x00};
const byte      Cmd_LedBuiltin_Read                 [4] = {0x05, 0x00, 0x00, 0x00};

const byte      Cmd_Streaming_Start                 [4] = {0x06, 0x00, 0x00, 0x00};  // By default, BLE send 0x06 as LSByte
const byte      Cmd_Streaming_Stop                  [4] = {0x06, 0x00, 0x00, 0x10};  // By default, BLE send 0x06 as LSByte, 0x10 as MSByte

const byte      Cmd_WR2Reg_StreamingInterval_Debug  [4] = {0x10, 0x00, 0x00, 0x20};
const byte      Cmd_WR2Reg_StreamingInterval_Default[4] = {0x20, 0x00, 0x00, 0x20};

const byte      Cmd_Disconnect_Arduino101BLE        [4] = {0x40, 0x40, 0x40, 0x40};

      byte      byCmdPrefix                             = 0x00;

//    byte      byTxTx[4]                               = {Cmd_DoNothing[0], Cmd_DoNothing[1], Cmd_DoNothing[2], Cmd_DoNothing[3]};  // In case to build custom commands on the fly

      long      lgRxRx        = 0x00000000L;
      
      uint16_t  u16RxRxLength = 0;

const String    Def_DoNothing                        = "DoNothing";

const String    Def_LedBuiltin_On                    = "LedBuiltin_On";
const String    Def_LedBuiltin_Off                   = "LedBuiltin_Off";
const String    Def_LedBuiltin_Toggle                = "LedBuiltin_Toggle";
const String    Def_LedBuiltin_Blink                 = "LedBuiltin_Blink";
const String    Def_LedBuiltin_Read                  = "LedBuiltin_Read";

const String    Def_Streaming_Start                  = "Streaming_Start";
const String    Def_Streaming_Stop                   = "Streaming_Stop";

const String    Def_WR2Reg_StreamingInterval_Debug   = "WR2Reg_StreamingInterval_Debug";
const String    Def_WR2Reg_StreamingInterval_Default = "WR2Reg_StreamingInterval_Default";

const String    Def_Disconnect_Arduino101BLE         = "Disconnect_Arduino101BLE";

      String    Str_UserCmd                          = Def_DoNothing;


      BLEDevice AirQQQPeripheral;


void WY_BlinkLed ()
{
    bool booStatus = digitalRead (LED_BUILTIN);

    booStatus = !booStatus;  digitalWrite (LED_BUILTIN, booStatus);  delay (100);
    booStatus = !booStatus;  digitalWrite (LED_BUILTIN, booStatus);
}


void setup ()
{
    Serial.begin (Working_SerialBaudRate);
    pinMode (LED_BUILTIN, OUTPUT);

    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);
    digitalWrite (LED_BUILTIN, LOW);  delay (1000);
    digitalWrite (LED_BUILTIN, HIGH); delay (1000);

    Serial.println (" ");
    Serial.print   (F("BLE Central = "));
    Serial.println (WaiYung_ServiceName);

    BLE.begin ();                           // 1.   Initialize Arduino 101 BLE

    delay (Delay_Short);
}


void loop ()
{
    BLE.scanForUuid (WaiYung_ServiceUUID);  // 2.   Start scanning BLE peripherals

    delay (Delay_Short);

    AirQQQPeripheral = BLE.available ();    // 3.   Check if a peripheral has been discovered

    delay (Delay_Short);

    if (AirQQQPeripheral)
    {
        Serial.print   (F("BLE Peripheral discovered at address "));     // 1.   Discovered a peripheral, print out address
        Serial.println (AirQQQPeripheral.address ());
        Serial.print   (F("BLE Peripheral localName is "));              // 2.   Discovered a peripheral, local name
        Serial.println (AirQQQPeripheral.localName ());
        Serial.print   (F("BLE Peripheral service UUID is "));           // 3.   Discovered a peripheral, advertised service
        Serial.println (AirQQQPeripheral.advertisedServiceUuid ());
        Serial.println (" ");
        Serial.println (" ");

        BLE.stopScan ();                                                 // 4.   Because of discovering a peripheral, stop BLE scanning

        if (AirQQQPeripheral.connect ())
        {
            Serial.println (F("BLE Peripheral is connected"));
        }
        else
        {
            Serial.println (F("BLE Peripheral is NOT connected"));
            while (1) {WY_BlinkLed ();}
        }


        Serial.println (F("Ready to retrieve BLE peripheral attributes"));
    
        if (AirQQQPeripheral.discoverAttributes ())
        {
            Serial.println (F("BLE Peripheral attributes discovered"));
        }
        else
        {
            Serial.println (F("BLE Peripheral attributes NOT discovered"));
            while (1) {WY_BlinkLed ();}
        }


        Serial.println (F("Ready to retrieve BLE peripheral characteristic"));
    
        BLECharacteristic AirQQQCharacteristic = AirQQQPeripheral.characteristic (WaiYung_ServiceUUID);
    
        if (!AirQQQCharacteristic)
        {
            Serial.println (F("BLE Peripheral DO NOT have AirQQQCharacteristic"));
            while (1) {WY_BlinkLed ();}
        }
        else if (!AirQQQCharacteristic.canWrite ())
        {
            Serial.println (F("BLE Peripheral DO NOT accept AirQQQCharacteristic command"));
            while (1) {WY_BlinkLed ();}
        }


        Serial.println (F("Ready to send command to BLE peripheral"));
        
        if (AirQQQPeripheral.connected ())
        {
            AirQQQCharacteristic.writeValue (Cmd_DoNothing, NumOfByte_TxTx);  // 5.   Tx command
            Serial.println (F("Sent command Cmd_StreamingStart to BLE peripheral"));
        }
        else
        {
            Serial.println (F("Error when sending ommand to BLE peripheral"));
            while (1) {WY_BlinkLed ();}
        }


        Serial.println (" ");
        Serial.println (" ");


        if (AirQQQCharacteristic.canRead ())
        {
            Serial.println (F("BLE peripheral can handle READ"));
        }
        else
        {
            Serial.println (F("BLE peripheral CANNOT handle READ"));
            while (1) {WY_BlinkLed ();}
        }


        if (AirQQQCharacteristic.canWrite ())
        {
            Serial.println (F("BLE peripheral can handle WRITE"));
        }
        else
        {
            Serial.println (F("BLE peripheral CANNOT handle WRITE"));
            while (1) {WY_BlinkLed ();}
        }


        if (AirQQQCharacteristic.canNotify ())
        {
            Serial.println (F("BLE peripheral can handle NOTIFY"));
        }
        else
        {
            Serial.println (F("BLE peripheral CANNOT handle NOTIFY"));
            while (1) {WY_BlinkLed ();}
        }


        if (AirQQQCharacteristic.canSubscribe ())
        {
            Serial.println (F("BLE peripheral can handle SUBSCRIBE"));
            AirQQQCharacteristic.subscribe ();
        }
        else
        {
            Serial.println (F("BLE peripheral CANNOT handle SUBSCRIBE"));
            while (1) {WY_BlinkLed ();}
        }


        Serial.print   (F("BLE Peripheral maximum size = "));
        Serial.println (AirQQQCharacteristic.valueSize (), DEC);


        while (1)
        {
            // Bridge from BLE to Serial
            //
            if (AirQQQCharacteristic.valueUpdated ())
            {
                u16RxRxLength = AirQQQCharacteristic.valueLength ();
                       lgRxRx = AirQQQCharacteristic.longValue ();

                Serial.print   (F("u16RxRxLength in decimal = "));
                Serial.println (u16RxRxLength, DEC);
                Serial.print   (F("lgRxRx in decimal = "));
                Serial.println (lgRxRx, DEC);

                byCmdPrefix = (lgRxRx >> 24);  // MSByte = Sensor data prefix

                if (byCmdPrefix == Pre_SensorData_CO2)
                {
                    Serial.print   (F("VocSensor CO2  raw reading = "));
                    Serial.println (lgRxRx, DEC);
                }

                if (byCmdPrefix == Pre_SensorData_TVOC)
                {
                    Serial.print   (F("VocSensor TVOC raw reading = "));
                    Serial.println (lgRxRx, DEC);
                }
            }


            delay (Delay_Rx2Tx);


            if (AirQQQPeripheral.connected ())
            {
                AirQQQCharacteristic.writeValue (Cmd_DoNothing, NumOfByte_TxTx);
//              Serial.println (F("Sent command Cmd_StreamingStart to BLE peripheral"));
            }
            else
            {
                Serial.println (F("Error when sending ommand to BLE peripheral"));
                break;
            }

            delay (Delay_Rx2Tx);
            

            // Bridge from Serial to BLE
            //
            if (Serial.available () > 0)
            {
                Str_UserCmd = Serial.readStringUntil (';');

                Serial.println (" ");
                Serial.print   (F("Original  UserCmd = "));
                Serial.println (Str_UserCmd);

                Str_UserCmd.toLowerCase ();

                Serial.print   (F("LowerCase UserCmd = "));
                Serial.println (Str_UserCmd);
                Serial.println (" ");

                if      (Str_UserCmd.equalsIgnoreCase (Def_LedBuiltin_On))                    {AirQQQCharacteristic.writeValue (Cmd_LedBuiltin_On,                    NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_LedBuiltin_On"));}
                else if (Str_UserCmd.equalsIgnoreCase (Def_LedBuiltin_Off))                   {AirQQQCharacteristic.writeValue (Cmd_LedBuiltin_Off,                   NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_LedBuiltin_Off"));}
                else if (Str_UserCmd.equalsIgnoreCase (Def_LedBuiltin_Toggle))                {AirQQQCharacteristic.writeValue (Cmd_LedBuiltin_Toggle,                NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_LedBuiltin_Toggle"));}
                else if (Str_UserCmd.equalsIgnoreCase (Def_LedBuiltin_Blink))                 {AirQQQCharacteristic.writeValue (Cmd_LedBuiltin_Blink,                 NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_LedBuiltin_Blink"));}
                else if (Str_UserCmd.equalsIgnoreCase (Def_LedBuiltin_Read))                  {AirQQQCharacteristic.writeValue (Cmd_LedBuiltin_Read,                  NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_LedBuiltin_Read"));}

                else if (Str_UserCmd.equalsIgnoreCase (Def_Streaming_Start))                  {AirQQQCharacteristic.writeValue (Cmd_Streaming_Start,                  NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_Streaming_Start"));}
                else if (Str_UserCmd.equalsIgnoreCase (Def_Streaming_Stop))                   {AirQQQCharacteristic.writeValue (Cmd_Streaming_Stop,                   NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_Streaming_Stop"));}

                else if (Str_UserCmd.equalsIgnoreCase (Def_WR2Reg_StreamingInterval_Debug))   {AirQQQCharacteristic.writeValue (Cmd_WR2Reg_StreamingInterval_Debug,   NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_WR2Reg_StreamingInterval_Debug"));}
                else if (Str_UserCmd.equalsIgnoreCase (Def_WR2Reg_StreamingInterval_Default)) {AirQQQCharacteristic.writeValue (Cmd_WR2Reg_StreamingInterval_Default, NumOfByte_TxTx);  Serial.println (F("Matched = Cmd_WR2Reg_StreamingInterval_Default"));}

                else if (Str_UserCmd.equalsIgnoreCase (Def_Disconnect_Arduino101BLE))
                     {
                         AirQQQPeripheral.disconnect ();

                         Serial.println (" ");
                         Serial.println (F("Disconnect Arduino101 BLE"));
                         Serial.println (F("Going into sleep now"));
                         Serial.println (F("You must use hardware reset to restart everything"));
                         Serial.println (" ");

                         while (1);
                     }

                Str_UserCmd = Def_DoNothing;  // Reset user command to default.  Otherwise, resend the same command again by mistake
            }
        }
    }

    Serial.println (F("Ready to BLE scan again"));

    delay (Delay_BLEScan);
}

Credits

Wai Yung

Wai Yung

1 project • 2 followers

Comments