Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RF24Network, RF24Mesh, and RXing BLE #33

Merged
merged 300 commits into from
Nov 23, 2021
Merged

RF24Network, RF24Mesh, and RXing BLE #33

merged 300 commits into from
Nov 23, 2021

Conversation

2bndy5
Copy link
Member

@2bndy5 2bndy5 commented Aug 4, 2021

yeah, I've been busy adding/improving this lib (yet again)... As always docs are hosted at rtfd.io.

You may notice that the docs' theme has changed slightly. This is due to the use of the new sphinx-immaterial theme. This theme allows for both light and dark themed color palettes (which can be sought from the system settings by the internet browser).

BLE can now receive

the fake_ble module now has a new class called QueueElement which is used to decode incoming BLE data as it goes from the FakeBLE class' new rx_cache buffer and is saved in the new rx_queue attribute. The existing example has been updated to demonstrate this additional API (which includes a new overridden available() & read()).

  • each QueueElement object will always contain the MAC address of the transmitting BLE device
  • current data that is translated is only the currently supported outgoing service data and device characteristics. This includes the transmitting device's
    • BLE device name (long or short)
    • transmitting PA level
    • battery service data
    • temperature data
    • URL data
  • any unknown data structure/characteristic encountered while decoding the received BLE data will be added to the QueueElement.data list (as a bytearray). All supported service data will coexist in the data attribute/list as objects that can be used for transmitting BLE data.
  • All ServiceData based classes have their own __repr__() method that will allow printing human-readable encapsulated data.

RF24Network & RF24Mesh

The C++ libraries that were ported to pure python are a freaking beast. Many of the compile time macros used in C++ could not be used in python (same goes for ALL the overloaded C++ functions). Instead, I had to utilize inheritance to limit consumed memory resources, but some C++ features that were hard-coded at compile-time are straight-up dynamic attributes in this lib. Instead of listing all the features, I will list the differences between C++ libs and this pure python lib's modules.

Instead of writing numerous examples that are almost identical, there is only 1 new example for networking. It demonstrates both fragmented and un-fragmented payloads as well as RF24Network, RF24Mesh, and RF24MeshNoMaster classes. Note, I had to diverge from using the typical master() and slave() named functions as to not confuse with network node operations; this example uses emit() and idle() functions instead.

context manager

As always I've kept compatibility with python's context management system (the with statements). Thus you can use the same radio to take a break from networking and quickly do BLE or basic RF24 operations. This will prove even more useful when using the radio to participate in separate networks on different channels and/or using different physical address "seeds".

RF24Network

  • C++ lib doesn't provide this feature, but with this lib, you can dynamically change the physical address "seeds" using the address_prefix and address_suffix attributes (both bytearrays). There is a quick tutorial in the docs' topology page about using different physical address "seeds" for 2 networks coexisting on the same channel.
  • C++ lib's DISABLE_USER_PAYLOADS exists in this lib as base class that RF24Network class inherits from called RF24NetworkRoutingOnly. In practice this may be used for routing nodes or possibly RF24Ethernet in the future (I need to better understand TCP/IP protocol first).
  • C++ lib's write(header, message) function is called send() in this lib due to lack of function overloading, However, users can pass entire frames to be sent using this lib's write(frame, traffic_direct) function.
  • C++ lib's queue implementation is broken away from this lib's RF24Network class and exists as its own class. I cannot rely on CPython's builtin collections module because it doesn't have what I need in CircuitPython.
  • C++ lib's NETWORK_EXTERNAL_DATA message types do not get put into their own queue. This may change with the introduction of RF24Ethernet/RF24Gateway in the future.
  • C++ lib's MAX_PAYLOAD_SIZE is a dynamically set attribute call max_message_length
  • C++ lib's toggling of fragmentation (done with a compile-time macro) is a dynamic bool attribute called fragmentation. Changing this attribute will reduce some memory (but not that much), and also resets the max_message_length attribute accordingly.
  • C++ lib's begin() function is basically an attribute in this lib called node_address. The RF24Network class' constructor takes this node_address as a required parameter, so there is very little need to set the attribute after instantiation.
  • C++ lib's networkFlags member is replaced with a private boolean called _parenthood (which is only used by RF24Mesh.allow_children member). All other networkFlags are not necessary for this lib (or they were not actually used in the original C++ libs).

RF24Mesh

All RF24Network functionality is inherited into RF24Mesh.

  • C++ lib's MESH_NO_MASTER macro exists as a base class called RF24MeshNoMaster. Obviously, this is meant for nodes that don't need the code that mesh master nodes use.
  • The above mentioned node_address attribute cannot be set (it is read-only in RF24Mesh) because mesh nodes need to be automatically assigned an address from the mesh network master node per the unique node_id number. The node_id number can be changed though doing so will disconnect the node from the network (if it is connected)
  • C++ lib's address list is called dhcp_dict in this lib's RF24Mesh class. Currently, I'm not supporting persistence on Circuitpython MCUs because it requires a write-accessible file system or using circuitpython's nvm module (every write to NVM should be carefully controlled by the user because those chips have a limited lifetime of write cycles).
    • On linux, the dhcp_dict can be saved/loaded to/from a JSON file. This is not automatically done like it is in the C++ lib however.
  • C++ lib's DHCP() function is private function in this lib, and it is automatically called when needed on master nodes.

Examples revisited

All examples have been slightly modified to use constant-type names for the SPI_BUS, CE_PIN, & CSN_PIN.

New Wrappers

  • This lib now supports the C-extension module SpiDev from pypi.org. This module is much faster than using CircuiPython's pureio module, thus it is encouraged to use spidev.SpiDev objects instead of board.SPI objects on Linux.
  • I've incorporated the micropython wrapper I wrote on a different repo, but I have yet to test it since getting this lib (actually more like a full package now) onto a micropython board is very tedious.

@2bndy5 2bndy5 merged commit a3d8131 into master Nov 23, 2021
@2bndy5 2bndy5 deleted the rf24-network branch November 26, 2021 06:16
adafruit-adabot added a commit to adafruit/CircuitPython_Community_Bundle that referenced this pull request Nov 27, 2021
Updating https://github.com/2bndy5/CircuitPython_nRF24L01 to 2.1.0 from 2.0.2:
  > proofread docs
  > RF24Network, RF24Mesh, and RXing BLE (nRF24/CircuitPython_nRF24L01#33)
  > Create CONTRIBUTING.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BLE beacons Receiving port RF24Mesh port RF24Network
2 participants