* Changed library to call by reference instead of using pointers. Makes code much cleaner.

* RelayNodes renamed to RepeaterNode to distiguish this from RelayActuator.
* Ack is now possible to request for all message types. Added ack-flag for some of the exposed internal messages and presentation message.
This commit is contained in:
Henrik Ekblad
2014-06-16 00:30:13 +02:00
parent 9ddf442e42
commit 90f79c97cd
15 changed files with 200 additions and 204 deletions
+8 -8
View File
@@ -28,9 +28,9 @@ MyGateway::MyGateway(uint8_t _cepin, uint8_t _cspin, uint8_t _inclusion_time, ui
void MyGateway::begin(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate, void (*inDataCallback)(char *)) { void MyGateway::begin(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate, void (*inDataCallback)(char *)) {
Serial.begin(BAUD_RATE); Serial.begin(BAUD_RATE);
relayMode = true; repeaterMode = true;
isGateway = true; isGateway = true;
setupRelayMode(); setupRepeaterMode();
if (inDataCallback != NULL) { if (inDataCallback != NULL) {
useWriteCallback = true; useWriteCallback = true;
@@ -157,7 +157,7 @@ void MyGateway::parseAndSend(char *commandBuffer) {
msg.type = type; msg.type = type;
mSetCommand(msg,command); mSetCommand(msg,command);
msg.set(value); msg.set(value);
ok = sendRoute(&msg); ok = sendRoute(msg);
if (!ok) { if (!ok) {
errBlink(1); errBlink(1);
} }
@@ -178,7 +178,7 @@ void MyGateway::setInclusionMode(boolean newMode) {
// Override normal validate to add error blink if crc check fails // Override normal validate to add error blink if crc check fails
uint8_t MyGateway::validate(MyMessage *message) { uint8_t MyGateway::validate(MyMessage &message) {
uint8_t res = MySensor::validate(message); uint8_t res = MySensor::validate(message);
if (res == VALIDATE_BAD_CRC) { if (res == VALIDATE_BAD_CRC) {
errBlink(1); errBlink(1);
@@ -189,8 +189,8 @@ uint8_t MyGateway::validate(MyMessage *message) {
void MyGateway::processRadioMessage() { void MyGateway::processRadioMessage() {
if (process()) { if (process()) {
// A new message was received from one of the sensors // A new message was received from one of the sensors
MyMessage *message = getLastMessage(); MyMessage message = getLastMessage();
if (mGetCommandP(message) == C_PRESENTATION && inclusionMode) { if (mGetCommand(message) == C_PRESENTATION && inclusionMode) {
rxBlink(3); rxBlink(3);
} else { } else {
rxBlink(1); rxBlink(1);
@@ -215,8 +215,8 @@ void MyGateway::serial(const char *fmt, ... ) {
} }
} }
void MyGateway::serial(MyMessage *msg) { void MyGateway::serial(MyMessage &msg) {
serial(PSTR("%d;%d;%d;%d;%s\n"),msg->sender, msg->sensor, mGetCommandP(msg), msg->type, msg->getString(convBuf)); serial(PSTR("%d;%d;%d;%d;%s\n"),msg.sender, msg.sensor, mGetCommand(msg), msg.type, msg.getString(convBuf));
} }
+2 -2
View File
@@ -69,8 +69,8 @@ class MyGateway : public MySensor
uint8_t pinEr; uint8_t pinEr;
void serial(const char *fmt, ... ); void serial(const char *fmt, ... );
void serial(MyMessage *msg); void serial(MyMessage &msg);
uint8_t validate(MyMessage *message); uint8_t validate(MyMessage &message);
void interruptStartInclusion(); void interruptStartInclusion();
void checkButtonTriggeredInclusion(); void checkButtonTriggeredInclusion();
void setInclusionMode(boolean newMode); void setInclusionMode(boolean newMode);
+37 -37
View File
@@ -15,26 +15,26 @@ MyMessage::MyMessage(uint8_t _sensor, uint8_t _type) {
/* Getters for payload converted to desired form */ /* Getters for payload converted to desired form */
void* MyMessage::getCustom() { void* MyMessage::getCustom() const {
return (void *)data; return (void *)data;
} }
char* MyMessage::getString() { const char* MyMessage::getString() const {
uint8_t payloadType = miGetPayloadType(); uint8_t payloadType = miGetPayloadType();
if (payloadType == P_STRING) { if (payloadType == P_STRING) {
data[miGetLength()] = '\0';
return data; return data;
} else { } else {
return NULL; return NULL;
} }
} }
char* MyMessage::getString(char *buffer) { char* MyMessage::getString(char *buffer) const {
uint8_t payloadType = miGetPayloadType(); uint8_t payloadType = miGetPayloadType();
if (payloadType == P_STRING) { if (payloadType == P_STRING) {
data[miGetLength()] = '\0'; strncpy(buffer, data, miGetLength());
return data; buffer[miGetLength()] = '\0';
return buffer;
} else if (buffer != NULL) { } else if (buffer != NULL) {
switch(payloadType) { switch(payloadType) {
case P_BYTE: case P_BYTE:
@@ -65,7 +65,7 @@ char* MyMessage::getString(char *buffer) {
} }
} }
uint8_t MyMessage::getByte() { uint8_t MyMessage::getByte() const {
switch(miGetPayloadType()) { switch(miGetPayloadType()) {
case P_BYTE: case P_BYTE:
return data[0]; return data[0];
@@ -76,15 +76,15 @@ uint8_t MyMessage::getByte() {
} }
} }
bool MyMessage::getBool() { bool MyMessage::getBool() const {
return !(data[0]-'0'==0); return !(data[0]-'0'==0);
} }
double MyMessage::getDouble() { double MyMessage::getDouble() const {
return strtod(data, NULL); return strtod(data, NULL);
} }
long MyMessage::getLong() { long MyMessage::getLong() const {
switch(miGetPayloadType()) { switch(miGetPayloadType()) {
case P_LONG32: case P_LONG32:
return lValue; return lValue;
@@ -95,7 +95,7 @@ long MyMessage::getLong() {
} }
} }
unsigned long MyMessage::getULong() { unsigned long MyMessage::getULong() const {
switch(miGetPayloadType()) { switch(miGetPayloadType()) {
case P_ULONG32: case P_ULONG32:
return ulValue; return ulValue;
@@ -106,7 +106,7 @@ unsigned long MyMessage::getULong() {
} }
} }
int MyMessage::getInt() { int MyMessage::getInt() const {
switch(miGetPayloadType()) { switch(miGetPayloadType()) {
case P_INT16: case P_INT16:
return iValue; return iValue;
@@ -117,7 +117,7 @@ int MyMessage::getInt() {
} }
} }
unsigned int MyMessage::getUInt() { unsigned int MyMessage::getUInt() const {
switch(miGetPayloadType()) { switch(miGetPayloadType()) {
case P_UINT16: case P_UINT16:
return uiValue; return uiValue;
@@ -130,85 +130,85 @@ unsigned int MyMessage::getUInt() {
} }
MyMessage* MyMessage::setType(uint8_t _type) { MyMessage& MyMessage::setType(uint8_t _type) {
type = _type; type = _type;
return this; return *this;
} }
MyMessage* MyMessage::setSensor(uint8_t _sensor) { MyMessage& MyMessage::setSensor(uint8_t _sensor) {
sensor = _sensor; sensor = _sensor;
return this; return *this;
} }
MyMessage* MyMessage::setDestination(uint8_t _destination) { MyMessage& MyMessage::setDestination(uint8_t _destination) {
destination = _destination; destination = _destination;
return this; return *this;
} }
// Set payload // Set payload
MyMessage* MyMessage::set(void* value, uint8_t length) { MyMessage& MyMessage::set(void* value, uint8_t length) {
miSetPayloadType(P_CUSTOM); miSetPayloadType(P_CUSTOM);
miSetLength(length); miSetLength(length);
memcpy(data, value, min(length, MAX_PAYLOAD)); memcpy(data, value, min(length, MAX_PAYLOAD));
return this; return *this;
} }
MyMessage* MyMessage::set(const char* value) { MyMessage& MyMessage::set(const char* value) {
uint8_t length = strlen(value); uint8_t length = strlen(value);
miSetLength(length); miSetLength(length);
miSetPayloadType(P_STRING); miSetPayloadType(P_STRING);
strncpy(data, value, min(length, MAX_PAYLOAD)); strncpy(data, value, min(length, MAX_PAYLOAD));
return this; return *this;
} }
MyMessage* MyMessage::set(uint8_t value) { MyMessage& MyMessage::set(uint8_t value) {
miSetLength(1); miSetLength(1);
miSetPayloadType(P_BYTE); miSetPayloadType(P_BYTE);
data[0] = value; data[0] = value;
return this; return *this;
} }
MyMessage* MyMessage::set(bool value) { MyMessage& MyMessage::set(bool value) {
miSetLength(1); miSetLength(1);
miSetPayloadType(P_STRING); miSetPayloadType(P_STRING);
data[0] = value?'1':'0'; data[0] = value?'1':'0';
return this; return *this;
} }
MyMessage* MyMessage::set(double value, uint8_t decimals) { MyMessage& MyMessage::set(double value, uint8_t decimals) {
dtostrf(value,2,decimals,data); dtostrf(value,2,decimals,data);
miSetLength(strlen(data)); miSetLength(strlen(data));
miSetPayloadType(P_STRING); miSetPayloadType(P_STRING);
return this; return *this;
} }
MyMessage* MyMessage::set(unsigned long value) { MyMessage& MyMessage::set(unsigned long value) {
miSetPayloadType(P_ULONG32); miSetPayloadType(P_ULONG32);
miSetLength(4); miSetLength(4);
ulValue = value; ulValue = value;
return this; return *this;
} }
MyMessage* MyMessage::set(long value) { MyMessage& MyMessage::set(long value) {
miSetPayloadType(P_LONG32); miSetPayloadType(P_LONG32);
miSetLength(4); miSetLength(4);
lValue = value; lValue = value;
return this; return *this;
} }
MyMessage* MyMessage::set(unsigned int value) { MyMessage& MyMessage::set(unsigned int value) {
miSetPayloadType(P_UINT16); miSetPayloadType(P_UINT16);
miSetLength(2); miSetLength(2);
uiValue = value; uiValue = value;
return this; return *this;
} }
MyMessage* MyMessage::set(int value) { MyMessage& MyMessage::set(int value) {
miSetPayloadType(P_INT16); miSetPayloadType(P_INT16);
miSetLength(2); miSetLength(2);
iValue = value; iValue = value;
return this; return *this;
} }
+45 -49
View File
@@ -24,9 +24,8 @@ typedef enum {
C_PRESENTATION = 0, C_PRESENTATION = 0,
C_SET = 1, C_SET = 1,
C_REQ = 2, C_REQ = 2,
C_SET_WITH_ACK = 3, C_INTERNAL = 3,
C_INTERNAL = 4, C_STREAM = 4 // For Firmware and other larger chunks of data that need to be divided into pieces.
C_STREAM = 5 // For Firmaware and other larger chunks of data that need to be divided into pieces.
} command; } command;
// Type of sensor data (for set/req/ack messages) // Type of sensor data (for set/req/ack messages)
@@ -49,7 +48,7 @@ typedef enum {
typedef enum { typedef enum {
S_DOOR, S_MOTION, S_SMOKE, S_LIGHT, S_DIMMER, S_COVER, S_TEMP, S_HUM, S_BARO, S_WIND, S_DOOR, S_MOTION, S_SMOKE, S_LIGHT, S_DIMMER, S_COVER, S_TEMP, S_HUM, S_BARO, S_WIND,
S_RAIN, S_UV, S_WEIGHT, S_POWER, S_HEATER, S_DISTANCE, S_LIGHT_LEVEL, S_ARDUINO_NODE, S_RAIN, S_UV, S_WEIGHT, S_POWER, S_HEATER, S_DISTANCE, S_LIGHT_LEVEL, S_ARDUINO_NODE,
S_ARDUINO_RELAY, S_LOCK, S_IR, S_WATER S_ARDUINO_REPEATER_NODE, S_LOCK, S_IR, S_WATER
} sensor; } sensor;
// Type of data stream (for streamed message) // Type of data stream (for streamed message)
@@ -83,29 +82,23 @@ typedef enum {
// Getters/setters for special fields in header // Getters/setters for special fields in header
#define mSetVersion(_msg,_version) BF_SET(_msg.version_length, _version, 0, 3) #define mSetVersion(_msg,_version) BF_SET(_msg.version_length, _version, 0, 3)
#define mSetLength(_msg,_length) BF_SET(_msg.version_length, _length, 3, 5) #define mSetLength(_msg,_length) BF_SET(_msg.version_length, _length, 3, 5)
#define mSetCommand(_msg,_command) BF_SET(_msg.command_payload, _command, 0, 4) #define mSetCommand(_msg,_command) BF_SET(_msg.command_ack_payload, _command, 0, 3)
#define mSetPayloadType(_msg, _pt) BF_SET(_msg.command_payload, _pt, 4, 4) #define mSetAck(_msg,_command) BF_SET(_msg.command_ack_payload, _command, 3, 1)
#define mSetVersionP(_msg,_version) BF_SET(_msg->version_length, _version, 0, 3) #define mSetPayloadType(_msg, _pt) BF_SET(_msg.command_ack_payload, _pt, 4, 4)
#define mSetLengthP(_msg,_length) BF_SET(_msg->version_length, _length, 3, 5)
#define mSetCommandP(_msg,_command) BF_SET(_msg->command_payload, _command, 0, 4)
#define mSetPayloadTypeP(_msg, _pt) BF_SET(_msg->command_payload, _pt, 4, 4)
#define mGetVersion(_msg) BF_GET(_msg.version_length, 0, 3) #define mGetVersion(_msg) BF_GET(_msg.version_length, 0, 3)
#define mGetLength(_msg) BF_GET(_msg.version_length, 3, 5) #define mGetLength(_msg) BF_GET(_msg.version_length, 3, 5)
#define mGetCommand(_msg) BF_GET(_msg.command_payload, 0, 4) #define mGetCommand(_msg) BF_GET(_msg.command_ack_payload, 0, 3)
#define mGetPayloadType(_msg) BF_GET(_msg.command_payload, 4, 4) #define mGetAck(_msg) BF_GET(_msg.command_ack_payload, 3, 1)
#define mGetVersionP(_msg) BF_GET(_msg->version_length, 0, 3) #define mGetPayloadType(_msg) BF_GET(_msg.command_ack_payload, 4, 4)
#define mGetLengthP(_msg) BF_GET(_msg->version_length, 3, 5)
#define mGetCommandP(_msg) BF_GET(_msg->command_payload, 0, 4)
#define mGetPayloadTypeP(_msg) BF_GET(_msg->command_payload, 4, 4)
// internal access for special fileds // internal access for special fields
#define miGetPayloadType() BF_GET(command_payload, 4, 4) #define miGetPayloadType() BF_GET(command_ack_payload, 4, 4)
#define miGetLength() BF_GET(version_length, 3, 5) #define miGetLength() BF_GET(version_length, 3, 5)
#define miSetLength(_length) BF_SET(version_length, _length, 3, 5) #define miSetLength(_length) BF_SET(version_length, _length, 3, 5)
#define miSetPayloadType(_pt) BF_SET(command_payload, _pt, 4, 4) #define miSetPayloadType(_pt) BF_SET(command_ack_payload, _pt, 4, 4)
class MyMessage class MyMessage
@@ -116,47 +109,50 @@ public:
MyMessage(uint8_t sensor, uint8_t type); MyMessage(uint8_t sensor, uint8_t type);
char* getString();
/** /**
* If payload is something else than P_STRING you can have the payload value converted * If payload is something else than P_STRING you can have the payload value converted
* into string representation by supplying a buffer with the minimum size of * into string representation by supplying a buffer with the minimum size of
* 2*MAX_PAYLOAD+1. This is to be able to fit hex-conversion of a full binary payload. * 2*MAX_PAYLOAD+1. This is to be able to fit hex-conversion of a full binary payload.
*/ */
char* getString(char *buffer); char* getString(char *buffer) const;
void* getCustom(); const char* getString() const;
uint8_t getByte(); void* getCustom() const;
bool getBool(); uint8_t getByte() const;
double getDouble(); bool getBool() const;
long getLong(); double getDouble() const;
unsigned long getULong(); long getLong() const;
int getInt(); unsigned long getULong() const;
unsigned int getUInt(); int getInt() const;
unsigned int getUInt() const;
// Setters for building message "on the fly" // Setters for building message "on the fly"
MyMessage* setType(uint8_t type); MyMessage& setType(uint8_t type);
MyMessage* setSensor(uint8_t sensor); MyMessage& setSensor(uint8_t sensor);
MyMessage* setDestination(uint8_t destination); MyMessage& setDestination(uint8_t destination);
// Setters for payload // Setters for payload
MyMessage* set(void* payload, uint8_t length); MyMessage& set(void* payload, uint8_t length);
MyMessage* set(const char* value); MyMessage& set(const char* value);
MyMessage* set(uint8_t value); MyMessage& set(uint8_t value);
MyMessage* set(bool value); MyMessage& set(bool value);
MyMessage* set(double value, uint8_t decimals); MyMessage& set(double value, uint8_t decimals);
MyMessage* set(unsigned long value); MyMessage& set(unsigned long value);
MyMessage* set(long value); MyMessage& set(long value);
MyMessage* set(unsigned int value); MyMessage& set(unsigned int value);
MyMessage* set(int value); MyMessage& set(int value);
uint8_t version_length; // 3 bit - Protocol version + 5 bit - Length of payload uint8_t version_length; // 3 bit - Protocol version
uint8_t command_payload; // 4 bit - Command type + 4 bit - Payload data type // 5 bit - Length of payload
uint8_t type; // 8 bit - Type varies depending on command uint8_t command_ack_payload; // 3 bit - Command type
uint8_t sensor; // 8 bit - Id of sensor that this message concerns. // 1 bit - Indicator that receiver should send an ack back.
uint8_t sender; // 8 bit - Id of sender node // 4 bit - Payload data type
uint8_t last; // 8 bit - Id of last node this message passed uint8_t type; // 8 bit - Type varies depending on command
uint8_t destination; // 8 bit - Id of destination node uint8_t sensor; // 8 bit - Id of sensor that this message concerns.
uint8_t crc; // 8 bit - Message checksum uint8_t sender; // 8 bit - Id of sender node
uint8_t last; // 8 bit - Id of last node this message passed
uint8_t destination; // 8 bit - Id of destination node
uint8_t crc; // 8 bit - Message checksum
// Each message can transfer a payload. We add one extra byte for string // Each message can transfer a payload. We add one extra byte for string
// terminator \0 to be "printable" this is not transferred OTA // terminator \0 to be "printable" this is not transferred OTA
+74 -77
View File
@@ -14,12 +14,13 @@
// Inline function and macros // Inline function and macros
inline MyMessage* build (MyMessage* msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type) { inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) {
msg->sender = sender; msg.sender = sender;
msg->destination = destination; msg.destination = destination;
msg->sensor = sensor; msg.sensor = sensor;
msg->type = type; msg.type = type;
mSetCommandP(msg,command); mSetCommand(msg,command);
mSetAck(msg,enableAck);
return msg; return msg;
} }
@@ -28,14 +29,14 @@ MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) {
} }
void MySensor::begin(void (*_msgCallback)(MyMessage), uint8_t _nodeId, boolean _relayMode, rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) { void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, boolean _repeaterMode, rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
Serial.begin(BAUD_RATE); Serial.begin(BAUD_RATE);
isGateway = false; isGateway = false;
relayMode = _relayMode; repeaterMode = _repeaterMode;
msgCallback = _msgCallback; msgCallback = _msgCallback;
if (relayMode) { if (repeaterMode) {
setupRelayMode(); setupRepeaterMode();
} }
setupRadio(paLevel, channel, dataRate); setupRadio(paLevel, channel, dataRate);
@@ -60,19 +61,19 @@ void MySensor::begin(void (*_msgCallback)(MyMessage), uint8_t _nodeId, boolean _
requestNodeId(); requestNodeId();
} }
debug(PSTR("%s started, id %d\n"), relayMode?"relay":"sensor", nc.nodeId); debug(PSTR("%s started, id %d\n"), repeaterMode?"repeater":"sensor", nc.nodeId);
// Open reading pipe for messages directed to this node (set write pipe to same) // Open reading pipe for messages directed to this node (set write pipe to same)
RF24::openReadingPipe(WRITE_PIPE, TO_ADDR(nc.nodeId)); RF24::openReadingPipe(WRITE_PIPE, TO_ADDR(nc.nodeId));
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId)); RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
// Send presentation for this radio node (attach // Send presentation for this radio node (attach
present(NODE_SENSOR_ID, relayMode? S_ARDUINO_RELAY : S_ARDUINO_NODE); present(NODE_SENSOR_ID, repeaterMode? S_ARDUINO_REPEATER_NODE : S_ARDUINO_NODE);
// Send a configuration exchange request to controller // Send a configuration exchange request to controller
// Node sends parent node. Controller answers with latest node configuration // Node sends parent node. Controller answers with latest node configuration
// which is picked up in process() // which is picked up in process()
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CONFIG)->set(nc.parentNodeId)); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CONFIG, false).set(nc.parentNodeId));
// Wait configuration reply. // Wait configuration reply.
waitForReply(); waitForReply();
@@ -102,7 +103,7 @@ void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS)); RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
} }
void MySensor::setupRelayMode(){ void MySensor::setupRepeaterMode(){
childNodeTable = new uint8_t[256]; childNodeTable = new uint8_t[256];
eeprom_read_block((void*)childNodeTable, (void*)EEPROM_ROUTES_ADDRESS, 256); eeprom_read_block((void*)childNodeTable, (void*)EEPROM_ROUTES_ADDRESS, 256);
} }
@@ -119,7 +120,7 @@ ControllerConfig MySensor::getConfig() {
void MySensor::requestNodeId() { void MySensor::requestNodeId() {
debug(PSTR("req node id\n")); debug(PSTR("req node id\n"));
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId)); RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_ID_REQUEST)->set("")); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_ID_REQUEST, false).set(""));
waitForReply(); waitForReply();
} }
@@ -131,8 +132,8 @@ void MySensor::findParentNode() {
nc.distance = 255; nc.distance = 255;
// Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to) // Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to)
build(&msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_PING)->set(""); build(msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_PING, false).set("");
sendWrite(BROADCAST_ADDRESS, &msg, true); sendWrite(BROADCAST_ADDRESS, msg, true);
// Wait for ping response. // Wait for ping response.
waitForReply(); waitForReply();
@@ -146,26 +147,26 @@ void MySensor::waitForReply() {
} }
} }
boolean MySensor::sendRoute(MyMessage *message) { boolean MySensor::sendRoute(MyMessage &message) {
// Make sure to process any incoming messages before sending (could this end up in recursive loop?) // Make sure to process any incoming messages before sending (could this end up in recursive loop?)
// process(); // process();
bool isInternal = mGetCommandP(message) == C_INTERNAL; bool isInternal = mGetCommand(message) == C_INTERNAL;
// If we still don't have any node id, re-request and skip this message. // If we still don't have any node id, re-request and skip this message.
if (nc.nodeId == AUTO && !(isInternal && message->type == I_ID_REQUEST)) { if (nc.nodeId == AUTO && !(isInternal && message.type == I_ID_REQUEST)) {
requestNodeId(); requestNodeId();
return false; return false;
} }
if (relayMode) { if (repeaterMode) {
uint8_t dest = message->destination; uint8_t dest = message.destination;
uint8_t route = getChildRoute(dest); uint8_t route = getChildRoute(dest);
if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) { if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) {
// --- debug(PSTR("route %d.\n"), route); // --- debug(PSTR("route %d.\n"), route);
// Message destination is not gateway and is in routing table for this node. // Message destination is not gateway and is in routing table for this node.
// Send it downstream // Send it downstream
return sendWrite(route, message); return sendWrite(route, message);
} else if (isInternal && message->type == I_ID_RESPONSE && dest==BROADCAST_ADDRESS) { } else if (isInternal && message.type == I_ID_RESPONSE && dest==BROADCAST_ADDRESS) {
// Node has not yet received any id. We need to send it // Node has not yet received any id. We need to send it
// by doing a broadcast sending, // by doing a broadcast sending,
return sendWrite(BROADCAST_ADDRESS, message, true); return sendWrite(BROADCAST_ADDRESS, message, true);
@@ -192,59 +193,56 @@ boolean MySensor::sendRoute(MyMessage *message) {
return false; return false;
} }
boolean MySensor::sendWrite(uint8_t next, MyMessage *message, bool broadcast) { boolean MySensor::sendWrite(uint8_t next, MyMessage &message, bool broadcast) {
uint8_t length = mGetLengthP(message); uint8_t length = mGetLength(message);
message->last = nc.nodeId; message.last = nc.nodeId;
mSetVersionP(message, PROTOCOL_VERSION); mSetVersion(message, PROTOCOL_VERSION);
message->crc = crc8Message(message); message.crc = crc8Message(message);
// Make sure radio has powered up // Make sure radio has powered up
RF24::powerUp(); RF24::powerUp();
RF24::stopListening(); RF24::stopListening();
RF24::openWritingPipe(TO_ADDR(next)); RF24::openWritingPipe(TO_ADDR(next));
bool ok = RF24::write(message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast); bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast);
RF24::startListening(); RF24::startListening();
debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d, st=%s:%s\n"), debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d, st=%s:%s\n"),
message->sender,message->last, next, message->destination, message->sensor, mGetCommandP(message), message->type, ok?"ok":"fail", message->getString(convBuf)); message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type, ok?"ok":"fail", message.getString(convBuf));
return ok; return ok;
} }
bool MySensor::send(MyMessage *message, bool enableAck) { bool MySensor::send(MyMessage &message, bool enableAck) {
message->sender = nc.nodeId; message.sender = nc.nodeId;
if (enableAck) { mSetCommand(message,C_SET);
mSetCommandP(message,C_SET_WITH_ACK); mSetAck(message,enableAck);
} else {
mSetCommandP(message,C_SET);
}
return sendRoute(message); return sendRoute(message);
} }
void MySensor::sendBatteryLevel(uint8_t value) { void MySensor::sendBatteryLevel(uint8_t value, bool enableAck) {
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_BATTERY_LEVEL)->set(value)); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_BATTERY_LEVEL, enableAck).set(value));
} }
void MySensor::present(uint8_t childSensorId, uint8_t sensorType) { void MySensor::present(uint8_t childSensorId, uint8_t sensorType, bool enableAck) {
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, childSensorId, C_PRESENTATION, sensorType)->set(LIBRARY_VERSION)); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, childSensorId, C_PRESENTATION, sensorType, enableAck).set(LIBRARY_VERSION));
} }
void MySensor::sendSketchInfo(const char *name, const char *version) { void MySensor::sendSketchInfo(const char *name, const char *version, bool enableAck) {
if (name != NULL) { if (name != NULL) {
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_NAME)->set(name)); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_NAME, enableAck).set(name));
} }
if (version != NULL) { if (version != NULL) {
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_VERSION)->set(version)); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_SKETCH_VERSION, enableAck).set(version));
} }
} }
void MySensor::request(uint8_t childSensorId, uint8_t variableType, uint8_t destination) { void MySensor::request(uint8_t childSensorId, uint8_t variableType, uint8_t destination) {
sendRoute(build(&msg, nc.nodeId, destination, childSensorId, C_REQ, variableType)); sendRoute(build(msg, nc.nodeId, destination, childSensorId, C_REQ, variableType, false));
} }
void MySensor::requestTime(void (* _timeCallback)(unsigned long)) { void MySensor::requestTime(void (* _timeCallback)(unsigned long)) {
timeCallback = _timeCallback; timeCallback = _timeCallback;
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_TIME)); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_TIME, false));
} }
@@ -259,7 +257,7 @@ boolean MySensor::process() {
RF24::read(&msg, len); RF24::read(&msg, len);
RF24::writeAckPayload(pipe,&pipe, 1 ); RF24::writeAckPayload(pipe,&pipe, 1 );
uint8_t valid = validate(&msg); uint8_t valid = validate(msg);
boolean ok = valid == VALIDATE_OK; boolean ok = valid == VALIDATE_OK;
// Make sure string gets terminated ok for full string messages. // Make sure string gets terminated ok for full string messages.
@@ -276,16 +274,26 @@ boolean MySensor::process() {
uint8_t last = msg.last; uint8_t last = msg.last;
uint8_t destination = msg.destination; uint8_t destination = msg.destination;
if (relayMode && command == C_INTERNAL && type == I_PING) { if (repeaterMode && command == C_INTERNAL && type == I_PING) {
// Relaying nodes should always answer ping messages // Relaying nodes should always answer ping messages
// Wait a random delay of 0-2 seconds to minimize collision // Wait a random delay of 0-2 seconds to minimize collision
// between ping ack messages from other relaying nodes // between ping ack messages from other relaying nodes
delay(millis() & 0x3ff); delay(millis() & 0x3ff);
sendWrite(sender, build(&msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_PING_ACK)->set(nc.distance), true); sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_PING_ACK, false).set(nc.distance), true);
return false; return false;
} else if (destination == nc.nodeId) { } else if (destination == nc.nodeId) {
// Check if sender requests an ack back.
if (mGetAck(msg)) {
// Copy message
ack = msg;
mSetAck(ack,false); // Reply without ack flag (otherwise we would end up in an eternal loop)
ack.sender = nc.nodeId;
ack.destination = msg.sender;
sendRoute(ack);
}
// This message is addressed to this node // This message is addressed to this node
if (relayMode && last != nc.parentNodeId) { if (repeaterMode && last != nc.parentNodeId) {
// Message is from one of the child nodes. Add it to routing table. // Message is from one of the child nodes. Add it to routing table.
addChildRoute(sender, last); addChildRoute(sender, last);
} }
@@ -334,13 +342,13 @@ boolean MySensor::process() {
} }
break; break;
case I_CHILDREN: case I_CHILDREN:
if (relayMode && msg.getByte() == 'C') { if (repeaterMode && msg.getByte() == 'C') {
// Clears child relay data for this node // Clears child relay data for this node
debug(PSTR("rd=clear\n")); debug(PSTR("rd=clear\n"));
for (uint8_t i=0;i< sizeof(childNodeTable); i++) { for (uint8_t i=0;i< sizeof(childNodeTable); i++) {
removeChildRoute(i); removeChildRoute(i);
} }
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CHILDREN)->set("")); sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CHILDREN,false).set(""));
} }
break; break;
case I_TIME: case I_TIME:
@@ -352,24 +360,13 @@ boolean MySensor::process() {
return false; return false;
} }
} }
// Check if sender requests an ack back.
if (command == C_SET_WITH_ACK) {
// Copy message
ack = msg;
mSetCommand(ack,C_SET);
ack.sender = nc.nodeId;
ack.destination = msg.sender;
sendRoute(&ack);
// The library user should not need to care about this ack request. Just treat it as a normal SET.
mSetCommand(msg,C_SET);
}
// Call incoming message callback if available // Call incoming message callback if available
if (msgCallback != NULL) { if (msgCallback != NULL) {
msgCallback(msg); msgCallback(msg);
} }
// Return true if message was addressed for this node... // Return true if message was addressed for this node...
return true; return true;
} else if (relayMode && pipe == CURRENT_NODE_PIPE) { } else if (repeaterMode && pipe == CURRENT_NODE_PIPE) {
// We should try to relay this message to another node // We should try to relay this message to another node
uint8_t route = getChildRoute(msg.destination); uint8_t route = getChildRoute(msg.destination);
@@ -385,7 +382,7 @@ boolean MySensor::process() {
// We're node C, Message comes from A and has destination D // We're node C, Message comes from A and has destination D
// //
// lookup route in table and send message there // lookup route in table and send message there
sendWrite(route, &msg); sendWrite(route, msg);
} else { } else {
// A message comes from a child node and we have no // A message comes from a child node and we have no
// route for it. // route for it.
@@ -399,7 +396,7 @@ boolean MySensor::process() {
// Message should be passed to node A (this nodes relay) // Message should be passed to node A (this nodes relay)
// This message should be routed back towards sensor net gateway // This message should be routed back towards sensor net gateway
sendWrite(nc.parentNodeId, &msg); sendWrite(nc.parentNodeId, msg);
// Add this child to our "routing table" if it not already exist // Add this child to our "routing table" if it not already exist
addChildRoute(sender, last); addChildRoute(sender, last);
} }
@@ -411,16 +408,16 @@ boolean MySensor::process() {
} }
MyMessage* MySensor::getLastMessage() { MyMessage& MySensor::getLastMessage() {
return &msg; return msg;
} }
/* /*
* calculate CRC8 on MyMessage data taking care of data structure and protocol version * calculate CRC8 on MyMessage data taking care of data structure and protocol version
*/ */
uint8_t MySensor::crc8Message(MyMessage *message) { uint8_t MySensor::crc8Message(MyMessage &message) {
uint8_t len = mGetLengthP(message); uint8_t len = mGetLength(message);
uint8_t crc = 0x00; uint8_t crc = 0x00;
uint8_t loop_count; uint8_t loop_count;
uint8_t bit_counter; uint8_t bit_counter;
@@ -429,16 +426,16 @@ uint8_t MySensor::crc8Message(MyMessage *message) {
uint8_t number_of_bytes_to_read = (uint8_t)sizeof(MyMessage); uint8_t number_of_bytes_to_read = (uint8_t)sizeof(MyMessage);
// Must set crc to a constant value. // Must set crc to a constant value.
message->crc = 0; message.crc = 0;
// fill unused space by zeroes for string data only // fill unused space by zeroes for string data only
if(len>=0 && len < sizeof(message->data)) { if(len>=0 && len < sizeof(message.data)) {
memset(&message->data[len], 0, sizeof(message->data) - len); memset(&message.data[len], 0, sizeof(message.data) - len);
} }
for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++) for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++)
{ {
data = ((uint8_t*)message)[loop_count]; data = ((uint8_t*)&message)[loop_count];
bit_counter = 8; bit_counter = 8;
do { do {
@@ -461,11 +458,11 @@ uint8_t MySensor::crc8Message(MyMessage *message) {
} }
uint8_t MySensor::validate(MyMessage *message) { uint8_t MySensor::validate(MyMessage &message) {
uint8_t oldCrc = message->crc; uint8_t oldCrc = message.crc;
uint8_t newCrc = crc8Message(message); uint8_t newCrc = crc8Message(message);
if(!(mGetVersionP(message) == PROTOCOL_VERSION)) return VALIDATE_BAD_VERSION; if(!(mGetVersion(message) == PROTOCOL_VERSION)) return VALIDATE_BAD_VERSION;
if(!(oldCrc == newCrc)) return VALIDATE_BAD_CRC; if(!(oldCrc == newCrc)) return VALIDATE_BAD_CRC;
return VALIDATE_OK; return VALIDATE_OK;
+21 -16
View File
@@ -95,13 +95,13 @@ class MySensor : public RF24
* Call this in setup(), before calling any other sensor net library methods. * Call this in setup(), before calling any other sensor net library methods.
* @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL. * @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL.
* @param nodeId The unique id (1-254) for this sensor. Default is AUTO(255) which means sensor tries to fetch an id from controller. * @param nodeId The unique id (1-254) for this sensor. Default is AUTO(255) which means sensor tries to fetch an id from controller.
* @param relayMode Activate relay mode. This node will forward messages to other nodes in the radio network. Make sure to call process() regularly. Default in false * @param repeaterMode Activate repeater mode. This node will forward messages to other nodes in the radio network. Make sure to call process() regularly. Default in false
* @param paLevel Radio PA Level for this sensor. Default RF24_PA_MAX * @param paLevel Radio PA Level for this sensor. Default RF24_PA_MAX
* @param channel Radio channel. Default is channel 76 * @param channel Radio channel. Default is channel 76
* @param dataRate Radio transmission speed. Default RF24_1MBPS * @param dataRate Radio transmission speed. Default RF24_1MBPS
*/ */
void begin(void (* msgCallback)(MyMessage)=NULL, uint8_t nodeId=AUTO, boolean relayMode=false, rf24_pa_dbm_e paLevel=RF24_PA_LEVEL, uint8_t channel=RF24_CHANNEL, rf24_datarate_e dataRate=RF24_DATARATE); void begin(void (* msgCallback)(const MyMessage &)=NULL, uint8_t nodeId=AUTO, boolean repeaterMode=false, rf24_pa_dbm_e paLevel=RF24_PA_LEVEL, uint8_t channel=RF24_CHANNEL, rf24_datarate_e dataRate=RF24_DATARATE);
/** /**
* Return the nodes nodeId. * Return the nodes nodeId.
@@ -113,16 +113,19 @@ class MySensor : public RF24
* It is usually good to present all attached sensors after power-up in setup(). * It is usually good to present all attached sensors after power-up in setup().
* *
* @param sensorId Select a unique sensor id for this sensor. Choose a number between 0-254. * @param sensorId Select a unique sensor id for this sensor. Choose a number between 0-254.
* @param sensorType The sensor type. See sensor typedef in Message.h. * @param sensorType The sensor type. See sensor typedef in MyMessage.h.
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
*/ */
void present(uint8_t sensorId, uint8_t sensorType); void present(uint8_t sensorId, uint8_t sensorType, bool ack=false);
/** /**
* Sends sketch meta information to the gateway. Not mandatory but a nice thing to do. * Sends sketch meta information to the gateway. Not mandatory but a nice thing to do.
* @param name String containing a short Sketch name or NULL if not applicable * @param name String containing a short Sketch name or NULL if not applicable
* @param version String containing a short Sketch version or NULL if not applicable * @param version String containing a short Sketch version or NULL if not applicable
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
*
*/ */
void sendSketchInfo(const char *name, const char *version); void sendSketchInfo(const char *name, const char *version, bool ack=false);
/** /**
* Sends a message to gateway or one of the other nodes in the radio network * Sends a message to gateway or one of the other nodes in the radio network
@@ -131,19 +134,21 @@ class MySensor : public RF24
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack. * @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination. * @return true Returns true if message reached the first stop on its way to destination.
*/ */
bool send(MyMessage *msg, bool ack=false); bool send(MyMessage &msg, bool ack=false);
/** /**
* Send this nodes battery level to gateway. * Send this nodes battery level to gateway.
* @param level Level between 0-100(%) * @param level Level between 0-100(%)
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
*
*/ */
void sendBatteryLevel(uint8_t level); void sendBatteryLevel(uint8_t level, bool ack=false);
/** /**
* Requests a value from gateway or some other sensor in the radio network. * Requests a value from gateway or some other sensor in the radio network.
* Make sure to add callback-method in begin-method to handle request responses. * Make sure to add callback-method in begin-method to handle request responses.
* *
* @param childSensorId The unique child id for the different sensors connected to this arduino. 0-254. * @param childSensorId The unique child id for the different sensors connected to this Arduino. 0-254.
* @param variableType The variableType to fetch * @param variableType The variableType to fetch
* @param destination The nodeId of other node in radio network. Default is gateway * @param destination The nodeId of other node in radio network. Default is gateway
*/ */
@@ -192,7 +197,7 @@ class MySensor : public RF24
/** /**
* Returns the last received message * Returns the last received message
*/ */
MyMessage* getLastMessage(void); MyMessage& getLastMessage(void);
/** /**
* Sleep (PowerDownMode) the Arduino and radio. Wake up on timer. * Sleep (PowerDownMode) the Arduino and radio. Wake up on timer.
@@ -229,16 +234,16 @@ class MySensor : public RF24
protected: protected:
NodeConfig nc; // Essential settings for node to work NodeConfig nc; // Essential settings for node to work
ControllerConfig cc; // Configuration coming from controller ControllerConfig cc; // Configuration coming from controller
bool relayMode; bool repeaterMode;
bool isGateway; bool isGateway;
MyMessage msg; // Buffer for incoming messages. MyMessage msg; // Buffer for incoming messages.
MyMessage ack; // Buffer for ack messages. MyMessage ack; // Buffer for ack messages.
void setupRelayMode(); void setupRepeaterMode();
void setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate); void setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate);
boolean sendRoute(MyMessage *message); boolean sendRoute(MyMessage &message);
boolean sendWrite(uint8_t dest, MyMessage *message, bool broadcast=false); boolean sendWrite(uint8_t dest, MyMessage &message, bool broadcast=false);
uint8_t validate(MyMessage *message); uint8_t validate(MyMessage &message);
private: private:
#ifdef DEBUG #ifdef DEBUG
@@ -247,12 +252,12 @@ class MySensor : public RF24
uint8_t failedTransmissions; uint8_t failedTransmissions;
uint8_t *childNodeTable; // In memory buffer for routing information to other nodes. also stored in EEPROM uint8_t *childNodeTable; // In memory buffer for routing information to other nodes. also stored in EEPROM
void (*timeCallback)(unsigned long); // Callback for requested time messages void (*timeCallback)(unsigned long); // Callback for requested time messages
void (*msgCallback)(MyMessage); // Callback for incoming messages from other nodes and gateway. void (*msgCallback)(const MyMessage &); // Callback for incoming messages from other nodes and gateway.
void waitForReply(); void waitForReply();
void requestNodeId(); void requestNodeId();
void findParentNode(); void findParentNode();
uint8_t crc8Message(MyMessage *message); uint8_t crc8Message(MyMessage &message);
uint8_t getChildRoute(uint8_t childId); uint8_t getChildRoute(uint8_t childId);
void addChildRoute(uint8_t childId, uint8_t route); void addChildRoute(uint8_t childId, uint8_t route);
void removeChildRoute(uint8_t childId); void removeChildRoute(uint8_t childId);
@@ -57,7 +57,7 @@ void loop()
if (lastTemperature[i] != temperature && temperature != -127.00) { if (lastTemperature[i] != temperature && temperature != -127.00) {
// Send in the new temperature // Send in the new temperature
gw.send(msg.setSensor(i)->set(temperature,1)); gw.send(msg.setSensor(i).set(temperature,1));
lastTemperature[i]=temperature; lastTemperature[i]=temperature;
} }
} }
@@ -93,7 +93,7 @@ void loop()
} }
} }
void incomingMessage(MyMessage message) { void incomingMessage(const MyMessage &message) {
if (message.type==V_VAR1) { if (message.type==V_VAR1) {
pulseCount = oldPulseCount = message.getLong(); pulseCount = oldPulseCount = message.getLong();
Serial.print("Received last pulse count from gw:"); Serial.print("Received last pulse count from gw:");
@@ -54,7 +54,7 @@ void loop()
void incomingMessage(MyMessage message) { void incomingMessage(const MyMessage &message) {
// We only expect one type of message from controller. But we better check anyway. // We only expect one type of message from controller. But we better check anyway.
if (message.type==V_LIGHT) { if (message.type==V_LIGHT) {
int incomingRelayStatus = message.getInt(); int incomingRelayStatus = message.getInt();
@@ -29,7 +29,7 @@ unsigned long SLEEP_TIME = 30; // Sleep time between reads (in seconds)
BH1750 lightSensor; BH1750 lightSensor;
MySensor gw; MySensor gw;
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL); MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
int lastlux; uint16_t lastlux;
void setup() void setup()
{ {
@@ -38,7 +38,7 @@ void loop()
gw.process(); gw.process();
} }
void incomingMessage(MyMessage message) { void incomingMessage(const MyMessage &message) {
// We only expect one type of message from controller. But we better check anyway. // We only expect one type of message from controller. But we better check anyway.
if (message.type==V_LIGHT) { if (message.type==V_LIGHT) {
// Change relay state // Change relay state
@@ -71,8 +71,7 @@ void loop()
void incomingMessage(MyMessage message) { void incomingMessage(const MyMessage &message) {
Serial.println(gw.getInternalTemp());
// We only expect one type of message from controller. But we better check anyway. // We only expect one type of message from controller. But we better check anyway.
if (message.type==V_LIGHT) { if (message.type==V_LIGHT) {
// Change relay state // Change relay state
@@ -1,8 +1,7 @@
// Example sketch showing how to create a node thay relays messages // Example sketch showing how to create a node thay repeates messages
// from nodes far from gateway back to gateway. // from nodes far from gateway back to gateway.
// Important here is that node uses Relay-class and calls // It is important that nodes that has enabled repeater mode calls
// gw.messageAvailable() frequently. This sketch should not // gw.preocess() frequently. This node should never sleep.
// sleep.
#include <MySensor.h> #include <MySensor.h>
#include <SPI.h> #include <SPI.h>
@@ -12,11 +11,11 @@ MySensor gw;
void setup() void setup()
{ {
// The third argument enables relaying mode. // The third argument enables repeater mode.
gw.begin(NULL, AUTO, true); gw.begin(NULL, AUTO, true);
//Send the sensor node sketch version information to the gateway //Send the sensor node sketch version information to the gateway
gw.sendSketchInfo("Relaying Node", "1.0"); gw.sendSketchInfo("Repeater Node", "1.0");
} }
void loop() void loop()
@@ -49,7 +49,7 @@ void loop()
} }
} }
void incomingMessage(MyMessage message) { void incomingMessage(const MyMessage &message) {
myservo.attach(SERVO_DIGITAL_OUT_PIN); myservo.attach(SERVO_DIGITAL_OUT_PIN);
attachedServo = true; attachedServo = true;
if (message.type==V_DIMMER) { // This could be M_ACK_VARIABLE or M_SET_VARIABLE if (message.type==V_DIMMER) { // This could be M_ACK_VARIABLE or M_SET_VARIABLE
@@ -109,7 +109,7 @@ void loop()
} }
} }
void incomingMessage(MyMessage message) { void incomingMessage(const MyMessage &message) {
if (message.type==V_VAR1) { if (message.type==V_VAR1) {
pulseCount = oldPulseCount = message.getLong(); pulseCount = oldPulseCount = message.getLong();
Serial.print("Received last pulse count from gw:"); Serial.print("Received last pulse count from gw:");