Testing Pi2 B GPIO - gpio

As a newbie Im testing my Pi 2 B's GPIO. Why doesn't the code below switch the 15 pin on and off with an interval, but keeps it turned on?
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(15, GPIO.OUT)
for i in range(1000):
GPIO.output(15,1)
time.sleep(3)
GPIO.output(15,0)
print("switch")
GPIO.cleanup()

Your loop is ill-formed.
You switch ON the GPIO just after switching it OFF.
Fix:
for i in range(1000):
GPIO.output(15,1)
time.sleep(1) # ON for one second
GPIO.output(15,0)
print("switch")
time.sleep(1) # sleeping after the switch

Related

Raspberry Pi 4: Keep the Physical Pin output remain HIGH until set to LOW

Looks like I just discovered something from the Raspberry Pi board. That is, command GPIO.output(led_pin,GPIO.HIGH) sets the output pin high only momentary. I originally thought it keeps the led_pin HIGH until I set it OFF. I was wrong. Again, I have to give time command to tell how long to keep it HIGH.
My question is, how to make the Pin output remain HIGH once set unless I set it again to LOW.
My code for keeping the Pin output HIGH for 5 seconds:
import RPi.GPIO as GPIO
import time
# To disable warning in the console
GPIO.setwarnings(False)
led_pin = 17
GPIO.setmode(GPIO.BCM)
GPIO.setup(led_pin,GPIO.OUT)
# Set the led Pin to HIGH
GPIO.output(led_pin,GPIO.HIGH)
# Keep led ON for 5 seconds
time.sleep(5)

Need to detect any usb block device with specific partition label

I'm surprised this is proving to be difficult to find.
I need to detect when a USB block device with a specific partition label is added (plugged in) using python3.
Is there a way to use pyudev to provide a list of USB block devices? How can I specify a filter with subsystem="block" AND subsystem="usb", they seem to be mutually exclusive filters.
When a USB device having a partition named "XYZ" is plugged in, I need to run a script to mount it and run a program that uses the data on that partition.
I have tried too many variations to count, from various udev rules, systemd units, many scripts and combinations thereof, but have not had any success until I used the following code. It worked but caused 100% CPU load. When I added sleep time in the while loop at the end it no longer worked at all, and even prevented PCmanFM automounting as well.
The issue was in the usbEvent.py process. I could run it from the command line and it worked just fine. First thing it does is use Popen to call "grep devName /proc/mounts" to wait for the automounter to mount the partition. The Popen is called in a loop and adding some time.sleep eliminated the CPU burden tho that was surprising since the mount point appears in under a few seconds.
There seems to be some interplay between the code below systemd runs and the usbEvent.py process it spawns that I don't fully understand. They are separate processes so I would think they should be quite independent of each other.
The usbEvent.py handler works but it takes much longer to recognize the mount and continue. While it's running it consumes around 5% of the CPU, and only 0.3 when it finishes. Why it doesn't end when the timeout is over must be due to p.communicate, but if p.poll does NOT return None the process should be complete and should not block... but it does! Why?
The platform is a Raspberry Pi4 with 8GB RAM and January 2021 Raspbery Pi OS release.
#!/usr/bin/env python3
import os
import time
import subprocess as sp
import pyudev
# This code is run on boot via systemd to detect when
# my custom USB storage device (USB stick, SSD etc)
# is inserted or removed. It spawns a new process to
# handle the event.
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by('block', device_type="partition")
def log_event(action, device):
devName = device.get('DEVNAME')
devLabel = device.get('ID_FS_LABEL')
if devLabel == "MY_CUSTOM_USB":
sp.Popen(["/home/user/bin/customUSB/usbEvent.py",
action, devName, devLabel],
stdin=sp.DEVNULL, stdout=sp.DEVNULL, stderr=sp.DEVNULL)
observer = pyudev.MonitorObserver(monitor, log_event)
observer.start()
while True:
# pass
time.sleep(0.1)
Here is the portion of the usbEvent.py handler that I changed to get it working:
# Waits for mount point of "dev" to appear and returns it. Communnicate
def getMountPoint(dev):
out = ""
interval = 0.1
timeout = 5 / interval
while timeout > 0:
p = sp.Popen(["grep", dev, "/proc/mounts"],
text=True, stdout=sp.PIPE, stderr=sp.PIPE)
retCode = p.poll()
if retCode is None:
time.sleep(interval)
else:
out, err = p.communicate() # This should not block but does!
if retCode == 0 and len(out) > 0:
out = out.split()[1]
break
else:
lg.info(f"exit code: {retCode} Error: {err}")
exit(1)
if timeout == 0:
p.terminate()
return out

