From a31d9d1074abcb69b03676a552e99aa185ab4a08 Mon Sep 17 00:00:00 2001 From: Henrik Ekblad Date: Thu, 15 May 2014 07:40:07 +0200 Subject: [PATCH] Reduce library size --- libraries/MySensors/MyConfig.h | 2 +- libraries/MySensors/MyGateway.cpp | 4 +- libraries/MySensors/MyMessage.cpp | 203 +++++----------- libraries/MySensors/MyMessage.h | 70 +++--- libraries/MySensors/MySensor.cpp | 219 +++++------------- libraries/MySensors/MySensor.h | 57 ++--- .../examples/RelayActuator/RelayActuator.ino | 16 +- 7 files changed, 176 insertions(+), 395 deletions(-) diff --git a/libraries/MySensors/MyConfig.h b/libraries/MySensors/MyConfig.h index 474b705..5d7956f 100644 --- a/libraries/MySensors/MyConfig.h +++ b/libraries/MySensors/MyConfig.h @@ -12,6 +12,6 @@ /*** * Enable/Disable debug logging */ -#define DEBUG +//#define DEBUG #endif diff --git a/libraries/MySensors/MyGateway.cpp b/libraries/MySensors/MyGateway.cpp index fbf148a..2abed16 100644 --- a/libraries/MySensors/MyGateway.cpp +++ b/libraries/MySensors/MyGateway.cpp @@ -187,7 +187,7 @@ void MyGateway::processRadioMessage() { if (process()) { // A new message was received from one of the sensors MyMessage message = getLastMessage(); - if (message.getCommand() == C_PRESENTATION && inclusionMode) { + if (mGetCommand(message) == C_PRESENTATION && inclusionMode) { rxBlink(3); } else { rxBlink(1); @@ -213,7 +213,7 @@ void MyGateway::serial(const char *fmt, ... ) { } void MyGateway::serial(MyMessage msg) { - serial(PSTR("%d;%d;%d;%d;%s\n"),msg.getSender(), msg.getSensor(), msg.getCommand(), msg.getType(), msg.getString(convBuf)); + serial(PSTR("%d;%d;%d;%d;%s\n"),msg.sender, msg.sensor, mGetCommand(msg), msg.type, msg.getString(convBuf)); } diff --git a/libraries/MySensors/MyMessage.cpp b/libraries/MySensors/MyMessage.cpp index 759d72e..9175489 100644 --- a/libraries/MySensors/MyMessage.cpp +++ b/libraries/MySensors/MyMessage.cpp @@ -4,73 +4,8 @@ MyMessage::MyMessage() { - setVersion(PROTOCOL_VERSION); } -MyMessage::MyMessage(uint8_t _sensor, uint8_t _type, uint8_t _destination) { - sensor = _sensor; - type = _type; - destination = _destination; - setVersion(PROTOCOL_VERSION); - setCommand(C_SET_VARIABLE); -} - -MyMessage MyMessage::build(uint8_t _sender, uint8_t _destination, uint8_t _sensor, uint8_t _command, uint8_t _type) { - sender = _sender; - destination = _destination; - sensor = _sensor; - type = _type; - setCommand(_command); - setLength(0); - setPayloadType(P_STRING); - return *this; -} - -/*MyMessage MyMessage::failed() { - return getCommand() == C_FAILED -}*/ - -// Header getters - -uint8_t MyMessage::getCRC() { - return crc; -} - -uint8_t MyMessage::getVersion() { - return BF_GET(version_length, 0, 3); -} - -uint8_t MyMessage::getLength() { - return BF_GET(version_length, 3, 5); -} - -uint8_t MyMessage::getCommand() { - return BF_GET(command_payload, 0, 4); -} - -uint8_t MyMessage::getPayloadType() { - return BF_GET(command_payload, 4, 4); -} - -uint8_t MyMessage::getType() { - return type; -} - -uint8_t MyMessage::getSensor() { - return sensor; -} - -uint8_t MyMessage::getSender() { - return sender; -} - -uint8_t MyMessage::getLast() { - return last; -} - -uint8_t MyMessage::getDestination() { - return destination; -} /* Getters for payload converted to desired form */ @@ -80,10 +15,10 @@ void* MyMessage::getCustom() { /* NOTE: Calling this method might affect the payload by converting it to its string representation */ char* MyMessage::getString(char *buffer) { - uint8_t payloadType = getPayloadType(); + uint8_t payloadType = miGetPayloadType(); if (payloadType == P_STRING) { - data[getLength()] = '\0'; + data[miGetLength()] = '\0'; return data; } else if (buffer != NULL) { switch(payloadType) { @@ -116,11 +51,14 @@ char* MyMessage::getString(char *buffer) { } uint8_t MyMessage::getByte() { - if (getPayloadType() == P_BYTE) + switch(miGetPayloadType()) { + case P_BYTE: return data[0]; - if (getPayloadType() == P_STRING) + case P_STRING: return atoi(data); - return 0; + default: + return 0; + } } bool MyMessage::getBool() { return !(data[0]-'0'==0); @@ -131,90 +69,55 @@ double MyMessage::getDouble() { } long MyMessage::getLong() { - if (getPayloadType() == P_LONG32) + switch(miGetPayloadType()) { + case P_LONG32: return lValue; - if (getPayloadType() == P_STRING) + case P_STRING: return atol(data); - return 0; + default: + return 0; + } } + unsigned long MyMessage::getULong() { - if (getPayloadType() == P_ULONG32) + switch(miGetPayloadType()) { + case P_ULONG32: return ulValue; - if (getPayloadType() == P_STRING) + case P_STRING: return atol(data); - return 0; + default: + return 0; + } } + int MyMessage::getInt() { - if (getPayloadType() == P_INT16) + switch(miGetPayloadType()) { + case P_INT16: return iValue; - if (getPayloadType() == P_STRING) + case P_STRING: return atoi(data); - return 0; + default: + return 0; + } } + unsigned int MyMessage::getUInt() { - if (getPayloadType() == P_UINT16) + switch(miGetPayloadType()) { + case P_UINT16: return uiValue; - if (getPayloadType() == P_STRING) + case P_STRING: return atoi(data); - return 0; -} + default: + return 0; + } -// Header setters -MyMessage MyMessage::setCRC(uint8_t _crc) { - crc = _crc; - return *this; -} - -MyMessage MyMessage::setVersion(uint8_t version) { - BF_SET(version_length, version, 0, 3); - return *this; -} - -MyMessage MyMessage::setLength(uint8_t length) { - BF_SET(version_length, length, 3, 5); - return *this; -} - -MyMessage MyMessage::setCommand(uint8_t command) { - BF_SET(command_payload, command, 0, 4); - return *this; -} - -MyMessage MyMessage::setPayloadType(uint8_t pt) { - BF_SET(command_payload, pt, 4, 4); - return *this; -} - -MyMessage MyMessage::setType(uint8_t _type) { - type = _type; - return *this; -} - -MyMessage MyMessage::setSensor(uint8_t _sensor) { - sensor = _sensor; - return *this; -} - -MyMessage MyMessage::setSender(uint8_t _sender) { - sender = _sender; - return *this; -} - -MyMessage MyMessage::setLast(uint8_t _last) { - last=_last; - return *this; -} - -MyMessage MyMessage::setDestination(uint8_t _destination) { - destination = _destination; - return *this; } // Set payload MyMessage MyMessage::set(void* value, uint8_t length) { - setPayloadType(P_CUSTOM); - setLength(length); + miSetPayloadType(P_CUSTOM); + miSetLength(length); memcpy(data, value, min(length, MAX_PAYLOAD)); return *this; } @@ -222,57 +125,57 @@ MyMessage MyMessage::set(void* value, uint8_t length) { MyMessage MyMessage::set(const char* value) { uint8_t length = strlen(value); - setLength(length); - setPayloadType(P_STRING); + miSetLength(length); + miSetPayloadType(P_STRING); strncpy(data, value, min(length, MAX_PAYLOAD)); return *this; } MyMessage MyMessage::set(uint8_t value) { - setLength(1); - setPayloadType(P_BYTE); + miSetLength(1); + miSetPayloadType(P_BYTE); data[0] = value; return *this; } MyMessage MyMessage::set(bool value) { - setLength(1); - setPayloadType(P_STRING); + miSetLength(1); + miSetPayloadType(P_STRING); data[0] = value?'1':'0'; return *this; } MyMessage MyMessage::set(double value, uint8_t decimals) { dtostrf(value,2,decimals,data); - setLength(strlen(data)); - setPayloadType(P_STRING); + miSetLength(strlen(data)); + miSetPayloadType(P_STRING); return *this; } MyMessage MyMessage::set(unsigned long value) { - setPayloadType(P_ULONG32); - setLength(4); + miSetPayloadType(P_ULONG32); + miSetLength(4); ulValue = value; return *this; } MyMessage MyMessage::set(long value) { - setPayloadType(P_LONG32); - setLength(4); + miSetPayloadType(P_LONG32); + miSetLength(4); lValue = value; return *this; } MyMessage MyMessage::set(unsigned int value) { - setPayloadType(P_INT16); - setLength(2); + miSetPayloadType(P_INT16); + miSetLength(2); uiValue = value; return *this; } MyMessage MyMessage::set(int value) { - setPayloadType(P_UINT16); - setLength(2); + miSetPayloadType(P_UINT16); + miSetLength(2); iValue = value; return *this; } diff --git a/libraries/MySensors/MyMessage.h b/libraries/MySensors/MyMessage.h index bd80b66..6d4f053 100644 --- a/libraries/MySensors/MyMessage.h +++ b/libraries/MySensors/MyMessage.h @@ -18,7 +18,6 @@ #define MAX_MESSAGE_LENGTH 32 #define HEADER_SIZE 8 #define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) -#define GATEWAY_ADDRESS ((uint8_t)0) // Message types typedef enum { @@ -27,8 +26,7 @@ typedef enum { C_REQ_VARIABLE = 2, C_SET_WITH_ACK = 3, C_INTERNAL = 4, - C_STREAM = 5, // For Firmaware and other larger chunks of data that need to be divided into pieces. - C_FAILED = 6 + C_STREAM = 5 // For Firmaware and other larger chunks of data that need to be divided into pieces. } command; // Type of sensor data (for set/req/ack messages) @@ -44,7 +42,7 @@ typedef enum { typedef enum { I_BATTERY_LEVEL, I_TIME, I_VERSION, I_REQUEST_ID, I_INCLUSION_MODE, I_RELAY_NODE, I_PING, I_PING_ACK, - I_LOG_MESSAGE, I_CHILDREN, I_UNIT, I_SKETCH_NAME, I_SKETCH_VERSION + I_LOG_MESSAGE, I_CHILDREN, I_CONFIG, I_SKETCH_NAME, I_SKETCH_VERSION } internal; // Type of sensor (for presentation message) @@ -82,46 +80,44 @@ typedef enum { // Insert a new bitfield value x into y. #define BF_SET(y, x, start, len) ( y= ((y) &~ BF_MASK(start, len)) | BF_PREP(x, start, len) ) +// Getters/setters for special fields in header +#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 mSetCommand(_msg,_command) BF_SET(_msg.command_payload, _command, 0, 4) +#define mSetPayloadType(_msg, _pt) BF_SET(_msg.command_payload, _pt, 4, 4) + +#define mGetVersion(_msg) BF_GET(_msg.version_length, 0, 3) +#define mGetLength(_msg) BF_GET(_msg.version_length, 3, 5) +#define mGetCommand(_msg) BF_GET(_msg.command_payload, 0, 4) +#define mGetPayloadType(_msg) BF_GET(_msg.command_payload, 4, 4) + +// internal access for special fileds +#define miGetPayloadType() BF_GET(command_payload, 4, 4) +#define miGetLength() BF_GET(version_length, 3, 5) + +#define miSetLength(_length) BF_SET(version_length, _length, 3, 5) +#define miSetPayloadType(_pt) BF_SET(command_payload, _pt, 4, 4) + + +// Check and fetch data from special messages +#define isTimeResponse(_msg) (mGetCommand(_msg)==C_INTERN && _msg.type==I_TIME) +#define isConfigResponse(_msg) (mGetCommand(_msg)==C_INTERN && _msg.type==I_CONFIG) +#define mIsMetric(_msg) (_msg.getByte() == 'M') class MyMessage { public: // Constructors - MyMessage(uint8_t sensor, uint8_t type, uint8_t destination=GATEWAY_ADDRESS); MyMessage(); - /* Check this after callback to see if request failed */ -// bool failed(); - - - // Getters for header - uint8_t getCRC(); - uint8_t getVersion(); - uint8_t getLength(); - uint8_t getCommand(); - uint8_t getPayloadType(); - uint8_t getType(); - uint8_t getSensor(); - uint8_t getSender(); - uint8_t getLast(); - uint8_t getDestination(); - - // Getters for payload - - /** * If payload is something else than P_STRING you can have payload the value converted * to 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. */ char* getString(char *buffer = NULL); - - /** - * Returns payload untouched - */ void* getCustom(); - uint8_t getByte(); bool getBool(); double getDouble(); @@ -130,21 +126,6 @@ public: int getInt(); unsigned int getUInt(); - // Builder helper - MyMessage build(uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type); - - // Setters for header - MyMessage setCRC(uint8_t crc); - MyMessage setVersion(uint8_t version); - MyMessage setLength(uint8_t length); - MyMessage setCommand(uint8_t command); - MyMessage setPayloadType(uint8_t pt); - MyMessage setType(uint8_t type); - MyMessage setSensor(uint8_t sensor); - MyMessage setSender(uint8_t sender); - MyMessage setLast(uint8_t last); - MyMessage setDestination(uint8_t destination); - // Setters for payload MyMessage set(void* payload, uint8_t length); @@ -166,6 +147,7 @@ public: 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 // terminator \0 to be "printable" this is not transferred OTA // This union is used to simplify the construction of the binary transferred int/long values. diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index dcd7798..02c8240 100644 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -14,7 +14,6 @@ MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) { } - void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) { failedTransmissions = 0; @@ -41,7 +40,7 @@ void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_ } void MySensor::setupRelayMode(){ - s.childNodeTable = (uint8_t *) malloc(256); + s.childNodeTable = new uint8_t[256]; eeprom_read_block((void*)s.childNodeTable, (void*)EEPROM_ROUTES_ADDRESS, 256); } @@ -81,7 +80,7 @@ void MySensor::begin(void (*_msgCallback)(MyMessage), boolean _relayMode, uint8_ present(NODE_CHILD_ID, relayMode? S_ARDUINO_RELAY : S_ARDUINO_NODE); // Send parent information back to sensor net gateway. - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_RELAY_NODE).set(s.parentNodeId)); + buildSendPayload(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_RELAY_NODE, s.parentNodeId); } @@ -92,7 +91,7 @@ uint8_t MySensor::getNodeId() { void MySensor::requestNodeId() { debug(PSTR("req node id\n")); RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(s.nodeId)); - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_REQUEST_ID)); + buildSend(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_REQUEST_ID); } @@ -110,7 +109,8 @@ void MySensor::findParentNode() { s.distance = 255; // Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to) - sendWrite(BROADCAST_ADDRESS, msg.build(s.nodeId, BROADCAST_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_PING)); + build(msg, s.nodeId, BROADCAST_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_PING) + sendWrite(BROADCAST_ADDRESS, msg, true); // Wait for replies for max 10 seconds (or when buffer for all parent nodes have been filled up) unsigned long enter = millis(); @@ -121,32 +121,18 @@ void MySensor::findParentNode() { } - - - -/* -boolean MySensor::sendAck(MyMessage message) { - // Build ack message - ack = message; - ack.setCommand(C_SET_VARIABLE); - ack.setSender(s.nodeId); - ack.setDestination(message.getSender()); - return sendRoute(ack); -}*/ - - boolean MySensor::sendRoute(MyMessage message) { // Make sure to process any incoming messages before sending (could this end up in recursive loop?) process(); // If we still don't have any node id, re-request and skip this message. - if (s.nodeId == AUTO && !(message.getCommand() == C_INTERNAL && message.getType() == I_REQUEST_ID)) { + if (s.nodeId == AUTO && !(mGetCommand(message) == C_INTERNAL && message.type == I_REQUEST_ID)) { requestNodeId(); return false; } if (relayMode) { - uint8_t dest = message.getDestination(); + uint8_t dest = message.destination; uint8_t route = getChildRoute(dest); if (route>0 && route<255 && dest != GATEWAY_ADDRESS) { debug(PSTR("route %d.\n"), route); @@ -176,16 +162,11 @@ boolean MySensor::sendRoute(MyMessage message) { return false; } - - - - -boolean MySensor::sendWrite(uint8_t next, MyMessage message) { - uint8_t length = message.getLength(); - message.setLast(s.nodeId); - message.setCRC(crc8Message(message)); - - bool broadcast = message.getCommand() == C_INTERNAL && message.getType() == I_PING; +boolean MySensor::sendWrite(uint8_t next, MyMessage message, bool broadcast) { + uint8_t length = mGetLength(message); + message.last = s.nodeId; + mSetVersion(message, PROTOCOL_VERSION); + message.crc = crc8Message(message); // Make sure radio has powered up RF24::powerUp(); @@ -196,115 +177,54 @@ boolean MySensor::sendWrite(uint8_t next, MyMessage message) { // Only debug print payload if it is of string type debug(PSTR("tx: %d-%d-%d-%d s=%d,c=%d,t=%d, st=%s:%s\n"), - message.getSender(),message.getLast(), next, message.getDestination(), message.getSensor(), message.getCommand(), message.getType(), ok?"ok":"fail", message.getString()); + message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type, ok?"ok":"fail", message.getString()); return ok; } bool MySensor::send(MyMessage message, bool enableAck) { - message.setSender(s.nodeId); + message.sender = s.nodeId; if (enableAck) { - message.setCommand(C_SET_WITH_ACK); + mSetCommand(message,C_SET_WITH_ACK); } return sendRoute(message); - -/* return wait(message, C_SET_VARIABLE, retry).getCommand() != C_FAILED; - } else { - return ; - }*/ } +void MySensor::sendBatteryLevel(uint8_t value) { + buildSendPayload(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_BATTERY_LEVEL, value); +} void MySensor::present(uint8_t childSensorId, uint8_t sensorType) { - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, childSensorId, C_PRESENTATION, sensorType).set(LIBRARY_VERSION)); + buildSendPayload(msg, s.nodeId, GATEWAY_ADDRESS, childSensorId, C_PRESENTATION, sensorType, LIBRARY_VERSION); } void MySensor::sketchInfo(const char *name, const char *version) { - if (name != NULL) - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_SKETCH_NAME).set(name)); - if (version != NULL) - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_SKETCH_VERSION).set(version)); + if (name != NULL) { + buildSendPayload(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_SKETCH_NAME, name); + } + if (version != NULL) { + buildSendPayload(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_SKETCH_VERSION, version); + } } -/* -MyMessage MySensor::get( uint8_t childSensorId, uint8_t variableType, uint8_t destination, uint8_t retry) { - msg.build(s.nodeId, destination, childSensorId, C_REQ_VARIABLE, variableType); - return wait(msg, C_SET_VARIABLE, retry); -}*/ - void MySensor::request(uint8_t childSensorId, uint8_t variableType, uint8_t destination) { - sendRoute(msg.build(s.nodeId, destination, childSensorId, C_REQ_VARIABLE, variableType)); + buildSend(msg, s.nodeId, destination, childSensorId, C_REQ_VARIABLE, variableType); } - - -void MySensor::sendBatteryLevel(int value) { - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_BATTERY_LEVEL).set(value)); -} - -/* -MyMessage MySensor::wait(MyMessage message, uint8_t expectedResponseCommand, uint8_t retry) { - while (retry>0) { - - uint8_t sensor = message.getSensor(); - uint8_t type = message.getType(); - sendRoute(message); - uint8_t i = 0; - while (i < 100) { // 1 seconds timeout before re-sending status request - while (process()) { - // Check that it is right type of message and not a routing message - if (msg.getCommand() == expectedResponseCommand && - msg.getType() == type && - msg.getSensor() == sensor) { - return msg; - } - } - delay(10); - i++; - } - retry--; - } - msg.setCommand(C_FAILED); - return msg; -} -*/ - - -/* -MyMessage MySensor::getInternal(uint8_t variableType, uint8_t retry) { - msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, variableType); - return wait(msg, C_INTERNAL, retry); -}*/ - -/*unsigned long MySensor::getTime(uint8_t retry) { - MyMessage message = getInternal(I_TIME, retry); - return message == NULL ? 0UL : message.getULong(); -}*/ - void MySensor::requestTime() { - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_TIME)); + buildSend(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_TIME); } -/*bool MySensor::isMetricSystem(uint8_t retry) { - MyMessage message = getInternal(I_UNIT, retry); - return (message == NULL) - return true; - else - return message.getByte() == 'M'; -}*/ - -void MySensor::requestIsMetricSystem() { - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_UNIT)); +void MySensor::requestConfiguration() { + buildSend(msg, s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_CONFIG); } - boolean MySensor::process() { uint8_t pipe; boolean available = RF24::available(&pipe); - if (available && pipe<7) { uint8_t len = RF24::getDynamicPayloadSize(); RF24::read(&msg, len); @@ -316,14 +236,14 @@ boolean MySensor::process() { // Make sure string gets terminated ok for full string messages. msg.data[len - HEADER_SIZE ] = '\0'; debug(PSTR("rx: %d-%d-%d s=%d,c=%d,t=%d,cr=%s: %s\n"), - msg.getSender(), msg.getLast(), msg.getDestination(), msg.getSensor(), msg.getCommand(), msg.getType(), valid==0?"ok":valid==1?"ec":"ev", msg.getString()); + msg.sender, msg.last, msg.destination, msg.sensor, mGetCommand(msg), msg.type, valid==0?"ok":valid==1?"ec":"ev", msg.getString()); if (ok) { - uint8_t command = msg.getCommand(); - uint8_t type = msg.getType(); - uint8_t sender = msg.getSender(); - uint8_t last = msg.getLast(); - uint8_t destination = msg.getDestination(); + uint8_t command = mGetCommand(msg); + uint8_t type = msg.type; + uint8_t sender = msg.sender; //getSender(); + uint8_t last = msg.last; + uint8_t destination = msg.destination; if (relayMode && command == C_INTERNAL && type == I_PING && s.nodeId != AUTO) { // Relaying nodes should always answer ping messages @@ -331,8 +251,9 @@ boolean MySensor::process() { // between ping ack messages from other relaying nodes randomSeed(millis()); delay(random(2000)); - uint8_t replyTo = msg.getSender(); - msg.build(s.nodeId, replyTo, NODE_CHILD_ID, C_INTERNAL, I_PING_ACK).set(s.distance); + uint8_t replyTo = msg.sender; + build(msg, s.nodeId, replyTo, NODE_CHILD_ID, C_INTERNAL, I_PING_ACK); + msg.set(s.distance); sendWrite(replyTo, msg); return false; } else if (destination == s.nodeId) { @@ -349,7 +270,7 @@ boolean MySensor::process() { if (distance0 && route<255) { // This message should be forwarded to a child node. If we send message // to this nodes pipe then all children will receive it because the are @@ -482,7 +411,7 @@ MyMessage MySensor::getLastMessage() { * calculate CRC8 on MyMessage data taking care of data structure and protocol version */ uint8_t MySensor::crc8Message(MyMessage message) { - uint8_t len = message.getLength(); + uint8_t len = mGetLength(message); uint8_t crc = 0x00; uint8_t loop_count; uint8_t bit_counter; @@ -491,7 +420,7 @@ uint8_t MySensor::crc8Message(MyMessage message) { uint8_t number_of_bytes_to_read = (uint8_t)sizeof(message); // Must set crc to a constant value. - message.setCRC(0); + message.crc = 0; // fill unused space by zeroes for string data only if(len>=0 && len < sizeof(message.data)-1) { @@ -525,16 +454,17 @@ uint8_t MySensor::crc8Message(MyMessage message) { uint8_t MySensor::validate(MyMessage message) { - uint8_t oldCrc = message.getCRC(); + uint8_t oldCrc = message.crc; uint8_t newCrc = crc8Message(message); - if(!(message.getVersion() == PROTOCOL_VERSION)) return VALIDATE_BAD_VERSION; + if(!(mGetVersion(message) == PROTOCOL_VERSION)) return VALIDATE_BAD_VERSION; if(!(oldCrc == newCrc)) return VALIDATE_BAD_CRC; return VALIDATE_OK; } + void MySensor::addChildRoute(uint8_t childId, uint8_t route) { if (s.childNodeTable[childId] != route) { s.childNodeTable[childId] = route; @@ -553,34 +483,13 @@ uint8_t MySensor::getChildRoute(uint8_t childId) { return s.childNodeTable[childId]; } -void MySensor::clearChildRoutes() { - debug(PSTR("rd=clear\n")); - for (unsigned int i=0;i< sizeof(s.childNodeTable); i++) { - removeChildRoute(i); - } - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_CHILDREN).set("")); -} - -void MySensor::sendChildren() { - // Send in which children that is using this node as parent. - // TODO: Fix this - for (int i=0;i< 50; i++) { -// Serial.println(s.childNodeTable[i]); - debug(PSTR("rd=%d, %d\n"), i, getChildRoute(i) ); - } - sendRoute(msg.build(s.nodeId, GATEWAY_ADDRESS, NODE_CHILD_ID, C_INTERNAL, I_CHILDREN).set("n/a")); -} - - - - #ifdef DEBUG void MySensor::debugPrint(const char *fmt, ... ) { char fmtBuffer[300]; if (s.nodeId == GATEWAY_ADDRESS) { // prepend debug message to be handled correctly by gw - Serial.print("0;0;4;11;"); + Serial.write("0;0;4;11;"); } va_list args; va_start (args, fmt ); @@ -598,8 +507,8 @@ void MySensor::debugPrint(const char *fmt, ... ) { Serial.print(fmtBuffer); Serial.flush(); - //Serial.print("0;0;4;11;Mem free:"); - //Serial.println(freeRam()); + //Serial.write("0;0;4;11;Mem free:"); + //Serial.write(freeRam()); } #endif diff --git a/libraries/MySensors/MySensor.h b/libraries/MySensors/MySensor.h index a01b155..1b0c794 100644 --- a/libraries/MySensors/MySensor.h +++ b/libraries/MySensors/MySensor.h @@ -57,6 +57,22 @@ #define SEND_RETRIES 3 #define FIND_RELAY_AFTER_FAILED_TRANSMISSIONS 5 +#define build(_msg, _sender, _destination, _sensor, _cmd, _type) \ + _msg.sender = _sender; \ + _msg.destination = _destination;\ + _msg.sensor = _sensor; \ + _msg.type = _type; \ + mSetCommand(_msg,_cmd); \ + +#define buildSend(_msg, _sender, _destination, _sensor, _cmd, _type) \ + build(_msg, _sender, _destination, _sensor, _cmd, _type) \ + sendRoute(_msg); + +#define buildSendPayload(_msg, _sender, _destination, _sensor, _cmd, _type, _value) \ + build(_msg, _sender, _destination, _sensor, _cmd, _type) \ + _msg.set(_value); \ + sendRoute(_msg); + class MySensor : public RF24 { @@ -120,7 +136,7 @@ class MySensor : public RF24 * Send this nodes battery level to gateway. * @param level Level between 0-100(%) */ - void sendBatteryLevel(int level); + void sendBatteryLevel(uint8_t level); /** * Fetches a value from gateway or some other sensor in the radio network. Resends request and waits for response. @@ -144,26 +160,24 @@ class MySensor : public RF24 * @param callback for result. This will be called when a message reply is received or request fails (see status of second argument). * @param destination The nodeId of other node in radio network. Default is gateway */ - /*void (* msgCallback)(MyMessage, bool)=NULL, */ void request(uint8_t childSensorId, uint8_t variableType, uint8_t destination=GATEWAY_ADDRESS); /** - * Fetches time from sensor net gateway. + * Requests time from controller. Pick up response in callback. * - * @return Seconds since 1970, 0 if failed. + * @return Seconds since 1970. */ -// unsigned long getTime(uint8_t retry=SEND_RETRIES); void requestTime(); /** - * Fetches unit setting from sensor net gateway. Returns true if metric system has been selected which means - * that sensor should report it's information in: celsius, meter, cm, gram, km/h, m/s etc.. + * Fetches configuration from controller. Returns true if metric system has been selected which means + * that sensor should report it's information in: + * celsius, meter, cm, gram, km/h, m/s etc.. * If false is returned the sensor should report data in imperial system which means * fahrenheit, feet, gallon, mph etc... */ - void requestIsMetricSystem(); -// bool isMetricSystem(uint8_t retry=SEND_RETRIES); + void requestConfiguration(); /** @@ -180,9 +194,6 @@ class MySensor : public RF24 - - - #ifdef DEBUG void debugPrint(const char *fmt, ... ); int freeRam(); @@ -199,44 +210,24 @@ class MySensor : public RF24 MyMessage msg; // Buffer for incoming messages. uint8_t failedTransmissions; boolean relayMode; -// char convBuffer[20]; void setupRelayMode(); void setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate); void findParentNode(); boolean sendRoute(MyMessage message); - boolean sendWrite(uint8_t dest, MyMessage message); -// void sendInternal(uint8_t variableType, const char *value); -// boolean sendAck(MyMessage message); - boolean sendData(uint8_t from, uint8_t to, uint8_t childId, uint8_t messageType, uint8_t type, const char *data, uint8_t length, boolean binaryMessage); + boolean sendWrite(uint8_t dest, MyMessage message, bool broadcast=false); uint8_t validate(MyMessage message); - void sendChildren(); - private: - // Callbacks for reqeusts -/* struct callback { - bool active; // Deactivates callback after each reply - uint8_t command; // Command type - uint8_t sender; - uint8_t sensor; - uint8_t type; - void (*msgCallback)(MyMessage, bool); - };*/ - - MyMessage ack; // Buffer for ack messages. void (*msgCallback)(MyMessage); // Callback for undefined incoming messages void requestNodeId(); uint8_t crc8Message(MyMessage); -// MyMessage wait(MyMessage msg, uint8_t expectedReceiveType, uint8_t retry); -// MyMessage getInternal(uint8_t variableType, uint8_t retry=SEND_RETRIES); uint8_t getChildRoute(uint8_t childId); void addChildRoute(uint8_t childId, uint8_t route); void removeChildRoute(uint8_t childId); - void clearChildRoutes(); }; #endif diff --git a/libraries/MySensors/examples/RelayActuator/RelayActuator.ino b/libraries/MySensors/examples/RelayActuator/RelayActuator.ino index b43e6fc..f4375d1 100644 --- a/libraries/MySensors/examples/RelayActuator/RelayActuator.ino +++ b/libraries/MySensors/examples/RelayActuator/RelayActuator.ino @@ -4,7 +4,6 @@ #include #include #include -#include #include @@ -48,18 +47,15 @@ void loop() void incomingMessage(MyMessage message) { // We only expect one type of message from controller. But we better check anyway. - Serial.println("hej"); - if (message.getType()==V_LIGHT) { - bool status = message.getBool(); - + if (message.type==V_LIGHT) { // Change relay state - digitalWrite(message.getSensor(), status?RELAY_ON:RELAY_OFF); + digitalWrite(message.sensor, message.getBool()?RELAY_ON:RELAY_OFF); // Write some debug info - Serial.print("Incoming change for relay on pin:"); - Serial.print(message.getSensor()); + Serial.print("Incoming change for sensor:"); + Serial.print(message.sensor); Serial.print(", New status: "); - Serial.println(status); - } + Serial.println(message.getBool()); + } }