Skip to content

Commit 960efcd

Browse files
committed
Prepared for ack:ing between sensors. And between actuator and gateway. Now using hardware ack when sending messages and burst-mode which gives much more reliable communication.
Use the corresponing development-branch for Vera plugin files.
1 parent 4021811 commit 960efcd

File tree

9 files changed

+81
-41
lines changed

9 files changed

+81
-41
lines changed

SerialGateway/SerialGateway.ino

-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include <PinChangeInt.h>
2929
#include <Gateway.h>
3030
#include <stdarg.h>
31-
#include <avr/progmem.h>
3231

3332
#define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled
3433
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button

libraries/MySensors/Config.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
* Configure Sensor Network
66
*/
77
#define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127
8-
#define RF24_DATARATE RF24_250KBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
9-
#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
10-
#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.
8+
#define RF24_DATARATE RF24_1MBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
9+
#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
10+
#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.
1111

1212
/***
1313
* Enable/Disable debug logging

libraries/MySensors/Gateway.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
The MySensors Arduino library adds a new layer on top of the RF24 library.
2+
The MySensors library adds a new layer on top of the RF24 library.
33
It handles radio network routing, relaying and ids.
44
55
Created by Henrik Ekblad <[email protected]>
@@ -67,6 +67,7 @@ void Gateway::begin(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e data
6767

6868
// Start up the radio library
6969
setupRadio(paLevel, channel, dataRate);
70+
RF24::openReadingPipe(WRITE_PIPE, BASE_RADIO_ID);
7071
RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID);
7172
RF24::startListening();
7273

libraries/MySensors/Gateway.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
The MySensors Arduino library adds a new layer on top of the RF24 library.
2+
The MySensors library adds a new layer on top of the RF24 library.
33
It handles radio network routing, relaying and ids.
44
55
Created by Henrik Ekblad <[email protected]>

libraries/MySensors/Relay.cpp

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
The MySensors Arduino library adds a new layer on top of the RF24 library.
2+
The MySensors library adds a new layer on top of the RF24 library.
33
It handles radio network routing, relaying and ids.
44
55
Created by Henrik Ekblad <[email protected]>
@@ -86,8 +86,20 @@ boolean Relay::messageAvailable() {
8686
}
8787

8888
if (available && pipe<7) {
89-
uint8_t len = RF24::getDynamicPayloadSize()-sizeof(msg.header);
90-
boolean ok = readMessage();
89+
uint8_t len = RF24::getDynamicPayloadSize();
90+
RF24::read(&msg, len);
91+
RF24::writeAckPayload(pipe,&pipe, 1 );
92+
93+
uint8_t valid = validate(len-sizeof(header_s));
94+
boolean ok = valid == VALIDATE_OK;
95+
96+
// Make sure string gets terminated ok for full sized messages.
97+
msg.data[len - sizeof(header_s) ] = '\0';
98+
debug(PSTR("Rx: fr=%d,to=%d,la=%d,ci=%d,mt=%d,t=%d,cr=%d(%s): %s\n"),
99+
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);
100+
101+
102+
//boolean ok = readMessage();
91103
if (ok) {
92104
if (msg.header.messageType == M_INTERNAL &&
93105
msg.header.type == I_PING) {
@@ -130,11 +142,14 @@ boolean Relay::messageAvailable() {
130142
} else {
131143
// If this is variable message from sensor net gateway. Send ack back.
132144
debug(PSTR("Message addressed for this node.\n"));
133-
if (msg.header.from == GATEWAY_ADDRESS &&
134-
msg.header.messageType == M_SET_VARIABLE) {
135-
// Send back ack message to sensor net gateway
145+
146+
// Send set-message back to sender if sender wants this
147+
if (msg.header.messageType == M_SET_WITH_ACK) {
136148
sendVariableAck();
149+
// The library user should not need to care about this ack request. Just treat it as a normal SET.
150+
msg.header.messageType = M_SET_VARIABLE;
137151
}
152+
138153
// Return message to waiting sketch...
139154
if (msg.header.last != GATEWAY_ADDRESS)
140155
addChildRoute(msg.header.from, msg.header.last);
@@ -143,7 +158,7 @@ boolean Relay::messageAvailable() {
143158
}
144159
} else {
145160
// We should probably try to relay this message
146-
relayMessage(len, pipe);
161+
relayMessage(len-sizeof(msg.header), pipe);
147162
}
148163
}
149164
}
@@ -243,14 +258,14 @@ void Relay::clearChildRoutes() {
243258
void Relay::sendChildren() {
244259
// Send in which children that is using this node as an relay.
245260
// TODO: Fix this
246-
debug(PSTR("Send child info to sensor gateway.\n"));
261+
debug(PSTR("Dump beginning of routing table\n"));
247262

248-
for (int i=0;i< 10; i++) {
263+
for (int i=0;i< 50; i++) {
249264
// Serial.println(childNodeTable[i]);
250265
debug(PSTR("rt:%d, %d\n"), i, getChildRoute(i) );
251266
}
252267

253-
//sendInternal(I_CHILDREN, "not implemented");
268+
sendInternal(I_CHILDREN, "not implemented");
254269
}
255270

256271

libraries/MySensors/Relay.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
The MySensors Arduino library adds a new layer on top of the RF24 library.
2+
The MySensors library adds a new layer on top of the RF24 library.
33
It handles radio network routing, relaying and ids.
44
55
Created by Henrik Ekblad <[email protected]>

libraries/MySensors/Sensor.cpp

+41-16
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,22 @@ void Sensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e
2222

2323
// Start up the radio library
2424
RF24::begin();
25+
RF24::setAutoAck(1);
26+
RF24::enableAckPayload();
27+
if (!RF24::isPVariant()) {
28+
debug(PSTR("Sorry, you'll need to use the P version of NRF24L01.\n"));
29+
while(1);
30+
}
31+
2532
RF24::setChannel(channel);
2633
RF24::setPALevel(paLevel);
2734
RF24::setDataRate(dataRate);
28-
RF24::setAutoAck(true);
29-
RF24::setRetries(2,15);
35+
RF24::setRetries(5,15);
3036
RF24::setCRCLength(RF24_CRC_16);
3137
RF24::enableDynamicPayloads();
3238

3339

40+
3441
// All repeater nodes and gateway listen to broadcast pipe (for PING messages)
3542
if (isRelay) {
3643
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
4451

4552
debug(PSTR("Started %s.\n"), isRelay?"relay":"sensor");
4653

54+
4755
setupRadio(paLevel, channel, dataRate);
4856

4957
// Fetch relay from EEPROM
@@ -58,7 +66,8 @@ void Sensor::begin(uint8_t _radioId, rf24_pa_dbm_e paLevel, uint8_t channel, rf2
5866

5967
initializeRadioId();
6068

61-
// Open reading pipe for messages directed to this node
69+
// Open reading pipe for messages directed to this node (set write pipe to same)
70+
RF24::openReadingPipe(WRITE_PIPE, TO_ADDR(radioId));
6271
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(radioId));
6372

6473
// Send presentation for this radio node
@@ -224,11 +233,16 @@ boolean Sensor::sendWrite(uint8_t dest, message_s message, int length) {
224233
message.header.from,message.header.to, message.header.last, dest, message.header.childId, message.header.messageType, message.header.type, message.header.crc, message.data);
225234

226235
bool broadcast = message.header.messageType == M_INTERNAL && message.header.type == I_PING;
236+
227237
RF24::stopListening();
228238
RF24::openWritingPipe(TO_ADDR(dest));
229239
bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, sizeof(message.header) + length), broadcast);
230240
RF24::startListening();
231241

242+
243+
//RF24::closeReadingPipe(WRITE_PIPE); // Stop listening to write-pipe after transmit
244+
//delay(50);
245+
232246
if (ok)
233247
debug(PSTR("Sent successfully\n"));
234248
else
@@ -351,11 +365,11 @@ char* Sensor::get(uint8_t nodeId, uint8_t childId, uint8_t sendType, uint8_t rec
351365
}
352366

353367
char* Sensor::getStatus(uint8_t childId, uint8_t variableType) {
354-
return get(GATEWAY_ADDRESS, childId, M_REQ_VARIABLE, M_ACK_VARIABLE, variableType);
368+
return get(GATEWAY_ADDRESS, childId, M_REQ_VARIABLE, M_SET_VARIABLE, variableType);
355369
}
356370

357371
char * Sensor::getStatus(uint8_t nodeId, int8_t childId, uint8_t variableType) {
358-
return get(nodeId, childId, M_REQ_VARIABLE, M_ACK_VARIABLE, variableType);
372+
return get(nodeId, childId, M_REQ_VARIABLE, M_SET_VARIABLE, variableType);
359373
}
360374

361375

@@ -385,22 +399,33 @@ void Sensor::requestIsMetricSystem() {
385399
boolean Sensor::messageAvailable() {
386400
uint8_t pipe;
387401
boolean available = RF24::available(&pipe);
402+
if (available && pipe<7) {
388403

389-
if (available) {
390-
debug(PSTR("Message available on pipe %d\n"),pipe);
391-
}
404+
uint8_t len = RF24::getDynamicPayloadSize();
405+
RF24::read(&msg, len);
406+
RF24::writeAckPayload(pipe,&pipe, 1 );
407+
408+
if (available) {
409+
debug(PSTR("Message available on pipe %d\n"),pipe);
410+
}
392411

412+
uint8_t valid = validate(len-sizeof(header_s));
413+
boolean ok = valid == VALIDATE_OK;
393414

394-
if (available && pipe<7) {
395-
boolean ok = readMessage();
415+
// Make sure string gets terminated ok for full sized messages.
416+
msg.data[len - sizeof(header_s) ] = '\0';
417+
debug(PSTR("Rx: fr=%d,to=%d,la=%d,ci=%d,mt=%d,t=%d,cr=%d(%s): %s\n"),
418+
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);
419+
420+
// boolean ok = readMessage();
396421
if (ok && msg.header.to == radioId) {
397422
// This message is addressed to this node
398423
debug(PSTR("Message addressed for this node.\n"));
399-
if (msg.header.from == GATEWAY_ADDRESS &&
400-
// If this is variable message from sensor net gateway. Send ack back.
401-
msg.header.messageType == M_SET_VARIABLE) {
402-
// Send back ack message to sensor net gateway
424+
// Send set-message back to sender if sender wants this
425+
if (msg.header.messageType == M_SET_WITH_ACK) {
403426
sendVariableAck();
427+
// The library user should not need to care about this ack request. Just treat it as a normal SET.
428+
msg.header.messageType = M_SET_VARIABLE;
404429
}
405430
// Return message to waiting sketch...
406431
return true;
@@ -423,7 +448,7 @@ message_s Sensor::getMessage() {
423448
}
424449

425450

426-
boolean Sensor::readMessage() {
451+
/*boolean Sensor::readMessage() {
427452
uint8_t len = RF24::getDynamicPayloadSize();
428453
RF24::read(&msg, len);
429454
@@ -435,7 +460,7 @@ boolean Sensor::readMessage() {
435460
debug(PSTR("Rx: fr=%d,to=%d,la=%d,ci=%d,mt=%d,t=%d,cr=%d(%s): %s\n"),
436461
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);
437462
return ok;
438-
}
463+
}*/
439464

