Skip to content

Releases: nRF24/CircuitPython_nRF24L01

Bug fix about connecting mesh nodes

05 Sep 10:31
74df26e
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.1.2...2.1.3

repo updates

26 Oct 04:36
Compare
Choose a tag to compare

What's Changed

Full Changelog: 2.1.1...2.1.2

Dropped support for MicroPython

16 Jun 08:27
9ce1c68
Compare
Choose a tag to compare

This revokes the experimental support for micropython. Going forward, it'd be better to rely on adafruit-blinka's progress toward micropython support (adafruit/Adafruit_Blinka#480) which is currently hindered for the same reason I'm revoking it here - the utime lib.

Other various changes include:

  • revert all use of f-strings back to str.format().
  • Complete type hinting. I'm worried this might break compatibility with much older versions of CircuitPython, but v6+ is highly recommended for execution speeds (v7+ is better with mpy compression).
  • RF24 class uses allocated _in and _out buffers (instance attributes) for SPI transactions. This is based on some "pro-tips" about using micropython.
  • various doc updates.
  • improved network example to allow receiving while idling during emit()
  • improve setup.py for MacOS installs
  • allow saving/loading DHCP as a binary file. This should help people to migrate existing networks that use the C++ RF24Mesh library.

RF24Network, RF24Mesh, and RXing BLE #33

26 Nov 06:10
Compare
Choose a tag to compare

Adds new features

  • RF24Network ported from TMRh20 C++ library (not WiFi compatible)
  • RF24Mesh ported from TMRh20 C++ library (not BLE/802.11 mesh compatible)
  • sniffing/receiving BLE payloads. This is still subject to the limitations of the nRF24L01 as have been outlined in the fake_ble module's docs.

See #33 for more details.

Also improved speed in certain aspects of the RF24 class.

patch update

07 Jun 18:27
397ea51
Compare
Choose a tag to compare

fix faulty logic in if self.is_plus_variant statement when setting RF data rate to 250 kbps(#27). Thank you @bhartung

patch and doc updates

29 Jan 22:48
9b8e3c2
Compare
Choose a tag to compare

This release includes:

  • A fix that avoids disabling auto_ack on pipe 0 when only pipe 0 has auto_ack enabled.
  • found and fixed several inaccuracies in docs

Retroactive Release

29 Jan 02:21
Compare
Choose a tag to compare

This release is a retrofitting of non-breaking backward compatible features introduced in v2.0.0. However, this also fixes 1 bug that allowed a flood of subsequent errors:

  • payload_length returns the setting for only pipe 0. This attribute can still be used to set individual pipes (see docs), but in v1.2.0-v1.2.3 it returned an internal list that prevented properly setting payload lengths for individual pipes. This error would also cause malfunctions in any(), send(), resend(), recv(), and write(). Use the new get_payload_length() function to retrieve the current setting for any pipe.

New features

  • Huge Speed-up (~10x faster transmissions)!
  • Examples retrofitted to be forward compatible not backward compatible. Additionally, all examples (except nrf24l01_context_test.py and nrf24l01_fake_ble_test.py) are compatible with the new examples in TMRh20's RF24 library (I wrote those examples also 😉 ). Conversely, the examples still use time.monotonic() to preserve compatibility with CPython v3.4 where v2.0.0 now requires CPython v3.7+ on Linux (because that's when time.monotonic_ns() was introduced).
  • Examples can now also be executed from Linux CLI (no need to keep from example_name import * anymore - but you still can).
  • New scanner example (warning: it runs a bit slower on older RPi). Also replaced nrf24l01_2arduino_handling_data.py with nrf24l01_manual_ack_test.py.
  • New available() function provided as a convenience instead of using nrf.update() and nrf.pipe is not None (a technique introduced in v1.2.3). Because FakeBLE class now inherits from RF24 class, this new function is overridden in the FakeBLE class with the existing available() function to prevent breaking backward compatibility. The difference in functionality will really only affect those trying to implement receiving BLE advertisements (officially unsupported at this time) using the FakeBLE API.
  • New set_*() and get_*() methods for auto_ack, dynamic_payloads payload_length, and ard/arc attributes. ard/arc attributes are consolidated into *et_auto_retries() methods (because they live in the same register on the nRF24L01).
  • Much more underlying optimizations listed in v2.0.0 release description under "Code Changes Include" section... However, auto_ack and dynamic_payloads attributes still return boolean (not integers like in v2.0.0).

Final Release

This will likely be the last release for v1.x. I just couldn't leave users constricted to using v1.x without the huge speed-up implementation and a known bug.

What I learned from TMRh20 and more

25 Jan 02:12
2ce7a1b
Compare
Choose a tag to compare

Breaking backward compatibility changes

  • NEW available() function provided as a convenience instead of using nrf.update() and nrf.pipe is not None (a technique introduced in the last release). To expose this new available() function in the FakeBLE API, I had to rename the current available() function to len_available().
  • RENAMED recv() is now read(). The descriptive name read() makes more sense because this function isn't actually doing the receiving, rather it is simply reading payload data that was already received and stored in the radio's RX FIFO.
  • RENAMED what_happened() to print_details(). The name "what_happened" came from my misunderstanding of the TMRh20 library's RF24::whatHappened() (& partly I just liked the name). Now, using "print_details" makes more sense because it is an apt description of what the function actually does.
  • REMOVED FakeBLE.to_android attribute because it was marked for deprecation.
  • REMOVED RF24.read_ack() function because it was marked for deprecation.
  • All examples now use time.monotonic_ns() to measure transmission times. This change requires Python v3.7 in Linux, thus setup.py stipulates this requirement via python_requires option. Recommend using latest release of the Raspberry Pi OS which ships with Python v3.7.2 (as of this writing).
  • auto_ack returns an integer (instead of a boolean) where each bit represent the feature's setting about a pipe.
  • dynamic_payloads returns an integer (instead of a boolean) where each bit represent the feature's setting about a pipe.
  • payload_length returns the current setting of pipe 0 instead of a list for all pipes. This actually fixes a bug that allowed a flood of other subsequent bugs.
    • In v1.2.0 - v1.2.3, if a user called payload_length[0] = 0, there was nothing in the code to prevent this mis-configuration (payload length cannot be 0). Furthermore this mis-configuration was not written to the corresponding nRF24L01 registers which would cause errors in every other function that handled payloads and/or payload lengths (namely any(), send(), write(), recv(), & what_happened(True))

Code Changes Include

  • TRANSMISSIONS THAT PREVIOUSLY TOOK 32 MILLISECONDS NOW TAKE ABOUT 2 OR 3 MILLISECONDS!!! (~10x Speed-up!) I've achieved this huge speed-up by removing the time.sleep(0.005) calls in the SPI access functions. To compensate for the inherent CSN pin bouncing instability, I've implemented the extra_clocks=8 parameter to Circuitpython's SPIDevice c'tor. Essentially this means that after the CSN pin is set inactive HIGH, the SPIDevice object writes another dummy byte to let the CSN pin settle. This technique is faster than trying to do a time-based delay using time.sleep() (& also turns the disadvantage of Python's slow execution time into more of a strength). I'm aware that this technique is meant for SD cards and is dependent on the SPI bus' frequency, but if we encounter problems... I'll cross that bridge if we come to it.
  • Removed any other time.sleep() call that waited for less than 100 microseconds. Also, I took an idea from TMRh20's RF24::write() and moved the ce_pin.value = 0 call to after the resulting status flags are asserted.
  • REMOVED the CSN_DELAY constant since altering its value had no real-time affect on the SPI access functions. Additionally, it isn't needed anymore due to the first point about implementing the huge speed-up.
  • listen no longer flushes RX FIFO when entering RX mode.
  • listen now flushes TX FIFO when entering TX mode and ack payloads are enabled.
  • listen closes pipe 0 if it hasn't been designated for RX when entering RX mode.
  • open_tx_pipe() does not actually open pipe 0 when auto_ack is enabled. Rather, listen now opens pipe 0 when entering TX mode and auto_ack is enabled for pipe 0.
  • send() & resend() doesn't clear the Status flags when finished anymore. This change will likely have little impact on applications since the status flags are still cleared when entering write() and resend(). This was done to speed up execution.
  • auto_ack now force-enables the automatic acknowledgement feature for pipe 0 when any other RX pipe has auto_ack enabled.
  • NEW set_*() & get_*() publicly exposed functions for auto_ack, dynamic_payloads, payload_length, & ard/arc attributes. These should allow faster, easier, & less error-prone interaction when setting or getting the configuration for said attributes on any individual pipe or all pipes at once. I haven't deprecated the attribute's older setter-decorated functions for backward compatibility (the new set_*() functions still utilize the attribute's setter-decorated functions as helpers).
  • ard, arc, & crc attributes now clamp invalid input values instead throwing a ValueError exception.
  • NEW allow_ask_no_ack attribute for unofficial support of the Si24R1 (a flaw from cloning a typo in the nRF24L01 datasheet)
  • NEW last_tx_arc attribute for getting the number of retry attempts made in previous transmission. This data was previously only available in what_happened(), I found it useful when helping people troubleshhoot TMRh20's RF24 library.
  • FakeBLE now inherits from RF24. Some attributes/functions are overridden to raise a NotImplementedError exception, so some vital ingredients to the BLE operation isn't compromised via the FakeBLE API.
  • close_rx_pipe() now properly prevents the listen attribute from overriding the pipe 0 reading address
  • print_details() now prints a more accurate representation of the addresses used on the pipes. Like the TMRh20 RF24 library's printDetails(), the address now prints a "hexlified" string in big endian form.
  • NEW address_repr() function (belonging to the rf24.py module not the RF24 class) is the helper function that returns the address specified as a "hexlified" string in big endian form.

Revised examples + new nrf24l01_manual_ack_test.py & nrf24l01_scanner_test.py

  • NEW scanner_test example that prints a vertical graph of potential RF interference for all applicable frequencies (vertically labeled by channel number).

  • In making a similar contribution to TMRh20's RF24 library, @TMRh20 kindly emphasized the importance of demonstrating "proper addressing" related to pipe usage. To show my appreciation for the discussion (& lessons learned), the examples have all (except the multiceiver example) been revised to use pipe 0 for TX & pipe 1 for RX. This revision adds a preliminary prompt that asks "Which radio is this?" Whereby:

    • entering 0 uses b"1Node" on pipe 0 and b"2Node" on pipe 1
    • entering 1 uses b"2Node" on pipe 0 and b"1Node" on pipe 1
  • some examples' payloads have also been altered. This has been done to match the new examples I've submitted to TMRh20's RF24 library.

    • simple_test uses a incrementing float that persists between calling master() & slave()
    • ack_payload_test shows data structure usage and C-string's NULL terminating char with a counter that increments on successful transmissions and persists between calling master() & slave()
    • NEW manual_ack_test mimics the ack_payload_test, but it doesn't use ACK payloads. Rather it uses manually switch between RX/TX modes.
    • multiceiver_test uses an 8 byte payload that is properly packed using Python's struct library (instead of directly encoding the UTF-8 data into the bytearray)
  • REMOVED nrf24l01_2arduino_handling_data.py in favor of the NEW nrf24l01_manual_ack_test.py example (they're practically identical).

  • Compatibility with TMRh20's library now only requires;

    1. dynamic_payloads has to be disabled
    2. payload_length has to be set accordingly to match TMRh20's RF24 new examples' configuration

    I've left these 2 lines commented out for easy modification (instead of typing it in the python REPL). Because most examples are compatible with TMRh20's new examples, the docs now have a table and hints about making this library compatible with TMRh20's RF24 library (instead of using 1 dedicated example).

  • multiceiver_test doesn't use ACK payloads for node(1) anymore. This demonstration was a bit over zealous anyway, and removing it better matches the multiceiverDemo.ino example I submitted to TMRh20's RF24 library.

  • all examples can be executed from CLI. This change is really helpful in that it requires less typing and less prone to typos (using terminal's auto-complete mechanism). This really only applies to the Linux platform, and there is no support for CLI args because CircuitPython firmware doesn't use them.

Other changes

  • Behold the new project Logo for usage on rtfd.io and social media links
    image
    Also changed the favicon to a miniature version of this logo. This should fall under the repo's MIT license, and I'm pretty sure its not as original as I think it is.
  • changed docs theme to use sphinx-material theme (better display on mobile screens)
  • Of course, there are corresponding doc changes to suit all code changes.
  • Docs now contain retroactive changes related to different versions of the library using Sphinx's admonitions .. versionadded:: and .. versionchanged::.
  • I've added a feature to the Github action build.yml workflow: Archiving built assets (namely the mpy files for Circuitpython firmware) as workflow artifacts that can be downloaded (for up to a maximum of 90 days).
  • The PyPi upload process now uses an API key because my PyPi account has 2FA enabled.

Better utility for write() & update(); stream test revised

16 Oct 22:54
Compare
Choose a tag to compare

Library changes (rf24.py and rf24_lite.py)

  • update() now always returns True
    • this allows for calling the update() function in a conditional statement.
      e.g. if nrf.update() and nrf.pipe is not None: (which is a bit faster than using if nrf.any(): as some of the examples used prior to this change)
  • write() returns a boolean describing if the payload was written to the TX FIFO
  • new master_fifo() function in the stream example to compare with original master() function.
    • master_fifo() uses the write() function to utilize all 3 levels of the TX FIFO. This function can provide some additional incite as to how many failed transmissions get retried when using send(buf, force_retry=2) in the original master() function.
    • master() still uses the send() function, but only manages 1 level of the TX FIFO (as it always has).
  • I got tired of changing the addresses in the 2arduino_handling_data.py example, so I mirrored the use of the radioNumber boolean variable from the TMRh20 library's GettingStarted_HandlingData.ino example. I also adjusted some function calls in this example script to show how this library behaves a little differently internally (as compared to the TMRh20 library); these adjustments now closely match the behavior of the TMRh20 library's behavior.
  • As always, I found more errors in the docs; this time it was about what fifo() returned when the check_empty parameter isn't specified. There were some insignificant typos too.

This release's revised stream test seems to have most significant performance differences on the Raspberry Pi. The following is my test result on the RPi2:

>>> from nrf24l01_stream_test import *
    nRF24L01 Stream test
    Run slave() on receiver
    Run master() on transmitter to use 1 level of the TX FIFO
    Run master_fifo() on transmitter to use all 3 levels of the TX FIFO.
>>> master()
Transmission took 1630.3276280164719 ms
successfully sent 100.0% (32/32)
>>> master_fifo()
Transmission took 1002.7778159976006 ms with 20 failures detected.

HINT: Try playing with the 'ard' and 'arc' attributes to reduce the number of
failures detected. Tests were better with these attributes at higher values, but
notice the transmission time differences.
>>> # max out the auto-retransmit feature's attributes
>>> nrf.arc = 15
>>> nrf.ard = 4000
>>> master_fifo()
Transmission took 990.8866219520569 ms with 0 failures detected. You Win!
>>> master()
Transmission took 1595.034959077835 ms
successfully sent 100.0% (32/32)

correcting confusion about BLE advertisement's PDU type

09 Oct 12:28
Compare
Choose a tag to compare

Thanks to generous testing done by @jerryneedell, This release clears up some confusion/misconception I had about what PDU type to use in the BLE advertisements.

original misconception

PDU type 0x40 only worked for iPhone, and PDU type 0x42 only worked for Android. Thus the FakeBLE.to_iphone attribute would act in accordance with this misconception.

correct implementation

PDU type 0x40 does not work for Android, but it does work for iPhone. PDU type 0x42 works for both iPhone and Android smartphones.

Changes

  • The FakeBLE.to_iphone attribute is now FakeBLE.to_android.
  • The default value for the FakeBLE.to_android attribute is True. This means BLE advertisements use PDU type 0x42 by default which targets both iPhone & Android smartphones.
  • removed any use of the old FakeBLE.to_iphone attribute from the nrf24l01_fake_ble_test.py example.
  • Updated the docs accordingly
  • Marked the new FakeBLE.to_android attribute for deprecation (on next major release) as it is no longer necessary to specify which BLE advertising PDU type to use.