I want to know if I any mistakes? - python

I have a problem with the Jsn-sr04t water proof ultrasonic sensor, knowing that the connection in the raspberry pi zero W1 is well made becouse it is activated but the readings of this are totally wrong, the pins were entered correctly but this one seems to have a data entry error. I tried several programs in python that were used on this same sensor model
PD: I'm aware that this works, because I tested it on an arduino mega and the sensor worked correctly
import RPi.GPIO as GPIO
import os
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO_TRIGGER = 10
GPIO_ECHO = 8
TRIGGER_TIME = 0.00001
MAX_TIME = 0.004 # max time waiting for response in case something is missed
GPIO.setup(GPIO_TRIGGER, GPIO.OUT) # Trigger
GPIO.setup(GPIO_ECHO, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Echo
GPIO.output(GPIO_TRIGGER, False)
def measure():
# Pulse the trigger/echo line to initiate a measurement
GPIO.output(GPIO_TRIGGER, True)
time.sleep(TRIGGER_TIME)
GPIO.output(GPIO_TRIGGER, False)
# ensure start time is set in case of very quick return
start = time.time()
timeout = start + MAX_TIME
while GPIO.input(GPIO_ECHO) == 0 and start <= timeout:
start = time.time()
if(start > timeout):
return -1
stop = time.time()
timeout = stop + MAX_TIME
# Wait for end of echo response
while GPIO.input(GPIO_ECHO) == 1 and stop <= timeout:
stop = time.time()
if(stop <= timeout):
elapsed = stop-start
distance = float(elapsed * 34300)/2.0
else:
return -1
return distance
if __name__ == '__main__':
try:
while True:
distance = measure()
if(distance > -1):
print("Measured Distance = %.1f cm" % distance)
else:
print("#")
time.sleep(0.5)
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()
constantly OUTPUT: "#"

Seems like an issue with the GPIO settings or a timing issue as the same setup works with an Arduino.
Try with higher trigger on time (maybe 20us)
After elapsed calculation, print the elapsed time on the screen and check the actual value
If it still doesn't work, then you can also checkout the alternate output options like serial UART, PWM, etc. You can get more details here -
https://tutorials.probots.co.in/communicating-with-a-waterproof-ultrasonic-sensor-aj-sr04m-jsn-sr04t/

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.

Python RecursionError: maximum recursion depth exceeded

I have a python program I wrote that moves my solar panel with the sun throughout the day. It works fine, but about twice a week I get RecursionError: maximum recursion depth exceeded
I'm pretty new to python and I've looked up Recursion Errors, it says when a function calls itself too many times, I don't see where that is happening in this program.
from datetime import date
from datetime import datetime, timezone, timedelta
import astral
from astral import Astral
import time
import pytz
# import RPi.GPIO as GPIO
# Global Variables
ast = Astral()
city_Name = 'Cleveland'
local_City = ast[city_Name]
# sun_Position = local_City.sun(local=True)
reset_Solar = True
# Retrieves and returns current time
def get_Current_Time():
eastern = pytz.timezone('America/New_York')
curr_Time = datetime.now(eastern)
return curr_Time
def main_Function():
global local_City
sun_Position = local_City.sun(local=True)
current_Time = get_Current_Time()
solar_Sunrise = sun_Position.get('sunrise')
solar_Noon = sun_Position.get('noon')
solar_Sunset = sun_Position.get('sunset')
calc_Sunrise_Noon = solar_Noon - solar_Sunrise
total_Seconds = calc_Sunrise_Noon.seconds
calc_Hours, remainder = divmod(total_Seconds, 3600)
calc_Minutes, calc_Seconds = divmod(remainder, 60)
time_To_Adjust = total_Seconds / 24
print (current_Time)
print (solar_Sunrise)
if current_Time >= solar_Sunrise and current_Time < solar_Sunset:
solar_Adjust_Active(time_To_Adjust)
elif reset_Solar == True:
reset_Solar_Panel()
else:
solar_Adjust_Deactive()
def solar_Adjust_Active(time_To_Adjust):
while time_To_Adjust > 0:
current_Time = get_Current_Time()
time_To_Adjust = time_To_Adjust - 1
time.sleep(1)
print (current_Time)
print (time_To_Adjust)
daylight_Adjustment()
def solar_Adjust_Deactive():
global local_City
curr_Time = get_Current_Time()
calc_Tomorrow = curr_Time.date() + timedelta(days=1)
sun_Position_Tomorrow = local_City.sun(local=True, date = calc_Tomorrow)
solar_Sunrise_Tomorrow = sun_Position_Tomorrow.get('sunrise')
time_Till_Sunrise = solar_Sunrise_Tomorrow - curr_Time
sunrise_Total_Seconds = time_Till_Sunrise.seconds
calc_Sunrise_Hours, remainder = divmod(sunrise_Total_Seconds, 3600)
calc_Sunrise_Minutes, calc_Sunrise_Seconds = divmod(remainder, 60)
while sunrise_Total_Seconds > 0:
sunrise_Total_Seconds = sunrise_Total_Seconds - 1
time.sleep(1)
# print ('Seconds till Sunrise', sunrise_Total_Seconds)
print (solar_Sunrise_Tomorrow)
main_Function()
def daylight_Adjustment():
global reset_Solar
# Adustment to Solar Panel
#GPIO.setmode(GPIO.BCM)
# init pin numbers
#pin_Open = [6]
# set mode default state is 'low'
#GPIO.setup(pin_Open, GPIO.OUT)
# Activate Open Relay to High (High turns Relay on)
#GPIO.output(pin_Open, GPIO.HIGH) # Activate Open relay
# Start Timer for duration actuator will be activated
timer = 0
while timer < 1:
time.sleep(1)
timer = timer + 1
print ('Panal adjusted')
# set Open relay back to low (Turns Relay off)
#GPIO.output(pin_Open, GPIO.LOW)
# Reset GPIO settings
#GPIO.cleanup()
reset_Solar = True
main_Function()
def reset_Solar_Panel():
global reset_Solar
print ('Setting panel back to original position')
# Adustment to Solar Panel
# GPIO.setmode(GPIO.BCM)
# init pin numbers
# pin_Open = [XX]
# set mode default state is 'low'
# GPIO.setup(pin_Open, GPIO.OUT)
# Activate Open Relay to High (High turns Relay on)
# GPIO.output(pin_Open, GPIO.HIGH) # Activate Open relay
# Start Timer for duration actuator will be activated
timer = 0
while timer <= 48:
time.sleep(1)
timer = timer + 1
# set Open relay back to low (Turns Relay off)
# GPIO.output(pin_Open, GPIO.LOW)
# Reset GPIO settings
# GPIO.cleanup()
reset_Solar = False
main_Function()
main_Function()
You have (at least one) a loop in your code:
def main_Function():
-> solar_Adjust_Active(time_To_Adjust)
-> daylight_Adjustment()
-> main_Function() -> .... # lets run that for a couple of days ...
Normally you have a main loop (f.e. while True:) and call/return from functions into your main loop without recursing:
Pseudocode:
def resetToStart():
move panels to sunrise position
return
def movePanel():
get_currnt_optimal_position_for_datetime
move_to_that_position
return
resetToStart() # start at a well known position
while True:
if NightTime: # sun is down
resetToStart()
sleep till daytime
elif DayTime: # sun is up
movePanel()
sleep some till adjustment needed

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?

Python Multiprocessing Stops after a while

So basically we're using raspberry pi for a project and a part of it includes the usage of ultrasonic sensors. We have three, and we've been able to get readings from all of them (I actually came from multi-threading but decided to move to multiprocessing). Here is my code:
#Libraries
from multiprocessing import Process, Lock
import RPi.GPIO as GPIO
import time
#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#set GPIO Pins
GPIO_TRIGGER1 = 23
GPIO_ECHO1 = 24
GPIO_TRIGGER2 = 27
GPIO_ECHO2 = 22
GPIO_TRIGGER3 = 25
GPIO_ECHO3 = 17
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER1, GPIO.OUT)
GPIO.setup(GPIO_ECHO1, GPIO.IN)
GPIO.setup(GPIO_TRIGGER2, GPIO.OUT)
GPIO.setup(GPIO_ECHO2, GPIO.IN)
GPIO.setup(GPIO_TRIGGER3, GPIO.OUT)
GPIO.setup(GPIO_ECHO3, GPIO.IN)
def sense_distance(lock, processName):
#lock.acquire()
gpio_echo_var = ''
gpio_trigger_var = ''
if processName == "Sensor-1":
gpio_echo_var = GPIO_ECHO1
gpio_trigger_var = GPIO_TRIGGER1
elif processName == "Sensor-2":
gpio_echo_var = GPIO_ECHO2
gpio_trigger_var = GPIO_TRIGGER2
elif processName == "Sensor-3":
gpio_echo_var = GPIO_ECHO3
gpio_trigger_var = GPIO_TRIGGER3
print "%s process created." % (processName)
try:
while True:
# set Trigger to HIGH
GPIO.output(gpio_trigger_var, True)
# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(gpio_trigger_var, False)
StartTime = time.time()
StopTime = time.time()
# save StartTime
while GPIO.input(gpio_echo_var) == 0:
StartTime = time.time()
# save time of arrival
while GPIO.input(gpio_echo_var) == 1:
StopTime = time.time()
# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2
if distance <= 10:
print "%s has read less than 10 cm." % (processName)
else:
pass
# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()
#lock.release()
if __name__ == '__main__':
lock = Lock()
Process(target=sense_distance, args=(lock, "Sensor-1")).start()
Process(target=sense_distance, args=(lock, "Sensor-2")).start()
Process(target=sense_distance, args=(lock, "Sensor-3")).start()
It successfully reads the input and prints out the text when input goes smaller than 10 cm. However, after some time, they stop. I have run out of ideas and have searched all over only to come up short. Any sort of help will be appreciated.

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