Blinking led script with GPIO LEDS - python

I've been starting to learn Python on my raspberry pi.
I have 5 LEDs on GPIO pin 8, 10, 12, 16 and 18.
I have another code working, but I was trying to make it more compact. This one is not working but you can probably guess what I was trying to do.
I'm trying to make each led blink one by one by cycling through the chan_list list, but I'm stuck. How do I repeat the function for each entry of the list?
import RPi.GPIO as GPIO
from time import sleep
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
chan_list = [8,10,12,16,18]
GPIO.setup(chan_list, GPIO.OUT, initial=0)
delay = 50
#delay = float(input("50-1000ms"))
delay = delay / 1000
led = 0
while True:
def blink():
GPIO.output(chan_list, 1)
sleep(delay)
GPIO.output(chan_list, 0)
sleep(delay)
blink()

You can use the itertools.cycle() function to create an iterator that will — wait for it! — cycle through the values is the list.
This means something like this ought to work (I can't test it). Note I also moved the definition of blink() out of the loop — there's no need to do it more than once.
from itertools import cycle # ADDED.
from time import sleep
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
chan_list = [8,10,12,16,18]
chan_cycler = cycle(chan_list) # ADDED.
GPIO.setup(chan_list, GPIO.OUT, initial=0)
delay = 50
#delay = float(input("50-1000ms"))
delay = delay / 1000
delay = 1
led = 0
def blink():
chan = next(chan_cycler) # ADDED.
GPIO.output(chan, GPIO.HIGH)
sleep(delay)
GPIO.output(chan, GPIO.LOW)
sleep(delay)
while True:
blink()

def blink(): should be defined near the top, not inside of a loop. The GPIO.output() function takes a single pin number as its input, not a list of pins. The same goes for GPIO.setup(). To make things a bit easier, get rid of the function. You don't need it in this specific case. You should use a for loop to go over each element and call GPIO.setup() on it. Then, inside of the while loop, you need another for loop which goes over each of the elements in chan_list and turns them on and off. i don't have a Raspberry Pi on me right now, but I'd bet this would get the job done:
import RPi.GPIO as GPIO
from time import sleep
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
chan_list = [8,10,12,16,18]
for pin_number in chan_list:
GPIO.setup(pin_number, GPIO.OUT, initial=0)
delay = 50
#delay = float(input("50-1000ms"))
delay = delay / 1000
led = 0
while True:
for pin_number in chan_list:
GPIO.output(pin_number, 1)
sleep(delay)
GPIO.output(pin_number, 0)
sleep(delay)

Related

Execute a function every minute while not blocing hardware interrupts?

I'm making an energy meter using a Raspberry Pi, which gets its reading from a flashing LED (1000 flashes/kWh). It counts the flashes for 60 seconds through an interrupt and then it sends the data to a database. This works great, none of the flashes are missed this way, but because it just constantly checks if 60 seconds have passed it pegs the given thread to a 100% which is less than optimal for a 24/365 usecase.
Here is the important part of the code:
sampleFreqency = 60 #seconds
flashCount = 0
time1 = time.time()
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def flashCounter(self):
global flashCount
if not GPIO.input(17):
print("Light!")
flashCount = flashCount + 1
GPIO.add_event_detect(17, GPIO.BOTH, callback=flashCounter, bouncetime=50)
while True:
if time.time() > time1+sampleFreqency:
energy = flashCount #Wh
power = energy * 0.36/(sampleFreqency/10) # kW
print("Power: " + str(power) + "kW, Energy: " + str(energy) + "Wh")
logData(power, energy)
flashCount = 0
time1 = time.time()
I have tried using the threading Timer module without success, as it blocks everything else until it runs.
Turns out interrupts in fact do trigget while the program is doing time.sleep() , only my code was not functioning as I would have wanted it to. I have rewritten the ISR like this:
def flashCounter(self):
global flashCount
print("Light!")
flashCount = flashCount + 1
GPIO.add_event_detect(17, GPIO.FALLING, callback=flashCounter, bouncetime=50)
Now it works flawlessly.
The issue was that for sensing the blinking I'm using a photoresistor which has a slow reaction time, and when the interrupt triggered on the falling edge, the voltage probably has not had fallen to a level which would read as low, so the if statement did not get fulfilled.

Raspbian Pi program to calculate vehicle Speed using hall effect sensor

I was facing a problem to break counter variable after every 1 second.
This counter variable will keep tract of vehicle wheel revolution per seond which will help to calculate speed.
Also how we can pass a parameter in a function callback inside GPIO.add_event_detect() method.
My code for calculating vehicle speed is as follows :
import time
import datetime
import RPi.GPIO as GPIO
def sensorCallback(channel,cir=1.884):
#Called if sensor output changes
ts = datetime.datetime.now()
s=ts.second
count=0
if s%59==0:
count=0
else:
#Magnet
count=count+1
speed = count*cir*3600/1000
print(speed)
def main():
count=0
r=30
cir = (2*3.14*r)/100
s=0
last=0
speed=0
try:
while True :
time.sleep(0.1)
except KeyboardInterrupt:
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
GPIO.setup(17 , GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(17, GPIO.BOTH, callback=sensorCallback(count), bouncetime=200)

Combining two python codes for raspberry pi with a servo and ldr sensor

I have Python code running on my raspberry pi 2b and a light sensor, which measures the amount of time it takes for the capacitor of the light sensor to charge and send the pin high:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
pin_to_circuit = 7
def rc_time (pin_to_circuit):
count = 0
#Output on the pin for
GPIO.setup(pin_to_circuit, GPIO.OUT)
GPIO.output(pin_to_circuit, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_to_circuit, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_to_circuit) == GPIO.LOW):
count += 1
if count > 1000000:
return True
else:
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print rc_time(pin_to_circuit)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
I want when the count goes higher than 1000000, a MG90S, that I have also connected to the pi and a 4AA battery pack, moves about 90 degrees.
The code I was trying to integrate to move the servo:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p.ChangeDutyCycle(7.5) # turn towards 90 degree
time.sleep(1) # sleep 1 second
p.stop()
GPIO.cleanup()
I want to combine these two Python codes. I tried for a bit, but I have almost no Python experience.
The code is now:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
pin_to_circuit = 7
def move_90_degrees():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p = GPIO.PWM(12, 50)
p.start(7.5)
p.ChangeDutyCycle(7.5) # turn towards 90 degree
time.sleep(1) # sleep 1 second
p.stop()
def rc_time (pin_to_circuit):
count = 0
#Output on the pin for
GPIO.setup(pin_to_circuit, GPIO.OUT)
GPIO.output(pin_to_circuit, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_to_circuit, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_to_circuit) == GPIO.LOW):
count += 1
if count > 1000000:
return True
move_90_degrees()
else:
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print rc_time(pin_to_circuit)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
The code does print True when the count exceeds 1000000, but the servo still doesn't move. The servo code on its own does however work correctly. (I forgot a bit of the servo code, that's why p wasn't defined, sorry.)
You could just integrate the code block you are using to move the MG90S into a function, insert it before or below your def rc_time (pin_to_circuit): (but first you have to define p inside, its not really clear what p refers to):
New Function from second code block:
def move_90_degrees():
p = '???'
GPIO.setup(12, GPIO.OUT)
p.ChangeDutyCycle(7.5) # turn towards 90 degree
time.sleep(1) # sleep 1 second
p.stop()
After defining this function, call it inside your first block like:
if count > 1000000:
move_90_degrees()
return True
else:
return count
That should work.
I've made a mistake in the code. I changed the order of the function call inside of the
if count > 1000000:
return True
move_90_degrees()
else:
return count
block to :
if count > 1000000:
move_90_degrees()
return True
else:
return count
otherwise, the code returns before the function call is executed. Is it working now?

