Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions libraries/MySensors/MyConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,26 @@
#define MY_OTA_FLASH_JDECID 0x1F65


/**********************************
* Information LEDs blinking
***********************************/
// This feature enables LEDs blinking on message receive, transmit
// or if some error occured. This was commonly used only in gateways,
// but now can be used in any sensor node. Also the LEDs can now be
// disabled in the gateway.

// #define WITH_LEDS_BLINKING

// default LEDs blinking period in milliseconds
#define DEFAULT_LED_BLINK_PERIOD 300
// The RX LED default pin
#define DEFAULT_RX_LED_PIN 8
// The TX LED default pin
#define DEFAULT_TX_LED_PIN 9
// The Error LED default pin
#define DEFAULT_ERR_LED_PIN 7


/**********************************
* Message Signing Settings
***********************************/
Expand Down
119 changes: 119 additions & 0 deletions libraries/MySensors/MySensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,19 @@ static inline bool isValidDistance( const uint8_t distance ) {
MySensor::MySensor(MyTransport &_radio, MyHw &_hw
#ifdef MY_SIGNING_FEATURE
, MySigning &_signer
#endif
#ifdef WITH_LEDS_BLINKING
, uint8_t _rx, uint8_t _tx, uint8_t _er, unsigned long _blink_period
#endif
)
:
radio(_radio),
#ifdef MY_SIGNING_FEATURE
signer(_signer),
#endif
#ifdef WITH_LEDS_BLINKING
pinRx(_rx), pinTx(_tx), pinEr(_er), ledBlinkPeriod(_blink_period),
#endif
#ifdef MY_OTA_FIRMWARE_FEATURE
flash(MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID),
#endif
Expand Down Expand Up @@ -90,6 +96,64 @@ bool MySensor::isValidFirmware() {

#endif

#ifdef WITH_LEDS_BLINKING
void MySensor::handleLedsBlinking() {
static unsigned long next_time = hw_millis() + ledBlinkPeriod;

// Just return if it is not the time...
// http://playground.arduino.cc/Code/TimingRollover
if ((long)(hw_millis() - next_time) < 0)
return;
else
next_time = hw_millis() + ledBlinkPeriod;

// do the actual blinking
if(countRx && countRx != 255) {
// switch led on
digitalWrite(pinRx, LOW);
}
else if(!countRx) {
// switching off
digitalWrite(pinRx, HIGH);
}
if(countRx != 255)
--countRx;

if(countTx && countTx != 255) {
// switch led on
digitalWrite(pinTx, LOW);
}
else if(!countTx) {
// switching off
digitalWrite(pinTx, HIGH);
}
if(countTx != 255)
--countTx;

if(countErr && countErr != 255) {
// switch led on
digitalWrite(pinEr, LOW);
}
else if(!countErr) {
// switching off
digitalWrite(pinEr, HIGH);
}
if(countErr != 255)
--countErr;
}

void MySensor::rxBlink(uint8_t cnt) {
if(countRx == 255) { countRx = cnt; }
}

void MySensor::txBlink(uint8_t cnt) {
if(countTx == 255) { countTx = cnt; }
}

void MySensor::errBlink(uint8_t cnt) {
if(countErr == 255) { countErr = cnt; }
}
#endif

void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, boolean _repeaterMode, uint8_t _parentNodeId) {
hw_init();
Expand All @@ -111,6 +175,23 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
hw_readConfigBlock((void*)doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS, sizeof(doSign));
#endif

#ifdef WITH_LEDS_BLINKING
// Setup led pins
pinMode(pinRx, OUTPUT);
pinMode(pinTx, OUTPUT);
pinMode(pinEr, OUTPUT);

// Set initial state of leds
digitalWrite(pinRx, HIGH);
digitalWrite(pinTx, HIGH);
digitalWrite(pinEr, HIGH);

// initialize counters
countRx = 0;
countTx = 0;
countErr = 0;
#endif

if (isGateway) {
// Set configuration for gateway
nc.parentNodeId = GATEWAY_ADDRESS;
Expand Down Expand Up @@ -246,12 +327,18 @@ boolean MySensor::sendRoute(MyMessage &message) {
// If we still don't have any parent id, re-request and skip this message.
if (nc.parentNodeId == AUTO) {
findParentNode();
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}

// If we still don't have any node id, re-request and skip this message.
if (nc.nodeId == AUTO) {
requestNodeId();
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}

Expand Down Expand Up @@ -288,10 +375,16 @@ boolean MySensor::sendRoute(MyMessage &message) {
}
if (hw_millis() - enter > MY_VERIFICATION_TIMEOUT_MS) {
debug(PSTR("nonce tmo\n"));
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}
if (!signOk) {
debug(PSTR("sign fail\n"));
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}
// After this point, only the 'last' member of the message structure is allowed to be altered if the message has been signed,
Expand Down Expand Up @@ -350,6 +443,9 @@ boolean MySensor::sendRoute(MyMessage &message) {
if (!ok) {
// Failure when sending to parent node. The parent node might be down and we
// need to find another route to gateway.
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
failedTransmissions++;
if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
findParentNode();
Expand All @@ -364,6 +460,9 @@ boolean MySensor::sendWrite(uint8_t to, MyMessage &message) {
mSetVersion(message, PROTOCOL_VERSION);
uint8_t length = mGetSigned(message) ? MAX_MESSAGE_LENGTH : mGetLength(message);
message.last = nc.nodeId;
#ifdef WITH_LEDS_BLINKING
txBlink(1);
#endif
bool ok = radio.send(to, &message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length));

debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,sg=%d,st=%s:%s\n"),
Expand Down Expand Up @@ -408,6 +507,11 @@ void MySensor::requestTime(void (* _timeCallback)(unsigned long)) {

boolean MySensor::process() {
hw_watchdogReset();

#ifdef WITH_LEDS_BLINKING
handleLedsBlinking();
#endif

uint8_t to = 0;
if (!radio.available(&to))
{
Expand All @@ -418,6 +522,9 @@ boolean MySensor::process() {
debug(PSTR("fw upd fail\n"));
// Give up. We have requested MY_OTA_RETRY times without any packet in return.
fwUpdateOngoing = false;
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}
fwRetry--;
Expand All @@ -439,6 +546,9 @@ boolean MySensor::process() {
#endif

uint8_t len = radio.receive((uint8_t *)&msg);
#ifdef WITH_LEDS_BLINKING
rxBlink(1);
#endif

#ifdef MY_SIGNING_FEATURE
// Before processing message, reject unsigned messages if signing is required and check signature (if it is signed and addressed to us)
Expand All @@ -451,10 +561,16 @@ boolean MySensor::process() {
if (!mGetSigned(msg)) {
// Got unsigned message that should have been signed
debug(PSTR("no sign\n"));
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}
else if (!signer.verifyMsg(msg)) {
debug(PSTR("verify fail\n"));
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false; // This signed message has been tampered with!
}
}
Expand All @@ -468,6 +584,9 @@ boolean MySensor::process() {

if(!(mGetVersion(msg) == PROTOCOL_VERSION)) {
debug(PSTR("ver mismatch\n"));
#ifdef WITH_LEDS_BLINKING
errBlink(1);
#endif
return false;
}

Expand Down
29 changes: 29 additions & 0 deletions libraries/MySensors/MySensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ class MySensor
MySensor(MyTransport &radio =*new MyTransportNRF24(), MyHw &hw=*new MyHwDriver()
#ifdef MY_SIGNING_FEATURE
, MySigning &signer=*new MySigningNone()
#endif
#ifdef WITH_LEDS_BLINKING
, uint8_t _rx=DEFAULT_RX_LED_PIN,
uint8_t _tx=DEFAULT_TX_LED_PIN,
uint8_t _er=DEFAULT_ERR_LED_PIN,
unsigned long _blink_period=DEFAULT_LED_BLINK_PERIOD
#endif
);

Expand Down Expand Up @@ -299,6 +305,15 @@ class MySensor
*/
int8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms=0);

#ifdef WITH_LEDS_BLINKING
/**
* Blink with LEDs
* @param cnt how many blink cycles to keep the LED on. Default cycle is 300ms
*/
void rxBlink(uint8_t cnt);
void txBlink(uint8_t cnt);
void errBlink(uint8_t cnt);
#endif

protected:
NodeConfig nc; // Essential settings for node to work
Expand All @@ -324,6 +339,20 @@ class MySensor
MySigning& signer;
#endif

#ifdef WITH_LEDS_BLINKING
uint8_t pinRx; // Rx led pin
uint8_t pinTx; // Tx led pin
uint8_t pinEr; // Err led pin

// these variables don't need to be volatile, since we are not using interrupts
uint8_t countRx;
uint8_t countTx;
uint8_t countErr;

unsigned long ledBlinkPeriod;
void handleLedsBlinking(); // do the actual blinking
#endif

MyTransport& radio;
MyHw& hw;

Expand Down
12 changes: 7 additions & 5 deletions libraries/MySensors/examples/EthernetGateway/EthernetGateway.ino
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
* E.g. If you want to use the defualt 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 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
Expand All @@ -68,7 +69,6 @@
#include <MyParserSerial.h>
#include <MySensor.h>
#include <stdarg.h>
#include <MsTimer2.h>
#include <PinChangeInt.h>
#include "GatewayUtil.h"

Expand Down Expand Up @@ -104,7 +104,12 @@ MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
MyHwATMega328 hw;

// Construct MySensors library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
// To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h
#ifdef WITH_LEDS_BLINKING
MySensor gw(transport, hw /*, signer*/, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN);
#else
MySensor gw(transport, hw /*, signer*/);
#endif


#define IP_PORT 5003 // The port you want to open
Expand Down Expand Up @@ -136,11 +141,8 @@ void output(const char *fmt, ... ) {
void setup()
{
Ethernet.begin(mac, myIp);
setupGateway(RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN, INCLUSION_MODE_PIN, INCLUSION_MODE_TIME, output);

// Add led timer interrupt
MsTimer2::set(300, ledTimersInterrupt);
MsTimer2::start();
setupGateway(INCLUSION_MODE_PIN, INCLUSION_MODE_TIME, output);

// Add interrupt for inclusion button to pin
PCintPort::attachInterrupt(pinInclusion, startInclusionInterrupt, RISING);
Expand Down
Loading