Is there an "interupt" command i should be using in my program - python

I would kindly ask for some support with my first program i am trying to write.
I have a raspberry pi 4 and am using the program Thonny and Python 3.9.2.
My program is trying to do the following.
There is a Microphone, and if it hears something it should turn on the yellow light. If it hears something 3 times in a set period of time it will turn on the red light.
The display runs though a script of explination and when the yellow or red light comes on it should switch to those expressions.
This is the problem I am having:
(to the best of my inspection) if the display is trying to change to the next line in the scrip and the yellow LED message is triggered the display gets "confused" and puts out nonsense.
I have tried to tell the display to only put out the discriptive script if the yellow and red light are off, but this didnt seem to really help.
The other observation i have is with the yellow and red LED. If the RED led triggers i want the counter reset on the yellow counter so that both yellow and red stay on for the same time, but the yellow light just stays on for the remainder of its time.sleep cycle.
I am a complete beginner and cant figure this out, is there an interupt command or something i could use here?
Here is the code for reference:
#V02 Trying to clean up the code and remove unessisary lines but working on fixing the strange characters that arrive and trying to get the system to reboot on its own.
import RPi.GPIO as GPIO #starts the IO functionality of the pi
import time # we need this for the sleep function
import threading #threading so we can get more than one thing to run at the same time
from time import sleep #sleep function
GPIO.setmode(GPIO.BCM) # setting for the IO
GPIO.setwarnings(False) #Suppress warnings
GPIO.setup(12,GPIO.OUT) #green
GPIO.setup(16,GPIO.OUT) #yellow
GPIO.setup(20,GPIO.OUT) #red
GPIO.setup(21,GPIO.IN) #NOISE SENSOR
# GPIO to LCD mapping
LCD_RS = 4 # BCM GPIO 4
LCD_E = 17 # BCM GPIO 17
LCD_D4 = 6 # BCM GPIO 6
LCD_D5 = 13 # BCM GPIO 13
LCD_D6 = 19 # BCM GPIO 19
LCD_D7 = 26 # BCM GPIO 26
# Device constants
LCD_CHR = True # Character mode
LCD_CMD = False # Command mode
LCD_CHARS = 16 # Characters per line (16 max)
LCD_LINE_1 = 0x80 # LCD memory location for 1st line
LCD_LINE_2 = 0xC0 # LCD memory location 2nd line
GPIO.output(16,GPIO.LOW) #set all pins to LOW Start postion for program
GPIO.output(20,GPIO.LOW) #set all pins to LOW Start postion for program
GPIO.output(12,GPIO.LOW) #set all pins to LOW Start postion for program
def Green(): #This is the status LED for the Green LED
while True:
GPIO.output(12,GPIO.HIGH)
time.sleep(2.5)
GPIO.output(12,GPIO.LOW)
time.sleep(.5)
def Yellow():
while True:
if GPIO.input(21) == 1: #this is the microphone sending a detection signal
print("Sound Detected")
GPIO.output(16,GPIO.HIGH) #turn on the yellow LED
lcd_text("I heard that",LCD_LINE_1)
lcd_text("Relax",LCD_LINE_2)
time.sleep(10)
GPIO.output(16,GPIO.LOW) #turn off the yellow LED
x = 0
def Red():
x = 0
while True:
if GPIO.input(16) == 1 and GPIO.input(21) == 1: #if Yellow light and Microphone activate at the same time we start counter for RED LED
x += 1
print(x)
time.sleep(.45)
if x > 2:
print("Too noisy in here")
GPIO.output(16,GPIO.HIGH)#if the x counter (sound counter) reaches greater than 3 we set the yellow and red LED on for 5 seconds
GPIO.output(20,GPIO.HIGH)
lcd_text("Schnauze",LCD_LINE_1)
lcd_text("sonst Beule",LCD_LINE_2)
time.sleep(10)
GPIO.output(20,GPIO.LOW)
GPIO.output(16,GPIO.LOW)
x = 0
if GPIO.input(16) == 0: #if the yellow light goes out before we reach x > 2 we set x back to 0
x = 0
t1 = threading.Thread(target=Green)
t2 = threading.Thread(target=Yellow)
t3 = threading.Thread(target=Red)
t1.start()
t2.start()
t3.start()
# Define main program code
def main():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
GPIO.setup(LCD_E, GPIO.OUT) # Set GPIO's to output mode
GPIO.setup(LCD_RS, GPIO.OUT)
GPIO.setup(LCD_D4, GPIO.OUT)
GPIO.setup(LCD_D5, GPIO.OUT)
GPIO.setup(LCD_D6, GPIO.OUT)
GPIO.setup(LCD_D7, GPIO.OUT)
# Initialize display
lcd_init()
# Loop - send text and sleep 3 seconds between texts
while True:
if GPIO.input(16) == 0 and GPIO.input(20) == 0:
lcd_text("Welcome to",LCD_LINE_1)
lcd_text("P4DQ",LCD_LINE_2)
time.sleep(5) # 3 second delay
lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
if GPIO.input(16) == 0 and GPIO.input(20) == 0:
lcd_text("I detect loud",LCD_LINE_1)
lcd_text("noise",LCD_LINE_2)
time.sleep(5) # 3 second delay
lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
if GPIO.input(16) == 0 and GPIO.input(20) == 0:
lcd_text("Green LED",LCD_LINE_1)
lcd_text("I'm listening",LCD_LINE_2)
time.sleep(5) # 3 second delay
lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
if GPIO.input(16) == 0 and GPIO.input(20) == 0:
lcd_text("Yellow LED",LCD_LINE_1)
lcd_text("I hear something",LCD_LINE_2)
time.sleep(5)
lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
if GPIO.input(16) == 0 and GPIO.input(20) == 0:
lcd_text("Red LED",LCD_LINE_1)
lcd_text("It's TOO LOUD :(",LCD_LINE_2)
time.sleep(5)
lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
if GPIO.input(16) == 0 and GPIO.input(20) == 0:
lcd_init() # start the LCD init program at the end of the loop to clear out strange characters on the display
# End of main program code
# Initialize and clear display
def lcd_init():
lcd_write(0x33,LCD_CMD) # Initialize
lcd_write(0x32,LCD_CMD) # Set to 4-bit mode
lcd_write(0x06,LCD_CMD) # Cursor move direction
lcd_write(0x0C,LCD_CMD) # Turn cursor off
lcd_write(0x28,LCD_CMD) # 2 line display
lcd_write(0x01,LCD_CMD) # Clear display
time.sleep(0.0005) # Delay to allow commands to process
def lcd_write(bits, mode):
# High bits
GPIO.output(LCD_RS, mode) # RS
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
lcd_toggle_enable()
def lcd_toggle_enable():
time.sleep(0.0005)
GPIO.output(LCD_E, True)
time.sleep(0.0005)
GPIO.output(LCD_E, False)
time.sleep(0.0005)
def lcd_text(message,line):
# Send text to display
message = message.ljust(LCD_CHARS," ")
lcd_write(line, LCD_CMD)
for i in range(LCD_CHARS):
lcd_write(ord(message[i]),LCD_CHR)
#Begin program
try:
main()
finally:
lcd_write(0x01, LCD_CMD)
GPIO.cleanup()

