Help with python script please for gpio

What is the problem?
I've attempted to write a script that monitors a gas sensor and then upon detection signals a relay to turn off the printer.
I wanted to tie the script into an action command I have setup in the config.yaml that triggers a GPIO pin to activate relay to turn the power on the printer. I have it setup in the config to run toggle GPIO pin and run the script working fine. However the issue is that if the sensor script is running it seems to own the GPIO communication until I quit the script and then the other action commands I have setup to turn on/off the printer/lights/temp/fan will work.

What did you already try to solve it?
googled, tested, trying to understand what the issue is. I'm not experienced enough with python to figure out how to release the GPIO but keep the script monitoring the gas sensor.

Additional information about your setup (OctoPrint version, OctoPi version, printer, firmware, octoprint.log, serial.log or output on terminal tab, ...)

Here's the config portion

  • action: printeron
    command: gpio -g mode 23 out
    command: /home/pi/oprint/bin/python /home/pi/scripts/smokesensor.py
    name: Turn on the Printer

Here's the script

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time
import math

DO = 3
PrinterPower = 23
GPIO.setmode(GPIO.BCM)

def setup():
GPIO.setup (DO, GPIO.IN)
GPIO.setup (PrinterPower, GPIO.OUT)
GPIO.output (PrinterPower, 0)

def Print(x):
if x == 1:
print ''
print ' *********'
print ' * Safe~ *'
print ' *********'
print ''
if x == 0:
print ''
print ' ***************'
print ' * Danger Gas! *'
print ' ***************'
print ''

def loop():
status = 1
count = 0
while True:

          tmp = GPIO.input(DO);
           if tmp != status:
                  Print(tmp)
                   status = tmp
           if status == 0:
           #       print(tmp)
                   count += 1
                   if count % 2 == 0:
                           GPIO.output(PrinterPower, 0)
                   else:
                           GPIO.output(PrinterPower, 1)
                           print(tmp)
                           import push
                          break

           time.sleep(1)

def destroy():
GPIO.output(PrinterPower, 0)
GPIO.cleanup()

if name == 'main':
try:
setup()
loop()
except KeyboardInterrupt:
destroy()

Thanks for any help!

Maybe foosel's answer in this thread would be helpful ...

1 Like

Thanks, but not quite the same kind of thing, at least I'm not able to adapt what he's written to my scenario.

I'm not quite understanding what the problem is, to be honest.

Where is that "config portion" again? It doesn't appear to be an event. I'm guessing this is an Action Command from your description.

If it were me, I think I would consider either running the script upon Raspbian startup or think of it in terms of firing off from the OctoPrint startup event. But that's just me.

You seem to indicate that the script does run, however. Anything that tries to talk to GPIO pins either has to run as root (sudo) or some other clever trick like Guy might have done with the OctoPi image. I'm pretty sure he's made it so that the pi user can do this without sudo.

It's possible that what you're saying is that this script—when it runs—seems to be hogging the entire GPIO space, preventing anything else from talking to it.

Foosel's reply was pretty brilliant:

#!/usr/bin/env python

import RPi.GPIO as GPIO
import time

# mapping of button id to pin
buttons = dict(button1=27, button2=23, button3=22, button4=17)

# setup pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(list(buttons.values()), GPIO.IN, pull_up_down=GPIO.PUD_UP)

# setup event detection
for pin in buttons.values():
    GPIO.add_event_detect(pin, GPIO.FALLING)

while True:
    for name, pin in buttons.items():
        if GPIO.event_detected(pin):
            print('{} pressed'.format(name))
    time.sleep(0.25)

She's using GPIO.event_detected(pin) here to minimize the impact on the system. My own clumsy attempt...

    button1 = GPIO.input(27)
    if button1 == False:
        print('Button1 ')
        time.sleep(0.25)

...apparently spends too much time polling the GPIO space rather than just looking for a trigger, as she did.

@Hobb3s did you ever get this working? This is exactly what I'm trying to do but with a flame/temp sensor.

Thanks!