gatewayTransportSend

This commit is contained in:
Dmitry Borisenko
2022-12-01 02:10:06 +01:00
parent 2c61580157
commit cb50965c3b
293 changed files with 67232 additions and 3 deletions

View File

@@ -0,0 +1,219 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* Connect the MQ2 sensor as follows :
*
* A H A >>> 5V
* B >>> A0
* H >>> GND
* B >>> 10K ohm >>> GND
*
* Contribution: epierre
* Based on http://sandboxelectronics.com/?p=165
* License: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
* Modified by HEK to work in 1.4
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID_MQ 0
/************************Hardware Related Macros************************************/
#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
/***********************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 interval(in milliseconds) between each samples in the
//calibration 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 interval(in milliseconds) between each samples in
//normal operation
/**********************Application Related Macros**********************************/
#define GAS_LPG (0)
#define GAS_CO (1)
#define GAS_SMOKE (2)
/*****************************Globals***********************************************/
uint32_t SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
//VARIABLES
float Ro = 10000.0; // this has to be tuned 10K Ohm
int val = 0; // variable to store the value coming from the sensor
uint16_t lastMQ = 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)
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)
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
}
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);
}
void loop()
{
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");
if (valMQ != lastMQ) {
send(msg.set((int16_t)ceil(valMQ)));
lastMQ = ceil(valMQ);
}
sleep(SLEEP_TIME); //sleep for: sleepTime
}
/****************** MQResistanceCalculation ****************************************
Input: raw_adc - raw value read from adc, which represents the voltage
Output: the calculated sensor resistance
Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
across the load resistor and its resistance, the resistance of the sensor
could be derived.
************************************************************************************/
float MQResistanceCalculation(int raw_adc)
{
return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}
/***************************** MQCalibration ****************************************
Input: mq_pin - analog channel
Output: Ro of the sensor
Remarks: This function assumes that the sensor is in clean air. It use
MQResistanceCalculation to calculates the sensor resistance in clean air
and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
10, which differs slightly between different sensors.
************************************************************************************/
float MQCalibration(int mq_pin)
{
int i;
float inVal=0;
for (i=0; i<CALIBARAION_SAMPLE_TIMES; i++) { //take multiple samples
inVal += MQResistanceCalculation(analogRead(mq_pin));
delay(CALIBRATION_SAMPLE_INTERVAL);
}
inVal = inVal/CALIBARAION_SAMPLE_TIMES; //calculate the average value
inVal = inVal/RO_CLEAN_AIR_FACTOR; //divided by RO_CLEAN_AIR_FACTOR yields the Ro
//according to the chart in the datasheet
return inVal;
}
/***************************** MQRead *********************************************
Input: mq_pin - analog channel
Output: Rs of the sensor
Remarks: This function use MQResistanceCalculation to calculate the sensor resistance (Rs).
The Rs changes as the sensor is in the different concentration of the target
gas. The sample times and the time interval between samples could be configured
by changing the definition of the macros.
************************************************************************************/
float MQRead(int mq_pin)
{
int i;
float rs=0;
for (i=0; i<READ_SAMPLE_TIMES; i++) {
rs += MQResistanceCalculation(analogRead(mq_pin));
delay(READ_SAMPLE_INTERVAL);
}
rs = rs/READ_SAMPLE_TIMES;
return rs;
}
/***************************** MQGetGasPercentage **********************************
Input: rs_ro_ratio - Rs divided by Ro
gas_id - target gas type
Output: ppm of the target gas
Remarks: This function passes different curves to the MQGetPercentage function which
calculates the ppm (parts per million) of the target gas.
************************************************************************************/
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);
}
return 0;
}
/***************************** MQGetPercentage **********************************
Input: rs_ro_ratio - Rs divided by Ro
pcurve - pointer to the curve of the target gas
Output: ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
of the line could be derived if y(rs_ro_ratio) is provided. As it is a
logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
value.
************************************************************************************/
int MQGetPercentage(float rs_ro_ratio, float *pcurve)
{
return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}

View File

@@ -0,0 +1,95 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* 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
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
uint32_t SLEEP_TIME = 900000; // sleep time between reads (seconds * 1000 milliseconds)
int oldBatteryPcnt = 0;
void setup()
{
// use the 1.1 V internal reference
#if defined(__AVR_ATmega2560__)
analogReference(INTERNAL1V1);
#else
analogReference(INTERNAL);
#endif
}
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;
#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);
}

View File

@@ -0,0 +1,119 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* Interrupt driven binary switch example with dual interrupts
* Author: Patrick 'Anticimex' Fallberg
* Connect one button or door/window reed switch between
* digital I/O pin 3 (BUTTON_PIN below) and GND and the other
* one in similar fashion on digital I/O pin 2.
* This example is designed to fit Arduino Nano/Pro Mini
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define SKETCH_NAME "Binary Sensor"
#define SKETCH_MAJOR_VER "1"
#define SKETCH_MINOR_VER "0"
#define PRIMARY_CHILD_ID 3
#define SECONDARY_CHILD_ID 4
#define PRIMARY_BUTTON_PIN 2 // Arduino Digital I/O pin for button/reed switch
#define SECONDARY_BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch
#if (PRIMARY_BUTTON_PIN < 2 || PRIMARY_BUTTON_PIN > 3)
#error PRIMARY_BUTTON_PIN must be either 2 or 3 for interrupts to work
#endif
#if (SECONDARY_BUTTON_PIN < 2 || SECONDARY_BUTTON_PIN > 3)
#error SECONDARY_BUTTON_PIN must be either 2 or 3 for interrupts to work
#endif
#if (PRIMARY_BUTTON_PIN == SECONDARY_BUTTON_PIN)
#error PRIMARY_BUTTON_PIN and BUTTON_PIN2 cannot be the same
#endif
#if (PRIMARY_CHILD_ID == SECONDARY_CHILD_ID)
#error PRIMARY_CHILD_ID and SECONDARY_CHILD_ID cannot be the same
#endif
// Change to V_LIGHT if you use S_LIGHT in presentation below
MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED);
MyMessage msg2(SECONDARY_CHILD_ID, V_TRIPPED);
void setup()
{
// Setup the buttons
pinMode(PRIMARY_BUTTON_PIN, INPUT_PULLUP);
pinMode(SECONDARY_BUTTON_PIN, INPUT_PULLUP);
}
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);
}
// Loop will iterate on changes on the BUTTON_PINs
void loop()
{
uint8_t value;
static uint8_t sentValue=2;
static uint8_t sentValue2=2;
// Short delay to allow buttons to properly settle
sleep(5);
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;
}
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;
}
// Sleep until something happens with the sensor
sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SECONDARY_BUTTON_PIN-2, CHANGE, 0);
}

View File

@@ -0,0 +1,107 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* MH-Z14 CO2 sensor
*
* Wiring:
* 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
* MH-Z14 has a PWM output, with a sensitivity range of 0ppm to 2000ppm CO2, an accuracy of ±200ppm.
* The cycle is 1004ms±5%, given the duty cicle Th (pulse high), Tl is 1004-Th, we can convert it to CO2 value using the formula:
* CO2ppm = 2000 * (Th - 2ms) /(Th + Tl - 4ms)
* From: http://airqualityegg.wikispaces.com/Sensor+Tests
* - response time is less than 30 s
* - 3 minute warm up time
* datasheet: http://www.futurlec.com/Datasheet/Sensor/MH-Z14.pdf
* Contributor: epierre
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID_AIQ 0
#define AIQ_SENSOR_ANALOG_PIN 6
uint32_t SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
float valAIQ =0.0;
float lastAIQ =0.0;
MyMessage msg(CHILD_ID_AIQ, V_LEVEL);
MyMessage msg2(CHILD_ID_AIQ, V_UNIT_PREFIX);
void setup()
{
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");
// 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()
{
//uint32_t 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
uint32_t 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((int32_t)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
}

View File

@@ -0,0 +1,44 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* 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>
void setup()
{
Serial.begin(MY_BAUD_RATE);
Serial.println("Started clearing. Please wait...");
for (uint16_t i=0; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) {
hwWriteConfig(i,0xFF);
}
Serial.println("Clearing done.");
}
void loop()
{
// Nothing to do here...
}

View File

@@ -0,0 +1,130 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - February 15, 2014 - Bruce Lacey
* Version 1.1 - August 13, 2014 - Converted to 1.4 (hek)
*
* DESCRIPTION
* This sketch provides a Dimmable LED Light using PWM and based Henrik Ekblad
* <henrik.ekblad@gmail.com> Vera Arduino Sensor project.
* Developed by Bruce Lacey, inspired by Hek's MySensor's example sketches.
*
* The circuit uses a MOSFET for Pulse-Wave-Modulation to dim the attached LED or LED strip.
* The MOSFET Gate pin is connected to Arduino pin 3 (LED_PIN), the MOSFET Drain pin is connected
* to the LED negative terminal and the MOSFET Source pin is connected to ground.
*
* This sketch is extensible to support more than one MOSFET/PWM dimmer per circuit.
* http://www.mysensors.org/build/dimmer
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define SN "DimmableLED"
#define SV "1.1"
#define LED_PIN 3 // Arduino pin attached to MOSFET Gate pin
#define FADE_DELAY 10 // Delay in ms for each percentage fade up/down (10ms = 1s full-range dim)
static int16_t currentLevel = 0; // Current dim level...
MyMessage dimmerMsg(0, V_DIMMER);
MyMessage lightMsg(0, V_LIGHT);
/***
* Dimmable LED initialization method
*/
void setup()
{
// Pull the gateway's current dim level - restore light level upon node power-up
request( 0, V_DIMMER );
}
void presentation()
{
// Register the LED Dimmable Light with the gateway
present( 0, S_DIMMER );
sendSketchInfo(SN, SV);
}
/***
* Dimmable LED main processing loop
*/
void loop()
{
}
void receive(const MyMessage &message)
{
if (message.getType() == V_LIGHT || message.getType() == V_DIMMER) {
// 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.getType() == V_LIGHT ? 100 : 1 );
// 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 );
fadeToLevel( requestedLevel );
// 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) );
}
}
/***
* This method provides a graceful fade up/down effect
*/
void fadeToLevel( int toLevel )
{
int delta = ( toLevel - currentLevel ) < 0 ? -1 : 1;
while ( currentLevel != toLevel ) {
currentLevel += delta;
analogWrite( LED_PIN, (int)(currentLevel / 100. * 255) );
delay( FADE_DELAY );
}
}

View File

@@ -0,0 +1,158 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - January 30, 2015 - Developed by GizMoCuz (Domoticz)
*
* DESCRIPTION
* This sketch provides an example how to implement a Dimmable Light
* It is pure virtual and it logs messages to the serial output
* It can be used as a base sketch for actual hardware.
* Stores the last light state and level in eeprom.
*
*/
// Enable debug prints
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID_LIGHT 1
#define EPROM_LIGHT_STATE 1
#define EPROM_DIMMER_LEVEL 2
#define LIGHT_OFF 0
#define LIGHT_ON 1
#define SN "Dimmable Light"
#define SV "1.0"
int16_t LastLightState=LIGHT_OFF;
int16_t LastDimValue=100;
MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT);
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;
}
}
//Here you actually switch on/off the light with the last known dim level
SetCurrentState2Hardware();
Serial.println( "Node ready to receive messages..." );
}
void presentation()
{
// Send the Sketch Version Information to the Gateway
sendSketchInfo(SN, SV);
present(CHILD_ID_LIGHT, S_DIMMER );
}
void loop()
{
}
void receive(const MyMessage &message)
{
if (message.getType() == 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);
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.getType() == 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();
}
void SetCurrentState2Hardware()
{
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();
}
void SendCurrentState2Controller()
{
if ((LastLightState==LIGHT_OFF)||(LastDimValue==0)) {
send(dimmerMsg.set((int16_t)0));
} else {
send(dimmerMsg.set(LastDimValue));
}
}

View File

@@ -0,0 +1,104 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* 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
* Authors: Cyrille Médard de Chardon (serialC), Christophe Trefois (Trefex)
*
* http://www.mysensors.org/build/dust
*
*/
// Enable debug prints
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID_DUST 0
#define DUST_SENSOR_ANALOG_PIN 1
uint32_t SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
//VARIABLES
int val = 0; // variable to store the value coming from the sensor
float valDUST =0.0;
float lastDUST =0.0;
int samplingTime = 280;
int deltaTime = 40;
int sleepTime = 9680;
float calcVoltage = 0;
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");
// 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
// 0 - 5V mapped to 0 - 1023 integer values
// recover voltage
calcVoltage = voMeasured * (5.0 / 1024.0);
// linear equation 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);
}

View File

@@ -0,0 +1,151 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* 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 5 of dust sensor -> Ground
* Datasheet: http://www.samyoungsnc.com/products/3-1%20Specification%20DSM501.pdf
* Contributor: epierre
**/
// Enable debug prints
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID_DUST_PM10 0
#define CHILD_ID_DUST_PM25 1
#define DUST_SENSOR_DIGITAL_PIN_PM10 6
#define DUST_SENSOR_DIGITAL_PIN_PM25 3
uint32_t SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
//VARIABLES
int val = 0; // variable to store the value coming from the sensor
float valDUSTPM25 =0.0;
float lastDUSTPM25 =0.0;
float valDUSTPM10 =0.0;
float lastDUSTPM10 =0.0;
uint32_t duration;
uint32_t starttime;
uint32_t endtime;
uint32_t sampletime_ms = 30000;
uint32_t lowpulseoccupancy = 0;
float ratio = 0;
long concentrationPM25 = 0;
long concentrationPM10 = 0;
MyMessage dustMsgPM10(CHILD_ID_DUST_PM10, V_LEVEL);
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()
{
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");
// 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()
{
//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((int32_t)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((int32_t)ppmv));
lastDUSTPM10 = ceil(concentrationPM10);
}
//sleep to save on radio
sleep(SLEEP_TIME);
}
long getPM(int DUST_SENSOR_DIGITAL_PIN)
{
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);
}
}
}

View File