Related

Python Threading: Using 2 Light Dependant Resistors (LDR)

I am using a simple code from PiMyLife tutorial to read from a Light Dependant Resistor using a capacitor. This works great..
I then added a 2nd LDR and capacitor, added it to pin 31 and then duplicated the code (the rc_time function and the fuction call) to add an additional Light Dependant Resistor but for some reason the second function call never happens.
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_ldr_one = 29
pin_ldr_two = 31
def rc_time_one (pin_ldr_one):
count_one = 0
#Output on the pin for
GPIO.setup(pin_ldr_one, GPIO.OUT)
GPIO.output(pin_ldr_one, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_one, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_one) == GPIO.LOW):
count_one += 1
return count_one
def rc_time_two (pin_ldr_two):
count_two = 0
#Output on the pin for
GPIO.setup(pin_ldr_two, GPIO.OUT)
GPIO.output(pin_ldr_two, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_two, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_two) == GPIO.LOW):
count_two += 1
return count_two
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print("LDR 1: ",rc_time_one(pin_ldr_one))
print("LDR 2: ",rc_time_two(pin_ldr_two))
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
So I thought I would try threading instead thinking that the 2 function calls were having issues.
So this is the threading code I came up with however this too fails to run the second (in this cask 2nd thread). Any ideas where I am going wrong. Thanks for all your help
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
from time import sleep, perf_counter
from threading import Thread
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_ldr_one = 29
pin_ldr_two = 31
def rc_time_one (pin_ldr_one = 29):
count_one = 0
#Output on the pin for
GPIO.setup(pin_ldr_one, GPIO.OUT)
GPIO.output(pin_ldr_one, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_one, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_one) == GPIO.LOW):
count_one += 1
print("LDR 1: ",count_one)
return count_one
def rc_time_two (pin_ldr_two = 31):
count_two = 0
#Output on the pin for
GPIO.setup(pin_ldr_two, GPIO.OUT)
GPIO.output(pin_ldr_two, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_two, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_two) == GPIO.LOW):
count_two += 1
print("LDR 2: ",count_two)
return count_two
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
# create two new threads
t1 = Thread(target=rc_time_one)
t2 = Thread(target=rc_time_two)
# start the threads
t1.start()
t2.start()
t1.join()
t2.join()
#print("LDR 1: ",rc_time_one(pin_ldr_one))
#print("LDR 2: ",rc_time_two(pin_ldr_two))
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Peter

