Skip to content

Commit 39bab3d

Browse files
committed
Split Application and Driver Layer
1 parent c3dbcd1 commit 39bab3d

File tree

10 files changed

+200
-104
lines changed

10 files changed

+200
-104
lines changed

libraries/MySensors/MyConfig.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
/***
55
* Configure Sensor Network
66
*/
7+
#define COMMDRIVER_NRF24
8+
9+
#ifdef COMMDRIVER_NRF24
10+
#include "MyDriverNRF24.h"
11+
typedef class MyDriverNRF24 MyDriverClass;
712
#define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127
813
#define RF24_DATARATE RF24_250KBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
914
#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_MAX=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.
11-
#define BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
12-
13-
// MySensors online examples defaults
14-
#define DEFAULT_CE_PIN 9
15-
#define DEFAULT_CS_PIN 10
16-
15+
#define RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
16+
#define RF24_CE_PIN 9
17+
#define RF24_CS_PIN 10
18+
#endif
1719

1820
/***
1921
* Enable/Disable debug logging

libraries/MySensors/MyDriver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "MyDriver.h"
2+
3+
MyDriver::MyDriver() {
4+
}

libraries/MySensors/MyDriver.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#ifndef MyDriver_h
2+
#define MyDriver_h
3+
4+
#include <stdint.h>
5+
6+
#ifdef DEBUG
7+
#define debug(x,...) debugPrint(x, ##__VA_ARGS__)
8+
#else
9+
#define debug(x,...)
10+
#endif
11+
12+
#define AUTO 0xFF // 0-254. Id 255 is reserved for auto initialization of nodeId.
13+
#define NODE_SENSOR_ID 0xFF // Node child id is always created for when a node
14+
15+
// This is the nodeId for sensor net gateway receiver sketch (where all sensors should send their data).
16+
#define GATEWAY_ADDRESS ((uint8_t)0)
17+
#define BROADCAST_ADDRESS ((uint8_t)0xFF)
18+
19+
class MyDriver
20+
{
21+
public:
22+
// MyDriver constructor
23+
// different parameters would be needed depending on radio module (e.g. pins connected etc.)
24+
// keeping these parameters as #define's in MyConfig to streamline the driver interface
25+
MyDriver();
26+
// init()
27+
// different parameters would be needed depending on radio module (e.g. channel, power, crc, etc.)
28+
// keeping these parameters as #define's in MyConfig to streamline the driver interface
29+
virtual void init() = 0;
30+
// setAddress(address)
31+
// set the node address and start listening to that address (and the broadcast address)
32+
virtual void setAddress(uint8_t address) = 0;
33+
// getAddress()
34+
// returns the current address from the radio driver
35+
virtual uint8_t getAddress() = 0;
36+
// send(to, data, len)
37+
// reliable transmission of the data with given length (in bytes) to the destination address
38+
// returns true if successfully submitted
39+
virtual bool send(uint8_t to, const void* data, uint8_t len) = 0;
40+
// available(to)
41+
// returns true if a new packet arrived in the rx buffer
42+
// populates "to" parameter with the address the packet was sent to (either own address or broadcast)
43+
virtual bool available(uint8_t *to) = 0;
44+
// receive(data)
45+
// returns length of received packet
46+
// populates "data" parameter with received data
47+
virtual uint8_t receive(void* data) = 0;
48+
// powers down the radio
49+
virtual void powerDown() = 0;
50+
};
51+
52+
#endif

libraries/MySensors/MyDriverNRF24.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include "MyDriver.h"
2+
#include "MyDriverNRF24.h"
3+
4+
MyDriverNRF24::MyDriverNRF24() : MyDriver() {
5+
rf24 = new RF24(RF24_CE_PIN, RF24_CS_PIN);
6+
}
7+
8+
void MyDriverNRF24::init() {
9+
// Start up the radio library
10+
rf24->begin();
11+
12+
if (!rf24->isPVariant()) {
13+
debug(PSTR("check wires\n"));
14+
while(1);
15+
}
16+
rf24->setAutoAck(1);
17+
rf24->setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
18+
rf24->enableAckPayload();
19+
rf24->setChannel(RF24_CHANNEL);
20+
rf24->setPALevel(RF24_PA_LEVEL);
21+
rf24->setDataRate(RF24_DATARATE);
22+
rf24->setRetries(5,15);
23+
rf24->setCRCLength(RF24_CRC_16);
24+
rf24->enableDynamicPayloads();
25+
26+
// All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages)
27+
rf24->openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
28+
}
29+
30+
void MyDriverNRF24::setAddress(uint8_t address) {
31+
_address = address;
32+
rf24->openReadingPipe(WRITE_PIPE, TO_ADDR(address));
33+
rf24->openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(address));
34+
rf24->startListening();
35+
}
36+
37+
uint8_t MyDriverNRF24::getAddress() {
38+
return _address;
39+
}
40+
41+
bool MyDriverNRF24::send(uint8_t to, const void* data, uint8_t len) {
42+
// Make sure radio has powered up
43+
rf24->powerUp();
44+
rf24->stopListening();
45+
rf24->openWritingPipe(TO_ADDR(to));
46+
bool ok = rf24->write(data, len, to == BROADCAST_ADDRESS);
47+
rf24->startListening();
48+
return ok;
49+
}
50+
51+
bool MyDriverNRF24::available(uint8_t *to) {
52+
uint8_t pipe = 255;
53+
boolean avail = rf24->available(&pipe);
54+
if (pipe == CURRENT_NODE_PIPE)
55+
*to = _address;
56+
else if (pipe == BROADCAST_PIPE)
57+
*to = BROADCAST_ADDRESS;
58+
return (rf24->available() && pipe < 6);
59+
}
60+
61+
uint8_t MyDriverNRF24::receive(void* data) {
62+
uint8_t len = rf24->getDynamicPayloadSize();
63+
rf24->read(data, len);
64+
}
65+
66+
void MyDriverNRF24::powerDown() {
67+
rf24->powerDown();
68+
}

libraries/MySensors/MyDriverNRF24.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#ifndef MyCommDriver_h
2+
#define MyCommDriver_h
3+
4+
#include "MyConfig.h"
5+
#include "MyDriver.h"
6+
#include <stdint.h>
7+
#include "utility/RF24.h"
8+
#include "utility/RF24_config.h"
9+
10+
#define TO_ADDR(x) (RF24_BASE_RADIO_ID + x)
11+
12+
#define WRITE_PIPE ((uint8_t)0)
13+
#define CURRENT_NODE_PIPE ((uint8_t)1)
14+
#define BROADCAST_PIPE ((uint8_t)2)
15+
16+
class MyDriverNRF24 : public MyDriver
17+
{
18+
public:
19+
MyDriverNRF24();
20+
void init();
21+
void setAddress(uint8_t address);
22+
uint8_t getAddress();
23+
bool send(uint8_t to, const void* data, uint8_t len);
24+
bool available(uint8_t *to);
25+
uint8_t receive(void* data);
26+
void powerDown();
27+
private:
28+
RF24 *rf24;
29+
uint8_t _address;
30+
};
31+
32+
#endif

libraries/MySensors/MySensor.cpp

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
*/
1111

