nRF24 / CircuitPython_nRF24L01

CircuitPython driver library for the nRF24L01 transceiver.
http://circuitpython-nrf24l01.rtfd.io/
MIT License
45 stars 11 forks source link

write_value parameter of spi.readinto() is incompatible with STM32F405 Feather #13

Closed water5 closed 3 years ago

water5 commented 4 years ago

I test it on STM32F405RG, CircuitPython 6.0.0 Alha 3,

from nrf24l01_simple_test import *

nRF24L01 Simple test. Run slave() on receiver Run master() on transmitter

slave()

Traceback (most recent call last): File "", line 1, in File "nrf24l01_simple_test.py", line 58, in slave File "rf24.py", line 394, in open_rx_pipe ValueError: address must be a buffer protocol object with a byte length equal to the address_length attribute (currently set to 14)

And test it on RPi with same way, not have this issue.

2bndy5 commented 4 years ago

Thanks for bringing this to my attention. I personally have not tested the library under circuitpython 6 (note that you're using a alpha release which can be unstable). This error is from the check on this line. There 2 things that could be wrong

  1. The error says your address_length attribute is set to 14. This shouldn't be possible, and the nrf24l01 isn't capable of handling addresses larger than 5 bytes.

  2. The address variable in the simple example is declared like a bytearray or bytes object (which are acceptable "buffer protocol objects"). Unless you changed the address variable in your code, it should already be in a "buffer protocol object".

I think you have the address_length attribute set improperly. Remember that the address_length must be the number of bytes (or characters) in the address. There is a preventative check when setting the address_length attribute that keeps the attribute's value in the proper range (3 <= value <= 5).

water5 commented 4 years ago

How should I test the address and address_length final output (characters and length) via simplest code, I want to test it on each platform or Python version(pure python and CircuitPython), I guess different method effect to the address and/or address_length on different Python version, because I use same "nrf24l01_simple_test.py" (nothing change, address = b'1Node', address_length=5), but on RPi the test result correct.

2bndy5 commented 4 years ago

Try downgrading the firmware on your STM32F405RG to CircuitPython 5 latest stable release

Also if you're using the rf24.mpy file, make sure you're using the version of the mpy file that was built for the version of the CircuitPython firmware that your board is using. Recommend you grab the proper mpy file from the community bundle's latest release or just use the normal rf24.py file

2bndy5 commented 4 years ago

@water5 any progress?

After you have from nrf24l01_simple_test import * in the CircuitPython REPL, you can verify address_length value and the address variable's datatype before or after you try slave() or master().

To verify address_length, type nrf.address_length which should return what the attribute is set to. You can change this by using nrf.address_length = 5. More info is available in the docs

To verify proper datatype of the address variable, type type(address) which should return something like <class 'bytes'>. More info about the type command is available in the python docs

I don't have an STM32F405 feather to test this library on, so I cannot personally reproduce this issue. Everything I'm reading about that board on Adafruit seems like CircuitPython support is still being developed. Normally I would recommend the Arduino IDE (or platformIO) and TMRh20's RF24 library, but it seems that library hasn't added support for the STM32 family (as far as I know).

water5 commented 4 years ago

Thanks for your answer. I check these variable after from nrf24l01_simple_test import * and nothing to change (except CE, CSN define): nrf.address_length

14

and the nrf.address_length 's value can't change,

nrf.address_length = 5 nrf.address_length

14

and the nrf._addr_len , address 's value: nrf._addr_len

5

address

b'1Node'

Because refer this document : https://circuitpython-nrf24l01.readthedocs.io/en/stable/index.html , hardware wiring base on ItsyBitsy M4, CE -> D4 CSN -> D5 IRQ -> D4

But on Feather STM32F405 Express does't has D4, I wiring with below: nRF24L01 -> Feather STM32F405 Express

GND -> GND VCC -> 3.3V CE -> D5 (PC7) CSN -> D6 (PC6) SCK -> SCK (PB13) MOSI -> MOSI (PB15) MISO -> MISO (PB14) IRQ -> D5 (PC7)

Feather STM32F405 Express D5 replace ItsyBitsy M4 D4 Feather STM32F405 Express D6 replace ItsyBitsy M4 D5

already change: ce = dio.DigitalInOut(board.D5) csn = dio.DigitalInOut(board.D6) in nrf24l01_simple_test.py

Is it possible some Pin status affect registers value readed ? or the nRF24L01+ hardware version difference ?

2bndy5 commented 4 years ago

Have you installed CircuitPython 5 (latest stable release) on your STM32 Feather? Are you using the rf24.py file or the rf24.mpy file in the /lib/circuitpython_nrf24l01 folder on your STM32 Feather?

The IRQ pin setting (board.D5 ) was a typo from when I consolidated the examples from both Raspberry Pi and itsybitsy M4 separated files. The master branch has been updated, but not re-released yet. In fact the IRQ pin is not required for the simple_test as stated in the readmet. This may not be your problem (but it is a problem) because the CE pin (what you also connected to board.D5) is only used to begin/end radio RX/TX transmissions and having the IRQ pin tied to the CE pin can screw up proper transmissions.

Thank you for also showing me the value of the internal _addr_len attribute. I can tell you that some how the value being set to the address_length attribute to is getting left shifted by 2, and I don't know why. The SetupAW register (at hex address 0x03) that holds the address length only accepts numbers 1, 2, & 3, which translates to 3, 4, & 5 in the nRF24L01 firmware (notice the values differ by 2). I've heard of nRF24L01 counterfeits that reportedly don't function properly, but I fortunately have never accidentally bought any.

So technically this is what is supposed to happen: when you set nrf.address_length = 5, the SetupAW register should contain the value 3 (but it contains the value 12 for you). nrf.__addr_len is meant to used (internally) for quick access without SPI transactions later in the RF24 class, however its not being used in nrf.open_rx_pipe(). nrf.open_rx_pipe() is actually using self.address_length which returns (the value in the SetupAW register + 2).

I've made a commit to my "lite-beta" branch (currently my developing branch) so that nrf.open_rx_pipe() will use self._addr_len in the next release. I don't know why the value for address_length is getting left shifted by 2 ((5 - 2) << 2 = 12; & obviously 12 + 2 = the returned 14). The best recommendation I can make:

  1. be sure you are running the stable release of CircuitPython (as of this writing, that is v5.3.1)
  2. disconnect the IRQ pin from the STM32 Feather or connect it to a different unused pin (the CE and IRQ pins on the nRF24L01 should not be sharing the same pin on the STM32 Feather).
  3. do from nrf24l01_simple_test import * and set nrf.address_length = 5
  4. verify the register contains the value 3 by using nrf._reg_read(0x03) (or bin(nrf._reg_read(0x03)) for the representation in binary).

If the register does not contain the value 3, then I have no idea what's going wrong (assuming you have not changed the rf24.py file). Note that the specification sheet says that the SetupAW register can only contain the value (in binary) 0b000000xx where xx cannot be 00 and must be 01, 10, or 11. I am curious; does it still return 14 if you set nrf.address_length = 3?

water5 commented 4 years ago

I disconnect IRQ pin, and:

  1. (on CircuitPython 6.0.0 Alpha 3), do these: from nrf24l01_simple_test import * nrf.address_length = 5 nrf._reg_read(0x03)

14

nrf.address_length = 3 nrf._reg_read(0x03)

14

  1. (on CircuitPython 5.3.1 Release), from nrf24l01_simple_test import * arise strange phenomenon, the NeoPixel LED off (in REPL it should be steady white), REPL stop respone, but the CIRCUITPY drive work still. I guess the SPI, adafruit_bus_device.SPIDevice work incorrect?

All test using .mpy file, because if use .py file, will arise MemoryError: memory allocation failed. STM32F405RG and ATSAMD51 has same size RAM (192Kb), I think ItsyBitsy M4 can't run the library via .py file format also.

If possible, please test nrf24l01_simple_test.py on your ItsyBitsy M4 with CircuitPython 6.0.0 Alpha 3. I will find what 's problem continue.

2bndy5 commented 4 years ago

Ok if you got the same 14 returned from a different address_length value, then it must be a problem with SPI some how (not a mysterious left shifting by 2 problem).

I developed the library on the itsybitsy m4 using the .py file and a multitude of other files on circuitpy drive, and I never ran into that memory error. Only the atsamd21 gives me that memory error. I will set up the M4 with the circuitPython 6 alpha build and get back to you.

EDIT: Found this comment about the memory. Apparently it's actually smaller RAM size than the store page says for the STM32 Feather

2bndy5 commented 3 years ago

ok, I've run the nrf24l01_simple_test.py on my ItsyBitsy M4 under both CircuitPython v5.3.1 and v6.0.0 Alpha 3 using the rf24.py file. No problems on my end. I'm sorry, but this error you're experiencing is specific to the STM32 Feather. I cannot reproduce the error since I don't have an STM32 Feather board.

Make sure you using the right mpy files

If you can, verify that the rf24.mpy file is from this community bundle that has been built for CircuitPython v6.x. You can find the adafruit_bus_device mpy files here (built for CircuitPython v6.x). It is very important that you're using the right mpy files because they're specifically built for each major version of CircuitPython. This solved a problem for someone else that raised an issue for this library.

Debugging the hardware

If the problem persists, have a look at the issues raised on the adafruit/circuitpython repo about the STM32 Feather. Another thing you can do to debug this error is hook up a 3-channel oscilliscope (maybe find a friend has one - they're not cheap) to capture the I/O signals on the MOSI, MISO, & SCK pins and make sure they're doing what they're supposed to. Also make sure that the STM32 Feather pins you connected to the CSN & CE pins are actually going HIGH and LOW using the digitalio library and an LED (with resistor).

The STM32 Feather has a debugging port on the back to help debug the software that's running on the board. Although it requires soldiering additional pins and additional hardware to interface with this port. Typically, this tactic is used to debug custom builds of CircuitPython.

I'm sorry you're experiencing this issue, but the problem is most likely not specific to this library.

water5 commented 3 years ago

Thanks your reply, I figuring it, it looks like CircuitPython SPI bus implement on STM32F405RG issue, I try other SPI relate device (e.g. wiznet5k) on CircuitPython 5.3.1 Release, has same issue (NeoPixel LED goes off, REPL stop respone).

Actually, I run this library on MicroPython works fine before : https://github.com/micropython/micropython/tree/master/drivers/nrf24l01 so the hardware should be ok.

2bndy5 commented 3 years ago

Yes, that is the source that this library started from, but it doesn't have many features that this library offers. Using dynamic payloads, disabling auto-ack packets, and appending custom payloads to the ack-packets are the major features missing in that micropython module.

I read through the issues on CircuitPython about the STM32, and one of the experts kept saying that micropython support for that board should work fine.

water5 commented 3 years ago

It looks like CircuitPython SPI bus implement on STM32F405RG issue, I try other SPI relate device (e.g. wiznet5k) on CircuitPython 5.3.1 Release, has same issue (NeoPixel LED goes off, REPL stop respone).

This issue only raise on CircuitPython 5.3.1 Release, on 6.0.0 Alpha-3, this issue looks like fixed, I run Wiznet5k (SPI interface device) on CircuitPython 6.0.0 Alpha-3 all functions OK. So, on CircuitPython 6.0.0 Alpha-3, I'm not ensure CircuitPython SPI bus issue is the source of nRF24L01 address_length incorrect problem.

2bndy5 commented 3 years ago

I'm not ensure CircuitPython SPI bus issue is the source of nRF24L01 address_length incorrect problem.

I don't understand what this sentence means. Could you try with your native language? Is this issue still a problem?

Did you make sure you're using the right mpy file? I wrote a whole paragraph about it in a previous post

water5 commented 3 years ago

My mean on CircuitPython 6.0.0 Alpha-3 SPI bus issue already fixed(but maybe not all also), I guess on CircuitPython 6.0.0 Alpha-3 this problem should not be occur. I will check all again.

water5 commented 3 years ago

Is it possible #3381 cause address_length incorrect ?

2bndy5 commented 3 years ago

before I release this, could you test it?

circuitpython_nrf24l01-6.x-mpy-cff9267.zip

You will find 2 files in the zip's /lib/circuitpython_nrf24l01 folder. You only need to copy the rf24.mpy and __init__.py file. The rf24_lite.mpy is a extremely slimmed down version I was using for ATSAMD21 memory issues. The example files may use different import statements so copy the nrf24l01_simple_test.py file from the examples folder also.

water5 commented 3 years ago

from nrf24l01_simple_test import *

Traceback (most recent call last): File "", line 1, in File "nrf24l01_simple_test.py", line 25, in File "rf24.py", line 52, in init File "rf24.py", line 470, in payload_length File "rf24.py", line 157, in _reg_write AttributeError: 'RF24' object has no attribute '_spi'

2bndy5 commented 3 years ago

Sorry. I forgot I left my lite-beta branch in an unstable state. I'm debugging as I write this. I'll get back to you when the simple_test runs on both rpi and my m4.

2bndy5 commented 3 years ago

updated version! This tested fine for the nrf24l01_simple_test.py, nrf24l01_ack_payload_test.py, and nrf24l01_context_test.py examples using a Raspberry Pi 2 and a ItsyBitsy M4. As for nrf24l01_stream_test.py example, my Raspberry Pi 2 is having trouble receiving data from my ItsyBitsy M4, although sending from Raspberry Pi 2 to my ItsyBitsy M4 works perfectly fine.

circuitpython_nrf24l01-6.x-mpy-784ad6f.zip

water5 commented 3 years ago

Yes, RPi(master()) -> STM32F405(slave()) works fine, STM32F405(master()) -> RPi(slave()) sometimes receive incorrect. Focus on large different transmission time between two scene?

I tested nrf24l01_simple_test.py only currently, other examples, I need more time to understanding the code.

2bndy5 commented 3 years ago

Yea, I've been fighting the Raspberry Pi's slower SPI transactions (seems to stem from the firmware's SPI kernel). I'm still trying to debug that issue, but it is a separate issue because its specific to the Raspberry Pi.

Nonethless, this is an absolute acheivment. I couldn't have done it without you. Thank you again for bringing this to my attention. Can you close the other issue you opened on the circuitpython repo? I will post news of our success as a reminder on that issue.

water5 commented 3 years ago

I only test something on this issue, all code improving works by you, even few understanding about nRF24L01 hardware.

2bndy5 commented 3 years ago

Found this issue for the TMRh20 library about STM32 compatibility.

2bndy5 commented 3 years ago

@water5 Please update your mpy file with the new release I have found (and fixed) a few bugs with the file I sent you. Plus I added BLE capability...