Alex
Created October 15, 2017

HAM | Home Automation and Monitoring System

HAM is the definition of IoT. It features a network formed by nodes with sensors, actuators, video surveillance system, alarms...

IntermediateShowcase (no instructions)4,799

Things used in this project

Hardware components

SparkFun ESP8266 Thing - Dev Board
SparkFun ESP8266 Thing - Dev Board
×1
ATmega328
Microchip ATmega328
×3
ATtiny85
Microchip ATtiny85
×1
Raspberry Pi Zero Wireless
Raspberry Pi Zero Wireless
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
HC-06 Bluetooth Module
×3
Electronic stuff as female/male headers, capacitors, resistances, crystals, transistors, etc
×1
18650 battery
×3
18650 battery charger from powerbanks
×3
CR2032 battery
×1
LOTS OF SENSORS (LISTED BELOW)
×1
Webcam
×1
Protoboard
×5

Software apps and online services

Cayenne
myDevices Cayenne
Cayenne API

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Soldering wire, flux, heat shrink tubes

Story

Read more

Custom parts and enclosures

SKETCH OF HOW ENCLOSURES COULD BE

Schematics

HAM-BLINDS

HAM-BLINDS ROOT

HAM-PEEPHOLE

HAM-PEEPHOLE ROOT

HAM-RDT

HAM-RDT ROOT

HAM-GAS

HAM-GAS ROOT

HAM-EXT

HAM-EXT ROOT

HAM-HUB UNCOVERED

HAM-HUB COVERED

HAM-HUB ROOT

Code

HAM-BLINDS

Arduino
//  BlindController by @Neoxelox
//  Rev. 1 | Last modification: 12/08/2017

//  Libraries Section:

//  Sleep for ATtiny85
  #include <avr/sleep.h>
  #include <avr/interrupt.h>

//  IR Receiver
  #include "IRLremote.h"
  
//------------------\\

//  Define Section:

  #define irInterrupt 0
  #define bupPin 0
  #define bstPin 1
  #define bdwPin 4

//------------------\\

//  Variable Section:

//  IR Receiver
uint8_t IRProtocol = 0; //Variables to store IR information
uint16_t IRAddress = 0;
uint32_t IRCommand = 0;

//------------------\\

void setup() 
{
  
  //  Transistors 
  pinMode(bupPin, OUTPUT);  //Prepare Pin to control the transistors
  pinMode(bstPin, OUTPUT);
  pinMode(bdwPin, OUTPUT);
  digitalWrite(bupPin, LOW); //Puts all the transistor on low
  digitalWrite(bstPin, LOW);
  digitalWrite(bdwPin, LOW);
 
  //  IR Receiver
  IRLbegin<IR_USER>(irInterrupt); //Initialize the IR Receiver
  
}

void loop() 
{
  sleep();

  delay(500); //The CPU needs that delay to handle the IR signal

  if (IRLavailable()) 
  {
    
    IRProtocol = IRLgetProtocol();  //Store the IR data
    IRAddress = IRLgetAddress();
    IRCommand = IRLgetCommand();
    
    if (IRAddress == 18509)
    {
      
      switch (IRCommand)
      {
        case 9180:  //Sent Blinds UP
        
        digitalWrite(bupPin, HIGH);
        delay(100);
        digitalWrite(bupPin, LOW);
        
        case 1020:  //Sent Blinds DOWN
        
        digitalWrite(bdwPin, HIGH);
        delay(100);
        digitalWrite(bdwPin, LOW);
        
        case 8670:  //Sent Blinds STOP
        
        digitalWrite(bstPin, HIGH);
        delay(100);
        digitalWrite(bstPin, LOW);
        
      }
    
    }
       
    IRLreset(); // Resume reading to get new values
    
  }
  
  
}

void decodeIR(const uint32_t duration) 
{
  // Called when directly received and interrupt CHANGE
  // Do not use Serial inside, it can crash your Arduino!
  
  decodeNec(duration);  //Only decode NEC to save flash space
  
}

void sleep() 
{

    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT2);                   // Use PB2 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep

    //Wake up after an interrupt
    
    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT2);                  // Turn off PB2 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts
    
}

ISR(PCINT0_vect){}  //It is required to wake up the cpu

HAM-PEEPHOLE

Python
#HAM-PEEPHOLE BY @Neoxelox
#Last modification 29/9/2017
import cayenne.client
import time
import RPi.GPIO as GPIO

#Sleep to allow wireless to connect before starting MQTT
time.sleep(5)

#Setting the GPIO
GPIO.setmode(GPIO.BOARD)

#Setting GPIO Vars
photoresistor_pin = 7
vibration_pin = 11
alarm_pin = 13
GPIO.setup(vibration_pin, GPIO.IN)
GPIO.setup(alarm_pin, GPIO.OUT)
GPIO.output(alarm_pin, GPIO.LOW)

#Time between packets and alarm
timePhr = 2  #Photoresistor
timeAlarm = 3  #Alarm

#Vars to store data
dataPhr = 0
dataVib = 0
alarm = False

# Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
MQTT_USERNAME  = ""
MQTT_PASSWORD  = ""
MQTT_CLIENT_ID = ""

# The callback for when a message is received from Cayenne.
def on_message(message):
  print("message received: " + str(message))

#Function for Photoresistor
def photoRead (photoresistor_pin):
    prCount = 0
    GPIO.setup(photoresistor_pin, GPIO.OUT)
    GPIO.output(photoresistor_pin, GPIO.LOW)
    time.sleep(0.1)
    GPIO.setup(photoresistor_pin, GPIO.IN)

    while (GPIO.input(photoresistor_pin) == GPIO.LOW):
        prCount += 1
    print("RAW VALUE " + str (prCount)) #COMMENT THIS BEFORE RELEASE
    print("MAP VALUE " + str(pimap(prCount, 0, 3000, 0, 100))) #COMMENT THIS BEFORE RELEASE
    return pimap(prCount, 0, 27000, 0, 100)

#Function for Vibration sensor
def vibRead(vibration_pin):
    return GPIO.input(vibration_pin)

#Function for map
def pimap(x, in_min, in_max, out_min, out_max):
    return int((x-in_min) * (out_max-out_min) / (in_max-in_min) + out_min)

#Setting Cayenne Vars
client = cayenne.client.CayenneMQTTClient()
client.on_message = on_message
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)

#Setting Time and Index Vars
i=0
timestamp = 0
timestamp2 = 0
oldVib = 0
vibCounts = 0
alarmCounts = 0

while True:
  client.loop()

  #Read Vibration data always
  dataVib = vibRead(vibration_pin)

  #Read Photoresistor data every 2 seconds
  if (time.time() > timestamp + timePhr):
    #Send to V1 Photoresistor data
    dataPhr = photoRead(photoresistor_pin)
    client.virtualWrite(1, dataPhr, "lum", "p")
    timestamp = time.time()
    i += 1

  if (dataVib != oldVib):
    #Get Vibration if its different
    oldVib = dataVib
    if (dataVib == 0):
      client.virtualWrite(2, 0, "null", " ")
    vibCounts += 1

  if (vibCounts == 5):
    #Send vibration data to V2 and start alarm if vib its different for 5 times
    vibCounts = 0
    client.virtualWrite(2, 1, "null", " ")
    alarm = True

  if (dataPhr >= 55):
    alarm = True

  if (alarm == True and time.time() > timestamp2 + timeAlarm):
    #Start the alarm!
    alarm = False
    GPIO.output(alarm_pin, GPIO.HIGH)
    time.sleep(0.1)
    GPIO.output(alarm_pin, GPIO.LOW)

