latest test sketches and working request for id
This commit is contained in:
@@ -54,7 +54,6 @@
|
|||||||
#include <PinChangeInt.h>
|
#include <PinChangeInt.h>
|
||||||
#include <MyGateway.h>
|
#include <MyGateway.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
//#include <avr/progmem.h>
|
|
||||||
|
|
||||||
#include <UIPEthernet.h> // Use this if you have attached a Ethernet ENC28J60 shields
|
#include <UIPEthernet.h> // Use this if you have attached a Ethernet ENC28J60 shields
|
||||||
//#include <Ethernet.h> // Use this fo WizNET module and Arduino Ethernet Shield
|
//#include <Ethernet.h> // Use this fo WizNET module and Arduino Ethernet Shield
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ MyMessage::MyMessage() {
|
|||||||
destination = 0; // Gateway is default destination
|
destination = 0; // Gateway is default destination
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MyMessage::MyMessage(uint8_t _sensor, uint8_t _type) {
|
||||||
|
destination = 0; // Gateway is default destination
|
||||||
|
sensor = _sensor;
|
||||||
|
type = _type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getters for payload converted to desired form */
|
/* Getters for payload converted to desired form */
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ typedef enum {
|
|||||||
|
|
||||||
// Type of internal messages (for internal messages)
|
// Type of internal messages (for internal messages)
|
||||||
typedef enum {
|
typedef enum {
|
||||||
I_BATTERY_LEVEL, I_TIME, I_VERSION, I_REQUEST_ID,
|
I_BATTERY_LEVEL, I_TIME, I_VERSION, I_ID_REQUEST, I_ID_RESPONSE,
|
||||||
I_INCLUSION_MODE, I_CONFIG, I_PING, I_PING_ACK,
|
I_INCLUSION_MODE, I_CONFIG, I_PING, I_PING_ACK,
|
||||||
I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION
|
I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION
|
||||||
} internal;
|
} internal;
|
||||||
@@ -114,6 +114,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
MyMessage();
|
MyMessage();
|
||||||
|
|
||||||
|
MyMessage(uint8_t sensor, uint8_t type);
|
||||||
|
|
||||||
char* getString();
|
char* getString();
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,37 +25,8 @@ inline MyMessage* build (MyMessage* msg, uint8_t sender, uint8_t destination, ui
|
|||||||
MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) {
|
MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
|
|
||||||
failedTransmissions = 0;
|
|
||||||
|
|
||||||
// Start up the radio library
|
void MySensor::begin(void (*_msgCallback)(MyMessage), uint8_t _nodeId, boolean _relayMode, rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
|
||||||
RF24::begin();
|
|
||||||
|
|
||||||
if (!RF24::isPVariant()) {
|
|
||||||
debug(PSTR("check wires\n"));
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
RF24::setAutoAck(1);
|
|
||||||
RF24::enableAckPayload();
|
|
||||||
RF24::setChannel(channel);
|
|
||||||
RF24::setPALevel(paLevel);
|
|
||||||
RF24::setDataRate(dataRate);
|
|
||||||
RF24::setRetries(5,15);
|
|
||||||
RF24::setCRCLength(RF24_CRC_16);
|
|
||||||
RF24::enableDynamicPayloads();
|
|
||||||
|
|
||||||
// All repeater nodes and gateway listen to broadcast pipe (for PING messages)
|
|
||||||
if (relayMode) {
|
|
||||||
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MySensor::setupRelayMode(){
|
|
||||||
childNodeTable = new uint8_t[256];
|
|
||||||
eeprom_read_block((void*)childNodeTable, (void*)EEPROM_ROUTES_ADDRESS, 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MySensor::begin(void (*_msgCallback)(MyMessage), boolean _relayMode, uint8_t _nodeId, rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
|
|
||||||
Serial.begin(BAUD_RATE);
|
Serial.begin(BAUD_RATE);
|
||||||
relayMode = _relayMode;
|
relayMode = _relayMode;
|
||||||
msgCallback = _msgCallback;
|
msgCallback = _msgCallback;
|
||||||
@@ -86,7 +57,7 @@ void MySensor::begin(void (*_msgCallback)(MyMessage), boolean _relayMode, uint8_
|
|||||||
requestNodeId();
|
requestNodeId();
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(PSTR("%s started\n"), relayMode?"relay":"sensor");
|
debug(PSTR("%s started, id %d\n"), relayMode?"relay":"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));
|
||||||
@@ -99,8 +70,38 @@ void MySensor::begin(void (*_msgCallback)(MyMessage), boolean _relayMode, uint8_
|
|||||||
// Node sends parent node. Controller answers with latest node configuration
|
// Node sends parent node. Controller answers with latest node configuration
|
||||||
// which is picked up in process()
|
// which is picked up in process()
|
||||||
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CONFIG)->set(nc.parentNodeId));
|
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CONFIG)->set(nc.parentNodeId));
|
||||||
Serial.print("XX");
|
|
||||||
Serial.println(nc.parentNodeId);
|
// Wait configuration reply.
|
||||||
|
waitForReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
|
||||||
|
failedTransmissions = 0;
|
||||||
|
|
||||||
|
// Start up the radio library
|
||||||
|
RF24::begin();
|
||||||
|
|
||||||
|
if (!RF24::isPVariant()) {
|
||||||
|
debug(PSTR("check wires\n"));
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
RF24::setAutoAck(1);
|
||||||
|
RF24::setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
|
||||||
|
RF24::enableAckPayload();
|
||||||
|
RF24::setChannel(channel);
|
||||||
|
RF24::setPALevel(paLevel);
|
||||||
|
RF24::setDataRate(dataRate);
|
||||||
|
RF24::setRetries(5,15);
|
||||||
|
RF24::setCRCLength(RF24_CRC_16);
|
||||||
|
RF24::enableDynamicPayloads();
|
||||||
|
|
||||||
|
// All nodes listen to broadcast pipe (for PING-ACK messages)
|
||||||
|
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySensor::setupRelayMode(){
|
||||||
|
childNodeTable = new uint8_t[256];
|
||||||
|
eeprom_read_block((void*)childNodeTable, (void*)EEPROM_ROUTES_ADDRESS, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +116,8 @@ ControllerConfig MySensor::getConfig() {
|
|||||||
void MySensor::requestNodeId() {
|
void MySensor::requestNodeId() {
|
||||||
debug(PSTR("req node id\n"));
|
debug(PSTR("req node id\n"));
|
||||||
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
|
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
|
||||||
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_REQUEST_ID));
|
sendRoute(build(&msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_ID_REQUEST)->set(""));
|
||||||
|
waitForReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -125,31 +127,33 @@ void MySensor::findParentNode() {
|
|||||||
|
|
||||||
failedTransmissions = 0;
|
failedTransmissions = 0;
|
||||||
|
|
||||||
// Open a reading pipe for current nodeId (if it differs from broadcast)
|
|
||||||
if (nc.nodeId != BROADCAST_PIPE) {
|
|
||||||
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
|
|
||||||
}
|
|
||||||
// Set distance to max
|
// Set distance to max
|
||||||
nc.distance = 255;
|
nc.distance = 255;
|
||||||
|
|
||||||
// Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to)
|
// 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_PING);
|
build(&msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_PING)->set("");
|
||||||
sendWrite(BROADCAST_ADDRESS, &msg, true);
|
sendWrite(BROADCAST_ADDRESS, &msg, true);
|
||||||
|
|
||||||
|
// Wait for ping response.
|
||||||
|
waitForReply();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MySensor::waitForReply() {
|
||||||
unsigned long enter = millis();
|
unsigned long enter = millis();
|
||||||
// Wait for ack responses slightly more than 1 second
|
// Wait a couple of seconds for response
|
||||||
while (millis() - enter < 1200) {
|
while (millis() - enter < 2000) {
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean MySensor::sendRoute(MyMessage *message) {
|
boolean MySensor::sendRoute(MyMessage *message) {
|
||||||
// Make sure to process any incoming messages before sending (could this end up in recursive loop?)
|
// Make sure to process any incoming messages before sending (could this end up in recursive loop?)
|
||||||
// process();
|
// process();
|
||||||
|
bool requestId = (mGetCommandP(message) == C_INTERNAL && message->type == I_ID_REQUEST);
|
||||||
|
bool responseId = (mGetCommandP(message) == C_INTERNAL && message->type == I_ID_RESPONSE);
|
||||||
|
|
||||||
// If we still don't have any node id, re-request and skip this message.
|
// If we still don't have any node id, re-request and skip this message.
|
||||||
if (nc.nodeId == AUTO && !(mGetCommandP(message) == C_INTERNAL && message->type == I_REQUEST_ID)) {
|
if (nc.nodeId == AUTO && !requestId) {
|
||||||
requestNodeId();
|
requestNodeId();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -157,16 +161,20 @@ boolean MySensor::sendRoute(MyMessage *message) {
|
|||||||
if (relayMode) {
|
if (relayMode) {
|
||||||
uint8_t dest = message->destination;
|
uint8_t dest = message->destination;
|
||||||
uint8_t route = getChildRoute(dest);
|
uint8_t route = getChildRoute(dest);
|
||||||
if (route>0 && route<255 && dest != GATEWAY_ADDRESS) {
|
if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) {
|
||||||
debug(PSTR("route %d.\n"), route);
|
// --- debug(PSTR("route %d.\n"), route);
|
||||||
// Message destination is not gateway and is in routing table for this node.
|
// Message destination is not gateway and is in routing table for this node.
|
||||||
// Send it downstream
|
// Send it downstream
|
||||||
return sendWrite(route, message);
|
return sendWrite(route, message);
|
||||||
|
} else if (responseId && dest==BROADCAST_ADDRESS) {
|
||||||
|
// Node has not yet received any id. We need to send it
|
||||||
|
// by doing a broadcast sending,
|
||||||
|
return sendWrite(BROADCAST_ADDRESS, message, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nc.nodeId != GATEWAY_ADDRESS) {
|
if (nc.nodeId != GATEWAY_ADDRESS) {
|
||||||
debug(PSTR("route parent\n"));
|
// --- debug(PSTR("route parent\n"));
|
||||||
// Should be routed back to gateway.
|
// Should be routed back to gateway.
|
||||||
bool ok = sendWrite(nc.parentNodeId, message);
|
bool ok = sendWrite(nc.parentNodeId, message);
|
||||||
|
|
||||||
@@ -190,7 +198,6 @@ boolean MySensor::sendWrite(uint8_t next, MyMessage *message, bool broadcast) {
|
|||||||
message->last = nc.nodeId;
|
message->last = nc.nodeId;
|
||||||
mSetVersionP(message, PROTOCOL_VERSION);
|
mSetVersionP(message, PROTOCOL_VERSION);
|
||||||
message->crc = crc8Message(message);
|
message->crc = crc8Message(message);
|
||||||
|
|
||||||
// Make sure radio has powered up
|
// Make sure radio has powered up
|
||||||
RF24::powerUp();
|
RF24::powerUp();
|
||||||
RF24::stopListening();
|
RF24::stopListening();
|
||||||
@@ -199,8 +206,8 @@ boolean MySensor::sendWrite(uint8_t next, MyMessage *message, bool broadcast) {
|
|||||||
RF24::startListening();
|
RF24::startListening();
|
||||||
|
|
||||||
// Only debug print payload if it is of string type
|
// Only debug print payload if it is of string type
|
||||||
debug(PSTR("tx: %d-%d-%d-%d s=%d,c=%d,t=%d, st=%s:%s\n"),
|
debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d, st=%s:%s\n"),
|
||||||
message->sender,message->last, next, message->destination, message->sensor, mGetCommandP(message), message->type, ok?"ok":"fail", message->getString());
|
message->sender,message->last, next, message->destination, message->sensor, mGetCommandP(message), message->type, ok?"ok":"fail", message->getString(convBuf));
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
@@ -259,8 +266,8 @@ boolean MySensor::process() {
|
|||||||
|
|
||||||
// Make sure string gets terminated ok for full string messages.
|
// Make sure string gets terminated ok for full string messages.
|
||||||
msg.data[len - HEADER_SIZE ] = '\0';
|
msg.data[len - HEADER_SIZE ] = '\0';
|
||||||
debug(PSTR("rx: %d-%d-%d s=%d,c=%d,t=%d,cr=%s: %s\n"),
|
debug(PSTR("read: %d-%d-%d s=%d,c=%d,t=%d,cr=%s: %s\n"),
|
||||||
msg.sender, msg.last, msg.destination, msg.sensor, mGetCommand(msg), msg.type, valid==0?"ok":valid==1?"ec":"ev", msg.getString());
|
msg.sender, msg.last, msg.destination, msg.sensor, mGetCommand(msg), msg.type, valid==0?"ok":valid==1?"ec":"ev", msg.getString(convBuf));
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
@@ -276,7 +283,7 @@ boolean MySensor::process() {
|
|||||||
// Wait a random delay of 0-2 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_PING_ACK)->set(nc.distance));
|
sendWrite(sender, build(&msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_PING_ACK)->set(nc.distance), true);
|
||||||
return false;
|
return false;
|
||||||
} else if (destination == nc.nodeId) {
|
} else if (destination == nc.nodeId) {
|
||||||
// This message is addressed to this node
|
// This message is addressed to this node
|
||||||
@@ -286,8 +293,9 @@ boolean MySensor::process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (command == C_INTERNAL) {
|
if (command == C_INTERNAL) {
|
||||||
if (type == I_PING_ACK) {
|
if (type == I_PING_ACK && nc.nodeId != GATEWAY_ADDRESS) {
|
||||||
// We've received a reply to our PING message looking for parent.
|
// We've received a reply to a PING message. Check if the distance is
|
||||||
|
// shorter than we already have.
|
||||||
uint8_t distance = msg.getByte();
|
uint8_t distance = msg.getByte();
|
||||||
if (distance<nc.distance-1) {
|
if (distance<nc.distance-1) {
|
||||||
// Found a neighbor closer to GW than previously found
|
// Found a neighbor closer to GW than previously found
|
||||||
@@ -295,14 +303,14 @@ boolean MySensor::process() {
|
|||||||
nc.parentNodeId = msg.sender;
|
nc.parentNodeId = msg.sender;
|
||||||
eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
|
eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
|
||||||
eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
|
eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
|
||||||
debug(PSTR("p=%d, d=%d\n"), nc.parentNodeId, 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) {
|
||||||
bool isMetric;
|
bool isMetric;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case I_REQUEST_ID:
|
case I_ID_RESPONSE:
|
||||||
if (nc.nodeId == AUTO) {
|
if (nc.nodeId == AUTO) {
|
||||||
nc.nodeId = msg.getByte();
|
nc.nodeId = msg.getByte();
|
||||||
// Write id to EEPROM
|
// Write id to EEPROM
|
||||||
@@ -363,7 +371,7 @@ boolean MySensor::process() {
|
|||||||
}
|
}
|
||||||
// Return true if message was addressed for this node...
|
// Return true if message was addressed for this node...
|
||||||
return true;
|
return true;
|
||||||
} else if (relayMode) {
|
} else if (relayMode && pipe == CURRENT_NODE_PIPE) {
|
||||||
// We should try to relay this message to another node
|
// We should try to relay this message to another node
|
||||||
|
|
||||||
uint8_t route = getChildRoute(msg.destination);
|
uint8_t route = getChildRoute(msg.destination);
|
||||||
@@ -380,7 +388,7 @@ boolean MySensor::process() {
|
|||||||
//
|
//
|
||||||
// lookup route in table and send message there
|
// lookup route in table and send message there
|
||||||
sendWrite(route, &msg);
|
sendWrite(route, &msg);
|
||||||
} else if (pipe == CURRENT_NODE_PIPE) {
|
} else {
|
||||||
// A message comes from a child node and we have no
|
// A message comes from a child node and we have no
|
||||||
// route for it.
|
// route for it.
|
||||||
//
|
//
|
||||||
@@ -396,33 +404,6 @@ boolean MySensor::process() {
|
|||||||
sendWrite(nc.parentNodeId, &msg);
|
sendWrite(nc.parentNodeId, &msg);
|
||||||
// Add this child to our "routing table" if it not already exist
|
// Add this child to our "routing table" if it not already exist
|
||||||
addChildRoute(sender, last);
|
addChildRoute(sender, last);
|
||||||
} else {
|
|
||||||
// We're snooped a message directed to gateway from another branch
|
|
||||||
// Make sure to remove the sender node from our routing table.
|
|
||||||
//
|
|
||||||
// +-----B <-- Message comes from here
|
|
||||||
// -A
|
|
||||||
// +-----C <-- We're here
|
|
||||||
//
|
|
||||||
// So the sender of message should never be in our
|
|
||||||
// routing table.
|
|
||||||
//
|
|
||||||
// We could also end up in this else-statement if message
|
|
||||||
// destination has no route.
|
|
||||||
// This can happen if a node never has sent any message to
|
|
||||||
// sensor net gateway (which will build up routing information in all nodes
|
|
||||||
// that gets passed).
|
|
||||||
|
|
||||||
// THIS SHOULD NOT HAPPEN ANY MORE
|
|
||||||
|
|
||||||
/*if (nc.nodeId == GATEWAY_ADDRESS) {
|
|
||||||
// We should perhaps inform gateway about the no-route situation?!
|
|
||||||
debug(PSTR("ro=?\n"));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
//debug(PSTR("Remove child node from routing table.\n"));
|
|
||||||
removeChildRoute(sender);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -495,11 +476,11 @@ uint8_t MySensor::validate(MyMessage *message) {
|
|||||||
|
|
||||||
void MySensor::saveState(uint8_t pos, uint8_t value) {
|
void MySensor::saveState(uint8_t pos, uint8_t value) {
|
||||||
if (loadState(pos) != value) {
|
if (loadState(pos) != value) {
|
||||||
eeprom_write_byte((uint8_t*)EEPROM_LOCAL_CONFIG_ADDRESS+pos, value);
|
eeprom_write_byte((uint8_t*)(EEPROM_LOCAL_CONFIG_ADDRESS+pos), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t MySensor::loadState(uint8_t pos) {
|
uint8_t MySensor::loadState(uint8_t pos) {
|
||||||
return eeprom_read_byte((uint8_t*)EEPROM_LOCAL_CONFIG_ADDRESS+pos);
|
return eeprom_read_byte((uint8_t*)(EEPROM_LOCAL_CONFIG_ADDRESS+pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -522,12 +503,27 @@ uint8_t MySensor::getChildRoute(uint8_t childId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long MySensor::getInternalTemp(void)
|
||||||
|
{
|
||||||
|
long result;
|
||||||
|
// Read internal temp sensor against 1.1V reference
|
||||||
|
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3);
|
||||||
|
delay(2); // Wait until Vref has settled
|
||||||
|
ADCSRA |= _BV(ADSC);
|
||||||
|
while (bit_is_set(ADCSRA,ADSC));
|
||||||
|
result = ADCL;
|
||||||
|
result |= ADCH<<8;
|
||||||
|
result = (result - 125) * 1075;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void MySensor::debugPrint(const char *fmt, ... ) {
|
void MySensor::debugPrint(const char *fmt, ... ) {
|
||||||
char fmtBuffer[300];
|
char fmtBuffer[300];
|
||||||
if (nc.nodeId == GATEWAY_ADDRESS) {
|
if (nc.nodeId == GATEWAY_ADDRESS) {
|
||||||
// prepend debug message to be handled correctly by gw
|
// prepend debug message to be handled correctly by gw (C_INTERNAL, I_LOG_MESSAGE)
|
||||||
Serial.write("0;0;4;11;");
|
Serial.write("0;0;4;8;");
|
||||||
}
|
}
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start (args, fmt );
|
va_start (args, fmt );
|
||||||
|
|||||||
@@ -93,14 +93,14 @@ class MySensor : public RF24
|
|||||||
*
|
*
|
||||||
* Call this in setup(), before calling any other sensor net library methods.
|
* Call this in setup(), before calling any other sensor net library methods.
|
||||||
* @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL.
|
* @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL.
|
||||||
* @param relayMode Activate relay mode. This node will forward messages to other nodes in the radio network. Make sure to call process() regularly. Default in false
|
|
||||||
* @param nodeId The unique id (1-254) for this sensor. Default is AUTO(255) which means sensor tries to fetch an id from controller.
|
* @param nodeId The unique id (1-254) for this sensor. Default is AUTO(255) which means sensor tries to fetch an id from controller.
|
||||||
|
* @param relayMode Activate relay mode. This node will forward messages to other nodes in the radio network. Make sure to call process() regularly. Default in false
|
||||||
* @param paLevel Radio PA Level for this sensor. Default RF24_PA_MAX
|
* @param paLevel Radio PA Level for this sensor. Default RF24_PA_MAX
|
||||||
* @param channel Radio channel. Default is channel 76
|
* @param channel Radio channel. Default is channel 76
|
||||||
* @param dataRate Radio transmission speed. Default RF24_1MBPS
|
* @param dataRate Radio transmission speed. Default RF24_1MBPS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void begin(void (* msgCallback)(MyMessage)=NULL, boolean relayMode=false, uint8_t nodeId=AUTO, rf24_pa_dbm_e paLevel=RF24_PA_LEVEL, uint8_t channel=RF24_CHANNEL, rf24_datarate_e dataRate=RF24_DATARATE);
|
void begin(void (* msgCallback)(MyMessage)=NULL, uint8_t nodeId=AUTO, boolean relayMode=false, rf24_pa_dbm_e paLevel=RF24_PA_LEVEL, uint8_t channel=RF24_CHANNEL, rf24_datarate_e dataRate=RF24_DATARATE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the nodes nodeId.
|
* Return the nodes nodeId.
|
||||||
@@ -194,6 +194,16 @@ class MySensor : public RF24
|
|||||||
MyMessage* getLastMessage(void);
|
MyMessage* getLastMessage(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getInternalTemp
|
||||||
|
*
|
||||||
|
* Read temp from internal (ATMEGA328 only) temperature sensor
|
||||||
|
*
|
||||||
|
* @return Temperature in milli-degrees Celsius
|
||||||
|
*/
|
||||||
|
long getInternalTemp(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void debugPrint(const char *fmt, ... );
|
void debugPrint(const char *fmt, ... );
|
||||||
@@ -214,12 +224,16 @@ class MySensor : public RF24
|
|||||||
uint8_t validate(MyMessage *message);
|
uint8_t validate(MyMessage *message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef DEBUG
|
||||||
|
char convBuf[MAX_PAYLOAD];
|
||||||
|
#endif
|
||||||
uint8_t failedTransmissions;
|
uint8_t failedTransmissions;
|
||||||
uint8_t *childNodeTable; // In memory buffer for routing information to other nodes. also stored in EEPROM
|
uint8_t *childNodeTable; // In memory buffer for routing information to other nodes. also stored in EEPROM
|
||||||
void (*timeCallback)(unsigned long); // Callback for requested time messages
|
void (*timeCallback)(unsigned long); // Callback for requested time messages
|
||||||
void (*msgCallback)(MyMessage); // Callback for incoming messages from other nodes and gateway.
|
void (*msgCallback)(MyMessage); // Callback for incoming messages from other nodes and gateway.
|
||||||
|
|
||||||
void requestNodeId();
|
void waitForReply();
|
||||||
|
void requestNodeId();
|
||||||
void findParentNode();
|
void findParentNode();
|
||||||
uint8_t crc8Message(MyMessage *message);
|
uint8_t crc8Message(MyMessage *message);
|
||||||
uint8_t getChildRoute(uint8_t childId);
|
uint8_t getChildRoute(uint8_t childId);
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ float lastTemperature[MAX_ATTACHED_DS18B20];
|
|||||||
int numSensors=0;
|
int numSensors=0;
|
||||||
boolean receivedConfig = false;
|
boolean receivedConfig = false;
|
||||||
boolean metric = true;
|
boolean metric = true;
|
||||||
MyMessage out;
|
// Initialize temperature message
|
||||||
|
MyMessage msg(0,V_TEMP);
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
@@ -37,9 +38,6 @@ void setup()
|
|||||||
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
|
for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
|
||||||
gw.present(i, S_TEMP);
|
gw.present(i, S_TEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize outgoing message to always send temperature
|
|
||||||
out.type = V_TEMP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +59,7 @@ void loop()
|
|||||||
if (lastTemperature[i] != temperature && temperature != -127.00) {
|
if (lastTemperature[i] != temperature && temperature != -127.00) {
|
||||||
|
|
||||||
// Send in the new temperature
|
// Send in the new temperature
|
||||||
gw.send(out.setSensor(i)->set(temperature,1));
|
gw.send(msg.setSensor(i)->set(temperature,1));
|
||||||
lastTemperature[i]=temperature;
|
lastTemperature[i]=temperature;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
|
#include <MySensor.h>
|
||||||
#include <Sleep_n0m1.h>
|
#include <Sleep_n0m1.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <EEPROM.h>
|
|
||||||
#include <RF24.h>
|
#include <RF24.h>
|
||||||
#include <Sensor.h>
|
|
||||||
|
|
||||||
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
|
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
|
||||||
#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
|
#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
|
||||||
#define CHILD_ID 0 // Id of the sensor child
|
#define CHILD_ID 1 // Id of the sensor child
|
||||||
|
|
||||||
Sensor gw;
|
MySensor gw;
|
||||||
Sleep sleep;
|
Sleep sleep;
|
||||||
|
// Initialize motion message
|
||||||
|
MyMessage msg(CHILD_ID, V_TRIPPED);
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
EEPROM.write(EEPROM_RELAY_ID_ADDRESS, 0);
|
//eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, 1);
|
||||||
|
//eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, 255);
|
||||||
|
//delay(2000);
|
||||||
gw.begin();
|
gw.begin();
|
||||||
|
|
||||||
// Send the sketch version information to the gateway and Controller
|
// Send the sketch version information to the gateway and Controller
|
||||||
@@ -22,7 +24,10 @@ void setup()
|
|||||||
|
|
||||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||||
// Register all sensors to gw (they will be created as child devices)
|
// Register all sensors to gw (they will be created as child devices)
|
||||||
gw.sendSensorPresentation(CHILD_ID, S_MOTION);
|
delay(500);
|
||||||
|
gw.present(CHILD_ID, S_MOTION);
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
@@ -31,7 +36,7 @@ void loop()
|
|||||||
boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
|
||||||
|
|
||||||
Serial.println(tripped);
|
Serial.println(tripped);
|
||||||
gw.sendVariable(CHILD_ID, V_TRIPPED, tripped?"1":"0"); // Send tripped value to gw
|
gw.send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||||
|
|
||||||
// Power down the radio. Note that the radio will get powered back up
|
// Power down the radio. Note that the radio will get powered back up
|
||||||
// on the next write() call.
|
// on the next write() call.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ MySensor gw;
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
// Initialize library and add callback for incoming messages
|
// Initialize library and add callback for incoming messages
|
||||||
gw.begin(incomingMessage, false);
|
gw.begin(incomingMessage, AUTO, true);
|
||||||
// Send the sketch version information to the gateway and Controller
|
// Send the sketch version information to the gateway and Controller
|
||||||
gw.sendSketchInfo("Relay", "1.0");
|
gw.sendSketchInfo("Relay", "1.0");
|
||||||
|
|
||||||
@@ -42,10 +42,9 @@ void incomingMessage(MyMessage message) {
|
|||||||
// We only expect one type of message from controller. But we better check anyway.
|
// We only expect one type of message from controller. But we better check anyway.
|
||||||
if (message.type==V_LIGHT) {
|
if (message.type==V_LIGHT) {
|
||||||
// Change relay state
|
// Change relay state
|
||||||
digitalWrite(message.sensor, message.getBool()?RELAY_ON:RELAY_OFF);
|
digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
|
||||||
// Store state in eeprom
|
// Store state in eeprom
|
||||||
gw.saveState(message.sensor, message.getBool());
|
gw.saveState(message.sensor, message.getBool());
|
||||||
|
|
||||||
// Write some debug info
|
// Write some debug info
|
||||||
Serial.print("Incoming change for sensor:");
|
Serial.print("Incoming change for sensor:");
|
||||||
Serial.print(message.sensor);
|
Serial.print(message.sensor);
|
||||||
|
|||||||
@@ -680,10 +680,10 @@ void RF24::startWrite( const void* buf, uint8_t len, const bool multicast ){
|
|||||||
// Send the payload
|
// Send the payload
|
||||||
|
|
||||||
//write_payload( buf, len );
|
//write_payload( buf, len );
|
||||||
write_payload( buf, len,multicast? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD ) ;
|
write_payload( buf, len, multicast?static_cast<uint8_t>(W_TX_PAYLOAD_NO_ACK):static_cast<uint8_t>(W_TX_PAYLOAD)) ;
|
||||||
|
|
||||||
ce(HIGH);
|
ce(HIGH);
|
||||||
ce(LOW);
|
ce(LOW);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user