@@ -0,0 +1,169 @@
/*
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-2019 Sensnology AB
Full contributor list: https://github.com/mysensors/MySensors/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.
*******************************
REVISION HISTORY
Version 1.0 - Henrik Ekblad
Version 1.1 - Peter Andersson added millis watt calculation if time between pulses > 1h
DESCRIPTION
This sketch provides an example how to implement a LM393 PCB
Use this sensor to measure kWh and Watt of your house meter
You need to set the correct pulsefactor of your meter (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
to calculate/report watt value.
http://www.mysensors.org/build/pulse_power
*/
// Enable debug prints
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#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 // Number of blinks per kWh of your meter. Normally 1000.
#define SLEEP_MODE false // Watt value can only be reported when sleep mode is false.
#define MAX_WATT 10000 // Max watt value to report. This filters outliers.
#define CHILD_ID 1 // Id of the sensor child
uint32_t SEND_FREQUENCY =
20000; // Minimum time between send (in milliseconds). We don't want to spam the gateway.
double ppwh = ((double)PULSE_FACTOR) / 1000; // Pulses per watt hour
bool pcReceived = false;
volatile uint32_t pulseCount = 0;
volatile uint32_t lastBlinkmicros = 0;
volatile uint32_t lastBlinkmillis = 0;
volatile uint32_t watt = 0;
uint32_t oldPulseCount = 0;
uint32_t oldWatt = 0;
double oldkWh;
uint32_t lastSend;
MyMessage wattMsg(CHILD_ID, V_WATT);
MyMessage kWhMsg(CHILD_ID, V_KWH);
MyMessage pcMsg(CHILD_ID, V_VAR1);
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
#define IRQ_HANDLER_ATTR ICACHE_RAM_ATTR
#else
#define IRQ_HANDLER_ATTR
#endif
void IRQ_HANDLER_ATTR onPulse()
{
if (!SLEEP_MODE) {
uint32_t newBlinkmicros = micros();
uint32_t newBlinkmillis = millis();
uint32_t intervalmicros = newBlinkmicros - lastBlinkmicros;
uint32_t intervalmillis = newBlinkmillis - lastBlinkmillis;
if (intervalmicros < 10000L && intervalmillis < 10L) { // Sometimes we get interrupt on RISING
return;
}
if (intervalmillis < 360000) { // Less than an hour since last pulse, use microseconds
watt = (3600000000.0 / intervalmicros) / ppwh;
} else {
watt = (3600000.0 / intervalmillis) /
ppwh; // more thAn an hour since last pulse, use milliseconds as micros will overflow after 70min
}
lastBlinkmicros = newBlinkmicros;
lastBlinkmillis = newBlinkmillis;
}
pulseCount++;
}
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);
attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, RISING);
lastSend = millis();
}
void presentation()
{
// Send the sketch version information to the gateway and Controller
sendSketchInfo(F("Energy Meter"), F("1.1"));
// Register this device as power sensor
present(CHILD_ID, S_POWER);
}
void loop()
{
uint32_t 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 don't get unreasonable large watt value, which
// could happen when long wraps or false interrupt triggered
if (watt < ((uint32_t)MAX_WATT)) {
send(wattMsg.set(watt)); // Send watt value to gw
}
Serial.print("Watt:");
Serial.println(watt);
oldWatt = watt;
}
// Pulse count value 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 pulse count value received from controller. Try requesting it again.
request(CHILD_ID, V_VAR1);
lastSend = now;
}
if (SLEEP_MODE) {
sleep(SEND_FREQUENCY, false);
}
}
void receive(const MyMessage &message)
{
if (message.getType()==V_VAR1) {
pulseCount = oldPulseCount = message.getLong();
Serial.print("Received last pulse count value from gw:");
Serial.println(pulseCount);
pcReceived = true;
}
}

View File

@@ -0,0 +1,84 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - tekka
*
* DESCRIPTION
* The ESP32 gateway sends data received from sensors to the WiFi link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
*
* Make sure to fill in your ssid and WiFi password below.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_ESP32
#define MY_WIFI_SSID "MySSID"
#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Enable UDP communication
//#define MY_USE_UDP // If using UDP you need to set MY_CONTROLLER_IP_ADDRESS or MY_CONTROLLER_URL_ADDRESS below
// Set the hostname for the WiFi Client. This is the hostname
// passed to the DHCP server if not static.
#define MY_HOSTNAME "ESP32_GW"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,1,100
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,1,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// The port to keep open on node server mode
#define MY_PORT 5003
// How many clients should be able to connect to this gateway (default 1)
#define MY_GATEWAY_MAX_CLIENTS 2
// Controller ip address. Enables client mode (default is "server" mode).
// Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68
//#define MY_CONTROLLER_URL_ADDRESS "my.controller.org"
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
}

View File

@@ -0,0 +1,90 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - tekka
*
* DESCRIPTION
* The ESP32 gateway sends data received from sensors to the WiFi link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
*
* Make sure to fill in your ssid and WiFi password below.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_MQTT_CLIENT
#define MY_GATEWAY_ESP32
// Set this node's subscribe and publish topic prefix
#define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out"
#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in"
// Set MQTT client id
#define MY_MQTT_CLIENT_ID "mysensors-1"
// Enable these if your MQTT broker requires usenrame/password
//#define MY_MQTT_USER "username"
//#define MY_MQTT_PASSWORD "password"
// Set WIFI SSID and password
#define MY_WIFI_SSID "MySSID"
#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Set the hostname for the WiFi Client. This is the hostname
// passed to the DHCP server if not static.
#define MY_HOSTNAME "ESP32_MQTT_GW"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,178,87
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// MQTT broker ip address.
#define MY_CONTROLLER_IP_ADDRESS 192, 168, 1, 5
// The MQTT broker port to to open
#define MY_PORT 1883
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attech sensors data here
}

View File

@@ -0,0 +1,120 @@
/**
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-2019 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.
*******************************
REVISION HISTORY
Version 1.0 - tekka
Contribution by Berk
DESCRIPTION
The ESP32 gateway sends data received from sensors to the WiFi link.
The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
Make sure to fill in your ssid and WiFi password below.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_ESP32
#define MY_WIFI_SSID "MySSID"
#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Set the hostname for the WiFi Client. This is the hostname
// passed to the DHCP server if not static.
#define MY_HOSTNAME "ESP32_GW"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,1,100
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,1,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// The port to keep open on node server mode
#define MY_PORT 5003
// How many clients should be able to connect to this gateway (default 1)
#define MY_GATEWAY_MAX_CLIENTS 2// Set blinking period
// Advanced Gateway Options
//#define MY_DEFAULT_LED_BLINK_PERIOD 50
// Flash leds on rx/tx/err
// Led pins used if blinking feature is enabled above
//#define MY_DEFAULT_ERR_LED_PIN 32 // Transfer data error led pin
//#define MY_DEFAULT_RX_LED_PIN 25 // Receive Data led pin
//#define MY_DEFAULT_TX_LED_PIN 27 // Transmit Data led pin
//#define MY_WITH_LEDS_BLINKING_INVERSE // At the time of Error, Receive, Transmit the pin is at a high level
#include <ArduinoOTA.h>
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
ArduinoOTA.onStart([]() {
Serial.println("Start updating");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd updating");
});
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();
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
ArduinoOTA.handle();
}

View File

@@ -0,0 +1,130 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
* Contribution by a-lurker and Anticimex,
* Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
* Contribution by Ivo Pullens (ESP8266 support)
*
* DESCRIPTION
* The EthernetGateway sends data received from sensors to the WiFi link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
*
* VERA CONFIGURATION:
* Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin.
* E.g. If you want to use the default values in this sketch enter: 192.168.178.66:5003
*
* LED purposes:
* - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs in your sketch, only the LEDs that is defined is used.
* - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
* See https://www.mysensors.org/build/connect_radio for wiring instructions.
*
* If you are using a "barebone" ESP8266, see
* https://www.mysensors.org/build/esp8266_gateway#wiring-for-barebone-esp8266
*
* Inclusion mode button:
* - Connect GPIO5 (=D1) via switch to GND ('inclusion switch')
*
* Hardware SHA204 signing is currently not supported!
*
* Make sure to fill in your ssid and WiFi password below for ssid & pass.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
#define MY_BAUD_RATE 9600
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_ESP8266
#define MY_WIFI_SSID "MySSID"
#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Enable UDP communication
//#define MY_USE_UDP // If using UDP you need to set MY_CONTROLLER_IP_ADDRESS or MY_CONTROLLER_URL_ADDRESS below
// Set the hostname for the WiFi Client. This is the hostname
// it will pass to the DHCP server if not static.
#define MY_HOSTNAME "ESP8266_GW"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,178,87
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// The port to keep open on node server mode
#define MY_PORT 5003
// How many clients should be able to connect to this gateway (default 1)
#define MY_GATEWAY_MAX_CLIENTS 2
// Controller ip address. Enables client mode (default is "server" mode).
// Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68
//#define MY_CONTROLLER_URL_ADDRESS "my.controller.org"
// Enable inclusion mode
//#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
//#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN D1
// Set blinking period
//#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
// Led pins used if blinking feature is enabled above
//#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
}

View File

@@ -0,0 +1,129 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
*
* DESCRIPTION
* The ESP8266 MQTT gateway sends radio network (or locally attached sensors) data to your MQTT broker.
* The node also listens to MY_MQTT_TOPIC_PREFIX and sends out those messages to the radio network
*
* LED purposes:
* - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs in your sketch
* - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
* See https://www.mysensors.org/build/connect_radio for wiring instructions.
*
* If you are using a "barebone" ESP8266, see
* https://www.mysensors.org/build/esp8266_gateway#wiring-for-barebone-esp8266
*
* Inclusion mode button:
* - Connect GPIO5 (=D1) via switch to GND ('inclusion switch')
*
* Hardware SHA204 signing is currently not supported!
*
* Make sure to fill in your ssid and WiFi password below for ssid & pass.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
#define MY_BAUD_RATE 9600
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_MQTT_CLIENT
#define MY_GATEWAY_ESP8266
// Set this node's subscribe and publish topic prefix
#define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out"
#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in"
// Set MQTT client id
#define MY_MQTT_CLIENT_ID "mysensors-1"
// Enable these if your MQTT broker requires username/password
//#define MY_MQTT_USER "username"
//#define MY_MQTT_PASSWORD "password"
// Set WIFI SSID and password
#define MY_WIFI_SSID "MySSID"
#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Set the hostname for the WiFi Client. This is the hostname
// passed to the DHCP server if not static.
#define MY_HOSTNAME "ESP8266_MQTT_GW"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,178,87
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// MQTT broker ip address.
#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68
//MQTT broker if using URL instead of ip address.
// #define MY_CONTROLLER_URL_ADDRESS "test.mosquitto.org"
// 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
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
//#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN D1
// Set blinking period
//#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
//#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
}

View File

@@ -0,0 +1,156 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
* Contribution by tekka,
* Contribution by a-lurker and Anticimex,
* Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
* Contribution by Ivo Pullens (ESP8266 support)
*
* DESCRIPTION
* The EthernetGateway sends data received from sensors to the WiFi link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
*
* VERA CONFIGURATION:
* Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin.
* E.g. If you want to use the default values in this sketch enter: 192.168.178.66:5003
*
* LED purposes:
* - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h
* - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
* See https://www.mysensors.org/build/connect_radio for wiring instructions.
*
* If you are using a "barebone" ESP8266, see
* https://www.mysensors.org/build/esp8266_gateway#wiring-for-barebone-esp8266
*
* Inclusion mode button:
* - Connect GPIO5 via switch to GND ('inclusion switch')
*
* Hardware SHA204 signing is currently not supported!
*
* Make sure to fill in your ssid and WiFi password below for ssid & pass.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
#define MY_BAUD_RATE 9600
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_ESP8266
#define MY_WIFI_SSID "MySSID"
#define MY_WIFI_PASSWORD "MyVerySecretPassword"
// Set the hostname for the WiFi Client. This is the hostname
// passed to the DHCP server if not static.
#define MY_HOSTNAME "ESP8266_GW"
// Enable UDP communication
//#define MY_USE_UDP // If using UDP you need to set MY_CONTROLLER_IP_ADDRESS below
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,178,87
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// The port to keep open on node server mode
#define MY_PORT 5003
// How many clients should be able to connect to this gateway (default 1)
#define MY_GATEWAY_MAX_CLIENTS 2
// Controller ip address. Enables client mode (default is "server" mode).
// Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
// #define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
// Led pins used if blinking feature is enabled above
#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin
#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin
#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
#include <ArduinoOTA.h>
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
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();
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
ArduinoOTA.handle();
}

View File

@@ -0,0 +1,137 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Rait Lotamõis
*
* DESCRIPTION
* The TinyGSM MQTT gateway sends radio network (or locally attached sensors) data to your MQTT broker using a GSM modem or optionally an ESP8266 as a WiFi modem.
* The node also listens to MY_MQTT_TOPIC_PREFIX and sends out those messages to the radio network
*
* LED purposes:
* - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h
* - 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
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_MQTT_CLIENT
// Enable GSM modem support
#define MY_GATEWAY_TINYGSM
// Define your modem
#define TINY_GSM_MODEM_SIM800
// #define TINY_GSM_MODEM_SIM808
// #define TINY_GSM_MODEM_SIM900
// #define TINY_GSM_MODEM_A6
// #define TINY_GSM_MODEM_A7
// #define TINY_GSM_MODEM_M590
// #define TINY_GSM_ESP8266
// leave empty anything that does not apply
#define MY_GSM_APN "internet"
//#define MY_GSM_PIN "1234"
#define MY_GSM_USR ""
//If using a GSM modem, this stands for your GSM connection password. If using WiFi, it's your wireless password.
#define MY_GSM_PSW ""
//#define MY_GSM_SSID ""
// Use Hardware Serial on Mega, Leonardo, Micro
//#define SerialAT Serial1
// or Software Serial on Uno, Nano
#include <SoftwareSerial.h>
#define MY_GSM_RX 4
#define MY_GSM_TX 5
// If your Mosquitto is old fashioned and does not support 3.1.1
//#define MQTT_VERSION MQTT_VERSION_3_1
// Set this node's subscribe and publish topic prefix
#define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out"
#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in"
// Set MQTT client id
#define MY_MQTT_CLIENT_ID "mysensors-1"
// Enable these if your MQTT broker requires usenrame/password
//#define MY_MQTT_USER "username"
//#define MY_MQTT_PASSWORD "password"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192,168,32,220
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,32,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// MQTT broker ip address or url. Define one or the other.
//#define MY_CONTROLLER_URL_ADDRESS "mymqttbroker.com"
#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68
// 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
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
*/
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
}

