diff --git a/SerialGateway/SerialGateway.ino b/SerialGateway/SerialGateway.ino index 2d3d5a3..2ce8685 100644 --- a/SerialGateway/SerialGateway.ino +++ b/SerialGateway/SerialGateway.ino @@ -28,7 +28,6 @@ #include #include #include -#include #define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled #define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button diff --git a/libraries/MySensors/Config.h b/libraries/MySensors/Config.h index baafd5b..3b3b6e4 100644 --- a/libraries/MySensors/Config.h +++ b/libraries/MySensors/Config.h @@ -5,9 +5,9 @@ * Configure Sensor Network */ #define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127 -#define RF24_DATARATE RF24_250KBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps -#define RF24_PA_LEVEL RF24_PA_MAX //Senor PA Level == RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBM, and RF24_PA_HIGH=0dBm -#define RF24_PA_LEVEL_GW RF24_PA_LEVEL //Gateway PA Level, defaults to Sensor net PA Level. Tune here if using an amplified nRF2401+ in your gateway. +#define RF24_DATARATE RF24_1MBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps +#define RF24_PA_LEVEL RF24_PA_MAX //Sensor PA Level == RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBM, and RF24_PA_HIGH=0dBm +#define RF24_PA_LEVEL_GW RF24_PA_LOW //Gateway PA Level, defaults to Sensor net PA Level. Tune here if using an amplified nRF2401+ in your gateway. /*** * Enable/Disable debug logging diff --git a/libraries/MySensors/Gateway.cpp b/libraries/MySensors/Gateway.cpp index 2470fe5..1b59d04 100644 --- a/libraries/MySensors/Gateway.cpp +++ b/libraries/MySensors/Gateway.cpp @@ -1,5 +1,5 @@ /* - The MySensors Arduino library adds a new layer on top of the RF24 library. + The MySensors library adds a new layer on top of the RF24 library. It handles radio network routing, relaying and ids. Created by Henrik Ekblad @@ -67,6 +67,7 @@ void Gateway::begin(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e data // Start up the radio library setupRadio(paLevel, channel, dataRate); + RF24::openReadingPipe(WRITE_PIPE, BASE_RADIO_ID); RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID); RF24::startListening(); diff --git a/libraries/MySensors/Gateway.h b/libraries/MySensors/Gateway.h index 692997f..f23beb8 100644 --- a/libraries/MySensors/Gateway.h +++ b/libraries/MySensors/Gateway.h @@ -1,5 +1,5 @@ /* - The MySensors Arduino library adds a new layer on top of the RF24 library. + The MySensors library adds a new layer on top of the RF24 library. It handles radio network routing, relaying and ids. Created by Henrik Ekblad diff --git a/libraries/MySensors/Relay.cpp b/libraries/MySensors/Relay.cpp index d955c99..19f5b0d 100644 --- a/libraries/MySensors/Relay.cpp +++ b/libraries/MySensors/Relay.cpp @@ -1,5 +1,5 @@ /* - The MySensors Arduino library adds a new layer on top of the RF24 library. + The MySensors library adds a new layer on top of the RF24 library. It handles radio network routing, relaying and ids. Created by Henrik Ekblad @@ -86,8 +86,20 @@ boolean Relay::messageAvailable() { } if (available && pipe<7) { - uint8_t len = RF24::getDynamicPayloadSize()-sizeof(msg.header); - boolean ok = readMessage(); + uint8_t len = RF24::getDynamicPayloadSize(); + RF24::read(&msg, len); + RF24::writeAckPayload(pipe,&pipe, 1 ); + + uint8_t valid = validate(len-sizeof(header_s)); + boolean ok = valid == VALIDATE_OK; + + // Make sure string gets terminated ok for full sized messages. + msg.data[len - sizeof(header_s) ] = '\0'; + debug(PSTR("Rx: fr=%d,to=%d,la=%d,ci=%d,mt=%d,t=%d,cr=%d(%s): %s\n"), + msg.header.from,msg.header.to, msg.header.last, msg.header.childId, msg.header.messageType, msg.header.type, msg.header.crc, valid==0?"ok":valid==1?"ec":"ev", msg.data); + + + //boolean ok = readMessage(); if (ok) { if (msg.header.messageType == M_INTERNAL && msg.header.type == I_PING) { @@ -130,11 +142,14 @@ boolean Relay::messageAvailable() { } else { // If this is variable message from sensor net gateway. Send ack back. debug(PSTR("Message addressed for this node.\n")); - if (msg.header.from == GATEWAY_ADDRESS && - msg.header.messageType == M_SET_VARIABLE) { - // Send back ack message to sensor net gateway + + // Send set-message back to sender if sender wants this + if (msg.header.messageType == M_SET_WITH_ACK) { sendVariableAck(); + // The library user should not need to care about this ack request. Just treat it as a normal SET. + msg.header.messageType = M_SET_VARIABLE; } + // Return message to waiting sketch... if (msg.header.last != GATEWAY_ADDRESS) addChildRoute(msg.header.from, msg.header.last); @@ -143,7 +158,7 @@ boolean Relay::messageAvailable() { } } else { // We should probably try to relay this message - relayMessage(len, pipe); + relayMessage(len-sizeof(msg.header), pipe); } } } @@ -243,14 +258,14 @@ void Relay::clearChildRoutes() { void Relay::sendChildren() { // Send in which children that is using this node as an relay. // TODO: Fix this - debug(PSTR("Send child info to sensor gateway.\n")); + debug(PSTR("Dump beginning of routing table\n")); - for (int i=0;i< 10; i++) { + for (int i=0;i< 50; i++) { // Serial.println(childNodeTable[i]); debug(PSTR("rt:%d, %d\n"), i, getChildRoute(i) ); } - //sendInternal(I_CHILDREN, "not implemented"); + sendInternal(I_CHILDREN, "not implemented"); } diff --git a/libraries/MySensors/Relay.h b/libraries/MySensors/Relay.h index 6c17656..c5f3272 100644 --- a/libraries/MySensors/Relay.h +++ b/libraries/MySensors/Relay.h @@ -1,5 +1,5 @@ /* - The MySensors Arduino library adds a new layer on top of the RF24 library. + The MySensors library adds a new layer on top of the RF24 library. It handles radio network routing, relaying and ids. Created by Henrik Ekblad diff --git a/libraries/MySensors/Sensor.cpp b/libraries/MySensors/Sensor.cpp index aa8a634..72adc9f 100644 --- a/libraries/MySensors/Sensor.cpp +++ b/libraries/MySensors/Sensor.cpp @@ -22,15 +22,22 @@ void Sensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e // Start up the radio library RF24::begin(); + RF24::setAutoAck(1); + RF24::enableAckPayload(); + if (!RF24::isPVariant()) { + debug(PSTR("Sorry, you'll need to use the P version of NRF24L01.\n")); + while(1); + } + RF24::setChannel(channel); RF24::setPALevel(paLevel); RF24::setDataRate(dataRate); - RF24::setAutoAck(true); - RF24::setRetries(2,15); + RF24::setRetries(5,15); RF24::setCRCLength(RF24_CRC_16); RF24::enableDynamicPayloads(); + // All repeater nodes and gateway listen to broadcast pipe (for PING messages) if (isRelay) { RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS)); @@ -44,6 +51,7 @@ void Sensor::begin(uint8_t _radioId, rf24_pa_dbm_e paLevel, uint8_t channel, rf2 debug(PSTR("Started %s.\n"), isRelay?"relay":"sensor"); + setupRadio(paLevel, channel, dataRate); // Fetch relay from EEPROM @@ -58,7 +66,8 @@ void Sensor::begin(uint8_t _radioId, rf24_pa_dbm_e paLevel, uint8_t channel, rf2 initializeRadioId(); - // Open reading pipe for messages directed to this node + // Open reading pipe for messages directed to this node (set write pipe to same) + RF24::openReadingPipe(WRITE_PIPE, TO_ADDR(radioId)); RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(radioId)); // Send presentation for this radio node @@ -224,11 +233,16 @@ boolean Sensor::sendWrite(uint8_t dest, message_s message, int length) { message.header.from,message.header.to, message.header.last, dest, message.header.childId, message.header.messageType, message.header.type, message.header.crc, message.data); bool broadcast = message.header.messageType == M_INTERNAL && message.header.type == I_PING; + RF24::stopListening(); RF24::openWritingPipe(TO_ADDR(dest)); bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, sizeof(message.header) + length), broadcast); RF24::startListening(); + + //RF24::closeReadingPipe(WRITE_PIPE); // Stop listening to write-pipe after transmit + //delay(50); + if (ok) debug(PSTR("Sent successfully\n")); else @@ -351,11 +365,11 @@ char* Sensor::get(uint8_t nodeId, uint8_t childId, uint8_t sendType, uint8_t rec } char* Sensor::getStatus(uint8_t childId, uint8_t variableType) { - return get(GATEWAY_ADDRESS, childId, M_REQ_VARIABLE, M_ACK_VARIABLE, variableType); + return get(GATEWAY_ADDRESS, childId, M_REQ_VARIABLE, M_SET_VARIABLE, variableType); } char * Sensor::getStatus(uint8_t nodeId, int8_t childId, uint8_t variableType) { - return get(nodeId, childId, M_REQ_VARIABLE, M_ACK_VARIABLE, variableType); + return get(nodeId, childId, M_REQ_VARIABLE, M_SET_VARIABLE, variableType); } @@ -385,22 +399,33 @@ void Sensor::requestIsMetricSystem() { boolean Sensor::messageAvailable() { uint8_t pipe; boolean available = RF24::available(&pipe); - - if (available) { - debug(PSTR("Message available on pipe %d\n"),pipe); - } - - if (available && pipe<7) { - boolean ok = readMessage(); + + uint8_t len = RF24::getDynamicPayloadSize(); + RF24::read(&msg, len); + RF24::writeAckPayload(pipe,&pipe, 1 ); + + if (available) { + debug(PSTR("Message available on pipe %d\n"),pipe); + } + + uint8_t valid = validate(len-sizeof(header_s)); + boolean ok = valid == VALIDATE_OK; + + // Make sure string gets terminated ok for full sized messages. + msg.data[len - sizeof(header_s) ] = '\0'; + debug(PSTR("Rx: fr=%d,to=%d,la=%d,ci=%d,mt=%d,t=%d,cr=%d(%s): %s\n"), + msg.header.from,msg.header.to, msg.header.last, msg.header.childId, msg.header.messageType, msg.header.type, msg.header.crc, valid==0?"ok":valid==1?"ec":"ev", msg.data); + + // boolean ok = readMessage(); if (ok && msg.header.to == radioId) { // This message is addressed to this node debug(PSTR("Message addressed for this node.\n")); - if (msg.header.from == GATEWAY_ADDRESS && - // If this is variable message from sensor net gateway. Send ack back. - msg.header.messageType == M_SET_VARIABLE) { - // Send back ack message to sensor net gateway + // Send set-message back to sender if sender wants this + if (msg.header.messageType == M_SET_WITH_ACK) { sendVariableAck(); + // The library user should not need to care about this ack request. Just treat it as a normal SET. + msg.header.messageType = M_SET_VARIABLE; } // Return message to waiting sketch... return true; @@ -423,7 +448,7 @@ message_s Sensor::getMessage() { } -boolean Sensor::readMessage() { +/*boolean Sensor::readMessage() { uint8_t len = RF24::getDynamicPayloadSize(); RF24::read(&msg, len); @@ -435,7 +460,7 @@ boolean Sensor::readMessage() { debug(PSTR("Rx: fr=%d,to=%d,la=%d,ci=%d,mt=%d,t=%d,cr=%d(%s): %s\n"), msg.header.from,msg.header.to, msg.header.last, msg.header.childId, msg.header.messageType, msg.header.type, msg.header.crc, valid==0?"ok":valid==1?"ec":"ev", msg.data); return ok; -} +}*/ /* * calculate CRC8 on message_s data taking care of data structure and protocol version diff --git a/libraries/MySensors/Sensor.h b/libraries/MySensors/Sensor.h index e17a691..d661bc5 100644 --- a/libraries/MySensors/Sensor.h +++ b/libraries/MySensors/Sensor.h @@ -1,5 +1,5 @@ /* - The Sensor Net Arduino library adds a new layer on top of the RF24 library. + The MySensors library adds a new layer on top of the RF24 library. It handles radio network routing, relaying and ids. Created by Henrik Ekblad @@ -41,7 +41,7 @@ // This is the radioId for sensor net gateway receiver sketch (where all sensors should send their data). // This is also act as base value for sensor radioId -#define BASE_RADIO_ID ((uint64_t)0xABCDABC000LL) +#define BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) #define GATEWAY_ADDRESS ((uint8_t)0) #define BROADCAST_ADDRESS ((uint8_t)0xFF) #define TO_ADDR(x) (BASE_RADIO_ID + x) @@ -61,7 +61,7 @@ typedef enum { M_PRESENTATION = 0, M_SET_VARIABLE = 1, M_REQ_VARIABLE = 2, - M_ACK_VARIABLE = 3, + M_SET_WITH_ACK = 3, M_INTERNAL = 4 } messageType; @@ -278,7 +278,7 @@ class Sensor : public RF24 void findRelay(); boolean send(message_s message, int length); boolean sendWrite(uint8_t dest, message_s message, int length); - boolean readMessage(); + //boolean readMessage(); void buildMsg(uint8_t from, uint8_t to, uint8_t childId, uint8_t messageType, uint8_t type, const char *data, uint8_t length, boolean binary); void sendInternal(uint8_t variableType, const char *value); boolean sendVariableAck(); diff --git a/libraries/MySensors/examples/RelayActuator/RelayActuator.ino b/libraries/MySensors/examples/RelayActuator/RelayActuator.ino index 8b995b6..47c73b7 100644 --- a/libraries/MySensors/examples/RelayActuator/RelayActuator.ino +++ b/libraries/MySensors/examples/RelayActuator/RelayActuator.ino @@ -6,11 +6,11 @@ #include #define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) -#define NUMBER_OF_RELAYS 1 -#define RELAY_ON 0 -#define RELAY_OFF 1 +#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 -Sensor gw; +Relay gw; void setup() {