Hardware components | ||||||
| × | 1 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 3 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 5 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
|
Welcome to the definition of IoT, welcome to HAM.
Source files: https://github.com/Neoxelox/HAM
An star and a watch is appreciated ;)
Video: demo of the project --> http://bit.ly/2gJbY01
INTRODUCTIONHAM, Home Automatation and Monitoring system, is the result of the combination of 4 outstanding things: Cayenne, ESP8266, Arduino and Raspberry.
The HAM network is formed by 5 different nodes and a central hub. However, thanks to the exclusive protocol inside of all the network, the HAM-PROTOCOL, can be expanded with more and more nodes.
It also features an exclusive APP, using Cayenne API, which brings together sensors data and the video surveillance system.
THE NODESThere are 3 nodes, HAM-EXT (exterior), HAM-RDT (radiation) and HAM-GAS (gases), formed by all types of sensors. RDT and GAS, have gas sensors as Air Pollution, CO2, Natural Gas... which can affect heavily the duration of the battery, because of that, they are controlled by a transistor which the user can switch off/on. There is also the HAM-BLINDS node, which is the controller for the blinds. The last node is HAM-PEEPHOLE, which is a video surveillance system with vibration sensor, illuminance sensor and a loud alarm. The hub, HAM-HUB, is formed by a Sparkfun 8266 dev thing, temperature sensor, IR emitter, bluetooth, and in future updates it will feature a display in case internet access is down. The 3 node sensors have a built-in battery with charger, this allows to make them portable, and stick them in any surface. HAM-HUB is meant to be static, HAM-BLINDS is inside of a blind controller and HAM-PEEPHOLE is attached to a peephole, and it is also meant to be static because of the power consumption of the RPI 0 W.
CONNECTIVITYThe connectivity of the HAM network is not only WiFi, actually only HAM-HUB has it, to send data values to cayenne, and also HAM-PEEPHOLE, where a camera surveillance server is hosted. HAM-EXT, HAM-GAS and HAM-RDT are connected to the hub via bluetooth, but how? Well, there are some BT modules that features piconet, which is a multi-slave bluetooth network. However, that things are $$$$, because of that, I decided to make my own false "piconet". Summarized, the proccess is a cycle for each BT module, divided in 3 parts: Connection, Gathering the sensors value and Disconnection. This is possible by entering the AT mode in a HC-05, and controlling the AT commands. This can seem tricky, but it actually made me end up making a hole protocol for all the nodes, which was a great idea. The protocol is named HAM-PROTOCOL, and it allows transfering, integer, float or string, information by the two ways in all my nodes, and it's more, I can make more nodes whenever I want, and putting them to the network in a few minutes. The protocol is explained in the codes of the nodes. However it looks like this:
To request a value or a sensor or something:
<HAM-PROTOCOL,REQUEST>
Example: <HAM-PROTOCOL,batteryRDT.request>
To answer that request or send information:
<HAM-PROTOCOL,CHANNEL,INT_DATA,FLOAT_DATA,STRING_DATA>
Example:
<HAM-PROTOCOL,batteryRDT,readBattery(),0,"0">
Another example: Request and responses used in the cycle for the false piconet:
- Connection:
Request:
<HAM-PROTOCOL,ready.request>
Response:
<HAM-PROTOCOL,HAM-EXT,0,0,"OK-READY">
- Gathering sensors data: Request and Response like in the examples.
- Disconnection:
Request:
<HAM-PROTOCOL,HAM-EXT.requestAction.OFF>
Response:
<HAM-PROTOCOL,HAM-EXT,0,0,"OK-OFF">
And the BT module in HAM-EXT will reboot, disconnecting BT Master module from him.
Finnaly, because HAM-BLINDS is inside of a little blind controller, it has to be very small, that's why I went for ATTINY85, and for the connectivity I decided IR using the HAM-PROTOCOL.
THE LIST OF SENSORS, ACTUATORS AND MORE, THAT EACH NODE HAS AND WHY- HAM-HUB
- TMP-36GZ: Temperature sensor. For room temperature.
- HC-SR501: IR Motion sensor. If anyone wants to touch the hub I will know...
- IR Emitter: To control HAM-BLINDS (or anything with IR).
- HC-05: In MASTER mode, to control all the Slaves.
- HAM-PEEPHOLE
- KY-01: Vibration sensor. It detects if anyone is entering or if the lock is being forced by burglars.
- LDR: Peephole darkness sensor. It detects if someone covers the peephole and blocks the video from the camera. As RPI 0 W doesn't have any analog inputs, it has a special circuit which RPI measures the time the capacitor takes to fill.
- Alarm: Loud alarm, borrowed from a old lego block I had, which RPI activates if the camera is blocked for 5 seconds, or if the vibrations are continuos.
- Webcam: Old webcam from a dead laptop. It can be any usb camera as RPI is using Motion script.
- HAM-BLINDS
- IR Receiver: To receive requests from HAM-HUB.
- Transistors: An ATTINY85 controls the motherboard of the blinds controller with transistors.
- HAM-EXT
- MQ 135: Air pollution sensor. God bless global warming!
- DHT11: Humidity/Temperature sensor. For exterior temperature/humidity.
- GY-91: Barometric pressure and altitude sensor, well altitude is not being measured (useless I think).
- KY-045: Rain sensor. It detects if it is raining / raining hard.
- LDR: Solar Illuminance sensor. Just take sun cream if this sensor says to you.
- UVM-30A: Solar UV sensor. High UV causes skin cancer.
- HC-06: Slave bluetooth for communication.
- HAM-RDT
- EMF Sensor: Electromagnetic field sensor. That radiation can cause cancer. This sensor is based on an antenna with a 3.3MOhm resistor.
- KY-05: Magnetic field sensor. Magnetic waves disturb our dreams.
- TSOP 34138: IR radiaton sensor. The atmosphere is pretty hot! Open the windows!
- SPARKFUN Electret MIC: You can already complain to your neighbor.
- HC-06: Slave bluetooth for communication.
- HAM-GAS
- MQ 2: CO2 sensor. CO2 is never good...
- MQ 5: Natural gas. At least my boiler works with it, so its good to detect any gas leak.
- MQ 6: Butane/Propane. Well I don't have a gas cooker, but my neighbors yes.
- MQ 7: CO is colorless, odorless, it doesn't taste, and last but not least it is letal.
- Thermistor: Temperature sensor. For Kitchen temperature (I run out of digital tmp sensors).
- KY-026: Fire sensor. Self-explanatory.
- HC-06: Slave bluetooth for communication.
THE HAM APPIt's in beta phase, so there is a bug with ham-gas displaying a "-", and the camera viewer works when it wants, but if I view it with chrome it works, I don't know why...
CAYENNE DASHBOARDThe nodes doesn't have an enclosure, which would be great, sadly I don't have a 3DPrinter, and I cannot use another material like wood, because of its weight. However, I have already experimented with 3D Modeling and I have made a sketch of how enclosures could be.
// 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 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)
// 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"));}
//=======================================================
}
// 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);}
//=======================================================
}
// 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 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();
}
Comments