View File

@@ -0,0 +1,101 @@
/**
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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 serial 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 received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level.
#define MY_RF24_PA_LEVEL RF24_PA_LOW
// Enable serial gateway
#define MY_GATEWAY_SERIAL
// Define a lower baud rate for Arduinos running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Inverses the behavior of leds
//#define MY_WITH_LEDS_BLINKING_INVERSE
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors
}
void loop()
{
// Send locally attached sensor data here
}

View File

@@ -0,0 +1,104 @@
/**
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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 received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive 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
// Enable RS485 transport layer
#define MY_RS485
// Define this to enables DE-pin management on defined pin
#define MY_RS485_DE_PIN 2
// Set RS485 baud rate to use
#define MY_RS485_BAUD_RATE 9600
// Enable this if RS485 is connected to a hardware serial port
//#define MY_RS485_HWSERIAL Serial1
// Enable serial gateway
#define MY_GATEWAY_SERIAL
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin
#define MY_DEFAULT_RX_LED_PIN 5 // Receive led pin
#define MY_DEFAULT_TX_LED_PIN 6 // the PCB, on board LED
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors
}
void loop()
{
// Send locally attached sensor data here
}

View File

@@ -0,0 +1,142 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
* Contribution by a-lurker and Anticimex
* Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
* Contribution by Tomas Hozza <thozza@gmail.com>
*
*
* DESCRIPTION
* The EthernetGateway sends data received from sensors to the ethernet link.
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
*
* The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program.
*
* LED purposes:
* - To use the feature, uncomment MY_DEFAULT_xxx_LED_PIN in the sketch below
* - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
* See http://www.mysensors.org/build/ethernet_gateway for wiring instructions.
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Enable gateway ethernet module type
#define MY_GATEWAY_W5100
// W5100 Ethernet module SPI enable (optional if using a shield/module that manages SPI_EN signal)
//#define MY_W5100_SPI_EN 4
// Enable Soft SPI for NRF radio (note different radio wiring is required)
// 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
#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
#endif
#ifndef MY_RF24_CS_PIN
#define MY_RF24_CS_PIN 6
#endif
// Enable UDP communication
//#define MY_USE_UDP // If using UDP you need to set MY_CONTROLLER_IP_ADDRESS or MY_CONTROLLER_URL_ADDRESS below
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
#define MY_IP_ADDRESS 192,168,178,66
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// Renewal period if using DHCP
//#define MY_IP_RENEWAL_INTERVAL 60000
// The port to keep open on node server mode / or port to contact in client mode
#define MY_PORT 5003
// Controller ip address. Enables client mode (default is "server" mode).
// Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
//#define MY_CONTROLLER_URL_ADDRESS "my.controller.org"
// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Arduino examples use "DEAD BEEF FEED" for the MAC address.
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 7 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 8 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 9 // Transmit led pin
#if defined(MY_USE_UDP)
#include <EthernetUdp.h>
#endif
#include <Ethernet.h>
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
}

View File

@@ -0,0 +1,154 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
*
* DESCRIPTION
* The W5100 MQTT gateway sends radio network (or locally attached sensors) data to your MQTT broker.
* The node also listens to MY_MQTT_TOPIC_PREFIX and sends out those messages to the radio network
*
* LED purposes:
* - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h
* - RX (green) - blink fast on radio message received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
* See http://www.mysensors.org/build/esp8266_gateway for wiring instructions.
* nRF24L01+ ESP8266
* VCC VCC
* CE GPIO4
* CSN/CS GPIO15
* SCK GPIO14
* MISO GPIO12
* MOSI GPIO13
*
* Not all ESP8266 modules have all pins available on their external interface.
* This code has been tested on an ESP-12 module.
* The ESP8266 requires a certain pin configuration to download code, and another one to run code:
* - Connect REST (reset) via 10K pullup resistor to VCC, and via switch to GND ('reset switch')
* - Connect GPIO15 via 10K pulldown resistor to GND
* - Connect CH_PD via 10K resistor to VCC
* - Connect GPIO2 via 10K resistor to VCC
* - Connect GPIO0 via 10K resistor to VCC, and via switch to GND ('bootload switch')
*
* Inclusion mode button:
* - Connect GPIO5 via switch to GND ('inclusion switch')
*
* Hardware SHA204 signing is currently not supported!
*
* Make sure to fill in your ssid and WiFi password below for ssid & pass.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enables and select radio type (if attached)
#define MY_RADIO_RF24
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#define MY_GATEWAY_MQTT_CLIENT
// Set this node's subscribe and publish topic prefix
#define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out"
#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in"
// Set MQTT client id
#define MY_MQTT_CLIENT_ID "mysensors-1"
// W5100 Ethernet module SPI enable (optional if using a shield/module that manages SPI_EN signal)
//#define MY_W5100_SPI_EN 4
// Enable Soft SPI for NRF radio (note different radio wiring is required)
// 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
#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
#endif
#ifndef MY_RF24_CS_PIN
#define MY_RF24_CS_PIN 6
#endif
// Enable these if your MQTT broker requires username/password
//#define MY_MQTT_USER "username"
//#define MY_MQTT_PASSWORD "password"
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
#define MY_IP_ADDRESS 192,168,178,87
// If using static ip you can define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// MQTT broker ip address or url. Define one or the other.
//#define MY_CONTROLLER_URL_ADDRESS "m20.cloudmqtt.com"
#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68
// 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
//#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
*/
#include <Ethernet.h>
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors here
}
void loop()
{
// Send locally attached sensors data here
}

View File

@@ -0,0 +1,70 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik EKblad
*
* DESCRIPTION
* Example sketch showing how to measure light level using a LM393 photo-resistor
* http://www.mysensors.org/build/light
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID_LIGHT 0
#define LIGHT_SENSOR_ANALOG_PIN 0
uint32_t SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
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");
// 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);
}

View File

@@ -0,0 +1,107 @@
/**
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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 serial 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 received. In inclusion mode will blink fast only on presentation received
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or receive crc error
*
* OTA DEBUG MESSAGES
* - Add the OTADebugReceive(message) into receive(const MyMessage &message) on a serial connected node
* - Add '#define MY_DEBUG_OTA (0)' to your Node sketch by replacing (0) with the node id of your serial connected node
*
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable OTA log display
#define MY_OTA_LOG_RECEIVER_FEATURE
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level.
#define MY_RF24_PA_LEVEL RF24_PA_LOW
// Enable serial gateway
#define MY_GATEWAY_SERIAL
// Define a lower baud rate for Arduinos running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
//#define MY_INCLUSION_BUTTON_FEATURE
// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Inverses the behavior of leds
//#define MY_WITH_LEDS_BLINKING_INVERSE
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED
#include <MySensors.h>
void setup()
{
// Setup locally attached sensors
}
void presentation()
{
// Present locally attached sensors
}
void loop()
{
// Send locally attached sensor data here
}

View File

@@ -0,0 +1,74 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* Example for sending debug messages over the air (OTA).
*
*/
// Enable debug
#define MY_DEBUG
// Enable OTA debugging to Node 0
#define MY_DEBUG_OTA (0)
// Allow sending logs without MY_DEBUG_OTA enabled
#define MY_OTA_LOG_SENDER_FEATURE
// Disable echoing of debug messages
//#define MY_DEBUG_OTA_DISABLE_ECHO
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
void setup()
{
}
void presentation()
{
// Send the sketch version information to the gateway and Controller
sendSketchInfo("DebugSensor", "1.0");
}
// Arduino loop
int c=0;
void loop()
{
// Wait some time
if (sleep(3000)==MY_SLEEP_NOT_POSSIBLE) {
delay(3000);
}
// Count loops
c++;
// A debug message
DEBUG_OUTPUT(PSTR("DEBUG\nc=%" PRId16 "\nmillis=%" PRId32 "\n"), c, hwMillis());
// Send a log message to a node, requesting that the message is echoed back to this node
OTALog(0, true, PSTR("LOG\nc=%" PRId16 "\nmillis=%" PRId32 "\n"), c, hwMillis());
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
# MockMySensors
Arduino sketch to fake sensor for the MySensors Library
This sketch is intended to create fake sensors which register and respond to the controller
Barduino, GizMoCuz 2015
-----------------
Comment/Uncomment the sensors you would like to test
Arduino Uno R3 can support about 12 sensors before it runs out of memory.
(turning off the MySensors debug helps if you are memory limited)
With a Mega you can have them all
Changes Log
-----------------
2015-09-07
Five more sensors
S_RGB_LIGHT
S_RGBW_LIGHT
S_COLOR_SENSOR
S_HVAC
S_MULTIMETER
Consolidated HVAC and HEATER incoming message
2015-09-06
Merge with Gizmocuz (implementation of S_HEATER & S_MOISTURE
Implementation of S_COVER, S_IR, S_SCENE_CONTROLLER
2015-08-19
Removed the load/save to eeprom
Touched the heater sensor
Created a pseudo sensor to handle the V_ARMED message.
All sensors which support V_ARMED will arm/disarm at the same time

View File

@@ -0,0 +1,74 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
*
* DESCRIPTION
* Motion Sensor example using HC-SR501
* http://www.mysensors.org/build/motion
*
*/
// Enable debug prints
// #define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
uint32_t SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
#define CHILD_ID 1 // Id of the sensor child
// 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 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);
}
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
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
}

View File

@@ -0,0 +1,98 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* 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
* 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
* 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
// Enable RS485 transport layer
#define MY_RS485
// Define this to enables DE-pin management on defined pin
#define MY_RS485_DE_PIN 2
// Set RS485 baud rate to use
#define MY_RS485_BAUD_RATE 9600
// Enable this if RS485 is connected to a hardware serial port
//#define MY_RS485_HWSERIAL Serial1
#include <MySensors.h>
uint32_t SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
#define CHILD_ID 1 // Id of the sensor child
// 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 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);
}
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
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
}

View File

@@ -0,0 +1,76 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - tekka 2018
*
* DESCRIPTION
* Node to node communication example, destination node id = ACTUATOR_ID
* Use SIGNING_ENABLED to enable soft/hard signing
*
*/
#define MY_DEBUG
#define MY_RADIO_RF24
#define CHILD_SENSOR_ID 0
#define ACTUATOR_ID 200
//#define SIGNING_ENABLED // enable for secure actuator
#if defined(SIGNING_ENABLED)
// Signing, select soft/hardware signing method
#define MY_SIGNING_SOFT
//#define MY_SIGNING_ATSHA204
#define MY_DEBUG_VERBOSE_SIGNING
// Enable this if you want destination node to sign all messages sent to this node.
//#define MY_SIGNING_REQUEST_SIGNATURES
#endif
// triggering interval
static const uint32_t trigger_ms = 10000;
#include "MySensors.h"
MyMessage msgGeneral(CHILD_SENSOR_ID, V_STATUS);
uint32_t lastTrigger = 0;
bool actuatorStatus = false;
void presentation(void)
{
sendSketchInfo("Node2Node", __DATE__);
present(CHILD_SENSOR_ID, S_BINARY, "Remote");
}
void setup()
{
#if defined(SIGNING_ENABLED)
SET_SIGN(ACTUATOR_ID); // define signing requirements for remote node
#endif
}
void loop()
{
if (millis() - lastTrigger > trigger_ms) {
lastTrigger = millis();
// set destination address
msgGeneral.setDestination(ACTUATOR_ID);
// send message to node
send(msgGeneral.set(actuatorStatus));
// invert status
actuatorStatus ^= true;
}
}

View File

@@ -0,0 +1,85 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - mboyer85
*
* DESCRIPTION
* Example sketch showing how to send PH readings back to the controller
*/
// Enable debug prints to serial monitor
//#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define COMPARE_PH 1 // Send PH only if changed? 1 = Yes 0 = No
uint32_t SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
float lastPH;
bool receivedConfig = false;
bool metric = true;
// Initialize PH message
MyMessage msg(0, V_PH);
void setup()
{
//Setup your PH sensor here (I2C,Serial,Phidget...)
}
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 loop()
{
float ph = getPH();
#if COMPARE_PH == 1
if (lastPH != ph) {
#endif
// 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);
}

View File

@@ -0,0 +1,69 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - tekka
*
* DESCRIPTION
* Passive node example: This is a passive & independent reporting node
*
*/
// Enable debug prints
#define MY_DEBUG
// Enable passive mode
#define MY_PASSIVE_NODE
// Passive mode requires static node ID
#define MY_NODE_ID 100
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define CHILD_ID 0 // Id of the sensor child
// Initialize general message
MyMessage msg(CHILD_ID, V_TEMP);
void setup()
{
}
void presentation()
{
// Send the sketch version information to the gateway and controller
sendSketchInfo("Passive node", "1.0");
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID, S_TEMP);
}
void loop()
{
// generate some random data
send(msg.set(25.0+random(0,30)/10.0,2));
sleep(2000);
}

View File

@@ -0,0 +1,65 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* Formatted logging to the Serial console.
* Compiled in by setting LOGDEBUG
*
* 2015-05-25 Bruce Lacey V1.0
*
* Based upon Arduino Playground prior art and should be moved to
* the MySensors library at some point as a common debug logging facility
*/
#ifndef MYSLog_h
#define MYSLog_h
#define LOGDEBUG 1
#if defined ( LOGDEBUG )
#define LOG(fmt, args... ) debugLog( fmt, ## args );
#else
#define LOG(fmt, args... )
#endif
void debugLog(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 debugLog(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
#else
vsnprintf(buf, sizeof(buf), (const char *)fmt, args); // for the rest of the world
#endif
va_end(args);
Serial.print(buf);
}
#endif

View File

@@ -0,0 +1,127 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* This is a simple sketch used to demonstrate and test node-to-node MySensors communication.
* To use this sketch, assemble MySensors nodes - they need nothing more than a radio
* 1. Flash each node with the same sketch, open the console and type either 0 or 1 to the respective nodes to set their ID
* 2. You only need to set the node id once, and restart the nodes
* 3. To being a ping-pong test, simply type T in the console for one of the nodes.
*
* 2015-05-25 Bruce Lacey v1.0
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#include "MYSLog.h"
#define VSN "v1.0"
// Define two generic nodes with a single child
#define YING 200
#define YANG 201
#define CHILD 1
MyMessage mPing(CHILD, V_VAR1); //Ping message
MyMessage mPong(CHILD, V_VAR2); //Pong message
void setup()
{
}
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 initiate 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((mysensors_data_t)message.getType()),
nodeTypeAsCharRepresentation(message.sender));
delay(250);
sendPingOrPongResponse( message );
}
void sendPingOrPongResponse( MyMessage msg )
{
MyMessage response = (msg.getType() == V_VAR1 ? mPong : mPing);
LOG(F("Sending %s to %s\n"), msgTypeAsCharRepresentation( (mysensors_data_t)response.getType() ),
nodeTypeAsCharRepresentation(msg.sender));
// Set payload to current time in millis to ensure each message is unique
response.set( (uint32_t)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);
hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (byte)nodeID);
}
const char * msgTypeAsCharRepresentation( mysensors_data_t mType )
{
return mType == V_VAR1 ? "Ping" : "Pong";
}
const char * nodeTypeAsCharRepresentation( uint8_t node )
{
return node == YING ? "Ying Node" : "Yang Node";
}

