Revert "Force parent node search for all transmits when parent node is not set or communication failed a number of times"

This commit is contained in:
Henrik Ekblad
2014-09-10 21:23:52 +02:00
parent b9c43029af
commit 6314cf8ef1
2 changed files with 59 additions and 87 deletions
+57 -85
View File
@@ -14,11 +14,9 @@
#include "utility/RF24.h" #include "utility/RF24.h"
#include "utility/RF24_config.h" #include "utility/RF24_config.h"
#define DISTANCE_INVALID (0xFF)
// Inline function and macros // Inline function and macros
static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) { 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;
@@ -29,13 +27,6 @@ static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destinat
return msg; return msg;
} }
static inline bool isValidParent( const uint8_t parent ) {
return parent != AUTO;
}
static inline bool isValidDistance( const uint8_t distance ) {
return distance != DISTANCE_INVALID;
}
MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) { MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) {
} }
@@ -46,7 +37,6 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
isGateway = false; isGateway = false;
repeaterMode = _repeaterMode; repeaterMode = _repeaterMode;
msgCallback = _msgCallback; msgCallback = _msgCallback;
failedTransmissions = 0;
if (repeaterMode) { if (repeaterMode) {
setupRepeaterMode(); setupRepeaterMode();
@@ -62,13 +52,11 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
cc.isMetric = 0x01; cc.isMetric = 0x01;
} }
autoFindParent = _parentNodeId == AUTO; if (_parentNodeId != AUTO) {
if (!autoFindParent) {
nc.parentNodeId = _parentNodeId; nc.parentNodeId = _parentNodeId;
nc.distance = 0; autoFindParent = false;
} else if (!isValidParent(nc.parentNodeId)) { } else {
// Auto find parent, but parent in eeprom is invalid. Force parent search on first transmit. autoFindParent = true;
nc.distance = DISTANCE_INVALID;
} }
if (_nodeId != AUTO) { if (_nodeId != AUTO) {
@@ -76,12 +64,17 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
nc.nodeId = _nodeId; nc.nodeId = _nodeId;
} }
// If no parent was found in eeprom. Try to find one.
if (autoFindParent && nc.parentNodeId == 0xff) {
findParentNode();
}
// Try to fetch node-id from gateway // Try to fetch node-id from gateway
if (nc.nodeId == AUTO) { if (nc.nodeId == AUTO) {
requestNodeId(); requestNodeId();
} }
debug(PSTR("%s started, id=%d, parent=%d, distance=%d\n"), repeaterMode?"repeater":"sensor", nc.nodeId, nc.parentNodeId, nc.distance); 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));
@@ -100,6 +93,8 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
} }
void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) { void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
failedTransmissions = 0;
// Start up the radio library // Start up the radio library
RF24::begin(); RF24::begin();
@@ -109,13 +104,13 @@ void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_
} }
RF24::setAutoAck(1); RF24::setAutoAck(1);
RF24::setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast RF24::setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
RF24::enableAckPayload();
RF24::setChannel(channel); RF24::setChannel(channel);
RF24::setPALevel(paLevel); RF24::setPALevel(paLevel);
RF24::setDataRate(dataRate); RF24::setDataRate(dataRate);
RF24::setRetries(5,15); RF24::setRetries(5,15);
RF24::setCRCLength(RF24_CRC_16); RF24::setCRCLength(RF24_CRC_16);
RF24::enableDynamicPayloads(); RF24::enableDynamicPayloads();
RF24::enableDynamicAck();// Required to disable ack-sending for broadcast messages
// All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages) // All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages)
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS)); RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
@@ -144,12 +139,14 @@ void MySensor::requestNodeId() {
void MySensor::findParentNode() { void MySensor::findParentNode() {
// Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to) failedTransmissions = 0;
debug(PSTR("find parent\n"));
// Set distance to max
nc.distance = 255;
// 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_FIND_PARENT, false).set(""); build(msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT, false).set("");
// Write msg, but suppress recursive parent search sendWrite(BROADCAST_ADDRESS, msg, true);
sendWrite(BROADCAST_ADDRESS, msg, false);
// Wait for ping response. // Wait for ping response.
waitForReply(); waitForReply();
@@ -185,64 +182,44 @@ boolean MySensor::sendRoute(MyMessage &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); return sendWrite(BROADCAST_ADDRESS, message, true);
} }
} }
if (!isGateway) { if (!isGateway) {
// --- debug(PSTR("route parent\n"));
// Should be routed back to gateway. // Should be routed back to gateway.
return sendWrite(nc.parentNodeId, message); bool ok = sendWrite(nc.parentNodeId, message);
if (!ok) {
// Failure when sending to parent node. The parent node might be down and we
// need to find another route to gateway.
if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
findParentNode();
}
failedTransmissions++;
} else {
failedTransmissions = 0;
}
return ok;
} }
return false; return false;
} }
boolean MySensor::sendWrite(uint8_t next, MyMessage &message, const bool allowFindParent) { boolean MySensor::sendWrite(uint8_t next, MyMessage &message, bool broadcast) {
bool ok = true; uint8_t length = mGetLength(message);
const bool broadcast = next == BROADCAST_ADDRESS; message.last = nc.nodeId;
const bool toParent = next == nc.parentNodeId; mSetVersion(message, PROTOCOL_VERSION);
// With current implementation parent node Id can equal the broadcast address when // Make sure radio has powered up
// starting with empty eeprom and AUTO node Id is active. RF24::powerUp();
// This behavior is undesired, as possible parents will report back to broadcast address. RF24::stopListening();
// debug(PSTR("sendWrite next=%d, parent=%d, distance=%d\n"), next, nc.parentNodeId, nc.distance); RF24::openWritingPipe(TO_ADDR(next));
// If sending directly to parent node and distance is not set, then try to find parent now. bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast);
if ( allowFindParent && toParent && !isValidDistance(nc.distance) ) { RF24::startListening();
findParentNode();
// Known distance indicates parent has been found
ok = isValidDistance(nc.distance);
}
if (ok) { debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,st=%s:%s\n"),
uint8_t length = mGetLength(message); message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type, mGetPayloadType(message), mGetLength(message), ok?"ok":"fail", message.getString(convBuf));
message.last = nc.nodeId;
mSetVersion(message, PROTOCOL_VERSION);
// Make sure radio has powered up
RF24::powerUp();
RF24::stopListening();
RF24::openWritingPipe(TO_ADDR(next));
// Send message. Disable auto-ack for broadcasts.
ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast);
RF24::startListening();
debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,st=%s:%s\n"),
message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type,
mGetPayloadType(message), mGetLength(message), broadcast ? "bc" : (ok ? "ok":"fail"), message.getString(convBuf));
// If many successive transmissions to parent failed, the parent node might be down and we
// need to find another route to gateway.
if (toParent) {
if (ok) {
failedTransmissions = 0;
} else {
failedTransmissions++;
if ( autoFindParent && (failedTransmissions >= SEARCH_FAILURES)) {
debug(PSTR("lost parent\n"));
// Set distance invalid to trigger parent search on next write.
nc.distance = DISTANCE_INVALID;
failedTransmissions = 0;
}
}
}
}
return ok; return ok;
} }
@@ -290,7 +267,7 @@ boolean MySensor::process() {
uint8_t len = RF24::getDynamicPayloadSize(); uint8_t len = RF24::getDynamicPayloadSize();
RF24::read(&msg, len); RF24::read(&msg, len);
// RF24::writeAckPayload(pipe,&pipe, 1 ); RF24::writeAckPayload(pipe,&pipe, 1 );
// Add string termination, good if we later would want to print it. // Add string termination, good if we later would want to print it.
msg.data[mGetLength(msg)] = '\0'; msg.data[mGetLength(msg)] = '\0';
@@ -310,10 +287,10 @@ boolean MySensor::process() {
if (repeaterMode && command == C_INTERNAL && type == I_FIND_PARENT) { if (repeaterMode && command == C_INTERNAL && type == I_FIND_PARENT) {
// Relaying nodes should always answer ping messages // Relaying nodes should always answer ping messages
// Wait a random delay of 0-1.023 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_FIND_PARENT_RESPONSE, false).set(nc.distance)); sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, 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. // Check if sender requests an ack back.
@@ -338,18 +315,13 @@ boolean MySensor::process() {
// We've received a reply to a FIND_PARENT message. Check if the distance is // We've received a reply to a FIND_PARENT message. Check if the distance is
// shorter than we already have. // shorter than we already have.
uint8_t distance = msg.getByte(); uint8_t distance = msg.getByte();
if (isValidDistance(distance)) if (distance<nc.distance-1) {
{ // Found a neighbor closer to GW than previously found
// Distance to gateway is one more for us w.r.t. parent nc.distance = distance + 1;
distance++; nc.parentNodeId = msg.sender;
if (isValidDistance(distance) && (distance < nc.distance)) { eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
// Found a neighbor closer to GW than previously found eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
nc.distance = distance; debug(PSTR("new parent=%d, d=%d\n"), nc.parentNodeId, nc.distance);
nc.parentNodeId = msg.sender;
eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
debug(PSTR("new parent=%d, d=%d\n"), nc.parentNodeId, nc.distance);
}
} }
return false; return false;
} else if (sender == GATEWAY_ADDRESS) { } else if (sender == GATEWAY_ADDRESS) {
+2 -2
View File
@@ -66,7 +66,7 @@
#define BROADCAST_PIPE ((uint8_t)2) #define BROADCAST_PIPE ((uint8_t)2)
// Search for a new parent node after this many transmission failures // Search for a new parent node after this many transmission failures
#define SEARCH_FAILURES 2 #define SEARCH_FAILURES 5
struct NodeConfig struct NodeConfig
{ {
@@ -254,7 +254,7 @@ class MySensor : public RF24
void setupRepeaterMode(); 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, const bool allowFindParent = true ); boolean sendWrite(uint8_t dest, MyMessage &message, bool broadcast=false);
private: private:
#ifdef DEBUG #ifdef DEBUG