HAM-RDT

Arduino
//  Radiations Sensor by @Neoxelox
//  Rev. 1 | Last modification: 12/10/2017

//  Define Section:

  #define btPin 2   // Bluetooth Pin
  #define efPin A0  // Electromagnetic Field Sensor Pin
  #define mfPin A1  // Magnetic Field Sensor Pin
  #define irPin A2  // Infrared Radation Sensor Pin
  #define dbPin A3  // Decibel Meter Sensor Pin

//------------------\\

//  Variable Section:

//  Bluetooth
  int btTimeout = 3000; // Time that Bluetooth will be off after finishing transmitting data

//  EF Sensor
  #define efSamples 100 // Samples from the sensor (More = More accurate but less SRAM)                                                         
  int efArray[efSamples];                    
  unsigned long efAverage;
  int efValue;

//  MF Sensor
  #define noField 535 // Calibrated data where there is not field
  #define toMilligauss 1.953125

//  IR Sensor
  #define irSamples 100 // Samples from the sensor (More = More accurate but less SRAM)                                                         
  int irArray[irSamples];                    
  unsigned long irAverage;
  int irValue;

//  DB Sensor
  #define dbSampleTime 50
  unsigned long dbSample;
  #define maxDb 1024
  #define minDb 0
  unsigned long dbMinSample;
  unsigned long dbMaxSample;
  unsigned long dbMillis;
  float peakDb;
  #define dbMaxOut 90
  #define dbMinOut 49.5

//  Battery
  long battery;

//  HAM PROTOCOL  
  const byte numChars = 64;
  char receivedChars[numChars];
  char tempChars[numChars]; // Temporary array for use when parsing

// Variables to hold the parsed data
  String BT_REQUEST, messageFromBTplaceHolder, BT_PROTOCOL;
  boolean newData = false;

//----------------------\\


void setup() 
{

//  Bluetooth
  pinMode(btPin, OUTPUT);
  digitalWrite(btPin, HIGH);  // Power on Bluetooth via transistor
  delay(100);
  Serial.begin(9600); // Prepare communication through BT

//  EF Sensor
  pinMode(efPin, INPUT);  // Prepare pin to receive data
  
//  MF Sensor
  pinMode(mfPin, INPUT);  // Prepare pin to receive data

//  IR Sensor  
  pinMode(irPin, INPUT);  // Prepare pin to receive data

//  DB Sensor  
  pinMode(dbPin, INPUT);  // Prepare pin to receive data
  
}

void loop()
{ 
 
  receiveHAMProtocol();
  if (newData == true) 
  {
    
    strcpy(tempChars, receivedChars); // Temporary copy to protect the original data for later manipulation
    
    if (parseData() == true)
    
    {
      
      manipulateData();
      
    }
   
    newData = false;
   
   }
  
}

void btRestart()  // Restarts the Bluetooth after transmitting data
{
  digitalWrite(btPin, LOW);
  delay(btTimeout);
  digitalWrite(btPin, HIGH);
  delay(100);
}

int readMf()  // Reads the Magnetic Field in MilliGauss
{
  return((analogRead(mfPin) - noField) * toMilligauss);  
}

int readEf()  // Reads the concentration of ElectroMagnetic Fields
{
  for(int i = 0; i < efSamples; i++)
  {              
  efArray[i] = analogRead(efPin);      
  efAverage += efArray[i];  
  }
                
  efValue = efAverage / efSamples;                  
  efValue = constrain(efValue, 0, 100);                                                    
  efAverage = 0;    
  return(efValue);              
}

int readIr()  // Reads the concentration of Infrared Radation Fields
{
  for(int i = 0; i < irSamples; i++)
  {              
  irArray[i] = analogRead(irPin);      
  irAverage += irArray[i];  
  }
                
  irValue = irAverage / irSamples;                  
  irValue = constrain(irValue, 0, 100);                                                    
  irAverage = 0;    
  return(irValue);              
}

float readDb()  // Reads de Decibels
{

  dbMillis = millis();

  while (millis() - dbMillis < dbSampleTime)
  {
    dbSample = analogRead(dbPin);
    
    if (dbSample < maxDb)
    {
      if (dbSample > minDb)
      {
        dbMinSample = dbSample;
      }
      else if(dbSample < maxDb)
      {
        dbMaxSample = dbSample;
      }
    }
  }

  peakDb = dbMinSample - dbMaxSample;

  return(map(peakDb, 20, 900, dbMinOut, dbMaxOut));
}

long readBattery()  // Reads the battery percent
{
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC);  // Convert
while (bit_is_set(ADCSRA,ADSC)); 
battery = ADCL;
battery |= ADCH<<8; 
battery = 1126400L / battery; // Back-calculate AVcc in mV
return (map(battery, 4500, 5000, 0, 100)); 
}

void receiveHAMProtocol() // Receives the message via HAM PROTOCOL
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) 
    {
        rc = Serial.read();

        if (recvInProgress == true) 
        {
            if (rc != endMarker) // Searchs for the endMarker
            {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) 
                {
                    ndx = numChars - 1;
                }
            }
            else 
            {
                receivedChars[ndx] = '\0'; // Terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) // Searchs for the startMarker
        {
            recvInProgress = true;
        }
    }
}

String buildHAMProtocol(String channelName, int intData, float floatData, String stringData)  // Constructs the necessary HAM protocol to send
{
  
  return("<HAM-PROTOCOL,"+ channelName + "," + String(intData) + "," + String(floatData) + "," + stringData + ">");
  
}

boolean parseData() // Splits the data into its parts --> Expects <HAM-PROTOCOL, request>
{      

    boolean correctProtocol;  // Boolean var to store if the readed protocol is the correct one
    char * strtokIndx;  // This is used by strtok() as an index

    // EXPECTED FIRST PART: THE HAM PROTOCOL

    strtokIndx = strtok(tempChars,","); // Gets the first part (a String)
     
    messageFromBTplaceHolder += strtokIndx;    
    BT_PROTOCOL = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    if (BT_PROTOCOL == "HAM-PROTOCOL"){correctProtocol = true;} else {correctProtocol = false;}

    //======================================

    // EXPECTED SECOND PART: THE REQUEST
    
    strtokIndx = strtok(NULL, ","); // Gets the second part (a String)
    
    messageFromBTplaceHolder += strtokIndx;    
    BT_REQUEST = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    //=====================================

    return correctProtocol; // Returns true if the protocol used was HAM-PROTOCOL

} 