QTR-8RC Reflectance Sensor Array not returning data

I purchased a QTR-8RC Reflectance Sensor Array and now trying to configure it with Python. I am trying to determine the rate of decay of the voltage that is being read by my receivers (phototransistors) so that I know when a line is being detected. I don't know why my Python code isn't returning anything. Not even a warning statement. Additional information includes that by default the GPIO is an output and the LEDs are ON. Any help is appreciated!
import RPi.GPIO as GPIO
from time import sleep
def Read():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5, GPIO.OUT)
sleep(0.01)
count = 0
GPIO.setup(5, GPIO.IN)
while GPIO.input(5) == True:
count = count + 1
return count
while True:
Read()
print(Read())
sleep(1)
I don't have any knowledge about QTR-8RC Reflectance Sensor Array.
But looking at your python code, the problem might be with
while GPIO.input(5) == True
If the value is always true then the line with the return statement is never reached.
You could use print statement after while block to check that. Something like
while GPIO.input(5) == True:
count = count + 1
print "while loop has ended"
return count
Instead of running the program continuously run it for some time and check the outputs.
And may be you need to increase the sleep time to see the output practically.
import RPi.GPIO as GPIO
from time import sleep
def Read():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5, GPIO.OUT)
sleep(0.01)
count = 0
GPIO.setup(5, GPIO.IN)
while GPIO.input(5) == True:
count = count + 1
print "count :", count
return count
for _ in range(100):
print(Read())
sleep(2)

