Coder Social home page Coder Social logo

metachris / rpio Goto Github PK

View Code? Open in Web Editor NEW
329.0 48.0 147.0 1.92 MB

RPIO is a GPIO toolbox for the Raspberry Pi.

Home Page: https://pypi.python.org/pypi/RPIO

License: GNU Lesser General Public License v3.0

C 47.10% Python 45.14% C++ 1.91% Shell 1.00% Makefile 2.43% Roff 2.42%

rpio's Issues

incorrect log statement in pwm.c

On line 462 of pwm.c

return fatal("Error: cannot add pulse to channel %d: width_start+width exceed max_width of %d\n", channels[channel].width_max);

two integer arguments are needed for fatal() function.

RPIO can't be imported

Platform Raspberry Pi Version 2 (the latest incarnation, runs at 1GHz)
Raspbian dated 2015-02-16
Python 3.4.3 and Python 3.2.3
RPIO was downloaded and installed on 2015-04-30

Problem:

  1. Open IDLE in interactive mode
  2. type "import RPIO"
  3. error message appears: "SystemError: This runs only on a Raspberry Pi!" (apologies --- this mightn't be the exact wording, but the essentials are there.)

Regards,
Tim Cole
[email protected]

False interrupt triggering

I initially added this to Issue #31, but on reflection it is actually a different problem so I now add it separately here.

I have been converting a program from using RPi.GPIO to use RPIO because I need to control the interrupt threading. I now have my interrupt threading working, such that interrupt handling code for the first interrupt runs to completion before the second interrupt is handled etc. BUT I have a new problem in that my routines using RPIO detect events (triggers) that are not actually present - even if I disconnect all wires from the trigger pins, events are detected and interrupts called. Apart from being unable to control threading, my hardware works properly with RPi.GPIO, with no unexpected interrupts occurring. So what is wrong?

I think it must be something simple with the add_interrupt_callbacks near the end, but I can't work out what.

My full code using RPIO (which triggers interrupts repeatedly) is below, followed by the equivalent version for RPi.GPIO (which works except for being unable to control threading)
What might be wrong?

PS: I know I have a logic flaw with the "don't respond to sounds if the piezo is sounding" handling. I will deal with that later.

Non-working RPIO version:
'''
import RPIO as RPIO
import time

on = 1
off = 0
sounder = off

This is not needed for RPIO # RPIO.setmode(RPIO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO$

Therefore this program will work only with Rev 2 Raspberry Pis

RPIO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time)

Set up pin numbering

These are tested and found to be correct

right side, top to bottom

P0 = 17 # BCM 17
P1 = 18 # BCM 18
P2 = 27 # BCM 27 (21 on Revision 1)
P3 = 22 # BCM 22
P4 = 23 # BCM 23
P5 = 24 # BCM 24
P6 = 25 # BCM 25
P7 = 4 # BCM 4

left side, top to bottom

CE1 = 7 # BCM 7
CE0 = 8 # BCM 8
SCLK = 11 # BCM 11
MISO = 9 # BCM 9
MOSI = 10 # BCM 10
RXD = 15 # BCM 15
TXD = 14 # BCM 14
SCL = 3 # BCM 3 (would be 1 on Revision 1)
SDA = 2 # BCM 2 (would be 0 on revision 1)

Set P0 to P3 as inputs with pull up resistors on P0 and P1

RPIO.setup(P0, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Doorbell push; pressing will ground this pin
RPIO.setup(P1, RPIO.IN, pull_up_down=RPIO.PUD_UP) # Magnetic contact; normally grounded; removing magnet lets it go high
RPIO.setup(P2, RPIO.IN) # PIR; goes ON with movement detected
RPIO.setup(P3, RPIO.IN) # Sound detector; goes OFF when sound detected

set P4 to P7 as outputs to relays etc

RPIO.setup(P4, RPIO.OUT)
RPIO.setup(P5, RPIO.OUT)
RPIO.setup(P6, RPIO.OUT)
RPIO.setup(P7, RPIO.OUT)

Set output P4 LOW (for Piezo sounder)

set all other outputs HIGH ( = relay off)

RPIO.output(P4, off) # Piezo sounder
RPIO.output(P5, on) # For relay, set ON as this leaves relay quiescent to save power
RPIO.output(P6, on) # Relay
RPIO.output(P7, on) # Relay

time.sleep(1) # pause to allow inputs to settle before enabling interrupts

P1 is magnetic contact. Pulled UP. Normally pin is connected to GROUND

When magnet removed, switch opens, pull up causes HIGH

P2 is PIR. Requires power of +5v, but output is 3v (RPi 3v3 compatible)

Output goes ON when movement detected

Trimmers adjust (a) sensitivity and (b) ON duration after detection

P3 Sound Detector. Requires power of 3-20v; we are using 3.3v.

Digital Output goes OFF and LED lights when sound detected

Turn resistor ANTICLOCKWISE for greater sensitivity

Because there are multiple triggers, cannot use "Wait for edge"

Define "Events" for each trigger and generate a "Callback" whenever that event occurs

First define the actions to take for each trigger

Then IO.add_event_detect(pin,IO.RISING,callback=name,bouncetime=1000)

def flash(pin, ontime, offtime, count, first):

first = state to send first. Set it to on or off.

global on
global off

second = 1 - first # second state is opposite to the first one

for i in range (1, count+1): # needs +1 so it loops the correct number of times ?why
RPIO.output (pin, first)
time.sleep(ontime)
RPIO.output(pin, second)
if i <> count: # this is to avoid a wait at the end
time.sleep(offtime)
def incident (pin, dummyvar): # something has caused an alarm; needs a 2nd parameter
global on
global off
global sounder

print(' ')
print('Incident detected - now decode what it was. Pin '+str(pin)+'; Value '+str(dummyvar))

if pin == P0: # doorbell
print('Doorbell pushed - sound piezo and flash light')
sounder = on # set flag to ignore sound detection
RPIO.output(P4, on) # piezo on
flash(P7, 0.5, 0.5, 3, off) # pulse relay 3x 0.5 sec
RPIO.output(P4, off) # Piezo off
sounder = off
print('Ended doorbell actions')

elif pin == P1: # Magnetic contact, Magnet removed
print('Magnet removed - flash light')
flash(P7, 1, 0.5, 5, off) # pulse relay
print('Ended magnet removed actions')

elif pin == P2: # PIR detected motion
print('Motion detected - flicker light')
flash(P7, 2, 0.2, 3, off) # flicker relay
print('Ended Motion detected actions')

elif pin == P3: # Sound detected
if sounder == off: # only react to sound detection if piezo is not sounding !!
print ('Sound detected - turn light on whilst playing 4 bleeps')
RPIO.output(P7,off) # turn light on
sounder = on # set flag to ignore sound detection
flash(P4, 1, 1, 4, on) # sound piezo 4x for 1 second
sounder = off
RPIO.output(P7,on) # turn light back off
print('Ended sound detected actions')

else: # No actions if piezo is sounding
     print('Ignoring sound detected as Piezo is sounding')

else: # unknown trigger
print ('Unidentified trigger')

If I change all threaded_callback to True, all the outputs run on top of each other. With False, only 1 runs at a time

So False is what I want

RPIO.add_interrupt_callback(P0, incident, edge='falling', threaded_callback=False, debounce_timeout_ms=3000) # ignore repeat doorbell presses within 3000mSec (3 sec)

RPIO.add_interrupt_callback(P1, incident, edge='rising', threaded_callback=False, debounce_timeout_ms=3000) # magnetic contact. Switch normally grounds P1; when magnet removed, pull-

up causes HIGH

RPIO.add_interrupt_callback(P2, incident, edge='rising', threaded_callback=False, debounce_timeout_ms=15000) # PIR ignore repeats within 15 sec

RPIO.add_interrupt_callback(P3, incident, edge='falling', threaded_callback=False, debounce_timeout_ms=30000) # sound detector ignore repats within 30 sec

try:
print('Monitoring started ...')
print('Press CTRL-C to exit')
RPIO.wait_for_interrupts(threaded=False) # False make the main prog stop here - then the following loop is not needed
while True: # just wait forever ...
time.sleep(10000)

RPIO.cleanup()
except KeyboardInterrupt:
print ('Ending monitoring')
RPIO.cleanup() # Cleanup on CTRL-C

RPIO.cleanup()
'''

Working (apart from threading) RPi.GPIO version:
'''
import RPi.GPIO as IO
import time

on = 1
off = 0
sounder = off

IO.setmode(IO.BCM) # This version set to use BCM (Broadcom, the processor chip) GPIO numbers

Therefore this program will work only with Rev 2 Raspberry Pis

IO.setwarnings(False) # Turn off warning messages (occur when run program after 1st time)

Set up pin numbering

These are tested and found to be correct

right side, top to bottom

P0 = 17 # BCM 17
P1 = 18 # BCM 18
P2 = 27 # BCM 27 (21 on Revision 1)
P3 = 22 # BCM 22
P4 = 23 # BCM 23
P5 = 24 # BCM 24
P6 = 25 # BCM 25
P7 = 4 # BCM 4

left side, top to bottom

CE1 = 7 # BCM 7
CE0 = 8 # BCM 8
SCLK = 11 # BCM 11
MISO = 9 # BCM 9
MOSI = 10 # BCM 10
RXD = 15 # BCM 15
TXD = 14 # BCM 14
SCL = 3 # BCM 3 (would be 1 on Revision 1)
SDA = 2 # BCM 2 (would be 0 on revision 1)

Set P0 to P3 as inputs with pull down resistors.

P1 has PULL UP (magnetic contact)

IO.setup(P0,IO.IN,pull_up_down=IO.PUD_UP) # Doorbell push
IO.setup(P1,IO.IN,pull_up_down=IO.PUD_UP) # Magnetic contact
IO.setup(P2,IO.IN) # PIR
IO.setup(P3,IO.IN) # Sound detector

set P4 to P7 as outputs to relays etc

IO.setup(P4,IO.OUT)
IO.setup(P5,IO.OUT)
IO.setup(P6,IO.OUT)
IO.setup(P7,IO.OUT)

Set output P4 LOW (for Piezo sounder)

set all other outputs HIGH ( = relay off)

IO.output(P4,off) # Piezo sounder
IO.output(P5,on) # For relay, set ON as this leaves relay quiescent to save power
IO.output(P6,on) # Relay
IO.output(P7,on) # Relay

First define the actions to take for each trigger

Then IO.add_event_detect(pin, IO.RISING, callback=name, bouncetime=1000)

def flash(pin, ontime, offtime, count, first):

first = state to send first. Set it to on or off.

global on
global off

second = 1 - first # second state is opposite to the first one

for i in range (1, count+1): # needs +1 so it loops the correct number of times ?why
IO.output (pin, first)
time.sleep(ontime)
IO.output(pin, second)
if i <> count: # this is to avoid a wait at the end
time.sleep(offtime)
def incident (pin): # something has caused an alarm
global on
global off
global sounder

print(' ')
print('Incident detected - now decode what it was. Pin '+str(pin))

if pin == P0: # doorbell
print('Doorbell pushed - sound piezo and flash light')
IO.output(P4, on) # piezo on
sounder = on # set flag to ignore sound detection
flash(P7, 0.5, 0.5, 3, off) # pulse relay 3x 0.5 sec
IO.output(P4, off) # Piezo off
sounder = off
print('Ended doorbell actions')

elif pin == P1: # Magnetic contact, Magnet removed
print('Magnet removed - flash light')
flash(P7, 1, 0.5, 5, off) # pulse relay
print('Ended magnet removed actions')

elif pin == P2: # PIR detected motion
print('Motion detected - flicker light')
flash(P7, 2, 0.2, 3, off) # flicker relay
print('Ended Motion detected actions')

elif pin == P3: # Sound detected
if sounder == off: # only raect to sound detection if piezo is not sounding !!
print ('Sound detected - turn light on whilst playing 4 bleeps')
IO.output(P7,off) # turn light on
sounder = on # set flag to ignore sound detection
flash(P4, 1, 1, 4, on) # sound piezo 4x for 1 second
sounder = off
IO.output(P7,on) # turn light back off
print('Ended sound detected actions')

else: # No actions if piezo is sounding
     print('Ignoring sound detected as Piezo is sounding')

else: # unknown trigger
print ('Unidentified trigger')

IO.add_event_detect(P0,IO.RISING, callback=incident, bouncetime=3000) # ignore doorbell presses within 3000mSec (3 sec)

IO.add_event_detect(P1,IO.RISING, callback=incident, bouncetime=3000) # magnetic contact. With temp switch, detects RELEASING button (but no matter)

IO.add_event_detect(P2,IO.RISING, callback=incident, bouncetime=15000) # PIR ignore repeats within 15 sec

IO.add_event_detect(P3,IO.FALLING, callback=incident, bouncetime=30000) # sound detector ignore repats within 30 sec

try:
print('Monitoring started ...')
print('Press CTRL-C to exit')
while True: # just wait forever ...
time.sleep(10000)

except KeyboardInterrupt:
print ('Ending monitoring')
IO.cleanup() # Cleanup on CTRL-C

IO.cleanup()

[DOC] Add the information about DMA PWM channels already in use

According to this post, DMA channels 0, 1, 2, 3, 6 and 7 are already in use (by the GPU for 1, 3, 6, 7, the frame buffer for 0 and the SD card for 2).

Thus, those channels should not be used for PWM (this leaves channel 4 and 8+). Using channel 2 is known to cause problems with the SDCard (read-only error and console error "command not found").

Using by default channel 4 at initialisation would be good.
Also, adding this information to the PWM documentation would help people avoiding mistakes.
Finally, the PWM documentation could be enriched with more information about the simultaneous use of one channel by several outputs (each at its own PWM rate), as explained in the post linked above.

Patch to build packages on latest Raspbian

diff --git a/README.rst b/README.rst
index cfb3dd8..7af0f9c 100644
--- a/README.rst
+++ b/README.rst
@@ -1,6 +1,6 @@
 RPIO is an advanced GPIO module for the Raspberry Pi.

-* PWM via DMA (up to 1<C2><B5>s resolution)
+* PWM via DMA (up to 1us resolution)
 * GPIO input and output (drop-in replacement for `RPi.GPIO <http://pypi.python.org/pypi/RPi.GPIO>`_)
 * GPIO interrupts (callbacks when events occur on input gpios)
 * TCP socket interrupts (callbacks when tcp socket clients send data)
diff --git a/debian/rules b/debian/rules
index 498c100..c3edfda 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,11 +1,13 @@
 #!/usr/bin/make -f
 # -*- makefile -*-

-PYTHON2=$(shell pyversions -vr)
-PYTHON3=$(shell py3versions -vr)
+#export DH_VERBOSE=1
+
+PYTHON2=$(shell pyversions -vd)
+PYTHON3=$(shell py3versions -vd)

 %:
-       dh $@ --with python2,python3
+       dh $@ --with python2,python3 --buildsystem=python_distutils

 build-python%:
        python$* setup.py build

AttributeError: 'module' object has no attribute 'epoll' when importing RPIO instantiated in another module

Not sure if this is real issue or me being a noob but I get this error:

Traceback (most recent call last):
File "run.py", line 6, in
app = create_app(True)
File "/home/pi/pi-booth/app/init.py", line 12, in create_app
from .main import main as main_blueprint
File "/home/pi/pi-booth/app/main/init.py", line 5, in
import routes, events
File "/home/pi/pi-booth/app/main/events.py", line 6, in
import camera
File "/home/pi/pi-booth/app/main/camera.py", line 1, in
import RPIO
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 116, in
from RPIO._RPIO import Interruptor
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 64, in
class Interruptor:
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 68, in Interruptor
_epoll = select.epoll()
AttributeError: 'module' object has no attribute 'epoll'
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
func(_targs, *_kargs)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 58, in exit_handler
RPIO.stop_waiting_for_interrupts()
AttributeError: 'NoneType' object has no attribute 'stop_waiting_for_interrupts'
Error in sys.exitfunc:
Traceback (most recent call last):
File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
func(_targs, *_kargs)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 58, in exit_handler
RPIO.stop_waiting_for_interrupts()
AttributeError: 'NoneType' object has no attribute 'stop_waiting_for_interrupts'

No error message when adding incompatible channel pulses

According to the comment at https://github.com/metachris/RPIO/blob/master/source/c_pwm/pwm.c#L445 add_channel_pulse(...) is uncapable of setting one GPIO pin LOW and another HIGH at the very same time on the same DMA channel.

Currently the only the last action will be applied to all.

I would rather expect a return fatal(...) so I don't experience mysterious behaviour and have to go through the source code to find a comment on why this basic functionality doesn't work.

ValueError in _handle_interrupt(self, fileno, val)

Received the following exception

Exception in thread Thread-39:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(_self.__args, *_self.__kwargs)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 320, in wait_for_interrupts
self._handle_interrupt(fileno, val)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 241, in _handle_interrupt
val = int(val)
ValueError: invalid literal for int() with base 10: ''

Please advise if you need more information. The code has been running for several days and this error has occurred once. The code seems to be continuing to run correctly.

Setup is:
RPIO.add_interrupt_callback( 4, self.callBack, edge = 'rising', threaded_callback = True,debounce_timeout_ms = 50)

Interrupts on GPIO 4 are triggered by the interrupt pin from a MCP23008 which monitors 8 limit switches.
On an interrupt, the callback routine posts a message on a queue .

The operational process (simplified) is:
Clear the queue
RPIO.wait_for_interrupts( threaded = True )
Enable MS23008 interrupts
while True:
try :
msg = queue.get( block=True, timeout=2.0)
Process interrupt message
break
except Queue,Empty:
break
disable MS23008 interrupts
RPIO.stop_waiting_for_interrupts()

PWM.clear_channel followed by init_channel fails

I need to change the subcycle_time_us of a channel after it's been initialized, but it seems to be impossible.

First, I tried PWM.clear_channel(chan) before PWM.init_channel(chan, subcycle_time_us=new_stu), but it gave an error that the channel was already initialized. Next, I tried a more draconian cleanup() call (I don't want to touch other channels, and this would mean initializing all of them which I really don't want to do, but even that didn't work.

It looks like the problem is the virtbase pointer in the channel structure. It's used throughout pwm.c to indicate whether the channel has been initialized. init_channel checks if it's set, and assumes it's initialized if it is set. But clear_channel doesn't clear it (and neither does shutdown (called by cleanup)). As there's no way to clear virtbase, there's no way to change the subcycle_time_us of a channel.

RPIO causes serious issues with subprocess / os

The following script should call 'ls' once per second - but as soon as the call to ls executes, the script dies.

from RPIO import PWM
import os
import time

def setup():
        PWM.setup()

def main():
        while True:
                os.system("ls")
                time.sleep(1.000)

setup()
main()

PWM OK from Console, but not in script

If I run the PWM script in the console, then everything works as expected, but if I run it from a script file, then the PWM dies after a few moments:

#!/usr/bin/env python2
from RPIO import PWM
def wdog(GPIO=18,CHAN=0,FREQ=20000):
PWM.setup()
PWM.init_channel(CHAN,FREQ) ## Freq = 199,000us

if(not PWM.is_channel_initialized(CHAN)):
  PWM.clear_channel_gpio(CHAN,GPIO)
PWM.add_channel_pulse(CHAN,GPIO,0,1000)  ## 50%

wdog(22,0)

PWM traps all signals, even those normally ignored

I have a server that just sits quietly in a tmux window, watching pins and doing it's thing. But if I attach it and my window size changes, it dies. The reason is that source/c_pwm/pwm.c traps all signals, even those that are normally ignored:

// Catch all signals possible - it is vital we kill the DMA engine
// on process exit!
static void
setup_sighandlers(void)
{
    int i;
    for (i = 0; i < 64; i++) {
        struct sigaction sa;
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = (void *) terminate;
        sigaction(i, &sa, NULL);
    }
}

I believe #19 and #15 are really this bug. But I put this here because the bug is more general than those issues.

Feature request: Interrupt timestamp

When an GPIO interrupt occurs, it is often interesting to now the microsecond counter at time of interrupt. Would it be possible to add this to the callback parameters ? I suspect such a timestamp would be far more accurate than reading the microsecond counter in Python.

rpio-curses on Raspbery Pi A+

rpio-curses command issued on Raspbery Pi A+ ends with following error:

root@kroko:/automat# rpio-curses
Traceback (most recent call last):
File "/usr/local/bin/rpio-curses", line 5, in
pkg_resources.run_script('RPIO==0.10.0', 'rpio-curses')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 93, in
"Maker: %s") % RPIO.sysinfo()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 183, in sysinfo
return (RPI_REVISION_HEX,) + MODEL_DATA[RPI_REVISION_HEX.lstrip("0")]
KeyError: '12'

how to change the pulse width of a GPIO pin?

In the example of "example4_pwm_lowlevel.py", it said we can add a new pulse to a subcycle. E.g.:

import RPIO.PWM as PWM

GPIO = 17
CHANNEL = 0

PWM.set_loglevel(PWM.LOG_LEVEL_DEBUG)

PWM.setup()
PWM.init_channel(CHANNEL)
PWM.print_channel(CHANNEL)

PWM.add_channel_pulse(CHANNEL, GPIO, 0, 50)
PWM.add_channel_pulse(CHANNEL, GPIO, 100, 50)

The above code will generate a pulse with two high levels, for each level, the width is 50*10us, the subcycle should looks like: --------__,

what if I want change the pulse to --? I don't think we can use PWM.add_channel_pulse(CHANNEL, GPIO, 50, 50), because I feel that will create: ------_, Am I right? how to change the pulse width smoothly?

Unable to install RPIO on OSX

$ pip install rpio
Collecting rpio
Downloading RPIO-0.10.0.tar.gz
Installing collected packages: rpio
Running setup.py install for rpio
Complete output from command /usr/local/opt/python/bin/python2.7 -c "import setuptools, tokenize;file='/private/var/folders/gx/dr6024r10jgdltk5gn18crtr0000gn/T/pip-build-8wpU6f/rpio/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" install --record /var/folders/gx/dr6024r10jgdltk5gn18crtr0000gn/T/pip-IhNepU-record/install-record.txt --single-version-externally-managed --compile:
running install
running build
running build_py
creating build
creating build/lib.macosx-10.10-x86_64-2.7
creating build/lib.macosx-10.10-x86_64-2.7/RPIO
copying source/RPIO/init.py -> build/lib.macosx-10.10-x86_64-2.7/RPIO
copying source/RPIO/_RPIO.py -> build/lib.macosx-10.10-x86_64-2.7/RPIO
copying source/RPIO/Exceptions.py -> build/lib.macosx-10.10-x86_64-2.7/RPIO
creating build/lib.macosx-10.10-x86_64-2.7/RPIO/PWM
copying source/RPIO/PWM/init.py -> build/lib.macosx-10.10-x86_64-2.7/RPIO/PWM
running build_ext
building 'RPIO._GPIO' extension
creating build/temp.macosx-10.10-x86_64-2.7
creating build/temp.macosx-10.10-x86_64-2.7/source
creating build/temp.macosx-10.10-x86_64-2.7/source/c_gpio
clang -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Qunused-arguments -Qunused-arguments -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c source/c_gpio/py_gpio.c -o build/temp.macosx-10.10-x86_64-2.7/source/c_gpio/py_gpio.o
source/c_gpio/py_gpio.c:361:1: error: static declaration of 'setmode' follows non-static declaration
setmode(PyObject self, PyObject *args)
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/unistd.h:695:7: note: previous declaration is here
void *setmode(const char *) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(setmode));
^
source/c_gpio/py_gpio.c:431:17: warning: incompatible pointer types initializing 'PyCFunction' (aka 'PyObject *(
)(PyObject *, PyObject *)') with an expression of type 'void *(const char *)' [-Wincompatible-pointer-types]
{"setmode", setmode, METH_VARARGS, "Set up numbering mode to use for channels.\nBOARD - Use Raspberry Pi board numbers\nBCM - Use Broadcom GPIO 00..nn numbers"},
^~~~~~~
1 warning and 1 error generated.
error: command 'clang' failed with exit status 1

----------------------------------------
Command "/usr/local/opt/python/bin/python2.7 -c "import setuptools, tokenize;__file__='/private/var/folders/gx/dr6024r10jgdltk5gn18crtr0000gn/T/pip-build-8wpU6f/rpio/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/gx/dr6024r10jgdltk5gn18crtr0000gn/T/pip-IhNepU-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /private/var/folders/gx/dr6024r10jgdltk5gn18crtr0000gn/T/pip-build-8wpU6f/rpio

issues with SD card when using RPIO

Hi - I am searching for an easy way to control servos (Hitec HS-805) with the RasPi.
I tried to use the one plain "PWM" provided by the RasPi with wiringPi's GPIO which worked out-of-the-box but not with satisfying results; the position of the servos is not reproducible and they vibrate slightly instead stopping until the PWM is switched off completely.
Then I searched the net and found some interesting work: "piblaster" and "servoblaster".
As piblaster seems more recent and claims to be an improved servoblaster, I tried it with ambivalent results: the positioning is acceptable but I got some weird DMA errors in the system log about filesystem corruption and problems accessing the SD card (/dev/mmcblk0p2), so I continued searching and found RPIO. Looked perfect in all aspects: easy install, in depth configurable for all servo needs, python and commandline interface, very accurate servo positioning - but after a while I get the same errors as with piblaster. First I thought I can force it with quickly moving the servo, but it also happens when doing just two cycles and waiting a few seconds.

I used your example - just with an other GPIO:


from RPIO import PWM
servo = PWM.Servo()
Using hardware: PWM
PW increments: 10us
servo.set_servo(4, 1000)
Initializing channel 0...
add_channel_pulse: channel=0, gpio=4, start=0, width=100
init_gpio 4
servo.set_servo(4, 1800)
clear_channel_gpio: channel=0, gpio=4
add_channel_pulse: channel=0, gpio=4, start=0, width=180
servo.stop_servo(4)
clear_channel_gpio: channel=0, gpio=4


This is moving my servo by 90 degrees.
I tried other servos, GPIOs, power supplies (both: servo and RasPi).
Do you also have seen anything like this yes? any ideas?

BTW: I am using Fedora 18 - no other tasks running, with
rpio --version = RPIO v0.10.1 (gpio-lib v0.10.1/0.4.2a).
rpio --sysinfo = 000d: Model B, Revision 2.0, RAM: 512 MB, Maker: Egoman

Christian

fails to build with musl libc due to use of caddr_t

This happens when trying to build with musl libc on Alpine Linux:

ccache gcc -DNDEBUG -Os -fomit-frame-pointer -Os -fomit-frame-pointer -Os -fomit-frame-pointer -fPIC -I/usr/include/python2.7 -c source/c_gpio/c_gpio.c -o build/temp.linux-i686-2.7/source/c_gpio/c_gpio.o
source/c_gpio/c_gpio.c: In function 'setup':
source/c_gpio/c_gpio.c:82:35: error: 'caddr_t' undeclared (first use in this function)
     gpio_map = (uint32_t *)mmap( (caddr_t)gpio_mem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, mem_fd, GPIO_BASE);
                                   ^

the caddr_t should be replaced with void *.
see http://stackoverflow.com/questions/6381526/what-is-the-significance-of-caddr-t-and-when-is-it-used

add_interrupt_callback error

I am getting an error with add_interrupt_callback.
I am using BOARD pin numbering with P0 set to 11 (ie BCM 18)
I can set up and read inputs (and setup and write outputs) OK. And my previous code with RPi.GPIO worked OK (except that I want to control the threading)

But when I try to set an interrupt with:
RPIO.add_interrupt_callback(P0, bellpush, edge='rising', threaded_callback=False, debounce_timeout_ms=3000)
I get a 'not valid pin on Raspberry Pi' error, as follows:

Traceback (most recent call last):
File "alarmv3.py", line 106, in
IO.add_interrupt_callback(P0, bellpush, edge='rising', threaded_callback=False, debounce_timeout_ms=3000)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 217, in add_interrupt_callback
threaded_callback, debounce_timeout_ms)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 139, in add_interrupt_callback
if RPIO.gpio_function(int(gpio_id)) == RPIO.IN:
RPIO.Exceptions.InvalidChannelException: The channel sent is invalid on a Raspberry Pi (not a valid pin)

I tried using values for RPi pins and BCM pins instead of the variable P0, but all give the same error. Am I doing something wrong, or is there a bug?

RPIO seems not to be able to handle with loosing its FD

RPIO seems not to be able to handle with loosing its FD like when daemonizing the process.
In the main() function, i try to call daemon_runner.do_action(), which results in

root@raspberrypi # python DoorcamExample.py start
root@raspberrypi #
started with pid 4374
Traceback (most recent call last):
  File "DoorcamExample.py", line 224, in <module>
    main()
  File "DoorcamExample.py", line 201, in main
    daemon_runner.do_action()
  File "/usr/local/lib/python2.7/dist-packages/daemon/runner.py", line 189, in do_action
    func(self)
  File "/usr/local/lib/python2.7/dist-packages/daemon/runner.py", line 134, in _start
    self.app.run()
  File "DoorcamExample.py", line 164, in run
    self.doorcam.startListening(channel=23, threaded=False, port=8099)
  File "DoorcamExample.py", line 141, in startListening
    RPIO.add_interrupt_callback(23, self.gpio_callback, pull_up_down=RPIO.PUD_DOWN, debounce_timeout_ms=1000)
  File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/__init__.py", line 217, in add_interrupt_callback
    threaded_callback, debounce_timeout_ms)
  File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_RPIO.py", line 215, in add_interrupt_callback
    self._epoll.register(f.fileno(), select.EPOLLPRI | select.EPOLLERR)
IOError: [Errno 9] Bad file descriptor
INFO:DoorcamLog:Stop listening

while commenting daemon_runner.do_action() and uncommenting #app.run() works just as I hoped...

Is this a bug in RPIO, or am I missing something?

External modules:
RPIO
python-daemon's runner module
picamera (I guess not a part of the problem)

For the sake of resolving this issue, I also placed an open question on stackexchange:
http://raspberrypi.stackexchange.com/questions/14387/rpio-not-able-to-cope-with-daemonizing-the-process

DoorcamExample.py:

#!/usr/bin/python
import sys
import os
if os.geteuid() != 0:
    # This works perfect on a Raspbian system because there's no rootpassword required
    os.execvp("sudo", ["sudo"] + sys.argv)
    print('to far!') #This should NEVER be reached, there is something wrong...
    sys.exit(1)

import time
import datetime
import subprocess
import re
import glob
import logging
from daemon import runner
from lockfile import LockTimeout
import RPIO
import picamera
import atexit




class Doorcam:
    global logger
    logger = logging.getLogger("DoorcamLog")
    def __init__(self):
        logger.info('Doorcam started capturing')
        self.pollLightFile='/var/tmp/picam-pollLight'
        #self.p=[]
        atexit.register(self.stopListening)

    def boolval(self, test):
        return [False, True][test.lower()[0] == 't']

    def shot(self,filename, number=1, trigger='timed',resolution=(800,600)):
        logger.info('Doorcam shot for %s'%trigger)
        with picamera.PiCamera() as camera:
            camera.resolution = resolution
            camera.brightness = 56
            if self.pollLight():
                camera.exposure_mode = 'verylong'
            else:
                camera.exposure_mode = 'auto'
            camera.start_preview()
            timestamp= datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
            if number <= 1:
                if self.pollLight():
                    time.sleep(2)
                else:
                    time.sleep(0.5)
                camera.exif_tags['IFD0.ImageDescription'] = str('Doorcam, %s shot %d of %d'%(trigger, number, number))
                filename=filename%(timestamp+'-'+trigger)
                camera.capture(filename)
            else:
                if self.pollLight():
                    time.sleep(1)
                else:
                    time.sleep(0.8/number)
                for x in range(1, number+1):
                    camera.exif_tags['IFD0.ImageDescription'] = str('Doorcam, %s shot %d of %d'%(trigger, x, number))
                    camera.capture(filename%(timestamp+'-'+trigger+'-'+str(x)+'of'+str(number)))
                    time.sleep(0.3)
                filename=filename%(timestamp+'-*')
            #timestampreadable= datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            return filename

    def upload(self, filename,trigger='', notify=False):
        names=sorted(glob.iglob(filename))
        if type(notify) is bool:
            if notify == True:
                subprocess.Popen(['su', 'pi', 'notify.sh', '%s @ %s'%(trigger,datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))], stdin=None, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT, close_fds=True)
                subprocess.Popen(['su', 'pi', 'notify_photo.sh', names[0]], stdin=None, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT, close_fds=True)
        else:
            subprocess.Popen(['su', 'pi', 'notify.sh', 'ERROR: %s with notify: %s (%s) @ %s'%(trigger, notify, type(notify), datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))], stdin=None, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT, close_fds=True)
        for name in names:
            basename=os.path.basename(name)
            logger.info('Doorcam started uploading %s as %s'%(name,basename))
            subprocess.Popen(['photohandler.sh', name, '/doorcam/%s'%basename,], stdin=None, stdout=open('/dev/null', 'w'), stderr=subprocess.STDOUT, close_fds=True)
        return names[0]

    def pollLight(self):
        try:
            (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(self.pollLightFile)
        except:
            mtime = 0
        #time.ctime(mtime)
        if mtime < (time.time()-1800):
            pollLine=['wget', 'http://www.isitdarkoutside.com/', '-q', '-O', '-']
            out = subprocess.check_output(pollLine, stderr=subprocess.STDOUT)
            out = re.search(b'id="answer">...', out)
            out = out.group(0)
            if out == 'id="answer">yes':
                lastPollReturn = True
            else:
                lastPollReturn = False
            file = open(self.pollLightFile, "w")
            file.write(str(lastPollReturn))
            file.close()
        else:
            file = open(self.pollLightFile)
            lastPollReturn= (file.read().lower() == 'true')
            file.close()
        return lastPollReturn

    def gpio_callback(self, gpio_id, val):
        self.upload(self.shot(filename=self.filename, number=10, trigger='Doorbell'), notify=True, trigger='Doorbell')

    def socket_callback(self, socket, val):
        vals=val.split()
        if len(vals) == 0 or len(vals) > 4:
            number=1
            notify=True
            trigger='Socket'
            triggernotify='Socket (value %s)'%val
        elif len(vals) == 1:
            number=int(vals[0])
            notify=True
            trigger='Socket'
            triggernotify='Socket (value %s)'%val
        elif len(vals) == 2:
            number=int(vals[1])
            notify=True
            trigger=vals[0]
            triggernotify=vals[0]
        elif len(vals) == 3:
            number=int(vals[1])
            trigger=vals[0]
            triggernotify=vals[0]
            notify=self.boolval(vals[2])
        elif len(vals) == 4:
            number=int(vals[2])
            trigger=vals[0]
            triggernotify=vals[0], [1]
            notify=self.boolval(vals[3])
        socket.send(self.upload(self.shot(filename=self.filename, number=number, trigger=trigger), notify=notify,trigger=triggernotify))
        RPIO.close_tcp_client(socket.fileno())

    def startListening(self,channel,port=8080, threaded=True):
        RPIO.add_interrupt_callback(23, self.gpio_callback, pull_up_down=RPIO.PUD_DOWN, debounce_timeout_ms=1000)
        RPIO.add_tcp_callback(port, self.socket_callback)
        RPIO.wait_for_interrupts(threaded=threaded)

    def stopListening(self):
        logger.info('Stop listening')
        RPIO.stop_waiting_for_interrupts()

class Doorcamdaemon():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/run/lock/doorcam.pid'
        self.pidfile_timeout = 5

    def run(self):
        self.doorcam=Doorcam()
        #while True:
        self.doorcam.filename='/var/tmp/%s.jpg'
        #logger.info(self.doorcam.filename)
        if self.shots > 0:
            self.doorcam.upload(self.doorcam.shot(filename=self.doorcam.filename, number=self.shots, trigger=self.trigger), notify=self.notify, trigger=self.trigger)
        self.doorcam.startListening(channel=23, threaded=False, port=8099)
        #self.doorcam.timerShots(30)
        #self.doorcam.stopListening()

#   def start(self):
#       try:
#           self.run()
#       except KeyboardInterrupt:
#           print('You pressed Ctrl+C!')
#       self.doorcam.stopListening()



def main():
    global logger
    trigger='doorbell'
    shots=0
    notify=False
    if len(sys.argv) == 2 and not (sys.argv[1] == 'start' or sys.argv[1] == 'stop' or sys.argv[1] == 'restart'):
        print( ("Usage: {0} start | stop | restart | trigger shots notify\nFor example:\n  {0} commandline 2 True").format(sys.argv[0]) )
        sys.exit(1)

    logger = logging.getLogger("DoorcamLog")
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    handler = logging.FileHandler("/var/log/doorcam.log")
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    app = Doorcamdaemon()

    daemon_runner = runner.DaemonRunner(app)
    #This ensures that the logger file handle does not get closed during daemonization
    daemon_runner.daemon_context.files_preserve=[handler.stream]
    app.trigger=trigger
    app.notify=notify
    app.shots=shots
    try:
        daemon_runner.do_action()
        #app.run()
    except LockTimeout:
        import errno
        if len(sys.argv) == 4:
            trigger=sys.argv[1]
            shots=int(sys.argv[2])
            notify = [False, True][sys.argv[3].lower()[0] == 't']
            try:
                from telnetlib import Telnet
                tn = Telnet('localhost', 8099)
                tn.write( ('{0} {1} {2}\r\n').format(trigger, shots, str(notify)).encode('latin-1'))
                #print(tn.read_all())
                sys.exit(0)
                logger.info("couldn't aquire lock, tcpsocket request has been made...")
                logger.debug(tn.read_all())
            except:
                sys.exit(errno.ECONNREFUSED)
        sys.exit(errno.EINVAL)
    except KeyboardInterrupt:
        logger.info('Caught CTRL-C, quitting...')

if __name__ == "__main__":
    main()

RPIO 0.10.0 did not work on RaspberryPi V2

Hello

I tried to use your library to generate some PWM signals on a RaspberryPi V2 but I get always same error:
Traceback (most recent call last):
File "/usr/local/bin/rpio", line 5, in
pkg_resources.run_script('RPIO==0.10.1', 'rpio')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.1-py2.7-linux-armv7l.egg/EGG-INFO/scripts/rpio", line 353, in
main()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.1-py2.7-linux-armv7l.egg/EGG-INFO/scripts/rpio", line 147, in main
import RPIO
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.1-py2.7-linux-armv7l.egg/RPIO/init.py", line 115, in
import RPIO._GPIO as _GPIO
SystemError: This module can only be run on a Raspberry Pi!

Any help on solving this would be welcome.
Thank you
-=Seba=-

rpio-curses doesn't start when terminal height is 24 or 25 lines with no indication of the problem

If the terminal height is 23 lines an error message is output that says what the problem is:
"Your terminal window is too small. rpio-curses needs 24 lines and 70 columns (you have 23 lines, 80 columns)."

If the terminal height is 24 or 25 lines, the following is output:
Traceback (most recent call last):
File "/usr/local/bin/rpio-curses", line 5, in
pkg_resources.run_script('RPIO==0.10.0', 'rpio-curses')
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.49-py2.7.egg/pkg_resources.py", line 507, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.49-py2.7.egg/pkg_resources.py", line 1272, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 495, in
main()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 461, in main
d.start()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 417, in start
self.draw()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 182, in draw
screen.addstr(pos_y, POS_GPIOLIST_X, option)
_curses.error: addstr() returned ERR

The output should offer a resolution OR the documentation needs to clearly specify a terminal window size to use

RPIO install error

I did this on my RPi2
$ sudo apt-get install python-setuptools
$ sudo easy_install -U RPIO

and got this

pi@raspberrypi ~/RPIO $ sudo easy_install -U RPIO
Searching for RPIO
Reading http://pypi.python.org/simple/RPIO/
Best match: RPIO 0.10.0
Downloading https://pypi.python.org/packages/source/R/RPIO/RPIO-0.10.0.tar.gz#md5=cefc45422833dcafcd59b78dffc540f4
Processing RPIO-0.10.0.tar.gz
Running RPIO-0.10.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install-iyUVZN/RPIO-0.10.0/egg-dist-tmp-mlGrcH
source/c_gpio/py_gpio.c:28:20: fatal error: Python.h: No such file or directory
compilation terminated.
error: Setup script exited with error: command 'gcc' failed with exit status 1

I tried this

$ git clone https://github.com/metachris/RPIO.git
$ cd RPIO
$ sudo python setup.py install

with a similar result.
can anyone tell me what I need to do please?

[python2.7][raspbian] pip install failing

Hey Chris,

pip is throwing an error during the build with:
source/c_gpio/py_gpio.c:9:20: fatal error: Python.h: No such file or directory

Any ideas?
If you need the pip log file or anything, just shout.

Cheers,
Padraic

What is the best practice to code an Interrupt in a python Class?

This is not an Issue, I just want to request an example of an Interrupt in a Class.

I do have a Interrupt trigger to a Callback function on a Class of a Movement Sensor

When I am importing the movement sensor Class in my code (since there are movement around) immediately start triggering the Callback function that gives an error because it does not have a "self" instance. (I am just importing the Class).

My question is there is a workaround? What is the best practice to code an Interrupt in a python Class?

Thanks in Advance,

Pablo.

Interrupt callback missed / speed limit

Hi, So, let's try to explain my issue.
Context : I'm using RPIO in a WebIOPi setup which seems to work properly as all functions work.
The project I'm working on is 5 bicycles (non moving, on home trainers) odometer. I use reed sensors on wheels. At each turn the magnet pass by the sensor and close it. On the RPi side, i catch those with interrupts on GPIO pins.
And here is my issue : some interrupts callbacks aren't triggered. In debug mode, I can see that :

  • At a small speed, all sensor rises are catched by RPIO which echoes a epoll message. And at each rise catched, the callback function in triggered and processed (I've put a debug track inside it)
  • At a bigger speed, (can't tell how much, maybe 20 per second) all sensor rises are catched by RPIO module and i can read the epoll message. But no (ZERO !) callback function is triggered anymore.
    I've set every RPIO.add_interrupt_callback in threaded mode as well as the RPIO.wait_for_interrupts. And debouncetime setting seems to not change anything. It is like the callback isn't threaded as it should be...

Anyone got an idea ?

Here is extracts of my code :
def velo_capt(gpio_id, value):
global data
data['velo%s' % gpio_id]['dist'] = data['velo%s' % gpio_id]['dist']+data['velo%s' % gpio_id]['circonf']

def setup():
RPIO.add_interrupt_callback(7, velo_capt, edge='rise', threaded_callback=True)
RPIO.add_interrupt_callback(8, velo_capt, edge='rise', threaded_callback=True)
RPIO.add_interrupt_callback(9, velo_capt, edge='rise', threaded_callback=True)
RPIO.add_interrupt_callback(10, velo_capt, edge='rise', threaded_callback=True)
RPIO.add_interrupt_callback(11, velo_capt, edge='rise', threaded_callback=True)
RPIO.wait_for_interrupts(threaded=True)

Thanx for your help !
Fred

Using RPIO with Python 3 (trying)

I get the following error message with my program:

pi@TestPi ~ $ sudo python3 "bread test.py"
Traceback (most recent call last):
File "bread test.py", line 7, in
import RPIO as GPIO
File "/usr/local/lib/python3.2/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 115, in
import RPIO._GPIO as _GPIO
ImportError: /usr/local/lib/python3.2/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/_GPIO.so: undefined symbol: _Py_ZeroStruct

When I installed RPIO, it only put the libraries in the python2.7 folder, so I copied the 2.7 libs directly into the python3.2 folder.

The same program runs fine (ignoring "print" formatting with the parenthesis) in python 2.7, but gets the above error in python 3.2

Also, when I try to run "rpio-curses" I get the following error:

pi@TestPi ~ $ rpio-curses
Script not started as root. Running sudo...
Traceback (most recent call last):
File "/usr/local/bin/rpio-curses", line 5, in
pkg_resources.run_script('RPIO==0.10.0', 'rpio-curses')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 93, in
"Maker: %s") % RPIO.sysinfo()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 183, in sysinfo
return (RPI_REVISION_HEX,) + MODEL_DATA[RPI_REVISION_HEX.lstrip("0")]
KeyError: '10'

Please help - I would love to be able to use rpio-curses and use the library with python 3.2.

Thanks!
James

Interrupt call_back arguments

I was unable to get a call back to work until I defined it with 3 arguments not 2 as noted in the documentation "def cb( me, pin, val) :" where "me" is a reference to the class so that class variables are referenced as me.xyz in the call back routine. Is this correct or am I doing something wrong?

Python 2.7 on Raspberry Pi wheezy updated.
My version of RPIO is "RPIO v0.10.0 (gpio-lib v0.10.0/0.4.2a)"

SystemError: This module can only be run on a Raspberry Pi!

Hi,
I have a Raspberry Pi 2 and am getting the error below when trying to import the RPIO module. Should. Was getting this error when trying to import RPi.GPIO as well until recently, but that imports OK after some recent updates? Only just worked out that these are two different things - being a newbie and all that!

@raspberrypi ~ $ python
Python 2.7.3 (default, Mar 18 2014, 05:13:23)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.

import RPIO
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.1-py2.7-linux-armv7l.egg/RPIO/init.py", line 115, in
import RPIO._GPIO as _GPIO
SystemError: This module can only be run on a Raspberry Pi!

rpio-curses failst to start

Traceback:

Traceback (most recent call last):
  File "/usr/local/bin/rpio-curses", line 495, in <module>
    main()
  File "/usr/local/bin/rpio-curses", line 461, in main
    d.start()
  File "/usr/local/bin/rpio-curses", line 417, in start
    self.draw()
  File "/usr/local/bin/rpio-curses", line 176, in draw
    screen.addstr(pos_y, POS_GPIOLIST_X+9, "%s     " % (GPIO_FUNCTIONS[func]), curses.color_pair(3) if func == 4 else 0)
KeyError: 6

Running RPIO 0.10.0.

Any clues?

Don't get my interrupt registered unless change "rising" "falling" or "both" when launch my script

Hi there, when running my script, each time I launch I don't get my callback registered unless I change the "rising" or "falling" or "both" value when I register? I suppose perhaps you don't re-register the callback each time unless something has changed? I am cancelling my last script with Ctrl_C so i'm not running any cleanup code. Could that be why? Can't the library just forcibly override the last registered callback so my script can guarantee it's registered each time?

Model B Plus not in current release

I get the following on the new Model B+:

pi@rpiplus ~ $ sudo rpio --version
RPIO v0.10.0 (gpio-lib v0.10.0/0.4.2a)
pi@rpiplus ~ $ sudo rpio --sysinfo
Traceback (most recent call last):
File "/usr/local/bin/rpio", line 5, in
pkg_resources.run_script('RPIO==0.10.0', 'rpio')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio", line 345, in
main()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio", line 338, in main
RPIO.sysinfo()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/init.py", line 183, in sysinfo
return (RPI_REVISION_HEX,) + MODEL_DATA[RPI_REVISION_HEX.lstrip("0")]
KeyError: '10'

Compilation problem under arch for raspberry pi

gbin@flypi ~/projects/RPIO> python setup.py install --user running install
running bdist_egg
running egg_info
writing top-level names to source/RPIO.egg-info/top_level.txt
writing source/RPIO.egg-info/PKG-INFO
writing dependency_links to source/RPIO.egg-info/dependency_links.txt
reading manifest file 'source/RPIO.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'source/RPIO.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-armv6l/egg
running install_lib
running build_py
running build_ext
building 'RPIO._GPIO' extension
gcc -pthread -Wno-unused-result -Werror=declaration-after-statement -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -march=armv6 -mfloat-abi=hard -mfpu=vfp -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -fPIC -I/usr/include/python3.4m -c source/c_gpio/py_gpio.c -o build/temp.linux-armv6l-3.4/source/c_gpio/py_gpio.o
gcc -pthread -Wno-unused-result -Werror=declaration-after-statement -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -march=armv6 -mfloat-abi=hard -mfpu=vfp -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -fPIC -I/usr/include/python3.4m -c source/c_gpio/c_gpio.c -o build/temp.linux-armv6l-3.4/source/c_gpio/c_gpio.o
gcc -pthread -Wno-unused-result -Werror=declaration-after-statement -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -march=armv6 -mfloat-abi=hard -mfpu=vfp -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -fPIC -I/usr/include/python3.4m -c source/c_gpio/cpuinfo.c -o build/temp.linux-armv6l-3.4/source/c_gpio/cpuinfo.o
source/c_gpio/cpuinfo.c: In function ‘get_cpuinfo_revision’:
source/c_gpio/cpuinfo.c:64:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
char* pos = strstr(revision_hex, "1000");

It compiles directly with the Makefile and make. I'll investigate if I have time.

RPIO - PWM mode issues

When PWM is used from the window icon it works but jams the screen (reboot time!). It's fine with non PWM I/O. Tried with python 2.7 and 3.2 - same result.

I'm calling python with sudo to get past /dev/mem access, I'm assuming this is correct.

If started from the LXTerminal window it is OK till you click on the Python Shell that it starts up, then jams the mouse again.

RPIO and Python are up to date as of today (Raspberian updated last week) - what am I doing wrong?

RPIO will be really good when I can get past these issues!

PS it seems to get mixed up if you try to use RPIO.BOARD.

Channel Pulse > 99999 Causes Runtime Error

When trying to create a channel pulse greater than 99999 in length a runtime error is returned. The error message also seems to contain errors (the channel number and the max_width). Below is an example that I generated in the python prompt:

import RPIO.PWM as pwm
pwm.setup()
Using hardware: PWM
PW increments: 10us
pwm.init_channel(0, 1000000)
Initializing channel 0...
pwm.add_channel_pulse(0, 18, 0, 99999)
add_channel_pulse: channel=0, gpio=18, start=0, width=99999
init_gpio 18
pwm.add_channel_pulse(0, 18, 0, 100000)
add_channel_pulse: channel=0, gpio=18, start=0, width=100000
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/RPIO/PWM/init.py", line 115, in add_channel_pulse
return _PWM.add_channel_pulse(dma_channel, gpio, start, width)
RuntimeError: Error: cannot add pulse to channel 99999: width_start+width exceed max_width of 0

BOARD numbering with interrupts

Is it currently possible to use the BOARD numbering scheme with interrupts? It doesn't currently seem to work.

I tried to set an interrupt on GPIO 2 (BOARD 3). When using RPIO.setmode(RPIO.BOARD) and add an interrupt callback to pin 3, I get an InvalidChannelException ("not a valid pin").

With RPIO.BCM and pin 2 it works though. Which is a little strange as pin 3 would be a valid GPIO pin with BCM numbering too.

Is this some bug? Do the interrupts not support the BOARD numbering?

Initializing and closing DMA channels segfault

When I open and close DMA channels repeatedly, Raspberry PI hangs.

This issue is observed rapidly when initializing 2 DMA channels, closing the channels and reopening them rapidly afterwards.

Seems to have a timing issue and concurrent access between closing and opening (accessing an illegal pointer?)

I have also observed a segfault when doing this with the inteactive python command line.

Raspberry Pi B+ is not supported

Please add support for model B+.
To start with, calling RPIO.sysinfo() in Python, returns a key error, because the MODEL_DATA dictionary doesn't have an entry for model B+ (key '10').

rpio and rpio-curses crash when PWM is active

With an active PWM channel modulating pins 23, 24 and 25, rpio-curses crashes on startup with the following stacktrace:

Traceback (most recent call last):
File "/usr/local/bin/rpio-curses", line 5, in
pkg_resources.run_script('RPIO==0.10.0', 'rpio-curses')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 495, in
main()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 461, in main
d.start()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 417, in start
self.draw()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio-curses", line 176, in draw
screen.addstr(pos_y, POS_GPIOLIST_X+9, "%s " % (GPIO_FUNCTIONS[func]), curses.color_pair(3) if func == 4 else 0)
KeyError: 6

Same for rpio -I:

GPIO 2: INPUT (1)
GPIO 3: INPUT (1)
GPIO 4: INPUT (1)
GPIO 7: INPUT (0)
GPIO 8: INPUT (0)
GPIO 9: INPUT (0)
GPIO 10: INPUT (0)
GPIO 11: INPUT (0)
GPIO 14: ALT0 (1)
GPIO 15: ALT0 (1)
GPIO 17: INPUT (0)
GPIO 18: INPUT (0)
GPIO 22: INPUT (0)
GPIO 23: OUTPUT (0)
GPIO 24: OUTPUT (1)
GPIO 25: OUTPUT (1)
GPIO 27: INPUT (0)
Traceback (most recent call last):
File "/usr/local/bin/rpio", line 5, in
pkg_resources.run_script('RPIO==0.10.0', 'rpio')
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 499, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 1235, in run_script
execfile(script_filename, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio", line 345, in
main()
File "/usr/local/lib/python2.7/dist-packages/RPIO-0.10.0-py2.7-linux-armv6l.egg/EGG-INFO/scripts/rpio", line 225, in main
RPIO._RPIO.GPIO_FUNCTIONS[f],
KeyError: 6

P5 pins no longer work as interrupts

In March I did an apt-get update, apt-get upgrade, and apt-get dist-upgrade prior to installing database software. I had GPIO 28 on the P5 header programmed as a interrupt callback using RPIO and it stopped working. I noticed one message that said interrupt 50 was disabled in the kernel. I moved the wire to GPIO 11 on the P1 header, edited the program and it worked as before. I checked GPIO 29 on the P5 header and it did not work as an interrupt either. I don't know if the P5 pins work as standard IO points. I assume that the upgrades caused the problem, I2C was also disabled but I was able to turn it back on using raspi-config. Any ideas on how to make the P5 pins usable again?
Thanks

Model data doesn't exist for the RPi B+ in the MODEL_DATA dictionary.

root@raspberrypi ~ #rpio-curses
Traceback (most recent call last):
File "/usr/local/bin/rpio-curses", line 93, in
"Maker: %s") % RPIO.sysinfo()
File "/usr/local/lib/python2.7/dist-packages/RPIO/init.py", line 183, in sysinfo
return (RPI_REVISION_HEX,) + MODEL_DATA[RPI_REVISION_HEX.lstrip("0")]
KeyError: '10'

Looks like the model data doesn't exist for the B+ in the MODEL_DATA dictionary.

MODEL_DATA = {
'2': ('B', '1.0', 256, '?'),
'3': ('B', '1.0', 256, '?'),
'4': ('B', '2.0', 256, 'Sony'),
'5': ('B', '2.0', 256, 'Qisda'),
'6': ('B', '2.0', 256, 'Egoman'),
'7': ('A', '2.0', 256, 'Egoman'),
'8': ('A', '2.0', 256, 'Sony'),
'9': ('A', '2.0', 256, 'Qisda'),
'd': ('B', '2.0', 512, 'Egoman'),
'e': ('B', '2.0', 512, 'Sony'),
'f': ('B', '2.0', 512, 'Qisda')
}

I'm running python 2.7 on the latest raspian on a Raspberry Pi B+.

not really an issue...Great Work!

Hi. I am developing a pi based analog to digital device for the neuroscience lab where I work (Swartz Center for Computational Neuroscience). In addition to having multiple analog inputs (I use the TI ads1015 and go through I2C) it is to generate a TTL pulse for triggering purposes. I found this library and just dropped pwm.c and pwm.h into my project folder, commented out the main function and compiled it as a library so that my application (C based) can generate the desired signal. This took all of 5 minutes and it works beautifully with all the modularity I need. Thank you so much for such an excellent utility and a project that is so well set up! This is how all code should be.
-David Medine

very long delays (hundreds of ms) when changing pulses

When changing pulses with add_channel_pulse() it can take a long time (up to half a second?) until the change is actually applied (see also raspberrypi/linux#476). I believe this is because the changed pulses will only be used for dma when the related cache lines get evicted from the cpu cache - this fits with the description in the issue I linked above, where some activity (for example io) can somewhat mitigate the issue. My workaround currently is to always use a very long subcycle time (and repeating the actually desired subcycle within that long subcycle), so that the whole cycle does not fit in cache. This does solve the problem, but a better solution would be to somehow avoid the cache altogether, though I have no idea if that is possible from userspace (in kernelspace dma_alloc_coherent might be used).

Have you experienced similar issues?

RPIO.PWM resets output on exit

I want to make a LED blink with a period of 2 seconds, and I would like the hardware to handle this, just like I can turn it on and off with RPi.GPIO and let my Python script exit. (With RPi.GPIO pin configuration and LOW/HIGH state is retained after script exits)

Using RPIO.PWM I can sucesfully configure the desired PWM signal.

The issue arises when I let my script exit: The PWM signal disappears.

I asume it is related to some DMA cleanup. Does anyone have some idea as to how this can be fixed?
I'll hapilly work on it myself, but some input as to where to dive in would be great!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.