From 2f5aea2f334dc6894ea3ad1c45de45dfc9dffdc2 Mon Sep 17 00:00:00 2001 From: TMRh20 Date: Sun, 30 Jun 2024 06:35:24 -0600 Subject: [PATCH] mesh.checkConnection via parent not master (#250) * mesh.checkConnection via parent not master - Adjust mesh.checkConnection function to verify connectivity with parent only. Leave old functionality in place with a #define - Suggestions in place per @2bndy5 closes #249 * Fix last commit - _nodeID not nodeID * review changes * trigger compile size reports for PRs Specifically for PRs that only change the lib src code and not examples. * doc review use doxygen references * [docs] clarify return value of checkConnection() * format RF24Mesh.h Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * review supported CMake options also defaults RF24_DRIVER to SPIDEV (per nRF24/RF24#971) * add reference to new config macro in checkConnection() doc. --------- Co-authored-by: Brendan <2bndy5@gmail.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .github/workflows/build_arduino.yml | 2 ++ CMakeLists.txt | 7 +++-- RF24Mesh.cpp | 22 +++++++++++++-- RF24Mesh.h | 11 +++++++- RF24Mesh_config.h | 19 +++++++++++++ cmake/AutoConfig_RF24_DRIVER.cmake | 42 +++++++++++++++-------------- examples_RPi/CMakeLists.txt | 16 ++++------- 7 files changed, 81 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build_arduino.yml b/.github/workflows/build_arduino.yml index 039877cd..ad0bbb82 100644 --- a/.github/workflows/build_arduino.yml +++ b/.github/workflows/build_arduino.yml @@ -6,6 +6,8 @@ on: paths: - ".github/workflows/build_arduino.yml" - "examples/**" + - "RF24Mesh.*" + - "RF24Mesh_config.h" push: branches: [master, v1.x] diff --git a/CMakeLists.txt b/CMakeLists.txt index da5b9703..47135be2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,10 +143,9 @@ if(DEFINED MESH_WRITE_TIMEOUT) message(STATUS "MESH_WRITE_TIMEOUT set to ${MESH_WRITE_TIMEOUT}") target_compile_definitions(${LibTargetName} PUBLIC MESH_WRITE_TIMEOUT=${MESH_WRITE_TIMEOUT}) endif() -# conditionally disable interruot support (a pigpio specific feature) -if("${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND" OR DEFINED RF24_NO_INTERRUPT) - message(STATUS "Disabling IRQ pin support") - target_compile_definitions(${LibTargetName} PUBLIC RF24_NO_INTERRUPT) +if(DEFINED RF24MESH_CONN_CHECK_TYPE) + message(STATUS "RF24MESH_CONN_CHECK_TYPE set to ${RF24MESH_CONN_CHECK_TYPE}") + target_compile_definitions(${LibTargetName} PUBLIC RF24MESH_CONN_CHECK_TYPE=${RF24MESH_CONN_CHECK_TYPE}) endif() diff --git a/RF24Mesh.cpp b/RF24Mesh.cpp index be6ef207..2717d31c 100644 --- a/RF24Mesh.cpp +++ b/RF24Mesh.cpp @@ -154,8 +154,25 @@ void ESBMesh::setChild(bool allow) template bool ESBMesh::checkConnection() { - // getAddress() doesn't use auto-ack; do a double-check to manually retry 1 more time - for (uint8_t i = 0; i < MESH_CONNECTION_CHECK_ATTEMPTS; i++) { + + if (!_nodeID) return false; + if (mesh_address == MESH_DEFAULT_ADDRESS) return false; + +// Connection check via parent node +#if RF24MESH_CONN_CHECK_TYPE == RF24MESH_CONN_CHECK_PARENT + RF24NetworkHeader header; + header.to_node = network.parent(); + header.type = NETWORK_PING; + for (uint8_t i = 0; i < MESH_CONNECTION_CHECK_ATTEMPTS; ++i) { + if (network.write(header, 0, 0)) { + return true; + } + } + return false; + +#else // Connection check via master node + // getAddress() doesn't use auto-ack; check connectivity multiple times + for (uint8_t i = 0; i < MESH_CONNECTION_CHECK_ATTEMPTS; ++i) { int16_t result = getAddress(_nodeID); switch (result) { @@ -170,6 +187,7 @@ bool ESBMesh::checkConnection() } } return false; +#endif } /*****************************************************/ diff --git a/RF24Mesh.h b/RF24Mesh.h index 603adcb7..b88f9644 100644 --- a/RF24Mesh.h +++ b/RF24Mesh.h @@ -190,7 +190,16 @@ class ESBMesh /** * Tests connectivity of this node to the mesh. * @note If this function fails, address renewal should typically be done. - * @return 1 if connected, 0 if mesh not responding + * + * The current behavior will only ping this node's parent to validate connection to mesh. + * Previously, this function would validate connection by looking up this node's assigned address with + * the master node's `RF24Mesh::addrList`. + * The old behavior can be mandated by changing @ref RF24MESH_CONN_CHECK_TYPE in RF24Mesh_config.h, + * although a large mesh network might suffer a performance cost using the old behavior. + * + * @return + * - True if connected. + * - False if not connected, mesh is not responding, or this node is the master node. */ bool checkConnection(); diff --git a/RF24Mesh_config.h b/RF24Mesh_config.h index 0c0d1a72..19f21f65 100644 --- a/RF24Mesh_config.h +++ b/RF24Mesh_config.h @@ -64,6 +64,25 @@ #define MESH_CONNECTION_CHECK_ATTEMPTS 3 #endif +#define RF24MESH_CONN_CHECK_PARENT 1 +#define RF24MESH_CONN_CHECK_MASTER 0 +/** + * @brief How to verify a connection + * + * On child nodes, determine how they verify/check their connection periodically, or when writes start to fail via the `RF24Mesh::checkConnection();` + * function. + * Set RF24MESH_CONN_CHECK_TYPE to @ref RF24MESH_CONN_CHECK_PARENT for the new behaviour of verifying connectivity only with their parent node. + * Set RF24MESH_CONN_CHECK_TYPE to @ref RF24MESH_CONN_CHECK_MASTER for the old behaviour of verifying connectivity with the master node. + * The old behaviour typically results in more network congestion, more load on the master node, and less reliable networks, + * but it can work well when radio conditions are good and/or when there are only a small number of nodes on the network and/or in close proximity + * to the master node. + */ +#ifndef RF24MESH_CONN_CHECK_TYPE + #define RF24MESH_CONN_CHECK_TYPE RF24MESH_CONN_CHECK_PARENT + // To use old behavior: + // #define RF24MESH_CONN_CHECK_TYPE RF24MESH_CONN_CHECK_MASTER +#endif + /**************************/ /*** Debug ***/ //#define RF24MESH_DEBUG_MINIMAL /** Uncomment for the Master Node to print out address assignments as they are assigned */ diff --git a/cmake/AutoConfig_RF24_DRIVER.cmake b/cmake/AutoConfig_RF24_DRIVER.cmake index 6e942caf..99e04082 100644 --- a/cmake/AutoConfig_RF24_DRIVER.cmake +++ b/cmake/AutoConfig_RF24_DRIVER.cmake @@ -26,31 +26,33 @@ else() endif() -if(${RF24_DRIVER} STREQUAL "UNKNOWN") # invokes automatic configuration - if("${SOC}" STREQUAL "BCM2708" OR "${SOC}" STREQUAL "BCM2709" OR "${SOC}" STREQUAL "BCM2835") - set(RF24_DRIVER RPi CACHE STRING "using folder /utility/RPi" FORCE) - elseif(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") - message(STATUS "Found pigpio library: ${LibPIGPIO}") - set(RF24_DRIVER pigpio CACHE STRING "using folder /utility/pigpio" FORCE) - elseif(NOT "${LibWiringPi}" STREQUAL "LibWiringPi-NOTFOUND") - message(STATUS "Found wiringPi library: ${LibWiringPi}") - set(RF24_DRIVER wiringPi CACHE STRING "using folder /utility/wiringPi" FORCE) - elseif(NOT "${LibLittleWire}" STREQUAL "LibLittleWire-NOTFOUND") - message(STATUS "Found LittleWire library: ${LibLittleWire}") - set(RF24_DRIVER LittleWire CACHE STRING "using folder /utility/LittleWire" FORCE) - elseif(NOT "${LibMRAA}" STREQUAL "LibMRAA-NOTFOUND") - message(STATUS "Found MRAA library: ${LibMRAA}") - set(RF24_DRIVER MRAA CACHE STRING "using folder /utility/MRAA" FORCE) - elseif(SPIDEV_EXISTS) # should be a non-empty string if SPI is enabled - message(STATUS "detected that SPIDEV is enabled: ${SPIDEV_EXISTS}") - set(RF24_DRIVER SPIDEV CACHE STRING "using folder /utility/SPIDEV" FORCE) - endif() -endif() +# if(${RF24_DRIVER} STREQUAL "UNKNOWN") # invokes automatic configuration +# if("${SOC}" STREQUAL "BCM2708" OR "${SOC}" STREQUAL "BCM2709" OR "${SOC}" STREQUAL "BCM2835") +# set(RF24_DRIVER RPi CACHE STRING "using folder /utility/RPi" FORCE) +# elseif(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") +# message(STATUS "Found pigpio library: ${LibPIGPIO}") +# set(RF24_DRIVER pigpio CACHE STRING "using folder /utility/pigpio" FORCE) +# elseif(NOT "${LibWiringPi}" STREQUAL "LibWiringPi-NOTFOUND") +# message(STATUS "Found wiringPi library: ${LibWiringPi}") +# set(RF24_DRIVER wiringPi CACHE STRING "using folder /utility/wiringPi" FORCE) +# elseif(NOT "${LibLittleWire}" STREQUAL "LibLittleWire-NOTFOUND") +# message(STATUS "Found LittleWire library: ${LibLittleWire}") +# set(RF24_DRIVER LittleWire CACHE STRING "using folder /utility/LittleWire" FORCE) +# elseif(NOT "${LibMRAA}" STREQUAL "LibMRAA-NOTFOUND") +# message(STATUS "Found MRAA library: ${LibMRAA}") +# set(RF24_DRIVER MRAA CACHE STRING "using folder /utility/MRAA" FORCE) +# elseif(SPIDEV_EXISTS) # should be a non-empty string if SPI is enabled +# message(STATUS "detected that SPIDEV is enabled: ${SPIDEV_EXISTS}") +# set(RF24_DRIVER SPIDEV CACHE STRING "using folder /utility/SPIDEV" FORCE) +# endif() +# endif() # override the auto-detect if RF24_DRIVER is defined in an env var if(DEFINED ENV{RF24_DRIVER}) message(STATUS "RF24_DRIVER (set from env var) = $ENV{RF24_DRIVER}") set(RF24_DRIVER $ENV{RF24_DRIVER} CACHE STRING "" FORCE) +elseif(${RF24_DRIVER} STREQUAL "UNKNOWN") + set(RF24_DRIVER SPIDEV CACHE STRING "using folder RF24/utility/SPIDEV" FORCE) endif() message(STATUS "Using driver: ${RF24_DRIVER}") diff --git a/examples_RPi/CMakeLists.txt b/examples_RPi/CMakeLists.txt index fe44a993..e202e47d 100644 --- a/examples_RPi/CMakeLists.txt +++ b/examples_RPi/CMakeLists.txt @@ -47,15 +47,13 @@ elseif("${RF24_DRIVER}" STREQUAL "wiringPi") else() message(FATAL "Lib ${RF24_DRIVER} not found.") endif() -elseif(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND" AND NOT DEFINED RF24_NO_INTERUPT) - if(NOT "${RF24_DRIVER}" STREQUAL "pigpio") - message(STATUS "linking to ${LibPIGPIO} for interrupt support") - else() +elseif("${RF24_DRIVER}" STREQUAL "pigpio") + if(NOT "${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND") message(STATUS "linking to ${LibPIGPIO}") + list(APPEND linked_libs ${LibPIGPIO}) + else() + message(FATAL "Lib ${RF24_DRIVER} not found.") endif() - list(APPEND linked_libs ${LibPIGPIO}) -else() - message(STATUS "Disabling IRQ pin support") endif() foreach(example ${EXAMPLES_LIST}) @@ -63,10 +61,6 @@ foreach(example ${EXAMPLES_LIST}) add_executable(${example} ${example}.cpp) # link the RF24 lib to the target. target_link_libraries(${example} PUBLIC ${linked_libs}) - # conditionally disable interruot support (a pigpio specific feature) - if("${LibPIGPIO}" STREQUAL "LibPIGPIO-NOTFOUND" OR DEFINED RF24_NO_INTERRUPT) - target_compile_definitions(${example} PUBLIC RF24_NO_INTERRUPT) - endif() endforeach() include(../cmake/enableNcursesExample.cmake)