View File

@@ -0,0 +1,99 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - tekka
*
* DESCRIPTION
* ATC mode settings and signal report functions, on RFM69 and RFM95 nodes
*
*/
// Enable debug prints
#define MY_DEBUG
// Enable and select radio type attached
// RFM69
//#define MY_RADIO_RFM69
//#define MY_RFM69_NEW_DRIVER // ATC on RFM69 works only with the new driver (not compatible with old=default driver)
//#define MY_RFM69_ATC_TARGET_RSSI_DBM (-70) // target RSSI -70dBm
//#define MY_RFM69_MAX_POWER_LEVEL_DBM (10) // max. TX power 10dBm = 10mW
// RFM95
#define MY_RADIO_RFM95
#define MY_RFM95_ATC_TARGET_RSSI_DBM (-70) // target RSSI -70dBm
#define MY_RFM95_MAX_POWER_LEVEL_DBM (10) // max. TX power 10dBm = 10mW
#include <MySensors.h>
// ID of the sensor child
#define CHILD_ID_UPLINK_QUALITY (0)
#define CHILD_ID_TX_LEVEL (1)
#define CHILD_ID_TX_PERCENT (2)
#define CHILD_ID_TX_RSSI (3)
#define CHILD_ID_RX_RSSI (4)
#define CHILD_ID_TX_SNR (5)
#define CHILD_ID_RX_SNR (6)
// Initialize general message
MyMessage msgTxRSSI(CHILD_ID_TX_RSSI, V_CUSTOM);
MyMessage msgRxRSSI(CHILD_ID_RX_RSSI, V_CUSTOM);
MyMessage msgTxSNR(CHILD_ID_TX_SNR, V_CUSTOM);
MyMessage msgRxSNR(CHILD_ID_RX_SNR, V_CUSTOM);
MyMessage msgTxLevel(CHILD_ID_TX_LEVEL, V_CUSTOM);
MyMessage msgTxPercent(CHILD_ID_TX_PERCENT, V_CUSTOM);
MyMessage msgUplinkQuality(CHILD_ID_UPLINK_QUALITY, V_CUSTOM);
void setup()
{
}
void presentation()
{
// Send the sketch version information to the gateway and controller
sendSketchInfo("ATC", "1.0");
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_UPLINK_QUALITY, S_CUSTOM, "UPLINK QUALITY RSSI");
present(CHILD_ID_TX_LEVEL, S_CUSTOM, "TX LEVEL DBM");
present(CHILD_ID_TX_PERCENT, S_CUSTOM, "TX LEVEL PERCENT");
present(CHILD_ID_TX_RSSI, S_CUSTOM, "TX RSSI");
present(CHILD_ID_RX_RSSI, S_CUSTOM, "RX RSSI");
present(CHILD_ID_TX_SNR, S_CUSTOM, "TX SNR");
present(CHILD_ID_RX_SNR, S_CUSTOM, "RX SNR");
}
void loop()
{
// send messages to GW
send(msgUplinkQuality.set(transportGetSignalReport(SR_UPLINK_QUALITY)));
send(msgTxLevel.set(transportGetSignalReport(SR_TX_POWER_LEVEL)));
send(msgTxPercent.set(transportGetSignalReport(SR_TX_POWER_PERCENT)));
// retrieve RSSI / SNR reports from incoming ACK
send(msgTxRSSI.set(transportGetSignalReport(SR_TX_RSSI)));
send(msgRxRSSI.set(transportGetSignalReport(SR_RX_RSSI)));
send(msgTxSNR.set(transportGetSignalReport(SR_TX_SNR)));
send(msgRxSNR.set(transportGetSignalReport(SR_RX_SNR)));
// wait a bit
wait(5000);
}

View File

@@ -0,0 +1,97 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
*
* DESCRIPTION
* 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
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Enable repeater functionality for this node
#define MY_REPEATER_FEATURE
#include <MySensors.h>
#define RELAY_PIN 4 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
#define RELAY_ON 1 // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
void before()
{
for (int sensor=1, pin=RELAY_PIN; 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_PIN; 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.getType()==V_STATUS) {
// Change relay state
digitalWrite(message.getSensor()-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
// Store state in eeprom
saveState(message.getSensor(), message.getBool());
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.getSensor());
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}

View File

@@ -0,0 +1,59 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
*
* DESCRIPTION
* Example sketch showing how to create a node that repeats 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.
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Enabled repeater feature for this node
#define MY_REPEATER_FEATURE
#include <MySensors.h>
void setup()
{
}
void presentation()
{
//Send the sensor node sketch version information to the gateway
sendSketchInfo("Repeater Node", "1.0");
}
void loop()
{
}

View File

@@ -0,0 +1,409 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* 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/
* 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
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#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 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.
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)
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.
bool programModeActive = false; // True if we're trying to program a new knock.
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
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 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 programming 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.
uint32_t startTime = millis(); // Reference for when this knock started.
uint32_t now;
do { // Listen for the next knock or wait for it to timeout.
knockSensorValue = digitalRead(knockSensor);
if (knockSensorValue == 0) { // Here's another knock. Save the time between knocks.
Serial.println("knock");
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.
}
// 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;
for (int timeDiff = 0, 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);
}
}
}
//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.
}
// 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);
}
// 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);
}
}
// 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 receive(const MyMessage &message)
{
// We only expect one type of message from controller. But we better check anyway.
if (message.getType()==V_LOCK_STATUS) {
// Change relay state
setLockState(message.getBool(), false);
// Write some debug info
Serial.print("Incoming lock status:");
Serial.println(message.getBool());
}
}

View File

@@ -0,0 +1,128 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*/
/**
* @ingroup MySigninggrp
* @{
* @file SecureActuator.ino
* @brief Example sketch showing how to securely control locks.
*
* This example will remember lock state even after power failure.
*
* REVISION HISTORY
* - See git log (git log libraries/MySensors/examples/SecureActuator/SecureActuator.ino)
*/
/**
* @example SecureActuator.ino
* This example implements a secure actuator in the form of a IO controlled electrical lock.<br>
* Multiple locks are supported as long as they are on subsequent IO pin indices. The first lock pin
* is defined by @ref LOCK_1. The number of locks is controlled by @ref NOF_LOCKS .<br>
* The sketch will require incoming messages to be signed and the use of signing backend is selected
* by @ref MY_SIGNING_ATSHA204 or @ref MY_SIGNING_SOFT. Hard or soft ATSHA204 signing is supported.<br>
* Whitelisting can be enabled through @ref MY_SIGNING_NODE_WHITELISTING in which case a single entry
* is provided in this example which typically should map to the gateway of the network.
*/
#define MY_DEBUG //!< Enable debug prints to serial monitor
#define MY_DEBUG_VERBOSE_SIGNING //!< Enable signing related debug prints to serial monitor
#define MY_NODE_LOCK_FEATURE //!< Enable lockdown of node if suspicious activity is detected
// Enable and select radio type attached
#define MY_RADIO_RF24 //!< nRF24L01 radio driver
//#define MY_RADIO_NRF5_ESB //!< nRF5 radio driver (RF24 compatible)
//#define MY_RADIO_RFM69 //!< RFM69 radio driver
//#define MY_RADIO_RFM95 //!< RFM95 radio driver
// Select soft/hardware signing method
#define MY_SIGNING_SOFT //!< Software signing
//#define MY_SIGNING_ATSHA204 //!< Hardware signing using ATSHA204A
// Enable node whitelisting
//#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
// Enable this if you want destination node to sign all messages sent to this node.
#define MY_SIGNING_REQUEST_SIGNATURES //!< destination node signs all messages sent to this node
// SETTINGS FOR MY_SIGNING_SOFT
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //!< Unconnected analog pin for random seed
// SETTINGS FOR MY_SIGNING_ATSHA204
#ifndef MY_SIGNING_ATSHA204_PIN
#define MY_SIGNING_ATSHA204_PIN 17 //!< A3 - pin where ATSHA204 is attached
#endif
#include <MySensors.h>
#define LOCK_1 3 //!< Arduino Digital I/O pin number for first lock (second on pin+1 etc)
#define NOF_LOCKS 1 //!< Total number of attached locks
#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 presentation()
{
// 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);
}
}
/** @brief Sketch execution code */
void loop()
{
}
/**
* @brief Incoming message handler
*
* @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 echoed messages are not accepted as control messages
if (message.getType()==V_LOCK_STATUS && message.getSensor()<=NOF_LOCKS && !message.isEcho()) {
// Change relay state
digitalWrite(message.getSensor()-1+LOCK_1, message.getBool()?LOCK_LOCK:LOCK_UNLOCK);
// Store state in eeprom
saveState(message.getSensor(), message.getBool());
// Write some debug info
Serial.print("Incoming change for lock:");
Serial.print(message.getSensor());
Serial.print(", New status: ");
Serial.println(message.getBool());
}
}
/** @}*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
// ----------------------------------------------------------------------------
// ATMEL Microcontroller Software Support - Colorado Springs, CO -
// ----------------------------------------------------------------------------
// DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
// DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------
/** \file
* \brief SHA204 Library Return Code Definitions
* \author Atmel Crypto Products
* \date September 27, 2010
*/
#ifndef SHA204_LIB_RETURN_CODES_H
# define SHA204_LIB_RETURN_CODES_H
#include <stddef.h> // data type definitions
#define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded.
#define SHA204_PARSE_ERROR ((uint8_t) 0xD2) //!< response status byte indicates parsing error
#define SHA204_CMD_FAIL ((uint8_t) 0xD3) //!< response status byte indicates command execution error
#define SHA204_STATUS_CRC ((uint8_t) 0xD4) //!< response status byte indicates CRC error
#define SHA204_STATUS_UNKNOWN ((uint8_t) 0xD5) //!< response status byte is unknown
#define SHA204_FUNC_FAIL ((uint8_t) 0xE0) //!< Function could not execute due to incorrect condition / state.
#define SHA204_GEN_FAIL ((uint8_t) 0xE1) //!< unspecified error
#define SHA204_BAD_PARAM ((uint8_t) 0xE2) //!< bad argument (out of range, null pointer, etc.)
#define SHA204_INVALID_ID ((uint8_t) 0xE3) //!< invalid device id, id not set
#define SHA204_INVALID_SIZE ((uint8_t) 0xE4) //!< Count value is out of range or greater than buffer size.
#define SHA204_BAD_CRC ((uint8_t) 0xE5) //!< incorrect CRC received
#define SHA204_RX_FAIL ((uint8_t) 0xE6) //!< Timed out while waiting for response. Number of bytes received is > 0.
#define SHA204_RX_NO_RESPONSE ((uint8_t) 0xE7) //!< Not an error while the Command layer is polling for a command response.
#define SHA204_RESYNC_WITH_WAKEUP ((uint8_t) 0xE8) //!< re-synchronization succeeded, but only after generating a Wake-up
#define SHA204_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. Same as in hardware dependent modules.
#define SHA204_TIMEOUT ((uint8_t) 0xF1) //!< Timed out while waiting for response. Number of bytes received is 0.
#endif

View File