Relay control with Raspberry Pi and Python3

below is a section of code I am using to control a relay to open electric gates via a relay which is controlled via pin 7 on a raspberry pi GPIO. The gates only need a momentary voltage (via the relay contacts) to open.
My question is, what do I need to add to this code to make the relay only switch on for 0.5 Seconds when pin 7 goes high. This would enable relay to return to the off state and then wait for the next time GPIO pin 7 goes high, the gates do not need any commands from the GPIO to close after a certain time, they close under the control of the separate gate control system.
if name=="gate":
GPIO.setmode(GPIO.BOARD) ## Use board pin numbering
GPIO.setup(int(7), GPIO.OUT) ## Setup GPIO Pin to OUTPUT
GPIO.output(int(7), state) ## State is true/false
Many thanks
Peter
In this example I will use gpiozero library instead of RPi.GPIO because I like the way, how this library handle events.
from gpiozero import Button, OutputDevice
from time import sleep
from signal import pause
buttonPin = 4
relayPin = 7
button = Button(buttonPin)
button.when_pressed = ButtonPressedCallback
relay = OutputDevice(relayPin)
def ButtonPressedCallback():
relay.on()
sleep(0.5)
relay.off()
pause()
I hope, I understood your question good.

RPi.GPIO pins - check state

I'm using the RPi.GPIO module in Python to turn on and off GPIO pins on the Raspberry Pi 3.
Is there a way to identify whether an output pin is ON or OFF and put that value into a variable that I can use to decide whether the pin is ON and needs to turn OFF, or is OFF and needs to turn ON.
from the docs
The code below should provide the functionality you are looking for.
import RPi.GPIO as GPIO
channel = 11
GPIO.setmode(GPIO.BCM)
# Setup your channel
GPIO.setup(channel, GPIO.OUT)
GPIO.output(channel, GPIO.LOW)
# To test the value of a pin use the .input method
channel_is_on = GPIO.input(channel) # Returns 0 if OFF or 1 if ON
if channel_is_on:
# Do something here

GPIO interrupt triggered by different pin

tl;dr:
Listening to a RISING event on GPIO PIN14 (with 10K pulldown resistor); Ghost RISING events when sending/receiving data on different GPIO pin;
I have the following issue:
In my technical room I have a Raspberry Pi 1B, and Raspberry Pi 3; I tested this on both units and I get the same results;
My mains meter has a flashing LED, 1000/kWh; I want to measure this using a photo resistor; The photo resistor is connected to GPIO PIN14; This setup works just fine, as long as I don't use any of the other GPIO pins.
Using the same unit I want to send some data over 433Mhz (GPIO PIN7, but as soon as I transmit data, I get RISING events on PIN14...
Across the internet I found different solutions, none of which seem to be working:
Use a different Raspberry Pi (B1 is a tad bit old)
Use a 10K pull down resistor on PIN14
Use a different power supply
Use separate power supplies for the raspberry pi, photo resistor, and 433Mhz transmitter
Using the code below, I can see expected behavior of the photo resistor and PIN14; But as soon as I startup the transmissions, the events of sending a message and RISING events on PIN14 synchronize. When I stop sending messages the listener on PIN14 stops working.
Does anyone have any idea how to fix this?
PIN14 Listener code:
import datetime
import time
try:
import RPi.GPIO as GPIO
except RuntimeError:
print(
'Error importing RPi.GPIO! This is probably because you need superuser privileges.')
delta = datetime.timedelta(microseconds=100000)
global last_electric_ping
last_electric_ping = datetime.datetime.now()
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.IN)
def electric_ping(channel):
if GPIO.input(14):
global last_electric_ping
now = datetime.datetime.now()
if delta + last_electric_ping <= now:
print(delta + last_electric_ping, end=" ")
print('ELECTRIC')
last_electric_ping = now
GPIO.add_event_detect(14, GPIO.RISING, callback=electric_ping)
while True:
continue
GPIO.cleanup()
Transmission code:
import time
from pi_switch import RCSwitchSender
sender = RCSwitchSender()
sender.enableTransmit(15) # use WiringPi pin 0
num = 1
while True:
time.sleep(1)
print("Woei!")
sender.sendDecimal(num, 24)
num += 1
Roll the drums:
Apparently I ran into a numbering issue; The BCM pin numbering says physical pin 8 is GPIO14, which is nice;
Now three guesses which number wiringPi gives to physical pin number 8... yes, number 15! Which is the one I'm trying send data to in the second script;
Now excuse while I go slap myself with a brick in the corner over there...

Resources