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.
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
#include <PinChangeInt.h>
|
||||
#include <Gateway.h>
|
||||
#include <stdarg.h>
|
||||
#include <avr/progmem.h>
|
||||
|
||||
#define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled
|
||||
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <henrik.ekblad@gmail.com>
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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 <henrik.ekblad@gmail.com>
|
||||
|
||||
@@ -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 <henrik.ekblad@gmail.com>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 <henrik.ekblad@gmail.com>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <henrik.ekblad@gmail.com>
|
||||
@@ -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();
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
#include <RF24.h>
|
||||
|
||||
#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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user