@@ -0,0 +1,861 @@
#include "Arduino.h"
#include "sha204_library.h"
#include "sha204_lib_return_codes.h"
// atsha204Class Constructor
// Feed this function the Arduino-ized pin number you want to assign to the ATSHA204's SDA pin
// For AVR ARCH, this will find the DDRX, PORTX, and PINX registrs it'll need to point to to control that pin
// As well as the bit value for each of those registers
// For others it will only store the pin number which is used in subsequent functions
atsha204Class::atsha204Class(uint8_t pin)
{
#if defined(ARDUINO_ARCH_AVR)
device_pin = digitalPinToBitMask(pin); // Find the bit value of the pin
uint8_t port = digitalPinToPort(pin); // temoporarily used to get the next three registers
// Point to data direction register port of pin
device_port_DDR = portModeRegister(port);
// Point to output register of pin
device_port_OUT = portOutputRegister(port);
// Point to input register of pin
device_port_IN = portInputRegister(port);
#else
device_pin = pin;
#endif
}
/* Puts a the ATSHA204's unique, 4-byte serial number in the response array
returns an SHA204 Return code */
uint8_t atsha204Class::getSerialNumber(uint8_t * response)
{
uint8_t readCommand[READ_COUNT];
uint8_t readResponse[READ_4_RSP_SIZE];
/* read from bytes 0->3 of config zone */
uint8_t returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN03);
if (!returnCode) { // should return 0 if successful
for (int i=0; i<4; i++) { // store bytes 0-3 into respones array
response[i] = readResponse[SHA204_BUFFER_POS_DATA+i];
}
/* read from bytes 8->11 of config zone */
returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN47);
for (int i=4; i<8; i++) { // store bytes 4-7 of SN into response array
response[i] = readResponse[SHA204_BUFFER_POS_DATA+(i-4)];
}
if (!returnCode) {
/* Finally if last two reads were successful, read byte 8 of the SN */
returnCode = sha204m_read(readCommand, readResponse, SHA204_ZONE_CONFIG, ADDRESS_SN8);
response[8] = readResponse[SHA204_BUFFER_POS_DATA]; // Byte 8 of SN should always be 0xEE
}
}
return returnCode;
}
/* Calculates CRC16 value of provided data (and optionally including provided existing CRC16 data)
returns the calculated CRC16 value */
uint16_t atsha204Class::calculateAndUpdateCrc(uint8_t length, uint8_t *data, uint16_t current_crc)
{
uint8_t counter;
uint16_t crc_register = current_crc;
uint16_t polynom = 0x8005;
uint8_t shift_register;
uint8_t data_bit, crc_bit;
for (counter = 0; counter < length; counter++) {
for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
data_bit = (data[counter] & shift_register) ? 1 : 0;
crc_bit = crc_register >> 15;
// Shift CRC to the left by 1.
crc_register <<= 1;
if ((data_bit ^ crc_bit) != 0) {
crc_register ^= polynom;
}
}
}
return crc_register;
}
/* SWI bit bang functions */
void atsha204Class::swi_set_signal_pin(uint8_t is_high)
{
SHA204_SET_OUTPUT();
if (is_high) {
SHA204_POUT_HIGH();
} else {
SHA204_POUT_LOW();
}
}
uint8_t atsha204Class::swi_send_bytes(uint8_t count, uint8_t *buffer)
{
uint8_t i, bit_mask;
// Disable interrupts while sending.
noInterrupts(); //swi_disable_interrupts();
// Set signal pin as output.
SHA204_POUT_HIGH();
SHA204_SET_OUTPUT();
// Wait turn around time.
delayMicroseconds(RX_TX_DELAY); //RX_TX_DELAY;
for (i = 0; i < count; i++) {
for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
if (bit_mask & buffer[i]) {
SHA204_POUT_LOW();
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_HIGH();
delayMicroseconds(7*BIT_DELAY); //BIT_DELAY_7;
} else {
// Send a zero bit.
SHA204_POUT_LOW();
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_HIGH();
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_LOW();
delayMicroseconds(BIT_DELAY); //BIT_DELAY_1;
SHA204_POUT_HIGH();
delayMicroseconds(5*BIT_DELAY); //BIT_DELAY_5;
}
}
}
interrupts(); //swi_enable_interrupts();
return SWI_FUNCTION_RETCODE_SUCCESS;
}
uint8_t atsha204Class::swi_send_byte(uint8_t value)
{
return swi_send_bytes(1, &value);
}
uint8_t atsha204Class::swi_receive_bytes(uint8_t count, uint8_t *buffer)
{
uint8_t status = SWI_FUNCTION_RETCODE_SUCCESS;
uint8_t i;
uint8_t bit_mask;
uint8_t pulse_count;
uint8_t timeout_count;
// Disable interrupts while receiving.
noInterrupts(); //swi_disable_interrupts();
// Configure signal pin as input
SHA204_SET_INPUT();
// Receive bits and store in buffer.
for (i = 0; i < count; i++) {
for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) {
pulse_count = 0;
// Make sure that the variable below is big enough.
// Change it to uint16_t if 255 is too small, but be aware that
// the loop resolution decreases on an 8-bit controller in that case.
timeout_count = START_PULSE_TIME_OUT;
// Detect start bit.
while (--timeout_count > 0) {
// Wait for falling edge.
if (SHA204_PIN_READ() == 0) {
break;
}
}
if (timeout_count == 0) {
status = SWI_FUNCTION_RETCODE_TIMEOUT;
break;
}
do {
// Wait for rising edge.
if (SHA204_PIN_READ() != 0) {
// For an Atmel microcontroller this might be faster than "pulse_count++".
pulse_count = 1;
break;
}
} while (--timeout_count > 0);
if (pulse_count == 0) {
status = SWI_FUNCTION_RETCODE_TIMEOUT;
break;
}
// Trying to measure the time of start bit and calculating the timeout
// for zero bit detection is not accurate enough for an 8 MHz 8-bit CPU.
// So let's just wait the maximum time for the falling edge of a zero bit
// to arrive after we have detected the rising edge of the start bit.
timeout_count = ZERO_PULSE_TIME_OUT;
// Detect possible edge indicating zero bit.
do {
if (SHA204_PIN_READ() == 0) {
// For an Atmel microcontroller this might be faster than "pulse_count++".
pulse_count = 2;
break;
}
} while (--timeout_count > 0);
// Wait for rising edge of zero pulse before returning. Otherwise we might interpret
// its rising edge as the next start pulse.
if (pulse_count == 2) {
do {
if (SHA204_PIN_READ() != 0) {
break;
}
} while (timeout_count-- > 0);
}
// Update byte at current buffer index.
else {
buffer[i] |= bit_mask; // received "one" bit
}
}
if (status != SWI_FUNCTION_RETCODE_SUCCESS) {
break;
}
}
interrupts(); //swi_enable_interrupts();
if (status == SWI_FUNCTION_RETCODE_TIMEOUT) {
if (i > 0)
// Indicate that we timed out after having received at least one byte.
{
status = SWI_FUNCTION_RETCODE_RX_FAIL;
}
}
return status;
}
/* Physical functions */
uint8_t atsha204Class::sha204p_wakeup()
{
swi_set_signal_pin(0);
delayMicroseconds(10*SHA204_WAKEUP_PULSE_WIDTH);
swi_set_signal_pin(1);
delay(SHA204_WAKEUP_DELAY);
return SHA204_SUCCESS;
}
uint8_t atsha204Class::sha204p_sleep()
{
return swi_send_byte(SHA204_SWI_FLAG_SLEEP);
}
uint8_t atsha204Class::sha204p_resync(uint8_t size, uint8_t *response)
{
delay(SHA204_SYNC_TIMEOUT);
return sha204p_receive_response(size, response);
}
uint8_t atsha204Class::sha204p_receive_response(uint8_t size, uint8_t *response)
{
uint8_t i;
uint8_t ret_code;
for (i = 0; i < size; i++) {
response[i] = 0;
}
(void) swi_send_byte(SHA204_SWI_FLAG_TX);
ret_code = swi_receive_bytes(size, response);
if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) {
uint8_t count_byte;
count_byte = response[SHA204_BUFFER_POS_COUNT];
if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) {
return SHA204_INVALID_SIZE;
}
return SHA204_SUCCESS;
}
// Translate error so that the Communication layer
// can distinguish between a real error or the
// device being busy executing a command.
if (ret_code == SWI_FUNCTION_RETCODE_TIMEOUT) {
return SHA204_RX_NO_RESPONSE;
} else {
return SHA204_RX_FAIL;
}
}
uint8_t atsha204Class::sha204p_send_command(uint8_t count, uint8_t * command)
{
uint8_t ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD);
if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS) {
return SHA204_COMM_FAIL;
}
return swi_send_bytes(count, command);
}
/* Communication functions */
uint8_t atsha204Class::sha204c_wakeup(uint8_t *response)
{
uint8_t ret_code = sha204p_wakeup();
if (ret_code != SHA204_SUCCESS) {
return ret_code;
}
ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response);
if (ret_code != SHA204_SUCCESS) {
return ret_code;
}
// Verify status response.
if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN) {
ret_code = SHA204_INVALID_SIZE;
} else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP) {
ret_code = SHA204_COMM_FAIL;
} else {
if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33)
|| (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43)) {
ret_code = SHA204_BAD_CRC;
}
}
if (ret_code != SHA204_SUCCESS) {
delay(SHA204_COMMAND_EXEC_MAX);
}
return ret_code;
}
uint8_t atsha204Class::sha204c_resync(uint8_t size, uint8_t *response)
{
// Try to re-synchronize without sending a Wake token
// (step 1 of the re-synchronization process).
uint8_t ret_code = sha204p_resync(size, response);
if (ret_code == SHA204_SUCCESS) {
return ret_code;
}
// We lost communication. Send a Wake pulse and try
// to receive a response (steps 2 and 3 of the
// re-synchronization process).
(void) sha204p_sleep();
ret_code = sha204c_wakeup(response);
// Translate a return value of success into one
// that indicates that the device had to be woken up
// and might have lost its TempKey.
return (ret_code == SHA204_SUCCESS ? SHA204_RESYNC_WITH_WAKEUP : ret_code);
}
uint8_t atsha204Class::sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size,
uint8_t *rx_buffer, uint8_t execution_delay, uint8_t execution_timeout)
{
uint8_t ret_code = SHA204_FUNC_FAIL;
uint8_t ret_code_resync;
uint8_t n_retries_send;
uint8_t n_retries_receive;
uint8_t i;
uint8_t status_byte;
uint8_t count = tx_buffer[SHA204_BUFFER_POS_COUNT];
uint8_t count_minus_crc = count - SHA204_CRC_SIZE;
uint16_t execution_timeout_us = (uint16_t) (execution_timeout * 1000) + SHA204_RESPONSE_TIMEOUT;
volatile uint16_t timeout_countdown;
// Append CRC.
sha204c_calculate_crc(count_minus_crc, tx_buffer, tx_buffer + count_minus_crc);
// Retry loop for sending a command and receiving a response.
n_retries_send = SHA204_RETRY_COUNT + 1;
while ((n_retries_send-- > 0) && (ret_code != SHA204_SUCCESS)) {
// Send command.
ret_code = sha204p_send_command(count, tx_buffer);
if (ret_code != SHA204_SUCCESS) {
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) {
return ret_code; // The device seems to be dead in the water.
} else {
continue;
}
}
// Wait minimum command execution time and then start polling for a response.
delay(execution_delay);
// Retry loop for receiving a response.
n_retries_receive = SHA204_RETRY_COUNT + 1;
while (n_retries_receive-- > 0) {
// Reset response buffer.
for (i = 0; i < rx_size; i++) {
rx_buffer[i] = 0;
}
// Poll for response.
timeout_countdown = execution_timeout_us;
do {
ret_code = sha204p_receive_response(rx_size, rx_buffer);
timeout_countdown -= SHA204_RESPONSE_TIMEOUT;
} while ((timeout_countdown > SHA204_RESPONSE_TIMEOUT) && (ret_code == SHA204_RX_NO_RESPONSE));
if (ret_code == SHA204_RX_NO_RESPONSE) {
// We did not receive a response. Re-synchronize and send command again.
if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE)
// The device seems to be dead in the water.
{
return ret_code;
} else {
break;
}
}
// Check whether we received a valid response.
if (ret_code == SHA204_INVALID_SIZE) {
// We see 0xFF for the count when communication got out of sync.
ret_code_resync = sha204c_resync(rx_size, rx_buffer);
if (ret_code_resync == SHA204_SUCCESS)
// We did not have to wake up the device. Try receiving response again.
{
continue;
}
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP)
// We could re-synchronize, but only after waking up the device.
// Re-send command.
{
break;
} else
// We failed to re-synchronize.
{
return ret_code;
}
}
// We received a response of valid size.
// Check the consistency of the response.
ret_code = sha204c_check_crc(rx_buffer);
if (ret_code == SHA204_SUCCESS) {
// Received valid response.
if (rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN)
// Received non-status response. We are done.
{
return ret_code;
}
// Received status response.
status_byte = rx_buffer[SHA204_BUFFER_POS_STATUS];
// Translate the three possible device status error codes
// into library return codes.
if (status_byte == SHA204_STATUS_BYTE_PARSE) {
return SHA204_PARSE_ERROR;
}
if (status_byte == SHA204_STATUS_BYTE_EXEC) {
return SHA204_CMD_FAIL;
}
if (status_byte == SHA204_STATUS_BYTE_COMM) {
// In case of the device status byte indicating a communication
// error this function exits the retry loop for receiving a response
// and enters the overall retry loop
// (send command / receive response).
ret_code = SHA204_STATUS_CRC;
break;
}
// Received status response from CheckMAC, DeriveKey, GenDig,
// Lock, Nonce, Pause, UpdateExtra, or Write command.
return ret_code;
}
else {
// Received response with incorrect CRC.
ret_code_resync = sha204c_resync(rx_size, rx_buffer);
if (ret_code_resync == SHA204_SUCCESS)
// We did not have to wake up the device. Try receiving response again.
{
continue;
}
if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP)
// We could re-synchronize, but only after waking up the device.
// Re-send command.
{
break;
} else
// We failed to re-synchronize.
{
return ret_code;
}
} // block end of check response consistency
} // block end of receive retry loop
} // block end of send and receive retry loop
return ret_code;
}
/* Marshaling functions */
uint8_t atsha204Class::sha204m_random(uint8_t * tx_buffer, uint8_t * rx_buffer, uint8_t mode)
{
if (!tx_buffer || !rx_buffer || (mode > RANDOM_NO_SEED_UPDATE)) {
return SHA204_BAD_PARAM;
}
tx_buffer[SHA204_COUNT_IDX] = RANDOM_COUNT;
tx_buffer[SHA204_OPCODE_IDX] = SHA204_RANDOM;
tx_buffer[RANDOM_MODE_IDX] = mode & RANDOM_SEED_UPDATE;
tx_buffer[RANDOM_PARAM2_IDX] =
tx_buffer[RANDOM_PARAM2_IDX + 1] = 0;
return sha204c_send_and_receive(&tx_buffer[0], RANDOM_RSP_SIZE, &rx_buffer[0], RANDOM_DELAY,
RANDOM_EXEC_MAX - RANDOM_DELAY);
}
uint8_t atsha204Class::sha204m_dev_rev(uint8_t *tx_buffer, uint8_t *rx_buffer)
{
if (!tx_buffer || !rx_buffer) {
return SHA204_BAD_PARAM;
}
tx_buffer[SHA204_COUNT_IDX] = DEVREV_COUNT;
tx_buffer[SHA204_OPCODE_IDX] = SHA204_DEVREV;
// Parameters are 0.
tx_buffer[DEVREV_PARAM1_IDX] =
tx_buffer[DEVREV_PARAM2_IDX] =
tx_buffer[DEVREV_PARAM2_IDX + 1] = 0;
return sha204c_send_and_receive(&tx_buffer[0], DEVREV_RSP_SIZE, &rx_buffer[0],
DEVREV_DELAY, DEVREV_EXEC_MAX - DEVREV_DELAY);
}
uint8_t atsha204Class::sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone,
uint16_t address)
{
uint8_t rx_size;
if (!tx_buffer || !rx_buffer || ((zone & ~READ_ZONE_MASK) != 0)
|| ((zone & READ_ZONE_MODE_32_BYTES) && (zone == SHA204_ZONE_OTP))) {
return SHA204_BAD_PARAM;
}
address >>= 2;
if ((zone & SHA204_ZONE_MASK) == SHA204_ZONE_CONFIG) {
if (address > SHA204_ADDRESS_MASK_CONFIG) {
return SHA204_BAD_PARAM;
}
} else if ((zone & SHA204_ZONE_MASK) == SHA204_ZONE_OTP) {
if (address > SHA204_ADDRESS_MASK_OTP) {
return SHA204_BAD_PARAM;
}
} else if ((zone & SHA204_ZONE_MASK) == SHA204_ZONE_DATA) {
if (address > SHA204_ADDRESS_MASK) {
return SHA204_BAD_PARAM;
}
}
tx_buffer[SHA204_COUNT_IDX] = READ_COUNT;
tx_buffer[SHA204_OPCODE_IDX] = SHA204_READ;
tx_buffer[READ_ZONE_IDX] = zone;
tx_buffer[READ_ADDR_IDX] = (uint8_t) (address & SHA204_ADDRESS_MASK);
tx_buffer[READ_ADDR_IDX + 1] = 0;
rx_size = (zone & SHA204_ZONE_COUNT_FLAG) ? READ_32_RSP_SIZE : READ_4_RSP_SIZE;
return sha204c_send_and_receive(&tx_buffer[0], rx_size, &rx_buffer[0], READ_DELAY,
READ_EXEC_MAX - READ_DELAY);
}
uint8_t atsha204Class::sha204m_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3,
uint8_t *data3,
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer)
{
uint8_t poll_delay, poll_timeout, response_size;
uint8_t *p_buffer;
uint8_t len;
uint8_t ret_code = sha204m_check_parameters(op_code, param1, param2,
datalen1, data1, datalen2, data2, datalen3, data3,
tx_size, tx_buffer, rx_size, rx_buffer);
if (ret_code != SHA204_SUCCESS) {
return ret_code;
}
// Supply delays and response size.
switch (op_code) {
case SHA204_CHECKMAC:
poll_delay = CHECKMAC_DELAY;
poll_timeout = CHECKMAC_EXEC_MAX - CHECKMAC_DELAY;
response_size = CHECKMAC_RSP_SIZE;
break;
case SHA204_DERIVE_KEY:
poll_delay = DERIVE_KEY_DELAY;
poll_timeout = DERIVE_KEY_EXEC_MAX - DERIVE_KEY_DELAY;
response_size = DERIVE_KEY_RSP_SIZE;
break;
case SHA204_DEVREV:
poll_delay = DEVREV_DELAY;
poll_timeout = DEVREV_EXEC_MAX - DEVREV_DELAY;
response_size = DEVREV_RSP_SIZE;
break;
case SHA204_GENDIG:
poll_delay = GENDIG_DELAY;
poll_timeout = GENDIG_EXEC_MAX - GENDIG_DELAY;
response_size = GENDIG_RSP_SIZE;
break;
case SHA204_HMAC:
poll_delay = HMAC_DELAY;
poll_timeout = HMAC_EXEC_MAX - HMAC_DELAY;
response_size = HMAC_RSP_SIZE;
break;
case SHA204_LOCK:
poll_delay = LOCK_DELAY;
poll_timeout = LOCK_EXEC_MAX - LOCK_DELAY;
response_size = LOCK_RSP_SIZE;
break;
case SHA204_MAC:
poll_delay = MAC_DELAY;
poll_timeout = MAC_EXEC_MAX - MAC_DELAY;
response_size = MAC_RSP_SIZE;
break;
case SHA204_NONCE:
poll_delay = NONCE_DELAY;
poll_timeout = NONCE_EXEC_MAX - NONCE_DELAY;
response_size = param1 == NONCE_MODE_PASSTHROUGH
? NONCE_RSP_SIZE_SHORT : NONCE_RSP_SIZE_LONG;
break;
case SHA204_PAUSE:
poll_delay = PAUSE_DELAY;
poll_timeout = PAUSE_EXEC_MAX - PAUSE_DELAY;
response_size = PAUSE_RSP_SIZE;
break;
case SHA204_RANDOM:
poll_delay = RANDOM_DELAY;
poll_timeout = RANDOM_EXEC_MAX - RANDOM_DELAY;
response_size = RANDOM_RSP_SIZE;
break;
case SHA204_READ:
poll_delay = READ_DELAY;
poll_timeout = READ_EXEC_MAX - READ_DELAY;
response_size = (param1 & SHA204_ZONE_COUNT_FLAG)
? READ_32_RSP_SIZE : READ_4_RSP_SIZE;
break;
case SHA204_UPDATE_EXTRA:
poll_delay = UPDATE_DELAY;
poll_timeout = UPDATE_EXEC_MAX - UPDATE_DELAY;
response_size = UPDATE_RSP_SIZE;
break;
case SHA204_WRITE:
poll_delay = WRITE_DELAY;
poll_timeout = WRITE_EXEC_MAX - WRITE_DELAY;
response_size = WRITE_RSP_SIZE;
break;
default:
poll_delay = 0;
poll_timeout = SHA204_COMMAND_EXEC_MAX;
response_size = rx_size;
}
// Assemble command.
len = datalen1 + datalen2 + datalen3 + SHA204_CMD_SIZE_MIN;
p_buffer = tx_buffer;
*p_buffer++ = len;
*p_buffer++ = op_code;
*p_buffer++ = param1;
*p_buffer++ = param2 & 0xFF;
*p_buffer++ = param2 >> 8;
if (datalen1 > 0) {
memcpy(p_buffer, data1, datalen1);
p_buffer += datalen1;
}
if (datalen2 > 0) {
memcpy(p_buffer, data2, datalen2);
p_buffer += datalen2;
}
if (datalen3 > 0) {
memcpy(p_buffer, data3, datalen3);
p_buffer += datalen3;
}
sha204c_calculate_crc(len - SHA204_CRC_SIZE, tx_buffer, p_buffer);
// Send command and receive response.
return sha204c_send_and_receive(&tx_buffer[0], response_size,
&rx_buffer[0], poll_delay, poll_timeout);
}
uint8_t atsha204Class::sha204m_check_parameters(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3,
uint8_t *data3,
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer)
{
#ifdef SHA204_CHECK_PARAMETERS
uint8_t len = datalen1 + datalen2 + datalen3 + SHA204_CMD_SIZE_MIN;
if (!tx_buffer || tx_size < len || rx_size < SHA204_RSP_SIZE_MIN || !rx_buffer) {
return SHA204_BAD_PARAM;
}
if ((datalen1 > 0 && !data1) || (datalen2 > 0 && !data2) || (datalen3 > 0 && !data3)) {
return SHA204_BAD_PARAM;
}
// Check parameters depending on op-code.
switch (op_code) {
case SHA204_CHECKMAC:
if (
// no null pointers allowed
!data1 || !data2
// No reserved bits should be set.
|| (param1 | CHECKMAC_MODE_MASK) != CHECKMAC_MODE_MASK
// key_id > 15 not allowed
|| param2 > SHA204_KEY_ID_MAX
) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_DERIVE_KEY:
if (param2 > SHA204_KEY_ID_MAX) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_DEVREV:
break;
case SHA204_GENDIG:
if ((param1 != GENDIG_ZONE_OTP) && (param1 != GENDIG_ZONE_DATA)) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_HMAC:
if ((param1 & ~HMAC_MODE_MASK) != 0) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_LOCK:
if (((param1 & ~LOCK_ZONE_MASK) != 0)
|| ((param1 & LOCK_ZONE_NO_CRC) && (param2 != 0))) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_MAC:
if (((param1 & ~MAC_MODE_MASK) != 0)
|| (((param1 & MAC_MODE_BLOCK2_TEMPKEY) == 0) && !data1)) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_NONCE:
if ( !data1
|| (param1 > NONCE_MODE_PASSTHROUGH)
|| (param1 == NONCE_MODE_INVALID)
) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_PAUSE:
break;
case SHA204_RANDOM:
if (param1 > RANDOM_NO_SEED_UPDATE) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_READ:
if (((param1 & ~READ_ZONE_MASK) != 0)
|| ((param1 & READ_ZONE_MODE_32_BYTES) && (param1 == SHA204_ZONE_OTP))) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_TEMPSENSE:
break;
case SHA204_UPDATE_EXTRA:
if (param1 > UPDATE_CONFIG_BYTE_86) {
return SHA204_BAD_PARAM;
}
break;
case SHA204_WRITE:
if (!data1 || ((param1 & ~WRITE_ZONE_MASK) != 0)) {
return SHA204_BAD_PARAM;
}
break;
default:
// unknown op-code
return SHA204_BAD_PARAM;
}
return SHA204_SUCCESS;
#else
(void)rx_size;
(void)tx_size;
(void)tx_buffer;
(void)rx_buffer;
(void)param1;
(void)param2;
(void)data1;
(void)data2;
(void)data3;
(void)datalen1;
(void)datalen2;
(void)datalen3;
(void)op_code;
return SHA204_SUCCESS;
#endif
}
/* CRC Calculator and Checker */
void atsha204Class::sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc)
{
uint16_t crc_register = 0;
crc_register = calculateAndUpdateCrc(length, data, crc_register);
crc[0] = (uint8_t) (crc_register & 0x00FF);
crc[1] = (uint8_t) (crc_register >> 8);
}
uint8_t atsha204Class::sha204c_check_crc(uint8_t *response)
{
uint8_t crc[SHA204_CRC_SIZE];
uint8_t count = response[SHA204_BUFFER_POS_COUNT];
count -= SHA204_CRC_SIZE;
sha204c_calculate_crc(count, response, crc);
return (crc[0] == response[count] && crc[1] == response[count + 1])
? SHA204_SUCCESS : SHA204_BAD_CRC;
}