void manipulateData() // Manipulates the data received and parsed
{

    // COMMAND ZONE =========================================    
    
    if (BT_REQUEST == "ready.request") /*-->*/ {Serial.println(buildHAMProtocol("HAM-RDT", 0, 0, "OK-READY"));}
    if (BT_REQUEST == "HAM-RDT.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("HAM-RDT", 0, 0, "OK-OFF")); delay(250); /*-->*/ btRestart();}
    if (BT_REQUEST == "batteryRDT.request") /*-->*/ {Serial.println(buildHAMProtocol("batteryRDT", readBattery(), 0, "0"));}
    if (BT_REQUEST == "emfield.requestData") /*-->*/ {Serial.println(buildHAMProtocol("emfield", readEf(), 0, "0"));}
    if (BT_REQUEST == "mfield.requestData") /*-->*/ {Serial.println(buildHAMProtocol("mfield", readMf(), 0, "0"));}
    if (BT_REQUEST == "irrad.requestData") /*-->*/ {Serial.println(buildHAMProtocol("irrad", readIr(), 0, "0"));}
    if (BT_REQUEST == "decibel.requestData") /*-->*/ {Serial.println(buildHAMProtocol("decibel", 0, readDb(), "0"));}

    //=======================================================
    
}

HAM-GAS

Arduino
//  Gases Sensor by @Neoxelox
//  Rev. 1 | Last modification: 12/10/2017

//  Define Section:

  #define btPin 2   // Bluetooth Pin
  #define m2Pin A0  // CO2 Gas Sensor Pin
  #define s2Pin 11   // MQ2 Switch
  #define m5Pin A1  // Natural Gas Sensor Pin
  #define s5Pin 9   // MQ5 Switch
  #define m6Pin A2  // Butane/Propane Gas Sensor Pin
  #define s6Pin 10   // MQ6 Switch
  #define m7Pin A3  // CO Gas Sensor Pin
  #define s7Pin 12   // MQ7 Switch
  #define flPin 13   // Flame Sensor Pin
  #define tpPin A4  // Temperature Sensor Pin

//------------------\\

//  Variable Section:

//  Bluetooth
  int btTimeout = 3000; // Time that Bluetooth will be off after finishing transmitting data

//  MQ2 Sensor
  #define m2Samples 50 // Samples from the sensor (More = More accurate but less SRAM)                                                         
  int m2Array[m2Samples];                    
  unsigned long m2Average;
  #define m2NoGas 500 // Calibrated data where there is not Gas
  int m2Value;

//  MQ5 Sensor
  #define m5Samples 50 // Samples from the sensor (More = More accurate but less SRAM)                                                         
  int m5Array[m5Samples];                    
  unsigned long m5Average;
  #define m5NoGas 500 // Calibrated data where there is not Gas
  int m5Value;

//  MQ6 Sensor
  #define m6Samples 50 // Samples from the sensor (More = More accurate but less SRAM)                                                         
  int m6Array[m6Samples];                    
  unsigned long m6Average;
  #define m6NoGas 500 // Calibrated data where there is not Gas
  int m6Value;

//  MQ7 Sensor
  #define m7Samples 50 // Samples from the sensor (More = More accurate but less SRAM)                                                         
  int m7Array[m7Samples];                    
  unsigned long m7Average;
  #define m7NoGas 500 // Calibrated data where there is not Gas
  int m7Value;    
  
//  Temperature Sensor
  #define tpMin 0 // Calibrated data where there is the minimun temperature
  #define tpMax 95.46 // Calibrated data where there is the maximum temperature

//  Battery
  long battery;  

//  HAM PROTOCOL  
  const byte numChars = 64;
  char receivedChars[numChars];
  char tempChars[numChars]; // Temporary array for use when parsing

// Variables to hold the parsed data
  String BT_REQUEST, messageFromBTplaceHolder, BT_PROTOCOL;
  boolean newData = false;

//----------------------\\


void setup() 
{

//  Bluetooth
  pinMode(btPin, OUTPUT);
  digitalWrite(btPin, HIGH);  // Power on Bluetooth via transistor
  delay(100);
  Serial.begin(9600); // Prepare communication through BT

//  MQ2 Sensor
  pinMode(m2Pin, INPUT);  // Prepare pin to receive data
  pinMode(s2Pin, OUTPUT);
  digitalWrite(s2Pin, HIGH); // Power on MQ2 via transistor

//  MQ5 Sensor
  pinMode(m5Pin, INPUT);  // Prepare pin to receive data
  pinMode(s5Pin, OUTPUT);
  digitalWrite(s5Pin, HIGH); // Power on MQ5 via transistor

//  MQ6 Sensor
  pinMode(m6Pin, INPUT);  // Prepare pin to receive data
  pinMode(s6Pin, OUTPUT);
  digitalWrite(s6Pin, HIGH); // Power on MQ6 via transistor

//  MQ7 Sensor
  pinMode(m7Pin, INPUT);  // Prepare pin to receive data
  pinMode(s7Pin, OUTPUT);
  digitalWrite(s7Pin, HIGH); // Power on MQ7 via transistor    
  
//  Flame Sensor
  pinMode(flPin, INPUT);  // Prepare pin to receive data

//  Temperature Sensor  
  pinMode(tpPin, INPUT);  // Prepare pin to receive data
  
}

void loop()
{

  receiveHAMProtocol();
  if (newData == true) 
  {
    
    strcpy(tempChars, receivedChars); // Temporary copy to protect the original data for later manipulation
    
    if (parseData() == true)
    
    {
      
      manipulateData();
      
    }
   
    newData = false;
   
   }
  
}

void btRestart()  // Restarts the Bluetooth after transmitting data
{
  digitalWrite(btPin, LOW);
  delay(btTimeout);
  digitalWrite(btPin, HIGH);
  delay(100);
}

float readTp()  // Reads the Temperature
{
  return(map(analogRead(tpPin), 0, 1023, tpMin, tpMax));  
}

int readM2()  // Reads the concentration of CO2 Gas
{
  for(int i = 0; i < m2Samples; i++)
  {              
  m2Array[i] = analogRead(m2Pin);      
  m2Average += m2Array[i];  
  }
                
  m2Value = m2Average / m2Samples;                  
  m2Value = map(m2Value, m2NoGas, 1023, 0, 100);                                                    
  m2Average = 0;    
  return(m2Value);              
}

int readM5()  // Reads the concentration of Natural Gas
{
  for(int i = 0; i < m5Samples; i++)
  {              
  m5Array[i] = analogRead(m5Pin);      
  m5Average += m5Array[i];  
  }
                
  m5Value = m5Average / m5Samples;                  
  m5Value = map(m5Value, m5NoGas, 1023, 0, 100);                                                    
  m5Average = 0;    
  return(m5Value);              
}

int readM6()  // Reads the concentration of Butane/Propane Gas
{
  for(int i = 0; i < m6Samples; i++)
  {              
  m6Array[i] = analogRead(m6Pin);      
  m6Average += m6Array[i];  
  }
                
  m6Value = m6Average / m6Samples;                  
  m6Value = map(m6Value, m6NoGas, 1023, 0, 100);                                                    
  m6Average = 0;    
  return(m6Value);              
}

int readM7()  // Reads the concentration of CO Gas
{
  for(int i = 0; i < m7Samples; i++)
  {              
  m7Array[i] = analogRead(m7Pin);      
  m7Average += m7Array[i];  
  }
                
  m7Value = m7Average / m7Samples;                  
  m7Value = map(m7Value, m7NoGas, 1023, 0, 100);                                                    
  m7Average = 0;    
  return(m7Value);              
}

long readBattery()  // Reads the battery percent
{
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC);  // Convert
while (bit_is_set(ADCSRA,ADSC)); 
battery = ADCL;
battery |= ADCH<<8; 
battery = 1126400L / battery; // Back-calculate AVcc in mV
return (map(battery, 4500, 5000, 0, 100)); 
}

void receiveHAMProtocol() // Receives the message via HAM PROTOCOL
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) 
    {
        rc = Serial.read();

        if (recvInProgress == true) 
        {
            if (rc != endMarker) // Searchs for the endMarker
            {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) 
                {
                    ndx = numChars - 1;
                }
            }
            else 
            {
                receivedChars[ndx] = '\0'; // Terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) // Searchs for the startMarker
        {
            recvInProgress = true;
        }
    }
}

String buildHAMProtocol(String channelName, int intData, float floatData, String stringData)  // Constructs the necessary HAM protocol to send
{
  
  return("<HAM-PROTOCOL,"+ channelName + "," + String(intData) + "," + String(floatData) + "," + stringData + ">");
  
}

