Skip to content

Commit 01a6adb

Browse files
committed
Merge pull request arduino#34 from mysensors/revert-33-master
Revert "Force parent node search for all transmits when parent node is n...
2 parents b9c4302 + 6314cf8 commit 01a6adb

File tree

2 files changed

+60
-88
lines changed

2 files changed

+60
-88
lines changed

libraries/MySensors/MySensor.cpp

Lines changed: 58 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414
#include "utility/RF24.h"
1515
#include "utility/RF24_config.h"
1616

17-
#define DISTANCE_INVALID (0xFF)
18-
1917

2018
// Inline function and macros
21-
static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) {
19+
inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) {
2220
msg.sender = sender;
2321
msg.destination = destination;
2422
msg.sensor = sensor;
@@ -29,13 +27,6 @@ static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destinat
2927
return msg;
3028
}
3129

32-
static inline bool isValidParent( const uint8_t parent ) {
33-
return parent != AUTO;
34-
}
35-
static inline bool isValidDistance( const uint8_t distance ) {
36-
return distance != DISTANCE_INVALID;
37-
}
38-
3930

4031
MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) {
4132
}
@@ -46,7 +37,6 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
4637
isGateway = false;
4738
repeaterMode = _repeaterMode;
4839
msgCallback = _msgCallback;
49-
failedTransmissions = 0;
5040

5141
if (repeaterMode) {
5242
setupRepeaterMode();
@@ -62,26 +52,29 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
6252
cc.isMetric = 0x01;
6353
}
6454

65-
autoFindParent = _parentNodeId == AUTO;
66-
if (!autoFindParent) {
55+
if (_parentNodeId != AUTO) {
6756
nc.parentNodeId = _parentNodeId;
68-
nc.distance = 0;
69-
} else if (!isValidParent(nc.parentNodeId)) {
70-
// Auto find parent, but parent in eeprom is invalid. Force parent search on first transmit.
71-
nc.distance = DISTANCE_INVALID;
57+
autoFindParent = false;
58+
} else {
59+
autoFindParent = true;
7260
}
7361

7462
if (_nodeId != AUTO) {
7563
// Set static id
7664
nc.nodeId = _nodeId;
7765
}
7866

67+
// If no parent was found in eeprom. Try to find one.
68+
if (autoFindParent && nc.parentNodeId == 0xff) {
69+
findParentNode();
70+
}
71+
7972
// Try to fetch node-id from gateway
8073
if (nc.nodeId == AUTO) {
8174
requestNodeId();
8275
}
8376

84-
debug(PSTR("%s started, id=%d, parent=%d, distance=%d\n"), repeaterMode?"repeater":"sensor", nc.nodeId, nc.parentNodeId, nc.distance);
77+
debug(PSTR("%s started, id %d\n"), repeaterMode?"repeater":"sensor", nc.nodeId);
8578

8679
// Open reading pipe for messages directed to this node (set write pipe to same)
8780
RF24::openReadingPipe(WRITE_PIPE, TO_ADDR(nc.nodeId));
@@ -100,6 +93,8 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
10093
}
10194

10295
void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
96+
failedTransmissions = 0;
97+
10398
// Start up the radio library
10499
RF24::begin();
105100

@@ -109,13 +104,13 @@ void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_
109104
}
110105
RF24::setAutoAck(1);
111106
RF24::setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
107+
RF24::enableAckPayload();
112108
RF24::setChannel(channel);
113109
RF24::setPALevel(paLevel);
114110
RF24::setDataRate(dataRate);
115111
RF24::setRetries(5,15);
116112
RF24::setCRCLength(RF24_CRC_16);
117113
RF24::enableDynamicPayloads();
118-
RF24::enableDynamicAck();// Required to disable ack-sending for broadcast messages
119114

120115
// All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages)
121116
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
@@ -144,12 +139,14 @@ void MySensor::requestNodeId() {
144139

145140

146141
void MySensor::findParentNode() {
147-
// Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to)
148-
debug(PSTR("find parent\n"));
142+
failedTransmissions = 0;
149143

144+
// Set distance to max
145+
nc.distance = 255;
146+
147+
// Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to)
150148
build(msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT, false).set("");
151-
// Write msg, but suppress recursive parent search
152-
sendWrite(BROADCAST_ADDRESS, msg, false);
149+
sendWrite(BROADCAST_ADDRESS, msg, true);
153150

154151
// Wait for ping response.
155152
waitForReply();
@@ -185,64 +182,44 @@ boolean MySensor::sendRoute(MyMessage &message) {
185182
} else if (isInternal && message.type == I_ID_RESPONSE && dest==BROADCAST_ADDRESS) {
186183
// Node has not yet received any id. We need to send it
187184
// by doing a broadcast sending,
188-
return sendWrite(BROADCAST_ADDRESS, message);
185+
return sendWrite(BROADCAST_ADDRESS, message, true);
189186
}
190187
}
191188

192189
if (!isGateway) {
190+
// --- debug(PSTR("route parent\n"));
193191
// Should be routed back to gateway.
194-
return sendWrite(nc.parentNodeId, message);
192+
bool ok = sendWrite(nc.parentNodeId, message);
193+
194+
if (!ok) {
195+
// Failure when sending to parent node. The parent node might be down and we
196+
// need to find another route to gateway.
197+
if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
198+
findParentNode();
199+
}
200+
failedTransmissions++;
201+
} else {
202+
failedTransmissions = 0;
203+
}
204+
return ok;
195205
}
196206
return false;
197207
}
198208

