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:
Patrick Fallberg
2016-12-07 23:44:29 +01:00
committed by GitHub
parent d4c4ab82ea
commit 8e1ef13804
167 changed files with 16103 additions and 15168 deletions
+68 -66
View File
@@ -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);
}
+37 -33
View File
@@ -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 );
}
}
+70 -74
View File
@@ -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));
}
}
+37 -35
View File
@@ -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);
}
+72 -71
View File
@@ -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++;
}
+9 -6
View File
@@ -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();
}
+46 -43
View File
@@ -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
}
+9 -8
View File
@@ -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
}
+19 -18
View File
@@ -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 -19
View File
@@ -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);
}
+19 -17
View File
@@ -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);
}
+20 -18
View File
@@ -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
+61 -53
View File
@@ -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";
}
+47 -44
View File
@@ -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());
}
}
+13 -12
View File
@@ -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()
{
}
+311 -282
View File
@@ -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());
}
}
+33 -31
View File
@@ -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
+11 -11
View File
@@ -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;
}
+70 -63
View File
@@ -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);
}
+52 -52
View File
@@ -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);
}
+23 -21
View File
@@ -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++;
}