boolean parseData() // Splits the data into its parts --> Expects <HAM-PROTOCOL, request>
{      

    boolean correctProtocol;  // Boolean var to store if the readed protocol is the correct one
    char * strtokIndx;  // This is used by strtok() as an index

    // EXPECTED FIRST PART: THE HAM PROTOCOL

    strtokIndx = strtok(tempChars,","); // Gets the first part (a String)
     
    messageFromBTplaceHolder += strtokIndx;    
    BT_PROTOCOL = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    if (BT_PROTOCOL == "HAM-PROTOCOL"){correctProtocol = true;} else {correctProtocol = false;}

    //======================================

    // EXPECTED SECOND PART: THE REQUEST
    
    strtokIndx = strtok(NULL, ","); // Gets the second part (a String)
    
    messageFromBTplaceHolder += strtokIndx;    
    BT_REQUEST = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    //=====================================

    return correctProtocol; // Returns true if the protocol used was HAM-PROTOCOL

} 

void manipulateData() // Manipulates the data received and parsed
{

    // COMMAND ZONE =========================================    

    if (BT_REQUEST == "ready.request") /*-->*/ {Serial.println(buildHAMProtocol("HAM-GAS", 0, 0, "OK-READY"));}
    if (BT_REQUEST == "HAM-GAS.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("HAM-GAS", 0, 0, "OK-OFF")); /*-->*/ delay(250); /*-->*/ btRestart();}
    if (BT_REQUEST == "batteryGAS.request") /*-->*/ {Serial.println(buildHAMProtocol("batteryGAS", readBattery(), 0, "0"));}
    if (BT_REQUEST == "CO2.requestData") /*-->*/ {Serial.println(buildHAMProtocol("CO2", readM2(), 0, "0"));}
    if (BT_REQUEST == "natugas.requestData") /*-->*/ {Serial.println(buildHAMProtocol("natugas", readM5(), 0, "0"));}
    if (BT_REQUEST == "butprop.requestData") /*-->*/ {Serial.println(buildHAMProtocol("butprop", readM6(), 0, "0"));}
    if (BT_REQUEST == "CO.requestData") /*-->*/ {Serial.println(buildHAMProtocol("CO", readM7(), 0, "0"));}
    if (BT_REQUEST == "flame.requestData") /*-->*/ {Serial.println(buildHAMProtocol("flame", digitalRead(flPin), 0, "0"));}
    if (BT_REQUEST == "kitchentemp.requestData") /*-->*/ {Serial.println(buildHAMProtocol("kitchentemp", 0, readTp(), "0"));}

    // Gas sensors switches:

    if (BT_REQUEST == "CO2.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("CO2", 0, 0, "OK-OFF")); /*-->*/ digitalWrite(s2Pin, LOW);}
    if (BT_REQUEST == "natugas.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("natugas", 0, 0, "OK-OFF")); /*-->*/ digitalWrite(s5Pin, LOW);}
    if (BT_REQUEST == "butprop.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("butprop", 0, 0, "OK-OFF")); /*-->*/ digitalWrite(s6Pin, LOW);}
    if (BT_REQUEST == "CO.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("CO", 0, 0, "OK-OFF")); /*-->*/ digitalWrite(s7Pin, LOW);}

    if (BT_REQUEST == "CO2.requestAction.ON") /*-->*/ {Serial.println(buildHAMProtocol("CO2", 0, 0, "OK-ON")); /*-->*/ digitalWrite(s2Pin, HIGH);}
    if (BT_REQUEST == "natugas.requestAction.ON") /*-->*/ {Serial.println(buildHAMProtocol("natugas", 0, 0, "OK-ON")); /*-->*/ digitalWrite(s5Pin, HIGH);}
    if (BT_REQUEST == "butprop.requestAction.ON") /*-->*/ {Serial.println(buildHAMProtocol("butprop", 0, 0, "OK-ON")); /*-->*/ digitalWrite(s6Pin, HIGH);}
    if (BT_REQUEST == "CO.requestAction.ON") /*-->*/ {Serial.println(buildHAMProtocol("CO", 0, 0, "OK-ON")); /*-->*/ digitalWrite(s7Pin, HIGH);}
    
    //=======================================================
    
}

HAM-EXT

Arduino
//  Exterior Sensors by @Neoxelox
//  Rev. 1 | Last modification: 12/10/2017

//  Libraries Section:

//  DHT11 Sensor
  #include <DHT.h>
  #include <DHT_U.h>

//  BMP280
  #include <Wire.h>
  #include "i2c.h"
  #include "i2c_BMP280.h"

//--------------\\  

//  Define Section:

  #define btPin 2   // Bluetooth Pin
  #define dhPin 11   // Humidity/Temperature Sensor Pin
  #define mqPin A0  // Air Pollution Sensor Pin
  #define smPin 13   // MQ135 Switch
  #define poPin A1  // Illuminance Sensor Pin
  #define rnPin A2  // Rain Sensor Pin
  #define uvPin A3  // UV Sensor Pin
  //BMP280 DEFINITIONS ARE DEFAULT 12C PINS A5/A4

//------------------\\

//  Variable Section:

//  Bluetooth
  int btTimeout = 3000; // Time that Bluetooth will be off after finishing transmitting data

//  DHT11 Sensor
  DHT dht11 (dhPin, DHT11); // Define the type of DHT (11)

// BMP280 Sensor
  BMP280 bmp280;  
  float pressure;
  static float altitude;

//  MQ135 Sensor
  #define mqSamples 50 // Samples from the sensor (More accurate)                                                         
  int mqArray[mqSamples];                    
  unsigned long mqAverage;
  #define mqNoPol 500 // Calibrated data where there is not Pollution
  int mqValue;

//  Illuminance Sensor
  #define alfaIllu 0.0048828125 // Alfa calibrated for unit of lux

//  Rain Sensor
  int rainRaw, rainVal;

//  UV Sensor
  int uvVoltage = 0;
  int uvIndex = 0;    

//  Battery
  long battery;  

//  HAM PROTOCOL  
  const byte numChars = 64;
  char receivedChars[numChars];
  char tempChars[numChars]; // Temporary array for use when parsing

//  Variables to hold the parsed data
  String BT_REQUEST, messageFromBTplaceHolder, BT_PROTOCOL;
  boolean newData = false;

//----------------------\\


void setup() 
{

//  Bluetooth
  pinMode(btPin, OUTPUT);
  digitalWrite(btPin, HIGH);  // Power on Bluetooth via transistor
  delay(100);
  Serial.begin(9600); // Prepare communication through BT

//  DHT11 Sensor
  dht11.begin();  // Begin DHT11

//  MQ135 Sensor
  pinMode(mqPin, INPUT);  // Prepare pin to receive data
  pinMode(smPin, OUTPUT);
  digitalWrite(smPin, HIGH); // Power on MQ135 via transistor

//  Illuminance Sensor
  pinMode(poPin, INPUT);  // Prepare pin to receive data

//  Rain Sensor
  pinMode(rnPin, INPUT);  // Prepare pin to receive data  

//  UV Sensor
  pinMode(uvPin, INPUT);  // Prepare pin to receive data

//  BMP280 Sensor
  bmp280.initialize();
  bmp280.setEnabled(0);
  bmp280.triggerMeasurement();   
  
}

void loop()
{

  receiveHAMProtocol();
  if (newData == true) 
  {
    
    strcpy(tempChars, receivedChars); // Temporary copy to protect the original data for later manipulation
    
    if (parseData() == true)
    
    {
      
      manipulateData();
      
    }
   
    newData = false;
   
   }
  
}

void btRestart()  // Restarts the Bluetooth after transmitting data
{
  digitalWrite(btPin, LOW);
  delay(btTimeout);
  digitalWrite(btPin, HIGH);
  delay(100);
}

int readIl()  // Reads the Illuminance
{
  return((2500/(analogRead(poPin)*alfaIllu)-500)/10);  
}

int readMq()  // Reads the concentration of Pollution
{
  for(int i = 0; i < mqSamples; i++)
  {              
  mqArray[i] = analogRead(mqPin);      
  mqAverage += mqArray[i];  
  }
                
  mqValue = mqAverage / mqSamples;                  
  mqValue = map(mqValue, mqNoPol, 1023, 0, 100);                                                    
  mqAverage = 0;    
  return(mqValue);              
}

int readRn()  // Reads the Rain
{
  rainRaw = analogRead(rnPin);
  if(rainRaw <=1023)
  {
    rainVal = 1;
  }else if(rainRaw >= 1024 && rainRaw <= 8000)
  {
    rainVal = 2;
  }else if(rainRaw > 8000)
  {
    rainVal = 3;
  }

  return(rainVal);
}

int readUv()  // Reads the UV Index
{
  uvVoltage = (analogRead(uvPin) * (5.0 / 1023.0)) * 1000;
  if(uvVoltage<227){
    uvIndex = 0;
  }
  if(uvVoltage>=227){
    uvIndex = 1;
  }
  if(uvVoltage>=318){
    uvIndex = 2;
  }
  if(uvVoltage>=408){
    uvIndex = 3;
  }
  if(uvVoltage>=503){
    uvIndex = 4;
  }
  if(uvVoltage>=606){
    uvIndex = 5;
  }
  if(uvVoltage>=669){
    uvIndex = 6;
  }
  if(uvVoltage>=795){
    uvIndex = 7;
  }
  if(uvVoltage>=881){
    uvIndex = 8;
  }
  if(uvVoltage>=976){
    uvIndex = 9;
  }
  if(uvVoltage>=1079){
    uvIndex = 10;
  }
  if(uvVoltage>=1170){
    uvIndex = 11;
  }
  return(uvIndex);
}

float readPressure() // Reads the pressure
{
  bmp280.awaitMeasurement();
  bmp280.getPressure(pressure);
  bmp280.triggerMeasurement();

  return(pressure);
}

float readAltitude() // Reads the altitude
{
  bmp280.awaitMeasurement();
  bmp280.getAltitude(altitude);
  bmp280.triggerMeasurement();

  return(altitude);
}

long readBattery()  // Reads the battery percent
{
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC);  // Convert
while (bit_is_set(ADCSRA,ADSC)); 
battery = ADCL;
battery |= ADCH<<8; 
battery = 1126400L / battery; // Back-calculate AVcc in mV
return (map(battery, 4500, 5000, 0, 100)); 
}

void receiveHAMProtocol() // Receives the message via HAM PROTOCOL
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) 
    {
        rc = Serial.read();

        if (recvInProgress == true) 
        {
            if (rc != endMarker) // Searchs for the endMarker
            {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) 
                {
                    ndx = numChars - 1;
                }
            }
            else 
            {
                receivedChars[ndx] = '\0'; // Terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) // Searchs for the startMarker
        {
            recvInProgress = true;
        }
    }
}

String buildHAMProtocol(String channelName, int intData, float floatData, String stringData)  // Constructs the necessary HAM protocol to send
{
  
  return("<HAM-PROTOCOL,"+ channelName + "," + String(intData) + "," + String(floatData) + "," + stringData + ">");
  
}

boolean parseData() // Splits the data into its parts --> Expects <HAM-PROTOCOL, request>
{      

    boolean correctProtocol;  // Boolean var to store if the readed protocol is the correct one
    char * strtokIndx;  // This is used by strtok() as an index

    // EXPECTED FIRST PART: THE HAM PROTOCOL

    strtokIndx = strtok(tempChars,","); // Gets the first part (a String)
     
    messageFromBTplaceHolder += strtokIndx;    
    BT_PROTOCOL = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    if (BT_PROTOCOL == "HAM-PROTOCOL"){correctProtocol = true;} else {correctProtocol = false;}

    //======================================

    // EXPECTED SECOND PART: THE REQUEST
    
    strtokIndx = strtok(NULL, ","); // Gets the second part (a String)
    
    messageFromBTplaceHolder += strtokIndx;    
    BT_REQUEST = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    //=====================================

    return correctProtocol; // Returns true if the protocol used was HAM-PROTOCOL

} 

void manipulateData() // Manipulates the data received and parsed
{

    // COMMAND ZONE =========================================    
    
    if (BT_REQUEST == "ready.request") /*-->*/ {Serial.println(buildHAMProtocol("HAM-EXT", 0, 0, "OK-READY"));}
    if (BT_REQUEST == "HAM-EXT.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("HAM-EXT", 0, 0, "OK-OFF")); delay(250); /*-->*/ btRestart();}
    if (BT_REQUEST == "batteryEXT.request") /*-->*/ {Serial.println(buildHAMProtocol("batteryEXT", readBattery(), 0, "0"));}
    if (BT_REQUEST == "airpol.requestData") /*-->*/ {Serial.println(buildHAMProtocol("airpol", readMq(), 0, "0"));}
    if (BT_REQUEST == "exteriortemp.requestData") /*-->*/ {Serial.println(buildHAMProtocol("exteriortemp", 0, dht11.readTemperature(), "0"));}
    if (BT_REQUEST == "humidity.requestData") /*-->*/ {Serial.println(buildHAMProtocol("humidity", 0, dht11.readHumidity(), "0"));}
    if (BT_REQUEST == "illuminance.requestData") /*-->*/ {Serial.println(buildHAMProtocol("illuminance", readIl(), 0, "0"));}
    if (BT_REQUEST == "rain.requestData") /*-->*/ {Serial.println(buildHAMProtocol("rain", readRn(), 0, "0"));}
    if (BT_REQUEST == "uvrad.requestData") /*-->*/ {Serial.println(buildHAMProtocol("uvrad", readUv(), 0, "0"));}
    if (BT_REQUEST == "pressure.requestData") /*-->*/ {Serial.println(buildHAMProtocol("pressure", 0, readPressure(), "0"));}
    if (BT_REQUEST == "altitude.requestData") /*-->*/ {Serial.println(buildHAMProtocol("altitude", 0, readAltitude(), "0"));}
   
    if (BT_REQUEST == "airpol.requestAction.OFF") /*-->*/ {Serial.println(buildHAMProtocol("airpol", 0, 0, "OK-OFF")); /*-->*/ digitalWrite(smPin, LOW);}
    if (BT_REQUEST == "airpol.requestAction.ON") /*-->*/ {Serial.println(buildHAMProtocol("airpol", 0, 0, "OK-ON")); /*-->*/ digitalWrite(smPin, HIGH);}
    
    //=======================================================
    
}

HAM-HUB

Arduino
//  HAM HUB by @Neoxelox
//  Rev. 1 | Last modification: 12/10/2017

//  Library Section:

  #include <SoftwareSerial.h> // We need another Serial Communication for the Bluetooth
  #include <CayenneMQTTESP8266.h> // Libary for Cayenne via MQTT protocol
  #include <IRremoteESP8266.h>  // IR Library for HAM-BLINDS
  #include <IRsend.h>

//------------------\\

//  Define Section:

  #define btPin 5   // Bluetooth TX Pin
  #define brPin 4   // Bluetooth RX Pin
  #define tpPin A0  // Temperature Sensor Pin
  #define irPin 14  // IR Emitter Pin
  #define moPin 13  // Ir Motion Sensor Pin
  

  // Network INFO:
    char ssid[] = "";
    char wifiPassword[] = "";

  // MQQT INFO:
    char username[] = "";
    char password[] = "";
    char clientID[] = "";

//------------------\\

//  Variable Section:

//  Bluetooth
  SoftwareSerial btSerial (btPin,brPin); //(TX,RX)
  int btCycleIX = 1;
  char cycleHelper;
  String cHelper, channelRequesting;
  boolean goodTogo = false;
  int tryouts;
  #define tryout 15
  #define TimeBetweenCycle 20000
  // For MQs switches
    boolean mq135OFF, mq2OFF, mq5OFF, mq6OFF, mq7OFF;

//  IR Emitter
  IRsend irsend(irPin);
  
//  HAM PROTOCOL  
  const byte numChars = 64;
  char receivedChars[numChars];
  char tempChars[numChars]; // Temporary array for use when parsing

//  Variables to hold the parsed data
  String BT_CHANNEL, messageFromBTplaceHolder, BT_PROTOCOL, stringFromBT;
  int intFromBT;
  float floatFromBT;
  
  boolean newData = false;

//----------------------\\


void setup() 
{
  
//  Bluetooth
  btSerial.begin(38400); // Prepare communication through BT
  Serial.begin(9600);
  irsend.begin(); // Prepare IR Emitter
  pinMode(tpPin, INPUT); // Prepare pin to receive data
  pinMode(moPin, INPUT); // Prepare pin to receive data
  delay(500);
  btSerial.print("AT+INIT\r\n");  // Initialitze BT libraries
  Serial.println("INICIALIZANDO...");
  
  Cayenne.begin(username, password, clientID, ssid, wifiPassword);  // Initialize Cayenne
}

void loop()
{ 
  Cayenne.loop();
  readMotion();
  
  static unsigned long BTTimeToRead = millis();
  if (millis() >= BTTimeToRead + TimeBetweenCycle)
  {
    Cayenne.virtualWrite(28, readTemp());
    Serial.println("ENTRANDO EN CICLO");
    btCycle();
    BTTimeToRead = millis();
  }
  
}

CAYENNE_IN(20)
{
  if (getValue.asInt() == 1) 
  {
    mq135OFF = false;
  }else if (getValue.asInt() == 0)
  {
    mq135OFF = true;
  }
}

CAYENNE_IN(21)
{
  if (getValue.asInt() == 1) 
  {
    mq2OFF = false;
  }else if (getValue.asInt() == 0)
  {
    mq2OFF = true;
  }
}

CAYENNE_IN(22)
{
  if (getValue.asInt() == 1) 
  {
    mq5OFF = false;
  }else if (getValue.asInt() == 0)
  {
    mq5OFF = true;
  }
}

CAYENNE_IN(23)
{
  if (getValue.asInt() == 1) 
  {
    mq6OFF = false;
  }else if (getValue.asInt() == 0)
  {
    mq6OFF = true;
  }
}

CAYENNE_IN(24)
{
  if (getValue.asInt() == 1) 
  {
    mq7OFF = false;
  }else if (getValue.asInt() == 0)
  {
    mq7OFF = true;
  }
}

CAYENNE_IN(25)
{
  if (getValue.asInt() == 1) 
  {
    irsend.sendNEC(0xDC23, 38);
  }
}

CAYENNE_IN(26)
{
  if (getValue.asInt() == 1) 
  {
    irsend.sendNEC(0xDE21, 38);
  }
}

CAYENNE_IN(27)
{
  if (getValue.asInt() == 1) 
  {
    irsend.sendNEC(0xFC03, 38);
  }
}

void btReset()
{
  btSerial.print("AT+RESET\r\n");
  delay(1500);
  btSerial.print("AT+INIT\r\n");
  loop();
}

float readTemp()
{
  return((((analogRead(tpPin)/1024)*5) - 0.5) * 100);
}

void readMotion()
{
  int motion = 0;
  int oldMotion = 0;
  motion = digitalRead(moPin);
  
  if (motion =! oldMotion)
  {
    oldMotion = 1;
    Cayenne.virtualWrite(29, motion);
  }
}

void receiveHAMProtocol() // Receives the message via HAM PROTOCOL
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (btSerial.available() > 0 && newData == false) 
    {
        rc = btSerial.read();

        if (recvInProgress == true) 
        {
            if (rc != endMarker) // Searchs for the endMarker
            {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) 
                {
                    ndx = numChars - 1;
                }
            }
            else 
            {
                receivedChars[ndx] = '\0'; // Terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) // Searchs for the startMarker
        {
            recvInProgress = true;
        }
        yield();
    }
}

String buildHAMProtocol(String channelName, int intData, float floatData, String stringData)  // Constructs the necessary HAM protocol to send
{
  
  return("<HAM-PROTOCOL,"+ channelName + "," + String(intData) + "," + String(floatData) + "," + stringData + ">");
  
}

boolean parseData() // Splits the data into its parts --> Expects <HAM-PROTOCOL,Channel,IntData,FloatData,StringData>
{      

    boolean correctProtocol;  // Boolean var to store if the readed protocol is the correct one
    char * strtokIndx;  // This is used by strtok() as an index

    // EXPECTED FIRST PART: THE HAM PROTOCOL

    strtokIndx = strtok(tempChars,","); // Gets the first part (a String)
     
    messageFromBTplaceHolder += strtokIndx;    
    BT_PROTOCOL = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    if (BT_PROTOCOL == "HAM-PROTOCOL"){correctProtocol = true;} else {correctProtocol = false;}

    //======================================

    // EXPECTED SECOND PART: THE CHANNEL
    
    strtokIndx = strtok(NULL, ","); // Gets the second part (a String)
    
    messageFromBTplaceHolder += strtokIndx;    
    BT_CHANNEL = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    //=====================================

    // EXPECTED THIRD PART: THE DATA
    
    strtokIndx = strtok(NULL, ","); // Gets the first data part (an Int)
    
    intFromBT = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ","); // Gets the second data part (a Float)
    
    floatFromBT = atof(strtokIndx);

    strtokIndx = strtok(NULL, ","); // Gets the second data part (a Float)
    
    messageFromBTplaceHolder += strtokIndx;    
    stringFromBT = messageFromBTplaceHolder;   
    messageFromBTplaceHolder = "";

    //=====================================

    return correctProtocol; // Returns true if the protocol used was HAM-PROTOCOL

} 

void manipulateData() // Manipulates the data received and parsed
{

    // COMMAND ZONE =========================================    
    
    if (BT_CHANNEL == channelRequesting && stringFromBT == "OK-READY") /*-->*/ {goodTogo = true;}
    if (BT_CHANNEL == channelRequesting && stringFromBT == "OK-OFF") /*-->*/ {goodTogo = true;}

    if (BT_CHANNEL == "batteryRDT") /*-->*/ {Serial.print("BATTERY-RDT:");Serial.println(intFromBT);Cayenne.virtualWrite(0, intFromBT);}
    if (BT_CHANNEL == "emfield") /*-->*/ {Serial.print("EMFIELD:");Serial.println(intFromBT);Cayenne.virtualWrite(1, intFromBT);}
    if (BT_CHANNEL == "mfield") /*-->*/ {Serial.print("MFIELD:");Serial.println(intFromBT);Cayenne.virtualWrite(2, intFromBT);}
    if (BT_CHANNEL == "irrad") /*-->*/ {Serial.print("IRRAD:");Serial.println(intFromBT);Cayenne.virtualWrite(3, intFromBT);}
    if (BT_CHANNEL == "decibel") /*-->*/ {Serial.print("DECIBEL:");Serial.println(floatFromBT);Cayenne.virtualWrite(4, floatFromBT);}

    if (BT_CHANNEL == "batteryEXT") /*-->*/ {Serial.print("BATTERY-EXT:");Serial.println(intFromBT);Cayenne.virtualWrite(5, intFromBT);}
    if (BT_CHANNEL == "airpol") /*-->*/ {Serial.print("AIRPOL:");Serial.println(intFromBT);Cayenne.virtualWrite(6, intFromBT);}
    if (BT_CHANNEL == "airpol" && stringFromBT != "0") /*-->*/ {Serial.print("AIRPOL:");Serial.println(stringFromBT);}
    if (BT_CHANNEL == "exteriortemp") /*-->*/ {Serial.print("EXTERIORTEMP:");Serial.println(floatFromBT);Cayenne.virtualWrite(7, floatFromBT);}
    if (BT_CHANNEL == "humidity") /*-->*/ {Serial.print("HUMIDITY:");Serial.println(floatFromBT);Cayenne.virtualWrite(8, floatFromBT);}
    if (BT_CHANNEL == "illuminance") /*-->*/ {Serial.print("ILLUMINANCE:");Serial.println(intFromBT);Cayenne.virtualWrite(9, intFromBT);}
    if (BT_CHANNEL == "rain") /*-->*/ {Serial.print("RAIN:");Serial.println(intFromBT);Cayenne.virtualWrite(10, intFromBT);}
    if (BT_CHANNEL == "uvrad") /*-->*/ {Serial.print("UVRAD:");Serial.println(intFromBT);Cayenne.virtualWrite(11, intFromBT);}
    if (BT_CHANNEL == "pressure") /*-->*/ {Serial.print("PRESSURE:");Serial.println(floatFromBT);Cayenne.virtualWrite(12, floatFromBT);}

    if (BT_CHANNEL == "batteryGAS") /*-->*/ {Serial.print("BATTERY-GAS:");Serial.println(intFromBT);Cayenne.virtualWrite(13, intFromBT);}
    if (BT_CHANNEL == "CO2") /*-->*/ {Serial.print("CO2:");Serial.println(intFromBT);Cayenne.virtualWrite(14, intFromBT);}
    if (BT_CHANNEL == "CO2" && stringFromBT != "0") /*-->*/ {Serial.print("CO2:");Serial.println(stringFromBT);}
    if (BT_CHANNEL == "natugas") /*-->*/ {Serial.print("NATUGAS:");Serial.println(intFromBT);Cayenne.virtualWrite(15, intFromBT);}
    if (BT_CHANNEL == "natugas" && stringFromBT != "0") /*-->*/ {Serial.print("NATUGAS:");Serial.println(stringFromBT);}
    if (BT_CHANNEL == "butprop") /*-->*/ {Serial.print("BUTPROP:");Serial.println(intFromBT);Cayenne.virtualWrite(16, intFromBT);}
    if (BT_CHANNEL == "butprop" && stringFromBT != "0") /*-->*/ {Serial.print("BUTPROP:");Serial.println(stringFromBT);}
    if (BT_CHANNEL == "CO") /*-->*/ {Serial.print("CO:");Serial.println(intFromBT);Cayenne.virtualWrite(17, intFromBT);}
    if (BT_CHANNEL == "CO" && stringFromBT != "0") /*-->*/ {Serial.print("CO:");Serial.println(stringFromBT);}
    if (BT_CHANNEL == "flame") /*-->*/ {Serial.print("FLAME:");Serial.println(intFromBT);Cayenne.virtualWrite(18, intFromBT);}
    if (BT_CHANNEL == "kitchentemp") /*-->*/ {Serial.print("KITCHENTEMP:");Serial.println(floatFromBT);Cayenne.virtualWrite(19, floatFromBT);}

    //=======================================================
    
}

void btCycle()  // Cycle for false piconet
{
  
  switch(btCycleIX)
  {
    
    case 1: // Cycle for HAM-RDT
    Serial.println("ENTRADO EN CICLO HAM-RDT"); //DELETE DEBUG
    channelRequesting = "HAM-RDT";
    Serial.println("ENVIANDO AT");  //DELETE DEBUG
    tryouts = 0;
    cHelper = "";
    while (cHelper != "OK\r\n") // Wait until BT says OK
    {
      cHelper = "";
      btSerial.print("AT\r\n");
      
      while (btSerial.available())
      {
        cycleHelper = btSerial.read();
        cHelper += cycleHelper;
        yield();
      }
      
      Serial.print(cHelper);  //DELETE DEBUG
      yield();
            
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      
      delay(100);      
    }
    cHelper = "";
    tryouts = 0;
    
    delay(100);
    
    Serial.println("ENVIANDO AT+LINK"); //DELETE DEBUG 
    btSerial.print("AT+LINK=98D3,31,B30806\r\n"); // Connect with HAM-RDT
   
    delay(5000);
    
    tryouts = 0;
    goodTogo = false;
    while (goodTogo == false) // Wait until ready.request is OK
    {
      btSerial.print("<HAM-PROTOCOL,ready.request>");
      getData();
      
      Serial.println("READY REQUEST ENVIADO");  //DELETE DEBUG
      yield();
      
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      delay(250);
    }
    goodTogo = false;
    tryouts = 0;
    
    // Connected!
    // Sending all the data requests
    for (int i = 1; i <= 6; i++)
    {

      switch(i)
      {
        case 1:
        btSerial.print("<HAM-PROTOCOL,batteryRDT.request>");
        break;
        case 2:
        btSerial.print("<HAM-PROTOCOL,emfield.requestData>");
        break;
        case 3:
        btSerial.print("<HAM-PROTOCOL,mfield.requestData>");
        break;
        case 4:
        btSerial.print("<HAM-PROTOCOL,irrad.requestData>");
        break;
        case 5:
        btSerial.print("<HAM-PROTOCOL,decibel.requestData>");
        break;        
      }
      
      getData();
      yield();
      Cayenne.loop();
      delay(250);
    }

    // Ending the communication
    tryouts = 0;
    goodTogo = false;
    Serial.println("ENTRANDO EN OFF");  //DELETE DEBUG
    while (goodTogo == false) // Wait until HAM-RDT.requestAction.OFF is OK
    {
      btSerial.print("<HAM-PROTOCOL,HAM-RDT.requestAction.OFF>");
      getData();
      
      Serial.println("OFF ENVIADO");  //DELETE DEBUG
      yield();
      
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      delay(250);
    }
    goodTogo = false;
    tryouts = 0;
        
    btCycleIX = 2;
    delay(2000);
    break;
    //---------------------------
    //---------------------------
    case 2: // Cycle for HAM-EXT
    Serial.println("ENTRADO EN CICLO HAM-EXT"); //DELETE DEBUG
    channelRequesting = "HAM-EXT";
    Serial.println("ENVIANDO AT");  //DELETE DEBUG
    tryouts = 0;
    cHelper = "";
    while (cHelper != "OK\r\n") // Wait until BT says OK
    {
      cHelper = "";
      btSerial.print("AT\r\n");
      
      while (btSerial.available())
      {
        cycleHelper = btSerial.read();
        cHelper += cycleHelper;
        yield();
      }
      
      Serial.print(cHelper);  //DELETE DEBUG
      yield();
      
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      
      delay(100);      
    }
    cHelper = "";
    tryouts = 0;
    
    delay(100);
    
    Serial.println("ENVIANDO AT+LINK"); //DELETE DEBUG 
    btSerial.print("AT+LINK=98D3,31,80A173\r\n"); // Connect with HAM-EXT
   
    delay(5000);
    
    tryouts = 0;
    goodTogo = false;
    while (goodTogo == false) // Wait until ready.request is OK
    {
      btSerial.print("<HAM-PROTOCOL,ready.request>");
      getData();
      
      Serial.println("READY REQUEST ENVIADO");  //DELETE DEBUG
      yield();
      
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      delay(250);
    }
    goodTogo = false;
    tryouts = 0;
    
    // Connected!
    // Sending all the data requests
    for (int i = 1; i <= 10; i++)
    {

      switch(i)
      {
        
        case 1:
        btSerial.print("<HAM-PROTOCOL,batteryEXT.request>");
        break;
        case 2:
        btSerial.print("<HAM-PROTOCOL,airpol.requestData>");
        break;
        case 3:
        btSerial.print("<HAM-PROTOCOL,exteriortemp.requestData>");
        break;
        case 4:
        btSerial.print("<HAM-PROTOCOL,humidity.requestData>");
        break;
        case 5:
        btSerial.print("<HAM-PROTOCOL,illuminance.requestData>");
        break;
        case 6:
        btSerial.print("<HAM-PROTOCOL,rain.requestData>");
        break;
        case 7:
        btSerial.print("<HAM-PROTOCOL,uvrad.requestData>");
        break;
        case 8:
        btSerial.print("<HAM-PROTOCOL,pressure.requestData>");
        break;
        case 9:
        if (mq135OFF == false)
        {
          btSerial.print("<HAM-PROTOCOL,airpol.requestAction.ON>"); 
        }else if (mq135OFF == true)
        {
          btSerial.print("<HAM-PROTOCOL,airpol.requestAction.OFF>");  
        }
        break;
                  
      }
      
      getData();
      yield();
      Cayenne.loop();
      delay(250);
    }

    // Ending the communication
    tryouts = 0;
    goodTogo = false;
    Serial.println("ENTRANDO EN OFF");  //DELETE DEBUG
    while (goodTogo == false) // Wait until HAM-EXT.requestAction.OFF is OK
    {
      btSerial.print("<HAM-PROTOCOL,HAM-EXT.requestAction.OFF>");
      getData();
      
      Serial.println("OFF ENVIADO");  //DELETE DEBUG
      yield();
      
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      delay(250);
    }
    goodTogo = false;
    tryouts = 0;
    
    btCycleIX = 3;
    delay(2000);
    break;
    //---------------------------
    //---------------------------
    case 3: // Cycle for HAM-GAS
    Serial.println("ENTRADO EN CICLO HAM-GAS"); //DELETE DEBUG
    channelRequesting = "HAM-GAS";
    Serial.println("ENVIANDO AT");  //DELETE DEBUG
    tryouts = 0;
    cHelper = "";
    while (cHelper != "OK\r\n") // Wait until BT says OK
    {
      cHelper = "";
      btSerial.print("AT\r\n");
      
      while (btSerial.available())
      {
        cycleHelper = btSerial.read();
        cHelper += cycleHelper;
        yield();
      }
      
      Serial.print(cHelper);  //DELETE DEBUG
      yield();

      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      
      delay(100);      
    }
    cHelper = "";
    tryouts = 0;
    
    delay(100);
    
    Serial.println("ENVIANDO AT+LINK"); //DELETE DEBUG 
    btSerial.print("AT+LINK=98D3,31,FD5B2E\r\n"); // Connect with HAM-GAS
   
    delay(5000);
    
    tryouts = 0;
    goodTogo = false;
    while (goodTogo == false) // Wait until ready.request is OK
    {
      btSerial.print("<HAM-PROTOCOL,ready.request>");
      getData();
      
      Serial.println("READY REQUEST ENVIADO");  //DELETE DEBUG
      yield();
      
      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      delay(250);
    }
    goodTogo = false;
    tryouts = 0;
    
    // Connected!
    // Sending all the data requests
    for (int i = 1; i <= 12; i++)
    {

      switch(i)
      {
        
        case 1:
        btSerial.print("<HAM-PROTOCOL,batteryGAS.request>");
        break;
        case 2:
        btSerial.print("<HAM-PROTOCOL,CO2.requestData>");
        break;
        case 3:
        btSerial.print("<HAM-PROTOCOL,natugas.requestData>");
        break;
        case 4:
        btSerial.print("<HAM-PROTOCOL,butprop.requestData>");
        break;
        case 5:
        btSerial.print("<HAM-PROTOCOL,CO.requestData>");
        break;
        case 6:
        btSerial.print("<HAM-PROTOCOL,flame.requestData>");
        break;
        case 7:
        btSerial.print("<HAM-PROTOCOL,kitchentemp.requestData>");
        break;
        case 8:
        if (mq2OFF == false)
        {
          btSerial.print("<HAM-PROTOCOL,CO2.requestAction.ON>"); 
        }else if (mq2OFF == true)
        {
          btSerial.print("<HAM-PROTOCOL,CO2.requestAction.OFF>");  
        }
        break;
        case 9:
        if (mq5OFF == false)
        {
          btSerial.print("<HAM-PROTOCOL,natugas.requestAction.ON>"); 
        }else if (mq5OFF == true)
        {
          btSerial.print("<HAM-PROTOCOL,natugas.requestAction.OFF>");  
        }
        break;
        case 10:
        if (mq6OFF == false)
        {
          btSerial.print("<HAM-PROTOCOL,butprop.requestAction.ON>"); 
        }else if (mq6OFF == true)
        {
          btSerial.print("<HAM-PROTOCOL,butprop.requestAction.OFF>");  
        }
        break;
        case 11:
        if (mq7OFF == false)
        {
          btSerial.print("<HAM-PROTOCOL,CO.requestAction.ON>"); 
        }else if (mq7OFF == true)
        {
          btSerial.print("<HAM-PROTOCOL,CO.requestAction.OFF>");  
        }
        break;          
      }
      
      getData();
      yield();
      Cayenne.loop();
      delay(250);
    }

    // Ending the communication
    tryouts = 0;
    goodTogo = false;
    Serial.println("ENTRANDO EN OFF");  //DELETE DEBUG
    while (goodTogo == false) // Wait until HAM-GAS.requestAction.OFF is OK
    {
      btSerial.print("<HAM-PROTOCOL,HAM-GAS.requestAction.OFF>");
      getData();
      
      Serial.println("OFF ENVIADO");  //DELETE DEBUG
      yield();

      if (tryouts == tryout)
      {
        tryouts = 0;
        btReset();
      }else if (tryouts != tryout)
      {
        tryouts++;
      }
      delay(250);
    }
    goodTogo = false;
    tryouts = 0;
    
    btCycleIX = 1;
    delay(2000);
    break;
    
  }
  
}

void getData()
{

  receiveHAMProtocol();
  if (newData == true) 
  {
    
    strcpy(tempChars, receivedChars); // Temporary copy to protect the original data for later manipulation
    
    if (parseData() == true)
    
    {
      
      manipulateData();
      
    }
   
    newData = false;
   
  }
  yield();
  Cayenne.loop();
  
}

Credits

Alex

Alex

2 projects • 5 followers

Comments