440465
/*
441466
* calculate CRC8 on message_s data taking care of data structure and protocol version

libraries/MySensors/Sensor.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
The Sensor Net Arduino library adds a new layer on top of the RF24 library.
2+
The MySensors library adds a new layer on top of the RF24 library.
33
It handles radio network routing, relaying and ids.
44
55
Created by Henrik Ekblad <[email protected]>
@@ -41,7 +41,7 @@
4141

4242
// This is the radioId for sensor net gateway receiver sketch (where all sensors should send their data).
4343
// This is also act as base value for sensor radioId
44-
#define BASE_RADIO_ID ((uint64_t)0xABCDABC000LL)
44+
#define BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL)
4545
#define GATEWAY_ADDRESS ((uint8_t)0)
4646
#define BROADCAST_ADDRESS ((uint8_t)0xFF)
4747
#define TO_ADDR(x) (BASE_RADIO_ID + x)
@@ -61,7 +61,7 @@ typedef enum {
6161
M_PRESENTATION = 0,
6262
M_SET_VARIABLE = 1,
6363
M_REQ_VARIABLE = 2,
64-
M_ACK_VARIABLE = 3,
64+
M_SET_WITH_ACK = 3,
6565
M_INTERNAL = 4
6666
} messageType;
6767

@@ -278,7 +278,7 @@ class Sensor : public RF24
278278
void findRelay();
279279
boolean send(message_s message, int length);
280280
boolean sendWrite(uint8_t dest, message_s message, int length);
281-
boolean readMessage();
281+
//boolean readMessage();
282282
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);
283283
void sendInternal(uint8_t variableType, const char *value);
284284
boolean sendVariableAck();

libraries/MySensors/examples/RelayActuator/RelayActuator.ino

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
#include <RF24.h>
77

88
#define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
9-
#define NUMBER_OF_RELAYS 1
10-
#define RELAY_ON 0
11-
#define RELAY_OFF 1
9+
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
10+
#define RELAY_ON 1 // GPIO value to write to turn on attached relay
11+
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
1212

13-
Sensor gw;
13+
Relay gw;
1414

1515
void setup()
1616
{

0 commit comments

Comments
 (0)