summaryrefslogtreecommitdiff
path: root/.pio/libdeps/esp32-s3-n16r8/RF24/examples
diff options
context:
space:
mode:
authorkrolyxon <me@krolyxon.com>2026-06-08 23:10:46 +0530
committerkrolyxon <me@krolyxon.com>2026-06-08 23:10:46 +0530
commit3120783000d0025b183b0397acaa8b769499eb38 (patch)
tree1c4f93be213f1b1d48f59e554562d847b4e7c25e /.pio/libdeps/esp32-s3-n16r8/RF24/examples
Initial gh-pages firmware hosting
Diffstat (limited to '.pio/libdeps/esp32-s3-n16r8/RF24/examples')
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/.clang-format145
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino207
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/GettingStarted/GettingStarted.ino154
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/InterruptConfigure/InterruptConfigure.ino353
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino222
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino194
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/StreamingData/StreamingData.ino192
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino123
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/print_details.py196
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino217
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino185
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino182
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino173
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino252
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino231
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/led_remote/led_remote.ino236
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino135
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp77
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino231
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/readme.md7
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino204
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino207
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/scanner/scanner.ino236
-rw-r--r--.pio/libdeps/esp32-s3-n16r8/RF24/examples/scannerGraphic/scannerGraphic.ino323
24 files changed, 4682 insertions, 0 deletions
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/.clang-format b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/.clang-format
new file mode 100644
index 0000000..f95490c
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/.clang-format
@@ -0,0 +1,145 @@
+# See: https://releases.llvm.org/11.0.1/tools/clang/docs/ClangFormatStyleOptions.html
+---
+Language: Cpp
+# LLVM is the default style setting, used when a configuration option is not set here
+BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveBitFields: false
+AlignConsecutiveDeclarations: false
+AlignConsecutiveMacros: false
+AlignEscapedNewlines: DontAlign
+AlignOperands: Align
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Always
+AllowShortCaseLabelsOnASingleLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: Always
+AllowShortLambdasOnASingleLine: Empty
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: No
+BinPackArguments: true
+BinPackParameters: true
+# Only used when "BreakBeforeBraces" set to "Custom"
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: false
+ AfterControlStatement: Never
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ #AfterObjCDeclaration:
+ AfterStruct: false
+ AfterUnion: false
+ AfterExternBlock: false
+ BeforeCatch: false
+ BeforeElse: false
+ BeforeLambdaBody: false
+ BeforeWhile: false
+ IndentBraces: false
+ SplitEmptyFunction: false
+ SplitEmptyRecord: false
+ SplitEmptyNamespace: false
+# Java-specific
+#BreakAfterJavaFieldAnnotations:
+BreakBeforeBinaryOperators: NonAssignment
+BreakBeforeBraces: Attach
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: false
+ColumnLimit: 0
+# "" matches none
+CommentPragmas: ""
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 2
+ContinuationIndentWidth: 2
+Cpp11BracedListStyle: false
+DeriveLineEnding: true
+DerivePointerAlignment: true
+DisableFormat: false
+# Docs say "Do not use this in config files". The default (LLVM 11.0.1) is "false".
+#ExperimentalAutoDetectBinPacking:
+FixNamespaceComments: false
+ForEachMacros: []
+IncludeBlocks: Preserve
+IncludeCategories: []
+# "" matches none
+IncludeIsMainRegex: ""
+IncludeIsMainSourceRegex: ""
+IndentCaseBlocks: true
+IndentCaseLabels: true
+IndentExternBlock: Indent
+IndentGotoLabels: false
+IndentPPDirectives: None
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+InsertTrailingCommas: None
+# Java-specific
+#JavaImportGroups:
+# JavaScript-specific
+#JavaScriptQuotes:
+#JavaScriptWrapImports
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ""
+MacroBlockEnd: ""
+# Set to a large number to effectively disable
+MaxEmptyLinesToKeep: 100000
+NamespaceIndentation: None
+NamespaceMacros: []
+# Objective C-specific
+#ObjCBinPackProtocolList:
+#ObjCBlockIndentWidth:
+#ObjCBreakBeforeNestedBlockParam:
+#ObjCSpaceAfterProperty:
+#ObjCSpaceBeforeProtocolList
+PenaltyBreakAssignment: 1
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 1
+PenaltyBreakFirstLessLess: 1
+PenaltyBreakString: 1
+PenaltyBreakTemplateDeclaration: 1
+PenaltyExcessCharacter: 1
+PenaltyReturnTypeOnItsOwnLine: 1
+# Used as a fallback if alignment style can't be detected from code (DerivePointerAlignment: true)
+PointerAlignment: Right
+RawStringFormats: []
+ReflowComments: false
+SortIncludes: false
+SortUsingDeclarations: false
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+StatementMacros: []
+TabWidth: 2
+TypenameMacros: []
+# Default to LF if line endings can't be detected from the content (DeriveLineEnding).
+UseCRLF: false
+UseTab: Never
+WhitespaceSensitiveMacros: []
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino
new file mode 100644
index 0000000..af0d7db
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino
@@ -0,0 +1,207 @@
+/*
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * Author: Brendan Doherty (2bndy5)
+ */
+
+/**
+ * A simple example of sending data from 1 nRF24L01 transceiver to another
+ * with Acknowledgement (ACK) payloads attached to ACK packets.
+ *
+ * This example was written to be used on 2 devices acting as "nodes".
+ * Use the Serial Monitor to change each node's behavior.
+ */
+#include <SPI.h>
+#include "printf.h"
+#include "RF24.h"
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// an identifying device destination
+// Let these addresses be used for the pair
+uint8_t address[][6] = { "1Node", "2Node" };
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+// to use different addresses on a pair of radios, we need a variable to
+
+// uniquely identify which address this radio will use to transmit
+bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
+
+// Used to control whether this node is sending or receiving
+bool role = false; // true = TX role, false = RX role
+
+// For this example, we'll be using a payload containing
+// a string & an integer number that will be incremented
+// on every successful transmission.
+// Make a data structure to store the entire payload of different datatypes
+struct PayloadStruct {
+ char message[7]; // only using 6 characters for TX & ACK payloads
+ uint8_t counter;
+};
+PayloadStruct payload;
+
+void setup() {
+
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/AcknowledgementPayloads"));
+
+ // To set the radioNumber via the Serial monitor on startup
+ Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+ char input = Serial.parseInt();
+ radioNumber = input == 1;
+ Serial.print(F("radioNumber = "));
+ Serial.println((int)radioNumber);
+
+ // role variable is hardcoded to RX behavior, inform the user of this
+ Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity to
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // to use ACK payloads, we need to enable dynamic payload lengths (for all nodes)
+ radio.enableDynamicPayloads(); // ACK payloads are dynamically sized
+
+ // Acknowledgement packets have no payloads by default. We need to enable
+ // this feature for all nodes (TX & RX) to use ACK payloads.
+ radio.enableAckPayload();
+
+ // set the TX address of the RX node for use on the TX pipe (pipe 0)
+ radio.stopListening(address[radioNumber]); // put radio in TX mode
+
+ // set the RX address of the TX node into a RX pipe
+ radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
+
+ // additional setup specific to the node's role
+ if (role) {
+ // setup the TX payload
+ memcpy(payload.message, "Hello ", 6); // set the payload message
+ } else {
+ // setup the ACK payload & load the first response into the FIFO
+
+ memcpy(payload.message, "World ", 6); // set the payload message
+ // load the payload for the first received transmission on pipe 0
+ radio.writeAckPayload(1, &payload, sizeof(payload));
+
+ radio.startListening(); // put radio in RX mode
+ }
+
+ // For debugging info
+ // printf_begin(); // needed only once for printing details
+ // radio.printDetails(); // (smaller) function that prints raw register values
+ // radio.printPrettyDetails(); // (larger) function that prints human readable data
+}
+
+void loop() {
+
+ if (role) {
+ // This device is a TX node
+
+ unsigned long start_timer = micros(); // start the timer
+ bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
+ unsigned long end_timer = micros(); // end the timer
+
+ if (report) {
+ Serial.print(F("Transmission successful! ")); // payload was delivered
+ Serial.print(F("Time to transmit = "));
+ Serial.print(end_timer - start_timer); // print the timer result
+ Serial.print(F(" us. Sent: "));
+ Serial.print(payload.message); // print the outgoing message
+ Serial.print(payload.counter); // print the outgoing counter
+ uint8_t pipe;
+ if (radio.available(&pipe)) { // is there an ACK payload? grab the pipe number that received it
+ PayloadStruct received;
+ radio.read(&received, sizeof(received)); // get incoming ACK payload
+ Serial.print(F(" Received "));
+ Serial.print(radio.getDynamicPayloadSize()); // print incoming payload size
+ Serial.print(F(" bytes on pipe "));
+ Serial.print(pipe); // print pipe number that received the ACK
+ Serial.print(F(": "));
+ Serial.print(received.message); // print incoming message
+ Serial.println(received.counter); // print incoming counter
+
+ // save incoming counter & increment for next outgoing
+ payload.counter = received.counter + 1;
+
+ } else {
+ Serial.println(F(" Received: an empty ACK packet")); // empty ACK packet received
+ }
+
+
+ } else {
+ Serial.println(F("Transmission failed or timed out")); // payload was not delivered
+ }
+
+ // to make this example readable in the serial monitor
+ delay(1000); // slow transmissions down by 1 second
+
+ } else {
+ // This device is a RX node
+
+ uint8_t pipe;
+ if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
+ uint8_t bytes = radio.getDynamicPayloadSize(); // get the size of the payload
+ PayloadStruct received;
+ radio.read(&received, sizeof(received)); // get incoming payload
+ Serial.print(F("Received "));
+ Serial.print(bytes); // print the size of the payload
+ Serial.print(F(" bytes on pipe "));
+ Serial.print(pipe); // print the pipe number
+ Serial.print(F(": "));
+ Serial.print(received.message); // print incoming message
+ Serial.print(received.counter); // print incoming counter
+ Serial.print(F(" Sent: "));
+ Serial.print(payload.message); // print outgoing message
+ Serial.println(payload.counter); // print outgoing counter
+
+ // save incoming counter & increment for next outgoing
+ payload.counter = received.counter + 1;
+ // load the payload for the first received transmission on pipe 0
+ radio.writeAckPayload(1, &payload, sizeof(payload));
+ }
+ } // role
+
+ if (Serial.available()) {
+ // change the role via the serial monitor
+
+ char c = toupper(Serial.read());
+ if (c == 'T' && !role) {
+ // Become the TX node
+
+ role = true;
+ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
+
+ memcpy(payload.message, "Hello ", 6); // change payload message
+ radio.stopListening(); // this also discards any unused ACK payloads
+
+ } else if (c == 'R' && role) {
+ // Become the RX node
+
+ role = false;
+ Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
+ memcpy(payload.message, "World ", 6); // change payload message
+
+ // load the payload for the first received transmission on pipe 0
+ radio.writeAckPayload(1, &payload, sizeof(payload));
+ radio.startListening();
+ }
+ }
+} // loop
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/GettingStarted/GettingStarted.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/GettingStarted/GettingStarted.ino
new file mode 100644
index 0000000..8273457
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/GettingStarted/GettingStarted.ino
@@ -0,0 +1,154 @@
+/*
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * Author: Brendan Doherty (2bndy5)
+ */
+
+/**
+ * A simple example of sending data from 1 nRF24L01 transceiver to another.
+ *
+ * This example was written to be used on 2 devices acting as "nodes".
+ * Use the Serial Monitor to change each node's behavior.
+ */
+#include <SPI.h>
+#include "printf.h"
+#include "RF24.h"
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// Let these addresses be used for the pair
+uint8_t address[][6] = { "1Node", "2Node" };
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+
+// to use different addresses on a pair of radios, we need a variable to
+// uniquely identify which address this radio will use to transmit
+bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
+
+// Used to control whether this node is sending or receiving
+bool role = false; // true = TX role, false = RX role
+
+// For this example, we'll be using a payload containing
+// a single float number that will be incremented
+// on every successful transmission
+float payload = 0.0;
+
+void setup() {
+
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/GettingStarted"));
+
+ // To set the radioNumber via the Serial monitor on startup
+ Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+ char input = Serial.parseInt();
+ radioNumber = input == 1;
+ Serial.print(F("radioNumber = "));
+ Serial.println((int)radioNumber);
+
+ // role variable is hardcoded to RX behavior, inform the user of this
+ Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity to
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // save on transmission time by setting the radio to only transmit the
+ // number of bytes we need to transmit a float
+ radio.setPayloadSize(sizeof(payload)); // float datatype occupies 4 bytes
+
+ // set the TX address of the RX node for use on the TX pipe (pipe 0)
+ radio.stopListening(address[radioNumber]); // put radio in TX mode
+
+ // set the RX address of the TX node into a RX pipe
+ radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
+
+ // additional setup specific to the node's RX role
+ if (!role) {
+ radio.startListening(); // put radio in RX mode
+ }
+
+ // For debugging info
+ // printf_begin(); // needed only once for printing details
+ // radio.printDetails(); // (smaller) function that prints raw register values
+ // radio.printPrettyDetails(); // (larger) function that prints human readable data
+
+} // setup
+
+void loop() {
+
+ if (role) {
+ // This device is a TX node
+
+ unsigned long start_timer = micros(); // start the timer
+ bool report = radio.write(&payload, sizeof(float)); // transmit & save the report
+ unsigned long end_timer = micros(); // end the timer
+
+ if (report) {
+ Serial.print(F("Transmission successful! ")); // payload was delivered
+ Serial.print(F("Time to transmit = "));
+ Serial.print(end_timer - start_timer); // print the timer result
+ Serial.print(F(" us. Sent: "));
+ Serial.println(payload); // print payload sent
+ payload += 0.01; // increment float payload
+ } else {
+ Serial.println(F("Transmission failed or timed out")); // payload was not delivered
+ }
+
+ // to make this example readable in the serial monitor
+ delay(1000); // slow transmissions down by 1 second
+
+ } else {
+ // This device is a RX node
+
+ uint8_t pipe;
+ if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
+ uint8_t bytes = radio.getPayloadSize(); // get the size of the payload
+ radio.read(&payload, bytes); // fetch payload from FIFO
+ Serial.print(F("Received "));
+ Serial.print(bytes); // print the size of the payload
+ Serial.print(F(" bytes on pipe "));
+ Serial.print(pipe); // print the pipe number
+ Serial.print(F(": "));
+ Serial.println(payload); // print the payload's value
+ }
+ } // role
+
+ if (Serial.available()) {
+ // change the role via the serial monitor
+
+ char c = toupper(Serial.read());
+ if (c == 'T' && !role) {
+ // Become the TX node
+
+ role = true;
+ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
+ radio.stopListening();
+
+ } else if (c == 'R' && role) {
+ // Become the RX node
+
+ role = false;
+ Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
+ radio.startListening();
+ }
+ }
+
+} // loop
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/InterruptConfigure/InterruptConfigure.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/InterruptConfigure/InterruptConfigure.ino
new file mode 100644
index 0000000..9d59759
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/InterruptConfigure/InterruptConfigure.ino
@@ -0,0 +1,353 @@
+/*
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * Author: Brendan Doherty (2bndy5)
+ */
+
+/**
+ * This example uses Acknowledgement (ACK) payloads attached to ACK packets to
+ * demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be
+ * configured to detect when data is received, or when data has transmitted
+ * successfully, or when data has failed to transmit.
+ *
+ * This example was written to be used on 2 devices acting as "nodes".
+ * Use the Serial Monitor to change each node's behavior.
+ */
+#include <SPI.h>
+#include "printf.h"
+#include "RF24.h"
+
+// We will be using the nRF24L01's IRQ pin for this example
+#define IRQ_PIN 2 // this needs to be a digital input capable pin
+volatile bool got_interrupt = false; // used to signal processing of interrupt
+volatile bool wait_for_event = false; // used to wait for an IRQ event to trigger
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// Let these addresses be used for the pair
+uint8_t address[][6] = { "1Node", "2Node" };
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+
+// to use different addresses on a pair of radios, we need a variable to
+// uniquely identify which address this radio will use to transmit
+bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
+
+// Used to control whether this node is sending or receiving
+bool role = false; // true = TX node, false = RX node
+
+// For this example, we'll be using a payload containing
+// a string that changes on every transmission. (successful or not)
+// Make a couple arrays of payloads & an iterator to traverse them
+const uint8_t tx_pl_size = 5;
+const uint8_t ack_pl_size = 4;
+uint8_t pl_iterator = 0;
+// The " + 1" compensates for the c-string's NULL terminating 0
+char tx_payloads[][tx_pl_size + 1] = { "Ping ", "Pong ", "Radio", "1FAIL" };
+char ack_payloads[][ack_pl_size + 1] = { "Yak ", "Back", " ACK" };
+
+void interruptHandler(); // prototype to handle IRQ events
+void printRxFifo(); // prototype to print RX FIFO with 1 buffer
+
+
+void setup() {
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/InterruptConfigure"));
+
+ // To set the radioNumber via the Serial monitor on startup
+ Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+ char input = Serial.parseInt();
+ radioNumber = input == 1;
+ Serial.print(F("radioNumber = "));
+ Serial.println((int)radioNumber);
+
+ // role variable is hardcoded to RX behavior, inform the user of this
+ Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
+
+ // setup the IRQ_PIN
+ pinMode(IRQ_PIN, INPUT);
+ attachInterrupt(digitalPinToInterrupt(IRQ_PIN), interruptHandler, FALLING);
+ // IMPORTANT: do not call radio.available() before calling
+ // radio.whatHappened() when the interruptHandler() is triggered by the
+ // IRQ pin FALLING event. According to the datasheet, the pipe information
+ // is unreliable during the IRQ pin FALLING transition.
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity to
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // For this example we use acknowledgment (ACK) payloads to trigger the
+ // IRQ pin when data is received on the TX node.
+ // to use ACK payloads, we need to enable dynamic payload lengths
+ radio.enableDynamicPayloads(); // ACK payloads are dynamically sized
+
+ // Acknowledgement packets have no payloads by default. We need to enable
+ // this feature for all nodes (TX & RX) to use ACK payloads.
+ radio.enableAckPayload();
+
+ // set the TX address of the RX node for use on the TX pipe (pipe 0)
+ radio.stopListening(address[radioNumber]); // put radio in TX mode
+
+ // set the RX address of the TX node into a RX pipe
+ radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
+
+ // additional setup specific to the node's RX role
+ if (!role) {
+ // setup for RX mode
+
+ // let IRQ pin only trigger on "data_ready" event in RX mode
+ radio.setStatusFlags(RF24_RX_DR);
+
+ // Fill the TX FIFO with 3 ACK payloads for the first 3 received
+ // transmissions on pipe 1
+ radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size);
+ radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size);
+ radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size);
+
+ radio.startListening(); // put radio in RX mode
+ }
+
+ // For debugging info
+ // printf_begin(); // needed only once for printing details
+ // radio.printDetails(); // (smaller) function that prints raw register values
+ // radio.printPrettyDetails(); // (larger) function that prints human readable data
+}
+
+void loop() {
+ if (got_interrupt) {
+ assessInterruptEvent();
+ }
+
+ if (role && !wait_for_event) {
+
+ // This device is a TX node. This if block is only triggered when
+ // NOT waiting for an IRQ event to happen
+
+ if (pl_iterator == 0) {
+ // Test the "data ready" event with the IRQ pin
+
+ Serial.println(F("\nConfiguring IRQ pin to ignore the 'data sent' event"));
+ radio.setStatusFlags(RF24_RX_DR | RF24_TX_DF);
+ Serial.println(F(" Pinging RX node for 'data ready' event..."));
+
+ } else if (pl_iterator == 1) {
+ // Test the "data sent" event with the IRQ pin
+
+ Serial.println(F("\nConfiguring IRQ pin to ignore the 'data ready' event"));
+ radio.setStatusFlags(RF24_TX_DS | RF24_TX_DF);
+ Serial.println(F(" Pinging RX node for 'data sent' event..."));
+
+ } else if (pl_iterator == 2) {
+ // Use this iteration to fill the RX node's FIFO which sets us up for the next test.
+
+ // write() uses virtual interrupt flags that work despite the masking of the IRQ pin
+ // disable IRQ pin for this step
+ radio.setStatusFlags();
+
+ Serial.println(F("\nSending 1 payload to fill RX node's FIFO. IRQ pin is neglected."));
+ // write() will call flush_tx() on 'data fail' events
+ if (radio.write(&tx_payloads[pl_iterator], tx_pl_size)) {
+ if (radio.rxFifoFull()) {
+ Serial.println(F("RX node's FIFO is full; it is not listening any more"));
+ } else {
+ Serial.println("Transmission successful, but the RX node might still be listening.");
+ }
+ } else {
+ Serial.println(F("Transmission failed or timed out. Continuing anyway."));
+ radio.flush_tx(); // discard payload(s) that failed to transmit
+ }
+
+ } else if (pl_iterator == 3) {
+ // test the "data fail" event with the IRQ pin
+
+ Serial.println(F("\nConfiguring IRQ pin to reflect all events"));
+ radio.setStatusFlags(RF24_IRQ_ALL);
+ Serial.println(F(" Pinging inactive RX node for 'data fail' event..."));
+ }
+
+ if (pl_iterator < 4 && pl_iterator != 2) {
+
+ // IRQ pin is LOW when activated. Otherwise it is always HIGH
+ // Wait until IRQ pin is activated.
+ wait_for_event = true;
+
+ // use the non-blocking call to write a payload and begin transmission
+ // the "false" argument means we are expecting an ACK packet response
+ radio.startFastWrite(tx_payloads[pl_iterator++], tx_pl_size, false);
+
+ // In this example, the "data fail" event is always configured to
+ // trigger the IRQ pin active. Because the auto-ACK feature is on by
+ // default, we don't need a timeout check to prevent an infinite loop.
+
+ } else if (pl_iterator == 4) {
+ // all IRQ tests are done; flush_tx() and print the ACK payloads for fun
+
+ // CE pin is still HIGH which consumes more power. Example is now idling so...
+ radio.stopListening(); // ensure CE pin is LOW
+ // stopListening() also calls flush_tx() when ACK payloads are enabled
+
+ printRxFifo();
+ pl_iterator++;
+
+
+ // inform user what to do next
+ Serial.println(F("\n*** PRESS 'T' to restart the transmissions"));
+ Serial.println(F("*** PRESS 'R' to change to Receive role\n"));
+
+
+ } else if (pl_iterator == 2) {
+ pl_iterator++; // proceed from step 3 to last step (stop at step 4 for readability)
+ }
+
+ } else if (!role && radio.rxFifoFull()) {
+ // This device is a RX node:
+ // wait until RX FIFO is full then stop listening
+
+ delay(100); // let ACK payload finish transmitting
+ radio.stopListening(); // also discards unused ACK payloads
+ printRxFifo(); // flush the RX FIFO
+
+ // Fill the TX FIFO with 3 ACK payloads for the first 3 received
+ // transmissions on pipe 1.
+ radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size);
+ radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size);
+ radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size);
+
+ delay(100); // let TX node finish its role
+ radio.startListening(); // We're ready to start over. Begin listening.
+
+ } // role
+
+ if (Serial.available()) {
+ // change the role via the serial monitor
+
+ char c = toupper(Serial.read());
+ if (c == 'T') {
+ // Become the TX node
+ if (!role)
+ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
+ else
+ Serial.println(F("*** RESTARTING IRQ PIN TEST ***"));
+
+ role = true;
+ wait_for_event = false;
+ pl_iterator = 0; // reset the iterator
+ radio.flush_tx(); // discard any payloads in the TX FIFO
+
+ // startListening() clears the IRQ masks also. This is required for
+ // continued TX operations when a transmission fails.
+ radio.stopListening(); // this also discards any unused ACK payloads
+
+ } else if (c == 'R' && role) {
+ // Become the RX node
+ Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
+
+ role = false;
+
+ // let IRQ pin only trigger on "data_ready" event in RX mode
+ radio.setStatusFlags(RF24_RX_DR);
+
+ // Fill the TX FIFO with 3 ACK payloads for the first 3 received
+ // transmissions on pipe 1
+ radio.flush_tx(); // make sure there is room for 3 new ACK payloads
+ radio.flush_rx(); // make sure there is room for 3 incoming payloads
+ radio.writeAckPayload(1, &ack_payloads[0], ack_pl_size);
+ radio.writeAckPayload(1, &ack_payloads[1], ack_pl_size);
+ radio.writeAckPayload(1, &ack_payloads[2], ack_pl_size);
+ radio.startListening();
+ }
+ } // Serial.available()
+} // loop
+
+
+/**
+ * when the IRQ pin goes active LOW.
+ * Here we just tell the main loop() to call `assessInterruptEve4nt()`.
+ */
+void interruptHandler() {
+ got_interrupt = true; // forward event handling back to main loop()
+}
+
+/**
+ * Called when an event has been triggered.
+ * Here, we want to verify the expected IRQ flag has been asserted.
+ */
+void assessInterruptEvent() {
+ // print IRQ status and all masking flags' states
+
+ Serial.println(F("\tIRQ pin is actively LOW")); // show that this function was called
+ delayMicroseconds(250);
+ uint8_t flags = radio.clearStatusFlags();
+ // Resetting the tx_df flag is required for
+ // continued TX operations when a transmission fails.
+ // clearing the status flags resets the IRQ pin to its inactive state (HIGH)
+
+ Serial.print(F("\tdata_sent: "));
+ Serial.print((flags & RF24_TX_DS) > 0); // print "data sent" flag state
+ Serial.print(F(", data_fail: "));
+ Serial.print((flags & RF24_TX_DF) > 0); // print "data fail" flag state
+ Serial.print(F(", data_ready: "));
+ Serial.println((flags & RF24_RX_DR) > 0); // print "data ready" flag state
+
+ if (flags & RF24_TX_DF) // if TX payload failed
+ radio.flush_tx(); // clear all payloads from the TX FIFO
+
+ // print if test passed or failed. Unintentional fails mean the RX node was not listening.
+ // pl_iterator has already been incremented by now
+ if (pl_iterator <= 1) {
+ Serial.print(F(" 'Data Ready' event test "));
+ Serial.println(flags & RF24_RX_DR ? F("passed") : F("failed"));
+ } else if (pl_iterator == 2) {
+ Serial.print(F(" 'Data Sent' event test "));
+ Serial.println(flags & RF24_TX_DS ? F("passed") : F("failed"));
+ } else if (pl_iterator == 4) {
+ Serial.print(F(" 'Data Fail' event test "));
+ Serial.println(flags & RF24_TX_DF ? F("passed") : F("failed"));
+ }
+ got_interrupt = false; // reset this flag to prevent calling this function from loop()
+ wait_for_event = false; // ready to continue with loop() operations
+}
+
+/**
+ * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO.
+ * Remember that the payload sizes are declared as tx_pl_size and ack_pl_size.
+ */
+void printRxFifo() {
+ if (radio.available()) { // if there is data in the RX FIFO
+ // to flush the data from the RX FIFO, we'll fetch it all using 1 buffer
+
+ uint8_t pl_size = !role ? tx_pl_size : ack_pl_size;
+ char rx_fifo[pl_size * 3 + 1]; // RX FIFO is full & we know ACK payloads' size
+ if (radio.rxFifoFull()) {
+ rx_fifo[pl_size * 3] = 0; // add a NULL terminating char to use as a c-string
+ radio.read(&rx_fifo, pl_size * 3); // this clears the RX FIFO (for this example)
+ } else {
+ uint8_t i = 0;
+ while (radio.available()) {
+ radio.read(&rx_fifo + (i * pl_size), pl_size);
+ i++;
+ }
+ rx_fifo[i * pl_size] = 0; // add a NULL terminating char to use as a c-string
+ }
+ Serial.print(F("Complete RX FIFO: "));
+ Serial.println(rx_fifo); // print the entire RX FIFO with 1 buffer
+ }
+}
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino
new file mode 100644
index 0000000..e4fbb38
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/ManualAcknowledgements/ManualAcknowledgements.ino
@@ -0,0 +1,222 @@
+/*
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * Author: Brendan Doherty (2bndy5)
+ */
+
+/**
+ * A simple example of sending data from 1 nRF24L01 transceiver to another
+ * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads.
+ * This example still uses ACK packets, but they have no payloads. Instead the
+ * acknowledging response is sent with `write()`. This tactic allows for more
+ * updated acknowledgement payload data, where actual ACK payloads' data are
+ * outdated by 1 transmission because they have to loaded before receiving a
+ * transmission.
+ *
+ * This example was written to be used on 2 devices acting as "nodes".
+ * Use the Serial Monitor to change each node's behavior.
+ */
+#include <SPI.h>
+#include "printf.h"
+#include "RF24.h"
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// Let these addresses be used for the pair
+uint8_t address[][6] = { "1Node", "2Node" };
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+
+// to use different addresses on a pair of radios, we need a variable to
+// uniquely identify which address this radio will use to transmit
+bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
+
+// Used to control whether this node is sending or receiving
+bool role = false; // true = TX node, false = RX node
+
+// For this example, we'll be using a payload containing
+// a string & an integer number that will be incremented
+// on every successful transmission.
+// Make a data structure to store the entire payload of different datatypes
+struct PayloadStruct {
+ char message[7]; // only using 6 characters for TX & RX payloads
+ uint8_t counter;
+};
+PayloadStruct payload;
+
+void setup() {
+
+ // append a NULL terminating character for printing as a c-string
+ payload.message[6] = 0;
+
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/ManualAcknowledgements"));
+
+ // To set the radioNumber via the Serial monitor on startup
+ Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+ char input = Serial.parseInt();
+ radioNumber = input == 1;
+ Serial.print(F("radioNumber = "));
+ Serial.println((int)radioNumber);
+
+ // role variable is hardcoded to RX behavior, inform the user of this
+ Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity to
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // save on transmission time by setting the radio to only transmit the
+ // number of bytes we need to transmit a float
+ radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes
+
+ // set the TX address of the RX node for use on the TX pipe (pipe 0)
+ radio.stopListening(address[radioNumber]); // put radio in TX mode
+
+ // set the RX address of the TX node into a RX pipe
+ radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
+
+ if (role) {
+ // setup the TX node
+
+ memcpy(payload.message, "Hello ", 6); // set the outgoing message
+ } else {
+ // setup the RX node
+
+ memcpy(payload.message, "World ", 6); // set the outgoing message
+ radio.startListening(); // put radio in RX mode
+ }
+
+ // For debugging info
+ // printf_begin(); // needed only once for printing details
+ // radio.printDetails(); // (smaller) function that prints raw register values
+ // radio.printPrettyDetails(); // (larger) function that prints human readable data
+
+} // setup()
+
+void loop() {
+
+ if (role) {
+ // This device is a TX node
+
+ unsigned long start_timer = micros(); // start the timer
+ bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
+
+ if (report) {
+ // transmission successful; wait for response and print results
+
+ radio.startListening(); // put in RX mode
+ unsigned long start_timeout = millis(); // timer to detect timeout
+ while (!radio.available()) { // wait for response
+ if (millis() - start_timeout > 200) // only wait 200 ms
+ break;
+ delayMicroseconds(200); // relax probing of available()
+ }
+ unsigned long end_timer = micros(); // end the timer
+ radio.stopListening(); // put back in TX mode
+
+ // print summary of transactions
+ Serial.print(F("Transmission successful!")); // payload was delivered
+ uint8_t pipe;
+ if (radio.available(&pipe)) { // is there a payload received
+ Serial.print(F(" Round-trip delay: "));
+ Serial.print(end_timer - start_timer); // print the timer result
+ Serial.print(F(" us. Sent: "));
+ Serial.print(payload.message); // print the outgoing payload's message
+ Serial.print(payload.counter); // print outgoing payload's counter
+ PayloadStruct received;
+ radio.read(&received, sizeof(received)); // get payload from RX FIFO
+ Serial.print(F(" Received "));
+ Serial.print(radio.getPayloadSize()); // print the size of the payload
+ Serial.print(F(" bytes on pipe "));
+ Serial.print(pipe); // print the pipe number
+ Serial.print(F(": "));
+ Serial.print(received.message); // print the incoming payload's message
+ Serial.println(received.counter); // print the incoming payload's counter
+ payload.counter = received.counter; // save incoming counter for next outgoing counter
+ } else {
+ Serial.println(F(" Received no response.")); // no response received
+ }
+ } else {
+ Serial.println(F("Transmission failed or timed out")); // payload was not delivered
+ } // report
+
+ // to make this example readable in the serial monitor
+ delay(1000); // slow transmissions down by 1 second
+
+ } else {
+ // This device is a RX node
+
+ uint8_t pipe;
+ if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
+ PayloadStruct received;
+ radio.read(&received, sizeof(received)); // get incoming payload
+ payload.counter = received.counter + 1; // increment incoming counter for next outgoing response
+
+ // transmit response & save result to `report`
+ radio.stopListening(); // put in TX mode
+
+ radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO
+ bool report = radio.txStandBy(150); // keep retrying for 150 ms
+
+ radio.startListening(); // put back in RX mode
+
+ // print summary of transactions
+ Serial.print(F("Received "));
+ Serial.print(radio.getPayloadSize()); // print the size of the payload
+ Serial.print(F(" bytes on pipe "));
+ Serial.print(pipe); // print the pipe number
+ Serial.print(F(": "));
+ Serial.print(received.message); // print incoming message
+ Serial.print(received.counter); // print incoming counter
+
+ if (report) {
+ Serial.print(F(" Sent: "));
+ Serial.print(payload.message); // print outgoing message
+ Serial.println(payload.counter); // print outgoing counter
+ } else {
+ Serial.println(" Response failed."); // failed to send response
+ }
+ }
+ } // role
+
+ if (Serial.available()) {
+ // change the role via the serial monitor
+
+ char c = toupper(Serial.read());
+ if (c == 'T' && !role) {
+ // Become the TX node
+
+ role = true;
+ memcpy(payload.message, "Hello ", 6); // set the outgoing message
+ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
+ radio.stopListening(); // put in TX mode
+
+ } else if (c == 'R' && role) {
+ // Become the RX node
+
+ role = false;
+ memcpy(payload.message, "World ", 6); // set the response message
+ Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
+ radio.startListening(); // put in RX mode
+ }
+ }
+} // loop
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino
new file mode 100644
index 0000000..99295bf
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/MulticeiverDemo/MulticeiverDemo.ino
@@ -0,0 +1,194 @@
+/*
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * Author: Brendan Doherty 2bndy5
+ */
+
+/**
+ * A simple example of sending data from as many as 6 nRF24L01 transceivers to
+ * 1 receiving transceiver. This technique is trademarked by
+ * Nordic Semiconductors as "MultiCeiver".
+ *
+ * This example was written to be used on up to 6 devices acting as TX nodes &
+ * only 1 device acting as the RX node (that's a maximum of 7 devices).
+ * Use the Serial Monitor to change each node's behavior.
+ */
+#include <SPI.h>
+#include "printf.h"
+#include "RF24.h"
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// For this example, we'll be using 6 addresses; 1 for each TX node
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+// Notice that the last byte is the only byte that changes in the last 5
+// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5
+// because they use the same first 4 MSBytes from pipe 1.
+uint8_t address[6][5] = { { 0x78, 0x78, 0x78, 0x78, 0x78 },
+ { 0xF1, 0xB6, 0xB5, 0xB4, 0xB3 },
+ { 0xCD, 0xB6, 0xB5, 0xB4, 0xB3 },
+ { 0xA3, 0xB6, 0xB5, 0xB4, 0xB3 },
+ { 0x0F, 0xB6, 0xB5, 0xB4, 0xB3 },
+ { 0x05, 0xB6, 0xB5, 0xB4, 0xB3 } };
+
+// role variable is used to control whether this node is sending or receiving
+char role = 'R'; // integers 0-5 = TX node; character 'R' or integer 82 = RX node
+
+// For this example, we'll be using a payload containing
+// a node ID number and a single integer number that will be incremented
+// on every successful transmission.
+// Make a data structure to use as a payload.
+struct PayloadStruct {
+ unsigned long nodeID;
+ unsigned long payloadID;
+};
+PayloadStruct payload;
+
+// This example uses all 6 pipes to receive while TX nodes only use 2 pipes
+// To make this easier we'll use a function to manage the addresses, and the
+// payload's nodeID
+void setRole(); // declare a prototype; definition is found after the loop()
+
+void setup() {
+
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/MulticeiverDemo"));
+ Serial.println(F("*** Enter a number between 0 and 5 (inclusive) to change"));
+ Serial.println(F(" the identifying node number that transmits."));
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity of
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // save on transmission time by setting the radio to only transmit the
+ // number of bytes we need to transmit a float
+ radio.setPayloadSize(sizeof(payload)); // 2x int datatype occupy 8 bytes
+
+ // Set the pipe addresses accordingly. This function additionally also
+ // calls startListening() or stopListening() and sets the payload's nodeID
+ setRole();
+
+ // For debugging info
+ // printf_begin(); // needed only once for printing details
+ // radio.printDetails(); // (smaller) function that prints raw register values
+ // radio.printPrettyDetails(); // (larger) function that prints human readable data
+
+} // setup()
+
+void loop() {
+
+ if (role <= 53) {
+ // This device is a TX node
+
+ unsigned long start_timer = micros(); // start the timer
+ bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
+ unsigned long end_timer = micros(); // end the timer
+
+ if (report) {
+ // payload was delivered
+
+ Serial.print(F("Transmission of payloadID "));
+ Serial.print(payload.payloadID); // print payloadID
+ Serial.print(F(" as node "));
+ Serial.print(payload.nodeID); // print nodeID
+ Serial.print(F(" successful!"));
+ Serial.print(F(" Time to transmit: "));
+ Serial.print(end_timer - start_timer); // print the timer result
+ Serial.println(F(" us"));
+ } else {
+ Serial.println(F("Transmission failed or timed out")); // payload was not delivered
+ }
+ payload.payloadID++; // increment payload number
+
+ // to make this example readable in the serial monitor
+ delay(1000); // slow transmissions down by 1 second
+
+ } else if (role == 'R') {
+ // This device is the RX node
+
+ uint8_t pipe;
+ if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
+ uint8_t bytes = radio.getPayloadSize(); // get the size of the payload
+ radio.read(&payload, bytes); // fetch payload from FIFO
+ Serial.print(F("Received "));
+ Serial.print(bytes); // print the size of the payload
+ Serial.print(F(" bytes on pipe "));
+ Serial.print(pipe); // print the pipe number
+ Serial.print(F(" from node "));
+ Serial.print(payload.nodeID); // print the payload's origin
+ Serial.print(F(". PayloadID: "));
+ Serial.println(payload.payloadID); // print the payload's number
+ }
+ } // role
+
+ if (Serial.available()) {
+ // change the role via the serial monitor
+
+ char c = Serial.read();
+ if (toupper(c) == 'R' && role <= 53) {
+ // Become the RX node
+
+ role = 'R';
+ Serial.println(F("*** CHANGING ROLE TO RECEIVER ***"));
+ Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to act as"));
+ Serial.println(F(" a unique node number that transmits to the RX node."));
+ setRole(); // change address on all pipes to TX nodes
+
+ } else if (c >= 48 && c <= 53 && c != role) {
+ // Become a TX node with identifier 'c'
+
+ role = c - 48;
+ Serial.print(F("*** CHANGING ROLE TO NODE "));
+ Serial.print(c);
+ Serial.println(F(" ***"));
+ Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to change"));
+ Serial.println(F(" the identifying node number that transmits."));
+ Serial.println(F("--- PRESS 'R' to act as the RX node."));
+ setRole(); // change address on pipe 0 to the RX node
+ }
+ }
+
+} // loop
+
+void setRole() {
+ if (role == 'R') {
+ // For the RX node
+
+ // Set the addresses for all pipes to TX nodes
+ for (uint8_t i = 0; i < 6; ++i)
+ radio.openReadingPipe(i, address[i]);
+
+ radio.startListening(); // put radio in RX mode
+
+ } else {
+ // For the TX node
+
+ // set the payload's nodeID & reset the payload's identifying number
+ payload.nodeID = role;
+ payload.payloadID = 0;
+
+ // set the TX address of the RX node for use on the TX pipe (pipe 0)
+ radio.stopListening(address[role]); // put radio in TX mode
+
+ // According to the datasheet, the auto-retry features's delay value should
+ // be "skewed" to allow the RX node to receive 1 transmission at a time.
+ // So, use varying delay between retry attempts and 15 (at most) retry attempts
+ radio.setRetries(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args
+ }
+} // setRole
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/StreamingData/StreamingData.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/StreamingData/StreamingData.ino
new file mode 100644
index 0000000..e4a4bc6
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/StreamingData/StreamingData.ino
@@ -0,0 +1,192 @@
+/*
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * Author: Brendan Doherty 2bndy5
+ */
+
+/**
+ * A simple example of streaming data from 1 nRF24L01 transceiver to another.
+ *
+ * This example was written to be used on 2 devices acting as "nodes".
+ * Use the Serial Monitor to change each node's behavior.
+ */
+#include <SPI.h>
+#include "printf.h"
+#include "RF24.h"
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// Let these addresses be used for the pair
+uint8_t address[][6] = { "1Node", "2Node" };
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+
+// to use different addresses on a pair of radios, we need a variable to
+// uniquely identify which address this radio will use to transmit
+bool radioNumber; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
+
+// Used to control whether this node is sending or receiving
+bool role = false; // true = TX node, false = RX node
+
+// For this example, we'll be sending 32 payloads each containing
+// 32 bytes of data that looks like ASCII art when printed to the serial
+// monitor. The TX node and RX node needs only a single 32 byte buffer.
+#define SIZE 32 // this is the maximum for this example. (minimum is 1)
+char buffer[SIZE + 1]; // for the RX node
+uint8_t counter = 0; // for counting the number of received payloads
+void makePayload(uint8_t); // prototype to construct a payload dynamically
+
+
+void setup() {
+
+ buffer[SIZE] = 0; // add a NULL terminating character (for easy printing)
+
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/StreamingData"));
+
+ // To set the radioNumber via the Serial monitor on startup
+ Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+ char input = Serial.parseInt();
+ radioNumber = input == 1;
+ Serial.print(F("radioNumber = "));
+ Serial.println((int)radioNumber);
+
+ // role variable is hardcoded to RX behavior, inform the user of this
+ Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity to
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // save on transmission time by setting the radio to only transmit the
+ // number of bytes we need to transmit
+ radio.setPayloadSize(SIZE); // default value is the maximum 32 bytes
+
+ // set the TX address of the RX node for use on the TX pipe (pipe 0)
+ radio.stopListening(address[radioNumber]); // put radio in TX mode
+
+ // set the RX address of the TX node into a RX pipe
+ radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
+
+ // additional setup specific to the node's RX role
+ if (!role) {
+ radio.startListening(); // put radio in RX mode
+ }
+
+ // For debugging info
+ // printf_begin(); // needed only once for printing details
+ // radio.printDetails(); // (smaller) function that prints raw register values
+ // radio.printPrettyDetails(); // (larger) function that prints human readable data
+
+} // setup()
+
+
+void loop() {
+
+ if (role) {
+ // This device is a TX node
+
+ radio.flush_tx();
+ uint8_t i = 0;
+ uint8_t failures = 0;
+ unsigned long start_timer = micros(); // start the timer
+ while (i < SIZE) {
+ makePayload(i); // make the payload
+ if (!radio.writeFast(&buffer, SIZE)) {
+ uint8_t flags = radio.getStatusFlags();
+ if (flags & RF24_TX_DF) {
+ failures++;
+ // now we need to reset the tx_df flag and the radio's CE pin
+ radio.ce(LOW);
+ radio.clearStatusFlags(RF24_TX_DF);
+ radio.ce(HIGH);
+ }
+ // else the TX FIFO is full; just continue loop.
+ } else {
+ i++;
+ }
+
+ if (failures >= 100) {
+ Serial.print(F("Too many failures detected. Aborting at payload "));
+ Serial.println(buffer[0]);
+ break;
+ }
+ }
+ unsigned long end_timer = micros(); // end the timer
+
+ Serial.print(F("Time to transmit = "));
+ Serial.print(end_timer - start_timer); // print the timer result
+ Serial.print(F(" us with "));
+ Serial.print(failures); // print failures detected
+ Serial.println(F(" failures detected"));
+
+ // to make this example readable in the serial monitor
+ delay(1000); // slow transmissions down by 1 second
+
+ } else {
+ // This device is a RX node
+
+ if (radio.available()) { // is there a payload?
+ radio.read(&buffer, SIZE); // fetch payload from FIFO
+ Serial.print(F("Received: "));
+ Serial.print(buffer); // print the payload's value
+ Serial.print(F(" - "));
+ Serial.println(counter++); // print the received counter
+ }
+ } // role
+
+ if (Serial.available()) {
+ // change the role via the serial monitor
+
+ char c = toupper(Serial.read());
+ if (c == 'T' && !role) {
+ // Become the TX node
+
+ role = true;
+ counter = 0; //reset the RX node's counter
+ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
+ radio.stopListening();
+
+ } else if (c == 'R' && role) {
+ // Become the RX node
+
+ role = false;
+ Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
+ radio.startListening();
+ }
+ }
+
+} // loop
+
+
+void makePayload(uint8_t i) {
+ // Make a single payload based on position in stream.
+ // This example employs function to save memory on certain boards.
+
+ // let the first character be an identifying alphanumeric prefix
+ // this lets us see which payload didn't get received
+ buffer[0] = i + (i < 26 ? 65 : 71);
+ for (uint8_t j = 0; j < SIZE - 1; ++j) {
+ char chr = j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - i);
+ chr |= j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - i);
+ buffer[j + 1] = chr + 48;
+ }
+}
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino
new file mode 100644
index 0000000..6aee593
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/encodeRadioDetails.ino
@@ -0,0 +1,123 @@
+/*
+ See documentation at https://nRF24.github.io/RF24
+ See License information at root directory of this library
+ Authors: Brendan Doherty (2bndy5), Douglas Quigg (dstroy0)
+*/
+
+/**
+ A simple example of getting debug info from the nRF24L01 transceiver.
+
+ This example was written to demonstrate alternative methods to get debugging data.
+ 1. radio.encodeRadioDetails() will provide a data dump of all the nRF24L01's registers.
+ 2. radio.sprintfPrettyDetails() will behave similarly to printPrettyDetails(), but it
+ outputs to a char buffer that can be printed to any Serial (or other output) stream.
+
+ Additionally, this example will show all default configuration values.
+*/
+#include <SPI.h>
+#include "RF24.h"
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+/*
+ For this example, we'll be using a data buffer containing
+ radio details encoded with RF24::encodeRadioDetails().
+ It is meant to be decoded by an external program.
+
+ There is a python script located in this example's folder that
+ will take a space-delimited string of hexadecimal characters and
+ decode then print it out as human readable information.
+*/
+uint8_t encoded_details[43] = { 0 };
+
+// Use this function to print out the encoded_details as a
+// space-delimited string of hexadecimal characters.
+void dumpRegData() {
+ for (uint8_t i = 0; i < 43; ++i) {
+ Serial.print(encoded_details[i], HEX);
+ if (i < 42)
+ Serial.print(F(" "));
+ }
+}
+
+void setup() {
+
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need to wait to ensure access to serial over USB
+ }
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware is not responding!!"));
+ while (1) {} // hold in infinite loop
+ }
+
+ // print example's introductory prompt
+ Serial.println(F("RF24/examples/encodedRadioDetails"));
+
+ Serial.println(F("Press any key to show debugging information"));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+
+ // For debugging info
+ char *debug_info = new char[870];
+ uint16_t str_len = radio.sprintfPrettyDetails(debug_info);
+ Serial.println(debug_info);
+ Serial.print(F("\nThe above output used "));
+ Serial.print(str_len);
+ Serial.println(F(" characters."));
+
+ // encoded_details is NOT human readable.
+ // encodeRadioDetails() is very small when used on its own because it puts debugging information into a byte array
+ // No printf() support needed because it doesn't use an output stream.
+ radio.encodeRadioDetails(encoded_details);
+ Serial.println(F("\nhexadecimal dump of all registers:"));
+ dumpRegData();
+
+ Serial.println(F("\n\nCopy the above string of hexadecimal characters (including spaces)."));
+ Serial.print(F("Then paste it into a terminal using the print_details.py located in"));
+ Serial.print(F(" this example's folder. Like so:\npython print_details.py \""));
+ dumpRegData();
+ Serial.println(F("\"\n***You may need to use 'python3' (without quotes) on Linux"));
+} // setup
+
+/* Registers corresponding to index of encoded_details array
+ 0: NRF_CONFIG
+ 1: EN_AA
+ 2: EN_RXADDR
+ 3: SETUP_AW
+ 4: SETUP_RETR
+ 5: RF_CH
+ 6: RF_SETUP
+ 7: NRF_STATUS
+ 8: OBSERVE_TX
+ 9: CD (aka RPD)
+ 10-14: RX_ADDR_P0
+ 15-19: RX_ADDR_P1
+ 20: RX_ADDR_P2
+ 21: RX_ADDR_P3
+ 22: RX_ADDR_P4
+ 23: RX_ADDR_P5
+ 24-28: TX_ADDR
+ 29: RX_PW_P0
+ 30: RX_PW_P1
+ 31: RX_PW_P2
+ 32: RX_PW_P3
+ 33: RX_PW_P4
+ 34: RX_PW_P5
+ 35: FIFO_STATUS
+ 36: DYNPD
+ 37: FEATURE
+ 38-39: ce_pin
+ 40-41: csn_pin
+ 42: SPI speed MHz | (isPlusVariant << 4)
+*/
+
+void loop() {
+ // Nothing to do here. We did it all at the end of setup()
+}
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/print_details.py b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/print_details.py
new file mode 100644
index 0000000..2d09e2c
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/encodeRadioDetails/print_details.py
@@ -0,0 +1,196 @@
+"""A simple script to take all data dumped from the nRF24L01 registers and
+output it in human readable form.
+
+Example usage:
+ print_details.py "0e 3f 02 03 00 02 00 0e"
+
+Notes:
+ * The radio's power state is represented under the assumption that
+ the radio's CE pin is inactive low.
+"""
+# pylint: disable=consider-using-f-string
+import struct
+import argparse
+
+
+def hex_str_to_bytes(s_in: str) -> bytes:
+ """Used to convert a string from CLI to a bytearray object.
+
+ .. warning:: This function assumes that the string consists of only
+ hexadecimal characters.
+ """
+ return bytes([int(i, 16) for i in s_in.split()])
+
+
+argparser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+)
+argparser.add_argument(
+ "buffer",
+ type=hex_str_to_bytes,
+ help="The encoded buffer from the Arduino Serial Monitor. The string passed is "
+ "expected to contain only hexadecimal digits. It should be 38 words long "
+ "(separated by spaces).",
+)
+
+
+def address_repr(buf, reverse: bool = True, delimit: str = "") -> str:
+ """Convert a buffer into a hexadecimal string."""
+ order = range(len(buf) - 1, -1, -1) if reverse else range(len(buf))
+ return delimit.join(["%02X" % buf[byte] for byte in order])
+
+
+# pylint: disable=too-many-locals,too-many-statements
+def print_details(encoded_buf: bytearray):
+ """This debugging function outputs all details about the nRF24L01."""
+ # declare sequences
+ pipes = [bytearray(5)] * 2 + [0] * 4
+ pl_len = [0] * 6
+
+ # unpack bytearray
+ (
+ config, # 0x00
+ auto_ack, # 0x01
+ open_pipes, # 0x02
+ addr_len, # 0x03
+ retry_setup, # 0x04
+ channel, # 0x05
+ rf_setup, # 0x06
+ status, # 0x07
+ observer, # 0x08
+ rpd, # 0x09
+ ) = struct.unpack("10B", encoded_buf[:10])
+ pipes[0] = encoded_buf[10:15] # 0x0A
+ pipes[1] = encoded_buf[15:20] # 0x0B
+ (
+ pipes[2], # 0x0C
+ pipes[3], # 0x0D
+ pipes[4], # 0x0E
+ pipes[5], # 0x0F
+ ) = struct.unpack("4B", encoded_buf[20:24])
+ tx_address = encoded_buf[24:29] # 0x10
+ (
+ pl_len[0], # 0x11
+ pl_len[1], # 0x12
+ pl_len[2], # 0x13
+ pl_len[3], # 0x14
+ pl_len[4], # 0x15
+ pl_len[5], # 0x16
+ fifo, # 0x17
+ dyn_pl, # 0x1C
+ features, # 0x1D
+ ) = struct.unpack("9B", encoded_buf[29:38])
+ ce_pin, csn_pin, spi_speed = struct.unpack(">2H1B", encoded_buf[38:44])
+
+ # do some deciphering arithmetic
+ addr_len += 2
+ crc = (2 if config & 4 else 1) if auto_ack else max(0, ((config & 0x0C) >> 2) - 1)
+ d_rate = rf_setup & 0x28
+ d_rate = (2 if d_rate == 8 else 250) if d_rate else 1
+ pa_level = (3 - ((rf_setup & 6) >> 1)) * -6
+ pa_level = (
+ "MIN"
+ if pa_level == -18
+ else ("LOW" if pa_level == -12 else ("HIGH" if pa_level == -6 else "MAX"))
+ )
+ dyn_p = (
+ ("_Enabled" if dyn_pl else "Disabled")
+ if dyn_pl == 0x3F or not dyn_pl
+ else "0b" + "0" * (8 - len(bin(dyn_pl))) + bin(dyn_pl)[2:]
+ )
+ auto_ack = (
+ ("Enabled" if auto_ack else "Disabled")
+ if auto_ack == 0x3F or not auto_ack
+ else "0b" + "0" * (8 - len(bin(auto_ack))) + bin(auto_ack)[2:]
+ )
+ pwr = "Standby" if config & 2 else "Off"
+ is_plus_variant = bool(spi_speed >> 4)
+ spi_speed = spi_speed & 0xF
+
+ # print it all out
+ print("CE pin____________________{}".format(ce_pin))
+ print("CSN pin___________________{}".format(csn_pin))
+ print("SPI speed_________________{} MHz".format(spi_speed))
+ print("Is a plus variant_________{}".format(is_plus_variant))
+ print(
+ "Channel___________________{}".format(channel),
+ "~ {} GHz".format((channel + 2400) / 1000),
+ )
+ print(
+ "RF Data Rate______________{}".format(d_rate),
+ "Mbps" if d_rate != 250 else "Kbps",
+ )
+ print("RF Power Amplifier________PA_{}".format(pa_level))
+ print(
+ "RF Low Noise Amplifier____{}abled".format(
+ "En" if bool(rf_setup & 1) else "Dis"
+ )
+ )
+ print("CRC Length________________{} bits".format(crc * 8))
+ print("Address length____________{} bytes".format(addr_len))
+ print("TX Payload lengths________{} bytes".format(pl_len[0]))
+ print(
+ "Auto retry delay__________{} microseconds".format(
+ ((retry_setup & 0xF0) >> 4) * 250 + 250
+ )
+ )
+ print("Auto retry attempts_______{} maximum".format(retry_setup & 0x0F))
+ print("Re-use TX FIFO____________{}".format(bool(fifo & 64)))
+ print("Received Power Detected___{}".format(bool(rpd)))
+ print(
+ "Packets lost on current channel_____________________{}".format(observer >> 4)
+ )
+ print(
+ "Retry attempts made for last transmission___________{}".format(observer & 0xF)
+ )
+ print(
+ "IRQ on Data Ready__{}abled".format("Dis" if config & 64 else "_En"),
+ " Data Ready___________{}".format(bool(status & 0x40)),
+ )
+ print(
+ "IRQ on Data Sent___{}abled".format("Dis" if config & 32 else "_En"),
+ " Data Sent____________{}".format(bool(status & 0x20)),
+ )
+ print(
+ "IRQ on Data Fail___{}abled".format("Dis" if config & 16 else "_En"),
+ " Data Failed__________{}".format(bool(status & 0x10)),
+ )
+ print(
+ "TX FIFO full__________{}e".format("_Tru" if fifo & 0x20 else "Fals"),
+ " TX FIFO empty________{}".format(bool(fifo & 0x10)),
+ )
+ print(
+ "RX FIFO full__________{}e".format("_Tru" if fifo & 2 else "Fals"),
+ " RX FIFO empty________{}".format(bool(fifo & 1)),
+ )
+ print(
+ "Multicast__________{}ed Custom ACK Payload___{}abled".format(
+ "_Allow" if features & 1 else "Disabl",
+ "En" if features & 2 else "Dis",
+ ),
+ )
+ print("Dynamic Payloads___{} Auto Acknowledgment__{}".format(dyn_p, auto_ack))
+ print(
+ "Primary Mode_____________{}X".format("R" if config & 1 else "T"),
+ " Power Mode___________{}".format(pwr),
+ )
+ print("TX address____________ 0x{}".format(address_repr(tx_address)))
+ for i in range(6):
+ is_open = open_pipes & (1 << i)
+ address = pipes[i] if i < 2 else bytes([pipes[i]]) + pipes[1][1:]
+ print(
+ "Pipe {} ({}) bound: 0x{}".format(
+ i, " open " if is_open else "closed", address_repr(address)
+ ),
+ )
+ if is_open and not dyn_pl & (1 << i):
+ print("\t\texpecting {} byte static payloads".format(pl_len[i]))
+
+
+# pylint: enable=too-many-locals,too-many-statements
+
+
+if __name__ == "__main__":
+ args = argparser.parse_args()
+ print_details(args.buffer)
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino
new file mode 100644
index 0000000..1b6695f
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/GettingStarted_HandlingFailures/GettingStarted_HandlingFailures.ino
@@ -0,0 +1,217 @@
+
+/*
+ Getting Started example sketch for nRF24L01+ radios
+ This is a very basic example of how to send data from one node to another
+ but modified to include failure handling.
+
+ The nrf24l01+ radios are fairly reliable devices, but on breadboards etc, with inconsistent wiring, failures may
+ occur randomly after many hours to days or weeks. This sketch demonstrates how to handle the various failures and
+ keep the radio operational.
+
+ The three main failure modes of the radio include:
+ Writing to radio: Radio unresponsive - Fixed internally by adding a timeout to the internal write functions in RF24 (failure handling)
+ Reading from radio: Available returns true always - Fixed by adding a timeout to available functions by the user. This is implemented internally in RF24Network.
+ Radio configuration settings are lost - Fixed by monitoring a value that is different from the default, and re-configuring the radio if this setting reverts to the default.
+
+ The printDetails output should appear as follows for radio #0:
+
+ STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
+ RX_ADDR_P0-1 = 0x65646f4e31 0x65646f4e32
+ RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
+ TX_ADDR = 0x65646f4e31
+ RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
+ EN_AA = 0x3f
+ EN_RXADDR = 0x02
+ RF_CH = 0x4c
+ RF_SETUP = 0x03
+ CONFIG = 0x0f
+ DYNPD/FEATURE = 0x00 0x00
+ Data Rate = 1MBPS
+ Model = nRF24L01+
+ CRC Length = 16 bits
+ PA Power = PA_LOW
+
+ Users can use this sketch to troubleshoot radio module wiring etc. as it makes the radios hot-swappable
+
+ Updated: 2019 by TMRh20
+*/
+
+#include <SPI.h>
+#include "RF24.h"
+#include "printf.h"
+
+/****************** User Config ***************************/
+/*** Set this radio as radio number 0 or 1 ***/
+bool radioNumber = 0;
+
+/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
+RF24 radio(7, 8);
+/**********************************************************/
+
+byte addresses[][6] = { "1Node", "2Node" };
+
+// Used to control whether this node is sending or receiving
+bool role = 0;
+
+
+/**********************************************************/
+//Function to configure the radio
+void configureRadio() {
+
+ radio.begin();
+
+ // Set the PA Level low to prevent power supply related issues since this is a
+ // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
+ radio.setPALevel(RF24_PA_LOW);
+
+ // Open a writing and reading pipe on each radio, with opposite addresses
+ if (radioNumber) {
+ radio.openWritingPipe(addresses[1]);
+ radio.openReadingPipe(1, addresses[0]);
+ } else {
+ radio.openWritingPipe(addresses[0]);
+ radio.openReadingPipe(1, addresses[1]);
+ }
+
+ // Start the radio listening for data
+ radio.startListening();
+ radio.printDetails();
+}
+
+
+/**********************************************************/
+
+void setup() {
+ Serial.begin(115200);
+ Serial.println(F("RF24/examples/GettingStarted"));
+ Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
+
+ printf_begin();
+
+ configureRadio();
+}
+
+uint32_t configTimer = millis();
+
+void loop() {
+
+ if (radio.failureDetected) {
+ radio.failureDetected = false;
+ delay(250);
+ Serial.println("Radio failure detected, restarting radio");
+ configureRadio();
+ }
+ // Every 5 seconds, verify the configuration of the radio. This can be
+ // done using any setting that is different from the radio defaults.
+ if (millis() - configTimer > 5000) {
+ configTimer = millis();
+ if (radio.getDataRate() != RF24_1MBPS) {
+ radio.failureDetected = true;
+ Serial.print("Radio configuration error detected");
+ }
+ }
+
+
+ /****************** Ping Out Role ***************************/
+
+ if (role == 1) {
+
+ radio.stopListening(); // First, stop listening so we can talk.
+
+ Serial.println(F("Now sending"));
+
+ unsigned long start_time = micros(); // Take the time, and send it. This will block until complete
+ if (!radio.write(&start_time, sizeof(unsigned long))) {
+ Serial.println(F("failed"));
+ }
+
+ radio.startListening(); // Now, continue listening
+
+ unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds
+ bool timeout = false; // Set up a variable to indicate if a response was received or not
+
+ while (!radio.available()) // While nothing is received
+ {
+ if (micros() - started_waiting_at > 200000) // If waited longer than 200ms, indicate timeout and exit while loop
+ {
+ timeout = true;
+ break;
+ }
+ }
+
+ if (timeout) {
+ // Describe the results
+ Serial.println(F("Failed, response timed out."));
+ } else {
+ // Grab the response, compare, and send to debugging spew
+
+ unsigned long got_time; // Variable for the received timestamp
+
+ // Failure Handling
+ uint32_t failTimer = millis();
+ while (radio.available()) // If available() always returns true, there is a problem
+ {
+ if (millis() - failTimer > 250) {
+ radio.failureDetected = true;
+ Serial.println("Radio available failure detected");
+ break;
+ }
+ radio.read(&got_time, sizeof(unsigned long));
+ }
+ unsigned long end_time = micros();
+
+ // Spew it
+ Serial.print(F("Sent "));
+ Serial.print(start_time);
+ Serial.print(F(", Got response "));
+ Serial.print(got_time);
+ Serial.print(F(", Round-trip delay "));
+ Serial.print(end_time - start_time);
+ Serial.println(F(" microseconds"));
+ }
+
+ delay(1000); // Try again 1s later
+ }
+
+
+ /****************** Pong Back Role ***************************/
+
+ if (role == 0) {
+ unsigned long got_time; // Variable for the received timestamp
+
+ if (radio.available()) {
+ uint32_t failTimer = millis();
+
+ while (radio.available()) // While there is data ready
+ {
+ if (millis() - failTimer > 500) {
+ Serial.println("Radio available failure detected");
+ radio.failureDetected = true;
+ break;
+ }
+ radio.read(&got_time, sizeof(unsigned long)); // Get the payload
+ }
+
+ radio.stopListening(); // First, stop listening so we can talk
+ radio.write(&got_time, sizeof(unsigned long)); // Send the final one back.
+ radio.startListening(); // Now, resume listening so we catch the next packets.
+ Serial.print(F("Sent response "));
+ Serial.println(got_time);
+ }
+ }
+
+
+ /****************** Change Roles via Serial Commands ***************************/
+
+ if (Serial.available()) {
+ char c = toupper(Serial.read());
+ if (c == 'T' && role == 0) {
+ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
+ role = 1; // Become the primary transmitter (ping out)
+ } else if (c == 'R' && role == 1) {
+ Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
+ role = 0; // Become the primary receiver (pong back)
+ radio.startListening();
+ }
+ }
+} // Loop
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino
new file mode 100644
index 0000000..2b831a8
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/TransferTimeouts/TransferTimeouts.ino
@@ -0,0 +1,185 @@
+/*
+ TMRh20 2014
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+*/
+
+/**
+ Reliably transmitting large volumes of data with a low signal or in noisy environments
+ This example demonstrates data transfer functionality with the use of auto-retry
+ and auto-reUse functionality enabled. This sketch demonstrates how a user can extend
+ the auto-retry functionality to any chosen time period, preventing data loss and ensuring
+ the consistency of data.
+
+ This sketch demonstrates use of the writeBlocking() functionality, and extends the standard
+ retry functionality of the radio. Payloads will be auto-retried until successful or the
+ extended timeout period is reached.
+*/
+
+
+
+#include <SPI.h>
+#include "nRF24L01.h"
+#include "RF24.h"
+#include "printf.h"
+
+/************* USER Configuration *****************************/
+
+RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
+unsigned long timeoutPeriod = 3000; // Set a user-defined timeout period. With auto-retransmit set to (15,15) retransmission will take up to 60ms and as little as 7.5ms with it set to (1,15).
+// With a timeout period of 1000, the radio will retry each payload for up to 1 second before giving up on the transmission and starting over
+
+/***************************************************************/
+
+const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
+
+byte data[32]; //Data buffer
+
+volatile unsigned long counter;
+unsigned long rxTimer, startTime, stopTime, payloads = 0;
+bool tx = 1, rx = 0, role = 0, transferInProgress = 0;
+
+
+void setup(void) {
+
+ Serial.begin(115200);
+ printf_begin();
+
+ radio.begin(); // Setup and configure rf radio
+ radio.setChannel(1); // Set the channel
+ radio.setPALevel(RF24_PA_LOW); // Set PA LOW for this demonstration. We want the radio to be as lossy as possible for this example.
+ radio.setDataRate(RF24_1MBPS); // Raise the data rate to reduce transmission distance and increase lossiness
+ radio.setAutoAck(1); // Ensure autoACK is enabled
+ radio.setRetries(2, 15); // Optionally, increase the delay between retries. Want the number of auto-retries as high as possible (15)
+ radio.setCRCLength(RF24_CRC_16); // Set CRC length to 16-bit to ensure quality of data
+ radio.openWritingPipe(pipes[0]); // Open the default reading and writing pipe
+ radio.openReadingPipe(1, pipes[1]);
+
+ radio.startListening(); // Start listening
+ radio.printDetails(); // Dump the configuration of the rf unit for debugging
+
+ printf("\n\rRF24/examples/Transfer Rates/\n\r");
+ printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
+
+ randomSeed(analogRead(0)); //Seed for random number generation
+ for (int i = 0; i < 32; i++) {
+ data[i] = random(255); //Load the buffer with random data
+ }
+ radio.powerUp(); //Power up the radio
+}
+
+
+
+void loop(void) {
+
+
+ if (role == tx) {
+ delay(2000); // Pause for a couple seconds between transfers
+ printf("Initiating Extended Timeout Data Transfer\n\r");
+
+ unsigned long cycles = 1000; // Change this to a higher or lower number. This is the number of payloads that will be sent.
+
+ unsigned long transferCMD[] = { 'H', 'S', cycles }; // Indicate to the other radio that we are starting, and provide the number of payloads that will be sent
+ radio.writeFast(&transferCMD, 12); // Send the transfer command
+ if (radio.txStandBy(timeoutPeriod)) { // If transfer initiation was successful, do the following
+
+ startTime = millis(); // For calculating transfer rate
+ boolean timedOut = 0; // Boolean for keeping track of failures
+
+ for (unsigned long i = 0; i < cycles; i++) // Loop through a number of cycles
+ {
+ data[0] = i; // Change the first byte of the payload for identification
+
+ if (!radio.writeBlocking(&data, 32, timeoutPeriod)) { // If retries are failing and the user defined timeout is exceeded
+ timedOut = 1; // Indicate failure
+ counter = cycles; // Set the fail count to maximum
+ break; // Break out of the for loop
+ }
+ }
+
+
+ stopTime = millis(); // Capture the time of completion or failure
+
+ //This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success
+ if (timedOut) {
+ radio.txStandBy(); //Partially blocking standby, blocks until success or max retries. FIFO flushed if auto timeout reached
+ } else {
+ radio.txStandBy(timeoutPeriod); //Standby, block until FIFO empty (sent) or user specified timeout reached. FIFO flushed if user timeout reached.
+ }
+
+ } else {
+ Serial.println("Communication not established"); //If unsuccessful initiating transfer, exit and retry later
+ }
+
+ float rate = cycles * 32 / (stopTime - startTime); //Display results:
+
+ Serial.print("Transfer complete at ");
+ Serial.print(rate);
+ Serial.println(" KB/s");
+ Serial.print(counter);
+ Serial.print(" of ");
+ Serial.print(cycles);
+ Serial.println(" Packets Failed to Send");
+ counter = 0;
+ }
+
+
+
+ if (role == rx) {
+
+ if (!transferInProgress) { // If a bulk data transfer has not been started
+ if (radio.available()) {
+ radio.read(&data, 32); //Read any available payloads for analysis
+
+ if (data[0] == 'H' && data[4] == 'S') { // If a bulk data transfer command has been received
+ payloads = data[8]; // Read the first two bytes of the unsigned long. Need to read the 3rd and 4th if sending more than 65535 payloads
+ payloads |= data[9] << 8; // This is the number of payloads that will be sent
+ counter = 0; // Reset the payload counter to 0
+ transferInProgress = 1; // Indicate it has started
+ startTime = rxTimer = millis(); // Capture the start time to measure transfer rate and calculate timeouts
+ }
+ }
+ } else {
+ if (radio.available()) { // If in bulk transfer mode, and a payload is available
+ radio.read(&data, 32); // Read the payload
+ rxTimer = millis(); // Reset the timeout timer
+ counter++; // Keep a count of received payloads
+ } else if (millis() - rxTimer > timeoutPeriod) { // If no data available, check the timeout period
+ Serial.println("Transfer Failed"); // If per-payload timeout exceeded, end the transfer
+ transferInProgress = 0;
+ } else if (counter >= payloads) { // If the specified number of payloads is reached, transfer is completed
+ startTime = millis() - startTime; // Calculate the total time spent during transfer
+ float numBytes = counter * 32; // Calculate the number of bytes transferred
+ Serial.print("Rate: "); // Print the transfer rate and number of payloads
+ Serial.print(numBytes / startTime);
+ Serial.println(" KB/s");
+ Serial.print("Payload Count: ");
+ Serial.println(counter);
+ transferInProgress = 0; // End the transfer as complete
+ }
+ }
+ }
+
+ //
+ // Change roles
+ //
+
+ if (Serial.available()) {
+ char c = toupper(Serial.read());
+ if (c == 'T' && role == rx) {
+ printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
+ radio.openWritingPipe(pipes[1]);
+ radio.openReadingPipe(1, pipes[0]);
+ radio.stopListening();
+ role = tx; // Become the primary transmitter (ping out)
+ } else if (c == 'R' && role == tx) {
+ radio.openWritingPipe(pipes[0]);
+ radio.openReadingPipe(1, pipes[1]);
+ radio.startListening();
+ printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
+ role = rx; // Become the primary receiver (pong back)
+ }
+ }
+}
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino
new file mode 100644
index 0000000..8df9524
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_dyn/pingpair_dyn.ino
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+/**
+ * Example using Dynamic Payloads
+ *
+ * This is an example of how to use payloads of a varying (dynamic) size.
+ */
+
+#include <SPI.h>
+#include "nRF24L01.h"
+#include "RF24.h"
+#include "printf.h"
+
+// Hardware configuration
+RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
+
+// Radio pipe addresses for the 2 nodes to communicate.
+const uint64_t addresses[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
+
+/************************* Role management ****************************/
+// Set up role. This sketch uses the same software for all the nodes in this
+// system. Doing so greatly simplifies testing.
+
+// The role_pin is a digital input pin used to set the role of this radio.
+// Connect the role_pin to GND to be the 'pong' receiver
+// Leave the role_pin open to be the 'ping' transmitter
+const short role_pin = 5; // use pin 5
+typedef enum { role_ping_out = 1,
+ role_pong_back } role_e; // The various roles supported by this sketch
+const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" }; // The debug-friendly names of those roles
+role_e role; // The role of the current running sketch
+
+
+// variables used for changing the payload size dynamically (used when role == role_ping_out)
+const int min_payload_size = 4;
+const int max_payload_size = 32;
+const int payload_size_increment = 1;
+int send_payload_size = min_payload_size;
+
+char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char
+
+void setup(void) {
+ pinMode(role_pin, INPUT); // set up the role pin
+ digitalWrite(role_pin, HIGH);
+ delay(20); // Just to get a solid reading on the role pin
+
+ // read the role_pin, establish our role
+ if (digitalRead(role_pin)) {
+ role = role_ping_out;
+ } else {
+ role = role_pong_back;
+ }
+
+ Serial.begin(115200);
+ printf_begin(); // needed for printDetails()
+
+ // Print preamble
+ Serial.println(F("RF24/examples/pingpair_dyn/"));
+ Serial.print(F("ROLE: "));
+ Serial.println(role_friendly_name[role]);
+
+ // Setup and configure rf radio
+ radio.begin();
+ radio.enableDynamicPayloads(); // Enable dynamic payloads
+ radio.setRetries(5, 15); // delay between retries = 5 * 250 + 250 = 1500 microseconds, number of retries = 15
+
+ // Open a writing and reading pipe on each radio, with opposite addresses
+ if (role == role_ping_out) {
+ radio.openWritingPipe(addresses[0]);
+ radio.openReadingPipe(1, addresses[1]);
+ } else {
+ radio.openWritingPipe(addresses[1]);
+ radio.openReadingPipe(1, addresses[0]);
+ }
+
+ radio.startListening(); // Start listening
+ radio.printDetails(); // Dump the configuration of the rf unit for debugging
+}
+
+void loop() {
+
+
+ /****************** Ping Out Role ***************************/
+
+ if (role == role_ping_out) {
+ // The payload will always be the same, what will change is how much of it we send.
+ static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012";
+
+ radio.stopListening(); // First, stop listening so we can talk.
+
+ // Send the payload
+ Serial.print(F("Now sending length "));
+ Serial.println(send_payload_size);
+ radio.write(send_payload, send_payload_size); // This will block until complete
+
+ radio.startListening(); // Now, continue listening
+
+ unsigned long started_waiting_at = millis(); // Start a timer for measuring timeout
+ bool timeout = false;
+ while (!radio.available() && !timeout) // Wait until we get a response or timeout is reached
+ {
+ if (millis() - started_waiting_at > 500) // Only wait for 500 milliseconds
+ timeout = true;
+ }
+
+ // Describe the results
+ if (timeout) {
+ Serial.println(F("Failed, response timed out."));
+ } else {
+ // Grab the response and print it
+
+ uint8_t len = radio.getDynamicPayloadSize(); // get payload's length
+
+ // If an illegal payload size was detected, all RX payloads will be flushed
+ if (!len)
+ return;
+
+ radio.read(receive_payload, len);
+
+ // Use payload as a C-string (for easy printing)
+ receive_payload[len] = 0; // put a NULL terminating zero at the end
+
+ // Spew it
+ Serial.print(F("Got response size="));
+ Serial.print(len);
+ Serial.print(F(" value="));
+ Serial.println(receive_payload);
+ }
+
+ send_payload_size += payload_size_increment; // Update size for next time.
+ if (send_payload_size > max_payload_size) // if payload length is larger than the radio can handle
+ send_payload_size = min_payload_size; // reset the payload length
+
+ delay(1000); // Try again 1s later
+ }
+
+
+ /****************** Pong Back Role ***************************/
+ // Receive each packet, send it back, and dump it out
+
+ if (role == role_pong_back) {
+ while (radio.available()) // if there is data ready
+ {
+
+ uint8_t len = radio.getDynamicPayloadSize(); // Fetch the the payload size
+
+ // If an illegal payload size was detected, all RX payloads will be flushed
+ if (!len)
+ continue;
+
+ radio.read(receive_payload, len);
+
+ // Use payload as a C-string (for easy printing)
+ receive_payload[len] = 0; // put a NULL terminating zero at the end
+
+ // Spew it
+ Serial.print(F("Got response size="));
+ Serial.print(len);
+ Serial.print(F(" value="));
+ Serial.println(receive_payload);
+
+ radio.stopListening(); // First, stop listening so we can talk
+
+ // Send a reply that the packet was received
+ //
+ // You will have better luck delivering your message if
+ // you wait for the other node to start listening first
+ delay(20);
+ radio.write(receive_payload, len);
+ Serial.println(F("Sent response."));
+
+ radio.startListening(); // Now, resume listening so we catch the next packets.
+ }
+ }
+} // loop
+// vim:cin:ai:sts=2 sw=2 ft=cpp
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino
new file mode 100644
index 0000000..19623cc
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_irq/pingpair_irq.ino
@@ -0,0 +1,173 @@
+/*
+ Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Update 2014 - TMRh20
+*/
+
+/**
+ Example of using interrupts
+
+ This is an example of how to user interrupts to interact with the radio, and a demonstration
+ of how to use them to sleep when receiving, and not miss any payloads.
+ The pingpair_sleepy example expands on sleep functionality with a timed sleep option for the transmitter.
+ Sleep functionality is built directly into my fork of the RF24Network library
+*/
+
+#include <SPI.h>
+#include "nRF24L01.h"
+#include "RF24.h"
+#include "printf.h"
+
+// Hardware configuration
+RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
+
+// Our ACK payload will simply be 4 bytes containing the number of payloads received
+static uint32_t message_count = 1; // start counting at 1
+
+// Demonstrates another method of setting up the addresses
+byte address[][5] = { 0xCC, 0xCE, 0xCC, 0xCE, 0xCC, 0xCE, 0xCC, 0xCE, 0xCC, 0xCE };
+
+/************************* Role management ****************************/
+// Set up role. This sketch uses the same software for all the nodes in this
+// system. Doing so greatly simplifies testing.
+
+// The role_pin is a digital input pin used to set the role of this radio.
+// Connect the role_pin to GND to be the 'pong' receiver
+// Leave the role_pin open to be the 'ping' transmitter
+const short role_pin = 5; // use pin 5
+typedef enum { role_sender = 1,
+ role_receiver } role_e; // The various roles supported by this sketch
+const char* role_friendly_name[] = { "invalid", "Sender", "Receiver" }; // The debug-friendly names of those roles
+role_e role; // The role of the current running sketch
+
+
+void setup() {
+
+ pinMode(role_pin, INPUT); // set up the role pin
+ digitalWrite(role_pin, HIGH); // Change this to LOW/HIGH instead of using an external pin
+ delay(20); // Just to get a solid reading on the role pin
+
+ if (digitalRead(role_pin)) // read the role_pin pin to establish our role
+ role = role_sender;
+ else
+ role = role_receiver;
+
+
+ Serial.begin(115200);
+ printf_begin(); // needed for printDetails()
+
+ // print introduction
+ Serial.print(F("\n\rRF24/examples/pingpair_irq\n\rROLE: "));
+ Serial.println(role_friendly_name[role]);
+
+
+ /********************** Setup and configure rf radio *********************/
+ radio.begin();
+
+ // Examples are usually run with both radios in close proximity to each other
+ radio.setPALevel(RF24_PA_LOW); // defaults to RF24_PA_MAX
+ radio.enableAckPayload(); // We will be using the ACK Payload feature which is not enabled by default
+ radio.enableDynamicPayloads(); // Ack payloads are dynamic payloads
+
+ // Open a writing and reading pipe on each radio, with opposite addresses
+ if (role == role_sender) {
+ radio.openWritingPipe(address[0]);
+ radio.openReadingPipe(1, address[1]);
+ } else {
+ radio.openWritingPipe(address[1]);
+ radio.openReadingPipe(1, address[0]);
+ radio.startListening(); // First we need to start listening
+
+ // Add an ACK payload for the first time around; 1 is the pipe number to acknowledge
+ radio.writeAckPayload(1, &message_count, sizeof(message_count));
+ ++message_count; // increment counter by 1 for next ACK payload
+ }
+
+ radio.printDetails(); // Dump the configuration of the rf unit for debugging
+ delay(50);
+
+ // Attach interrupt handler to interrupt #0 (using pin 2) on BOTH the sender and receiver
+ attachInterrupt(0, check_radio, LOW);
+} // setup
+
+
+void loop() {
+
+
+ /****************** Ping Out Role ***************************/
+
+ if (role == role_sender) {
+ // Repeatedly send the current time
+
+ unsigned long time = millis(); // Take the time
+ Serial.print(F("Now sending "));
+ Serial.println(time);
+ radio.startWrite(&time, sizeof(unsigned long), 0); // Send the time
+ delay(2000); // Try again soon (in 2 seconds)
+ }
+
+
+ /****************** Pong Back Role ***************************/
+ // Receiver does nothing! All the work is in Interrupt Handler
+
+ if (role == role_receiver) {}
+
+} // loop
+
+
+/********************** Interrupt Handler *********************/
+
+void check_radio(void) {
+
+ bool tx, fail, rx; // declare variables to store IRQ flags
+ radio.whatHappened(tx, fail, rx); // What happened?
+
+ if (tx) { // Have we successfully transmitted?
+ if (role == role_sender)
+ Serial.println(F("Send:OK"));
+ if (role == role_receiver)
+ Serial.println(F("Ack Payload:Sent"));
+ }
+
+ if (fail) { // Have we failed to transmit?
+ if (role == role_sender)
+ Serial.println(F("Send:Failed"));
+ if (role == role_receiver)
+ Serial.println(F("Ack Payload:Failed"));
+ }
+
+ if (rx || radio.available()) { // Did we receive a message?
+
+
+
+
+ /**************** Ping Out Role (about received ACK payload) ************************/
+ // If we're the sender, we've received an ack payload
+ if (role == role_sender) {
+ // Get the payload and dump it
+ radio.read(&message_count, sizeof(message_count));
+ Serial.print(F("Ack: "));
+ Serial.println(message_count);
+ }
+
+
+ /****************** Pong Back Role ***************************/
+ // If we're the receiver, we've received a time message
+ if (role == role_receiver) {
+ // Get the payload and dump it
+
+ static unsigned long got_time; // variable to hold the received time
+ radio.read(&got_time, sizeof(got_time)); // get the payload
+ Serial.print(F("Got payload "));
+ Serial.println(got_time);
+
+ // Add an ACK payload for the next time around; 1 is the pipe number to acknowledge
+ radio.writeAckPayload(1, &message_count, sizeof(message_count));
+ ++message_count; // increment packet counter
+ }
+ }
+} // check_radio
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino
new file mode 100644
index 0000000..8e32879
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_multi_dyn/pingpair_multi_dyn.ino
@@ -0,0 +1,252 @@
+/*
+ Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+*/
+
+/**
+ Example using Dynamic Payloads
+
+ This is an example of how to use payloads of a varying (dynamic) size.
+*/
+
+#include <SPI.h>
+#include "RF24.h"
+
+//
+// Hardware configuration
+//
+
+// Set up nRF24L01 radio on SPI bus plus pins 8 & 9
+RF24 radio(7, 8);
+
+// Use multicast?
+// sets the multicast behavior this unit in hardware. Connect to GND to use unicast
+// Leave open (default) to use multicast.
+const int multicast_pin = 6;
+
+// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
+// Leave open to be the 'ping' transmitter
+const int role_pin = 5;
+bool multicast = true;
+
+//
+// Topology
+//
+
+// Radio pipe addresses for the 2 nodes to communicate.
+const uint64_t pipes[2] = { 0xEEFAFDFDEELL, 0xEEFDFAF50DFLL };
+
+//
+// Role management
+//
+// Set up role. This sketch uses the same software for all the nodes
+// in this system. Doing so greatly simplifies testing. The hardware itself specifies
+// which node it is.
+//
+// This is done through the role_pin
+//
+
+// The various roles supported by this sketch
+typedef enum { role_ping_out = 1,
+ role_pong_back } role_e;
+
+// The debug-friendly names of those roles
+const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" };
+
+// The role of the current running sketch
+role_e role;
+
+//
+// Payload
+//
+
+const int min_payload_size = 1;
+const int max_payload_size = 32;
+const int payload_size_increments_by = 1;
+int next_payload_size = min_payload_size;
+
+char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char
+
+void setup(void) {
+ //
+ // Multicast
+ //
+ pinMode(multicast_pin, INPUT);
+ digitalWrite(multicast_pin, HIGH);
+ delay(20);
+
+ // read multicast role, LOW for unicast
+ if (digitalRead(multicast_pin))
+ multicast = true;
+ else
+ multicast = false;
+
+
+ //
+ // Role
+ //
+
+ // set up the role pin
+ pinMode(role_pin, INPUT);
+ digitalWrite(role_pin, HIGH);
+ delay(20); // Just to get a solid reading on the role pin
+
+ // read the address pin, establish our role
+ if (digitalRead(role_pin))
+ role = role_ping_out;
+ else
+ role = role_pong_back;
+
+ //
+ // Print preamble
+ //
+
+ Serial.begin(115200);
+
+ Serial.println(F("RF24/examples/pingpair_multi_dyn/"));
+ Serial.print(F("ROLE: "));
+ Serial.println(role_friendly_name[role]);
+
+ Serial.print(F("MULTICAST: "));
+ Serial.println(multicast ? F("true (unreliable)") : F("false (reliable)"));
+
+ //
+ // Setup and configure rf radio
+ //
+
+ radio.begin();
+
+ // enable dynamic payloads
+ radio.enableDynamicPayloads();
+ radio.setCRCLength(RF24_CRC_16);
+
+ // optionally, increase the delay between retries & # of retries
+ radio.setRetries(15, 5);
+ radio.setAutoAck(true);
+ //radio.setPALevel( RF24_PA_LOW ) ;
+
+ //
+ // Open pipes to other nodes for communication
+ //
+
+ // This simple sketch opens two pipes for these two nodes to communicate
+ // back and forth.
+ // Open 'our' pipe for writing
+ // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
+
+ if (role == role_ping_out) {
+ radio.openWritingPipe(pipes[0]);
+ radio.openReadingPipe(1, pipes[1]);
+ } else {
+ radio.openWritingPipe(pipes[1]);
+ radio.openReadingPipe(1, pipes[0]);
+ }
+
+ //
+ // Start listening
+ //
+ radio.powerUp();
+ radio.startListening();
+
+ //
+ // Dump the configuration of the rf unit for debugging
+ //
+
+ radio.printDetails();
+}
+
+void loop(void) {
+ //
+ // Ping out role. Repeatedly send the current time
+ //
+
+ if (role == role_ping_out) {
+ // The payload will always be the same, what will change is how much of it we send.
+ static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012";
+
+ // First, stop listening so we can talk.
+ radio.stopListening();
+
+ // Take the time, and send it. This will block until complete
+ Serial.print(F("Now sending length "));
+ Serial.println(next_payload_size);
+ radio.write(send_payload, next_payload_size, multicast);
+
+ // Now, continue listening
+ radio.startListening();
+
+ // Wait here until we get a response, or timeout
+ unsigned long started_waiting_at = millis();
+ bool timeout = false;
+ while (!radio.available() && !timeout)
+ if (millis() - started_waiting_at > 500)
+ timeout = true;
+
+ // Describe the results
+ if (timeout) {
+ Serial.println(F("Failed, response timed out."));
+ } else {
+ // Grab the response, compare, and send to debugging spew
+ uint8_t len = radio.getDynamicPayloadSize();
+ radio.read(receive_payload, len);
+
+ // Put a zero at the end for easy printing
+ receive_payload[len] = 0;
+
+ // Spew it
+ Serial.print(F("Got response size="));
+ Serial.print(len);
+ Serial.print(F(" value="));
+ Serial.println(receive_payload);
+ }
+
+ // Update size for next time.
+ next_payload_size += payload_size_increments_by;
+ if (next_payload_size > max_payload_size)
+ next_payload_size = min_payload_size;
+
+ // Try again 1s later
+ delay(250);
+ }
+
+ //
+ // Pong back role. Receive each packet, dump it out, and send it back
+ //
+
+ if (role == role_pong_back) {
+ // if there is data ready
+ if (radio.available()) {
+ // Dump the payloads until we've gotten everything
+ uint8_t len;
+ bool done = false;
+ while (radio.available()) {
+ // Fetch the payload, and see if this was the last one.
+ len = radio.getDynamicPayloadSize();
+ radio.read(receive_payload, len);
+
+ // Put a zero at the end for easy printing
+ receive_payload[len] = 0;
+
+ // Spew it
+ Serial.print(F("Got response size="));
+ Serial.print(len);
+ Serial.print(F(" value="));
+ Serial.println(receive_payload);
+ }
+
+ // First, stop listening so we can talk
+ radio.stopListening();
+
+ // Send the final one back.
+ radio.write(receive_payload, len, multicast);
+ Serial.println(F("Sent response."));
+
+ // Now, resume listening so we catch the next packets.
+ radio.startListening();
+ }
+ }
+}
+// vim:cin:ai:sts=2 sw=2 ft=cpp
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino
new file mode 100644
index 0000000..c3beec8
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/pingpair_sleepy/pingpair_sleepy.ino
@@ -0,0 +1,231 @@
+/*
+ Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ TMRh20 2014 - Updates to the library allow sleeping both in TX and RX modes:
+ TX Mode: The radio can be powered down (.9uA current) and the Arduino slept using the watchdog timer
+ RX Mode: The radio can be left in standby mode (22uA current) and the Arduino slept using an interrupt pin
+*/
+
+/**
+ Example RF Radio Ping Pair which Sleeps between Sends
+
+ This is an example of how to use the RF24 class to create a battery-
+ efficient system. It is just like the GettingStarted_CallResponse example, but the
+ ping node powers down the radio and sleeps the MCU after every
+ ping/pong cycle, and the receiver sleeps between payloads.
+
+ Write this sketch to two different nodes,
+ connect the role_pin to ground on one. The ping node sends the current
+ time to the pong node, which responds by sending the value back. The ping
+ node can then see how long the whole cycle took.
+*/
+
+#include <SPI.h>
+#include <avr/sleep.h>
+#include <avr/power.h>
+#include "nRF24L01.h"
+#include "RF24.h"
+#include "printf.h"
+
+
+// Set up nRF24L01 radio on SPI bus plus pins 7 & 8
+RF24 radio(7, 8);
+
+// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
+// Leave open to be the 'ping' transmitter
+const int role_pin = 5;
+
+const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // Radio pipe addresses for the 2 nodes to communicate.
+
+// Role management
+// Set up role. This sketch uses the same software for all the nodes
+// in this system. Doing so greatly simplifies testing. The hardware itself specifies
+// which node it is.
+
+// The various roles supported by this sketch
+typedef enum { role_ping_out = 1,
+ role_pong_back } role_e;
+
+// The debug-friendly names of those roles
+const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" };
+
+// The role of the current running sketch
+role_e role;
+
+
+// Sleep declarations
+typedef enum { wdt_16ms = 0,
+ wdt_32ms,
+ wdt_64ms,
+ wdt_128ms,
+ wdt_250ms,
+ wdt_500ms,
+ wdt_1s,
+ wdt_2s,
+ wdt_4s,
+ wdt_8s } wdt_prescalar_e;
+
+void setup_watchdog(uint8_t prescalar);
+void do_sleep(void);
+
+const short sleep_cycles_per_transmission = 4;
+volatile short sleep_cycles_remaining = sleep_cycles_per_transmission;
+
+
+
+void setup() {
+
+ // set up the role pin
+ pinMode(role_pin, INPUT);
+ digitalWrite(role_pin, HIGH);
+ delay(20); // Just to get a solid reading on the role pin
+
+ // read the address pin, establish our role
+ if (digitalRead(role_pin))
+ role = role_ping_out;
+ else
+ role = role_pong_back;
+
+ Serial.begin(115200);
+ printf_begin();
+ Serial.print(F("\n\rRF24/examples/pingpair_sleepy/\n\rROLE: "));
+ Serial.println(role_friendly_name[role]);
+
+ // Prepare sleep parameters
+ // Only the ping out role uses WDT. Wake up every 4s to send a ping
+ //if ( role == role_ping_out )
+ setup_watchdog(wdt_4s);
+
+ // Setup and configure rf radio
+
+ radio.begin();
+
+ // Open pipes to other nodes for communication
+
+ // This simple sketch opens two pipes for these two nodes to communicate
+ // back and forth.
+ // Open 'our' pipe for writing
+ // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
+
+ if (role == role_ping_out) {
+ radio.openWritingPipe(pipes[0]);
+ radio.openReadingPipe(1, pipes[1]);
+ } else {
+ radio.openWritingPipe(pipes[1]);
+ radio.openReadingPipe(1, pipes[0]);
+ }
+
+ // Start listening
+ radio.startListening();
+
+ // Dump the configuration of the rf unit for debugging
+ //radio.printDetails();
+}
+
+void loop() {
+
+
+ if (role == role_ping_out) { // Ping out role. Repeatedly send the current time
+ radio.powerUp(); // Power up the radio after sleeping
+ radio.stopListening(); // First, stop listening so we can talk.
+
+ unsigned long time = millis(); // Take the time, and send it.
+ Serial.print(F("Now sending... "));
+ Serial.println(time);
+
+ radio.write(&time, sizeof(unsigned long));
+
+ radio.startListening(); // Now, continue listening
+
+ unsigned long started_waiting_at = millis(); // Wait here until we get a response, or timeout (250ms)
+ bool timeout = false;
+ while (!radio.available()) {
+ if (millis() - started_waiting_at > 250) { // Break out of the while loop if nothing available
+ timeout = true;
+ break;
+ }
+ }
+
+ if (timeout) { // Describe the results
+ Serial.println(F("Failed, response timed out."));
+ } else {
+ unsigned long got_time; // Grab the response, compare, and send to debugging spew
+ radio.read(&got_time, sizeof(unsigned long));
+
+ printf("Got response %lu, round-trip delay: %lu\n\r", got_time, millis() - got_time);
+ }
+
+ // Shut down the system
+ delay(500); // Experiment with some delay here to see if it has an effect
+ // Power down the radio.
+ radio.powerDown(); // NOTE: The radio MUST be powered back up again manually
+
+ // Sleep the MCU.
+ do_sleep();
+ }
+
+
+ // Pong back role. Receive each packet, dump it out, and send it back
+ if (role == role_pong_back) {
+
+ if (radio.available()) { // if there is data ready
+
+ unsigned long got_time;
+ while (radio.available()) { // Dump the payloads until we've gotten everything
+ radio.read(&got_time, sizeof(unsigned long)); // Get the payload, and see if this was the last one.
+ // Spew it. Include our time, because the ping_out millis counter is unreliable
+ printf("Got payload %lu @ %lu...", got_time, millis()); // due to it sleeping
+ }
+
+ radio.stopListening(); // First, stop listening so we can talk
+ radio.write(&got_time, sizeof(unsigned long)); // Send the final one back.
+ Serial.println(F("Sent response."));
+ radio.startListening(); // Now, resume listening so we catch the next packets.
+ } else {
+ Serial.println(F("Sleeping"));
+ delay(50); // Delay so the serial data can print out
+ do_sleep();
+ }
+ }
+}
+
+void wakeUp() {
+ sleep_disable();
+}
+
+// Sleep helpers
+
+//Prescaler values
+// 0=16ms, 1=32ms,2=64ms,3=125ms,4=250ms,5=500ms
+// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
+
+void setup_watchdog(uint8_t prescalar) {
+
+ uint8_t wdtcsr = prescalar & 7;
+ if (prescalar & 8)
+ wdtcsr |= _BV(WDP3);
+ MCUSR &= ~_BV(WDRF); // Clear the WD System Reset Flag
+ WDTCSR = _BV(WDCE) | _BV(WDE); // Write the WD Change enable bit to enable changing the prescaler and enable system reset
+ WDTCSR = _BV(WDCE) | wdtcsr | _BV(WDIE); // Write the prescalar bits (how long to sleep, enable the interrupt to wake the MCU
+}
+
+ISR(WDT_vect) {
+ //--sleep_cycles_remaining;
+ Serial.println(F("WDT"));
+}
+
+void do_sleep(void) {
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
+ sleep_enable();
+ attachInterrupt(0, wakeUp, LOW);
+ WDTCSR |= _BV(WDIE);
+ sleep_mode(); // System sleeps here
+ // The WDT_vect interrupt wakes the MCU from here
+ sleep_disable(); // System continues execution here when watchdog timed out
+ detachInterrupt(0);
+ WDTCSR &= ~_BV(WDIE);
+}
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/led_remote/led_remote.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/led_remote/led_remote.ino
new file mode 100644
index 0000000..6ec865e
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/led_remote/led_remote.ino
@@ -0,0 +1,236 @@
+/*
+ Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+*/
+
+/**
+ Example LED Remote
+
+ This is an example of how to use the RF24 class to control a remote
+ bank of LED's using buttons on a remote control.
+
+ On the 'remote', connect any number of buttons or switches from
+ an arduino pin to ground. Update 'button_pins' to reflect the
+ pins used.
+
+ On the 'led' board, connect the same number of LED's from an
+ arduino pin to a resistor to ground. Update 'led_pins' to reflect
+ the pins used. Also connect a separate pin to ground and change
+ the 'role_pin'. This tells the sketch it's running on the LED board.
+
+ Every time the buttons change on the remote, the entire state of
+ buttons is send to the led board, which displays the state.
+*/
+
+#include <SPI.h>
+#include "nRF24L01.h"
+#include "RF24.h"
+#include "printf.h"
+
+//
+// Hardware configuration
+//
+
+// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 (CE & CS)
+
+RF24 radio(9, 10);
+
+// sets the role of this unit in hardware. Connect to GND to be the 'led' board receiver
+// Leave open to be the 'remote' transmitter
+const int role_pin = A4;
+
+// Pins on the remote for buttons
+const uint8_t button_pins[] = { 2, 3, 4, 5, 6, 7 };
+const uint8_t num_button_pins = sizeof(button_pins);
+
+// Pins on the LED board for LED's
+const uint8_t led_pins[] = { 2, 3, 4, 5, 6, 7 };
+const uint8_t num_led_pins = sizeof(led_pins);
+
+//
+// Topology
+//
+
+// Single radio pipe address for the 2 nodes to communicate.
+const uint64_t pipe = 0xE8E8F0F0E1LL;
+
+//
+// Role management
+//
+// Set up role. This sketch uses the same software for all the nodes in this
+// system. Doing so greatly simplifies testing. The hardware itself specifies
+// which node it is.
+//
+// This is done through the role_pin
+//
+
+// The various roles supported by this sketch
+typedef enum { role_remote = 1,
+ role_led } role_e;
+
+// The debug-friendly names of those roles
+const char* role_friendly_name[] = { "invalid", "Remote", "LED Board" };
+
+// The role of the current running sketch
+role_e role;
+
+//
+// Payload
+//
+
+uint8_t button_states[num_button_pins];
+uint8_t led_states[num_led_pins];
+
+//
+// Setup
+//
+
+void setup(void) {
+ //
+ // Role
+ //
+
+ // set up the role pin
+ pinMode(role_pin, INPUT);
+ digitalWrite(role_pin, HIGH);
+ delay(20); // Just to get a solid reading on the role pin
+
+ // read the address pin, establish our role
+ if (digitalRead(role_pin))
+ role = role_remote;
+ else
+ role = role_led;
+
+ //
+ // Print preamble
+ //
+
+ Serial.begin(115200);
+ printf_begin();
+ printf("\n\rRF24/examples/led_remote/\n\r");
+ printf("ROLE: %s\n\r", role_friendly_name[role]);
+
+ //
+ // Setup and configure rf radio
+ //
+
+ radio.begin();
+
+ //
+ // Open pipes to other nodes for communication
+ //
+
+ // This simple sketch opens a single pipes for these two nodes to communicate
+ // back and forth. One listens on it, the other talks to it.
+
+ if (role == role_remote) {
+ radio.openWritingPipe(pipe);
+ } else {
+ radio.openReadingPipe(1, pipe);
+ }
+
+ //
+ // Start listening
+ //
+
+ if (role == role_led)
+ radio.startListening();
+
+ //
+ // Dump the configuration of the rf unit for debugging
+ //
+
+ radio.printDetails();
+
+ //
+ // Set up buttons / LED's
+ //
+
+ // Set pull-up resistors for all buttons
+ if (role == role_remote) {
+ int i = num_button_pins;
+ while (i--) {
+ pinMode(button_pins[i], INPUT);
+ digitalWrite(button_pins[i], HIGH);
+ }
+ }
+
+ // Turn LED's ON until we start getting keys
+ if (role == role_led) {
+ int i = num_led_pins;
+ while (i--) {
+ pinMode(led_pins[i], OUTPUT);
+ led_states[i] = HIGH;
+ digitalWrite(led_pins[i], led_states[i]);
+ }
+ }
+}
+
+//
+// Loop
+//
+
+void loop(void) {
+ //
+ // Remote role. If the state of any button has changed, send the whole state of
+ // all buttons.
+ //
+
+ if (role == role_remote) {
+ // Get the current state of buttons, and
+ // Test if the current state is different from the last state we sent
+ int i = num_button_pins;
+ bool different = false;
+ while (i--) {
+ uint8_t state = !digitalRead(button_pins[i]);
+ if (state != button_states[i]) {
+ different = true;
+ button_states[i] = state;
+ }
+ }
+
+ // Send the state of the buttons to the LED board
+ if (different) {
+ printf("Now sending...");
+ bool ok = radio.write(button_states, num_button_pins);
+ if (ok)
+ printf("ok\n\r");
+ else
+ printf("failed\n\r");
+ }
+
+ // Try again in a short while
+ delay(20);
+ }
+
+ //
+ // LED role. Receive the state of all buttons, and reflect that in the LEDs
+ //
+
+ if (role == role_led) {
+ // if there is data ready
+ if (radio.available()) {
+ // Dump the payloads until we've gotten everything
+ while (radio.available()) {
+ // Fetch the payload, and see if this was the last one.
+ radio.read(button_states, num_button_pins);
+
+ // Spew it
+ printf("Got buttons\n\r");
+
+ // For each button, if the button now on, then toggle the LED
+ int i = num_led_pins;
+ while (i--) {
+ if (button_states[i]) {
+ led_states[i] ^= HIGH;
+ digitalWrite(led_pins[i], led_states[i]);
+ }
+ }
+ }
+ }
+ }
+}
+// vim:ai:cin:sts=2 sw=2 ft=cpp
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino
new file mode 100644
index 0000000..894d926
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/nordic_fob/nordic_fob.ino
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2012 J. Coliz <maniacbug@ymail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+*/
+
+/**
+ Example Nordic FOB Receiver
+
+ This is an example of how to use the RF24 class to receive signals from the
+ Sparkfun Nordic FOB. Thanks to Kirk Mower for providing test hardware.
+
+ See blog post at http://maniacbug.wordpress.com/2012/01/08/nordic-fob/
+*/
+
+#include <SPI.h>
+#include <RF24.h>
+#include "nRF24L01.h"
+#include "printf.h"
+
+//
+// Hardware configuration
+//
+
+// Set up nRF24L01 radio on SPI bus plus pins 9 & 10
+
+RF24 radio(9, 10);
+
+//
+// Payload
+//
+
+struct payload_t {
+ uint8_t buttons;
+ uint16_t id;
+ uint8_t empty;
+};
+
+const char* button_names[] = { "Up", "Down", "Left", "Right", "Center" };
+const int num_buttons = 5;
+
+//
+// Forward declarations
+//
+
+uint16_t flip_endian(uint16_t in);
+
+//
+// Setup
+//
+
+void setup(void) {
+ //
+ // Print preamble
+ //
+
+ Serial.begin(115200);
+ printf_begin();
+ printf("\r\nRF24/examples/nordic_fob/\r\n");
+
+ //
+ // Setup and configure rf radio according to the built-in parameters
+ // of the FOB.
+ //
+
+ radio.begin();
+ radio.setChannel(2);
+ radio.setPayloadSize(4);
+ radio.setAutoAck(false);
+ radio.setCRCLength(RF24_CRC_8);
+ radio.openReadingPipe(1, 0xE7E7E7E7E7LL);
+
+ //
+ // Start listening
+ //
+
+ radio.startListening();
+
+ //
+ // Dump the configuration of the rf unit for debugging
+ //
+
+ radio.printDetails();
+}
+
+//
+// Loop
+//
+
+void loop(void) {
+ //
+ // Receive each packet, dump it out
+ //
+
+ // if there is data ready
+ if (radio.available()) {
+ // Get the packet from the radio
+ payload_t payload;
+ radio.read(&payload, sizeof(payload));
+
+ // Print the ID of this message. Note that the message
+ // is sent 'big-endian', so we have to flip it.
+ printf("#%05u Buttons ", flip_endian(payload.id));
+
+ // Print the name of each button
+ int i = num_buttons;
+ while (i--) {
+ if (!(payload.buttons & _BV(i))) {
+ printf("%s ", button_names[i]);
+ }
+ }
+
+ // If no buttons, print None
+ if (payload.buttons == _BV(num_buttons) - 1)
+ printf("None");
+
+ printf("\r\n");
+ }
+}
+
+//
+// Helper functions
+//
+
+// Change a big-endian word into a little-endian
+uint16_t flip_endian(uint16_t in) {
+ uint16_t low = in >> 8;
+ uint16_t high = in << 8;
+
+ return high | low;
+}
+
+// vim:cin:ai:sts=2 sw=2 ft=cpp
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp
new file mode 100644
index 0000000..be3ea98
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/main.cpp
@@ -0,0 +1,77 @@
+#ifdef MAPLE_IDE
+
+#include <stdio.h>
+#include "wirish.h"
+
+extern void setup(void);
+extern void loop(void);
+
+void board_start(const char* program_name) {
+ // Set up the LED to steady on
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ digitalWrite(BOARD_LED_PIN, HIGH);
+
+ // Setup the button as input
+ pinMode(BOARD_BUTTON_PIN, INPUT);
+ digitalWrite(BOARD_BUTTON_PIN, HIGH);
+
+ SerialUSB.begin();
+ SerialUSB.println("Press BUT");
+
+ // Wait for button press
+ while (!isButtonPressed()) {
+ }
+
+ SerialUSB.println("Welcome!");
+ SerialUSB.println(program_name);
+
+ int i = 11;
+ while (i--) {
+ toggleLED();
+ delay(50);
+ }
+}
+
+/**
+ Custom version of _write, which will print to the USB.
+ In order to use it you MUST ADD __attribute__((weak))
+ to _write in libmaple/syscalls.c
+*/
+extern "C" int _write(int file, char* ptr, int len) {
+ if ((file != 1) && (file != 2))
+ return 0;
+ else
+ SerialUSB.write(ptr, len);
+ return len;
+}
+
+/**
+ Re-entrant version of _write. Yagarto and Devkit now use
+ the re-entrant newlib, so these get called instead of the
+ non_r versions.
+*/
+extern "C" int _write_r(void*, int file, char* ptr, int len) {
+ return _write(file, ptr, len);
+}
+
+__attribute__((constructor)) __attribute__((weak)) void premain() {
+ init();
+}
+
+__attribute__((weak)) void setup(void) {
+ board_start("No program defined");
+}
+
+__attribute__((weak)) void loop(void) {
+}
+
+__attribute__((weak)) int main(void) {
+ setup();
+
+ while (true) {
+ loop();
+ }
+ return 0;
+}
+#endif // ifdef MAPLE_IDE
+// vim:cin:ai:sts=2 sw=2 ft=cpp
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino
new file mode 100644
index 0000000..e1b0511
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/pingpair_maple/pingpair_maple.ino
@@ -0,0 +1,231 @@
+/*
+ Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+*/
+
+/**
+ Example RF Radio Ping Pair ... for Maple
+
+ This is an example of how to use the RF24 class. Write this sketch to two different nodes,
+ connect the role_pin to ground on one. The ping node sends the current time to the pong node,
+ which responds by sending the value back. The ping node can then see how long the whole cycle
+ took.
+*/
+
+#include "WProgram.h"
+#include <SPI.h>
+#include "nRF24L01.h"
+#include "RF24.h"
+
+//
+// Maple specific setup. Other than this section, the sketch is the same on Maple as on
+// Arduino
+//
+
+#ifdef MAPLE_IDE
+
+// External startup function
+extern void board_start(const char* program_name);
+
+// Use SPI #2.
+HardwareSPI SPI(2);
+
+#else
+#define board_startup printf
+#define toggleLED(x) (x)
+#endif
+
+//
+// Hardware configuration
+//
+
+// Set up nRF24L01 radio on SPI bus plus pins 7 & 6
+// (This works for the Getting Started board plugged into the
+// Maple Native backwards.)
+
+RF24 radio(7, 6);
+
+// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
+// Leave open to be the 'ping' transmitter
+const int role_pin = 10;
+
+//
+// Topology
+//
+
+// Radio pipe addresses for the 2 nodes to communicate.
+const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
+
+//
+// Role management
+//
+// Set up role. This sketch uses the same software for all the nodes
+// in this system. Doing so greatly simplifies testing. The hardware itself specifies
+// which node it is.
+//
+// This is done through the role_pin
+//
+
+// The various roles supported by this sketch
+typedef enum { role_ping_out = 1,
+ role_pong_back } role_e;
+
+// The debug-friendly names of those roles
+const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back" };
+
+// The role of the current running sketch
+role_e role;
+
+void setup(void) {
+ //
+ // Role
+ //
+
+ // set up the role pin
+ pinMode(role_pin, INPUT);
+ digitalWrite(role_pin, HIGH);
+ delay(20); // Just to get a solid reading on the role pin
+
+ // read the address pin, establish our role
+ if (digitalRead(role_pin))
+ role = role_ping_out;
+ else
+ role = role_pong_back;
+
+ //
+ // Print preamble
+ //
+
+ board_start("\n\rRF24/examples/pingpair/\n\r");
+ printf("ROLE: %s\n\r", role_friendly_name[role]);
+
+ //
+ // Setup and configure rf radio
+ //
+
+ radio.begin();
+
+ // optionally, increase the delay between retries & # of retries
+ radio.setRetries(15, 15);
+
+ // optionally, reduce the payload size. seems to
+ // improve reliability
+ radio.setPayloadSize(8);
+
+ //
+ // Open pipes to other nodes for communication
+ //
+
+ // This simple sketch opens two pipes for these two nodes to communicate
+ // back and forth.
+ // Open 'our' pipe for writing
+ // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
+
+ if (role == role_ping_out) {
+ radio.openWritingPipe(pipes[0]);
+ radio.openReadingPipe(1, pipes[1]);
+ } else {
+ radio.openWritingPipe(pipes[1]);
+ radio.openReadingPipe(1, pipes[0]);
+ }
+
+ //
+ // Start listening
+ //
+
+ radio.startListening();
+
+ //
+ // Dump the configuration of the rf unit for debugging
+ //
+
+ radio.printDetails();
+}
+
+void loop(void) {
+ //
+ // Ping out role. Repeatedly send the current time
+ //
+
+ if (role == role_ping_out) {
+ toggleLED();
+
+ // First, stop listening so we can talk.
+ radio.stopListening();
+
+ // Take the time, and send it. This will block until complete
+ unsigned long time = millis();
+ printf("Now sending %lu...", time);
+ bool ok = radio.write(&time, sizeof(unsigned long));
+
+ if (ok)
+ printf("ok...\r\n");
+ else
+ printf("failed.\r\n");
+
+ // Now, continue listening
+ radio.startListening();
+
+ // Wait here until we get a response, or timeout (250ms)
+ unsigned long started_waiting_at = millis();
+ bool timeout = false;
+ while (!radio.available() && !timeout)
+ if (millis() - started_waiting_at > 200)
+ timeout = true;
+
+ // Describe the results
+ if (timeout) {
+ printf("Failed, response timed out.\r\n");
+ } else {
+ // Grab the response, compare, and send to debugging spew
+ unsigned long got_time;
+ radio.read(&got_time, sizeof(unsigned long));
+
+ // Spew it
+ printf("Got response %lu, round-trip delay: %lu\r\n", got_time, millis() - got_time);
+ }
+
+ toggleLED();
+
+ // Try again 1s later
+ delay(1000);
+ }
+
+ //
+ // Pong back role. Receive each packet, dump it out, and send it back
+ //
+
+ if (role == role_pong_back) {
+ // if there is data ready
+ if (radio.available()) {
+ // Dump the payloads until we've gotten everything
+ unsigned long got_time;
+ bool done = false;
+ while (!done) {
+ // Fetch the payload, and see if this was the last one.
+ done = radio.read(&got_time, sizeof(unsigned long));
+
+ // Spew it
+ printf("Got payload %lu...", got_time);
+
+ // Delay just a little bit to let the other unit
+ // make the transition to receiver
+ delay(20);
+ }
+
+ // First, stop listening so we can talk
+ radio.stopListening();
+
+ // Send the final one back.
+ radio.write(&got_time, sizeof(unsigned long));
+ printf("Sent response.\r\n");
+
+ // Now, resume listening so we catch the next packets.
+ radio.startListening();
+ }
+ }
+}
+// vim:cin:ai:sts=2 sw=2 ft=cpp
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/readme.md b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/readme.md
new file mode 100644
index 0000000..c4b3fbb
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/old_backups/recipes/readme.md
@@ -0,0 +1,7 @@
+# Recipes
+
+> [!note]
+> These recipe examples may have not been maintained with library updates, and are provided as-is for reference purposes.
+
+> [!warning]
+> These are recipe examples are intended for specific hardware usage.
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino
new file mode 100644
index 0000000..4c5faf3
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/rf24ping85/rf24ping85.ino
@@ -0,0 +1,204 @@
+/**
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * written in 2014 by tong67 (https://github.com/tong67)
+ * Updated 2020 by 2bndy5 (http://github.com/2bndy5) for the
+ * SpenceKonde ATTinyCore (https://github.com/SpenceKonde/ATTinyCore)
+ */
+
+/**
+ * The RF24 library uses the [ATTinyCore by
+ * SpenceKonde](https://github.com/SpenceKonde/ATTinyCore)
+ *
+ * This sketch is a duplicate of the ManualAcknowledgements.ino example
+ * (without all the Serial input/output code), and it demonstrates
+ * a ATTiny25/45/85 or ATTiny24/44/84 driving the nRF24L01 transceiver using
+ * the RF24 class to communicate with another node.
+ *
+ * A simple example of sending data from 1 nRF24L01 transceiver to another
+ * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads.
+ * This example still uses ACK packets, but they have no payloads. Instead the
+ * acknowledging response is sent with `write()`. This tactic allows for more
+ * updated acknowledgement payload data, where actual ACK payloads' data are
+ * outdated by 1 transmission because they have to loaded before receiving a
+ * transmission.
+ *
+ * This example was written to be used on 2 devices acting as "nodes".
+ */
+
+/*
+ * ********** Hardware configuration (& schematics) *******************
+ *
+ * When direct use of 3V does not work (UNO boards tend to have poor 3V supply),
+ * use 5V with LED (1.8V ~ 2.2V drop) instead.
+ * For low power consumption solutions floating pins (SCK and MOSI) should be
+ * pulled HIGH or LOW with 10K resistors.
+ *
+ * ATTiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 4
+ * ^^
+ * +-\/-+ //
+ * PB5 1|o |8 Vcc --- nRF24L01 VCC --- |<|--- 5V
+ * nRF24L01 CE --- PB3 2| |7 PB2 --- nRF24L01 SCK LED
+ * nRF24L01 CSN --- PB4 3| |6 PB1 --- nRF24L01 MOSI
+ * nRF24L01 GND --- GND 4| |5 PB0 --- nRF24L01 MISO
+ * +----+
+ *
+ * ATTiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 3 => PB3 and PB4 are
+ * free to use for other purposes. This "3 pin solution" is from
+ * Ralph Doncaster (AKA NerdRalph) which is outlined on his blog at
+ * http://nerdralph.blogspot.ca/2014/01/nrf24l01-control-with-3-attiny85-pins.html
+ * Original RC combination was 1K/100nF. 22K/10nF combination worked better.
+ *
+ * For best settle time delay value to use for RF24::csDelay in RF24::csn(), use
+ * the examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino sketch.
+ *
+ * This configuration is enabled in the RF24 library when CE_PIN and
+ * CSN_PIN parameters to the constructor are equal. Notice (in the schematic
+ * below) that these pins aren't directly to the ATTiny85. Because the CE pin
+ * is always HIGH, the power consumption is higher than it would be for the
+ * typical 5 pins solution.
+ * ^^
+ * +-\/-+ nRF24L01 CE --------| //
+ * PB5 1|o |8 Vcc --- nRF24L01 VCC -------x----------x--|<|-- 5V
+ * PB3 2| |7 PB2 --- nRF24L01 SCK ---|<|---x-[22k]--| LED
+ * PB4 3| |6 PB1 --- nRF24L01 MOSI 1n4148 |
+ * nRF24L01 GND -x- GND 4| |5 PB0 --- nRF24L01 MISO |
+ * | +----+ |
+ * |-----------------------------------------||----x-- nRF24L01 CSN
+ * 10nF
+ *
+ * ATTiny24/44/84 Pin map with CE_PIN 8 and CSN_PIN 7 & assuming 1.9V to 3V on VCC
+ * Schematic provided and successfully tested by
+ * Carmine Pastore (https://github.com/Carminepz)
+ *
+ * +-\/-+
+ * nRF24L01 VCC ---- VCC 1|o |14 GND --- nRF24L01 GND
+ * PB0 2| |13 AREF
+ * PB1 3| |12 PA1
+ * PB3 4| |11 PA2 --- nRF24L01 CE
+ * PB2 5| |10 PA3 --- nRF24L01 CSN
+ * PA7 6| |9 PA4 --- nRF24L01 SCK
+ * nRF24L01 MOSI --- PA6 7| |8 PA5 --- nRF24L01 MISO
+ * +----+
+ */
+
+#include "SPI.h"
+#include "RF24.h"
+
+// CE and CSN are configurable, specified values for ATTiny85 as connected above
+#define CE_PIN 3
+#define CSN_PIN 4
+//#define CSN_PIN 3 // uncomment for ATTiny85 3 pins solution
+
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// Let these addresses be used for the pair
+uint8_t address[][6] = { "1Node", "2Node" };
+// It is very helpful to think of an address as a path instead of as
+// an identifying device destination
+
+// to use different addresses on a pair of radios, we need a variable to
+// uniquely identify which address this radio will use to transmit
+bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
+
+// Used to control whether this node is sending or receiving
+bool role = false; // true = TX node, false = RX node
+
+// For this example, we'll be using a payload containing
+// a string & an integer number that will be incremented
+// on every successful transmission.
+// Make a data structure to store the entire payload of different datatypes
+struct PayloadStruct {
+ char message[7]; // only using 6 characters for TX & RX payloads
+ uint8_t counter;
+};
+PayloadStruct payload;
+
+void setup() {
+
+ // append a NULL terminating character for printing as a c-string
+ payload.message[6] = 0;
+
+ // initialize the transceiver on the SPI bus
+ if (!radio.begin()) {
+ while (1) {} // hold in infinite loop
+ }
+
+ // Set the PA Level low to try preventing power supply related problems
+ // because these examples are likely run with nodes in close proximity to
+ // each other.
+ radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
+
+ // save on transmission time by setting the radio to only transmit the
+ // number of bytes we need to transmit a float
+ radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes
+
+ // set the TX address of the RX node into the TX pipe
+ radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
+
+ // set the RX address of the TX node into a RX pipe
+ radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
+
+ if (role) {
+ // setup the TX node
+
+ memcpy(payload.message, "Hello ", 6); // set the outgoing message
+ radio.stopListening(); // put radio in TX mode
+ } else {
+ // setup the RX node
+
+ memcpy(payload.message, "World ", 6); // set the outgoing message
+ radio.startListening(); // put radio in RX mode
+ }
+} // setup()
+
+void loop() {
+
+ if (role) {
+ // This device is a TX node
+
+ bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
+
+ if (report) {
+ // transmission successful; wait for response and print results
+
+ radio.startListening(); // put in RX mode
+ unsigned long start_timeout = millis(); // timer to detect no response
+ while (!radio.available()) { // wait for response or timeout
+ if (millis() - start_timeout > 200) // only wait 200 ms
+ break;
+ }
+ radio.stopListening(); // put back in TX mode
+
+ // print summary of transactions
+ if (radio.available()) { // is there a payload received?
+
+ PayloadStruct received;
+ radio.read(&received, sizeof(received)); // get payload from RX FIFO
+ payload.counter = received.counter; // save incoming counter for next outgoing counter
+ }
+ } // report
+
+ // to make this example readable in the serial monitor
+ delay(1000); // slow transmissions down by 1 second
+
+ } else {
+ // This device is a RX node
+
+ if (radio.available()) { // is there a payload?
+
+ PayloadStruct received;
+ radio.read(&received, sizeof(received)); // get incoming payload
+ payload.counter = received.counter + 1; // increment incoming counter for next outgoing response
+
+ // transmit response & save result to `report`
+ radio.stopListening(); // put in TX mode
+
+ radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO
+ radio.txStandBy(150); // keep retrying for 150 ms
+
+ radio.startListening(); // put back in RX mode
+ }
+ } // role
+} // loop
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino
new file mode 100644
index 0000000..6a983fa
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/rf24_ATTiny/timingSearch3pin/timingSearch3pin.ino
@@ -0,0 +1,207 @@
+/**
+ * See documentation at https://nRF24.github.io/RF24
+ * See License information at root directory of this library
+ * written by tong67 (https://github.com/tong67)
+ * edited by 2bndy5 (http://github.com/2bndy5) for compatibility with SpenceKonde's ATTinyCore
+ */
+
+/*
+ * This sketch can determine the best settle time values to use for
+ * macros, defined as RF24_CSN_SETTLE_HIGH_DELAY and RF24_CSN_SETTLE_LOW_DELAY,
+ * in RF24::csn().
+ * The settle time values used here are 100/20. However, these values depend
+ * on the actual used RC combination and voltage drop by LED. The
+ * intermediate results are written to TX (PB3, pin 2 -- using Serial).
+ *
+ * For schematic details, see introductory comment block in the
+ * examples/rf24_ATTiny/rf24ping85/rf24ping85.ino sketch.
+ */
+
+#include <stdio.h>
+#include <SPI.h>
+#include <Arduino.h>
+#include <nRF24L01.h>
+
+
+#if defined(ARDUINO) && !defined(__arm__)
+#if defined(__AVR_ATtinyX5__) || defined(__AVR_ATtinyX4__)
+#define RF24_TINY
+#endif
+#endif
+
+/****************************************************************************/
+
+#if defined(RF24_TINY)
+
+// when Attiny84 or Attiny85 is detected
+#define CE_PIN 3 /** "Chip Enable" pin, activates the RX or TX role */
+#define CSN_PIN 3 /** SPI Chip Select Not */
+
+#else
+// when not running on an ATTiny84 or ATTiny85
+#define CE_PIN 7 /** "Chip Enable" pin, activates the RX or TX role */
+#define CSN_PIN 8 /** SPI Chip Select Not */
+
+#endif
+
+#define MAX_HIGH 100
+#define MAX_LOW 100
+#define MINIMAL 8
+
+// Use these adjustable variables to test for best configuration to be used on
+// the ATTiny chips. These variables are defined as macros in the library's
+// RF24/utility/ATTiny/RF24_arch_config.h file. To change them, simply define
+// the corresponding macro(s) before #include <RF24> in your sketch.
+uint8_t csnHighSettle = MAX_HIGH; // defined as RF24_CSN_SETTLE_HIGH_DELAY
+uint8_t csnLowSettle = MAX_LOW; // defined as RF24_CSN_SETTLE_LOW_DELAY
+
+/****************************************************************************/
+void ce(bool level) {
+ if (CE_PIN != CSN_PIN) digitalWrite(CE_PIN, level);
+}
+
+/****************************************************************************/
+void csn(bool mode) {
+ if (CE_PIN != CSN_PIN) {
+ digitalWrite(CSN_PIN, mode);
+ } else {
+ // digitalWrite(SCK, mode);
+ if (mode == HIGH) {
+ PORTB |= (1 << PINB2); // SCK->CSN HIGH
+ delayMicroseconds(csnHighSettle); // allow csn to settle
+ } else {
+ PORTB &= ~(1 << PINB2); // SCK->CSN LOW
+ delayMicroseconds(csnLowSettle); // allow csn to settle
+ }
+ }
+}
+
+/****************************************************************************/
+uint8_t read_register(uint8_t reg) {
+ csn(LOW);
+ SPI.transfer(reg);
+ uint8_t result = SPI.transfer(0xff);
+ csn(HIGH);
+ return result;
+}
+
+/****************************************************************************/
+void write_register(uint8_t reg, uint8_t value) {
+ csn(LOW);
+ SPI.transfer(W_REGISTER | reg);
+ SPI.transfer(value);
+ csn(HIGH);
+}
+
+/****************************************************************************/
+void setup(void) {
+
+#ifndef __AVR_ATtinyX313__
+ // not enough memory on ATTiny4313 or ATTint2313(a) to use Serial I/O for this sketch
+
+ // start serial port and SPI
+ Serial.begin(115200);
+ SPI.begin();
+ // configure CE and CSN as output when used
+ pinMode(CE_PIN, OUTPUT);
+ if (CSN_PIN != CE_PIN)
+ pinMode(CSN_PIN, OUTPUT);
+
+ // csn is used in SPI transfers. Set to LOW at start and HIGH after transfer. Set to HIGH to reflect no transfer active
+ // SPI command are accepted in Power Down state.
+ // CE pin represent PRX (LOW) or PTX (HIGH) mode apart from register settings. Start in PRX mode.
+ ce(LOW);
+ csn(HIGH);
+
+ // nRF24L01 goes from to Power Down state 100ms after Power on Reset ( Vdd > 1.9V) or when PWR_UP is 0 in config register
+ // Goto Power Down state (Powerup or force) and set in transmit mode
+ write_register(NRF_CONFIG, read_register(NRF_CONFIG) & ~_BV(PWR_UP) & ~_BV(PRIM_RX));
+ delay(100);
+
+ // Goto Standby-I
+ // Technically we require 4.5ms Tpd2stby+ 14us as a worst case. We'll just call it 5ms for good measure.
+ // WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
+ write_register(NRF_CONFIG, read_register(NRF_CONFIG) | _BV(PWR_UP));
+ delay(5);
+
+ // Goto Standby-II
+ ce(HIGH);
+ Serial.print("Scanning for optimal setting time for csn");
+
+
+ /************************** Main program *********************************/
+
+ uint8_t result; // used to compare read/write results with read/write cmds
+ bool success = true;
+ uint8_t bottom_success;
+ bool bottom_found;
+ uint8_t value[] = { 5, 10 };
+ uint8_t limit[] = { MAX_HIGH, MAX_LOW };
+ uint8_t advice[] = { MAX_HIGH, MAX_LOW };
+
+ // check max values give correct behavior
+ for (uint8_t k = 0; k < 2; k++) {
+ bottom_found = false;
+ bottom_success = 0;
+ while (bottom_success < 255) {
+ csnHighSettle = limit[0];
+ csnLowSettle = limit[1];
+ // check current values
+ uint8_t i = 0;
+ while (i < 255 && success) {
+ for (uint8_t j = 0; j < 2; j++) {
+ write_register(EN_AA, value[j]);
+ result = read_register(EN_AA);
+ if (value[j] != result) {
+ success = false;
+ }
+ }
+ i++;
+ }
+ // process result of current values
+ if (!success) {
+ Serial.print("Settle Not OK. csnHigh=");
+ Serial.print(limit[0], DEC);
+ Serial.print(" csnLow=");
+ Serial.println(limit[1], DEC);
+ limit[k]++;
+ bottom_found = true;
+ bottom_success = 0;
+ success = true;
+ } else {
+ Serial.print("Settle OK. csnHigh=");
+ Serial.print(limit[0], DEC);
+ Serial.print(" csnLow=");
+ Serial.println(limit[1], DEC);
+ if (!bottom_found) {
+ limit[k]--;
+ if (limit[k] == MINIMAL) {
+ bottom_found = true;
+ bottom_success = 0;
+ success = true;
+ }
+ } else {
+ bottom_success++;
+ }
+ }
+ } // while (bottom_success < 255)
+ Serial.print("Settle value found for ");
+ if (k == 0) {
+ Serial.print("csnHigh: ");
+ } else {
+ Serial.print("csnLow: ");
+ }
+ Serial.println(limit[k], DEC);
+ advice[k] = limit[k] + (limit[k] / 10);
+ limit[k] = 100;
+ } // for (uint8_t k = 0; k < 2; k++)
+ Serial.print("Advised Settle times are: csnHigh=");
+ Serial.print(advice[0], DEC);
+ Serial.print(" csnLow=");
+ Serial.println(advice[1], DEC);
+
+#endif // not defined __AVR_ATtinyX313__
+}
+
+
+void loop(void) {} // this program runs only once, thus it resides in setup()
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/scanner/scanner.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/scanner/scanner.ino
new file mode 100644
index 0000000..d6c7d44
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/scanner/scanner.ino
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
+ * Updated 2020 TMRh20
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+/**
+ * Channel scanner and Continuous Carrier Wave Output
+ *
+ * Example to detect interference on the various channels available.
+ * This is a good diagnostic tool to check whether you're picking a
+ * good channel for your application.
+ *
+ * Run this sketch on two devices. On one device, start emitting a constant carrier wave
+ * by sending a channel number in the Serial Monitor. The other device scanning should
+ * detect the constant carrier wave from the sending device on the given channel.
+ * Send a negative number in the Serial Monitor to stop emitting a constant carrier wave
+ * and resume scanning.
+ *
+ * Inspired by cpixip.
+ * See https://forum.arduino.cc/t/poor-mans-2-4-ghz-scanner/54846
+ *
+ * See documentation at https://nRF24.github.io/RF24
+ */
+
+/*
+ * How to read the output:
+ * - The header is a list of supported channels in decimal written vertically.
+ * - Each column corresponding to the vertical header is a hexadecimal count of
+ * detected signals (max is 15 or 'f').
+ *
+ * The following example
+ * 000
+ * 111
+ * 789
+ * ~~~ <- just a divider between the channel's vertical labels and signal counts
+ * 1-2
+ * can be interpreted as
+ * - 1 signal detected on channel 17
+ * - 0 signals (denoted as '-') detected on channel 18
+ * - 2 signals detected on channel 19
+ *
+ * Each line of signal counts represent 100 passes of the supported spectrum.
+ */
+
+#include "RF24.h"
+#include "printf.h"
+
+//
+// Hardware configuration
+//
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+//
+// Channel info
+//
+
+const uint8_t num_channels = 126; // 0-125 are supported
+uint8_t values[num_channels]; // the array to store summary of signal counts per channel
+
+// To detect noise, we'll use the worst addresses possible (a reverse engineering tactic).
+// These addresses are designed to confuse the radio into thinking
+// that the RF signal's preamble is part of the packet/payload.
+const uint8_t noiseAddress[][2] = { { 0x55, 0x55 }, { 0xAA, 0xAA }, { 0xA0, 0xAA }, { 0xAB, 0xAA }, { 0xAC, 0xAA }, { 0xAD, 0xAA } };
+
+const int num_reps = 100; // number of passes for each scan of the entire spectrum
+bool constCarrierMode = 0; // this flag controls example behavior (scan mode is default)
+
+void printHeader(); // prototype function for printing the channels' header
+
+
+void setup(void) {
+
+ // Print preamble
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need this to wait for Serial connection
+ }
+ Serial.println(F("RF24/examples/scanner/"));
+
+ // Setup and configure rf radio
+ if (!radio.begin()) {
+ Serial.println(F("radio hardware not responding!"));
+ while (true) {
+ // hold in an infinite loop
+ }
+ }
+ radio.stopConstCarrier(); // in case MCU was reset while radio was emitting carrier wave
+ radio.setAutoAck(false); // Don't acknowledge arbitrary signals
+ radio.disableCRC(); // Accept any signal we find
+ radio.setAddressWidth(2); // A reverse engineering tactic (not typically recommended)
+ for (uint8_t i = 0; i < 6; ++i) {
+ radio.openReadingPipe(i, noiseAddress[i]);
+ }
+
+ // set the data rate
+ Serial.print(F("Select your Data Rate. "));
+ Serial.print(F("Enter '1' for 1 Mbps, '2' for 2 Mbps, '3' for 250 kbps. "));
+ Serial.println(F("Defaults to 1Mbps."));
+ while (!Serial.available()) {
+ // wait for user input
+ }
+ uint8_t dataRate = Serial.parseInt();
+ if (dataRate == 50) {
+ Serial.println(F("Using 2 Mbps."));
+ radio.setDataRate(RF24_2MBPS);
+ } else if (dataRate == 51) {
+ Serial.println(F("Using 250 kbps."));
+ radio.setDataRate(RF24_250KBPS);
+ } else {
+ Serial.println(F("Using 1 Mbps."));
+ radio.setDataRate(RF24_1MBPS);
+ }
+ Serial.println(F("***Enter a channel number to emit a constant carrier wave."));
+ Serial.println(F("***Enter a negative number to switch back to scanner mode."));
+
+ // Get into standby mode
+ radio.startListening();
+ radio.stopListening();
+ radio.flush_rx();
+
+ // printf_begin();
+ // radio.printPrettyDetails();
+ // delay(1000);
+
+ // Print out vertical header
+ printHeader();
+}
+
+void loop(void) {
+ /****************************************/
+ // Send a number over Serial to begin Constant Carrier Wave output
+ // Configure the power amplitude level below
+ if (Serial.available()) {
+ int8_t c = Serial.parseInt();
+ if (c >= 0) {
+ c = min((int8_t)125, c); // clamp channel to supported range
+ constCarrierMode = 1;
+ radio.stopListening();
+ delay(2);
+ Serial.print("\nStarting Carrier Wave Output on channel ");
+ Serial.println(c);
+ // for non-plus models, startConstCarrier() changes address on pipe 0 and sets address width to 5
+ radio.startConstCarrier(RF24_PA_LOW, c);
+ } else {
+ constCarrierMode = 0;
+ radio.stopConstCarrier();
+ radio.setAddressWidth(2); // reset address width
+ radio.openReadingPipe(0, noiseAddress[0]); // ensure address is looking for noise
+ Serial.println("\nStopping Carrier Wave Output");
+ printHeader();
+ }
+
+ // discard any CR and LF sent
+ while (Serial.peek() != -1) {
+ if (Serial.peek() == '\r' || Serial.peek() == '\n') {
+ Serial.read();
+ } else { // got a charater that isn't a line feed
+ break; // handle it on next loop() iteration
+ }
+ }
+ }
+
+ /****************************************/
+
+ if (constCarrierMode == 0) {
+ // Clear measurement values
+ memset(values, 0, sizeof(values));
+
+ // Scan all channels num_reps times
+ int rep_counter = num_reps;
+ while (rep_counter--) {
+ int i = num_channels;
+ while (i--) {
+ // Select this channel
+ radio.setChannel(i);
+
+ // Listen for a little
+ radio.startListening();
+ delayMicroseconds(128);
+ bool foundSignal = radio.testRPD();
+ radio.stopListening();
+
+ // Did we get a signal?
+ if (foundSignal || radio.testRPD() || radio.available()) {
+ ++values[i];
+ radio.flush_rx(); // discard packets of noise
+ }
+ }
+ }
+
+ // Print out channel measurements, clamped to a single hex digit
+ for (int i = 0; i < num_channels; ++i) {
+ if (values[i])
+ Serial.print(min((uint8_t)0xf, values[i]), HEX);
+ else
+ Serial.print(F("-"));
+ }
+ Serial.println();
+
+ } // if constCarrierMode == 0
+ else {
+ // show some output to prove that the program isn't bricked
+ Serial.print(F("."));
+ delay(1000); // delay a second to keep output readable
+ }
+} // end loop()
+
+void printHeader() {
+ // Print the hundreds digits
+ for (uint8_t i = 0; i < num_channels; ++i)
+ Serial.print(i / 100);
+ Serial.println();
+
+ // Print the tens digits
+ for (uint8_t i = 0; i < num_channels; ++i)
+ Serial.print((i % 100) / 10);
+ Serial.println();
+
+ // Print the singles digits
+ for (uint8_t i = 0; i < num_channels; ++i)
+ Serial.print(i % 10);
+ Serial.println();
+
+ // Print the header's divider
+ for (uint8_t i = 0; i < num_channels; ++i)
+ Serial.print(F("~"));
+ Serial.println();
+} \ No newline at end of file
diff --git a/.pio/libdeps/esp32-s3-n16r8/RF24/examples/scannerGraphic/scannerGraphic.ino b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/scannerGraphic/scannerGraphic.ino
new file mode 100644
index 0000000..ddbed5a
--- /dev/null
+++ b/.pio/libdeps/esp32-s3-n16r8/RF24/examples/scannerGraphic/scannerGraphic.ino
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2022 Brendan Doherty <2bndy5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+/*
+ * This example uses 1 of 2 different popular displays. To control which display to use,
+ * comment/uncomment the lines below that define
+ * - `SPI_DISPLAY`: This requires the "Adafruit ST7735 and ST7789 Library" installed
+ * - `I2C_DISPLAY`: This requires the "Adafruit SSD1306" library installed
+ *
+ * Use the Arduino Library manager to ensure the required libraries are installed.
+ * By default, this sketch uses the SPI_DISPLAY (ST7789). Using both displays at the same
+ * time is not supported by this sketch.
+ *
+ * NOTES:
+ * The `SCREEN_HEIGHT` and `SCREEN_WIDTH` defines may need to be adjusted according
+ * to your display module's capability. This example expects the display to be at
+ * least 128 pixels wide. Otherwise, you would have to reduce the `numChannels`
+ * constant to fit within your display's width.
+ *
+ * The SPI_DISPLAY uses its own pins defined by `TFT_CS`, `TFT_DC`, and the
+ * optional `TFT_RST` (see below). The SPI bus is shared between radio and display,
+ * so the display's CS pin must be connected as specified by `TFT_CS`.
+ * If your ST7789 display does not have a CS pin, then further modification must
+ * be made so it does not use the same SPI bus that the radio uses.
+ *
+ * `DEBUGGING` can be enabled (uncommented) to show Serial output. This is just a
+ * convenience to set radio data rate or further development. See our other
+ * RF24/scanner example that only uses the Serial Monitor instead of a graphic
+ * display.
+ *
+ * See documentation at https://nRF24.github.io/RF24
+ */
+#include <Adafruit_GFX.h> // dependency of Adafruit display libraries
+#include "RF24.h"
+
+/********************************************************************
+ * CHOOSE A DISPLAY INTERFACE
+ * uncomment/comment only 1 of the following to use the desired display
+ ********************************************************************/
+// #define I2C_DISPLAY // using the SSD1306
+#define SPI_DISPLAY // using ST7789
+
+/********************************************************************
+ * Choose a sketch feature
+ * uncomment any of the following to enable a special feature
+ ********************************************************************/
+// #define DEBUGGING // uncomment to enable Serial output (optional)
+// #define HOLD_PEAKS // uncomment to disable decay of maxPeak pixels (useful for assessing total noise)
+
+/********************************************************************
+ * Instantiate the radio and app-specific attributes
+ ********************************************************************/
+
+#define CE_PIN 7
+#define CSN_PIN 8
+// instantiate an object for the nRF24L01 transceiver
+RF24 radio(CE_PIN, CSN_PIN);
+
+// To detect noise, we'll use the worst addresses possible (a reverse engineering tactic).
+// These addresses are designed to confuse the radio into thinking
+// that the RF signal's preamble is part of the packet/payload.
+const uint8_t noiseAddress[][2] = { { 0x55, 0x55 }, { 0xAA, 0xAA }, { 0xA0, 0xAA }, { 0xAB, 0xAA }, { 0xAC, 0xAA }, { 0xAD, 0xAA } };
+
+const uint8_t numChannels = 126; // 0-125 are supported
+
+/***********************************************************************
+ * Declare caching mechanism to track history of signals for peak decay
+ **********************************************************************/
+
+const uint8_t cacheMax = 4;
+
+/// A data structure to organize the cache of signals for a certain channel.
+struct ChannelHistory {
+ /// max peak value is (at most) 2 * CACHE_MAX to allow for half-step decays
+ uint8_t maxPeak = 0;
+
+ /// Push a signal's value into cached history while popping
+ /// oldest cached value. This also sets the maxPeak value.
+ /// @returns The sum of signals found in the cached history
+ uint8_t push(bool value) {
+ uint8_t sum = value;
+ for (uint8_t i = 0; i < cacheMax - 1; ++i) {
+ history[i] = history[i + 1];
+ sum += history[i];
+ }
+ history[cacheMax - 1] = value;
+ maxPeak = max((uint8_t)(sum * 2), maxPeak); // sum * 2 to allow half-step decay
+ return sum;
+ }
+
+private:
+ bool history[cacheMax] = { 0 };
+};
+
+/// An array of caches to use as channels' history
+ChannelHistory stored[numChannels];
+
+/********************************************************************
+ * Instantiate the appropriate display objects according to the
+ * defines (above near top of file)
+ ********************************************************************/
+
+#ifdef I2C_DISPLAY
+
+#include <Wire.h>
+#include <Adafruit_SSD1306.h>
+
+#define SCREEN_WIDTH 128 // OLED display width, in pixels
+#define SCREEN_HEIGHT 64 // OLED display height, in pixels
+
+// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
+// The pins for I2C are defined by the Wire-library.
+// On an arduino UNO: A4(SDA), A5(SCL)
+// On an arduino MEGA 2560: 20(SDA), 21(SCL)
+// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
+#define OLED_RESET -1 // Or set to -1 and connect to Arduino RESET pin
+#define SCREEN_ADDRESS 0x3D // See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
+Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
+
+#define BLACK SSD1306_BLACK
+#define WHITE SSD1306_WHITE
+#define REFRESH ({ display.display(); })
+#define CLEAR_DISPLAY ({ display.clearDisplay(); })
+
+#elif defined(SPI_DISPLAY)
+
+#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
+
+#define TFT_CS 9
+#define TFT_RST -1 // Or set to -1 and connect to Arduino RESET pin
+#define TFT_DC 6
+
+#define SCREEN_WIDTH 135 // TFT display width, in pixels
+#define SCREEN_HEIGHT 240 // TFT display height, in pixels
+
+// For 1.14", 1.3", 1.54", 1.69", and 2.0" TFT with ST7789:
+Adafruit_ST7789 display = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
+
+#define BLACK ST77XX_BLACK
+#define WHITE ST77XX_WHITE
+#define REFRESH
+#define CLEAR_DISPLAY ({ display.fillScreen(BLACK); })
+
+#endif // if defined(I2C_DISPLAY) || defined(SPI_DISPLAY)
+
+// constant chart size attributes
+const uint16_t margin = 1; // use 1 pixel margin for markers on each side of chart
+const uint16_t barWidth = (SCREEN_WIDTH - (margin * 2)) / numChannels;
+const uint16_t chartHeight = SCREEN_HEIGHT - 10;
+const uint16_t chartWidth = margin * 2 + (numChannels * barWidth);
+
+/********************************************************************
+ * Configure debugging on Serial output
+ ********************************************************************/
+
+#ifdef DEBUGGING
+#include "printf.h"
+#define SERIAL_DEBUG(x) ({ x; })
+#else
+#define SERIAL_DEBUG(x)
+#endif
+
+/********************************************************************
+ * Setup the app
+ ********************************************************************/
+void setup(void) {
+
+#ifdef DEBUGGING
+ // Print preamble
+ Serial.begin(115200);
+ while (!Serial) {
+ // some boards need this to wait for Serial connection
+ }
+ Serial.println(F("RF24/examples/scannerGraphic"));
+#endif
+
+#ifdef I2C_DISPLAY
+ // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+ if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
+ SERIAL_DEBUG(Serial.println(F("SSD1306 allocation failed")););
+ while (true) {
+ // Don't proceed, loop forever
+ }
+ }
+#elif defined(SPI_DISPLAY)
+ // use this initializer for a 1.14" 240x135 TFT:
+ display.init(SCREEN_WIDTH, SCREEN_HEIGHT); // Init ST7789 240x135
+#endif
+
+ // Clear the buffer
+ CLEAR_DISPLAY;
+
+ // Setup and configure rf radio
+ if (!radio.begin()) {
+ SERIAL_DEBUG(Serial.println(F("radio hardware not responding!")););
+ display.setCursor(1, 1);
+ display.setTextColor(WHITE);
+ display.print(F("radio hardware\nnot responding!"));
+ REFRESH;
+ while (true) {
+ // hold in an infinite loop
+ }
+ }
+ displayChartAxis();
+
+ radio.setAutoAck(false); // Don't acknowledge arbitrary signals
+ radio.disableCRC(); // accept any signal we find
+ radio.setAddressWidth(2); // a reverse engineering tactic (not typically recommended)
+ for (uint8_t i = 0; i < 6; ++i) {
+ radio.openReadingPipe(i, noiseAddress[i]);
+ }
+
+ // set the data rate
+#ifdef DEBUGGING
+ unsigned long inputTimeout = millis() + 7000;
+ Serial.print(F("Select your Data Rate. "));
+ Serial.println(F("Enter '1' for 1Mbps, '2' for 2Mbps, '3' for 250kbps. Defaults to 1 Mbps."));
+ while (!Serial.available() && millis() < inputTimeout) {
+ // Wait for user input. Timeout after 7 seconds.
+ }
+ char dataRate = !Serial.available() ? '1' : Serial.parseInt();
+#else
+ char dataRate = '1';
+#endif
+ if (dataRate == '2') {
+ SERIAL_DEBUG(Serial.println(F("Using 2 Mbps.")););
+ radio.setDataRate(RF24_2MBPS);
+ } else if (dataRate == '3') {
+ SERIAL_DEBUG(Serial.println(F("Using 250 kbps.")););
+ radio.setDataRate(RF24_250KBPS);
+ } else { // dataRate == '1' or invalid values
+ SERIAL_DEBUG(Serial.println(F("Using 1 Mbps.")););
+ radio.setDataRate(RF24_1MBPS);
+ }
+
+ // Get into standby mode
+ radio.startListening();
+ radio.stopListening();
+ radio.flush_rx();
+}
+
+/********************************************************************
+ * Make the app loop forever
+ ********************************************************************/
+void loop(void) {
+ // Print out channel measurements, clamped to a single hex digit
+ for (uint8_t channel = 0; channel < numChannels; ++channel) {
+ bool foundSignal = scanChannel(channel);
+ uint8_t cacheSum = stored[channel].push(foundSignal);
+ uint8_t x = (barWidth * channel) + 1 + margin - (barWidth * (bool)channel);
+ // reset bar for current channel to 0
+ display.fillRect(x, 0, barWidth, chartHeight, BLACK);
+ if (stored[channel].maxPeak > cacheSum * 2) {
+ // draw a peak line only if it is greater than current sum of cached signal counts
+ uint16_t y = chartHeight - (chartHeight * stored[channel].maxPeak / (cacheMax * 2));
+ display.drawLine(x, y, x + barWidth, y, WHITE);
+#ifndef HOLD_PEAKS
+ stored[channel].maxPeak -= 1; // decrement max peak
+#endif
+ }
+ if (cacheSum) { // draw the cached signal count
+ uint8_t barHeight = chartHeight * cacheSum / cacheMax;
+ display.fillRect(x, chartHeight - barHeight, barWidth, barHeight, WHITE);
+ }
+ }
+ REFRESH;
+} // end loop()
+
+/// Scan a specified channel and return the resulting flag
+bool scanChannel(uint8_t channel) {
+ radio.setChannel(channel);
+
+ // Listen for a little
+ radio.startListening();
+ delayMicroseconds(130);
+ bool foundSignal = radio.testRPD();
+ radio.stopListening();
+
+ // Did we get a signal?
+ if (foundSignal || radio.testRPD() || radio.available()) {
+ radio.flush_rx(); // discard packets of noise
+ return true;
+ }
+ return false;
+}
+
+/// Draw the chart axis and labels
+void displayChartAxis() {
+ // draw base line
+ display.drawLine(0, chartHeight + 1, chartWidth - margin, chartHeight + 1, WHITE);
+
+ // draw base line border
+ display.drawLine(margin, SCREEN_HEIGHT, margin, chartHeight - 2, WHITE);
+ display.drawLine(chartWidth - margin, SCREEN_HEIGHT, chartWidth - margin, chartHeight - 2, WHITE);
+
+ // draw scalar marks
+ for (uint8_t i = 0; i < cacheMax; ++i) {
+ uint8_t scalarHeight = chartHeight * i / cacheMax;
+ display.drawLine(0, scalarHeight, chartWidth, scalarHeight, WHITE);
+ }
+
+ // draw channel range labels
+ display.setTextSize(1);
+ display.setTextColor(WHITE);
+ uint8_t maxChannelDigits = 0;
+ uint8_t tmp = numChannels;
+ while (tmp) {
+ maxChannelDigits += 1;
+ tmp /= 10;
+ }
+ display.setCursor(chartWidth - (7 * maxChannelDigits), chartHeight + 3);
+ display.print(numChannels - 1);
+ display.setCursor(margin + 2, chartHeight + 3);
+ display.print(0);
+
+ // refresh display
+ REFRESH;
+}