199-
boolean MySensor::sendWrite(uint8_t next, MyMessage &message, const bool allowFindParent) {
200-
bool ok = true;
201-
const bool broadcast = next == BROADCAST_ADDRESS;
202-
const bool toParent = next == nc.parentNodeId;
203-
// With current implementation parent node Id can equal the broadcast address when
204-
// starting with empty eeprom and AUTO node Id is active.
205-
// This behavior is undesired, as possible parents will report back to broadcast address.
206-
// debug(PSTR("sendWrite next=%d, parent=%d, distance=%d\n"), next, nc.parentNodeId, nc.distance);
207-
// If sending directly to parent node and distance is not set, then try to find parent now.
208-
if ( allowFindParent && toParent && !isValidDistance(nc.distance) ) {
209-
findParentNode();
210-
// Known distance indicates parent has been found
211-
ok = isValidDistance(nc.distance);
212-
}
209+
boolean MySensor::sendWrite(uint8_t next, MyMessage &message, bool broadcast) {
210+
uint8_t length = mGetLength(message);
211+
message.last = nc.nodeId;
212+
mSetVersion(message, PROTOCOL_VERSION);
213+
// Make sure radio has powered up
214+
RF24::powerUp();
215+
RF24::stopListening();
216+
RF24::openWritingPipe(TO_ADDR(next));
217+
bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast);
218+
RF24::startListening();
219+
220+
debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,st=%s:%s\n"),
221+
message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type, mGetPayloadType(message), mGetLength(message), ok?"ok":"fail", message.getString(convBuf));
213222

214-
if (ok) {
215-
uint8_t length = mGetLength(message);
216-
message.last = nc.nodeId;
217-
mSetVersion(message, PROTOCOL_VERSION);
218-
// Make sure radio has powered up
219-
RF24::powerUp();
220-
RF24::stopListening();
221-
RF24::openWritingPipe(TO_ADDR(next));
222-
// Send message. Disable auto-ack for broadcasts.
223-
ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast);
224-
RF24::startListening();
225-
226-
debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,st=%s:%s\n"),
227-
message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type,
228-
mGetPayloadType(message), mGetLength(message), broadcast ? "bc" : (ok ? "ok":"fail"), message.getString(convBuf));
229-
230-
// If many successive transmissions to parent failed, the parent node might be down and we
231-
// need to find another route to gateway.
232-
if (toParent) {
233-
if (ok) {
234-
failedTransmissions = 0;
235-
} else {
236-
failedTransmissions++;
237-
if ( autoFindParent && (failedTransmissions >= SEARCH_FAILURES)) {
238-
debug(PSTR("lost parent\n"));
239-
// Set distance invalid to trigger parent search on next write.
240-
nc.distance = DISTANCE_INVALID;
241-
failedTransmissions = 0;
242-
}
243-
}
244-
}
245-
}
246223
return ok;
247224
}
248225

@@ -290,7 +267,7 @@ boolean MySensor::process() {
290267

291268
uint8_t len = RF24::getDynamicPayloadSize();
292269
RF24::read(&msg, len);
293-
// RF24::writeAckPayload(pipe,&pipe, 1 );
270+
RF24::writeAckPayload(pipe,&pipe, 1 );
294271

295272
// Add string termination, good if we later would want to print it.
296273
msg.data[mGetLength(msg)] = '\0';
@@ -310,10 +287,10 @@ boolean MySensor::process() {
310287

311288
if (repeaterMode && command == C_INTERNAL && type == I_FIND_PARENT) {
312289
// Relaying nodes should always answer ping messages
313-
// Wait a random delay of 0-1.023 seconds to minimize collision
290+
// Wait a random delay of 0-2 seconds to minimize collision
314291
// between ping ack messages from other relaying nodes
315292
delay(millis() & 0x3ff);
316-
sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(nc.distance));
293+
sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(nc.distance), true);
317294
return false;
318295
} else if (destination == nc.nodeId) {
319296
// Check if sender requests an ack back.
@@ -338,18 +315,13 @@ boolean MySensor::process() {
338315
// We've received a reply to a FIND_PARENT message. Check if the distance is
339316
// shorter than we already have.
340317
uint8_t distance = msg.getByte();
341-
if (isValidDistance(distance))
342-
{
343-
// Distance to gateway is one more for us w.r.t. parent
344-
distance++;
345-
if (isValidDistance(distance) && (distance < nc.distance)) {
346-
// Found a neighbor closer to GW than previously found
347-
nc.distance = distance;
348-
nc.parentNodeId = msg.sender;
349-
eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
350-
eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
351-
debug(PSTR("new parent=%d, d=%d\n"), nc.parentNodeId, nc.distance);
352-
}
318+
if (distance<nc.distance-1) {
319+
// Found a neighbor closer to GW than previously found
320+
nc.distance = distance + 1;
321+
nc.parentNodeId = msg.sender;
322+
eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
323+
eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
324+
debug(PSTR("new parent=%d, d=%d\n"), nc.parentNodeId, nc.distance);
353325
}
354326
return false;
355327
} else if (sender == GATEWAY_ADDRESS) {

libraries/MySensors/MySensor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
#define BROADCAST_PIPE ((uint8_t)2)
6767

6868
// Search for a new parent node after this many transmission failures
69-
#define SEARCH_FAILURES 2
69+
#define SEARCH_FAILURES 5
7070

7171
struct NodeConfig
7272
{
@@ -254,7 +254,7 @@ class MySensor : public RF24
254254
void setupRepeaterMode();
255255
void setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate);
256256
boolean sendRoute(MyMessage &message);
257-
boolean sendWrite(uint8_t dest, MyMessage &message, const bool allowFindParent = true );
257+
boolean sendWrite(uint8_t dest, MyMessage &message, bool broadcast=false);
258258

259259
private:
260260
#ifdef DEBUG

0 commit comments

Comments
 (0)