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 <PinChangeInt.h>
|
||||||
#include <Gateway.h>
|
#include <Gateway.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <avr/progmem.h>
|
|
||||||
|
|
||||||
#define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled
|
#define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled
|
||||||
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
|
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
* Configure Sensor Network
|
* Configure Sensor Network
|
||||||
*/
|
*/
|
||||||
#define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127
|
#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_DATARATE RF24_1MBPS //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 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_LEVEL //Gateway PA Level, defaults to Sensor net PA Level. Tune here if using an amplified nRF2401+ in your gateway.
|
#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
|
* 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.
|
It handles radio network routing, relaying and ids.
|
||||||
|
|
||||||
Created by Henrik Ekblad <henrik.ekblad@gmail.com>
|
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
|
// Start up the radio library
|
||||||
setupRadio(paLevel, channel, dataRate);
|
setupRadio(paLevel, channel, dataRate);
|
||||||
|
RF24::openReadingPipe(WRITE_PIPE, BASE_RADIO_ID);
|
||||||
RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID);
|
RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID);
|
||||||
RF24::startListening();
|
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.
|
It handles radio network routing, relaying and ids.
|
||||||
|
|
||||||
Created by Henrik Ekblad <henrik.ekblad@gmail.com>
|
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.
|
It handles radio network routing, relaying and ids.
|
||||||
|
|
||||||
Created by Henrik Ekblad <henrik.ekblad@gmail.com>
|
Created by Henrik Ekblad <henrik.ekblad@gmail.com>
|
||||||
@@ -86,8 +86,20 @@ boolean Relay::messageAvailable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (available && pipe<7) {
|
if (available && pipe<7) {
|
||||||
uint8_t len = RF24::getDynamicPayloadSize()-sizeof(msg.header);
|
uint8_t len = RF24::getDynamicPayloadSize();
|
||||||
boolean ok = readMessage();
|
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 (ok) {
|
||||||
if (msg.header.messageType == M_INTERNAL &&
|
if (msg.header.messageType == M_INTERNAL &&
|
||||||
msg.header.type == I_PING) {
|
msg.header.type == I_PING) {
|
||||||
@@ -130,11 +142,14 @@ boolean Relay::messageAvailable() {
|
|||||||
} else {
|
} else {
|
||||||
// If this is variable message from sensor net gateway. Send ack back.
|
// If this is variable message from sensor net gateway. Send ack back.
|
||||||
debug(PSTR("Message addressed for this node.\n"));
|
debug(PSTR("Message addressed for this node.\n"));
|
||||||
if (msg.header.from == GATEWAY_ADDRESS &&
|
|
||||||
msg.header.messageType == M_SET_VARIABLE) {
|
// Send set-message back to sender if sender wants this
|
||||||
// Send back ack message to sensor net gateway
|
if (msg.header.messageType == M_SET_WITH_ACK) {
|
||||||
sendVariableAck();
|
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 message to waiting sketch...
|
||||||
if (msg.header.last != GATEWAY_ADDRESS)
|
if (msg.header.last != GATEWAY_ADDRESS)
|
||||||
addChildRoute(msg.header.from, msg.header.last);
|
addChildRoute(msg.header.from, msg.header.last);
|
||||||
@@ -143,7 +158,7 @@ boolean Relay::messageAvailable() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We should probably try to relay this message
|
// 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() {
|
void Relay::sendChildren() {
|
||||||
// Send in which children that is using this node as an relay.
|
// Send in which children that is using this node as an relay.
|
||||||
// TODO: Fix this
|
// 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]);
|
// Serial.println(childNodeTable[i]);
|
||||||
debug(PSTR("rt:%d, %d\n"), i, getChildRoute(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.
|
It handles radio network routing, relaying and ids.
|
||||||
|
|
||||||
Created by Henrik Ekblad <henrik.ekblad@gmail.com>
|
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
|
// Start up the radio library
|
||||||
RF24::begin();
|
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::setChannel(channel);
|
||||||
RF24::setPALevel(paLevel);
|
RF24::setPALevel(paLevel);
|
||||||
RF24::setDataRate(dataRate);
|
RF24::setDataRate(dataRate);
|
||||||
RF24::setAutoAck(true);
|
RF24::setRetries(5,15);
|
||||||
RF24::setRetries(2,15);
|
|
||||||
RF24::setCRCLength(RF24_CRC_16);
|
RF24::setCRCLength(RF24_CRC_16);
|
||||||
RF24::enableDynamicPayloads();
|
RF24::enableDynamicPayloads();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// All repeater nodes and gateway listen to broadcast pipe (for PING messages)
|
// All repeater nodes and gateway listen to broadcast pipe (for PING messages)
|
||||||
if (isRelay) {
|
if (isRelay) {
|
||||||
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
|
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");
|
debug(PSTR("Started %s.\n"), isRelay?"relay":"sensor");
|
||||||
|
|
||||||
|
|
||||||
setupRadio(paLevel, channel, dataRate);
|
setupRadio(paLevel, channel, dataRate);
|
||||||
|
|
||||||
// Fetch relay from EEPROM
|
// Fetch relay from EEPROM
|
||||||
@@ -58,7 +66,8 @@ void Sensor::begin(uint8_t _radioId, rf24_pa_dbm_e paLevel, uint8_t channel, rf2
|
|||||||
|
|
||||||
initializeRadioId();
|
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));
|
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(radioId));
|
||||||
|
|
||||||
// Send presentation for this radio node
|
// 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);
|
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;
|
bool broadcast = message.header.messageType == M_INTERNAL && message.header.type == I_PING;
|
||||||
|
|
||||||
RF24::stopListening();
|
RF24::stopListening();
|
||||||
RF24::openWritingPipe(TO_ADDR(dest));
|
RF24::openWritingPipe(TO_ADDR(dest));
|
||||||
bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, sizeof(message.header) + length), broadcast);
|
bool ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, sizeof(message.header) + length), broadcast);
|
||||||
RF24::startListening();
|
RF24::startListening();
|
||||||
|
|
||||||
|
|
||||||
|
//RF24::closeReadingPipe(WRITE_PIPE); // Stop listening to write-pipe after transmit
|
||||||
|
//delay(50);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
debug(PSTR("Sent successfully\n"));
|
debug(PSTR("Sent successfully\n"));
|
||||||
else
|
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) {
|
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) {
|
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() {
|
boolean Sensor::messageAvailable() {
|
||||||
uint8_t pipe;
|
uint8_t pipe;
|
||||||
boolean available = RF24::available(&pipe);
|
boolean available = RF24::available(&pipe);
|
||||||
|
if (available && pipe<7) {
|
||||||
|
|
||||||
|
uint8_t len = RF24::getDynamicPayloadSize();
|
||||||
|
RF24::read(&msg, len);
|
||||||
|
RF24::writeAckPayload(pipe,&pipe, 1 );
|
||||||
|
|
||||||
if (available) {
|
if (available) {
|
||||||
debug(PSTR("Message available on pipe %d\n"),pipe);
|
debug(PSTR("Message available on pipe %d\n"),pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t valid = validate(len-sizeof(header_s));
|
||||||
|
boolean ok = valid == VALIDATE_OK;
|
||||||
|
|
||||||
if (available && pipe<7) {
|
// Make sure string gets terminated ok for full sized messages.
|
||||||
boolean ok = readMessage();
|
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) {
|
if (ok && msg.header.to == radioId) {
|
||||||
// This message is addressed to this node
|
// This message is addressed to this node
|
||||||
debug(PSTR("Message addressed for this node.\n"));
|
debug(PSTR("Message addressed for this node.\n"));
|
||||||
if (msg.header.from == GATEWAY_ADDRESS &&
|
// Send set-message back to sender if sender wants this
|
||||||
// If this is variable message from sensor net gateway. Send ack back.
|
if (msg.header.messageType == M_SET_WITH_ACK) {
|
||||||
msg.header.messageType == M_SET_VARIABLE) {
|
|
||||||
// Send back ack message to sensor net gateway
|
|
||||||
sendVariableAck();
|
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 message to waiting sketch...
|
||||||
return true;
|
return true;
|
||||||
@@ -423,7 +448,7 @@ message_s Sensor::getMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean Sensor::readMessage() {
|
/*boolean Sensor::readMessage() {
|
||||||
uint8_t len = RF24::getDynamicPayloadSize();
|
uint8_t len = RF24::getDynamicPayloadSize();
|
||||||
RF24::read(&msg, len);
|
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"),
|
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);
|
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;
|
return ok;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* calculate CRC8 on message_s data taking care of data structure and protocol version
|
* 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.
|
It handles radio network routing, relaying and ids.
|
||||||
|
|
||||||
Created by Henrik Ekblad <henrik.ekblad@gmail.com>
|
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 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
|
// 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 GATEWAY_ADDRESS ((uint8_t)0)
|
||||||
#define BROADCAST_ADDRESS ((uint8_t)0xFF)
|
#define BROADCAST_ADDRESS ((uint8_t)0xFF)
|
||||||
#define TO_ADDR(x) (BASE_RADIO_ID + x)
|
#define TO_ADDR(x) (BASE_RADIO_ID + x)
|
||||||
@@ -61,7 +61,7 @@ typedef enum {
|
|||||||
M_PRESENTATION = 0,
|
M_PRESENTATION = 0,
|
||||||
M_SET_VARIABLE = 1,
|
M_SET_VARIABLE = 1,
|
||||||
M_REQ_VARIABLE = 2,
|
M_REQ_VARIABLE = 2,
|
||||||
M_ACK_VARIABLE = 3,
|
M_SET_WITH_ACK = 3,
|
||||||
M_INTERNAL = 4
|
M_INTERNAL = 4
|
||||||
} messageType;
|
} messageType;
|
||||||
|
|
||||||
@@ -278,7 +278,7 @@ class Sensor : public RF24
|
|||||||
void findRelay();
|
void findRelay();
|
||||||
boolean send(message_s message, int length);
|
boolean send(message_s message, int length);
|
||||||
boolean sendWrite(uint8_t dest, 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 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);
|
void sendInternal(uint8_t variableType, const char *value);
|
||||||
boolean sendVariableAck();
|
boolean sendVariableAck();
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
#include <RF24.h>
|
#include <RF24.h>
|
||||||
|
|
||||||
#define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
|
#define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
|
||||||
#define NUMBER_OF_RELAYS 1
|
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
|
||||||
#define RELAY_ON 0
|
#define RELAY_ON 1 // GPIO value to write to turn on attached relay
|
||||||
#define RELAY_OFF 1
|
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
|
||||||
|
|
||||||
Sensor gw;
|
Relay gw;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user