View File

@@ -0,0 +1,467 @@
#include "Arduino.h"
#ifndef sha204_library_H
#define sha204_library_H
/* bitbang_config.h */
#define PORT_ACCESS_TIME (630) //! time it takes to toggle the pin at CPU clock of 16 MHz (ns)
#define START_PULSE_WIDTH (4340) //! width of start pulse (ns)
#define BIT_DELAY (4) //! delay macro for width of one pulse (start pulse or zero pulse, in ns)
#define RX_TX_DELAY (15) //! turn around time when switching from receive to transmit
#define START_PULSE_TIME_OUT (255) //! This value is decremented while waiting for the falling edge of a start pulse.
#define ZERO_PULSE_TIME_OUT (26) //! This value is decremented while waiting for the falling edge of a zero pulse.
/* swi_phys.h */
#define SWI_FUNCTION_RETCODE_SUCCESS ((uint8_t) 0x00) //!< Communication with device succeeded.
#define SWI_FUNCTION_RETCODE_TIMEOUT ((uint8_t) 0xF1) //!< Communication timed out.
#define SWI_FUNCTION_RETCODE_RX_FAIL ((uint8_t) 0xF9) //!< Communication failed after at least one byte was received.
/* sha204_physical.h */
#define SHA204_RSP_SIZE_MIN ((uint8_t) 4) //!< minimum number of bytes in response
#define SHA204_RSP_SIZE_MAX ((uint8_t) 35) //!< maximum size of response packet
#define SHA204_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response
#define SHA204_BUFFER_POS_DATA (1) //!< buffer index of data in response
#define SHA204_WAKEUP_PULSE_WIDTH (uint8_t) (6.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) //! width of Wakeup pulse in 10 us units
#define SHA204_WAKEUP_DELAY (uint8_t) (3.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) //! delay between Wakeup pulse and communication in ms
/* sha204_swi.c */
#define SHA204_SWI_FLAG_CMD ((uint8_t) 0x77) //!< flag preceding a command
#define SHA204_SWI_FLAG_TX ((uint8_t) 0x88) //!< flag requesting a response
#define SHA204_SWI_FLAG_IDLE ((uint8_t) 0xBB) //!< flag requesting to go into Idle mode
#define SHA204_SWI_FLAG_SLEEP ((uint8_t) 0xCC) //!< flag requesting to go into Sleep mode
/* sha204_comm_marshaling.h */
// command op-code definitions
#define SHA204_CHECKMAC ((uint8_t) 0x28) //!< CheckMac command op-code
#define SHA204_DERIVE_KEY ((uint8_t) 0x1C) //!< DeriveKey command op-code
#define SHA204_DEVREV ((uint8_t) 0x30) //!< DevRev command op-code
#define SHA204_GENDIG ((uint8_t) 0x15) //!< GenDig command op-code
#define SHA204_HMAC ((uint8_t) 0x11) //!< HMAC command op-code
#define SHA204_LOCK ((uint8_t) 0x17) //!< Lock command op-code
#define SHA204_MAC ((uint8_t) 0x08) //!< MAC command op-code
#define SHA204_NONCE ((uint8_t) 0x16) //!< Nonce command op-code
#define SHA204_PAUSE ((uint8_t) 0x01) //!< Pause command op-code
#define SHA204_RANDOM ((uint8_t) 0x1B) //!< Random command op-code
#define SHA204_READ ((uint8_t) 0x02) //!< Read command op-code
#define SHA204_UPDATE_EXTRA ((uint8_t) 0x20) //!< UpdateExtra command op-code
#define SHA204_WRITE ((uint8_t) 0x12) //!< Write command op-code
// packet size definitions
#define SHA204_RSP_SIZE_VAL ((uint8_t) 7) //!< size of response packet containing four bytes of data
// parameter range definitions
#define SHA204_KEY_ID_MAX ((uint8_t) 15) //!< maximum value for key id
#define SHA204_OTP_BLOCK_MAX ((uint8_t) 1) //!< maximum value for OTP block
// definitions for command packet indexes common to all commands
#define SHA204_COUNT_IDX ( 0) //!< command packet index for count
#define SHA204_OPCODE_IDX ( 1) //!< command packet index for op-code
#define SHA204_PARAM1_IDX ( 2) //!< command packet index for first parameter
#define SHA204_PARAM2_IDX ( 3) //!< command packet index for second parameter
#define SHA204_DATA_IDX ( 5) //!< command packet index for second parameter
// zone definitions
#define SHA204_ZONE_CONFIG ((uint8_t) 0x00) //!< Configuration zone
#define SHA204_ZONE_OTP ((uint8_t) 0x01) //!< OTP (One Time Programming) zone
#define SHA204_ZONE_DATA ((uint8_t) 0x02) //!< Data zone
#define SHA204_ZONE_MASK ((uint8_t) 0x03) //!< Zone mask
#define SHA204_ZONE_COUNT_FLAG ((uint8_t) 0x80) //!< Zone bit 7 set: Access 32 bytes, otherwise 4 bytes.
#define SHA204_ZONE_ACCESS_4 ((uint8_t) 4) //!< Read or write 4 bytes.
#define SHA204_ZONE_ACCESS_32 ((uint8_t) 32) //!< Read or write 32 bytes.
#define SHA204_ADDRESS_MASK_CONFIG ( 0x001F) //!< Address bits 5 to 7 are 0 for Configuration zone.
#define SHA204_ADDRESS_MASK_OTP ( 0x000F) //!< Address bits 4 to 7 are 0 for OTP zone.
#define SHA204_ADDRESS_MASK ( 0x007F) //!< Address bit 7 to 15 are always 0.
// CheckMAC command definitions
#define CHECKMAC_MODE_IDX SHA204_PARAM1_IDX //!< CheckMAC command index for mode
#define CHECKMAC_KEYID_IDX SHA204_PARAM2_IDX //!< CheckMAC command index for key identifier
#define CHECKMAC_CLIENT_CHALLENGE_IDX SHA204_DATA_IDX //!< CheckMAC command index for client challenge
#define CHECKMAC_CLIENT_RESPONSE_IDX (37) //!< CheckMAC command index for client response
#define CHECKMAC_DATA_IDX (69) //!< CheckMAC command index for other data
#define CHECKMAC_COUNT (84) //!< CheckMAC command packet size
#define CHECKMAC_MODE_MASK ((uint8_t) 0x27) //!< CheckMAC mode bits 3, 4, 6, and 7 are 0.
#define CHECKMAC_CLIENT_CHALLENGE_SIZE (32) //!< CheckMAC size of client challenge
#define CHECKMAC_CLIENT_RESPONSE_SIZE (32) //!< CheckMAC size of client response
#define CHECKMAC_OTHER_DATA_SIZE (13) //!< CheckMAC size of "other data"
// DeriveKey command definitions
#define DERIVE_KEY_RANDOM_IDX SHA204_PARAM1_IDX //!< DeriveKey command index for random bit
#define DERIVE_KEY_TARGETKEY_IDX SHA204_PARAM2_IDX //!< DeriveKey command index for target slot
#define DERIVE_KEY_MAC_IDX SHA204_DATA_IDX //!< DeriveKey command index for optional MAC
#define DERIVE_KEY_COUNT_SMALL SHA204_CMD_SIZE_MIN //!< DeriveKey command packet size without MAC
#define DERIVE_KEY_COUNT_LARGE (39) //!< DeriveKey command packet size with MAC
#define DERIVE_KEY_RANDOM_FLAG ((uint8_t) 4) //!< DeriveKey 1. parameter
#define DERIVE_KEY_MAC_SIZE (32) //!< DeriveKey MAC size
// DevRev command definitions
#define DEVREV_PARAM1_IDX SHA204_PARAM1_IDX //!< DevRev command index for 1. parameter (ignored)
#define DEVREV_PARAM2_IDX SHA204_PARAM2_IDX //!< DevRev command index for 2. parameter (ignored)
#define DEVREV_COUNT SHA204_CMD_SIZE_MIN //!< DevRev command packet size
// GenDig command definitions
#define GENDIG_ZONE_IDX SHA204_PARAM1_IDX //!< GenDig command index for zone
#define GENDIG_KEYID_IDX SHA204_PARAM2_IDX //!< GenDig command index for key id
#define GENDIG_DATA_IDX SHA204_DATA_IDX //!< GenDig command index for optional data
#define GENDIG_COUNT SHA204_CMD_SIZE_MIN //!< GenDig command packet size without "other data"
#define GENDIG_COUNT_DATA (11) //!< GenDig command packet size with "other data"
#define GENDIG_OTHER_DATA_SIZE (4) //!< GenDig size of "other data"
#define GENDIG_ZONE_CONFIG ((uint8_t) 0) //!< GenDig zone id config
#define GENDIG_ZONE_OTP ((uint8_t) 1) //!< GenDig zone id OTP
#define GENDIG_ZONE_DATA ((uint8_t) 2) //!< GenDig zone id data
// HMAC command definitions
#define HMAC_MODE_IDX SHA204_PARAM1_IDX //!< HMAC command index for mode
#define HMAC_KEYID_IDX SHA204_PARAM2_IDX //!< HMAC command index for key id
#define HMAC_COUNT SHA204_CMD_SIZE_MIN //!< HMAC command packet size
#define HMAC_MODE_MASK ((uint8_t) 0x74) //!< HMAC mode bits 0, 1, 3, and 7 are 0.
// Lock command definitions
#define LOCK_ZONE_IDX SHA204_PARAM1_IDX //!< Lock command index for zone
#define LOCK_SUMMARY_IDX SHA204_PARAM2_IDX //!< Lock command index for summary
#define LOCK_COUNT SHA204_CMD_SIZE_MIN //!< Lock command packet size
#define LOCK_ZONE_NO_CONFIG ((uint8_t) 0x01) //!< Lock zone is OTP or Data
#define LOCK_ZONE_NO_CRC ((uint8_t) 0x80) //!< Lock command: Ignore summary.
#define LOCK_ZONE_MASK (0x81) //!< Lock parameter 1 bits 2 to 6 are 0.
// Mac command definitions
#define MAC_MODE_IDX SHA204_PARAM1_IDX //!< MAC command index for mode
#define MAC_KEYID_IDX SHA204_PARAM2_IDX //!< MAC command index for key id
#define MAC_CHALLENGE_IDX SHA204_DATA_IDX //!< MAC command index for optional challenge
#define MAC_COUNT_SHORT SHA204_CMD_SIZE_MIN //!< MAC command packet size without challenge
#define MAC_COUNT_LONG (39) //!< MAC command packet size with challenge
#define MAC_MODE_BLOCK2_TEMPKEY ((uint8_t) 0x01) //!< MAC mode bit 0: second SHA block from TempKey
#define MAC_MODE_BLOCK1_TEMPKEY ((uint8_t) 0x02) //!< MAC mode bit 1: first SHA block from TempKey
#define MAC_MODE_SOURCE_FLAG_MATCH ((uint8_t) 0x04) //!< MAC mode bit 2: match TempKey.SourceFlag
#define MAC_MODE_PASSTHROUGH ((uint8_t) 0x07) //!< MAC mode bit 0-2: pass-through mode
#define MAC_MODE_INCLUDE_OTP_88 ((uint8_t) 0x10) //!< MAC mode bit 4: include first 88 OTP bits
#define MAC_MODE_INCLUDE_OTP_64 ((uint8_t) 0x20) //!< MAC mode bit 5: include first 64 OTP bits
#define MAC_MODE_INCLUDE_SN ((uint8_t) 0x40) //!< MAC mode bit 6: include serial number
#define MAC_CHALLENGE_SIZE (32) //!< MAC size of challenge
#define MAC_MODE_MASK ((uint8_t) 0x77) //!< MAC mode bits 3 and 7 are 0.
// Nonce command definitions
#define NONCE_MODE_IDX SHA204_PARAM1_IDX //!< Nonce command index for mode
#define NONCE_PARAM2_IDX SHA204_PARAM2_IDX //!< Nonce command index for 2. parameter
#define NONCE_INPUT_IDX SHA204_DATA_IDX //!< Nonce command index for input data
#define NONCE_COUNT_SHORT (27) //!< Nonce command packet size for 20 bytes of data
#define NONCE_COUNT_LONG (39) //!< Nonce command packet size for 32 bytes of data
#define NONCE_MODE_MASK ((uint8_t) 3) //!< Nonce mode bits 2 to 7 are 0.
#define NONCE_MODE_SEED_UPDATE ((uint8_t) 0x00) //!< Nonce mode: update seed
#define NONCE_MODE_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Nonce mode: do not update seed
#define NONCE_MODE_INVALID ((uint8_t) 0x02) //!< Nonce mode 2 is invalid.
#define NONCE_MODE_PASSTHROUGH ((uint8_t) 0x03) //!< Nonce mode: pass-through
#define NONCE_NUMIN_SIZE (20) //!< Nonce data length
#define NONCE_NUMIN_SIZE_PASSTHROUGH (32) //!< Nonce data length in pass-through mode (mode = 3)
// Pause command definitions
#define PAUSE_SELECT_IDX SHA204_PARAM1_IDX //!< Pause command index for Selector
#define PAUSE_PARAM2_IDX SHA204_PARAM2_IDX //!< Pause command index for 2. parameter
#define PAUSE_COUNT SHA204_CMD_SIZE_MIN //!< Pause command packet size
// Random command definitions
#define RANDOM_MODE_IDX SHA204_PARAM1_IDX //!< Random command index for mode
#define RANDOM_PARAM2_IDX SHA204_PARAM2_IDX //!< Random command index for 2. parameter
#define RANDOM_COUNT SHA204_CMD_SIZE_MIN //!< Random command packet size
#define RANDOM_SEED_UPDATE ((uint8_t) 0x00) //!< Random mode for automatic seed update
#define RANDOM_NO_SEED_UPDATE ((uint8_t) 0x01) //!< Random mode for no seed update
// Read command definitions
#define READ_ZONE_IDX SHA204_PARAM1_IDX //!< Read command index for zone
#define READ_ADDR_IDX SHA204_PARAM2_IDX //!< Read command index for address
#define READ_COUNT SHA204_CMD_SIZE_MIN //!< Read command packet size
#define READ_ZONE_MASK ((uint8_t) 0x83) //!< Read zone bits 2 to 6 are 0.
#define READ_ZONE_MODE_32_BYTES ((uint8_t) 0x80) //!< Read mode: 32 bytes
// UpdateExtra command definitions
#define UPDATE_MODE_IDX SHA204_PARAM1_IDX //!< UpdateExtra command index for mode
#define UPDATE_VALUE_IDX SHA204_PARAM2_IDX //!< UpdateExtra command index for new value
#define UPDATE_COUNT SHA204_CMD_SIZE_MIN //!< UpdateExtra command packet size
#define UPDATE_CONFIG_BYTE_86 ((uint8_t) 0x01) //!< UpdateExtra mode: update Config byte 86
// Write command definitions
#define WRITE_ZONE_IDX SHA204_PARAM1_IDX //!< Write command index for zone
#define WRITE_ADDR_IDX SHA204_PARAM2_IDX //!< Write command index for address
#define WRITE_VALUE_IDX SHA204_DATA_IDX //!< Write command index for data
#define WRITE_MAC_VS_IDX ( 9) //!< Write command index for MAC following short data
#define WRITE_MAC_VL_IDX (37) //!< Write command index for MAC following long data
#define WRITE_COUNT_SHORT (11) //!< Write command packet size with short data and no MAC
#define WRITE_COUNT_LONG (39) //!< Write command packet size with long data and no MAC
#define WRITE_COUNT_SHORT_MAC (43) //!< Write command packet size with short data and MAC
#define WRITE_COUNT_LONG_MAC (71) //!< Write command packet size with long data and MAC
#define WRITE_MAC_SIZE (32) //!< Write MAC size
#define WRITE_ZONE_MASK ((uint8_t) 0xC3) //!< Write zone bits 2 to 5 are 0.
#define WRITE_ZONE_WITH_MAC ((uint8_t) 0x40) //!< Write zone bit 6: write encrypted with MAC
// Response size definitions
#define CHECKMAC_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of DeriveKey command
#define DERIVE_KEY_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of DeriveKey command
#define DEVREV_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of DevRev command returns 4 bytes
#define GENDIG_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of GenDig command
#define HMAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of HMAC command
#define LOCK_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Lock command
#define MAC_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of MAC command
#define NONCE_RSP_SIZE_SHORT SHA204_RSP_SIZE_MIN //!< response size of Nonce command with mode[0:1] = 3
#define NONCE_RSP_SIZE_LONG SHA204_RSP_SIZE_MAX //!< response size of Nonce command
#define PAUSE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Pause command
#define RANDOM_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Random command
#define READ_4_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of Read command when reading 4 bytes
#define READ_32_RSP_SIZE SHA204_RSP_SIZE_MAX //!< response size of Read command when reading 32 bytes
#define TEMP_SENSE_RSP_SIZE SHA204_RSP_SIZE_VAL //!< response size of TempSense command returns 4 bytes
#define UPDATE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of UpdateExtra command
#define WRITE_RSP_SIZE SHA204_RSP_SIZE_MIN //!< response size of Write command
// command timing definitions for minimum execution times (ms)
#define CHECKMAC_DELAY ((uint8_t) (12.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define DERIVE_KEY_DELAY ((uint8_t) (14.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define DEVREV_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define GENDIG_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define HMAC_DELAY ((uint8_t) (27.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define LOCK_DELAY ((uint8_t) ( 5.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define MAC_DELAY ((uint8_t) (12.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define NONCE_DELAY ((uint8_t) (22.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define PAUSE_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define RANDOM_DELAY ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define READ_DELAY ((uint8_t) ( 0.4 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define TEMP_SENSE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define UPDATE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
#define WRITE_DELAY ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_NEGATIVE - 0.5))
// command timing definitions for maximum execution times (ms)
#define CHECKMAC_EXEC_MAX ((uint8_t) (38.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define DERIVE_KEY_EXEC_MAX ((uint8_t) (62.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define DEVREV_EXEC_MAX ((uint8_t) ( 2.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define GENDIG_EXEC_MAX ((uint8_t) (43.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define HMAC_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define LOCK_EXEC_MAX ((uint8_t) (24.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define MAC_EXEC_MAX ((uint8_t) (35.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define NONCE_EXEC_MAX ((uint8_t) (60.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define PAUSE_EXEC_MAX ((uint8_t) ( 2.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define RANDOM_EXEC_MAX ((uint8_t) (50.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define READ_EXEC_MAX ((uint8_t) ( 4.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define TEMP_SENSE_EXEC_MAX ((uint8_t) (11.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define UPDATE_EXEC_MAX ((uint8_t) ( 6.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
#define WRITE_EXEC_MAX ((uint8_t) (42.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5))
/* from sha204_config.h */
#define CPU_CLOCK_DEVIATION_POSITIVE (1.01)
#define CPU_CLOCK_DEVIATION_NEGATIVE (0.99)
#define SHA204_RETRY_COUNT (1)
#define SWI_RECEIVE_TIME_OUT ((uint16_t) 163) //! #START_PULSE_TIME_OUT in us instead of loop counts
#define SWI_US_PER_BYTE ((uint16_t) 313) //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits).
#define SHA204_SYNC_TIMEOUT ((uint8_t) 85)//! delay before sending a transmit flag in the synchronization routine
#define SHA204_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag.
/* from sha204_comm.h */
#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)
#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
#define SHA204_BUFFER_POS_DATA (1) //! buffer index of first data byte in data response
#define SHA204_STATUS_BYTE_WAKEUP ((uint8_t) 0x11) //! command parse error
#define SHA204_STATUS_BYTE_PARSE ((uint8_t) 0x03) //! command parse error
#define SHA204_STATUS_BYTE_EXEC ((uint8_t) 0x0F) //! command execution error
#define SHA204_STATUS_BYTE_COMM ((uint8_t) 0xFF) //! communication error
/* EEPROM Addresses */
/* Configuration Zone */
#define ADDRESS_SN03 0 // SN[0:3] are bytes 0->3 of configuration zone
#define ADDRESS_RevNum 4 // bytes 4->7 of config zone are RevNum
#define ADDRESS_SN47 8 // SN[4:7] are bytes 8->11 of config zone
#define ADDRESS_SN8 12 // SN[8] is byte 12 of config zone, should be 0xEE
#define ADDRESS_I2CEN 14 // I2C Enable, bit 0 represents I2C enable status
#define ADDRESS_I2CADD 16 // Defines I2C address of SHA204
#define ADDRESS_OTPMODE 18 // Sets the One-time-programmable mode
#define ADDRESS_SELECTOR 19 // Controls writability of Selector
/* 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)
#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)
#endif
/**
* atsha204Class class
*/
class atsha204Class
{
private:
uint8_t device_pin;
#ifdef ARDUINO_ARCH_AVR
volatile uint8_t *device_port_DDR, *device_port_OUT, *device_port_IN;
#endif
void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc);
uint8_t sha204c_check_crc(uint8_t *response);
void swi_set_signal_pin(uint8_t is_high);
uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer);
uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer);
uint8_t swi_send_byte(uint8_t value);
uint8_t sha204p_receive_response(uint8_t size, uint8_t *response);
uint8_t sha204p_wakeup();
uint8_t sha204p_send_command(uint8_t count, uint8_t * command);
uint8_t sha204p_sleep();
uint8_t sha204p_resync(uint8_t size, uint8_t *response);
public:
/**
* @brief Constructor
*
* @param[in] pin The pin to use for communication
*/
explicit atsha204Class(uint8_t pin);
/**
* @brief Wake up device
*
* @param response The response from the device
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204c_wakeup(uint8_t *response);
/**
* @brief Send and receive data
*
* @param tx_buffer The transmit buffer
* @param[in] rx_size The receive size
* @param rx_buffer The receive buffer
* @param[in] execution_delay The execution delay
* @param[in] execution_timeout The execution timeout
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer,
uint8_t execution_delay, uint8_t execution_timeout);
/**
* @brief Resyncronize the device
*
* @param[in] size The size of the response buffer
* @param response The response
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204c_resync(uint8_t size, uint8_t *response);
/**
* @brief Generate random data
*
* @param tx_buffer The transmit buffer
* @param rx_buffer The receive buffer
* @param[in] mode The mode
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204m_random(uint8_t * tx_buffer, uint8_t * rx_buffer, uint8_t mode);
/**
* @brief Read device revision
*
* @param tx_buffer The transmit buffer
* @param rx_buffer The receive buffer
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204m_dev_rev(uint8_t *tx_buffer, uint8_t *rx_buffer);
/**
* @brief Read from device
*
* @param tx_buffer The transmit buffer
* @param rx_buffer The receive buffer
* @param[in] zone The zone
* @param[in] address The address
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204m_read(uint8_t *tx_buffer, uint8_t *rx_buffer, uint8_t zone, uint16_t address);
/**
* @brief Execute command
*
* @param[in] op_code The operation code
* @param[in] param1 The parameter 1
* @param[in] param2 The parameter 2
* @param[in] datalen1 The datalen 1
* @param data1 The data 1
* @param[in] datalen2 The datalen 2
* @param data2 The data 2
* @param[in] datalen3 The datalen 3
* @param data3 The data 3
* @param[in] tx_size The transmit size
* @param tx_buffer The transmit buffer
* @param[in] rx_size The receive size
* @param rx_buffer The receive buffer
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204m_execute(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3,
uint8_t *data3,
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
/**
* @brief Validate parameters
*
* @param[in] op_code The operation code
* @param[in] param1 The parameter 1
* @param[in] param2 The parameter 2
* @param[in] datalen1 The datalen 1
* @param data1 The data 1
* @param[in] datalen2 The datalen 2
* @param data2 The data 2
* @param[in] datalen3 The datalen 3
* @param data3 The data 3
* @param[in] tx_size The transmit size
* @param tx_buffer The transmit buffer
* @param[in] rx_size The receive size
* @param rx_buffer The receive buffer
*
* @return Error code (SHA204_SUCCESS if OK)
*/
uint8_t sha204m_check_parameters(uint8_t op_code, uint8_t param1, uint16_t param2,
uint8_t datalen1, uint8_t *data1, uint8_t datalen2, uint8_t *data2, uint8_t datalen3,
uint8_t *data3,
uint8_t tx_size, uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer);
/**
* @brief Gets the serial number.
*
* @param response The response
*
* @return The serial number
*/
uint8_t getSerialNumber(uint8_t *response);
/**
* @brief Calculates and update crc.
*
* @param[in] length The length
* @param data The data
* @param[in] current_crc The current crc
*
* @return The updated crc
*/
uint16_t calculateAndUpdateCrc(uint8_t length, uint8_t *data, uint16_t current_crc);
};
#endif

