joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.47k stars 410 forks source link

Missed packets using RaspberryPi and nRF24L01. #611

Closed b1narygl1tch closed 4 months ago

b1narygl1tch commented 4 months ago

Hello! I'm experimenting with Raspberry Pi Zero 2 W and SPI-connected nRF24L01 module. I use Python library https://github.com/bjarne-hansen/py-nrf24 which uses pigpio (pigpiod). In nRF24L01 promiscuous mode I see some data on RX, but I definitely don't see packets from my Logitech mouse.

I checked with other project https://github.com/DigitalSecurity/raspjack which uses RPi.GPIO (https://pypi.org/project/RPi.GPIO/) and spidev (https://pypi.org/project/spidev/). Everything works as expected there.

I analyzed py-nrf24 library that I'm using, experimented with different parameters, compared libs outputs, nRF24L01 registers states, etc. It seems that the problem with pigpio library.

Would be appreciated for hints where to start digging to solve the problem!

P.S.: I don't have a logic analyzer.

guymcswain commented 4 months ago

Sure. Let's start with some basic testing. Since I've never used the Pi Zero 2 W, please run the Python x_pigpio.py test to verify the installation and that everything works on this platform.

Caution: Disconnect anything you have connected to GPIO 25 (Broadcom pin numbering)!

wget https://github.com/joan2937/pigpio/raw/master/x_pigpio.py
sudo pigpiod # if not already running
sudo python x_pigpio.py

All tests should pass: "TEST x.y PASS (blah blah)"

guymcswain commented 4 months ago

Also, please report the header output. For example, my header is:

Testing pigpio Python module 1.78 Python 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110] pigpio version 79. Hardware revision 12595477.

b1narygl1tch commented 4 months ago

@guymcswain thank you for the quick response!

All the tests have PASS status. Here is the header:

Testing pigpio Python module 1.78
Python 3.11.2 (main, May  2 2024, 11:59:08) [GCC 12.2.0]
pigpio version 79.
Hardware revision 9445664.
guymcswain commented 4 months ago

Good. Can you tell me more about what you did. In particular why you think it's a problem with the lib.

I analyzed py-nrf24 library that I'm using, experimented with different parameters, compared libs outputs, nRF24L01 registers states, etc. It seems that the problem with pigpio library.

Have you run any of the examples given from py-nrf24 library? Perhaps we should just focus on the simple-receiver.py and simple-sender.py

b1narygl1tch commented 4 months ago

I'm trying to implement MouseJack (https://www.bastille.net/research/vulnerabilities/mousejack/technical-details) on RPi + nRF24L01. May be "problem" was not a correct word from my side. Please, don't take it personally. I'm just trying to understand what's going wrong.

I've tried examples from py-nrf24 library, yes. I was able to send messages from one module and receive them at another using int-sender.py and int-receiver.py. I had to use IRQ, because both modules were connected to one RPi.

This is how I switch nRF24L01 module to promiscuous mode:

self.radio.set_pa_level(RF24_PA.LOW)
self.radio.set_data_rate(RF24_DATA_RATE.RATE_2MBPS)
self.radio.set_payload_size(RF24_PAYLOAD.MAX)
self.radio.set_channel(self.channel)
self.write_register(NRF24.EN_RXADDR, 0)
self.write_register(NRF24.SETUP_AW, 0)     
self.radio.open_reading_pipe(RF24_RX_ADDR.P0, self.__ADDRESS)
self.unset_auto_ack()
self.radio.disable_crc()
self.radio.show_registers() # For debugging purposes

Then my code reads RX like this:

channels = range(0, 126) 
channel_index = 0
self.channel = channels[channel_index]
self.radio.set_channel(self.channel)
last_tune = time.time()
while True:
    self.channel = channels[channel_index]
    self.radio.set_channel(self.channel)
    channel_index = (channel_index + 1) % (len(channels))
    last_tune = time.time()
    while (time.time() - last_tune) < ch_timeout: # ch_timeout is a function parameter
        while self.radio.data_ready():
            raw_data = self.radio.get_payload()
            address = ':'.join('{:02X}'.format(b) for b in payload[0:5])
            packet = self.extract_packet_from_raw_data(raw_data)

As I already said, I compared registers states for both scripts (mine and raspjack) and they have equal values. Many thanks for your help!

guymcswain commented 4 months ago

I compared registers states for both scripts (mine and raspjack) and they have equal values.

So, does this mean the issue can be closed?

b1narygl1tch commented 4 months ago

I compared registers states for both scripts (mine and raspjack) and they have equal values.

So, does this mean the issue can be closed?

The problem still exists. Despite setups and debug outputs (registers, SPI speeds, etc) for the both scripts are looking the same, I don't see packets from my Logitech mouse while using py-nrf24 and pigpiod. You can close the issue. I will use another library for my project.

Thanks a lot!

guymcswain commented 4 months ago

Yeah, given there's nothing more specific to go by and you've got a working solution, I'll close this.