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

update master branch from lite-beta branch #14

Merged
merged 131 commits into from
Oct 6, 2020
Merged

update master branch from lite-beta branch #14

merged 131 commits into from
Oct 6, 2020

Conversation

2bndy5
Copy link
Member

@2bndy5 2bndy5 commented Sep 12, 2020

many optimizations and fixes. Once this PR is merged, there will be a new release. Updated docs for this branch are live. Changes include:

New Modules

  • A lite version (rf24_lite.py) has been introduced for boards with limited available memory (e.g. ATSAMD21 core M0 based boards). Although, using TMRh20's Arduino/PlatformIO library is still highly recommended (especially for complex applications) as CircuitPython leaves little room for user-space code in this scenario. This lite version may not remain in the next release, so consider it experimental. Info about what was stripped away can be found in the docs (main difference is no context manager compatibility in the lite version). MemoryError: memory allocation failed on ATSAMD21 M0 boards #10
  • A new module named fake_ble.py has been added to implement using the nRF24L01+ as a fake BLE advertising beacon. Docs have been updated to include an example and describe the additional API including battery level, URL, and temperature measurement service data helper classes. FakeBLE class allows advertising a device name, the nRF24L01's pa_level as "TX power level", custom mac address, & a to_iphone flag to aim advertisements at different smartphones. This new fake_ble.py module is NOT compatible with the rf24_lite.py module.

Optimizations:

  • Constructor now only takes required parameters (spi, csn, & ce objects). This saves storage space and de-clutters the docs a bit. Notice there are setters for all attributes that were affected by all previously available kwargs to constructor. Per Possible to change the SPI bus speed on RPi before creation of RF24 object #15 the constructor also takes an optional kwarg spi_frequency to customize the frequency used for SPI transactions. However the SPI frequency cannot be changed after instantiating the RF24 or FakeBLE objects.
  • send() has been re-written. It now employs recursion when passing a list/tuple of payloads. Payload format checking now relies on internal write() call. send() no longer calculates a timeout, rather it blocks until a status flag is asserted by the ESB protocol from the nRF24L01 (application will only hang if there is a SPI bus malfunction). send() now only returns False or True; it can still return an ACK payload, but empty ACK payloads will show as True (not None). NEW send_only parameter to disable automatic fetching of ACK payloads when calling send() or resend() (this parameter defaults to False for backward compatibility).
  • Docs have been more adequately indexed in the sidebar navigation.
  • Fixed an issue where any() may have been returning incorrect data in some cases. This seemed to affect recv() also because it calls any() to get the RX'd payload length.
  • recv() now takes an optional parameter, length, that can manually specify how many bytes to read from the RX FIFO. Notice every attempt to read from the RX FIFO starts with the first byte (if available) in the top level of the RX FIFO. A payload is only removed when it is completely read from the RX FIFO.
    • If length is greater than payload in top level, then data from next available payload(s) is returned.
    • If length is greater than last available payload in RX FIFO, then the returned buffer is padded with the last byte in payload and payload is removed from FIFO. Also, the last byte read from RX FIFO is repeatedly returned when reading from an empty RX FIFO.
    • If length is less than payload in top level, the payload will remain in RX FIFO.
  • Doc strings split. Source code now only contains a brief description of functions/attributes (for quick usage of python's builtin help()). Detailed info on function parameters and attributes now live in online documentation. This reduced the size of source code stored on CIRCUITPY drive by more than 50% (84 kB -> 30 kB when using rf24.py -- rf24.mpy compiles to less than 20 kB).
  • Switched to Github actions instead of using travisCI.
  • Tested compatible with STM32F405 Feather (requires CircuitPython v6.x). Thank you @water5
  • Removed address_length check on open_rx_pipe() & open_tx_pipe(). The nRF24L01 will only save up to 5 bytes for addresses assigned to pipes 0 & 1 (1 byte max for the rest of the data pipes). Furthermore, the nRF24L01 will only use the first X number of bytes (where X is specified using address_length attribute) when reading addresses from the respective pipe address registers during automatic packet assembly.
  • write() now has an optional parameter called write_only. Use this parameter as True to fill the nRF24L01's TX FIFO before beginning transmissions.

Changes

  • read_ack() marked for deprecation. It is currently still available until the next major release for backward compatibility with previous versions of this library. I highly recommend using recv() instead as it is synonymous with read_ack()
  • IRQ attributes' names are now pythonic. irq_DS is now irq_ds, irq_DF is now irq_df, irq_DR is now irq_dr.
  • Context manager now powers down the nRF24L01 when exiting a with statement block. Context manager also now persists pipe addresses (both RX & TX).
  • pipe() is now a read-only attribute with same name (RF24.pipe)
  • RX & TX addresses can be fetched using the new address() function (read-only; see docs for more info).
  • Expanded info about data pipes in what_happened(True) to show expected payload_length setting for static payloads (when dynamic_payloads are disabled) only on open pipes.
  • Fixed typo in examples and readme about what MCU pin to connect to the nRF24L01's IRQ pin. Thank you @jerryneedell
  • Removed the reset parameter from close_rx_pipe(). It doesn't matter what the address for a data pipe is if that data pipe is closed. Error in v1.1.2 docs: addresses for data pipes do reset to factory defaults on nRF24L01 boot (when VCC goes from 0V to 3.3V).
  • NEW rpd attribute (read-only) for advanced usage. This can be used to detect interference or a carrier wave on a specific channel. Docs contain link to datasheet for more detail.
  • NEW start_carrier_wave() and stop_carrier_wave() functions to verify the nRF24L01 TX output is functioning. This a hardware test only. The carrier wave can be detected with another nRF24l01 listening for a rpd flag (example code in API docs).
  • pa_level now accepts list or tuple in addition to original functionality to compensate for the peculiar LNA_HUCRR bit used by nRF24L01 (non-plus variant) and the Si24R1 (cheap nRF24L01 clone).
  • NEW is_plus_variant attribute to determine if the nRF24L01 is a plus variant module or an older non-plus variant module. This attribute is also used internally to accommodate the difference in expected behaviors among the 2 variants.
  • dynamic_payloads, auto_ack, & payload_length all now take an optional tuple or list of parameters to control the respective features on a per pipe basis. A payload_length of 0 means that pipe remains unaffected. Setting a pipe's auto_ack or dynamic_payload feature to a negative number means that pipe will remain unaffected.
  • The interrupt pin example has been re-written to show how to use the write() function properly in conjunction with the nRF24L01's IRQ pin (while also using the nRF24L01's ack payloads feature). Notice that this example runs extremely quick as there are no unnecessary time.sleep() calls.

