Skip to content

Commit 32e78d2

Browse files
TMRh202bndy5
andauthored
Fix for large payloads with NRF52 (#244)
* Fix for large payloads with NRF52 * Specify nrf_to_nrf or RF24 behavior in the overloaded write() functions * modify doc comment * add CI for nrf_to_nrf * disambiguate examples in docs - Add intermediate function write() and change the old write() function to main_write() * Make main_write() function inline Co-authored-by: Brendan <2bndy5@gmail.com> * Remove max_frame_size var Per @2bndy5 in #244 * Remove setting max_frame_payload_size in RF24 write function * Missing bracket... --------- Co-authored-by: Brendan <2bndy5@gmail.com>
1 parent 731a368 commit 32e78d2

File tree

7 files changed

+387
-7
lines changed

7 files changed

+387
-7
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: nRF52840 build
2+
3+
on:
4+
pull_request:
5+
branches: [master]
6+
push:
7+
branches: [master]
8+
9+
jobs:
10+
build:
11+
uses: nRF24/.github/.github/workflows/build_platformio.yaml@main
12+
with:
13+
example-path: ${{ matrix.example }}
14+
board-id: ${{ matrix.board }}
15+
lib-deps: -l https://github.com/TMRh20/nrf_to_nrf.git
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
example:
20+
- "examples/nrf_to_nrf/helloworld_rx/helloworld_rx.ino"
21+
- "examples/nrf_to_nrf/helloworld_tx/helloworld_tx.ino"
22+
- "examples/nrf_to_nrf/helloworld_rxEncryption/helloworld_rxEncryption.ino"
23+
- "examples/nrf_to_nrf/helloworld_txEncryption/helloworld_txEncryption.ino"
24+
board:
25+
- "adafruit_feather_nrf52840"

RF24Network.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,14 +696,37 @@ bool ESBNetwork<radio_t>::write(RF24NetworkHeader& header, const void* message,
696696

697697
/******************************************************************/
698698

699+
template<>
700+
bool ESBNetwork<RF24>::write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect)
701+
{
702+
return main_write(header, message, len, writeDirect);
703+
}
704+
705+
/******************************************************************/
706+
#if defined NRF52_RADIO_LIBRARY
707+
template<>
708+
bool ESBNetwork<nrf_to_nrf>::write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect)
709+
{
710+
max_frame_payload_size = (uint8_t)NRF_RADIO->PCNF1 - sizeof(RF24NetworkHeader);
711+
if (radio.enableEncryption == true) {
712+
max_frame_payload_size -= CCM_IV_SIZE + CCM_COUNTER_SIZE + CCM_MIC_SIZE;
713+
}
714+
return main_write(header, message, len, writeDirect);
715+
}
716+
#endif
717+
/******************************************************************/
718+
699719
template<class radio_t>
700-
bool ESBNetwork<radio_t>::write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect)
720+
bool ESBNetwork<radio_t>::main_write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect)
701721
{
702722

703723
#if defined(DISABLE_FRAGMENTATION)
704-
frame_size = rf24_min(len + sizeof(RF24NetworkHeader), MAX_FRAME_SIZE);
724+
725+
frame_size = rf24_min(len + sizeof(RF24NetworkHeader), max_frame_payload_size + sizeof(RF24NetworkHeader));
705726
return _write(header, message, rf24_min(len, max_frame_payload_size), writeDirect);
727+
706728
#else // !defined(DISABLE_FRAGMENTATION)
729+
707730
if (len <= max_frame_payload_size) {
708731
//Normal Write (Un-Fragmented)
709732
frame_size = len + sizeof(RF24NetworkHeader);

RF24Network.h

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@
192192
#define USER_TX_TO_LOGICAL_ADDRESS 3 // network ACK
193193
#define USER_TX_MULTICAST 4
194194

195-
#define MAX_FRAME_SIZE 32 // Size of individual radio frames
195+
#if defined NRF52_RADIO_LIBRARY
196+
#define MAX_FRAME_SIZE 123 // Size of individual radio frames is larger with NRF52
197+
#else
198+
#define MAX_FRAME_SIZE 32 // Size of individual radio frames
199+
#endif
200+
196201
#define FRAME_HEADER_SIZE 10 // Size of RF24Network frames - data
197202

198203
/**
@@ -902,6 +907,11 @@ class ESBNetwork
902907
*/
903908
bool _write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
904909

910+
/*
911+
* The main write function where fragmentation and processing of the payload is initiated
912+
*/
913+
inline bool main_write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
914+
905915
struct logicalToPhysicalStruct
906916
{
907917
/** The immediate destination (1 hop) of an outgoing frame */
@@ -934,8 +944,9 @@ class ESBNetwork
934944

935945
radio_t& radio; /** Underlying radio driver, provides link/physical layers */
936946

937-
uint8_t frame_size; /* The outgoing frame's total size including the header info. Ranges [8, MAX_PAYLOAD_SIZE] */
938-
const static unsigned int max_frame_payload_size = MAX_FRAME_SIZE - sizeof(RF24NetworkHeader); /* always 24 bytes to compensate for the frame's header */
947+
uint8_t frame_size; /* The outgoing frame's total size including the header info. Ranges [8, MAX_PAYLOAD_SIZE] */
948+
949+
unsigned int max_frame_payload_size = MAX_FRAME_SIZE - sizeof(RF24NetworkHeader); /* always 24 bytes to compensate for the frame's header */
939950

940951
#if defined(RF24_LINUX)
941952
std::queue<RF24NetworkFrame> frame_queue;
@@ -995,15 +1006,15 @@ typedef ESBNetwork<nrf_to_nrf> RF52Network;
9951006
#endif
9961007

9971008
/**
998-
* @example helloworld_tx.ino
1009+
* @example examples/helloworld_tx/helloworld_tx.ino
9991010
*
10001011
* Simplest possible example of using RF24Network. Put this sketch
10011012
* on one node, and helloworld_rx.pde on the other. Tx will send
10021013
* Rx a nice message every 2 seconds which rx will print out for us.
10031014
*/
10041015

10051016
/**
1006-
* @example helloworld_rx.ino
1017+
* @example examples/helloworld_rx/helloworld_rx.ino
10071018
*
10081019
* Simplest possible example of using RF24Network. Put this sketch
10091020
* on one node, and helloworld_tx.pde on the other. Tx will send
@@ -1063,4 +1074,36 @@ typedef ESBNetwork<nrf_to_nrf> RF52Network;
10631074
* An example of handling/prioritizing different types of data passing through the RF24Network
10641075
*/
10651076

1077+
/**
1078+
* @example examples/nrf_to_nrf/helloworld_tx/helloworld_tx.ino
1079+
*
1080+
* Simplest possible example of using RF24Network with nrf_to_nrf library (instead of RF24).
1081+
* Put this sketch on one node, and helloworld_tx.pde on the other. Tx will send
1082+
* Rx a nice message every 2 seconds which rx will print out for us.
1083+
*/
1084+
1085+
/**
1086+
* @example examples/nrf_to_nrf/helloworld_rx/helloworld_rx.ino
1087+
*
1088+
* Simplest possible example of using RF24Network with nrf_to_nrf library (instead of RF24).
1089+
* Put this sketch on one node, and helloworld_tx.pde on the other. Tx will send
1090+
* Rx a nice message every 2 seconds which rx will print out for us.
1091+
*/
1092+
1093+
/**
1094+
* @example examples/nrf_to_nrf/helloworld_txEncryption/helloworld_txEncryption.ino
1095+
*
1096+
* Simplest possible example of using RF24Network with nrf_to_nrf library (instead of RF24) with encryption.
1097+
* Put this sketch on one node, and helloworld_tx.pde on the other. Tx will send
1098+
* Rx a nice message every 2 seconds which rx will print out for us.
1099+
*/
1100+
1101+
/**
1102+
* @example examples/nrf_to_nrf/helloworld_rxEncryption/helloworld_rxEncryption.ino
1103+
*
1104+
* Simplest possible example of using RF24Network with nrf_to_nrf library (instead of RF24) with encryption.
1105+
* Put this sketch on one node, and helloworld_tx.pde on the other. Tx will send
1106+
* Rx a nice message every 2 seconds which rx will print out for us.
1107+
*/
1108+
10661109
#endif // __RF24NETWORK_H__
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright (C) 2012 James Coliz, Jr. <maniacbug@ymail.com>
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License
6+
* version 2 as published by the Free Software Foundation.
7+
*
8+
* Update 2014 - TMRh20
9+
*/
10+
11+
/**
12+
* Simplest possible example of using RF24Network,
13+
*
14+
* RECEIVER NODE
15+
* Listens for messages from the transmitter and prints them out.
16+
*/
17+
18+
#include <nrf_to_nrf.h>
19+
#include <RF24Network.h>
20+
21+
22+
nrf_to_nrf radio; // nRF24L01(+) radio attached using Getting Started board
23+
24+
RF52Network network(radio); // Network uses that radio
25+
const uint16_t this_node = 00; // Address of our node in Octal format (04, 031, etc)
26+
const uint16_t other_node = 01; // Address of the other node in Octal format
27+
28+
struct payload_t { // Structure of our payload
29+
unsigned long ms;
30+
unsigned long counter;
31+
};
32+
33+
34+
void setup(void) {
35+
Serial.begin(115200);
36+
while (!Serial) {
37+
// some boards need this because of native USB capability
38+
}
39+
Serial.println(F("RF24Network/examples/helloworld_rx/"));
40+
41+
if (!radio.begin()) {
42+
Serial.println(F("Radio hardware not responding!"));
43+
while (1) {
44+
// hold in infinite loop
45+
}
46+
}
47+
radio.setChannel(90);
48+
network.begin(/*node address*/ this_node);
49+
}
50+
51+
void loop(void) {
52+
53+
network.update(); // Check the network regularly
54+
55+
while (network.available()) { // Is there anything ready for us?
56+
57+
RF24NetworkHeader header; // If so, grab it and print it out
58+
payload_t payload;
59+
network.read(header, &payload, sizeof(payload));
60+
Serial.print(F("Received packet: counter="));
61+
Serial.print(payload.counter);
62+
Serial.print(F(", origin timestamp="));
63+
Serial.println(payload.ms);
64+
}
65+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright (C) 2012 James Coliz, Jr. <maniacbug@ymail.com>
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License
6+
* version 2 as published by the Free Software Foundation.
7+
*
8+
* Update 2014 - TMRh20
9+
*/
10+
11+
/**
12+
* Simplest possible example of using RF24Network,
13+
*
14+
* RECEIVER NODE
15+
* Listens for messages from the transmitter and prints them out.
16+
*/
17+
18+
#include <nrf_to_nrf.h>
19+
#include <RF24Network.h>
20+
21+
//Set up our encryption key
22+
uint8_t myKey[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
23+
24+
nrf_to_nrf radio; // nRF24L01(+) radio attached using Getting Started board
25+
26+
RF52Network network(radio); // Network uses that radio
27+
const uint16_t this_node = 00; // Address of our node in Octal format (04, 031, etc)
28+
const uint16_t other_node = 01; // Address of the other node in Octal format
29+
30+
struct payload_t { // Structure of our payload
31+
unsigned long ms;
32+
unsigned long counter;
33+
};
34+
35+
36+
void setup(void) {
37+
Serial.begin(115200);
38+
while (!Serial) {
39+
// some boards need this because of native USB capability
40+
}
41+
Serial.println(F("RF24Network/examples/helloworld_rx/"));
42+
43+
if (!radio.begin()) {
44+
Serial.println(F("Radio hardware not responding!"));
45+
while (1) {
46+
// hold in infinite loop
47+
}
48+
}
49+
50+
radio.setKey(myKey); // Set our key and IV
51+
radio.enableEncryption = true; // Enable encryption
52+
radio.enableDynamicPayloads(123); //This is important to call so the encryption overhead will not be included in the 32-byte limit
53+
//To overcome the 32-byte limit, edit RF24Network.h and set MAX_FRAME_SIZE to 111
54+
radio.setChannel(90);
55+
network.begin(/*node address*/ this_node);
56+
}
57+
58+
void loop(void) {
59+
60+
network.update(); // Check the network regularly
61+
62+
while (network.available()) { // Is there anything ready for us?
63+
64+
RF24NetworkHeader header; // If so, grab it and print it out
65+
payload_t payload;
66+
network.read(header, &payload, sizeof(payload));
67+
Serial.print(F("Received packet: counter="));
68+
Serial.print(payload.counter);
69+
Serial.print(F(", origin timestamp="));
70+
Serial.println(payload.ms);
71+
}
72+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Copyright (C) 2012 James Coliz, Jr. <maniacbug@ymail.com>
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License
6+
* version 2 as published by the Free Software Foundation.
7+
*
8+
* Update 2014 - TMRh20
9+
*/
10+
11+
/**
12+
* Simplest possible example of using RF24Network
13+
*
14+
* TRANSMITTER NODE
15+
* Every 2 seconds, send a payload to the receiver node.
16+
*/
17+
18+
#include <nrf_to_nrf.h>
19+
#include <RF24Network.h>
20+
21+
nrf_to_nrf radio; // nRF24L01(+) radio attached using Getting Started board
22+
23+
RF52Network network(radio); // Network uses that radio
24+
25+
const uint16_t this_node = 01; // Address of our node in Octal format
26+
const uint16_t other_node = 00; // Address of the other node in Octal format
27+
28+
const unsigned long interval = 2000; // How often (in ms) to send 'hello world' to the other unit
29+
30+
unsigned long last_sent; // When did we last send?
31+
unsigned long packets_sent; // How many have we sent already
32+
33+
34+
struct payload_t { // Structure of our payload
35+
unsigned long ms;
36+
unsigned long counter;
37+
};
38+
39+
void setup(void) {
40+
Serial.begin(115200);
41+
while (!Serial) {
42+
// some boards need this because of native USB capability
43+
}
44+
Serial.println(F("RF24Network/examples/helloworld_tx/"));
45+
46+
if (!radio.begin()) {
47+
Serial.println(F("Radio hardware not responding!"));
48+
while (1) {
49+
// hold in infinite loop
50+
}
51+
}
52+
radio.setChannel(90);
53+
network.begin(/*node address*/ this_node);
54+
}
55+
56+
void loop() {
57+
58+
network.update(); // Check the network regularly
59+
60+
unsigned long now = millis();
61+
62+
// If it's time to send a message, send it!
63+
if (now - last_sent >= interval) {
64+
last_sent = now;
65+
66+
Serial.print(F("Sending... "));
67+
payload_t payload = { millis(), packets_sent++ };
68+
RF24NetworkHeader header(/*to node*/ other_node);
69+
bool ok = network.write(header, &payload, sizeof(payload));
70+
Serial.println(ok ? F("ok.") : F("failed."));
71+
}
72+
}

0 commit comments

Comments
 (0)