PI controller threading & strange issue

I have a attached a rotary encoder to a DC motor shaft in hopes of creating a python script on a PI4 in which one could set a desired angle, motor will move CW at a 10 - duty cycle, and motor will stop and hold position on desired angle that once set angle is read back into code from rotary encoder (# 800 pulses per revolution - reading out 0.45 deg increments).
The PI controller will ideally then hold the set angle (set in code but later GUI) and will not move regardless of outside force on the shaft.
Lastly i am using if statments after my PI control signal 'PI' into a duty cycle ouput thus controlling the speed of the motor as it reaches the set point (either slowing down or speeding up tp get to the set point) with error PI polarity governing directional output....if this could be done better i'd appreciate any suggestions
I am only getting 1 error i cant figure out and cant find a solution online...but i feel i am close to getting this code right. Any criticism is welcome. The error is regarding the "PI" output of the Pi equation:
"Value of type "int" is not indexable"
from RPi import GPIO
import time
import threading
#Encoder GPIO Pins
clk = 15 # GRN/YLW Z+
dt = 11 # BLU/GRN Z-
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
#Motor GPIO Pins
PWMPin = 18 # PWM Pin connected to ENA.
Motor1 = 16 # Connected to Input 1.
Motor2 = 18 # Connected to Input 2.
GPIO.setup(PWMPin, GPIO.OUT) # We have set our pin mode to output
GPIO.setup(Motor1, GPIO.OUT)
GPIO.setup(Motor2, GPIO.OUT)
GPIO.output(Motor1, GPIO.LOW)# When program start then all Pins will be LOW.
GPIO.output(Motor2, GPIO.LOW)
def MotorClockwise():
GPIO.output(Motor1, GPIO.LOW) # Motor will move in clockwise direction.
GPIO.output(Motor2, GPIO.HIGH)
def MotorAntiClockwise():
GPIO.output(Motor1, GPIO.HIGH) # Motor will move in anti-clockwise direction.
GPIO.output(Motor2, GPIO.LOW)
#Sim Values
duty_c = 10 #duty Cycle
PwmValue = GPIO.PWM(PWMPin, 10000) # We have set our PWM frequency to 5000.
PwmValue.start(duty_c) # That's the maximum value 100 %.
error = 0
Set_point = 1.8
encoder_counter = 0
encoder_angle = 0
Kp = 2
Ki = 1
PI = 0
#Sim Parameters
Ts = .1 #sampling time
Tstop = 200 #end simulation time
N = int(Tstop/Ts)#simulation length
def ReadEncoder():
global encoder_counter
global encoder_angle
clkLastState = GPIO.input(clk)
while True:
clkState = GPIO.input(clk)
dtState = GPIO.input(dt)
encoder_angle = float(encoder_counter/800)*360
if clkState != clkLastState:
if dtState != clkState:
encoder_counter += 1
else:
encoder_counter -= 1
#print("encoder_counter", encoder_counter )
print("encoder_angle", encoder_angle )
time.sleep(1)
clkState = clkLastState
# some delay needed in order to prevent too much CPU load,
# however this will limit the max rotation speed detected
time.sleep(.001)
def PI_function():
global PI
global duty_c
global error
global Kp
global Ki
global encoder_angle
for k in range(N+1):
error = int(Set_point) - encoder_angle
print (f"{error} Error Detected")
PI = PI[k-1] + Kp*(error[k] - error[k-1]) + (Kp/Ki)*error[k] #PI equation
print (f"{PI} PI value")
if (PI > 0):
MotorClockwise()
else:
MotorAntiClockwise()
if ((PI > duty_c) & (duty_c <100)):
duty_c += 1
if ((PI < duty_c) & (duty_c > 10)):
duty_c -= 1
return()
def main_function():
if (N != 0):
encoder_thread = threading.Thread( target=ReadEncoder)
encoder_thread.start()
encoder_thread.join()
PI_thread = threading.Thread( target=PI_function)
PI_thread.start()
PI_thread.join()
PwmValue.ChangeDutyCycle(duty_c)
else:
PwmValue.ChangeDutyCycle(0)
print(f"Motor Stopped & Holding at {encoder_angle} Degrees")

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?

How to control LEDs via a LDR and a button as well?

I'm currently working on a Node-RED webapplication to control several leds with switch buttons. Next, using a Python script to read the LDR value. This value will be used to determine if it's light or dark outside. When it's dark, one led has to be enabled and the others disabled, the opposite when it's light.
#!/usr/bin/env python
import cgitb ; cgitb.enable()
import spidev
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)
GPIO.setup(27, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
spi = spidev.SpiDev() # create spi object
spi.open(0,0) # open spi port 0, device CS0 pin 24
# read SPI data 8 possible adc's (0 thru 7)
def readadc(adcnum):
if ((adcnum > 7) or (adcnum < 0)):
return -1
r = spi.xfer2([1,(8+adcnum)<<4,0])
adcout = ((r[1]&3) << 8) + r[2]
return adcout
As you can see, the rest of this script keeps going because of the while loop.
while True:
tmp0 = readadc(0) # read channel 0
if(tmp0 > 500):
msg = "LIGHT"
GPIO.output(17, False)
else:
msg = "DARK"
GPIO.output(17, True)
GPIO.output(18, False)
GPIO.output(22, False)
GPIO.output(27, False)
time.sleep(0.3)
print msg
Finnally, I can't use both. Once I click one a switch the led will go on for 1 second. I need to find a manner to combine both methods. Any tips?
IF what you want, is for the light conditions to dictate the initial led state, as well as updating the state when the light conditions change; but the switches to over-ride these until the light conditions change, then this should help:
light_set = None
while True:
tmp0 = readadc(0) # read channel 0
if(tmp0 > 500) and light_set != "LIGHT":
msg = "LIGHT"
light_set = msg
GPIO.output(17, False)
else if light_set != "DARK":
msg = "DARK"
light_set = msg
GPIO.output(17, True)
GPIO.output(18, False)
GPIO.output(22, False)
GPIO.output(27, False)
time.sleep(0.3)
print msg
This should "remember" what this code section last set the led to, so it won't keep setting it if it's changed with a switch. It will still change it, when the current light conditions aren't what it last set it to though.

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