View File

@@ -0,0 +1,281 @@
/**
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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 serial 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 received. In inclusion mode will blink fast only on presentation received
* - Green : TX - Blink fast on radio message transmitted. In inclusion mode will blink slowly
* - Red : ERR - Fast blink on error during transmission error or receive crc error
* - Blue : free - (use with LED_BLUE macro)
*
*/
#define SKETCH_VERSION "0.2"
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
// Set LOW transmit power level as default, if you have an amplified NRF-module and
// power your radio separately with a good regulator you can turn up PA level.
#define MY_RF24_PA_LEVEL RF24_PA_HIGH
// Enable serial gateway
#define MY_GATEWAY_SERIAL
// Define a lower baud rate for Arduinos running on 8 MHz (Arduino Pro Mini 3.3V & Sensebender)
#if F_CPU == 8000000L
#define MY_BAUD_RATE 38400
#endif
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE
// Inverses behavior of inclusion button (if using external pullup)
//#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Inverses the behavior of leds
//#define MY_WITH_LEDS_BLINKING_INVERSE
// Flash leds on rx/tx/err
// Uncomment to override default HW configurations
//#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin
//#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin
//#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED
#include <MySensors.h>
#include <SD.h>
#include <drivers/ATSHA204/ATSHA204.cpp>
Sd2Card card;
#define EEPROM_VERIFICATION_ADDRESS 0x01
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 presentation()
{
// Present locally attached sensors
}
void loop()
{
// Send locally attached sensor data here
}
void preHwInit()
{
pinMode(MY_SWC1, INPUT_PULLUP);
pinMode(MY_SWC2, INPUT_PULLUP);
if (digitalRead(MY_SWC1) && digitalRead(MY_SWC2)) {
return;
}
uint8_t tests = 0;
for (int i=0; i< num_of_leds; i++) {
pinMode(leds[i], OUTPUT);
}
if (digitalRead(MY_SWC1)) {
uint8_t led_state = 0;
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);
}
}
}
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;
}
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 ");
eeprom_d1 = hwReadConfig(EEPROM_VERIFICATION_ADDRESS);
delay(500);
eeprom_d1 = ~eeprom_d1; // invert the bits
hwWriteConfig(EEPROM_VERIFICATION_ADDRESS, eeprom_d1);
delay(500);
eeprom_d2 = hwReadConfig(EEPROM_VERIFICATION_ADDRESS);
if (eeprom_d1 == eeprom_d2) {
SerialUSB.println("PASSED");
hwWriteConfig(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;
}

View File

@@ -0,0 +1,198 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* 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:
* DIY: See http://vanderleevineyard.com/1/category/vinduino/1.html
* 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.
*
* Connection:
* D6, D7: alternative powering to avoid sensor degradation
* A0, A1: alternative resistance measuring
*
* Based on:
* "Vinduino" portable soil moisture sensor code V3.00
* Date December 31, 2012
* Reinier van der Lee and Theodore Kaskalis
* www.vanderleevineyard.com
* Contributor: epierre
*/
// Copyright (C) 2015, Reinier van der Lee
// www.vanderleevineyard.com
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <math.h> // Conversion equation from resistance to %
#include <MySensors.h>
// Setting up format for reading 3 soil sensors
#define NUM_READS (int)10 // Number of sensor reads for filtering
#define CHILD_ID 0
MyMessage msg(CHILD_ID, V_LEVEL);
uint32_t SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
long buffer[NUM_READS];
int idx;
/// @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
} values;
const long knownResistor = 4700; // Constant value of known resistor in Ohms
int supplyVoltage; // Measured supply voltage
int sensorVoltage; // Measured sensor voltage
values valueOf[NUM_READS]; // Calculated moisture percentages and resistances to be sorted and filtered
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);
// 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_MOISTURE);
}
void loop()
{
measure(6,7,1);
Serial.print ("\t");
Serial.println (average());
long read1 = average();
measure(7,6,0);
Serial.print ("\t");
Serial.println (average());
long read2= average();
long sensor1 = (read1 + read2)/2;
Serial.print ("resistance bias =" );
Serial.println (read1-read2);
Serial.print ("sensor bias compensated value = ");
Serial.println (sensor1);
Serial.println ();
//send back the values
send(msg.set((int32_t)ceil(sensor1)));
// delay until next measurement (msec)
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
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);
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) ;
delay(1);
addReading(resistance);
Serial.print (resistance);
Serial.print ("\t");
}
}
// Averaging algorithm
void addReading(long resistance)
{
buffer[idx] = resistance;
idx++;
if (idx >= NUM_READS) {
idx = 0;
}
}
long average()
{
long sum = 0;
for (int cnt = 0; cnt < NUM_READS; cnt++) {
sum += buffer[cnt];
}
return (long)(sum / NUM_READS);
}