Testing 4-byte payloads on an ItsyBitsy M4 Express has shown that transmissions now take about 26-55 milliseconds (60-65 milliseconds for ACK packets with customized payloads).

tested using a compiled mpy file (for circuitpython v5)
employing my wrapper modules from another repo called circuitpython2micropython
abandon timeout calculations in send() & resend(). `payload_length`  is set to all pipes & removed internal `_pl_widths[]` for context manager as it was synonomous with `paylaod_length` anyway
@2bndy5
Copy link
Member Author

2bndy5 commented Oct 1, 2020

@jerryneedell I wrapped the PA/LNA module with electrical tape and then foil around that (for shielding). Then I wired up a PA/LNA module with a 3V regulator (L4931 with a 2.2 µF capacitor between Vout & GND) using my ItsyBitsy M4 5V (AKA USB) pin (going directly to the L4931 Vin pin). The following are experiences from running simple, ack, & stream tests with a reliable nRF24L01+ (no PA/LNA) on the other end (driven by a RPi2):

Ordered by different pa_level settings

  • 0 dBm 👎: master() worked the first time (during simple test) then continuously failed (during all tests). slave() worked on simple & stream tests, but the opposing master() node reporting that ACK packets (without payloads) were not received from the PA/LNA module; slave() failed to send ACK packet payloads during the ack test.
  • -6 dBm 🆗: master() worked consistently on simple, ack, & stream test. slave() worked reliably on simple & stream tests, but failed to transmit any ACK packet payloads in the ack test.
  • -12 dBm 👍: master() worked consistently on simple, ack, & stream test. slave() worked reliably on simple & stream tests, but failed to transmit some ACK packet payloads in the ack test.
  • -18 dBm 🥇: master() worked consistently on simple, ack, & stream test. slave() worked reliably on simple, ack, & stream tests, meaning all ACK packet payloads were successfully transmit in the ack test.