1212
#include "MySensor.h"
13-
#include "utility/LowPower.h"
14-
#include "utility/RF24.h"
15-
#include "utility/RF24_config.h"
1613

1714
#define DISTANCE_INVALID (0xFF)
1815

@@ -36,12 +33,12 @@ static inline bool isValidDistance( const uint8_t distance ) {
3633
return distance != DISTANCE_INVALID;
3734
}
3835

39-
40-
MySensor::MySensor(uint8_t _cepin, uint8_t _cspin) : RF24(_cepin, _cspin) {
41-
}
36+
MySensor::MySensor() {
37+
driver = (MyDriver*) new MyDriverClass();
38+
}
4239

4340

44-
void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, boolean _repeaterMode, uint8_t _parentNodeId, rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
41+
void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, boolean _repeaterMode, uint8_t _parentNodeId) {
4542
Serial.begin(BAUD_RATE);
4643
repeaterMode = _repeaterMode;
4744
msgCallback = _msgCallback;
@@ -52,7 +49,7 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
5249
if (repeaterMode) {
5350
setupRepeaterMode();
5451
}
55-
setupRadio(paLevel, channel, dataRate);
52+
setupRadio();
5653

5754
// Read settings from EEPROM
5855
eeprom_read_block((void*)&nc, (void*)EEPROM_NODE_ID_ADDRESS, sizeof(NodeConfig));
@@ -92,8 +89,7 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
9289
}
9390

9491
// Open reading pipe for messages directed to this node (set write pipe to same)
95-
RF24::openReadingPipe(WRITE_PIPE, TO_ADDR(nc.nodeId));
96-
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
92+
driver->setAddress(nc.nodeId);
9793

9894
// Send presentation for this radio node (attach
9995
present(NODE_SENSOR_ID, repeaterMode? S_ARDUINO_REPEATER_NODE : S_ARDUINO_NODE);
@@ -107,26 +103,9 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
107103
waitForReply();
108104
}
109105

