I am trying to write a simple code in python which working on the Raspberry pi.
This code is working but I want to make a better code when I turb on LED in different time.
such as 5minutes later turn on the first led and another 5minutes later second led ....
The problem is when I changing the dlay time such as 5minutes or 10minutes, I have to do hard coding and it seems not a good way to do.
I also tried to adding time to timeset but could not find out the solution.
import RPi.GPIO as GPIO
from datetime import datetime
from datetime import timedelta
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(24, GPIO.OUT)
GPIO.setup(6, GPIO.OUT)
GPIO.setup(5, GPIO.OUT)
try:
while True:
timeset = datetime.now().strftime("%H:%M:%S")
print(timeset)
time.sleep(5)
if timeset > "19:11":
GPIO.output(24, True)
print('Please take a medicine')
if timeset > "19:12":
GPIO.output(6, True)
time.sleep(10)
GPIO.output(24, False)
GPIO.output(6, False)
time.sleep(0.30)
#if timeset =="00:23:30":
# timeset = datetime.now() + timedelta(minutes=1)
finally:
print("clean up")
GPIO.cleanup()`
https://discuss.tryton.org/t/typeerror-unsupported-operand-type-s-for-int-and-datetime-timedelta/4966
I have looked this and tried applying on my code but does not work.
You could go with a basic state machine.
Keep just sleep periods. No need anymore to deal with dates.
Example :
import time
i = 0
state = 0
while True:
time.sleep(5)
state = i%3
if state == 0:
print("light on led A")
elif state == 1:
print("light on led B")
elif state == 2:
print("light on led C")
i += 1
i increments forever
At each loop iteration thanks to the modulo function, state changes value in a cyclic way : 0, 1, 2, 0, 1, 2, ...
For each state value it's up to you to do whatever you decide with the RPi leds.
Related
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
Hi ladies and gentleman,
please forgive me if I've inputted the below code wrong as this is my first time posting here. I have a python script here that polls a capacitor every tenth of a second that is currently being used with a light dependent resistor to determine the brightness outside.
The only problem is that the numerical value often varies by around +/- 5. I would like to implement a line of code that averages the last ten polls every second and prints them. I have no idea where to start, any help would be appreciated!!
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
import I2C_LCD_driver
GPIO.setmode(GPIO.BOARD)
mylcd = I2C_LCD_driver.lcd()
#define the pin that goes to the circuit
pin_to_circuit = 40
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
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print "Current date & time " + time.strftime("%c")
print rc_time(pin_to_circuit)
a = rc_time(pin_to_circuit)
mylcd.lcd_display_string("->%s" %a)
mylcd.lcd_display_string("%s" %time.strftime("%m/%d/%Y %H:%M"), 2)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
You could define a list in your main loop:
polls = []
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print "Current date & time " + time.strftime("%c")
print rc_time(pin_to_circuit)
a = rc_time(pin_to_circuit)
#add current poll to list of polls
polls.append(a)
#remove excess history
if len(polls) > 10:
polls.pop(0)
#calculate average
avg = sum(polls)/len(polls)
mylcd.lcd_display_string("->%s" %avg)
mylcd.lcd_display_string("%s" %time.strftime("%m/%d/%Y %H:%M"), 2)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
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?
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)
I have a robot I am working on and am controlling it with PWM. The way I am controlling it is with a script that sets the PWM and then exits. I need it to set the PWM and then keep running. The reason I need it to exit is because I am just calling this script through an ssh connection each time the x and y values change. Normal digital outputs continue after the program exits but PWM doesn't with the way I have it setup.
Here is my code so far. It contains a lot of print statements to try to help me figure out what the problem was.
#filename: setMotors.py
import RPi.GPIO as GPIO
from sys import argv
from time import sleep
MOTOR_EN_1_PIN = 14
MOTOR_A_1_PIN = 15
MOTOR_B_1_PIN = 18
MOTOR_EN_2_PIN = 23
MOTOR_A_2_PIN = 24
MOTOR_B_2_PIN = 25
def mixXY(x, y):
"""
mixes x and y from a joystick to values for a 2 motor drive system
input: x (int or float), y (int or float)
output: (leftMotor (float), rightMotor (float)) tuple
"""
leftMotor = y + x
rightMotor = y - x
return (leftMotor, rightMotor)
def setMotorPWMS(leftMotor, rightMotor):
#left motor
if leftMotor == 0:
print("left motor 0")
GPIO.output(MOTOR_EN_1_PIN, 0)
motor1A.stop()
motor1B.stop()
elif leftMotor < 0:
print("left motor < 0")
GPIO.output(MOTOR_EN_1_PIN, 1)
motor1A.stop()
motor1B.ChangeDutyCycle(abs(leftMotor))
else:
print("left motor else")
GPIO.output(MOTOR_EN_1_PIN, 1)
motor1A.ChangeDutyCycle(leftMotor)
motor1B.stop()
#right motor
if rightMotor == 0:
print("right motor 0")
GPIO.output(MOTOR_EN_2_PIN, 0)
motor2A.stop()
motor2B.stop()
elif rightMotor < 0:
print("right motor < 0")
GPIO.output(MOTOR_EN_2_PIN, 1)
motor2A.stop()
motor2B.ChangeDutyCycle(abs(rightMotor))
else:
print("right motor else")
GPIO.output(MOTOR_EN_2_PIN, 1)
motor2A.ChangeDutyCycle(rightMotor)
motor2B.stop()
GPIO.setwarnings(False)
#setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(MOTOR_EN_1_PIN, GPIO.OUT)
GPIO.setup(MOTOR_A_1_PIN, GPIO.OUT)
GPIO.setup(MOTOR_B_1_PIN, GPIO.OUT)
GPIO.setup(MOTOR_EN_2_PIN, GPIO.OUT)
GPIO.setup(MOTOR_A_2_PIN, GPIO.OUT)
GPIO.setup(MOTOR_B_2_PIN, GPIO.OUT)
motor1A = GPIO.PWM(MOTOR_A_1_PIN, 50)
motor1B = GPIO.PWM(MOTOR_B_1_PIN, 50)
motor2A = GPIO.PWM(MOTOR_A_2_PIN, 50)
motor2B = GPIO.PWM(MOTOR_B_2_PIN, 50)
motor1A.start(0)
motor1B.start(0)
motor2A.start(0)
motor2B.start(0)
if len(argv) <= 2:
print("Need to call with x and y from commandline")
else:
motorPWM = mixXY(int(argv[1]), int(argv[2]))
leftMotorPWM = motorPWM[0]
rightMotorPWM = motorPWM[1]
print("left motor:",leftMotorPWM)
print("right motor:", rightMotorPWM)
setMotorPWMS(leftMotorPWM, rightMotorPWM)
sleep(5)
print("done")
The way it would be called is with sudo python setMotors.py x y. Is there a way of keeping the PWM going after the program exits or a better way of doing this?
The RaspberryPi doesn't support hardware PWM, so it's emulated using a software loop. Basically, it sets the GPIO, sleeps a little, resets the GPIO, sleeps a little and loops. This is done in a separated thread which is killed when the program ends.
Thus, you have to find a way to keep your program alive in the background. If you look at the official example on use of PWM, you'll notice the endless loop that keeps the program alive until manually killed.
You should also add something like
try:
while 1:
time.sleep(0.5)
except KeyboardInterrupt:
pass
p.stop()
GPIO.cleanup()
to the end of your program, or something better constructed using the signal module.
Then, leave the process in the background before destroying the console
sudo python setMotors.py x y &
You could also let your program get daemonized.