0

I am using BLavery's lib_nrf24 library with an nRF24L01 module on my pi running Octopi (it's pretty much rasbpian for the purposes here, AFAIK - here is the result of the os-release command).

PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

I am able to setup the radio according to this tutorial, but the code that waits for the radio to receive data;

    while not radio.available(0):
        time.sleep(1/100)

throws an OSError (errno 9) Bad file descriptor. Here is the full error traceback:

Traceback (most recent call last):
  File "main.py", line 72, in <module>
    main()
  File "main.py", line 18, in main
    while not radio.available(0):
  File "/home/pi/smarthome/lib_nrf24.py", line 506, in available
    status = self.get_status()
  File "/home/pi/smarthome/lib_nrf24.py", line 293, in get_status
    return self.spidev.xfer2([NRF24.NOP])[0]
OSError: [Errno 9] Bad file descriptor

I found this stackoverflow post about what OSError is and means, but I'm not sure how this would help me figure out what is going on in the lib_nrf24 library, and how to make it work so the radio behaves normally.

The post says that this error can be thrown if a file is opened, and closed elsewhere so the current environment thinks it is still open, and throws this error when it tries to close the file. The implicating code in the library is just a return statement;

    def get_status(self):
    return self.spidev.xfer2([NRF24.NOP])[0]

And I'm not learning anything more from looking at the available method that calls the get_status

    def available(self, pipe_num=None):
    if not pipe_num:
        pipe_num = []

    status = self.get_status()
    result = False
    ...

I've searched for any posts that mention both the lib_nrf24 library and any of 'OSError' 'errno 9' or 'Bad file descriptor' and come up with zero hits for the intersection of these two issues.

I realize on the lib_nrf24 github page it says the library is out of support as of May 2018. Am I out of luck? I couldn't find a more recent python library for these rf modules. The only other approach I have seen is to figure out how to use the c++ boost libraries to use the tmrh20 library... but I've looked at that and couldn't figure it out.

Ingo
  • 42,107
  • 20
  • 85
  • 197
sideways8
  • 11
  • 2
  • 1
    Please don't present only links to understand your problem. Most of us will not follow it because to much effort.. Explain what's the problem by yourself so we can understand it only from the question. Please take the short Tour and visit the Help Center to get an idea how things work here. – Ingo Apr 21 '20 at 09:14
  • The following similar question seems already has an answer: https://raspberrypi.stackexchange.com/questions/107608/rpi-spi-nrf24l01-2-4ghz-transceiver-module-send-message-to-arduino-problem. – tlfong01 Apr 21 '20 at 14:50
  • Your error message seems origins from this statement "return self.spidev.xfer2([NRF24.NOP])[0]". The "spidev.xfer2" is a standard SPI transfer operation. It appears that the parameter "([NRF24.NOP])[0]" is causing the trouble.The traced back statement is a statement in the "lib_nrf24" which is just python. The 2018 May version is the author's last beta. He says he verified the basic operation, and so far nobody complains. Perhaps you might like to insert debug print statements around the "get_status()" method, to check out what causes the trouble. In other words, bug is at python level, not C. – tlfong01 Apr 21 '20 at 15:06
  • 1
    @Ingo I've really tried to do that, I explicitly stated the errors I am getting, and I summarized the post I linked to, saying what is relevant from it. I put the code from the library I linked in this post as well. I really think everything is in this post - can you be more specific about what I could've done differently? – sideways8 Apr 22 '20 at 00:45
  • 1
    @tlfong01 Yes, I know the error is from the python code in the library. I am only using python in this project. I tried printing the information that the get_status method needs to return, but then the print statement throws the same error; Bad file descriptor. Where can I find more information about spidev.xfer2 ? The spidev library I have is github.com/Gadgetoid/py-spidev, and I don't know what I should look for in this library to solve this issue. – sideways8 Apr 22 '20 at 02:17
  • Hi @sideways8, Yes, you need to know more about spidev.xfer2. I did have trouble using spidev in another project. Perhaps you may like to skim my problem on the part about spi sorrows: (3) SPI MFRC522 NFC reader notes  https://raspberrypi.stackexchange.com/questions/109773/how-can-rpi-python-read-a-mfrc522-pn532-nfc-rfid-mifare-smart-card-tag (3a) Part 3 - SPI Loopback test, (3b) Part 4 - Where is spidev, (3c) Ref 28, 32, 40 - SPI gitHub, spec, python loopback test program. – tlfong01 Apr 22 '20 at 04:22
  • Let me summarize the causes of trouble. (i) There are a couple of SPI variants associated with different libraries. If you pip install or git clone, the spidev for the particular library might be placed together with the library and example programs. So you need to make sure you are using the correct spidev. Part 4 of the above references uses pip install to locate the directories where they library and spidev are hiding. You might like to check if you are using different versions, eg. PyPi spidev v4.3 or others. – tlfong01 Apr 22 '20 at 04:24
  • You know it is the following function causing trouble: "def get_status(self): return self.spidev.xfer2([NRF24.NOP])[0]". So let us look at the function/method "spidev.xfer2"and see why the argument "([NRF24.NOP]" makes trouble. The time has finally come to read the friendly user manual:"spidev 3.4 pip install spidev https://pypi.org/project/spidev/" explaining the following methods: (a) xfer(list of values[, speed_hz, delay_usec, bits_per_word]), (b) xfer2(list of values[, speed_hz, delay_usec, bits_per_word]), (c) xfer3(list of values[, speed_hz, delay_usec, bits_per_word]). – tlfong01 Apr 22 '20 at 05:00
  • Now let us zoom in to the trace back record: (1) File "/home/pi/smarthome/lib_nrf24.py", line 506, in available, status = self.get_status(), (2) File "/home/pi/smarthome/lib_nrf24.py", line 293, in get_status, return self.*spidev.xfer2([NRF24.NOP])[0]*, OSError: [Errno 9] Bad file descriptor. It appears that the 0th element of the output list causes trouble. Comments welcome. – tlfong01 Apr 22 '20 at 08:31
  • I watched the YouTuble tutorial and found it good. Then I visited the tutorial's web page: Wireless Pi to Pi Communication with NRF24L01+ - ZamShow 2016 http://thezanshow.com/electronics-tutorials/raspberry-pi/tutorial-32-33. There are only three example python programs. You did not mention which program you were using. So I looked at the master.py. I found the following three lines around lint 48: (1) command = "GET_TEMP", (2) message = [] (3) message = list(command) I guess line 2 should be "[ ]". – tlfong01 Apr 22 '20 at 11:37
  • Since python is dynamically typed, so it is only when the python interpreter running to "message = list(command)" and found that "message" is NOT a list and therefore gives the OSError message, complaining that you cannot put something into a NON list. The error description is about not able to access a already closed file. One reason is that in Unix, list data structure is denoted by a "file" handler, so a non existent "list" is referred as a non existent "file" error. – tlfong01 Apr 22 '20 at 11:45
  • 1
    I tried the SPI loopback test from Appendix E of the post you linked. I get all zeroes. I'm not sure what I should be getting. Should MOSI be connected to MISO? I am using the recv.py program. – sideways8 Apr 22 '20 at 16:23
  • 1
    I've looked into the PyPi spidev manual (though I am using Gadgetoid's py-spidev, as per the tutorial). I can't find out what spidev.xfer2 is supposed to return. The NRF24.NOP value is just 0xFF. If I try to print (self.spidev.xfer2([NRF24.NOP])) (ie without the accessor to get the 0 element) the output prints nothing, and the error is still thrown by this print statement, not the return statement that follows. – sideways8 Apr 22 '20 at 16:28

0 Answers0