View File

@@ -0,0 +1,111 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* 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
*
* Connect sensor:
*
* + >>> 5V
* - >>> GND
* out >>> A0
*
* License: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define UV_SENSOR_ANALOG_PIN 0
#define CHILD_ID_UV 0
uint32_t SLEEP_TIME = 30*1000; // Sleep time between reads (in milliseconds)
MyMessage uvMsg(CHILD_ID_UV, V_UV);
uint32_t 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()
{
uint32_t 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);
}

View File

@@ -0,0 +1,101 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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
*
* Vibration Sensor
*
* connect the sensor as follows :
*
* VCC >>> 5V
* S >>> D3
* GND >>> GND
*
* Based on: http://www.dfrobot.com/wiki/index.php/DFRobot_Digital_Vibration_Sensor_V2_SKU:DFR0027
* Contributor: epierre
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#include <Wire.h>
#define CHILD_ID_VIBRATION 0
#define VIBRATION_SENSOR_DIGITAL_PIN 3
#define SensorLED 13
uint32_t SLEEP_TIME = 10*1000; // Sleep time between reads (in seconds)
//VARIABLES
int val = 0; // variable to store the value coming from the sensor
float valVIBRATION =0.0;
float lastVIBRATION =0.0;
unsigned char state = 0;
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);
}
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);
}
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);
}
// 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
}
void blink()//Interrupts function
{
state++;
}

View File

@@ -0,0 +1,194 @@
/*
* 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-2019 Sensnology AB
* Full contributor list: https://github.com/mysensors/MySensors/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.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik Ekblad
* Version 1.1 - GizMoCuz
*
* DESCRIPTION
* Use this sensor to measure volume and flow of your house water meter.
* 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
* to calculate/report flow.
* http://www.mysensors.org/build/pulse_water
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_RF24
//#define MY_RADIO_NRF5_ESB
//#define MY_RADIO_RFM69
//#define MY_RADIO_RFM95
#include <MySensors.h>
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!)
#define PULSE_FACTOR 1000 // Number of blinks per m3 of your meter (One rotation/liter)
#define SLEEP_MODE false // flowvalue can only be reported when sleep mode is false.
#define MAX_FLOW 40 // Max flow (l/min) value to report. This filters outliers.
#define CHILD_ID 1 // Id of the sensor child
uint32_t 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);
MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
double ppl = ((double)PULSE_FACTOR)/1000; // Pulses per liter
volatile uint32_t pulseCount = 0;
volatile uint32_t lastBlink = 0;
volatile double flow = 0;
bool pcReceived = false;
uint32_t oldPulseCount = 0;
double oldflow = 0;
double oldvolume =0;
uint32_t lastSend =0;
uint32_t lastPulse =0;
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
#define IRQ_HANDLER_ATTR ICACHE_RAM_ATTR
#else
#define IRQ_HANDLER_ATTR
#endif
void IRQ_HANDLER_ATTR onPulse()
{
if (!SLEEP_MODE) {
uint32_t newBlink = micros();
uint32_t interval = newBlink-lastBlink;
if (interval!=0) {
lastPulse = millis();
if (interval<500000L) {
// Sometimes we get interrupt on RISING, 500000 = 0.5 second debounce ( max 120 l/min)
return;
}
flow = (60000000.0 /interval) / ppl;
}
lastBlink = newBlink;
}
pulseCount++;
}
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 Water flow sensor
present(CHILD_ID, S_WATER);
}
void loop()
{
uint32_t 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 don't get unreasonable large flow value.
// could happen when long wraps or false interrupt triggered
if (flow<((uint32_t)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, false);
}
}
void receive(const MyMessage &message)
{
if (message.getType()==V_VAR1) {
uint32_t gwPulseCount=message.getULong();
pulseCount += gwPulseCount;
flow=oldflow=0;
Serial.print("Received last pulse count from gw:");
Serial.println(pulseCount);
pcReceived = true;
}
}