110-
void MySensor::setupRadio(rf24_pa_dbm_e paLevel, uint8_t channel, rf24_datarate_e dataRate) {
111-
// Start up the radio library
112-
RF24::begin();
113-
114-
if (!RF24::isPVariant()) {
115-
debug(PSTR("check wires\n"));
116-
while(1);
117-
}
118-
RF24::setAutoAck(1);
119-
RF24::setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
120-
RF24::setChannel(channel);
121-
RF24::setPALevel(paLevel);
122-
RF24::setDataRate(dataRate);
123-
RF24::setRetries(5,15);
124-
RF24::setCRCLength(RF24_CRC_16);
125-
RF24::enableDynamicPayloads();
126-
RF24::enableDynamicAck(); // Required to disable ack-sending for broadcast messages
127-
128-
// All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages)
129-
RF24::openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
106+
void MySensor::setupRadio() {
107+
failedTransmissions = 0;
108+
driver->init();
130109
}
131110

132111
void MySensor::setupRepeaterMode(){
@@ -145,7 +124,7 @@ ControllerConfig MySensor::getConfig() {
145124

146125
void MySensor::requestNodeId() {
147126
debug(PSTR("req node id\n"));
148-
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
127+
driver->setAddress(nc.nodeId);
149128
sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_ID_REQUEST, false).set(""));
150129
waitForReply();
151130
}
@@ -223,13 +202,7 @@ boolean MySensor::sendWrite(uint8_t next, MyMessage &message, const bool allowFi
223202
uint8_t length = mGetLength(message);
224203
message.last = nc.nodeId;
225204
mSetVersion(message, PROTOCOL_VERSION);
226-
// Make sure radio has powered up
227-
RF24::powerUp();
228-
RF24::stopListening();
229-
RF24::openWritingPipe(TO_ADDR(next));
230-
// Send message. Disable auto-ack for broadcasts.
231-
ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length), broadcast);
232-
RF24::startListening();
205+
bool ok = driver->send(next, &message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length));
233206

234207
debug(PSTR("send: %d-%d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d,st=%s:%s\n"),
235208
message.sender,message.last, next, message.destination, message.sensor, mGetCommand(message), message.type,
@@ -290,14 +263,11 @@ void MySensor::requestTime(void (* _timeCallback)(unsigned long)) {
290263

291264

292265
boolean MySensor::process() {
293-
uint8_t pipe;
294-
boolean available = RF24::available(&pipe);
295-
296-
if (!available || pipe>6)
266+
uint8_t to = 0;
267+
if (!driver->available(&to))
297268
return false;
298269

299-
uint8_t len = RF24::getDynamicPayloadSize();
300-
RF24::read(&msg, len);
270+
uint8_t len = driver->receive((uint8_t *)&msg);
301271

302272
// Add string termination, good if we later would want to print it.
303273
msg.data[mGetLength(msg)] = '\0';
@@ -380,7 +350,7 @@ boolean MySensor::process() {
380350
debug(PSTR("full\n"));
381351
while (1); // Wait here. Nothing else we can do...
382352
} else {
383-
RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
353+
driver->setAddress(nc.nodeId);
384354
eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, nc.nodeId);
385355
}
386356
debug(PSTR("id=%d\n"), nc.nodeId);
@@ -412,7 +382,7 @@ boolean MySensor::process() {
412382
}
413383
// Return true if message was addressed for this node...
414384
return true;
415-
} else if (repeaterMode && pipe == CURRENT_NODE_PIPE) {
385+
} else if (repeaterMode && to == nc.nodeId) {
416386
// We should try to relay this message to another node
417387

418388
uint8_t route = getChildRoute(msg.destination);
@@ -511,7 +481,7 @@ void MySensor::internalSleep(unsigned long ms) {
511481
void MySensor::sleep(unsigned long ms) {
512482
// Let serial prints finish (debug, log etc)
513483
Serial.flush();
514-
RF24::powerDown();
484+
driver->powerDown();
515485
pinIntTrigger = 0;
516486
internalSleep(ms);
517487
}
@@ -520,7 +490,7 @@ bool MySensor::sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) {
520490
// Let serial prints finish (debug, log etc)
521491
bool pinTriggeredWakeup = true;
522492
Serial.flush();
523-
RF24::powerDown();
493+
driver->powerDown();
524494
attachInterrupt(interrupt, wakeUp, mode);
525495
if (ms>0) {
526496
pinIntTrigger = 0;
@@ -539,7 +509,7 @@ bool MySensor::sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) {
539509
int8_t MySensor::sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) {
540510
int8_t retVal = 1;
541511
Serial.flush(); // Let serial prints finish (debug, log etc)
542-
RF24::powerDown();
512+
driver->powerDown();
543513
attachInterrupt(interrupt1, wakeUp, mode1);
544514
attachInterrupt(interrupt2, wakeUp2, mode2);
545515
if (ms>0) {

0 commit comments

Comments
 (0)