Side notes

  • I should add that changing the data_rate (tried all 3 -- 1 Mbps, 2 Mbps, & 250 kbps) had no noticeable effect during any of these trials.
  • I also noticed that master() transmissions were consistently quicker (when successful) on the PA/LNA module (never exceeded 32 ms -- usually only took 25 ms), but that may have more to do with all the improvements to this branch.
  • The nRF24L01's (non-plus variant) peculiar ACTIVATE command (nrf._reg_write(0x73, 0x50)) had no effect, meaning the PA/LNA modules may actually be plus variant modules. This is the only way I could tell since the command isn't listed in the plus variant datasheet, and the command has reportedly no effect on nRF24L01+ modules.
  • The BLE test worked in any pa_level except 0 dBm, but I can't imagine the usefulness of a PA/LNA module for BLE advertisements (feels like overkill).

Conclusion (finally)

The PA/LNA modules seem to require quite a bit more power to transmit. The L4931 regulator that I used in the tests boasts a 300 mA current limit and a typical current of 250 mA. While the ItsyBitsy M4 boasts a 500 mA max, it would seem that much of that is consumed internally. Since playing with the pa_level is a current saving hack (as noted in the datasheet), I can only imagine that a higher power 3V regulator may enable sending transmissions from PA/LNA modules (including ACK packets -- with or without ACK payloads attached) for higher pa_level settings. More testing is called for, but I don't have an oscilloscope ( ☹️ ) to measure the peak current draws.

I'll make the examples instigate -12 dBm pa_level for better exhibition (usually example scripts are run on modules in close proximity anyway). The TMRh20 Arduino library's examples also do this while that library's default setting (upon instantiation) is also 0 dBm.

@jerryneedell
Copy link

@2bndy5 Interesting results. Thanks for all the examples. The PA/LNA units sure are complex! I won't be able to do any more testing until this weekend, but will try to do some when I can.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 1, 2020

Today, using the L4931 regulator still wired up, I swapped out the shielded PA/LNA module with an un-shielded (bare) PA/LNA module (purchased from the same stock -- if that means anything) and ran the simple_test on all available pa_level settings. It failed to transmit anything (again); it could receive, but ACK packets did not get through (again). So, it would seem that shielding is equally important to higher power sourcing.

@jerryneedell
Copy link

Back home and trying a few more tests.
The 3 BLE tests all worked well with my iPhone. The "Physical Web" App see the URL beacon.
Thank you for getting this working!

Still having issues transmitting with the PA/LNA modules. I have not tried any alternative ways of powering it yet.
2 nRF24L01+ modules working well the stream test.

Will try to explore more of the examples later today and tomorrow.

@2bndy5
Copy link
Member Author

2bndy5 commented Oct 3, 2020

@jerryneedell that's great! I'll probably modify the BLE example to alternate advertisements between the different "PDU types" (basically that's what it boils down to). I also modified the context test to demonstrate how to use 1 nRF24L01 as a BLE device and a normal RF24 device in the same script. With your iPhone confirmation, I'm ready to release, but I want to give it another proofread and make sure it passes the all the tests again (you know -- "for good measure").

Heads up, I'll be changing the default setting of the to_iphone attribute to False.

@2bndy5 2bndy5 merged commit e3912e5 into master Oct 6, 2020
adafruit-adabot added a commit to adafruit/CircuitPython_Community_Bundle that referenced this pull request Oct 6, 2020
Updating https://github.com/2bndy5/CircuitPython_nRF24L01 to 1.2.0 from 1.1.2:
  > Merge pull request nRF24/CircuitPython_nRF24L01#14 from 2bndy5/lite-beta
  > found typos
  > badge missing target link
  > update badges & prepare switch to github actions
  > Update build.yml
  > Update build.yml
  > Create build.yml
  > deleting travis.yml
  > enabling github actions
  > updated examples for new returned format of send()
  > updated darkness.css for sidebar menu
  > (-) experimentals from logitech-mouse branch
  > updates from logitech-mouse branch
  > found pin conflict in irq example -> uses d12 now
  > context manager powers down radio on exit
  > changed spi bus attribute to a hidden attribute
  > docs badge links to stable releases
  > valid names: irq_D* => irq_d*, ce => ce_pin, etc
  > Delete .gitattributes
@2bndy5 2bndy5 deleted the lite-beta branch October 8, 2020 03:02
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.

2 participants