Repo restyled using astyle (#683)
The rules are in .tools/astyle/config/style.cfg and can also be reviewed at https://www.mysensors.org/view/260#coding-guidelines-core-library
This commit is contained in:
@@ -48,14 +48,14 @@
|
||||
#define MQ_SENSOR_ANALOG_PIN (0) //define which analog input channel you are going to use
|
||||
#define RL_VALUE (5) //define the load resistance on the board, in kilo ohms
|
||||
#define RO_CLEAN_AIR_FACTOR (9.83) //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
|
||||
//which is derived from the chart in datasheet
|
||||
//which is derived from the chart in datasheet
|
||||
/***********************Software Related Macros************************************/
|
||||
#define CALIBARAION_SAMPLE_TIMES (50) //define how many samples you are going to take in the calibration phase
|
||||
#define CALIBRATION_SAMPLE_INTERVAL (500) //define the time interal(in milisecond) between each samples in the
|
||||
//cablibration phase
|
||||
//cablibration phase
|
||||
#define READ_SAMPLE_INTERVAL (50) //define how many samples you are going to take in normal operation
|
||||
#define READ_SAMPLE_TIMES (5) //define the time interal(in milisecond) between each samples in
|
||||
//normal operation
|
||||
//normal operation
|
||||
/**********************Application Related Macros**********************************/
|
||||
#define GAS_LPG (0)
|
||||
#define GAS_CO (1)
|
||||
@@ -68,58 +68,60 @@ int val = 0; // variable to store the value coming from the sensor
|
||||
float valMQ =0.0;
|
||||
float lastMQ =0.0;
|
||||
float LPGCurve[3] = {2.3,0.21,-0.47}; //two points are taken from the curve.
|
||||
//with these two points, a line is formed which is "approximately equivalent"
|
||||
//to the original curve.
|
||||
//data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59)
|
||||
//with these two points, a line is formed which is "approximately equivalent"
|
||||
//to the original curve.
|
||||
//data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59)
|
||||
float COCurve[3] = {2.3,0.72,-0.34}; //two points are taken from the curve.
|
||||
//with these two points, a line is formed which is "approximately equivalent"
|
||||
//to the original curve.
|
||||
//data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000, 0.15)
|
||||
float SmokeCurve[3] ={2.3,0.53,-0.44}; //two points are taken from the curve.
|
||||
//with these two points, a line is formed which is "approximately equivalent"
|
||||
//to the original curve.
|
||||
//data format:{ x, y, slope}; point1: (lg200, 0.53), point2:(lg10000,-0.22)
|
||||
//with these two points, a line is formed which is "approximately equivalent"
|
||||
//to the original curve.
|
||||
//data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000, 0.15)
|
||||
float SmokeCurve[3] = {2.3,0.53,-0.44}; //two points are taken from the curve.
|
||||
//with these two points, a line is formed which is "approximately equivalent"
|
||||
//to the original curve.
|
||||
//data format:{ x, y, slope}; point1: (lg200, 0.53), point2:(lg10000,-0.22)
|
||||
|
||||
|
||||
MyMessage msg(CHILD_ID_MQ, V_LEVEL);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Ro = MQCalibration(MQ_SENSOR_ANALOG_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air
|
||||
Ro = MQCalibration(
|
||||
MQ_SENSOR_ANALOG_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Air Quality Sensor", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Air Quality Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_MQ, S_AIR_QUALITY);
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_MQ, S_AIR_QUALITY);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
uint16_t valMQ = MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_CO);
|
||||
Serial.println(val);
|
||||
uint16_t valMQ = MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_CO);
|
||||
Serial.println(val);
|
||||
|
||||
Serial.print("LPG:");
|
||||
Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_LPG) );
|
||||
Serial.print( "ppm" );
|
||||
Serial.print(" ");
|
||||
Serial.print("CO:");
|
||||
Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_CO) );
|
||||
Serial.print( "ppm" );
|
||||
Serial.print(" ");
|
||||
Serial.print("SMOKE:");
|
||||
Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_SMOKE) );
|
||||
Serial.print( "ppm" );
|
||||
Serial.print("\n");
|
||||
Serial.print("LPG:");
|
||||
Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_LPG) );
|
||||
Serial.print( "ppm" );
|
||||
Serial.print(" ");
|
||||
Serial.print("CO:");
|
||||
Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_CO) );
|
||||
Serial.print( "ppm" );
|
||||
Serial.print(" ");
|
||||
Serial.print("SMOKE:");
|
||||
Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN)/Ro,GAS_SMOKE) );
|
||||
Serial.print( "ppm" );
|
||||
Serial.print("\n");
|
||||
|
||||
if (valMQ != lastMQ) {
|
||||
send(msg.set((int16_t)ceil(valMQ)));
|
||||
lastMQ = ceil(valMQ);
|
||||
}
|
||||
if (valMQ != lastMQ) {
|
||||
send(msg.set((int16_t)ceil(valMQ)));
|
||||
lastMQ = ceil(valMQ);
|
||||
}
|
||||
|
||||
sleep(SLEEP_TIME); //sleep for: sleepTime
|
||||
sleep(SLEEP_TIME); //sleep for: sleepTime
|
||||
}
|
||||
|
||||
/****************** MQResistanceCalculation ****************************************
|
||||
@@ -131,7 +133,7 @@ Remarks: The sensor and the load resistor forms a voltage divider. Given the vol
|
||||
************************************************************************************/
|
||||
float MQResistanceCalculation(int raw_adc)
|
||||
{
|
||||
return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
|
||||
return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
|
||||
}
|
||||
|
||||
/***************************** MQCalibration ****************************************
|
||||
@@ -144,19 +146,19 @@ Remarks: This function assumes that the sensor is in clean air. It use
|
||||
************************************************************************************/
|
||||
float MQCalibration(int mq_pin)
|
||||
{
|
||||
int i;
|
||||
float val=0;
|
||||
int i;
|
||||
float val=0;
|
||||
|
||||
for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { //take multiple samples
|
||||
val += MQResistanceCalculation(analogRead(mq_pin));
|
||||
delay(CALIBRATION_SAMPLE_INTERVAL);
|
||||
}
|
||||
val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value
|
||||
for (i=0; i<CALIBARAION_SAMPLE_TIMES; i++) { //take multiple samples
|
||||
val += MQResistanceCalculation(analogRead(mq_pin));
|
||||
delay(CALIBRATION_SAMPLE_INTERVAL);
|
||||
}
|
||||
val = val/CALIBARAION_SAMPLE_TIMES; //calculate the average value
|
||||
|
||||
val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
|
||||
//according to the chart in the datasheet
|
||||
val = val/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
|
||||
//according to the chart in the datasheet
|
||||
|
||||
return val;
|
||||
return val;
|
||||
}
|
||||
/***************************** MQRead *********************************************
|
||||
Input: mq_pin - analog channel
|
||||
@@ -168,17 +170,17 @@ Remarks: This function use MQResistanceCalculation to caculate the sensor resist
|
||||
************************************************************************************/
|
||||
float MQRead(int mq_pin)
|
||||
{
|
||||
int i;
|
||||
float rs=0;
|
||||
int i;
|
||||
float rs=0;
|
||||
|
||||
for (i=0;i<READ_SAMPLE_TIMES;i++) {
|
||||
rs += MQResistanceCalculation(analogRead(mq_pin));
|
||||
delay(READ_SAMPLE_INTERVAL);
|
||||
}
|
||||
for (i=0; i<READ_SAMPLE_TIMES; i++) {
|
||||
rs += MQResistanceCalculation(analogRead(mq_pin));
|
||||
delay(READ_SAMPLE_INTERVAL);
|
||||
}
|
||||
|
||||
rs = rs/READ_SAMPLE_TIMES;
|
||||
rs = rs/READ_SAMPLE_TIMES;
|
||||
|
||||
return rs;
|
||||
return rs;
|
||||
}
|
||||
|
||||
/***************************** MQGetGasPercentage **********************************
|
||||
@@ -190,15 +192,15 @@ Remarks: This function passes different curves to the MQGetPercentage function w
|
||||
************************************************************************************/
|
||||
int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
|
||||
{
|
||||
if ( gas_id == GAS_LPG ) {
|
||||
return MQGetPercentage(rs_ro_ratio,LPGCurve);
|
||||
} else if ( gas_id == GAS_CO ) {
|
||||
return MQGetPercentage(rs_ro_ratio,COCurve);
|
||||
} else if ( gas_id == GAS_SMOKE ) {
|
||||
return MQGetPercentage(rs_ro_ratio,SmokeCurve);
|
||||
}
|
||||
if ( gas_id == GAS_LPG ) {
|
||||
return MQGetPercentage(rs_ro_ratio,LPGCurve);
|
||||
} else if ( gas_id == GAS_CO ) {
|
||||
return MQGetPercentage(rs_ro_ratio,COCurve);
|
||||
} else if ( gas_id == GAS_SMOKE ) {
|
||||
return MQGetPercentage(rs_ro_ratio,SmokeCurve);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************** MQGetPercentage **********************************
|
||||
@@ -212,5 +214,5 @@ Remarks: By using the slope and a point of the line. The x(logarithmic value of
|
||||
************************************************************************************/
|
||||
int MQGetPercentage(float rs_ro_ratio, float *pcurve)
|
||||
{
|
||||
return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
|
||||
return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@
|
||||
* This is an example that demonstrates how to report the battery level for a sensor
|
||||
* Instructions for measuring battery capacity on A0 are available here:
|
||||
* http://www.mysensors.org/build/battery
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
@@ -42,51 +42,52 @@ int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
|
||||
unsigned long SLEEP_TIME = 900000; // sleep time between reads (seconds * 1000 milliseconds)
|
||||
int oldBatteryPcnt = 0;
|
||||
|
||||
void setup()
|
||||
void setup()
|
||||
{
|
||||
// use the 1.1 V internal reference
|
||||
// use the 1.1 V internal reference
|
||||
#if defined(__AVR_ATmega2560__)
|
||||
analogReference(INTERNAL1V1);
|
||||
analogReference(INTERNAL1V1);
|
||||
#else
|
||||
analogReference(INTERNAL);
|
||||
analogReference(INTERNAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Battery Meter", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Battery Meter", "1.0");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// get the battery Voltage
|
||||
int sensorValue = analogRead(BATTERY_SENSE_PIN);
|
||||
#ifdef MY_DEBUG
|
||||
Serial.println(sensorValue);
|
||||
#endif
|
||||
|
||||
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
|
||||
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
|
||||
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
|
||||
// 3.44/1023 = Volts per bit = 0.003363075
|
||||
|
||||
int batteryPcnt = sensorValue / 10;
|
||||
// get the battery Voltage
|
||||
int sensorValue = analogRead(BATTERY_SENSE_PIN);
|
||||
#ifdef MY_DEBUG
|
||||
Serial.println(sensorValue);
|
||||
#endif
|
||||
|
||||
#ifdef MY_DEBUG
|
||||
float batteryV = sensorValue * 0.003363075;
|
||||
Serial.print("Battery Voltage: ");
|
||||
Serial.print(batteryV);
|
||||
Serial.println(" V");
|
||||
// 1M, 470K divider across battery and using internal ADC ref of 1.1V
|
||||
// Sense point is bypassed with 0.1 uF cap to reduce noise at that point
|
||||
// ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
|
||||
// 3.44/1023 = Volts per bit = 0.003363075
|
||||
|
||||
Serial.print("Battery percent: ");
|
||||
Serial.print(batteryPcnt);
|
||||
Serial.println(" %");
|
||||
#endif
|
||||
int batteryPcnt = sensorValue / 10;
|
||||
|
||||
if (oldBatteryPcnt != batteryPcnt) {
|
||||
// Power up radio after sleep
|
||||
sendBatteryLevel(batteryPcnt);
|
||||
oldBatteryPcnt = batteryPcnt;
|
||||
}
|
||||
sleep(SLEEP_TIME);
|
||||
#ifdef MY_DEBUG
|
||||
float batteryV = sensorValue * 0.003363075;
|
||||
Serial.print("Battery Voltage: ");
|
||||
Serial.print(batteryV);
|
||||
Serial.println(" V");
|
||||
|
||||
Serial.print("Battery percent: ");
|
||||
Serial.print(batteryPcnt);
|
||||
Serial.println(" %");
|
||||
#endif
|
||||
|
||||
if (oldBatteryPcnt != batteryPcnt) {
|
||||
// Power up radio after sleep
|
||||
sendBatteryLevel(batteryPcnt);
|
||||
oldBatteryPcnt = batteryPcnt;
|
||||
}
|
||||
sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
@@ -69,52 +69,53 @@ MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED);
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Setup the buttons
|
||||
pinMode(PRIMARY_BUTTON_PIN, INPUT);
|
||||
pinMode(SECONDARY_BUTTON_PIN, INPUT);
|
||||
// Setup the buttons
|
||||
pinMode(PRIMARY_BUTTON_PIN, INPUT);
|
||||
pinMode(SECONDARY_BUTTON_PIN, INPUT);
|
||||
|
||||
// Activate internal pull-ups
|
||||
digitalWrite(PRIMARY_BUTTON_PIN, HIGH);
|
||||
digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
|
||||
// Activate internal pull-ups
|
||||
digitalWrite(PRIMARY_BUTTON_PIN, HIGH);
|
||||
digitalWrite(SECONDARY_BUTTON_PIN, HIGH);
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
|
||||
|
||||
// Register binary input sensor to sensor_node (they will be created as child devices)
|
||||
// You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
|
||||
// If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
|
||||
present(PRIMARY_CHILD_ID, S_DOOR);
|
||||
present(SECONDARY_CHILD_ID, S_DOOR);
|
||||
// Register binary input sensor to sensor_node (they will be created as child devices)
|
||||
// You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
|
||||
// If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
|
||||
present(PRIMARY_CHILD_ID, S_DOOR);
|
||||
present(SECONDARY_CHILD_ID, S_DOOR);
|
||||
}
|
||||
|
||||
// Loop will iterate on changes on the BUTTON_PINs
|
||||
void loop()
|
||||
{
|
||||
uint8_t value;
|
||||
static uint8_t sentValue=2;
|
||||
static uint8_t sentValue2=2;
|
||||
uint8_t value;
|
||||
static uint8_t sentValue=2;
|
||||
static uint8_t sentValue2=2;
|
||||
|
||||
// Short delay to allow buttons to properly settle
|
||||
sleep(5);
|
||||
// Short delay to allow buttons to properly settle
|
||||
sleep(5);
|
||||
|
||||
value = digitalRead(PRIMARY_BUTTON_PIN);
|
||||
value = digitalRead(PRIMARY_BUTTON_PIN);
|
||||
|
||||
if (value != sentValue) {
|
||||
// Value has changed from last transmission, send the updated value
|
||||
send(msg.set(value==HIGH));
|
||||
sentValue = value;
|
||||
}
|
||||
if (value != sentValue) {
|
||||
// Value has changed from last transmission, send the updated value
|
||||
send(msg.set(value==HIGH));
|
||||
sentValue = value;
|
||||
}
|
||||
|
||||
value = digitalRead(SECONDARY_BUTTON_PIN);
|
||||
value = digitalRead(SECONDARY_BUTTON_PIN);
|
||||
|
||||
if (value != sentValue2) {
|
||||
// Value has changed from last transmission, send the updated value
|
||||
send(msg2.set(value==HIGH));
|
||||
sentValue2 = value;
|
||||
}
|
||||
if (value != sentValue2) {
|
||||
// Value has changed from last transmission, send the updated value
|
||||
send(msg2.set(value==HIGH));
|
||||
sentValue2 = value;
|
||||
}
|
||||
|
||||
// Sleep until something happens with the sensor
|
||||
sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SECONDARY_BUTTON_PIN-2, CHANGE, 0);
|
||||
// Sleep until something happens with the sensor
|
||||
sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SECONDARY_BUTTON_PIN-2, CHANGE, 0);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
* DESCRIPTION
|
||||
*
|
||||
* MH-Z14 CO2 sensor
|
||||
*
|
||||
*
|
||||
* Wiring:
|
||||
* Pad 1, Pad 5: Vin (Voltage input 4.5V-6V)
|
||||
* Pad 2, Pad 3, Pad 12: GND
|
||||
* Pad 1, Pad 5: Vin (Voltage input 4.5V-6V)
|
||||
* Pad 2, Pad 3, Pad 12: GND
|
||||
* Pad 6: PWM output ==> pin 6
|
||||
*
|
||||
* From: http://davidegironi.blogspot.fr/2014/01/co2-meter-using-ndir-infrared-mh-z14.html
|
||||
@@ -39,13 +39,13 @@
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define CHILD_ID_AIQ 0
|
||||
#define AIQ_SENSOR_ANALOG_PIN 6
|
||||
@@ -58,44 +58,48 @@ float lastAIQ =0.0;
|
||||
MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
|
||||
MyMessage msg2(CHILD_ID_AIQ, V_UNIT_PREFIX);
|
||||
|
||||
void setup()
|
||||
void setup()
|
||||
{
|
||||
pinMode(AIQ_SENSOR_ANALOG_PIN, INPUT);
|
||||
pinMode(AIQ_SENSOR_ANALOG_PIN, INPUT);
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("AIQ Sensor CO2 MH-Z14", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("AIQ Sensor CO2 MH-Z14", "1.0");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_AIQ, S_AIR_QUALITY);
|
||||
send(msg2.set("ppm"));
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_AIQ, S_AIR_QUALITY);
|
||||
send(msg2.set("ppm"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
|
||||
//unsigned long duration = pulseIn(AIQ_SENSOR_ANALOG_PIN, HIGH);
|
||||
while(digitalRead(AIQ_SENSOR_ANALOG_PIN) == HIGH) {;}
|
||||
//wait for the pin to go HIGH and measure HIGH time
|
||||
unsigned long duration = pulseIn(AIQ_SENSOR_ANALOG_PIN, HIGH);
|
||||
|
||||
//Serial.print(duration/1000); Serial.println(" ms ");
|
||||
//from datasheet
|
||||
//unsigned long duration = pulseIn(AIQ_SENSOR_ANALOG_PIN, HIGH);
|
||||
while(digitalRead(AIQ_SENSOR_ANALOG_PIN) == HIGH) {
|
||||
;
|
||||
}
|
||||
//wait for the pin to go HIGH and measure HIGH time
|
||||
unsigned long duration = pulseIn(AIQ_SENSOR_ANALOG_PIN, HIGH);
|
||||
|
||||
//Serial.print(duration/1000); Serial.println(" ms ");
|
||||
//from datasheet
|
||||
//CO2 ppm = 2000 * (Th - 2ms) / (Th + Tl - 4ms)
|
||||
// given Tl + Th = 1004
|
||||
// Tl = 1004 - Th
|
||||
// = 2000 * (Th - 2ms) / (Th + 1004 - Th -4ms)
|
||||
// = 2000 * (Th - 2ms) / 1000 = 2 * (Th - 2ms)
|
||||
long co2ppm = 2 * ((duration/1000) - 2);
|
||||
//Serial.print(co2ppm);
|
||||
if ((co2ppm != lastAIQ)&&(abs(co2ppm-lastAIQ)>=10)) {
|
||||
send(msg.set((long)ceil(co2ppm)));
|
||||
lastAIQ = ceil(co2ppm);
|
||||
}
|
||||
|
||||
//Serial.println();
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
sleep(SLEEP_TIME); //sleep for: sleepTime
|
||||
long co2ppm = 2 * ((duration/1000) - 2);
|
||||
//Serial.print(co2ppm);
|
||||
if ((co2ppm != lastAIQ)&&(abs(co2ppm-lastAIQ)>=10)) {
|
||||
send(msg.set((long)ceil(co2ppm)));
|
||||
lastAIQ = ceil(co2ppm);
|
||||
}
|
||||
|
||||
//Serial.println();
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
sleep(SLEEP_TIME); //sleep for: sleepTime
|
||||
}
|
||||
|
||||
@@ -21,24 +21,24 @@
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This sketch clears radioId, relayId and other routing information in EEPROM back to factory default
|
||||
*
|
||||
*
|
||||
*/
|
||||
// load core modules only
|
||||
#define MY_CORE_ONLY
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(MY_BAUD_RATE);
|
||||
Serial.println("Started clearing. Please wait...");
|
||||
for (int i=0;i<EEPROM_LOCAL_CONFIG_ADDRESS;i++) {
|
||||
hwWriteConfig(i,0xFF);
|
||||
}
|
||||
Serial.println("Clearing done. You're ready to go!");
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(MY_BAUD_RATE);
|
||||
Serial.println("Started clearing. Please wait...");
|
||||
for (int i=0; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) {
|
||||
hwWriteConfig(i,0xFF);
|
||||
}
|
||||
Serial.println("Clearing done. You're ready to go!");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Nothing to do here...
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
// Nothing to do here...
|
||||
}
|
||||
@@ -60,15 +60,16 @@ MyMessage lightMsg(0, V_LIGHT);
|
||||
*/
|
||||
void setup()
|
||||
{
|
||||
// Pull the gateway's current dim level - restore light level upon sendor node power-up
|
||||
request( 0, V_DIMMER );
|
||||
// Pull the gateway's current dim level - restore light level upon sendor node power-up
|
||||
request( 0, V_DIMMER );
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Register the LED Dimmable Light with the gateway
|
||||
present( 0, S_DIMMER );
|
||||
void presentation()
|
||||
{
|
||||
// Register the LED Dimmable Light with the gateway
|
||||
present( 0, S_DIMMER );
|
||||
|
||||
sendSketchInfo(SN, SV);
|
||||
sendSketchInfo(SN, SV);
|
||||
}
|
||||
|
||||
/***
|
||||
@@ -80,46 +81,48 @@ void loop()
|
||||
|
||||
|
||||
|
||||
void receive(const MyMessage &message) {
|
||||
if (message.type == V_LIGHT || message.type == V_DIMMER) {
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
if (message.type == V_LIGHT || message.type == V_DIMMER) {
|
||||
|
||||
// Retrieve the power or dim level from the incoming request message
|
||||
int requestedLevel = atoi( message.data );
|
||||
// Retrieve the power or dim level from the incoming request message
|
||||
int requestedLevel = atoi( message.data );
|
||||
|
||||
// Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
|
||||
requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );
|
||||
// Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
|
||||
requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );
|
||||
|
||||
// Clip incoming level to valid range of 0 to 100
|
||||
requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
|
||||
requestedLevel = requestedLevel < 0 ? 0 : requestedLevel;
|
||||
// Clip incoming level to valid range of 0 to 100
|
||||
requestedLevel = requestedLevel > 100 ? 100 : requestedLevel;
|
||||
requestedLevel = requestedLevel < 0 ? 0 : requestedLevel;
|
||||
|
||||
Serial.print( "Changing level to " );
|
||||
Serial.print( requestedLevel );
|
||||
Serial.print( ", from " );
|
||||
Serial.println( currentLevel );
|
||||
Serial.print( "Changing level to " );
|
||||
Serial.print( requestedLevel );
|
||||
Serial.print( ", from " );
|
||||
Serial.println( currentLevel );
|
||||
|
||||
fadeToLevel( requestedLevel );
|
||||
fadeToLevel( requestedLevel );
|
||||
|
||||
// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
|
||||
send(lightMsg.set(currentLevel > 0));
|
||||
// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
|
||||
send(lightMsg.set(currentLevel > 0));
|
||||
|
||||
// hek comment: Is this really nessesary?
|
||||
send( dimmerMsg.set(currentLevel) );
|
||||
// hek comment: Is this really nessesary?
|
||||
send( dimmerMsg.set(currentLevel) );
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* This method provides a graceful fade up/down effect
|
||||
*/
|
||||
void fadeToLevel( int toLevel ) {
|
||||
void fadeToLevel( int toLevel )
|
||||
{
|
||||
|
||||
int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1;
|
||||
int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1;
|
||||
|
||||
while ( currentLevel != toLevel ) {
|
||||
currentLevel += delta;
|
||||
analogWrite( LED_PIN, (int)(currentLevel / 100. * 255) );
|
||||
delay( FADE_DELAY );
|
||||
}
|
||||
while ( currentLevel != toLevel ) {
|
||||
currentLevel += delta;
|
||||
analogWrite( LED_PIN, (int)(currentLevel / 100. * 255) );
|
||||
delay( FADE_DELAY );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,28 +57,29 @@ MyMessage dimmerMsg(CHILD_ID_LIGHT, V_DIMMER);
|
||||
|
||||
void setup()
|
||||
{
|
||||
//Retreive our last light state from the eprom
|
||||
int LightState=loadState(EPROM_LIGHT_STATE);
|
||||
if (LightState<=1) {
|
||||
LastLightState=LightState;
|
||||
int DimValue=loadState(EPROM_DIMMER_LEVEL);
|
||||
if ((DimValue>0)&&(DimValue<=100)) {
|
||||
//There should be no Dim value of 0, this would mean LIGHT_OFF
|
||||
LastDimValue=DimValue;
|
||||
}
|
||||
}
|
||||
//Retreive our last light state from the eprom
|
||||
int LightState=loadState(EPROM_LIGHT_STATE);
|
||||
if (LightState<=1) {
|
||||
LastLightState=LightState;
|
||||
int DimValue=loadState(EPROM_DIMMER_LEVEL);
|
||||
if ((DimValue>0)&&(DimValue<=100)) {
|
||||
//There should be no Dim value of 0, this would mean LIGHT_OFF
|
||||
LastDimValue=DimValue;
|
||||
}
|
||||
}
|
||||
|
||||
//Here you actualy switch on/off the light with the last known dim level
|
||||
SetCurrentState2Hardware();
|
||||
//Here you actualy switch on/off the light with the last known dim level
|
||||
SetCurrentState2Hardware();
|
||||
|
||||
Serial.println( "Node ready to receive messages..." );
|
||||
Serial.println( "Node ready to receive messages..." );
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the Sketch Version Information to the Gateway
|
||||
sendSketchInfo(SN, SV);
|
||||
void presentation()
|
||||
{
|
||||
// Send the Sketch Version Information to the Gateway
|
||||
sendSketchInfo(SN, SV);
|
||||
|
||||
present(CHILD_ID_LIGHT, S_DIMMER );
|
||||
present(CHILD_ID_LIGHT, S_DIMMER );
|
||||
}
|
||||
|
||||
void loop()
|
||||
@@ -87,74 +88,69 @@ void loop()
|
||||
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
if (message.type == V_LIGHT) {
|
||||
Serial.println( "V_LIGHT command received..." );
|
||||
if (message.type == V_LIGHT) {
|
||||
Serial.println( "V_LIGHT command received..." );
|
||||
|
||||
int lstate= atoi( message.data );
|
||||
if ((lstate<0)||(lstate>1)) {
|
||||
Serial.println( "V_LIGHT data invalid (should be 0/1)" );
|
||||
return;
|
||||
}
|
||||
LastLightState=lstate;
|
||||
saveState(EPROM_LIGHT_STATE, LastLightState);
|
||||
int lstate= atoi( message.data );
|
||||
if ((lstate<0)||(lstate>1)) {
|
||||
Serial.println( "V_LIGHT data invalid (should be 0/1)" );
|
||||
return;
|
||||
}
|
||||
LastLightState=lstate;
|
||||
saveState(EPROM_LIGHT_STATE, LastLightState);
|
||||
|
||||
if ((LastLightState==LIGHT_ON)&&(LastDimValue==0)) {
|
||||
//In the case that the Light State = On, but the dimmer value is zero,
|
||||
//then something (probably the controller) did something wrong,
|
||||
//for the Dim value to 100%
|
||||
LastDimValue=100;
|
||||
saveState(EPROM_DIMMER_LEVEL, LastDimValue);
|
||||
}
|
||||
if ((LastLightState==LIGHT_ON)&&(LastDimValue==0)) {
|
||||
//In the case that the Light State = On, but the dimmer value is zero,
|
||||
//then something (probably the controller) did something wrong,
|
||||
//for the Dim value to 100%
|
||||
LastDimValue=100;
|
||||
saveState(EPROM_DIMMER_LEVEL, LastDimValue);
|
||||
}
|
||||
|
||||
//When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
|
||||
//This means if you previously set the lights dimmer value to 50%, and turn the light ON
|
||||
//it will do so at 50%
|
||||
}
|
||||
else if (message.type == V_DIMMER) {
|
||||
Serial.println( "V_DIMMER command received..." );
|
||||
int dimvalue= atoi( message.data );
|
||||
if ((dimvalue<0)||(dimvalue>100)) {
|
||||
Serial.println( "V_DIMMER data invalid (should be 0..100)" );
|
||||
return;
|
||||
}
|
||||
if (dimvalue==0) {
|
||||
LastLightState=LIGHT_OFF;
|
||||
}
|
||||
else {
|
||||
LastLightState=LIGHT_ON;
|
||||
LastDimValue=dimvalue;
|
||||
saveState(EPROM_DIMMER_LEVEL, LastDimValue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println( "Invalid command received..." );
|
||||
return;
|
||||
}
|
||||
//When receiving a V_LIGHT command we switch the light between OFF and the last received dimmer value
|
||||
//This means if you previously set the lights dimmer value to 50%, and turn the light ON
|
||||
//it will do so at 50%
|
||||
} else if (message.type == V_DIMMER) {
|
||||
Serial.println( "V_DIMMER command received..." );
|
||||
int dimvalue= atoi( message.data );
|
||||
if ((dimvalue<0)||(dimvalue>100)) {
|
||||
Serial.println( "V_DIMMER data invalid (should be 0..100)" );
|
||||
return;
|
||||
}
|
||||
if (dimvalue==0) {
|
||||
LastLightState=LIGHT_OFF;
|
||||
} else {
|
||||
LastLightState=LIGHT_ON;
|
||||
LastDimValue=dimvalue;
|
||||
saveState(EPROM_DIMMER_LEVEL, LastDimValue);
|
||||
}
|
||||
} else {
|
||||
Serial.println( "Invalid command received..." );
|
||||
return;
|
||||
}
|
||||
|
||||
//Here you set the actual light state/level
|
||||
SetCurrentState2Hardware();
|
||||
//Here you set the actual light state/level
|
||||
SetCurrentState2Hardware();
|
||||
}
|
||||
|
||||
void SetCurrentState2Hardware()
|
||||
{
|
||||
if (LastLightState==LIGHT_OFF) {
|
||||
Serial.println( "Light state: OFF" );
|
||||
}
|
||||
else {
|
||||
Serial.print( "Light state: ON, Level: " );
|
||||
Serial.println( LastDimValue );
|
||||
}
|
||||
if (LastLightState==LIGHT_OFF) {
|
||||
Serial.println( "Light state: OFF" );
|
||||
} else {
|
||||
Serial.print( "Light state: ON, Level: " );
|
||||
Serial.println( LastDimValue );
|
||||
}
|
||||
|
||||
//Send current state to the controller
|
||||
SendCurrentState2Controller();
|
||||
//Send current state to the controller
|
||||
SendCurrentState2Controller();
|
||||
}
|
||||
|
||||
void SendCurrentState2Controller()
|
||||
{
|
||||
if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
|
||||
send(dimmerMsg.set((int16_t)0));
|
||||
}
|
||||
else {
|
||||
send(dimmerMsg.set(LastDimValue));
|
||||
}
|
||||
if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
|
||||
send(dimmerMsg.set((int16_t)0));
|
||||
} else {
|
||||
send(dimmerMsg.set(LastDimValue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,21 +21,21 @@
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - epierre
|
||||
* Converted to 1.4 by Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Arduino Dust Sensort
|
||||
*
|
||||
* connect the sensor as follows :
|
||||
*
|
||||
*
|
||||
* VCC >>> 5V
|
||||
* A >>> A0
|
||||
* GND >>> GND
|
||||
*
|
||||
* Based on: http://www.dfrobot.com/wiki/index.php/Sharp_GP2Y1010AU
|
||||
* Based on: http://www.dfrobot.com/wiki/index.php/Sharp_GP2Y1010AU
|
||||
* Authors: Cyrille Médard de Chardon (serialC), Christophe Trefois (Trefex)
|
||||
*
|
||||
*
|
||||
* http://www.mysensors.org/build/dust
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
// Enable debug prints
|
||||
@@ -45,7 +45,7 @@
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define CHILD_ID_DUST 0
|
||||
#define DUST_SENSOR_ANALOG_PIN 1
|
||||
@@ -64,38 +64,40 @@ float dustDensity = 0;
|
||||
|
||||
MyMessage dustMsg(CHILD_ID_DUST, V_LEVEL);
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Dust Sensor", "1.1");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Dust Sensor", "1.1");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_DUST, S_DUST);
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_DUST, S_DUST);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
uint16_t voMeasured = analogRead(DUST_SENSOR_ANALOG_PIN);// Get DUST value
|
||||
void loop()
|
||||
{
|
||||
uint16_t voMeasured = analogRead(DUST_SENSOR_ANALOG_PIN);// Get DUST value
|
||||
|
||||
// 0 - 5V mapped to 0 - 1023 integer values
|
||||
// recover voltage
|
||||
calcVoltage = voMeasured * (5.0 / 1024.0);
|
||||
// 0 - 5V mapped to 0 - 1023 integer values
|
||||
// recover voltage
|
||||
calcVoltage = voMeasured * (5.0 / 1024.0);
|
||||
|
||||
// linear eqaution taken from http://www.howmuchsnow.com/arduino/airquality/
|
||||
// Chris Nafis (c) 2012
|
||||
dustDensity = (0.17 * calcVoltage - 0.1)*1000;
|
||||
|
||||
Serial.print("Raw Signal Value (0-1023): ");
|
||||
Serial.print(voMeasured);
|
||||
|
||||
Serial.print(" - Voltage: ");
|
||||
Serial.print(calcVoltage);
|
||||
|
||||
Serial.print(" - Dust Density: ");
|
||||
Serial.println(dustDensity); // unit: ug/m3
|
||||
|
||||
if (ceil(dustDensity) != lastDUST) {
|
||||
send(dustMsg.set((int16_t)ceil(dustDensity)));
|
||||
lastDUST = ceil(dustDensity);
|
||||
}
|
||||
|
||||
sleep(SLEEP_TIME);
|
||||
// linear eqaution taken from http://www.howmuchsnow.com/arduino/airquality/
|
||||
// Chris Nafis (c) 2012
|
||||
dustDensity = (0.17 * calcVoltage - 0.1)*1000;
|
||||
|
||||
Serial.print("Raw Signal Value (0-1023): ");
|
||||
Serial.print(voMeasured);
|
||||
|
||||
Serial.print(" - Voltage: ");
|
||||
Serial.print(calcVoltage);
|
||||
|
||||
Serial.print(" - Dust Density: ");
|
||||
Serial.println(dustDensity); // unit: ug/m3
|
||||
|
||||
if (ceil(dustDensity) != lastDUST) {
|
||||
send(dustMsg.set((int16_t)ceil(dustDensity)));
|
||||
lastDUST = ceil(dustDensity);
|
||||
}
|
||||
|
||||
sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
*
|
||||
* Dust Sensor for SamYoung DSM501
|
||||
* connect the sensor as follows :
|
||||
* Pin 2 of dust sensor PM1 -> Digital 3 (PMW)
|
||||
* Pin 3 of dust sensor -> +5V
|
||||
* Pin 4 of dust sensor PM2.5 -> Digital 6 (PWM)
|
||||
* Pin 3 of dust sensor -> +5V
|
||||
* Pin 4 of dust sensor PM2.5 -> Digital 6 (PWM)
|
||||
* Pin 5 of dust sensor -> Ground
|
||||
* Datasheet: http://www.samyoungsnc.com/products/3-1%20Specification%20DSM501.pdf
|
||||
* Contributor: epierre
|
||||
@@ -37,7 +37,7 @@
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define CHILD_ID_DUST_PM10 0
|
||||
#define CHILD_ID_DUST_PM25 1
|
||||
@@ -65,84 +65,85 @@ MyMessage msgPM10(CHILD_ID_DUST_PM10, V_UNIT_PREFIX);
|
||||
MyMessage dustMsgPM25(CHILD_ID_DUST_PM25, V_LEVEL);
|
||||
MyMessage msgPM25(CHILD_ID_DUST_PM25, V_UNIT_PREFIX);
|
||||
|
||||
void setup()
|
||||
void setup()
|
||||
{
|
||||
pinMode(DUST_SENSOR_DIGITAL_PIN_PM10,INPUT);
|
||||
pinMode(DUST_SENSOR_DIGITAL_PIN_PM25,INPUT);
|
||||
pinMode(DUST_SENSOR_DIGITAL_PIN_PM10,INPUT);
|
||||
pinMode(DUST_SENSOR_DIGITAL_PIN_PM25,INPUT);
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Dust Sensor DSM501", "1.4");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Dust Sensor DSM501", "1.4");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_DUST_PM10, S_DUST);
|
||||
send(msgPM10.set("ppm"));
|
||||
present(CHILD_ID_DUST_PM25, S_DUST);
|
||||
send(msgPM25.set("ppm"));
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_DUST_PM10, S_DUST);
|
||||
send(msgPM10.set("ppm"));
|
||||
present(CHILD_ID_DUST_PM25, S_DUST);
|
||||
send(msgPM25.set("ppm"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
void loop()
|
||||
{
|
||||
|
||||
//get PM 2.5 density of particles over 2.5 μm.
|
||||
concentrationPM25=(long)getPM(DUST_SENSOR_DIGITAL_PIN_PM25);
|
||||
Serial.print("PM25: ");
|
||||
Serial.println(concentrationPM25);
|
||||
Serial.print("\n");
|
||||
//get PM 2.5 density of particles over 2.5 μm.
|
||||
concentrationPM25=(long)getPM(DUST_SENSOR_DIGITAL_PIN_PM25);
|
||||
Serial.print("PM25: ");
|
||||
Serial.println(concentrationPM25);
|
||||
Serial.print("\n");
|
||||
|
||||
if ((concentrationPM25 != lastDUSTPM25)&&(concentrationPM25>0)) {
|
||||
send(dustMsgPM25.set((long)ceil(concentrationPM25)));
|
||||
lastDUSTPM25 = ceil(concentrationPM25);
|
||||
}
|
||||
|
||||
//get PM 1.0 - density of particles over 1 μm.
|
||||
concentrationPM10=getPM(DUST_SENSOR_DIGITAL_PIN_PM10);
|
||||
Serial.print("PM10: ");
|
||||
Serial.println(concentrationPM10);
|
||||
Serial.print("\n");
|
||||
//ppmv=mg/m3 * (0.08205*Tmp)/Molecular_mass
|
||||
//0.08205 = Universal gas constant in atm·m3/(kmol·K)
|
||||
int temp=20; //external temperature, if you can replace this with a DHT11 or better
|
||||
long ppmv=(concentrationPM10*0.0283168/100/1000) * (0.08205*temp)/0.01;
|
||||
|
||||
if ((ceil(concentrationPM10) != lastDUSTPM10)&&((long)concentrationPM10>0)) {
|
||||
send(dustMsgPM10.set((long)ppmv));
|
||||
lastDUSTPM10 = ceil(concentrationPM10);
|
||||
}
|
||||
|
||||
//sleep to save on radio
|
||||
sleep(SLEEP_TIME);
|
||||
|
||||
if ((concentrationPM25 != lastDUSTPM25)&&(concentrationPM25>0)) {
|
||||
send(dustMsgPM25.set((long)ceil(concentrationPM25)));
|
||||
lastDUSTPM25 = ceil(concentrationPM25);
|
||||
}
|
||||
|
||||
//get PM 1.0 - density of particles over 1 μm.
|
||||
concentrationPM10=getPM(DUST_SENSOR_DIGITAL_PIN_PM10);
|
||||
Serial.print("PM10: ");
|
||||
Serial.println(concentrationPM10);
|
||||
Serial.print("\n");
|
||||
//ppmv=mg/m3 * (0.08205*Tmp)/Molecular_mass
|
||||
//0.08205 = Universal gas constant in atm·m3/(kmol·K)
|
||||
int temp=20; //external temperature, if you can replace this with a DHT11 or better
|
||||
long ppmv=(concentrationPM10*0.0283168/100/1000) * (0.08205*temp)/0.01;
|
||||
|
||||
if ((ceil(concentrationPM10) != lastDUSTPM10)&&((long)concentrationPM10>0)) {
|
||||
send(dustMsgPM10.set((long)ppmv));
|
||||
lastDUSTPM10 = ceil(concentrationPM10);
|
||||
}
|
||||
|
||||
//sleep to save on radio
|
||||
sleep(SLEEP_TIME);
|
||||
|
||||
}
|
||||
|
||||
|
||||
long getPM(int DUST_SENSOR_DIGITAL_PIN) {
|
||||
long getPM(int DUST_SENSOR_DIGITAL_PIN)
|
||||
{
|
||||
|
||||
starttime = millis();
|
||||
starttime = millis();
|
||||
|
||||
while (1) {
|
||||
|
||||
duration = pulseIn(DUST_SENSOR_DIGITAL_PIN, LOW);
|
||||
lowpulseoccupancy += duration;
|
||||
endtime = millis();
|
||||
|
||||
if ((endtime-starttime) > sampletime_ms)
|
||||
{
|
||||
ratio = (lowpulseoccupancy-endtime+starttime)/(sampletime_ms*10.0); // Integer percentage 0=>100
|
||||
long concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
|
||||
//Serial.print("lowpulseoccupancy:");
|
||||
//Serial.print(lowpulseoccupancy);
|
||||
//Serial.print("\n");
|
||||
//Serial.print("ratio:");
|
||||
//Serial.print(ratio);
|
||||
//Serial.print("\n");
|
||||
//Serial.print("DSM501A:");
|
||||
//Serial.println(concentration);
|
||||
//Serial.print("\n");
|
||||
|
||||
lowpulseoccupancy = 0;
|
||||
return(concentration);
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
|
||||
duration = pulseIn(DUST_SENSOR_DIGITAL_PIN, LOW);
|
||||
lowpulseoccupancy += duration;
|
||||
endtime = millis();
|
||||
|
||||
if ((endtime-starttime) > sampletime_ms) {
|
||||
ratio = (lowpulseoccupancy-endtime+starttime)/(sampletime_ms*10.0); // Integer percentage 0=>100
|
||||
long concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
|
||||
//Serial.print("lowpulseoccupancy:");
|
||||
//Serial.print(lowpulseoccupancy);
|
||||
//Serial.print("\n");
|
||||
//Serial.print("ratio:");
|
||||
//Serial.print(ratio);
|
||||
//Serial.print("\n");
|
||||
//Serial.print("DSM501A:");
|
||||
//Serial.println(concentration);
|
||||
//Serial.print("\n");
|
||||
|
||||
lowpulseoccupancy = 0;
|
||||
return(concentration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,16 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik EKblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This sketch provides an example how to implement a distance sensor using HC-SR04
|
||||
* This sketch provides an example how to implement a distance sensor using HC-SR04
|
||||
* Use this sensor to measure KWH and Watt of your house meeter
|
||||
* You need to set the correct pulsefactor of your meeter (blinks per KWH).
|
||||
* The sensor starts by fetching current KWH value from gateway.
|
||||
* Reports both KWH and Watt back to gateway.
|
||||
*
|
||||
* Unfortunately millis() won't increment when the Arduino is in
|
||||
* sleepmode. So we cannot make this sensor sleep if we also want
|
||||
* Unfortunately millis() won't increment when the Arduino is in
|
||||
* sleepmode. So we cannot make this sensor sleep if we also want
|
||||
* to calculate/report watt-number.
|
||||
* http://www.mysensors.org/build/pulse_power
|
||||
*/
|
||||
@@ -41,7 +41,7 @@
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your light sensor. (Only 2 and 3 generates interrupt!)
|
||||
#define PULSE_FACTOR 1000 // Nummber of blinks per KWH of your meeter
|
||||
@@ -49,13 +49,14 @@
|
||||
#define MAX_WATT 10000 // Max watt value to report. This filetrs outliers.
|
||||
#define CHILD_ID 1 // Id of the sensor child
|
||||
|
||||
unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
|
||||
unsigned long SEND_FREQUENCY =
|
||||
20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway.
|
||||
double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour
|
||||
bool pcReceived = false;
|
||||
volatile unsigned long pulseCount = 0;
|
||||
volatile unsigned long pulseCount = 0;
|
||||
volatile unsigned long lastBlink = 0;
|
||||
volatile unsigned long watt = 0;
|
||||
unsigned long oldPulseCount = 0;
|
||||
unsigned long oldPulseCount = 0;
|
||||
unsigned long oldWatt = 0;
|
||||
double oldKwh;
|
||||
unsigned long lastSend;
|
||||
@@ -64,88 +65,90 @@ MyMessage kwhMsg(CHILD_ID,V_KWH);
|
||||
MyMessage pcMsg(CHILD_ID,V_VAR1);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Fetch last known pulse count value from gw
|
||||
request(CHILD_ID, V_VAR1);
|
||||
void setup()
|
||||
{
|
||||
// Fetch last known pulse count value from gw
|
||||
request(CHILD_ID, V_VAR1);
|
||||
|
||||
// Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
|
||||
// If no pullup is used, the reported usage will be too high because of the floating pin
|
||||
pinMode(DIGITAL_INPUT_SENSOR,INPUT_PULLUP);
|
||||
// Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output
|
||||
// If no pullup is used, the reported usage will be too high because of the floating pin
|
||||
pinMode(DIGITAL_INPUT_SENSOR,INPUT_PULLUP);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, RISING);
|
||||
lastSend=millis();
|
||||
attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, RISING);
|
||||
lastSend=millis();
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Energy Meter", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Energy Meter", "1.0");
|
||||
|
||||
// Register this device as power sensor
|
||||
present(CHILD_ID, S_POWER);
|
||||
// Register this device as power sensor
|
||||
present(CHILD_ID, S_POWER);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long now = millis();
|
||||
// Only send values at a maximum frequency or woken up from sleep
|
||||
bool sendTime = now - lastSend > SEND_FREQUENCY;
|
||||
if (pcReceived && (SLEEP_MODE || sendTime)) {
|
||||
// New watt value has been calculated
|
||||
if (!SLEEP_MODE && watt != oldWatt) {
|
||||
// Check that we dont get unresonable large watt value.
|
||||
// could hapen when long wraps or false interrupt triggered
|
||||
if (watt<((unsigned long)MAX_WATT)) {
|
||||
send(wattMsg.set(watt)); // Send watt value to gw
|
||||
}
|
||||
Serial.print("Watt:");
|
||||
Serial.println(watt);
|
||||
oldWatt = watt;
|
||||
}
|
||||
|
||||
// Pulse cout has changed
|
||||
if (pulseCount != oldPulseCount) {
|
||||
send(pcMsg.set(pulseCount)); // Send pulse count value to gw
|
||||
double kwh = ((double)pulseCount/((double)PULSE_FACTOR));
|
||||
oldPulseCount = pulseCount;
|
||||
if (kwh != oldKwh) {
|
||||
send(kwhMsg.set(kwh, 4)); // Send kwh value to gw
|
||||
oldKwh = kwh;
|
||||
}
|
||||
}
|
||||
lastSend = now;
|
||||
} else if (sendTime && !pcReceived) {
|
||||
// No count received. Try requesting it again
|
||||
request(CHILD_ID, V_VAR1);
|
||||
lastSend=now;
|
||||
}
|
||||
|
||||
if (SLEEP_MODE) {
|
||||
sleep(SEND_FREQUENCY);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
unsigned long now = millis();
|
||||
// Only send values at a maximum frequency or woken up from sleep
|
||||
bool sendTime = now - lastSend > SEND_FREQUENCY;
|
||||
if (pcReceived && (SLEEP_MODE || sendTime)) {
|
||||
// New watt value has been calculated
|
||||
if (!SLEEP_MODE && watt != oldWatt) {
|
||||
// Check that we dont get unresonable large watt value.
|
||||
// could hapen when long wraps or false interrupt triggered
|
||||
if (watt<((unsigned long)MAX_WATT)) {
|
||||
send(wattMsg.set(watt)); // Send watt value to gw
|
||||
}
|
||||
Serial.print("Watt:");
|
||||
Serial.println(watt);
|
||||
oldWatt = watt;
|
||||
}
|
||||
|
||||
// Pulse cout has changed
|
||||
if (pulseCount != oldPulseCount) {
|
||||
send(pcMsg.set(pulseCount)); // Send pulse count value to gw
|
||||
double kwh = ((double)pulseCount/((double)PULSE_FACTOR));
|
||||
oldPulseCount = pulseCount;
|
||||
if (kwh != oldKwh) {
|
||||
send(kwhMsg.set(kwh, 4)); // Send kwh value to gw
|
||||
oldKwh = kwh;
|
||||
}
|
||||
}
|
||||
lastSend = now;
|
||||
} else if (sendTime && !pcReceived) {
|
||||
// No count received. Try requesting it again
|
||||
request(CHILD_ID, V_VAR1);
|
||||
lastSend=now;
|
||||
}
|
||||
|
||||
if (SLEEP_MODE) {
|
||||
sleep(SEND_FREQUENCY);
|
||||
}
|
||||
}
|
||||
|
||||
void receive(const MyMessage &message) {
|
||||
if (message.type==V_VAR1) {
|
||||
pulseCount = oldPulseCount = message.getLong();
|
||||
Serial.print("Received last pulse count from gw:");
|
||||
Serial.println(pulseCount);
|
||||
pcReceived = true;
|
||||
}
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
if (message.type==V_VAR1) {
|
||||
pulseCount = oldPulseCount = message.getLong();
|
||||
Serial.print("Received last pulse count from gw:");
|
||||
Serial.println(pulseCount);
|
||||
pcReceived = true;
|
||||
}
|
||||
}
|
||||
|
||||
void onPulse()
|
||||
{
|
||||
if (!SLEEP_MODE) {
|
||||
unsigned long newBlink = micros();
|
||||
unsigned long interval = newBlink-lastBlink;
|
||||
if (interval<10000L) { // Sometimes we get interrupt on RISING
|
||||
return;
|
||||
}
|
||||
watt = (3600000000.0 /interval) / ppwh;
|
||||
lastBlink = newBlink;
|
||||
}
|
||||
pulseCount++;
|
||||
void onPulse()
|
||||
{
|
||||
if (!SLEEP_MODE) {
|
||||
unsigned long newBlink = micros();
|
||||
unsigned long interval = newBlink-lastBlink;
|
||||
if (interval<10000L) { // Sometimes we get interrupt on RISING
|
||||
return;
|
||||
}
|
||||
watt = (3600000000.0 /interval) / ppwh;
|
||||
lastBlink = newBlink;
|
||||
}
|
||||
pulseCount++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -126,21 +126,24 @@
|
||||
#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
|
||||
|
||||
#if defined(MY_USE_UDP)
|
||||
#include <WiFiUdp.h>
|
||||
#include <WiFiUdp.h>
|
||||
#endif
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors here
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors here
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
// Send locally attached sensors data here
|
||||
void loop()
|
||||
{
|
||||
// Send locally attached sensors data here
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
// The MQTT broker port to to open
|
||||
#define MY_PORT 1883
|
||||
|
||||
/*
|
||||
/*
|
||||
// Enable inclusion mode
|
||||
#define MY_INCLUSION_MODE_FEATURE
|
||||
// Enable Inclusion mode button on gateway
|
||||
@@ -126,14 +126,17 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors here
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors here
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
// Send locally attech sensors data here
|
||||
void loop()
|
||||
{
|
||||
// Send locally attech sensors data here
|
||||
}
|
||||
|
||||
@@ -128,45 +128,54 @@
|
||||
#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
|
||||
|
||||
#if defined(MY_USE_UDP)
|
||||
#include <WiFiUDP.h>
|
||||
#include <WiFiUDP.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#endif
|
||||
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
|
||||
ArduinoOTA.onStart([]() {
|
||||
Serial.println("ArduinoOTA start");
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nArduinoOTA end");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
|
||||
else if (error == OTA_END_ERROR) Serial.println("End Failed");
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
Serial.println("Ready");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
ArduinoOTA.onStart([]() {
|
||||
Serial.println("ArduinoOTA start");
|
||||
});
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Serial.println("\nArduinoOTA end");
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) {
|
||||
Serial.println("Auth Failed");
|
||||
} else if (error == OTA_BEGIN_ERROR) {
|
||||
Serial.println("Begin Failed");
|
||||
} else if (error == OTA_CONNECT_ERROR) {
|
||||
Serial.println("Connect Failed");
|
||||
} else if (error == OTA_RECEIVE_ERROR) {
|
||||
Serial.println("Receive Failed");
|
||||
} else if (error == OTA_END_ERROR) {
|
||||
Serial.println("End Failed");
|
||||
}
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
Serial.println("Ready");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors here
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors here
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
// Send locally attech sensors data here
|
||||
ArduinoOTA.handle();
|
||||
void loop()
|
||||
{
|
||||
// Send locally attech sensors data here
|
||||
ArduinoOTA.handle();
|
||||
}
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2015 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The ArduinoGateway prints data received from sensors on the serial link.
|
||||
* The gateway accepts input on seral which will be sent out on radio network.
|
||||
*
|
||||
* The GW code is designed for Arduino Nano 328p / 16MHz
|
||||
*
|
||||
* Wire connections (OPTIONAL):
|
||||
* - Inclusion button should be connected between digital pin 3 and GND
|
||||
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
|
||||
*
|
||||
* LEDs (OPTIONAL):
|
||||
* - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs
|
||||
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||
* - ERR (red) - fast blink on error during transmission error or recieve crc error
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2015 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The ArduinoGateway prints data received from sensors on the serial link.
|
||||
* The gateway accepts input on seral which will be sent out on radio network.
|
||||
*
|
||||
* The GW code is designed for Arduino Nano 328p / 16MHz
|
||||
*
|
||||
* Wire connections (OPTIONAL):
|
||||
* - Inclusion button should be connected between digital pin 3 and GND
|
||||
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
|
||||
*
|
||||
* LEDs (OPTIONAL):
|
||||
* - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs
|
||||
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||
* - ERR (red) - fast blink on error during transmission error or recieve crc error
|
||||
*
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
@@ -83,14 +83,17 @@
|
||||
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
// Setup locally attached sensors
|
||||
void setup()
|
||||
{
|
||||
// Setup locally attached sensors
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Send locally attached sensor data here
|
||||
void loop()
|
||||
{
|
||||
// Send locally attached sensor data here
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2015 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The RS485 Gateway prints data received from sensors on the serial link.
|
||||
* The gateway accepts input on seral which will be sent out on
|
||||
* the RS485 link.
|
||||
*
|
||||
* Wire connections (OPTIONAL):
|
||||
* - Inclusion button should be connected between digital pin 3 and GND
|
||||
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
|
||||
*
|
||||
* LEDs (OPTIONAL):
|
||||
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||
* - ERR (red) - fast blink on error during transmission error or recieve crc error
|
||||
*
|
||||
* If your Arduino board has additional serial ports
|
||||
* you can use to connect the RS485 module.
|
||||
* Otherwise, the gateway uses AltSoftSerial to handle two serial
|
||||
* links on one Arduino. Use the following pins for RS485 link
|
||||
*
|
||||
* Board Transmit Receive PWM Unusable
|
||||
* ----- -------- ------- ------------
|
||||
* Teensy 3.0 & 3.1 21 20 22
|
||||
* Teensy 2.0 9 10 (none)
|
||||
* Teensy++ 2.0 25 4 26, 27
|
||||
* Arduino Uno 9 8 10
|
||||
* Arduino Leonardo 5 13 (none)
|
||||
* Arduino Mega 46 48 44, 45
|
||||
* Wiring-S 5 6 4
|
||||
* Sanguino 13 14 12
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2015 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The RS485 Gateway prints data received from sensors on the serial link.
|
||||
* The gateway accepts input on seral which will be sent out on
|
||||
* the RS485 link.
|
||||
*
|
||||
* Wire connections (OPTIONAL):
|
||||
* - Inclusion button should be connected between digital pin 3 and GND
|
||||
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
|
||||
*
|
||||
* LEDs (OPTIONAL):
|
||||
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||
* - ERR (red) - fast blink on error during transmission error or recieve crc error
|
||||
*
|
||||
* If your Arduino board has additional serial ports
|
||||
* you can use to connect the RS485 module.
|
||||
* Otherwise, the gateway uses AltSoftSerial to handle two serial
|
||||
* links on one Arduino. Use the following pins for RS485 link
|
||||
*
|
||||
* Board Transmit Receive PWM Unusable
|
||||
* ----- -------- ------- ------------
|
||||
* Teensy 3.0 & 3.1 21 20 22
|
||||
* Teensy 2.0 9 10 (none)
|
||||
* Teensy++ 2.0 25 4 26, 27
|
||||
* Arduino Uno 9 8 10
|
||||
* Arduino Leonardo 5 13 (none)
|
||||
* Arduino Mega 46 48 44, 45
|
||||
* Wiring-S 5 6 4
|
||||
* Sanguino 13 14 12
|
||||
*
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
@@ -88,14 +88,17 @@
|
||||
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
// Setup locally attached sensors
|
||||
void setup()
|
||||
{
|
||||
// Setup locally attached sensors
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Send locally attached sensor data here
|
||||
void loop()
|
||||
{
|
||||
// Send locally attached sensor data here
|
||||
}
|
||||
|
||||
@@ -58,18 +58,18 @@
|
||||
// The W5100 ethernet module seems to have a hard time co-operate with
|
||||
// radio on the same spi bus.
|
||||
#if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD)
|
||||
#define MY_SOFTSPI
|
||||
#define MY_SOFT_SPI_SCK_PIN 14
|
||||
#define MY_SOFT_SPI_MISO_PIN 16
|
||||
#define MY_SOFT_SPI_MOSI_PIN 15
|
||||
#define MY_SOFTSPI
|
||||
#define MY_SOFT_SPI_SCK_PIN 14
|
||||
#define MY_SOFT_SPI_MISO_PIN 16
|
||||
#define MY_SOFT_SPI_MOSI_PIN 15
|
||||
#endif
|
||||
|
||||
// When W5100 is connected we have to move CE/CSN pins for NRF radio
|
||||
#ifndef MY_RF24_CE_PIN
|
||||
#define MY_RF24_CE_PIN 5
|
||||
#define MY_RF24_CE_PIN 5
|
||||
#endif
|
||||
#ifndef MY_RF24_CS_PIN
|
||||
#define MY_RF24_CS_PIN 6
|
||||
#define MY_RF24_CS_PIN 6
|
||||
#endif
|
||||
|
||||
// Enable to UDP
|
||||
@@ -110,7 +110,7 @@
|
||||
|
||||
|
||||
#if defined(MY_USE_UDP)
|
||||
#include <EthernetUdp.h>
|
||||
#include <EthernetUdp.h>
|
||||
#endif
|
||||
#include <Ethernet.h>
|
||||
#include <MySensors.h>
|
||||
@@ -120,5 +120,6 @@ void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -81,18 +81,18 @@
|
||||
// The W5100 ethernet module seems to have a hard time co-operate with
|
||||
// radio on the same spi bus.
|
||||
#if !defined(MY_W5100_SPI_EN) && !defined(ARDUINO_ARCH_SAMD)
|
||||
#define MY_SOFTSPI
|
||||
#define MY_SOFT_SPI_SCK_PIN 14
|
||||
#define MY_SOFT_SPI_MISO_PIN 16
|
||||
#define MY_SOFT_SPI_MOSI_PIN 15
|
||||
#define MY_SOFTSPI
|
||||
#define MY_SOFT_SPI_SCK_PIN 14
|
||||
#define MY_SOFT_SPI_MISO_PIN 16
|
||||
#define MY_SOFT_SPI_MOSI_PIN 15
|
||||
#endif
|
||||
|
||||
// When W5100 is connected we have to move CE/CSN pins for NRF radio
|
||||
#ifndef MY_RF24_CE_PIN
|
||||
#define MY_RF24_CE_PIN 5
|
||||
#define MY_RF24_CE_PIN 5
|
||||
#endif
|
||||
#ifndef MY_RF24_CS_PIN
|
||||
#define MY_RF24_CS_PIN 6
|
||||
#define MY_RF24_CS_PIN 6
|
||||
#endif
|
||||
|
||||
// Enable these if your MQTT broker requires usenrame/password
|
||||
@@ -113,7 +113,7 @@
|
||||
// The MQTT broker port to to open
|
||||
#define MY_PORT 1883
|
||||
|
||||
/*
|
||||
/*
|
||||
// Enable inclusion mode
|
||||
#define MY_INCLUSION_MODE_FEATURE
|
||||
// Enable Inclusion mode button on gateway
|
||||
@@ -136,14 +136,17 @@
|
||||
#include <Ethernet.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors here
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors here
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
// Send locally attached sensors data here
|
||||
void loop()
|
||||
{
|
||||
// Send locally attached sensors data here
|
||||
}
|
||||
|
||||
@@ -20,20 +20,20 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik EKblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Example sketch showing how to measue light level using a LM393 photo-resistor
|
||||
* Example sketch showing how to measue light level using a LM393 photo-resistor
|
||||
* http://www.mysensors.org/build/light
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define CHILD_ID_LIGHT 0
|
||||
#define LIGHT_SENSOR_ANALOG_PIN 0
|
||||
@@ -44,23 +44,24 @@ MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
|
||||
int lastLightLevel;
|
||||
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Light Sensor", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Light Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
|
||||
Serial.println(lightLevel);
|
||||
if (lightLevel != lastLightLevel) {
|
||||
send(msg.set(lightLevel));
|
||||
lastLightLevel = lightLevel;
|
||||
}
|
||||
sleep(SLEEP_TIME);
|
||||
void loop()
|
||||
{
|
||||
int16_t lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
|
||||
Serial.println(lightLevel);
|
||||
if (lightLevel != lastLightLevel) {
|
||||
send(msg.set(lightLevel));
|
||||
lastLightLevel = lightLevel;
|
||||
}
|
||||
sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,9 +20,9 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Motion Sensor example using HC-SR501
|
||||
* Motion Sensor example using HC-SR501
|
||||
* http://www.mysensors.org/build/motion
|
||||
*
|
||||
*/
|
||||
@@ -43,29 +43,30 @@ unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in millisecond
|
||||
// Initialize motion message
|
||||
MyMessage msg(CHILD_ID, V_TRIPPED);
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||
void setup()
|
||||
{
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Motion Sensor", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Motion Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
present(CHILD_ID, S_MOTION);
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
present(CHILD_ID, S_MOTION);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Read digital motion value
|
||||
bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
||||
|
||||
Serial.println(tripped);
|
||||
send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||
void loop()
|
||||
{
|
||||
// Read digital motion value
|
||||
bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
||||
|
||||
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
|
||||
sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
|
||||
Serial.println(tripped);
|
||||
send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||
|
||||
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
|
||||
sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,18 +20,18 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This is an example of sensors using RS485 as transport layer
|
||||
*
|
||||
* Motion Sensor example using HC-SR501
|
||||
*
|
||||
* Motion Sensor example using HC-SR501
|
||||
* http://www.mysensors.org/build/motion
|
||||
*
|
||||
*
|
||||
* If your Arduino board has additional serial ports
|
||||
* you can use to connect the RS485 module.
|
||||
* Otherwise, the transport uses AltSoftSerial to handle two serial
|
||||
* links on one Arduino. Use the following pins for RS485 link
|
||||
*
|
||||
*
|
||||
* Board Transmit Receive PWM Unusable
|
||||
* ----- -------- ------- ------------
|
||||
* Teensy 3.0 & 3.1 21 20 22
|
||||
@@ -41,8 +41,8 @@
|
||||
* Arduino Leonardo 5 13 (none)
|
||||
* Arduino Mega 46 48 44, 45
|
||||
* Wiring-S 5 6 4
|
||||
* Sanguino 13 14 12 *
|
||||
*
|
||||
* Sanguino 13 14 12 *
|
||||
*
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
@@ -51,7 +51,7 @@
|
||||
// Enable RS485 transport layer
|
||||
#define MY_RS485
|
||||
|
||||
// Define this to enables DE-pin management on defined pin
|
||||
// Define this to enables DE-pin management on defined pin
|
||||
#define MY_RS485_DE_PIN 2
|
||||
|
||||
// Set RS485 baud rate to use
|
||||
@@ -69,29 +69,30 @@ unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in millisecond
|
||||
// Initialize motion message
|
||||
MyMessage msg(CHILD_ID, V_TRIPPED);
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||
void setup()
|
||||
{
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Motion Sensor", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Motion Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
present(CHILD_ID, S_MOTION);
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
present(CHILD_ID, S_MOTION);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Read digital motion value
|
||||
bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
||||
|
||||
Serial.println(tripped);
|
||||
send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||
void loop()
|
||||
{
|
||||
// Read digital motion value
|
||||
bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
||||
|
||||
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
|
||||
sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
|
||||
Serial.println(tripped);
|
||||
send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||
|
||||
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
|
||||
sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,37 +42,39 @@ MyMessage msg(0, V_PH);
|
||||
|
||||
void setup()
|
||||
{
|
||||
//Setup your PH sensor here (I2C,Serial,Phidget...)
|
||||
//Setup your PH sensor here (I2C,Serial,Phidget...)
|
||||
}
|
||||
|
||||
float getPH() {
|
||||
//query your PH sensor here (I2C,Serial,Phidget...)
|
||||
float dummy = 7;
|
||||
return dummy;
|
||||
float getPH()
|
||||
{
|
||||
//query your PH sensor here (I2C,Serial,Phidget...)
|
||||
float dummy = 7;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("PH Sensor", "1.1");
|
||||
present(0, S_WATER_QUALITY);
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("PH Sensor", "1.1");
|
||||
present(0, S_WATER_QUALITY);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
float ph = getPH();
|
||||
float ph = getPH();
|
||||
|
||||
#if COMPARE_PH == 1
|
||||
if (lastPH != ph) {
|
||||
if (lastPH != ph) {
|
||||
#endif
|
||||
|
||||
// Send in the new PH value
|
||||
send(msg.set(ph, 1));
|
||||
// Save new PH value for next compare
|
||||
lastPH = ph;
|
||||
// Send in the new PH value
|
||||
send(msg.set(ph, 1));
|
||||
// Save new PH value for next compare
|
||||
lastPH = ph;
|
||||
|
||||
#if COMPARE_PH == 1
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sleep(SLEEP_TIME);
|
||||
sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
@@ -13,32 +13,34 @@
|
||||
#define LOGDEBUG 1
|
||||
|
||||
#if defined ( LOGDEBUG )
|
||||
#define LOG(fmt, args... ) log( fmt, ## args );
|
||||
#define LOG(fmt, args... ) log( fmt, ## args );
|
||||
#else
|
||||
#define log(fmt, args... )
|
||||
#define log(fmt, args... )
|
||||
#endif
|
||||
|
||||
void log(const char *fmt, ... ) {
|
||||
char buff[128];
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
vsnprintf(buff, sizeof(buff), fmt, args);
|
||||
va_end (args);
|
||||
buff[sizeof(buff)/sizeof(buff[0])-1]='\0';
|
||||
Serial.print(buff);
|
||||
void log(const char *fmt, ... )
|
||||
{
|
||||
char buff[128];
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
vsnprintf(buff, sizeof(buff), fmt, args);
|
||||
va_end (args);
|
||||
buff[sizeof(buff)/sizeof(buff[0])-1]='\0';
|
||||
Serial.print(buff);
|
||||
}
|
||||
|
||||
void log(const __FlashStringHelper *fmt, ... ){
|
||||
char buf[128]; // resulting string limited to 128 chars
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
void log(const __FlashStringHelper *fmt, ... )
|
||||
{
|
||||
char buf[128]; // resulting string limited to 128 chars
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
#ifdef __AVR__
|
||||
vsnprintf_P(buf, sizeof(buf), (const char *)fmt, args); // progmem for AVR
|
||||
vsnprintf_P(buf, sizeof(buf), (const char *)fmt, args); // progmem for AVR
|
||||
#else
|
||||
vsnprintf(buf, sizeof(buf), (const char *)fmt, args); // for the rest of the world
|
||||
vsnprintf(buf, sizeof(buf), (const char *)fmt, args); // for the rest of the world
|
||||
#endif
|
||||
va_end(args);
|
||||
Serial.print(buf);
|
||||
va_end(args);
|
||||
Serial.print(buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
@@ -28,71 +28,79 @@
|
||||
MyMessage mPing(CHILD, V_VAR1); //Ping message
|
||||
MyMessage mPong(CHILD, V_VAR2); //Pong message
|
||||
|
||||
void setup() {
|
||||
void setup()
|
||||
{
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
present(CHILD, S_CUSTOM); //
|
||||
|
||||
sendSketchInfo( nodeTypeAsCharRepresentation( getNodeId() ), VSN );
|
||||
LOG(F("\n%sReady.\n"), nodeTypeAsCharRepresentation(getNodeId()));
|
||||
void presentation()
|
||||
{
|
||||
present(CHILD, S_CUSTOM); //
|
||||
|
||||
sendSketchInfo( nodeTypeAsCharRepresentation( getNodeId() ), VSN );
|
||||
LOG(F("\n%sReady.\n"), nodeTypeAsCharRepresentation(getNodeId()));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// Interactive command and control
|
||||
// Entering a number from 0 or 1 will write the node 200 (YING) or 201 (YANG) to EEPROM
|
||||
// Entering T on either node will initiatve a ping-pong test.
|
||||
if (Serial.available()) {
|
||||
byte inChar = Serial.read();
|
||||
uint8_t node = getNodeId();
|
||||
|
||||
// Manual Test Mode
|
||||
if (inChar == 'T' || inChar == 't') {
|
||||
LOG(F("T received - starting test...\n"));
|
||||
MyMessage msg = mPong;
|
||||
msg.sender = (node == YING ? YANG : YING);
|
||||
sendPingOrPongResponse( msg );
|
||||
}
|
||||
else if (inChar == '0' or inChar == '1') {
|
||||
byte nodeID = 200 + (inChar - '0');
|
||||
setNodeId(nodeID);
|
||||
}
|
||||
else {
|
||||
LOG("Invalid input\n");
|
||||
}
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
|
||||
// Interactive command and control
|
||||
// Entering a number from 0 or 1 will write the node 200 (YING) or 201 (YANG) to EEPROM
|
||||
// Entering T on either node will initiatve a ping-pong test.
|
||||
if (Serial.available()) {
|
||||
byte inChar = Serial.read();
|
||||
uint8_t node = getNodeId();
|
||||
|
||||
// Manual Test Mode
|
||||
if (inChar == 'T' || inChar == 't') {
|
||||
LOG(F("T received - starting test...\n"));
|
||||
MyMessage msg = mPong;
|
||||
msg.sender = (node == YING ? YANG : YING);
|
||||
sendPingOrPongResponse( msg );
|
||||
} else if (inChar == '0' or inChar == '1') {
|
||||
byte nodeID = 200 + (inChar - '0');
|
||||
setNodeId(nodeID);
|
||||
} else {
|
||||
LOG("Invalid input\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void receive(const MyMessage &message) {
|
||||
|
||||
LOG(F("Received %s from %s\n"), msgTypeAsCharRepresentation((mysensor_data)message.type), nodeTypeAsCharRepresentation(message.sender));
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
|
||||
delay(250);
|
||||
sendPingOrPongResponse( message );
|
||||
LOG(F("Received %s from %s\n"), msgTypeAsCharRepresentation((mysensor_data)message.type),
|
||||
nodeTypeAsCharRepresentation(message.sender));
|
||||
|
||||
delay(250);
|
||||
sendPingOrPongResponse( message );
|
||||
}
|
||||
|
||||
void sendPingOrPongResponse( MyMessage msg ) {
|
||||
|
||||
MyMessage response = (msg.type == V_VAR1 ? mPong : mPing);
|
||||
|
||||
LOG(F("Sending %s to %s\n"), msgTypeAsCharRepresentation( (mysensor_data)response.type ), nodeTypeAsCharRepresentation(msg.sender));
|
||||
|
||||
// Set payload to current time in millis to ensure each message is unique
|
||||
response.set( millis() );
|
||||
response.setDestination(msg.sender);
|
||||
send(response);
|
||||
void sendPingOrPongResponse( MyMessage msg )
|
||||
{
|
||||
|
||||
MyMessage response = (msg.type == V_VAR1 ? mPong : mPing);
|
||||
|
||||
LOG(F("Sending %s to %s\n"), msgTypeAsCharRepresentation( (mysensor_data)response.type ),
|
||||
nodeTypeAsCharRepresentation(msg.sender));
|
||||
|
||||
// Set payload to current time in millis to ensure each message is unique
|
||||
response.set( millis() );
|
||||
response.setDestination(msg.sender);
|
||||
send(response);
|
||||
}
|
||||
|
||||
void setNodeId(byte nodeID) {
|
||||
LOG(F("Setting node id to: %i.\n***Please restart the node for changes to take effect.\n"), nodeID);
|
||||
eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, (byte)nodeID);
|
||||
void setNodeId(byte nodeID)
|
||||
{
|
||||
LOG(F("Setting node id to: %i.\n***Please restart the node for changes to take effect.\n"), nodeID);
|
||||
eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, (byte)nodeID);
|
||||
}
|
||||
|
||||
const char * msgTypeAsCharRepresentation( mysensor_data mType ) {
|
||||
return mType == V_VAR1 ? "Ping" : "Pong";
|
||||
const char * msgTypeAsCharRepresentation( mysensor_data mType )
|
||||
{
|
||||
return mType == V_VAR1 ? "Ping" : "Pong";
|
||||
}
|
||||
|
||||
const char * nodeTypeAsCharRepresentation( uint8_t node ) {
|
||||
return node == YING ? "Ying Node" : "Yang Node";
|
||||
const char * nodeTypeAsCharRepresentation( uint8_t node )
|
||||
{
|
||||
return node == YING ? "Ying Node" : "Yang Node";
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Example sketch showing how to control physical relays.
|
||||
* Example sketch showing how to control physical relays.
|
||||
* This example will remember relay state after power failure.
|
||||
* http://www.mysensors.org/build/relay
|
||||
*/
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
@@ -45,48 +45,51 @@
|
||||
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
|
||||
|
||||
|
||||
void before() {
|
||||
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
|
||||
// Then set relay pins in output mode
|
||||
pinMode(pin, OUTPUT);
|
||||
// Set relay to last known state (using eeprom storage)
|
||||
digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
|
||||
}
|
||||
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Relay", "1.0");
|
||||
|
||||
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
present(sensor, S_BINARY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
void before()
|
||||
{
|
||||
|
||||
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
|
||||
// Then set relay pins in output mode
|
||||
pinMode(pin, OUTPUT);
|
||||
// Set relay to last known state (using eeprom storage)
|
||||
digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
void receive(const MyMessage &message) {
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_STATUS) {
|
||||
// Change relay state
|
||||
digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
|
||||
// Store state in eeprom
|
||||
saveState(message.sensor, message.getBool());
|
||||
// Write some debug info
|
||||
Serial.print("Incoming change for sensor:");
|
||||
Serial.print(message.sensor);
|
||||
Serial.print(", New status: ");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
void setup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Relay", "1.0");
|
||||
|
||||
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
present(sensor, S_BINARY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_STATUS) {
|
||||
// Change relay state
|
||||
digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
|
||||
// Store state in eeprom
|
||||
saveState(message.sensor, message.getBool());
|
||||
// Write some debug info
|
||||
Serial.print("Incoming change for sensor:");
|
||||
Serial.print(message.sensor);
|
||||
Serial.print(", New status: ");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,16 +20,16 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Example sketch showing how to create a node thay repeates messages
|
||||
* from nodes far from gateway back to gateway.
|
||||
* It is important that nodes that has enabled repeater mode calls
|
||||
* process() frequently. Repeaters should never sleep.
|
||||
* from nodes far from gateway back to gateway.
|
||||
* It is important that nodes that has enabled repeater mode calls
|
||||
* process() frequently. Repeaters should never sleep.
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
@@ -40,17 +40,18 @@
|
||||
|
||||
#include <MySensors.h>
|
||||
|
||||
void setup() {
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void presentation()
|
||||
{
|
||||
//Send the sensor node sketch version information to the gateway
|
||||
sendSketchInfo("Repeater Node", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
//Send the sensor node sketch version information to the gateway
|
||||
sendSketchInfo("Repeater Node", "1.0");
|
||||
}
|
||||
|
||||
void loop()
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,67 +20,75 @@
|
||||
*
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Secret Knock Sensor
|
||||
* http://www.mysensors.org/build/knock
|
||||
*
|
||||
* See original instructions here (note: The MySensors adopted code might differ in wiring. The instructions below is correct):
|
||||
* https://learn.adafruit.com/secret-knock-activated-drawer-lock/
|
||||
* https://learn.adafruit.com/secret-knock-activated-drawer-lock/
|
||||
* Version 13.10.31 Built with Arduino IDE 1.0.5
|
||||
*
|
||||
*
|
||||
* By Steve Hoefer http://grathio.com
|
||||
* Adapted to MySensors by Henrik Ekblad
|
||||
*
|
||||
*
|
||||
* Licensed under Creative Commons Attribution-Noncommercial-Share Alike 3.0
|
||||
* http://creativecommons.org/licenses/by-nc-sa/3.0/us/
|
||||
* (In short: Do what you want, as long as you credit me, don't relicense it, and don't sell it or use it in anything you sell without contacting me.)
|
||||
*
|
||||
* ------Wiring------
|
||||
* Pin 0: Program button used for recording a new Knock (connect Pin0 -> button -> GND)
|
||||
* Pin 1: Optional: Connect LED here (remember resisor in series)
|
||||
* Pin 2: Optional: Piezo element (for beeps).
|
||||
* Pin 5: A sound sensor (digital output) for sensing knocks. See MySensors purchase guide. I used this: http://rover.ebay.com/rover/1/711-53200-19255-0/1?icep_ff3=2&pub=5575069610&toolid=10001&campid=5337433187&customid=&icep_item=200941260251&ipn=psmain&icep_vectorid=229466&kwid=902099&mtid=824&kw=lg
|
||||
* Pin 4: Connects to either 1. Relay which open door or lock or
|
||||
* 2. transistor that opens a solenoid lock when HIGH (see adafruit guide for this option).
|
||||
*
|
||||
*
|
||||
* Connect radio according as usual(you can skip IRQ pin)
|
||||
* http://www.mysensors.org/build/connect_radio
|
||||
* ------Wiring------
|
||||
* Pin 0: Program button used for recording a new Knock (connect Pin0 -> button -> GND)
|
||||
* Pin 1: Optional: Connect LED here (remember resisor in series)
|
||||
* Pin 2: Optional: Piezo element (for beeps).
|
||||
* Pin 5: A sound sensor (digital output) for sensing knocks. See MySensors purchase guide. I used this: http://rover.ebay.com/rover/1/711-53200-19255-0/1?icep_ff3=2&pub=5575069610&toolid=10001&campid=5337433187&customid=&icep_item=200941260251&ipn=psmain&icep_vectorid=229466&kwid=902099&mtid=824&kw=lg
|
||||
* Pin 4: Connects to either 1. Relay which open door or lock or
|
||||
* 2. transistor that opens a solenoid lock when HIGH (see adafruit guide for this option).
|
||||
*
|
||||
*
|
||||
* Connect radio according as usual(you can skip IRQ pin)
|
||||
* http://www.mysensors.org/build/connect_radio
|
||||
*/
|
||||
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
|
||||
#define CHILD_ID 99 // Id of the sensor child
|
||||
|
||||
const byte eepromValid = 121; // If the first byte in eeprom is this then the data is valid.
|
||||
|
||||
|
||||
/*Pin definitions*/
|
||||
const int programButton = 0; // (Digital 0) Record A New Knock button.
|
||||
const int ledPin = 1; // (Digital 1) The LED pin (if any)
|
||||
const int knockSensor = 5; // (Digital 5) for using the microphone digital output (tune knob to register knock)
|
||||
const int audioOut = 2; // (Digital 2) for using the peizo as an output device. (Thing that goes beep.)
|
||||
const int knockSensor =
|
||||
5; // (Digital 5) for using the microphone digital output (tune knob to register knock)
|
||||
const int audioOut =
|
||||
2; // (Digital 2) for using the peizo as an output device. (Thing that goes beep.)
|
||||
const int lockPin = 4; // (Digital 4) The pin that activates the relay/solenoid lock.
|
||||
|
||||
|
||||
/*Tuning constants. Changing the values below changes the behavior of the device.*/
|
||||
int threshold = 3; // Minimum signal from the piezo to register as a knock. Higher = less sensitive. Typical values 1 - 10
|
||||
const int rejectValue = 25; // If an individual knock is off by this percentage of a knock we don't unlock. Typical values 10-30
|
||||
const int averageRejectValue = 15; // If the average timing of all the knocks is off by this percent we don't unlock. Typical values 5-20
|
||||
const int knockFadeTime = 150; // Milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)
|
||||
const int lockOperateTime = 2500; // Milliseconds that we operate the lock solenoid latch before releasing it.
|
||||
int threshold =
|
||||
3; // Minimum signal from the piezo to register as a knock. Higher = less sensitive. Typical values 1 - 10
|
||||
const int rejectValue =
|
||||
25; // If an individual knock is off by this percentage of a knock we don't unlock. Typical values 10-30
|
||||
const int averageRejectValue =
|
||||
15; // If the average timing of all the knocks is off by this percent we don't unlock. Typical values 5-20
|
||||
const int knockFadeTime =
|
||||
150; // Milliseconds we allow a knock to fade before we listen for another one. (Debounce timer.)
|
||||
const int lockOperateTime =
|
||||
2500; // Milliseconds that we operate the lock solenoid latch before releasing it.
|
||||
const int maximumKnocks = 20; // Maximum number of knocks to listen for.
|
||||
const int knockComplete = 1200; // Longest time to wait for a knock before we assume that it's finished. (milliseconds)
|
||||
|
||||
const int knockComplete =
|
||||
1200; // Longest time to wait for a knock before we assume that it's finished. (milliseconds)
|
||||
|
||||
byte secretCode[maximumKnocks] = {50, 25, 25, 50, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Initial setup: "Shave and a Hair Cut, two bits."
|
||||
int knockReadings[maximumKnocks]; // When someone knocks this array fills with the delays between knocks.
|
||||
int knockSensorValue = 0; // Last reading of the knock sensor.
|
||||
@@ -90,290 +98,311 @@ bool lockStatus;
|
||||
|
||||
MyMessage lockMsg(CHILD_ID, V_LOCK_STATUS);
|
||||
|
||||
void setup() {
|
||||
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(knockSensor, INPUT);
|
||||
pinMode(lockPin, OUTPUT);
|
||||
pinMode(programButton, INPUT);
|
||||
digitalWrite(programButton, HIGH); // Enable internal pull up
|
||||
void setup()
|
||||
{
|
||||
|
||||
readSecretKnock(); // Load the secret knock (if any) from EEPROM.
|
||||
|
||||
digitalWrite(lockPin, HIGH); // Unlock the door for a bit when we power up. For system check and to allow a way in if the key is forgotten
|
||||
delay(500); // Wait a short time
|
||||
|
||||
lockStatus = loadState(0); // Read last lock status from eeprom
|
||||
setLockState(lockStatus, true); // Now set the last known state and send it to controller
|
||||
pinMode(ledPin, OUTPUT);
|
||||
pinMode(knockSensor, INPUT);
|
||||
pinMode(lockPin, OUTPUT);
|
||||
pinMode(programButton, INPUT);
|
||||
digitalWrite(programButton, HIGH); // Enable internal pull up
|
||||
|
||||
delay(500); // This delay is here because the solenoid lock returning to place can otherwise trigger and inadvertent knock.
|
||||
readSecretKnock(); // Load the secret knock (if any) from EEPROM.
|
||||
|
||||
digitalWrite(lockPin,
|
||||
HIGH); // Unlock the door for a bit when we power up. For system check and to allow a way in if the key is forgotten
|
||||
delay(500); // Wait a short time
|
||||
|
||||
lockStatus = loadState(0); // Read last lock status from eeprom
|
||||
setLockState(lockStatus, true); // Now set the last known state and send it to controller
|
||||
|
||||
delay(500); // This delay is here because the solenoid lock returning to place can otherwise trigger and inadvertent knock.
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
sendSketchInfo("Secret Knock", "1.0");
|
||||
present(CHILD_ID, S_LOCK);
|
||||
void presentation()
|
||||
{
|
||||
sendSketchInfo("Secret Knock", "1.0");
|
||||
present(CHILD_ID, S_LOCK);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Listen for any knock at all.
|
||||
knockSensorValue = digitalRead(knockSensor);
|
||||
if (digitalRead(programButton) == LOW){ // is the program button pressed?
|
||||
delay(100); // Cheap debounce.
|
||||
if (digitalRead(programButton) == LOW){
|
||||
if (programModeActive == false){ // If we're not in programming mode, turn it on.
|
||||
programModeActive = true; // Remember we're in programming mode.
|
||||
digitalWrite(ledPin, HIGH); // Turn on the red light too so the user knows we're programming.
|
||||
chirp(500, 1500); // And play a tone in case the user can't see the LED.
|
||||
chirp(500, 1000);
|
||||
} else { // If we are in programing mode, turn it off.
|
||||
programModeActive = false;
|
||||
digitalWrite(ledPin, LOW);
|
||||
chirp(500, 1000); // Turn off the programming LED and play a sad note.
|
||||
chirp(500, 1500);
|
||||
delay(500);
|
||||
}
|
||||
while (digitalRead(programButton) == LOW){
|
||||
delay(10); // Hang around until the button is released.
|
||||
}
|
||||
}
|
||||
delay(250); // Another cheap debounce. Longer because releasing the button can sometimes be sensed as a knock.
|
||||
}
|
||||
|
||||
|
||||
if (knockSensorValue == 0) {
|
||||
if (programModeActive == true){ // Blink the LED when we sense a knock.
|
||||
digitalWrite(ledPin, LOW);
|
||||
} else {
|
||||
digitalWrite(ledPin, HIGH);
|
||||
}
|
||||
knockDelay();
|
||||
if (programModeActive == true){ // Un-blink the LED.
|
||||
digitalWrite(ledPin, HIGH);
|
||||
} else {
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
listenToSecretKnock(); // We have our first knock. Go and see what other knocks are in store...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Listen for any knock at all.
|
||||
knockSensorValue = digitalRead(knockSensor);
|
||||
if (digitalRead(programButton) == LOW) { // is the program button pressed?
|
||||
delay(100); // Cheap debounce.
|
||||
if (digitalRead(programButton) == LOW) {
|
||||
if (programModeActive == false) { // If we're not in programming mode, turn it on.
|
||||
programModeActive = true; // Remember we're in programming mode.
|
||||
digitalWrite(ledPin, HIGH); // Turn on the red light too so the user knows we're programming.
|
||||
chirp(500, 1500); // And play a tone in case the user can't see the LED.
|
||||
chirp(500, 1000);
|
||||
} else { // If we are in programing mode, turn it off.
|
||||
programModeActive = false;
|
||||
digitalWrite(ledPin, LOW);
|
||||
chirp(500, 1000); // Turn off the programming LED and play a sad note.
|
||||
chirp(500, 1500);
|
||||
delay(500);
|
||||
}
|
||||
while (digitalRead(programButton) == LOW) {
|
||||
delay(10); // Hang around until the button is released.
|
||||
}
|
||||
}
|
||||
delay(250); // Another cheap debounce. Longer because releasing the button can sometimes be sensed as a knock.
|
||||
}
|
||||
|
||||
|
||||
if (knockSensorValue == 0) {
|
||||
if (programModeActive == true) { // Blink the LED when we sense a knock.
|
||||
digitalWrite(ledPin, LOW);
|
||||
} else {
|
||||
digitalWrite(ledPin, HIGH);
|
||||
}
|
||||
knockDelay();
|
||||
if (programModeActive == true) { // Un-blink the LED.
|
||||
digitalWrite(ledPin, HIGH);
|
||||
} else {
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
listenToSecretKnock(); // We have our first knock. Go and see what other knocks are in store...
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Records the timing of knocks.
|
||||
void listenToSecretKnock(){
|
||||
int i = 0;
|
||||
// First reset the listening array.
|
||||
for (i=0; i < maximumKnocks; i++){
|
||||
knockReadings[i] = 0;
|
||||
}
|
||||
|
||||
int currentKnockNumber = 0; // Position counter for the array.
|
||||
int startTime = millis(); // Reference for when this knock started.
|
||||
int now = millis();
|
||||
|
||||
do { // Listen for the next knock or wait for it to timeout.
|
||||
knockSensorValue = digitalRead(knockSensor);
|
||||
void listenToSecretKnock()
|
||||
{
|
||||
int i = 0;
|
||||
// First reset the listening array.
|
||||
for (i=0; i < maximumKnocks; i++) {
|
||||
knockReadings[i] = 0;
|
||||
}
|
||||
|
||||
if (knockSensorValue == 0){ // Here's another knock. Save the time between knocks.
|
||||
Serial.println("knock");
|
||||
int currentKnockNumber = 0; // Position counter for the array.
|
||||
int startTime = millis(); // Reference for when this knock started.
|
||||
int now = millis();
|
||||
|
||||
now=millis();
|
||||
knockReadings[currentKnockNumber] = now - startTime;
|
||||
currentKnockNumber ++;
|
||||
startTime = now;
|
||||
|
||||
if (programModeActive==true){ // Blink the LED when we sense a knock.
|
||||
digitalWrite(ledPin, LOW);
|
||||
} else {
|
||||
digitalWrite(ledPin, HIGH);
|
||||
}
|
||||
knockDelay();
|
||||
if (programModeActive == true){ // Un-blink the LED.
|
||||
digitalWrite(ledPin, HIGH);
|
||||
} else {
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
now = millis();
|
||||
|
||||
// Stop listening if there are too many knocks or there is too much time between knocks.
|
||||
} while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
|
||||
Serial.println("end");
|
||||
do { // Listen for the next knock or wait for it to timeout.
|
||||
knockSensorValue = digitalRead(knockSensor);
|
||||
|
||||
//we've got our knock recorded, lets see if it's valid
|
||||
if (programModeActive == false){ // Only do this if we're not recording a new knock.
|
||||
if (validateKnock() == true){
|
||||
// Lock/unlock door
|
||||
chirp(500, 1500); // And play a tone in case the user can't see the LED.
|
||||
chirp(500, 1000);
|
||||
setLockState(!lockStatus, true);
|
||||
} else {
|
||||
Serial.println("fail unlock");
|
||||
if (knockSensorValue == 0) { // Here's another knock. Save the time between knocks.
|
||||
Serial.println("knock");
|
||||
|
||||
// knock is invalid. Blink the LED as a warning to others.
|
||||
for (i=0; i < 4; i++){
|
||||
digitalWrite(ledPin, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(ledPin, LOW);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
} else { // If we're in programming mode we still validate the lock because it makes some numbers we need, we just don't do anything with the return.
|
||||
validateKnock();
|
||||
}
|
||||
now=millis();
|
||||
knockReadings[currentKnockNumber] = now - startTime;
|
||||
currentKnockNumber ++;
|
||||
startTime = now;
|
||||
|
||||
if (programModeActive==true) { // Blink the LED when we sense a knock.
|
||||
digitalWrite(ledPin, LOW);
|
||||
} else {
|
||||
digitalWrite(ledPin, HIGH);
|
||||
}
|
||||
knockDelay();
|
||||
if (programModeActive == true) { // Un-blink the LED.
|
||||
digitalWrite(ledPin, HIGH);
|
||||
} else {
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
now = millis();
|
||||
|
||||
// Stop listening if there are too many knocks or there is too much time between knocks.
|
||||
} while ((now-startTime < knockComplete) && (currentKnockNumber < maximumKnocks));
|
||||
Serial.println("end");
|
||||
|
||||
//we've got our knock recorded, lets see if it's valid
|
||||
if (programModeActive == false) { // Only do this if we're not recording a new knock.
|
||||
if (validateKnock() == true) {
|
||||
// Lock/unlock door
|
||||
chirp(500, 1500); // And play a tone in case the user can't see the LED.
|
||||
chirp(500, 1000);
|
||||
setLockState(!lockStatus, true);
|
||||
} else {
|
||||
Serial.println("fail unlock");
|
||||
|
||||
// knock is invalid. Blink the LED as a warning to others.
|
||||
for (i=0; i < 4; i++) {
|
||||
digitalWrite(ledPin, HIGH);
|
||||
delay(50);
|
||||
digitalWrite(ledPin, LOW);
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
} else { // If we're in programming mode we still validate the lock because it makes some numbers we need, we just don't do anything with the return.
|
||||
validateKnock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Unlocks the door.
|
||||
void setLockState(bool state, bool doSend){
|
||||
if (state)
|
||||
Serial.println("open lock");
|
||||
else
|
||||
Serial.println("close lock");
|
||||
if (doSend)
|
||||
send(lockMsg.set(state));
|
||||
|
||||
digitalWrite(ledPin, state);
|
||||
digitalWrite(lockPin, state);
|
||||
saveState(0,state);
|
||||
lockStatus = state;
|
||||
delay(500); // This delay is here because releasing the latch can cause a vibration that will be sensed as a knock.
|
||||
void setLockState(bool state, bool doSend)
|
||||
{
|
||||
if (state) {
|
||||
Serial.println("open lock");
|
||||
} else {
|
||||
Serial.println("close lock");
|
||||
}
|
||||
if (doSend) {
|
||||
send(lockMsg.set(state));
|
||||
}
|
||||
|
||||
digitalWrite(ledPin, state);
|
||||
digitalWrite(lockPin, state);
|
||||
saveState(0,state);
|
||||
lockStatus = state;
|
||||
delay(500); // This delay is here because releasing the latch can cause a vibration that will be sensed as a knock.
|
||||
}
|
||||
|
||||
|
||||
// Checks to see if our knock matches the secret.
|
||||
// Returns true if it's a good knock, false if it's not.
|
||||
bool validateKnock(){
|
||||
int i = 0;
|
||||
|
||||
int currentKnockCount = 0;
|
||||
int secretKnockCount = 0;
|
||||
int maxKnockInterval = 0; // We use this later to normalize the times.
|
||||
|
||||
for (i=0;i<maximumKnocks;i++){
|
||||
if (knockReadings[i] > 0){
|
||||
currentKnockCount++;
|
||||
}
|
||||
if (secretCode[i] > 0){
|
||||
secretKnockCount++;
|
||||
}
|
||||
|
||||
if (knockReadings[i] > maxKnockInterval){ // Collect normalization data while we're looping.
|
||||
maxKnockInterval = knockReadings[i];
|
||||
}
|
||||
}
|
||||
|
||||
// If we're recording a new knock, save the info and get out of here.
|
||||
if (programModeActive == true){
|
||||
for (i=0; i < maximumKnocks; i++){ // Normalize the time between knocks. (the longest time = 100)
|
||||
secretCode[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
|
||||
}
|
||||
saveSecretKnock(); // save the result to EEPROM
|
||||
programModeActive = false;
|
||||
playbackKnock(maxKnockInterval);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentKnockCount != secretKnockCount){ // Easiest check first. If the number of knocks is wrong, don't unlock.
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now we compare the relative intervals of our knocks, not the absolute time between them.
|
||||
(ie: if you do the same pattern slow or fast it should still open the door.)
|
||||
This makes it less picky, which while making it less secure can also make it
|
||||
less of a pain to use if you're tempo is a little slow or fast.
|
||||
*/
|
||||
int totaltimeDifferences = 0;
|
||||
int timeDiff = 0;
|
||||
for (i=0; i < maximumKnocks; i++){ // Normalize the times
|
||||
knockReadings[i]= map(knockReadings[i], 0, maxKnockInterval, 0, 100);
|
||||
timeDiff = abs(knockReadings[i] - secretCode[i]);
|
||||
if (timeDiff > rejectValue){ // Individual value too far out of whack. No access for this knock!
|
||||
return false;
|
||||
}
|
||||
totaltimeDifferences += timeDiff;
|
||||
}
|
||||
// It can also fail if the whole thing is too inaccurate.
|
||||
if (totaltimeDifferences / secretKnockCount > averageRejectValue){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
bool validateKnock()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
int currentKnockCount = 0;
|
||||
int secretKnockCount = 0;
|
||||
int maxKnockInterval = 0; // We use this later to normalize the times.
|
||||
|
||||
for (i=0; i<maximumKnocks; i++) {
|
||||
if (knockReadings[i] > 0) {
|
||||
currentKnockCount++;
|
||||
}
|
||||
if (secretCode[i] > 0) {
|
||||
secretKnockCount++;
|
||||
}
|
||||
|
||||
if (knockReadings[i] > maxKnockInterval) { // Collect normalization data while we're looping.
|
||||
maxKnockInterval = knockReadings[i];
|
||||
}
|
||||
}
|
||||
|
||||
// If we're recording a new knock, save the info and get out of here.
|
||||
if (programModeActive == true) {
|
||||
for (i=0; i < maximumKnocks; i++) { // Normalize the time between knocks. (the longest time = 100)
|
||||
secretCode[i] = map(knockReadings[i], 0, maxKnockInterval, 0, 100);
|
||||
}
|
||||
saveSecretKnock(); // save the result to EEPROM
|
||||
programModeActive = false;
|
||||
playbackKnock(maxKnockInterval);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentKnockCount !=
|
||||
secretKnockCount) { // Easiest check first. If the number of knocks is wrong, don't unlock.
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now we compare the relative intervals of our knocks, not the absolute time between them.
|
||||
(ie: if you do the same pattern slow or fast it should still open the door.)
|
||||
This makes it less picky, which while making it less secure can also make it
|
||||
less of a pain to use if you're tempo is a little slow or fast.
|
||||
*/
|
||||
int totaltimeDifferences = 0;
|
||||
int timeDiff = 0;
|
||||
for (i=0; i < maximumKnocks; i++) { // Normalize the times
|
||||
knockReadings[i]= map(knockReadings[i], 0, maxKnockInterval, 0, 100);
|
||||
timeDiff = abs(knockReadings[i] - secretCode[i]);
|
||||
if (timeDiff >
|
||||
rejectValue) { // Individual value too far out of whack. No access for this knock!
|
||||
return false;
|
||||
}
|
||||
totaltimeDifferences += timeDiff;
|
||||
}
|
||||
// It can also fail if the whole thing is too inaccurate.
|
||||
if (totaltimeDifferences / secretKnockCount > averageRejectValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// reads the secret knock from EEPROM. (if any.)
|
||||
void readSecretKnock(){
|
||||
byte reading;
|
||||
reading = loadState(1);
|
||||
if (reading == eepromValid){ // only read EEPROM if the signature byte is correct.
|
||||
for (int i=0; i < maximumKnocks ;i++){
|
||||
secretCode[i] = loadState(i+2);
|
||||
}
|
||||
}
|
||||
void readSecretKnock()
|
||||
{
|
||||
byte reading;
|
||||
reading = loadState(1);
|
||||
if (reading == eepromValid) { // only read EEPROM if the signature byte is correct.
|
||||
for (int i=0; i < maximumKnocks ; i++) {
|
||||
secretCode[i] = loadState(i+2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//saves a new pattern too eeprom
|
||||
void saveSecretKnock(){
|
||||
saveState(1, 0); // clear out the signature. That way we know if we didn't finish the write successfully.
|
||||
for (int i=0; i < maximumKnocks; i++){
|
||||
saveState(i+2, secretCode[i]);
|
||||
}
|
||||
saveState(1, eepromValid); // all good. Write the signature so we'll know it's all good.
|
||||
void saveSecretKnock()
|
||||
{
|
||||
saveState(1,
|
||||
0); // clear out the signature. That way we know if we didn't finish the write successfully.
|
||||
for (int i=0; i < maximumKnocks; i++) {
|
||||
saveState(i+2, secretCode[i]);
|
||||
}
|
||||
saveState(1, eepromValid); // all good. Write the signature so we'll know it's all good.
|
||||
}
|
||||
|
||||
|
||||
// Plays back the pattern of the knock in blinks and beeps
|
||||
void playbackKnock(int maxKnockInterval){
|
||||
digitalWrite(ledPin, LOW);
|
||||
delay(1000);
|
||||
digitalWrite(ledPin, HIGH);
|
||||
chirp(200, 1800);
|
||||
for (int i = 0; i < maximumKnocks ; i++){
|
||||
digitalWrite(ledPin, LOW);
|
||||
// only turn it on if there's a delay
|
||||
if (secretCode[i] > 0){
|
||||
delay(map(secretCode[i], 0, 100, 0, maxKnockInterval)); // Expand the time back out to what it was. Roughly.
|
||||
digitalWrite(ledPin, HIGH);
|
||||
chirp(200, 1800);
|
||||
}
|
||||
}
|
||||
digitalWrite(ledPin, LOW);
|
||||
void playbackKnock(int maxKnockInterval)
|
||||
{
|
||||
digitalWrite(ledPin, LOW);
|
||||
delay(1000);
|
||||
digitalWrite(ledPin, HIGH);
|
||||
chirp(200, 1800);
|
||||
for (int i = 0; i < maximumKnocks ; i++) {
|
||||
digitalWrite(ledPin, LOW);
|
||||
// only turn it on if there's a delay
|
||||
if (secretCode[i] > 0) {
|
||||
delay(map(secretCode[i], 0, 100, 0,
|
||||
maxKnockInterval)); // Expand the time back out to what it was. Roughly.
|
||||
digitalWrite(ledPin, HIGH);
|
||||
chirp(200, 1800);
|
||||
}
|
||||
}
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
|
||||
|
||||
// Deals with the knock delay thingy.
|
||||
void knockDelay(){
|
||||
int itterations = (knockFadeTime / 20); // Wait for the peak to dissipate before listening to next one.
|
||||
for (int i=0; i < itterations; i++){
|
||||
delay(10);
|
||||
analogRead(knockSensor); // This is done in an attempt to defuse the analog sensor's capacitor that will give false readings on high impedance sensors.
|
||||
delay(10);
|
||||
}
|
||||
void knockDelay()
|
||||
{
|
||||
int itterations = (knockFadeTime /
|
||||
20); // Wait for the peak to dissipate before listening to next one.
|
||||
for (int i=0; i < itterations; i++) {
|
||||
delay(10);
|
||||
analogRead(
|
||||
knockSensor); // This is done in an attempt to defuse the analog sensor's capacitor that will give false readings on high impedance sensors.
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Plays a non-musical tone on the piezo.
|
||||
// playTime = milliseconds to play the tone
|
||||
// delayTime = time in microseconds between ticks. (smaller=higher pitch tone.)
|
||||
void chirp(int playTime, int delayTime){
|
||||
long loopTime = (playTime * 1000L) / delayTime;
|
||||
pinMode(audioOut, OUTPUT);
|
||||
for(int i=0; i < loopTime; i++){
|
||||
digitalWrite(audioOut, HIGH);
|
||||
delayMicroseconds(delayTime);
|
||||
digitalWrite(audioOut, LOW);
|
||||
}
|
||||
pinMode(audioOut, INPUT);
|
||||
void chirp(int playTime, int delayTime)
|
||||
{
|
||||
long loopTime = (playTime * 1000L) / delayTime;
|
||||
pinMode(audioOut, OUTPUT);
|
||||
for(int i=0; i < loopTime; i++) {
|
||||
digitalWrite(audioOut, HIGH);
|
||||
delayMicroseconds(delayTime);
|
||||
digitalWrite(audioOut, LOW);
|
||||
}
|
||||
pinMode(audioOut, INPUT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void receive(const MyMessage &message) {
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_LOCK_STATUS) {
|
||||
// Change relay state
|
||||
setLockState(message.getBool(), false);
|
||||
|
||||
// Write some debug info
|
||||
Serial.print("Incoming lock status:");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_LOCK_STATUS) {
|
||||
// Change relay state
|
||||
setLockState(message.getBool(), false);
|
||||
|
||||
// Write some debug info
|
||||
Serial.print("Incoming lock status:");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24 //!< NRF24L01 radio driver
|
||||
//#define MY_RADIO_RFM69 //!< RFM69 radio driver
|
||||
|
||||
|
||||
// Select soft/hardware signing method
|
||||
#define MY_SIGNING_SOFT //!< Software signing
|
||||
//#define MY_SIGNING_ATSHA204 //!< Hardware signing using ATSHA204A
|
||||
@@ -73,29 +73,30 @@
|
||||
#define LOCK_LOCK 1 //!< GPIO value to write to lock attached lock
|
||||
#define LOCK_UNLOCK 0 //!< GPIO value to write to unlock attached lock
|
||||
|
||||
void setup() {
|
||||
for (int lock=1, pin=LOCK_1; lock<=NOF_LOCKS;lock++, pin++) {
|
||||
// Set lock pins in output mode
|
||||
pinMode(pin, OUTPUT);
|
||||
// Set lock to last known state (using eeprom storage)
|
||||
digitalWrite(pin, loadState(lock)?LOCK_LOCK:LOCK_UNLOCK);
|
||||
}
|
||||
void setup()
|
||||
{
|
||||
for (int lock=1, pin=LOCK_1; lock<=NOF_LOCKS; lock++, pin++) {
|
||||
// Set lock pins in output mode
|
||||
pinMode(pin, OUTPUT);
|
||||
// Set lock to last known state (using eeprom storage)
|
||||
digitalWrite(pin, loadState(lock)?LOCK_LOCK:LOCK_UNLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
void presentation()
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Secure Lock", "1.0");
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Secure Lock", "1.0");
|
||||
|
||||
// Fetch lock status
|
||||
for (int lock=1, pin=LOCK_1; lock<=NOF_LOCKS;lock++, pin++) {
|
||||
// Register all locks to gw (they will be created as child devices)
|
||||
present(lock, S_LOCK, "SecureActuator", false);
|
||||
}
|
||||
// Fetch lock status
|
||||
for (int lock=1, pin=LOCK_1; lock<=NOF_LOCKS; lock++, pin++) {
|
||||
// Register all locks to gw (they will be created as child devices)
|
||||
present(lock, S_LOCK, "SecureActuator", false);
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Sketch execution code */
|
||||
void loop()
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -104,19 +105,20 @@ void loop()
|
||||
*
|
||||
* @param message The message to handle.
|
||||
*/
|
||||
void receive(const MyMessage &message) {
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
// And acks are not accepted as control messages
|
||||
if (message.type==V_LOCK_STATUS && message.sensor<=NOF_LOCKS && !mGetAck(message)) {
|
||||
// Change relay state
|
||||
digitalWrite(message.sensor-1+LOCK_1, message.getBool()?LOCK_LOCK:LOCK_UNLOCK);
|
||||
// Store state in eeprom
|
||||
saveState(message.sensor, message.getBool());
|
||||
// Write some debug info
|
||||
Serial.print("Incoming change for lock:");
|
||||
Serial.print(message.sensor);
|
||||
Serial.print(", New status: ");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
// And acks are not accepted as control messages
|
||||
if (message.type==V_LOCK_STATUS && message.sensor<=NOF_LOCKS && !mGetAck(message)) {
|
||||
// Change relay state
|
||||
digitalWrite(message.sensor-1+LOCK_1, message.getBool()?LOCK_LOCK:LOCK_UNLOCK);
|
||||
// Store state in eeprom
|
||||
saveState(message.sensor, message.getBool());
|
||||
// Write some debug info
|
||||
Serial.print("Incoming change for lock:");
|
||||
Serial.print(message.sensor);
|
||||
Serial.print(", New status: ");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
}
|
||||
/** @}*/
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -260,7 +260,7 @@
|
||||
#define SHA204_COMMAND_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5)) //! maximum command delay
|
||||
#define SHA204_CMD_SIZE_MIN ((uint8_t) 7) //! minimum number of bytes in command (from count byte to second CRC byte)
|
||||
#ifndef SHA204_CMD_SIZE_MAX
|
||||
#define SHA204_CMD_SIZE_MAX ((uint8_t) 84) //! maximum size of command packet (CheckMac)
|
||||
#define SHA204_CMD_SIZE_MAX ((uint8_t) 84) //! maximum size of command packet (CheckMac)
|
||||
#endif
|
||||
#define SHA204_CRC_SIZE ((uint8_t) 2) //! number of CRC bytes
|
||||
#define SHA204_BUFFER_POS_STATUS (1) //! buffer index of status byte in status response
|
||||
@@ -284,17 +284,17 @@
|
||||
/* Low level HW access macros */
|
||||
/* function calls is not working, as it will have too much overhead */
|
||||
#if !defined(ARDUINO_ARCH_AVR) // For everything else than AVR use pinMode / digitalWrite
|
||||
#define SHA204_SET_OUTPUT() pinMode(device_pin, OUTPUT)
|
||||
#define SHA204_SET_INPUT() pinMode(device_pin, INPUT)
|
||||
#define SHA204_POUT_HIGH() digitalWrite(device_pin, HIGH)
|
||||
#define SHA204_POUT_LOW() digitalWrite(device_pin, LOW)
|
||||
#define SHA204_PIN_READ() digitalRead(device_pin)
|
||||
#define SHA204_SET_OUTPUT() pinMode(device_pin, OUTPUT)
|
||||
#define SHA204_SET_INPUT() pinMode(device_pin, INPUT)
|
||||
#define SHA204_POUT_HIGH() digitalWrite(device_pin, HIGH)
|
||||
#define SHA204_POUT_LOW() digitalWrite(device_pin, LOW)
|
||||
#define SHA204_PIN_READ() digitalRead(device_pin)
|
||||
#else
|
||||
#define SHA204_SET_INPUT() *device_port_DDR &= ~device_pin
|
||||
#define SHA204_SET_OUTPUT() *device_port_DDR |= device_pin
|
||||
#define SHA204_POUT_HIGH() *device_port_OUT |= device_pin
|
||||
#define SHA204_POUT_LOW() *device_port_OUT &= ~device_pin
|
||||
#define SHA204_PIN_READ() (*device_port_IN & device_pin)
|
||||
#define SHA204_SET_INPUT() *device_port_DDR &= ~device_pin
|
||||
#define SHA204_SET_OUTPUT() *device_port_DDR |= device_pin
|
||||
#define SHA204_POUT_HIGH() *device_port_OUT |= device_pin
|
||||
#define SHA204_POUT_LOW() *device_port_OUT &= ~device_pin
|
||||
#define SHA204_PIN_READ() (*device_port_IN & device_pin)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2015 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The ArduinoGateway prints data received from sensors on the serial link.
|
||||
* The gateway accepts input on seral which will be sent out on radio network.
|
||||
*
|
||||
* This GW code is designed for Sensebender GateWay / (Arduino Zero variant)
|
||||
*
|
||||
* Wire connections (OPTIONAL):
|
||||
* - Inclusion button should be connected to SW2
|
||||
*
|
||||
* LEDs on board (default assignments):
|
||||
* - Orange: USB RX/TX - Blink when receiving / transmitting on USB CDC device
|
||||
* - Yellow: RX - Blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||
* - Green : TX - Blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||
* - Red : ERR - Fast blink on error during transmission error or recieve crc error
|
||||
* - Blue : free - (use with LED_BLUE macro)
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2015 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The ArduinoGateway prints data received from sensors on the serial link.
|
||||
* The gateway accepts input on seral which will be sent out on radio network.
|
||||
*
|
||||
* This GW code is designed for Sensebender GateWay / (Arduino Zero variant)
|
||||
*
|
||||
* Wire connections (OPTIONAL):
|
||||
* - Inclusion button should be connected to SW2
|
||||
*
|
||||
* LEDs on board (default assignments):
|
||||
* - Orange: USB RX/TX - Blink when receiving / transmitting on USB CDC device
|
||||
* - Yellow: RX - Blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
||||
* - Green : TX - Blink fast on radio message transmitted. In inclusion mode will blink slowly
|
||||
* - Red : ERR - Fast blink on error during transmission error or recieve crc error
|
||||
* - Blue : free - (use with LED_BLUE macro)
|
||||
*
|
||||
*/
|
||||
|
||||
#define SKETCH_VERSION "0.2"
|
||||
// Enable debug prints to serial monitor
|
||||
@@ -92,177 +92,189 @@ Sd2Card card;
|
||||
static uint8_t num_of_leds = 5;
|
||||
static uint8_t leds[] = {LED_BLUE, LED_RED, LED_GREEN, LED_YELLOW, LED_ORANGE};
|
||||
|
||||
void setup() {
|
||||
// Setup locally attached sensors
|
||||
void setup()
|
||||
{
|
||||
// Setup locally attached sensors
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Present locally attached sensors
|
||||
void presentation()
|
||||
{
|
||||
// Present locally attached sensors
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Send locally attached sensor data here
|
||||
void loop()
|
||||
{
|
||||
// Send locally attached sensor data here
|
||||
}
|
||||
|
||||
|
||||
void preHwInit() {
|
||||
void preHwInit()
|
||||
{
|
||||
|
||||
pinMode(MY_SWC1, INPUT_PULLUP);
|
||||
pinMode(MY_SWC2, INPUT_PULLUP);
|
||||
if (digitalRead(MY_SWC1) && digitalRead(MY_SWC2)) return;
|
||||
pinMode(MY_SWC1, INPUT_PULLUP);
|
||||
pinMode(MY_SWC2, INPUT_PULLUP);
|
||||
if (digitalRead(MY_SWC1) && digitalRead(MY_SWC2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t tests = 0;
|
||||
uint8_t tests = 0;
|
||||
|
||||
for (int i=0; i< num_of_leds; i++) {
|
||||
pinMode(leds[i], OUTPUT);
|
||||
}
|
||||
uint8_t led_state = 0;
|
||||
if (digitalRead(MY_SWC1)) {
|
||||
while (!Serial) {
|
||||
digitalWrite(LED_BLUE, led_state);
|
||||
led_state ^= 0x01;
|
||||
delay(500);
|
||||
} // Wait for USB to be connected, before spewing out data.
|
||||
}
|
||||
digitalWrite(LED_BLUE, LOW);
|
||||
if (Serial) {
|
||||
Serial.println("Sensebender GateWay test routine");
|
||||
Serial.print("Mysensors core version : ");
|
||||
Serial.println(MYSENSORS_LIBRARY_VERSION);
|
||||
Serial.print("GateWay sketch version : ");
|
||||
Serial.println(SKETCH_VERSION);
|
||||
Serial.println("----------------------------------");
|
||||
Serial.println();
|
||||
}
|
||||
if (testSha204()) {
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
tests++;
|
||||
}
|
||||
if (testSDCard()) {
|
||||
digitalWrite(LED_YELLOW, HIGH);
|
||||
tests++;
|
||||
}
|
||||
for (int i=0; i< num_of_leds; i++) {
|
||||
pinMode(leds[i], OUTPUT);
|
||||
}
|
||||
uint8_t led_state = 0;
|
||||
if (digitalRead(MY_SWC1)) {
|
||||
while (!Serial) {
|
||||
digitalWrite(LED_BLUE, led_state);
|
||||
led_state ^= 0x01;
|
||||
delay(500);
|
||||
} // Wait for USB to be connected, before spewing out data.
|
||||
}
|
||||
digitalWrite(LED_BLUE, LOW);
|
||||
if (Serial) {
|
||||
Serial.println("Sensebender GateWay test routine");
|
||||
Serial.print("Mysensors core version : ");
|
||||
Serial.println(MYSENSORS_LIBRARY_VERSION);
|
||||
Serial.print("GateWay sketch version : ");
|
||||
Serial.println(SKETCH_VERSION);
|
||||
Serial.println("----------------------------------");
|
||||
Serial.println();
|
||||
}
|
||||
if (testSha204()) {
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
tests++;
|
||||
}
|
||||
if (testSDCard()) {
|
||||
digitalWrite(LED_YELLOW, HIGH);
|
||||
tests++;
|
||||
}
|
||||
|
||||
if (testEEProm()) {
|
||||
digitalWrite(LED_ORANGE, HIGH);
|
||||
tests++;
|
||||
}
|
||||
if (testAnalog()) {
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
tests++;
|
||||
}
|
||||
if (tests == 4) {
|
||||
while(1) {
|
||||
for (int i=0; i<num_of_leds; i++) {
|
||||
digitalWrite(leds[i], HIGH);
|
||||
delay(200);
|
||||
digitalWrite(leds[i], LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (1) {
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
delay(200);
|
||||
digitalWrite(LED_RED, LOW);
|
||||
delay(200);
|
||||
}
|
||||
}
|
||||
if (testEEProm()) {
|
||||
digitalWrite(LED_ORANGE, HIGH);
|
||||
tests++;
|
||||
}
|
||||
if (testAnalog()) {
|
||||
digitalWrite(LED_BLUE, HIGH);
|
||||
tests++;
|
||||
}
|
||||
if (tests == 4) {
|
||||
while(1) {
|
||||
for (int i=0; i<num_of_leds; i++) {
|
||||
digitalWrite(leds[i], HIGH);
|
||||
delay(200);
|
||||
digitalWrite(leds[i], LOW);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (1) {
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
delay(200);
|
||||
digitalWrite(LED_RED, LOW);
|
||||
delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool testSha204(){
|
||||
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
|
||||
uint8_t ret_code;
|
||||
if (Serial) Serial.print("- > SHA204 ");
|
||||
atsha204_init(MY_SIGNING_ATSHA204_PIN);
|
||||
ret_code = atsha204_wakeup(rx_buffer);
|
||||
bool testSha204()
|
||||
{
|
||||
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
|
||||
uint8_t ret_code;
|
||||
if (Serial) {
|
||||
Serial.print("- > SHA204 ");
|
||||
}
|
||||
atsha204_init(MY_SIGNING_ATSHA204_PIN);
|
||||
ret_code = atsha204_wakeup(rx_buffer);
|
||||
|
||||
if (ret_code == SHA204_SUCCESS)
|
||||
{
|
||||
ret_code = atsha204_getSerialNumber(rx_buffer);
|
||||
if (ret_code != SHA204_SUCCESS)
|
||||
{
|
||||
if (Serial) Serial.println(F("Failed to obtain device serial number. Response: ")); Serial.println(ret_code, HEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Serial) {
|
||||
Serial.print(F("Ok (serial : "));
|
||||
for (int i=0; i<9; i++)
|
||||
{
|
||||
if (rx_buffer[i] < 0x10)
|
||||
{
|
||||
Serial.print('0'); // Because Serial.print does not 0-pad HEX
|
||||
}
|
||||
Serial.print(rx_buffer[i], HEX);
|
||||
}
|
||||
Serial.println(")");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Serial) Serial.println(F("Failed to wakeup SHA204"));
|
||||
}
|
||||
return false;
|
||||
if (ret_code == SHA204_SUCCESS) {
|
||||
ret_code = atsha204_getSerialNumber(rx_buffer);
|
||||
if (ret_code != SHA204_SUCCESS) {
|
||||
if (Serial) {
|
||||
Serial.println(F("Failed to obtain device serial number. Response: "));
|
||||
}
|
||||
Serial.println(ret_code, HEX);
|
||||
} else {
|
||||
if (Serial) {
|
||||
Serial.print(F("Ok (serial : "));
|
||||
for (int i=0; i<9; i++) {
|
||||
if (rx_buffer[i] < 0x10) {
|
||||
Serial.print('0'); // Because Serial.print does not 0-pad HEX
|
||||
}
|
||||
Serial.print(rx_buffer[i], HEX);
|
||||
}
|
||||
Serial.println(")");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (Serial) {
|
||||
Serial.println(F("Failed to wakeup SHA204"));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool testSDCard() {
|
||||
if (Serial) Serial.print("- > SD CARD ");
|
||||
if (!card.init(SPI_HALF_SPEED, MY_SDCARD_CS)) {
|
||||
if (Serial) Serial.println("SD CARD did not initialize!");
|
||||
}
|
||||
else {
|
||||
if (Serial) {
|
||||
Serial.print("SD Card initialized correct! - ");
|
||||
Serial.print("type detected : ");
|
||||
switch(card.type()) {
|
||||
case SD_CARD_TYPE_SD1:
|
||||
Serial.println("SD1");
|
||||
break;
|
||||
case SD_CARD_TYPE_SD2:
|
||||
Serial.println("SD2");
|
||||
break;
|
||||
case SD_CARD_TYPE_SDHC:
|
||||
Serial.println("SDHC");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unknown");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool testSDCard()
|
||||
{
|
||||
if (Serial) {
|
||||
Serial.print("- > SD CARD ");
|
||||
}
|
||||
if (!card.init(SPI_HALF_SPEED, MY_SDCARD_CS)) {
|
||||
if (Serial) {
|
||||
Serial.println("SD CARD did not initialize!");
|
||||
}
|
||||
} else {
|
||||
if (Serial) {
|
||||
Serial.print("SD Card initialized correct! - ");
|
||||
Serial.print("type detected : ");
|
||||
switch(card.type()) {
|
||||
case SD_CARD_TYPE_SD1:
|
||||
Serial.println("SD1");
|
||||
break;
|
||||
case SD_CARD_TYPE_SD2:
|
||||
Serial.println("SD2");
|
||||
break;
|
||||
case SD_CARD_TYPE_SDHC:
|
||||
Serial.println("SDHC");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unknown");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool testEEProm() {
|
||||
uint8_t eeprom_d1, eeprom_d2;
|
||||
SerialUSB.print(" -> EEPROM ");
|
||||
Wire.begin();
|
||||
eeprom_d1 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
|
||||
delay(500);
|
||||
eeprom_d1 = ~eeprom_d1; // invert the bits
|
||||
i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, eeprom_d1);
|
||||
delay(500);
|
||||
eeprom_d2 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
|
||||
if (eeprom_d1 == eeprom_d2) {
|
||||
SerialUSB.println("PASSED");
|
||||
i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, ~eeprom_d1);
|
||||
return true;
|
||||
}
|
||||
SerialUSB.println("FAILED!");
|
||||
return false;
|
||||
bool testEEProm()
|
||||
{
|
||||
uint8_t eeprom_d1, eeprom_d2;
|
||||
SerialUSB.print(" -> EEPROM ");
|
||||
Wire.begin();
|
||||
eeprom_d1 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
|
||||
delay(500);
|
||||
eeprom_d1 = ~eeprom_d1; // invert the bits
|
||||
i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, eeprom_d1);
|
||||
delay(500);
|
||||
eeprom_d2 = i2c_eeprom_read_byte(EEPROM_VERIFICATION_ADDRESS);
|
||||
if (eeprom_d1 == eeprom_d2) {
|
||||
SerialUSB.println("PASSED");
|
||||
i2c_eeprom_write_byte(EEPROM_VERIFICATION_ADDRESS, ~eeprom_d1);
|
||||
return true;
|
||||
}
|
||||
SerialUSB.println("FAILED!");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool testAnalog() {
|
||||
int bat_detect = analogRead(MY_BAT_DETECT);
|
||||
Serial.print("-> analog : ");
|
||||
Serial.print(bat_detect);
|
||||
if (bat_detect < 400 || bat_detect > 650) {
|
||||
Serial.println(" Failed");
|
||||
return false;
|
||||
}
|
||||
Serial.println(" Passed");
|
||||
return true;
|
||||
bool testAnalog()
|
||||
{
|
||||
int bat_detect = analogRead(MY_BAT_DETECT);
|
||||
Serial.print("-> analog : ");
|
||||
Serial.print(bat_detect);
|
||||
if (bat_detect < 400 || bat_detect > 650) {
|
||||
Serial.println(" Failed");
|
||||
return false;
|
||||
}
|
||||
Serial.println(" Passed");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,24 +22,24 @@
|
||||
*
|
||||
* Arduino soil moisture based on gypsum sensor/resistive sensor to avoid electric catalyse in soil
|
||||
* Required to interface the sensor: 2 * 4.7kOhm + 2 * 1N4148
|
||||
*
|
||||
* Gypsum sensor and calibration:
|
||||
*
|
||||
* Gypsum sensor and calibration:
|
||||
* DIY: See http://vanderleevineyard.com/1/category/vinduino/1.html
|
||||
* Built: Davis / Watermark 200SS
|
||||
* Built: Davis / Watermark 200SS
|
||||
* http://www.cooking-hacks.com/watermark-soil-moisture-sensor?_bksrc=item2item&_bkloc=product
|
||||
* http://www.irrometer.com/pdf/supportmaterial/sensors/voltage-WM-chart.pdf
|
||||
* cb (centibar) http://www.irrometer.com/basics.html
|
||||
* 0-10 Saturated Soil. Occurs for a day or two after irrigation
|
||||
* 10-20 Soil is adequately wet (except coarse sands which are drying out at this range)
|
||||
* 30-60 Usual range to irrigate or water (except heavy clay soils).
|
||||
* 60-100 Usual range to irrigate heavy clay soils
|
||||
* 100-200 Soil is becoming dangerously dry for maximum production. Proceed with caution.
|
||||
*
|
||||
* 0-10 Saturated Soil. Occurs for a day or two after irrigation
|
||||
* 10-20 Soil is adequately wet (except coarse sands which are drying out at this range)
|
||||
* 30-60 Usual range to irrigate or water (except heavy clay soils).
|
||||
* 60-100 Usual range to irrigate heavy clay soils
|
||||
* 100-200 Soil is becoming dangerously dry for maximum production. Proceed with caution.
|
||||
*
|
||||
* Connection:
|
||||
* D6, D7: alternative powering to avoid sensor degradation
|
||||
* A0, A1: alternative resistance mesuring
|
||||
*
|
||||
* Based on:
|
||||
* Based on:
|
||||
* "Vinduino" portable soil moisture sensor code V3.00
|
||||
* Date December 31, 2012
|
||||
* Reinier van der Lee and Theodore Kaskalis
|
||||
@@ -61,7 +61,7 @@
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
@@ -74,7 +74,7 @@
|
||||
#define NUM_READS 10 // Number of sensor reads for filtering
|
||||
#define CHILD_ID 0
|
||||
|
||||
MyMessage msg(CHILD_ID, V_LEVEL);
|
||||
MyMessage msg(CHILD_ID, V_LEVEL);
|
||||
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
|
||||
|
||||
long buffer[NUM_READS];
|
||||
@@ -82,8 +82,8 @@ int index;
|
||||
|
||||
/// @brief Structure to be used in percentage and resistance values matrix to be filtered (have to be in pairs)
|
||||
typedef struct {
|
||||
int moisture; //!< Moisture
|
||||
long resistance; //!< Resistance
|
||||
int moisture; //!< Moisture
|
||||
long resistance; //!< Resistance
|
||||
} values;
|
||||
|
||||
const long knownResistor = 4700; // Constant value of known resistor in Ohms
|
||||
@@ -95,24 +95,27 @@ values valueOf[NUM_READS]; // Calculated moisture percentages and resista
|
||||
|
||||
int i; // Simple index variable
|
||||
|
||||
void setup() {
|
||||
// initialize the digital pins as an output.
|
||||
// Pin 6,7 is for sensor 1
|
||||
// initialize the digital pin as an output.
|
||||
// Pin 6 is sense resistor voltage supply 1
|
||||
pinMode(6, OUTPUT);
|
||||
void setup()
|
||||
{
|
||||
// initialize the digital pins as an output.
|
||||
// Pin 6,7 is for sensor 1
|
||||
// initialize the digital pin as an output.
|
||||
// Pin 6 is sense resistor voltage supply 1
|
||||
pinMode(6, OUTPUT);
|
||||
|
||||
// initialize the digital pin as an output.
|
||||
// Pin 7 is sense resistor voltage supply 2
|
||||
pinMode(7, OUTPUT);
|
||||
// initialize the digital pin as an output.
|
||||
// Pin 7 is sense resistor voltage supply 2
|
||||
pinMode(7, OUTPUT);
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
sendSketchInfo("Soil Moisture Sensor Reverse Polarity", "1.0");
|
||||
present(CHILD_ID, S_HUM);
|
||||
void presentation()
|
||||
{
|
||||
sendSketchInfo("Soil Moisture Sensor Reverse Polarity", "1.0");
|
||||
present(CHILD_ID, S_HUM);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop()
|
||||
{
|
||||
|
||||
measure(6,7,1);
|
||||
Serial.print ("\t");
|
||||
@@ -131,59 +134,63 @@ void loop() {
|
||||
Serial.print ("sensor bias compensated value = ");
|
||||
Serial.println (sensor1);
|
||||
Serial.println ();
|
||||
|
||||
|
||||
//send back the values
|
||||
send(msg.set((long int)ceil(sensor1)));
|
||||
// delay until next measurement (msec)
|
||||
sleep(SLEEP_TIME);
|
||||
sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
void measure (int phase_b, int phase_a, int analog_input)
|
||||
{
|
||||
// read sensor, filter, and calculate resistance value
|
||||
// Noise filter: median filter
|
||||
// read sensor, filter, and calculate resistance value
|
||||
// Noise filter: median filter
|
||||
|
||||
for (i=0; i<NUM_READS; i++) {
|
||||
for (i=0; i<NUM_READS; i++) {
|
||||
|
||||
// Read 1 pair of voltage values
|
||||
digitalWrite(phase_a, HIGH); // set the voltage supply on
|
||||
delayMicroseconds(25);
|
||||
supplyVoltage = analogRead(analog_input); // read the supply voltage
|
||||
delayMicroseconds(25);
|
||||
digitalWrite(phase_a, LOW); // set the voltage supply off
|
||||
delay(1);
|
||||
// Read 1 pair of voltage values
|
||||
digitalWrite(phase_a, HIGH); // set the voltage supply on
|
||||
delayMicroseconds(25);
|
||||
supplyVoltage = analogRead(analog_input); // read the supply voltage
|
||||
delayMicroseconds(25);
|
||||
digitalWrite(phase_a, LOW); // set the voltage supply off
|
||||
delay(1);
|
||||
|
||||
digitalWrite(phase_b, HIGH); // set the voltage supply on
|
||||
delayMicroseconds(25);
|
||||
sensorVoltage = analogRead(analog_input); // read the sensor voltage
|
||||
delayMicroseconds(25);
|
||||
digitalWrite(phase_b, LOW); // set the voltage supply off
|
||||
digitalWrite(phase_b, HIGH); // set the voltage supply on
|
||||
delayMicroseconds(25);
|
||||
sensorVoltage = analogRead(analog_input); // read the sensor voltage
|
||||
delayMicroseconds(25);
|
||||
digitalWrite(phase_b, LOW); // set the voltage supply off
|
||||
|
||||
// Calculate resistance
|
||||
// the 0.5 add-term is used to round to the nearest integer
|
||||
// Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction
|
||||
long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ;
|
||||
// Calculate resistance
|
||||
// the 0.5 add-term is used to round to the nearest integer
|
||||
// Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction
|
||||
long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ;
|
||||
|
||||
delay(1);
|
||||
addReading(resistance);
|
||||
Serial.print (resistance);
|
||||
Serial.print ("\t");
|
||||
}
|
||||
delay(1);
|
||||
addReading(resistance);
|
||||
Serial.print (resistance);
|
||||
Serial.print ("\t");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Averaging algorithm
|
||||
void addReading(long resistance){
|
||||
buffer[index] = resistance;
|
||||
index++;
|
||||
if (index >= NUM_READS) index = 0;
|
||||
void addReading(long resistance)
|
||||
{
|
||||
buffer[index] = resistance;
|
||||
index++;
|
||||
if (index >= NUM_READS) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
long average(){
|
||||
long sum = 0;
|
||||
for (int i = 0; i < NUM_READS; i++){
|
||||
sum += buffer[i];
|
||||
}
|
||||
return (long)(sum / NUM_READS);
|
||||
long average()
|
||||
{
|
||||
long sum = 0;
|
||||
for (int i = 0; i < NUM_READS; i++) {
|
||||
sum += buffer[i];
|
||||
}
|
||||
return (long)(sum / NUM_READS);
|
||||
}
|
||||
|
||||
@@ -21,29 +21,29 @@
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - epierre
|
||||
* Contribution: bulldoglowell, gizmocuz
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Arduino UVM-30A
|
||||
* Index table taken from: http://www.elecrow.com/sensors-c-111/environment-c-111_112/uv-sensor-moduleuvm30a-p-716.html
|
||||
* Because this table is pretty lineair, we can calculate a UVI with one decimal
|
||||
* Because this table is pretty lineair, we can calculate a UVI with one decimal
|
||||
*
|
||||
* Connect sensor:
|
||||
*
|
||||
* + >>> 5V
|
||||
* - >>> GND
|
||||
* out >>> A0
|
||||
*
|
||||
* out >>> A0
|
||||
*
|
||||
* License: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define UV_SENSOR_ANALOG_PIN 0
|
||||
|
||||
@@ -53,57 +53,57 @@ unsigned long SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds
|
||||
|
||||
MyMessage uvMsg(CHILD_ID_UV, V_UV);
|
||||
|
||||
unsigned long lastSend =0;
|
||||
unsigned long lastSend =0;
|
||||
float uvIndex;
|
||||
float lastUV = -1;
|
||||
uint16_t uvIndexValue [12] = { 50, 227, 318, 408, 503, 606, 696, 795, 881, 976, 1079, 1170};
|
||||
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("UV Sensor", "1.2");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_UV, S_UV);
|
||||
}
|
||||
|
||||
void loop()
|
||||
void presentation()
|
||||
{
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
uint16_t uv = analogRead(UV_SENSOR_ANALOG_PIN);// Get UV value
|
||||
if (uv>1170)
|
||||
uv=1170;
|
||||
|
||||
//Serial.print("UV Analog reading: ");
|
||||
//Serial.println(uv);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
if (uv <= uvIndexValue[i])
|
||||
{
|
||||
uvIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//calculate 1 decimal if possible
|
||||
if (i>0) {
|
||||
float vRange=uvIndexValue[i]-uvIndexValue[i-1];
|
||||
float vCalc=uv-uvIndexValue[i-1];
|
||||
uvIndex+=(1.0/vRange)*vCalc-1.0;
|
||||
}
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("UV Sensor", "1.2");
|
||||
|
||||
//Serial.print("UVI: ");
|
||||
//Serial.println(uvIndex,2);
|
||||
|
||||
//Send value to gateway if changed, or at least every 5 minutes
|
||||
if ((uvIndex != lastUV)||(currentTime-lastSend >= 5UL*60UL*1000UL)) {
|
||||
lastSend=currentTime;
|
||||
send(uvMsg.set(uvIndex,2));
|
||||
lastUV = uvIndex;
|
||||
}
|
||||
|
||||
sleep(SLEEP_TIME);
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_UV, S_UV);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
uint16_t uv = analogRead(UV_SENSOR_ANALOG_PIN);// Get UV value
|
||||
if (uv>1170) {
|
||||
uv=1170;
|
||||
}
|
||||
|
||||
//Serial.print("UV Analog reading: ");
|
||||
//Serial.println(uv);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 12; i++) {
|
||||
if (uv <= uvIndexValue[i]) {
|
||||
uvIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//calculate 1 decimal if possible
|
||||
if (i>0) {
|
||||
float vRange=uvIndexValue[i]-uvIndexValue[i-1];
|
||||
float vCalc=uv-uvIndexValue[i-1];
|
||||
uvIndex+=(1.0/vRange)*vCalc-1.0;
|
||||
}
|
||||
|
||||
//Serial.print("UVI: ");
|
||||
//Serial.println(uvIndex,2);
|
||||
|
||||
//Send value to gateway if changed, or at least every 5 minutes
|
||||
if ((uvIndex != lastUV)||(currentTime-lastSend >= 5UL*60UL*1000UL)) {
|
||||
lastSend=currentTime;
|
||||
send(uvMsg.set(uvIndex,2));
|
||||
lastUV = uvIndex;
|
||||
}
|
||||
|
||||
sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
@@ -58,40 +58,42 @@ MyMessage vibrationMsg(CHILD_ID_VIBRATION, V_LEVEL);
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(VIBRATION_SENSOR_DIGITAL_PIN, INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(VIBRATION_SENSOR_DIGITAL_PIN), blink, FALLING); // Trigger the blink function when the falling edge is detected
|
||||
pinMode(SensorLED, OUTPUT);
|
||||
pinMode(VIBRATION_SENSOR_DIGITAL_PIN, INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(VIBRATION_SENSOR_DIGITAL_PIN), blink,
|
||||
FALLING); // Trigger the blink function when the falling edge is detected
|
||||
pinMode(SensorLED, OUTPUT);
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("VIBRATION Sensor", "1.0");
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("VIBRATION Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_VIBRATION, S_VIBRATION);
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
present(CHILD_ID_VIBRATION, S_VIBRATION);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if(state>=40){ // basically below 40 so ignire basic level
|
||||
send(vibrationMsg.set(int16_t(state)));
|
||||
state = 0;
|
||||
digitalWrite(SensorLED,HIGH);
|
||||
} else {
|
||||
state = 0;
|
||||
digitalWrite(SensorLED,LOW);
|
||||
}
|
||||
if(state>=40) { // basically below 40 so ignire basic level
|
||||
send(vibrationMsg.set(int16_t(state)));
|
||||
state = 0;
|
||||
digitalWrite(SensorLED,HIGH);
|
||||
} else {
|
||||
state = 0;
|
||||
digitalWrite(SensorLED,LOW);
|
||||
}
|
||||
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
|
||||
sleep(SLEEP_TIME); //sleep for: sleepTime
|
||||
sleep(SLEEP_TIME); //sleep for: sleepTime
|
||||
}
|
||||
|
||||
void blink()//Interrupts function
|
||||
{
|
||||
state++;
|
||||
state++;
|
||||
}
|
||||
|
||||
@@ -21,27 +21,27 @@
|
||||
* REVISION HISTORY
|
||||
* Version 1.0 - Henrik Ekblad
|
||||
* Version 1.1 - GizMoCuz
|
||||
*
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Use this sensor to measure volume and flow of your house watermeter.
|
||||
* You need to set the correct pulsefactor of your meter (pulses per m3).
|
||||
* The sensor starts by fetching current volume reading from gateway (VAR 1).
|
||||
* Reports both volume and flow back to gateway.
|
||||
*
|
||||
* Unfortunately millis() won't increment when the Arduino is in
|
||||
* sleepmode. So we cannot make this sensor sleep if we also want
|
||||
* Unfortunately millis() won't increment when the Arduino is in
|
||||
* sleepmode. So we cannot make this sensor sleep if we also want
|
||||
* to calculate/report flow.
|
||||
* http://www.mysensors.org/build/pulse_water
|
||||
*/
|
||||
|
||||
// Enable debug prints to serial monitor
|
||||
#define MY_DEBUG
|
||||
#define MY_DEBUG
|
||||
|
||||
// Enable and select radio type attached
|
||||
#define MY_RADIO_NRF24
|
||||
//#define MY_RADIO_RFM69
|
||||
|
||||
#include <MySensors.h>
|
||||
#include <MySensors.h>
|
||||
|
||||
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
|
||||
#define CHILD_ID 1 // Id of the sensor child
|
||||
|
||||
unsigned long SEND_FREQUENCY = 30000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
|
||||
unsigned long SEND_FREQUENCY =
|
||||
30000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
|
||||
|
||||
MyMessage flowMsg(CHILD_ID,V_FLOW);
|
||||
MyMessage volumeMsg(CHILD_ID,V_VOLUME);
|
||||
@@ -61,127 +62,126 @@ MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
|
||||
|
||||
double ppl = ((double)PULSE_FACTOR)/1000; // Pulses per liter
|
||||
|
||||
volatile unsigned long pulseCount = 0;
|
||||
volatile unsigned long pulseCount = 0;
|
||||
volatile unsigned long lastBlink = 0;
|
||||
volatile double flow = 0;
|
||||
volatile double flow = 0;
|
||||
bool pcReceived = false;
|
||||
unsigned long oldPulseCount = 0;
|
||||
unsigned long newBlink = 0;
|
||||
unsigned long newBlink = 0;
|
||||
double oldflow = 0;
|
||||
double volume =0;
|
||||
double volume =0;
|
||||
double oldvolume =0;
|
||||
unsigned long lastSend =0;
|
||||
unsigned long lastPulse =0;
|
||||
|
||||
void setup()
|
||||
{
|
||||
// initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
|
||||
|
||||
pulseCount = oldPulseCount = 0;
|
||||
|
||||
// Fetch last known pulse count value from gw
|
||||
request(CHILD_ID, V_VAR1);
|
||||
|
||||
lastSend = lastPulse = millis();
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, FALLING);
|
||||
}
|
||||
|
||||
void presentation() {
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Water Meter", "1.1");
|
||||
|
||||
// Register this device as Waterflow sensor
|
||||
present(CHILD_ID, S_WATER);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
// Only send values at a maximum frequency or woken up from sleep
|
||||
if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY))
|
||||
{
|
||||
lastSend=currentTime;
|
||||
|
||||
if (!pcReceived) {
|
||||
//Last Pulsecount not yet received from controller, request it again
|
||||
request(CHILD_ID, V_VAR1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SLEEP_MODE && flow != oldflow) {
|
||||
oldflow = flow;
|
||||
|
||||
Serial.print("l/min:");
|
||||
Serial.println(flow);
|
||||
|
||||
// Check that we dont get unresonable large flow value.
|
||||
// could hapen when long wraps or false interrupt triggered
|
||||
if (flow<((unsigned long)MAX_FLOW)) {
|
||||
send(flowMsg.set(flow, 2)); // Send flow value to gw
|
||||
}
|
||||
}
|
||||
|
||||
// No Pulse count received in 2min
|
||||
if(currentTime - lastPulse > 120000){
|
||||
flow = 0;
|
||||
}
|
||||
|
||||
// Pulse count has changed
|
||||
if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
|
||||
oldPulseCount = pulseCount;
|
||||
|
||||
Serial.print("pulsecount:");
|
||||
Serial.println(pulseCount);
|
||||
|
||||
send(lastCounterMsg.set(pulseCount)); // Send pulsecount value to gw in VAR1
|
||||
|
||||
double volume = ((double)pulseCount/((double)PULSE_FACTOR));
|
||||
if ((volume != oldvolume)||(!SLEEP_MODE)) {
|
||||
oldvolume = volume;
|
||||
|
||||
Serial.print("volume:");
|
||||
Serial.println(volume, 3);
|
||||
|
||||
send(volumeMsg.set(volume, 3)); // Send volume value to gw
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SLEEP_MODE) {
|
||||
sleep(SEND_FREQUENCY);
|
||||
}
|
||||
}
|
||||
|
||||
void receive(const MyMessage &message) {
|
||||
if (message.type==V_VAR1) {
|
||||
unsigned long gwPulseCount=message.getULong();
|
||||
pulseCount += gwPulseCount;
|
||||
flow=oldflow=0;
|
||||
Serial.print("Received last pulse count from gw:");
|
||||
Serial.println(pulseCount);
|
||||
pcReceived = true;
|
||||
}
|
||||
}
|
||||
|
||||
void onPulse()
|
||||
void setup()
|
||||
{
|
||||
if (!SLEEP_MODE)
|
||||
{
|
||||
unsigned long newBlink = micros();
|
||||
unsigned long interval = newBlink-lastBlink;
|
||||
|
||||
if (interval!=0)
|
||||
{
|
||||
lastPulse = millis();
|
||||
if (interval<500000L) {
|
||||
// Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min)
|
||||
return;
|
||||
}
|
||||
flow = (60000000.0 /interval) / ppl;
|
||||
}
|
||||
lastBlink = newBlink;
|
||||
}
|
||||
pulseCount++;
|
||||
// initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion)
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);
|
||||
|
||||
pulseCount = oldPulseCount = 0;
|
||||
|
||||
// Fetch last known pulse count value from gw
|
||||
request(CHILD_ID, V_VAR1);
|
||||
|
||||
lastSend = lastPulse = millis();
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, FALLING);
|
||||
}
|
||||
|
||||
void presentation()
|
||||
{
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
sendSketchInfo("Water Meter", "1.1");
|
||||
|
||||
// Register this device as Waterflow sensor
|
||||
present(CHILD_ID, S_WATER);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long currentTime = millis();
|
||||
|
||||
// Only send values at a maximum frequency or woken up from sleep
|
||||
if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY)) {
|
||||
lastSend=currentTime;
|
||||
|
||||
if (!pcReceived) {
|
||||
//Last Pulsecount not yet received from controller, request it again
|
||||
request(CHILD_ID, V_VAR1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SLEEP_MODE && flow != oldflow) {
|
||||
oldflow = flow;
|
||||
|
||||
Serial.print("l/min:");
|
||||
Serial.println(flow);
|
||||
|
||||
// Check that we dont get unresonable large flow value.
|
||||
// could hapen when long wraps or false interrupt triggered
|
||||
if (flow<((unsigned long)MAX_FLOW)) {
|
||||
send(flowMsg.set(flow, 2)); // Send flow value to gw
|
||||
}
|
||||
}
|
||||
|
||||
// No Pulse count received in 2min
|
||||
if(currentTime - lastPulse > 120000) {
|
||||
flow = 0;
|
||||
}
|
||||
|
||||
// Pulse count has changed
|
||||
if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) {
|
||||
oldPulseCount = pulseCount;
|
||||
|
||||
Serial.print("pulsecount:");
|
||||
Serial.println(pulseCount);
|
||||
|
||||
send(lastCounterMsg.set(pulseCount)); // Send pulsecount value to gw in VAR1
|
||||
|
||||
double volume = ((double)pulseCount/((double)PULSE_FACTOR));
|
||||
if ((volume != oldvolume)||(!SLEEP_MODE)) {
|
||||
oldvolume = volume;
|
||||
|
||||
Serial.print("volume:");
|
||||
Serial.println(volume, 3);
|
||||
|
||||
send(volumeMsg.set(volume, 3)); // Send volume value to gw
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SLEEP_MODE) {
|
||||
sleep(SEND_FREQUENCY);
|
||||
}
|
||||
}
|
||||
|
||||
void receive(const MyMessage &message)
|
||||
{
|
||||
if (message.type==V_VAR1) {
|
||||
unsigned long gwPulseCount=message.getULong();
|
||||
pulseCount += gwPulseCount;
|
||||
flow=oldflow=0;
|
||||
Serial.print("Received last pulse count from gw:");
|
||||
Serial.println(pulseCount);
|
||||
pcReceived = true;
|
||||
}
|
||||
}
|
||||
|
||||
void onPulse()
|
||||
{
|
||||
if (!SLEEP_MODE) {
|
||||
unsigned long newBlink = micros();
|
||||
unsigned long interval = newBlink-lastBlink;
|
||||
|
||||
if (interval!=0) {
|
||||
lastPulse = millis();
|
||||
if (interval<500000L) {
|
||||
// Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min)
|
||||
return;
|
||||
}
|
||||
flow = (60000000.0 /interval) / ppl;
|
||||
}
|
||||
lastBlink = newBlink;
|
||||
}
|
||||
pulseCount++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user