Closed bulletmark closed 10 years ago
What happens when you just try using the SPIDevice object? Type the following into a Python 3 shell:
import pifacecommon.spi
spidev = pifacecommon.spi.SPIDevice(0, 0)
spidev.spisend(bytes((0x40, 0x12, 0xaa)))
Also, what's the output of:
ls -l /dev/spi*
Also,
IOError: [Errno 24] Too many open files
Is suggesting that you've opened too many files with Python. Are you creating lots and lots of PIFaceDigital objects? Each one opens a file descriptor to PiFace Digital.
Can you run:
python3 /usr/share/doc/python3-pifacedigitalio/examples/blink.py
Note that I am using python 2, not 3 because some of the 3rd party modules I am using are python 2 only (as I said in that other issue #5). I am not using any PF objects, my piface interface is trivial, just an init() and periodic polled reads and writes. Nor am I opening many other file descriptors at all.
I git pulled back to tags close to the version of raspian packages I was previously using (except that there was no tag for python-pifacecommon 3.1.2 - I had to pull 3.1.1), and it works again so there is defnitely something wrong in the current code.
I created a virtualenv, pulled the current master branches of pifacecommon nad pifacdedigital, and ran (in python2) that spi test of yours above and got output:
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
I did not want to run the blink test because my outputs are hooked up to sirens etc, assuming you will strobe them.
Bytes work differently in Python 2:
import pifacecommon.spi
spidev = pifacecommon.spi.SPIDevice(0, 0)
spidev.spisend(chr(0x40) + chr(0x12) + chr(0xaa))
That's an SPI command to write (0x40) the value 0xaa to the output port (0x12). Don't run it if you have sirens connected!
Anyway, that doesn't really matter. What does matter is that you got a response when you issued the spisend command which means pifacedigitalio is recognising your PiFace again.
In the same virtual env can you run digital_read/digital_write?
Well I had run that first command and since both piface relays are hooked up to sirens I would have expected, if what you say is correct, that I would have woken up my entire family just now, but I didn't(!). The simple init/read/write seems to work but I should add that I noticed my app had successfully read some inputs also before it died with that "have you enabled the SPI module" error message. The point is my app has 2 months of logs recorded and I have never seen that error message until immediately after I did nothing more than an "apt-get dist-upgrade" which pulled in the updated piface packages. Got those messages after every time I restarted the app and it died. Pulled the old versions back and the error message is gone and app works again. My app has been running solidly for nine months.
BTW, I see looking at the code the only way that error can be generated is if the open() fails and given the "too many open files" error message could it be that you are erroneously creating massive number of SPIDevice(), i.e. MCP23S17() objects, e.g. at every read() or write()?
digital_read
and digital_write
create a new PiFaceDigital object, you're right. It appears that Python isn't cleaning up after itself. I figured when the object is no longer referenced then the garbage collector runs the del magic method.
I've added a deinit_board method to PiFaceDigital which closes the file in v3.0.4. digital_read
/digital_write
now call this method. It's in the testing branch, can you test this for me so that I can push it to the Raspbian repo's, please?
That is, the testing branch of https://github.com/piface/pifacedigitalio
I pulled the testing branches of both pifacecommon and pifacedigitalio and it does seem to stop that "too many files" error but there are now worse issues. My pi is using massive amounts of cpu and memory leaks away until all system memory is used, my app stops responding, and the pi itself becomes unusably slow. If I kill the app then system memory is freed and the pi returns to normal.
Regardless of the memory leak, creating (and then destroying) significant object instances every read or write is a terribly inefficient design anyhow.
This is my home alarm system we use every day so I will have to go back to the old https://github.com/thomasmacpherson/piface repo sorry.
digital_read
/digital_write
are mainly there for backwards compatibility. Your app should really be using:
pfd = pifacedigitalio.PiFaceDigital()
pfd.output_pins[0].turn_on()
Nevertheless, I've made some efficiency improvements in the tpdev branch. I haven't tested these on any Pi yet so don't expect them to work. I'm busy tomorrow but I'll try and test the changes over the weekend.
I'm not quite sure why you're getting a memory leak.
The leak may have been in your previous version too but I never got to notice it because the app got killed quickly due to the "too many files" error. With working piface modules, my app uses miniscule memory and cpu. Normal ram total is about 35MB used of 438MB available system ram and total system cpu load sits at 4%.
I've fixed digital read/write. I couldn't replicate the memory leak however it's much faster now that it isn't creating a new object on each read/write. Hopefully this should solve your problem too. Would you be able to test it with your particular set up, please? It would be a great help.
The change is in the testing branch of pifacedigitalio.
That's much better. It works without issue now although it does use more cpu than the original piface module. I installed it on my second pi + piface and ran it in parallel with the original one running the original piface module. All hardware, software, and raspian OS the same except for the piface modules. I artificially bumped my input polling rate to 10ms instead of the normal 250ms to check cpu usage under load. Viewing htop on both in adjacent windows, the average cpu usage by the app was 36% compared to 26% on the original and memory usage was the same. No evidence of any memory leak. So there is a slight cpu performance degradation although maybe not sigificant enough for you to bother with. I will let that pi run for 24 hours to make sure nothing crops up and will post here if it does.
That's good to hear. The extra CPU cycles are probably coming from the extra layers of software digital_read
and digital_write
have to go through. I can't invest any time into improving that at the moment (new product releases etc) but I'll put it on my todo list. Thanks.
If you can get back to me by tomorrow with an update on how things go I can merge the fix and get it in Raspbian ASAP. :+1:
Ok, left it running under load for 24 hours and still working fine, at same CPU load and memory usage. Bug can be closed now.
Hi Tom and Bulletmark I am new with piface. I am trying to install the pifacedigital-emulator but I obtain the following screen: pi@raspberrypi ~ $ pifacedigital-emulator Error initialising PiFace Digital: I can't see /dev/spidev0.0. Have you enabled the SPI module? (http://piface.github.io/pifacecommon/installation.html#enable-the-spi-module) Running without hardware PiFace Digital. Traceback (most recent call last): File "/usr/local/lib/python3.2/dist-packages/pifacecommon/spi.py", line 40, in open_fd self.fd = posix.open(spi_device, posix.O_RDWR) OSError: [Errno 2] No such file or directory: '/dev/spidev0.0'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/pifacedigital-emulator", line 3, in
I know that this converasation was closed, sorry about that, but I really dont know how to fix it. I red all your conversation but I still dont understand what can I do to make it work. I have tried everything, uninstall, reintall, reboot, follow the instalation instructions but nothing works. Can you guys pleas help me?
What is the output of:
$ lsmod
and
$ ls -l /dev/spidev*
Tom I have solved it by installing spidev0 and spidev0.1 files with this proccedure: http://neophob.com/2012/08/raspberry-pi-enable-the-spi-device/ I don't know why, but the original distribution of raspbian doesnt include it, you can even set SPI true in the raspi-config screen, but it doesnt work if the spidev0 and pidev0.1 files are not installed. Maybe it coul be nice if the instalation of pifacedigital-emulator could verify if and if it is missing, then auto installing. Another little issue I found in the spidev0 instalation proccedure, is that you have to install/upgrade firmware files, then other devices depending on the version istalled(like wifi dongle in my case) can be misconfiguerd.
As I mentioned in issue #5, I changed my piface app to use python-pifacecommon 3.1.2-1 and python-pifacedigitalio 2.1.0-1 from the raspian repos 3 weeks ago and everything has been working fine. However, I did a apt-get dist-upgrade today which pulled in python-pifacecommon 4.0.0-1 and python-pifacedigitalio 3.0.0-1 I now get the following error reported. I did not change anything else (i.e. no change to my code).
I aptitude purged those 2 packages, installed the latest versions for both from master branch on github, built the spi and gpio udev rules, permissions/groups, blacklist removal, etc by hand - but still get the exact same error.
I've checked the owner+group+permissions on /dev/spidev* and on /sys/class/gpio/ and my user and it all looks fine. So the udev rules are installed and working. My user is in correct spi and gpio groups and I have rebooted many times.