Can someone tell me how I would modify this code to come on more than once a day?

Can someone please tell me how I would modify this code to come on more than once a day? I am very new to python and trying to get my pi to run this timer. I tried adding an additional variable to the array such as SatOn2 but it is ignored. Clearly I do not understand how this works in Python. This was originally intended to run xmas lights but I am modifying to run an irrigation drip timer.
Any help greatly appreciated. Thank You!
# Raspberry Pi custom Christmas light timer
# import GPIO module
import RPi.GPIO as GPIO
# set up GPIO pins as outputs
# This convention is for the "P1" header pin convention
# where the pins start with P1 in the upper left
# and go to P26 in the lower right, with odds in the
# left column and evens in the right column.
# So, pins P1-11 and P1-12 correspond to GPIO17 and
# GPIO18 respectively.
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
# import date and time modules
import datetime
import time
# Enter the times you want the lights to turn on and off for
# each day of the week. Default is for lights to turn on at
# 5:30pm and off at 10:30pm on weekdays, on at 5:00pm and off
# at 11:30pm on weekends. Note that this is using a 24-hour clock.
MonOn = datetime.time(hour=17,minute=30,second=0)
MonOff = datetime.time(hour=22,minute=30,second=0)
TueOn = datetime.time(hour=17,minute=30,second=0)
TueOff = datetime.time(hour=22,minute=30,second=0)
WedOn = datetime.time(hour=17,minute=30,second=0)
WedOff = datetime.time(hour=22,minute=30,second=0)
ThuOn = datetime.time(hour=17,minute=30,second=0)
ThuOff = datetime.time(hour=22,minute=30,second=0)
FriOn = datetime.time(hour=17,minute=30,second=0)
FriOff = datetime.time(hour=22,minute=30,second=0)
SatOn = datetime.time(hour=17,minute=0,second=0)
SatOff = datetime.time(hour=23,minute=30,second=0)
SunOn = datetime.time(hour=17,minute=0,second=0)
SunOff = datetime.time(hour=23,minute=30,second=0)
# Store these times in an array for easy access later.
OnTime = [MonOn, TueOn, WedOn, ThuOn, FriOn, SatOn, SunOn]
OffTime = [MonOff, TueOff, WedOff, ThuOff, FriOff, SatOff, SunOff]
# Set a "wait time" in seconds. This ensures that the program pauses
# briefly after it turns the lights on or off. Otherwise, since the
# loop will execute more than once a second, it will try to keep
# turning the lights on when they are already on (or off when they are
# already off.
waitTime = 3
# Start the loop that will run until you stop the program or turn
# off your Raspberry Pi.
while True:
# get the current time in hours, minutes and seconds
currTime = datetime.datetime.now()
# get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
currDay = datetime.datetime.now().weekday()
#Check to see if it's time to turn the lights on
if (currTime.hour - OnTime[currDay].hour == 0 and
currTime.minute - OnTime[currDay].minute == 0 and
currTime.second - OnTime[currDay].second == 0):
# set the GPIO pin to HIGH, equivalent of
# pressing the ON button on the remote
GPIO.output(11, GPIO.HIGH)
# wait for a very short period of time then set
# the value to LOW, the equivalent of releasing the
# ON button
time.sleep(.5)
GPIO.output(11, GPIO.LOW)
# wait for a few seconds so the loop doesn't come
# back through and press the "on" button again
# while the lights ae already on
time.sleep(waitTime)
#check to see if it's time to turn the lights off
elif (currTime.hour - OffTime[currDay].hour == 0 and
currTime.minute - OffTime[currDay].minute == 0 and
currTime.second - OffTime[currDay].second == 0):
# set the GPIO pin to HIGH, equivalent of
# pressing the OFF button on the remote
GPIO.output(12, GPIO.HIGH)
# wait for a very short period of time then set
# the value to LOW, the equivalent of releasing the
# OFF button
time.sleep(.5)
GPIO.output(12, GPIO.LOW)
# wait for a few seconds so the loop doesn't come
# back through and press the "off" button again
# while the lights ae already off
time.sleep(waitTime)
Something like this should work:
# Raspberry Pi custom Christmas light timer
# import GPIO module
import RPi.GPIO as GPIO
# set up GPIO pins as outputs
# This convention is for the "P1" header pin convention
# where the pins start with P1 in the upper left
# and go to P26 in the lower right, with odds in the
# left column and evens in the right column.
# So, pins P1-11 and P1-12 correspond to GPIO17 and
# GPIO18 respectively.
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(12, GPIO.OUT)
# import date and time modules
import datetime
import time
# Enter the times you want the lights to turn on and off for
# each day of the week. Default is for lights to turn on at
# 5:30pm and off at 10:30pm on weekdays, on at 5:00pm and off
# at 11:30pm on weekends. Note that this is using a 24-hour clock.
MonOn = datetime.time(hour=17,minute=30,second=0)
MonOff = datetime.time(hour=22,minute=30,second=0)
TueOn = datetime.time(hour=17,minute=30,second=0)
TueOff = datetime.time(hour=22,minute=30,second=0)
WedOn = datetime.time(hour=17,minute=30,second=0)
WedOff = datetime.time(hour=22,minute=30,second=0)
ThuOn = datetime.time(hour=17,minute=30,second=0)
ThuOff = datetime.time(hour=22,minute=30,second=0)
FriOn = datetime.time(hour=17,minute=30,second=0)
FriOff = datetime.time(hour=22,minute=30,second=0)
SatOn = datetime.time(hour=17,minute=0,second=0)
SatOff = datetime.time(hour=23,minute=30,second=0)
SunOn = datetime.time(hour=17,minute=0,second=0)
SunOff = datetime.time(hour=23,minute=30,second=0)
MonOnTwo = datetime.time(hour=12,minute=30,second=0)
MonOffTwo = datetime.time(hour=13,minute=30,second=0)
# Store these times in an array for easy access later.
OnTime = [[MonOn, MonOnTwo], [TueOn], [WedOn], [ThuOn], [FriOn], [SatOn], [SunOn]]
OffTime = [[MonOff, MonOffTwo], [TueOff], [WedOff], [ThuOff], [FriOff], [SatOff], [SunOff]]
# Set a "wait time" in seconds. This ensures that the program pauses
# briefly after it turns the lights on or off. Otherwise, since the
# loop will execute more than once a second, it will try to keep
# turning the lights on when they are already on (or off when they are
# already off.
waitTime = 3
halfWait = waitTime / 2
# Start the loop that will run until you stop the program or turn
# off your Raspberry Pi.
while True:
# get the current time in hours, minutes and seconds
currTime = datetime.datetime.now()
# get the current day of the week (0=Monday, 1=Tuesday, 2=Wednesday...)
currDay = datetime.datetime.now().weekday()
for dtimes in OnTime[currDay]:
#Check to see if it's time to turn the lights on
if (currTime.hour - dtimes.hour == 0 and
currTime.minute - dtimes.minute == 0 and
currTime.second - dtimes.second > -halfWait and
currTime.second - dtimes.second < halfWait):
# set the GPIO pin to HIGH, equivalent of
# pressing the ON button on the remote
GPIO.output(11, GPIO.HIGH)
# wait for a very short period of time then set
# the value to LOW, the equivalent of releasing the
# ON button
time.sleep(.5)
GPIO.output(11, GPIO.LOW)
for dtimes in OffTime[currDay]:
#check to see if it's time to turn the lights off
if (currTime.hour - dtimes.hour == 0 and
currTime.minute - dtimes.minute == 0 and
currTime.second - dtimes.second > -halfWait and
currTime.second - dtimes.second < halfWait):
# set the GPIO pin to HIGH, equivalent of
# pressing the OFF button on the remote
GPIO.output(12, GPIO.HIGH)
# wait for a very short period of time then set
# the value to LOW, the equivalent of releasing the
# OFF button
time.sleep(.5)
GPIO.output(12, GPIO.LOW)
# wait for a few seconds because it's pointless to burn energy
# with no benefit
time.sleep(waitTime)

Categories