I am trying to code ultrasonic sensors to count the number of cars in a parking lot. I am relatively new to Python, so I am asking here for help.
I have three parking slots, in which each of them has an ultrasonic sensor.
How do I make it so that the sensors and their counters work together? For example, when the parking slots are empty, the counter shows three parking slots available. When two parking slots are filled, the counter shows one availability, etc.
I have done the following code, and I am wondering how I could continue to achieve my objective?
# Sensor 1
def distance_1():
time.sleep(0.5)
GPIO.output(TRIG_1, True)
time.sleep(0.00001)
GPIO.output(TRIG_1, False)
print("Reading Sensor 1")
while GPIO.input(ECHO_1) == 0:
start = time.time()
while GPIO.input(ECHO_1) == 1:
end = time.time()
duration = end - start
sound = 34000 / 2
distance = duration * sound
round(distance, 0)
total = 3
count = total
if distance <= 10:
count -= 1
elif distance > 10:
count += 1
if count < 0:
count = 0
elif count > total:
count = total
print(count)
mylcd.lcd_display_string("{}".format(count), 2)
# Sensor 2
def distance_2():
time.sleep(0.5)
GPIO.output(TRIG_2, True)
time.sleep(0.00001)
GPIO.output(TRIG_2, False)
print("Reading Sensor 2")
while GPIO.input(ECHO_2) == 0:
start = time.time()
while GPIO.input(ECHO_2) == 1:
end = time.time()
duration = end - start
sound = 34000 / 2
distance = duration * sound
round(distance, 0)
total = 3
count = total
if distance <= 10:
count -= 1
elif distance > 10:
count += 1
if count < 0:
count = 0
elif count > total:
count = total
print(count)
mylcd.lcd_display_string("{}".format(count), 2)
# Sensor 3
def distance_3():
time.sleep(0.5)
GPIO.output(TRIG_3, True)
time.sleep(0.00001)
GPIO.output(TRIG_3, False)
print("Reading Sensor 3")
while GPIO.input(ECHO_3) == 0:
start = time.time()
while GPIO.input(ECHO_3) == 1:
end = time.time()
duration = end - start
sound = 34000 / 2
distance = duration * sound
round(distance, 0)
total = 3
count = total
if distance <= 10:
count -= 1
elif distance > 10:
count += 1
if count < 0:
count = 0
elif count > total:
count = total
print(count)
mylcd.lcd_display_string("{}".format(count), 2)
while True:
distance_1()
distance_2()
distance_3()
GPIO.cleanup()
The trouble with programming is there are so many ways to achieve the same result.
Looking at your code, I would suggest taking a step back and refactoring it to use Python classes instead. You have a lot of code repetition happening, and eventually, the code will break if you need to keep adding more sensors.
For example:
class Parking:
"This is a parking class"
def __init__(self, space):
self.space = space
def empty(self):
if self.space == 0:
print('Parking space is empty')
def full(self):
if self.space == 1:
print('Parking space is full')
def distance(self):
time.sleep(0.5)
GPIO.output(TRIG, True)
. . .
# Input:
sensor1 = Parking(1)
sensor2 = Parking(1)
sensor3 = Parking(0)
# Output:
sensor1.empty()
sensor2.empty()
sensor3.empty()
# Output:
sensor1.full()
sensor2.full()
sensor3.full()
You can then update a dictionary with the output to monitor the latest sensor information. Ideally, the dictionary would be written to a central file accessible by all the sensors or raspberry pis to read.
available_spaces = {"sensor1": 0, "sensor2": 1, "sensor3": 0}
I analyzed your code and I did some refactorings.
I suggest you to use constant values initialization (the config section you see in the code below). The values I used are random.
A function can be parametrized, so you can pass arguments to functions, and avoid writing the same piece of code changing only a few values in the same place.
You should set up your microcontroller when the script starts, to tell the board how you are using the pins (as input or output).
I didn't dig into on the snippet above the lcd_display_string and why are you doing those operations. I suppose that these are required to print on screen the distance.
## configuration
# trigger
TRIG_1 = 17
TRIG_2 = 27
TRIG_3 = 22
# echo
ECHO_1 = 10
ECHO_2 = 9
ECHO_3 = 11
# timings
INITIAL_DELAY = 0.5
TRIGGERING_DELAY = 0.00001
## support functions
# initializing GPIO
def set_up():
# set trigger GPIOs as output pins
GPIO.setup(TRIG_1, GPIO.OUT)
GPIO.setup(TRIG_2, GPIO.OUT)
GPIO.setup(TRIG_3, GPIO.OUT)
# set echo GPIOs as input pins
GPIO.setup(ECHO_1, GPIO.IN)
GPIO.setup(ECHO_2, GPIO.IN)
GPIO.setup(ECHO_3, GPIO.IN)
# I didn't dig into these values and why are you doing these operations. I suppose that these are required to print on screen the distance.
def print_distance_on_lcd(distance):
total = 3
count = total
if distance <= 10:
count -= 1
elif distance > 10:
count += 1
if count < 0:
count = 0
elif count > total:
count = total
print(count)
mylcd.lcd_display_string("{}".format(count), 2)
def trigger(trigger):
time.sleep(INITIAL_DELAY)
GPIO.output(trigger, True) # set output pin on HIGH state
time.sleep(TRIGGERING_DELAY)
GPIO.output(trigger, False) # set output pin on LOW state
def distance(t, echo):
trigger(t)
# initializing the variables here, allows you to use it outside the while block below
# using variable names that explains their content
start_time = time.time()
end_time = time.time()
# this block is not wrong, but unnecessary: initializing the variable like above is enough
'''
while GPIO.input(echo) == 0:
start_time = time.time()
'''
while GPIO.input(echo) == 1:
end_time = time.time()
duration = end_time - start_time
sound = 34000 / 2
distance = duration * sound
return distance
# call initialization function (this will be executed only one time)
set_up()
# loop forever
while True:
set_up()
print("Reading Sensor 1")
distance_sensor_1 = distance(TRIG_1, ECHO_1)
print_distance_on_lcd(distance_sensor_1)
print("Reading Sensor 2")
distance_sensor_2 = distance(TRIG_2, ECHO_2)
print_distance_on_lcd(distance_sensor_2)
print("Reading Sensor 3")
distance_sensor_3 = distance(TRIG_3, ECHO_3)
print_distance_on_lcd(distance_sensor_3)
GPIO.cleanup()
Related
since i didnt really get the Adafruit-Library going to read the sensor correctly, i started using PIGPIO to read the DHT22. It works and i can see the Temperature and Humidity. My problem is now, how do i get those values into InfluxDB to use them in Grafana.
I already installed my DB and connected it with Grafana and made a DB called temp. The connection worked, now i just need to input some data.
!/usr/bin/env python
# 2014-07-11 DHT22.py
import time
import atexit
import pigpio
class sensor:
"""
A class to read relative humidity and temperature from the
DHT22 sensor. The sensor is also known as the AM2302.
The sensor can be powered from the Pi 3V3 or the Pi 5V rail.
Powering from the 3V3 rail is simpler and safer. You may need
to power from 5V if the sensor is connected via a long cable.
For 3V3 operation connect pin 1 to 3V3 and pin 4 to ground.
Connect pin 2 to a gpio.
For 5V operation connect pin 1 to 5V and pin 4 to ground.
The following pin 2 connection works for me. Use at YOUR OWN RISK.
5V--5K_resistor--+--10K_resistor--Ground
|
DHT22 pin 2 -----+
|
gpio ------------+
"""
def __init__(self, pi, gpio, LED=None, power=None):
"""
Instantiate with the Pi and gpio to which the DHT22 output
pin is connected.
Optionally a LED may be specified. This will be blinked for
each successful reading.
Optionally a gpio used to power the sensor may be specified.
This gpio will be set high to power the sensor. If the sensor
locks it will be power cycled to restart the readings.
Taking readings more often than about once every two seconds will
eventually cause the DHT22 to hang. A 3 second interval seems OK.
"""
self.pi = pi
self.gpio = gpio
self.LED = LED
self.power = power
if power is not None:
pi.write(power, 1) # Switch sensor on.
time.sleep(2)
self.powered = True
self.cb = None
atexit.register(self.cancel)
self.bad_CS = 0 # Bad checksum count.
self.bad_SM = 0 # Short message count.
self.bad_MM = 0 # Missing message count.
self.bad_SR = 0 # Sensor reset count.
# Power cycle if timeout > MAX_TIMEOUTS.
self.no_response = 0
self.MAX_NO_RESPONSE = 2
self.rhum = -999
self.temp = -999
self.tov = None
self.high_tick = 0
self.bit = 40
pi.set_pull_up_down(gpio, pigpio.PUD_OFF)
pi.set_watchdog(gpio, 0) # Kill any watchdogs.
self.cb = pi.callback(gpio, pigpio.EITHER_EDGE, self._cb)
def _cb(self, gpio, level, tick):
"""
Accumulate the 40 data bits. Format into 5 bytes, humidity high,
humidity low, temperature high, temperature low, checksum.
"""
diff = pigpio.tickDiff(self.high_tick, tick)
if level == 0:
# Edge length determines if bit is 1 or 0.
if diff >= 50:
val = 1
if diff >= 200: # Bad bit?
self.CS = 256 # Force bad checksum.
else:
val = 0
if self.bit >= 40: # Message complete.
self.bit = 40
elif self.bit >= 32: # In checksum byte.
self.CS = (self.CS << 1) + val
if self.bit == 39:
# 40th bit received.
self.pi.set_watchdog(self.gpio, 0)
self.no_response = 0
total = self.hH + self.hL + self.tH + self.tL
if (total & 255) == self.CS: # Is checksum ok?
self.rhum = ((self.hH << 8) + self.hL) * 0.1
if self.tH & 128: # Negative temperature.
mult = -0.1
self.tH = self.tH & 127
else:
mult = 0.1
self.temp = ((self.tH << 8) + self.tL) * mult
self.tov = time.time()
if self.LED is not None:
self.pi.write(self.LED, 0)
else:
self.bad_CS += 1
elif self.bit >= 24: # in temp low byte
self.tL = (self.tL << 1) + val
elif self.bit >= 16: # in temp high byte
self.tH = (self.tH << 1) + val
elif self.bit >= 8: # in humidity low byte
self.hL = (self.hL << 1) + val
elif self.bit >= 0: # in humidity high byte
self.hH = (self.hH << 1) + val
else: # header bits
pass
self.bit += 1
elif level == 1:
self.high_tick = tick
if diff > 250000:
self.bit = -2
self.hH = 0
self.hL = 0
self.tH = 0
self.tL = 0
self.CS = 0
else: # level == pigpio.TIMEOUT:
self.pi.set_watchdog(self.gpio, 0)
if self.bit < 8: # Too few data bits received.
self.bad_MM += 1 # Bump missing message count.
self.no_response += 1
if self.no_response > self.MAX_NO_RESPONSE:
self.no_response = 0
self.bad_SR += 1 # Bump sensor reset count.
if self.power is not None:
self.powered = False
self.pi.write(self.power, 0)
time.sleep(2)
self.pi.write(self.power, 1)
time.sleep(2)
self.powered = True
elif self.bit < 39: # Short message receieved.
self.bad_SM += 1 # Bump short message count.
self.no_response = 0
else: # Full message received.
self.no_response = 0
def temperature(self):
"""Return current temperature."""
return self.temp
def humidity(self):
"""Return current relative humidity."""
return self.rhum
def staleness(self):
"""Return time since measurement made."""
if self.tov is not None:
return time.time() - self.tov
else:
return -999
def bad_checksum(self):
"""Return count of messages received with bad checksums."""
return self.bad_CS
def short_message(self):
"""Return count of short messages."""
return self.bad_SM
def missing_message(self):
"""Return count of missing messages."""
return self.bad_MM
def sensor_resets(self):
"""Return count of power cycles because of sensor hangs."""
return self.bad_SR
def trigger(self):
"""Trigger a new relative humidity and temperature reading."""
if self.powered:
if self.LED is not None:
self.pi.write(self.LED, 1)
self.pi.write(self.gpio, pigpio.LOW)
time.sleep(0.017) # 17 ms
self.pi.set_mode(self.gpio, pigpio.INPUT)
self.pi.set_watchdog(self.gpio, 200)
def cancel(self):
"""Cancel the DHT22 sensor."""
self.pi.set_watchdog(self.gpio, 0)
if self.cb is not None:
self.cb.cancel()
self.cb = None
if __name__ == "__main__":
import time
import pigpio
import DHT22
# Intervals of about 2 seconds or less will eventually hang the DHT22.
INTERVAL = 3
pi = pigpio.pi()
s = DHT22.sensor(pi, 2, LED=16, power=8)
r = 0
next_reading = time.time()
while True:
r += 1
s.trigger()
time.sleep(0.2)
print("{} {} {} {:3.2f} {} {} {} {}".format(
r, s.humidity(), s.temperature(), s.staleness(),
s.bad_checksum(), s.short_message(), s.missing_message(),
s.sensor_resets()))
next_reading += INTERVAL
time.sleep(next_reading-time.time()) # Overall INTERVAL second polling.
s.cancel()
pi.stop()
from microbit import *
from ssd1306 import initialize, clear_oled
from ssd1306_stamp import draw_stamp
from ssd1306_img import create_stamp
from ssd1306_text import add_text
import utime as time
window = []
threshold = 550 # limit
count = 0
sample = 0
beat = False
start = False
good = create_stamp(Image.HAPPY)
bad = create_stamp(Image.SAD)
heart = create_stamp(Image.HEART)
values = []
def mean(datalist):
sum = 0
for i in datalist:
sum += i
if len(datalist) > 0:
return sum/len(datalist)
else:
return None
while True:
if button_a.was_pressed():
while True:
signal = pin1.read_analog()
window.append(signal)
avg = round(mean(window))
values.append(avg)
if len(window) == 11:
window.pop(0)
if beat is False and avg >= threshold+10:
beat = True
count += 1
display.show(Image.HEART, wait=False)
if count == 1:
t1 = time.ticks_ms()
if count == 11:
t2 = time.ticks_ms()
T = t2 - t1
bpm = round(600*1000/(T))
display.scroll(str(bpm))
initialize()
clear_oled()
add_text(0, 0, "Heart rate :")
add_text(0, 3, str(bpm) + " bpm")
if 60 <= bpm <= 100:
draw_stamp(38, 24, good, 1)
else :
draw_stamp(38, 24, bad, 1)
count = 0
sleep(2000)
if button_b.was_pressed():
break
count = 0
elif beat is True and avg <= threshold-10:
beat = False
display.clear()
sample += 1
if sample == 250:
threshold = mean(values)
values = []
sample = 0
sleep(20)
sleep(20)
This is the code connect to the microbit, and the function is about the heart rate sensor, which it will appear the average beat per minute when sensing 10 beats of the heart.
I am thinking of adding a function that if button b is pressed, the loop will pause, and press the button a to start again. I tried to add a break function in the loop, it worked when I click the button b, it pause the loop, however, the count of beat won't reset, and the time between the beat is also recorded although I break the loop.
Is there any way that I can break the loop and reset the count?
You should reset the counter before breaking. In your current code the line for the count is not executing since it breaks out before it reaches it.
if button_b.was_pressed():
count = 0
break
im fairly new with python but im tring to get a device to turn on for one minute and off for 3 minutes repeatedly from the times of 9am to 5pm and i can't get the if statement to reference the updated time from the loop any help would be greatly appreciated!!!
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
now = datetime.datetime.now()
hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.second
total = 1
if hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
for i in range(1,100):
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
else :
for i in range(1,100):
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
You could fix it with a while loop instead, it would look like this, just put all of it inside your function
now = datetime.datetime.now()
hour = now.hour
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run:
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.second
print (hour)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
while run == False:
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
if hour >= 8 and hour <= 16:
run = True
else:
run = False
Maybe using a while statement. In addition, you have hour = now.second on the second line of the function count and I think it should be hour = now.hour.
See the code with comments:
import datetime
import time
n = "on" #to be replaced with GPIO output
f = "off" #to be replaced with GPIO output
nt = "tis not be the time" #used to see if working or not
tt = "tis be time" #used to see if working or not
#Next lines are redundant, commented out.
#now = datetime.datetime.now()
#hour = now.hour
def count():
now = datetime.datetime.now()
hour = now.hour #now.second
total = 1
while hour >= 8 and hour <= 16:
now = datetime.datetime.now()
hour = now.hour
# for i in range(1,100): -> why you need this?
total = total*2
print (tt)
print (n)
time.sleep(60)
print(f)
time.sleep(180)
now = datetime.datetime.now()
hour = now.hour #now.second
print (hour)
for i in range(1,100): #I don't know why you need a loop here
now = datetime.datetime.now()
hour = now.hour
print (nt)
print (hour)
time.sleep(10)
count()
Edited for correcting another hour = now.second inside the while loop
I don't know how are you planning on running the code, but the main problem I see is that you do not have any loop for your code to run infinitely and check the time condition.
Also it's not clear for me why you need this total variable that gets doubled.
Another thing is your for loops - the condition is not clear. Why do you want to run it in this specific range?
What I would do is I would create an infinite loop and inside it make some decisions based on a clear time conditions - the conditions that are specified by you.
So if I understood your case correctly I'd rather write something like this:
# between 9am to 5pm turn on the device for 60 seconds and off for 180 seconds repeatedly
from datetime import datetime
import time
def update_device_state(state):
# TODO: implement GPIO output code
pass
def run():
device_state = 'off'
new_state = device_state
on_timer = 0
off_timer = time.time() - 180 # initial value must be over 180 seconds to trigger device on a first run
while True:
hour = datetime.now().hour
if 5 <= hour <= 17:
if device_state == 'off' and time.time() - off_timer > 180:
on_timer = time.time()
new_state = 'on'
off_timer = 0
elif device_state == 'on' and time.time() - on_timer > 60:
off_timer = time.time()
new_state = 'off'
on_timer = 0
else:
if device_state = 'on'
new_state = 'off'
on_timer = 0
off_timer = time.time()
if device_state != new_state:
update_device_state(new_state)
device_state = new_state
time.sleep(1)
run()
But the code requires some testing as I just quickly drafted it and I just briefly red it.
I've been working on a personal assistant in python for a long time now and I've come across a problem that I can't solve.
I want to add a reminder.
I want to combine the alarm code and assistant code in two different loops.
When I set the alarm timer I want to do the other input tasks until the timer runs out.
How can I do that? Thanks.
I've tried this code, but it doesn't work because I only have one loop:
import datetime
import os
import time
import random
def assistant():
command = input('command: ')
if command == '1':
print('is it one')
elif command == '2':
print('is it two')
elif command == 'alarm':
import datetime
def check_alarm_input(alarm_time):
if len(alarm_time) == 1: # [Hour] Format
if alarm_time[0] < 24 and alarm_time[0] >= 0:
return True
if len(alarm_time) == 2: # [Hour:Minute] Format
if alarm_time[0] < 24 and alarm_time[0] >= 0 and \
alarm_time[1] < 60 and alarm_time[1] >= 0:
return True
elif len(alarm_time) == 3: # [Hour:Minute:Second] Format
if alarm_time[0] < 24 and alarm_time[0] >= 0 and \
alarm_time[1] < 60 and alarm_time[1] >= 0 and \
alarm_time[2] < 60 and alarm_time[2] >= 0:
return True
return False
# Get user input for the alarm time
print("Set a time for the alarm (Ex. 06:30 or 18:30:00)")
while True:
alarm_input = input(">> ")
try:
alarm_time = [int(n) for n in alarm_input.split(":")]
if check_alarm_input(alarm_time):
break
else:
raise ValueError
except ValueError:
print("ERROR: Enter time in HH:MM or HH:MM:SS format")
# Convert the alarm time from [H:M] or [H:M:S] to seconds
seconds_hms = [3600, 60, 1] # Number of seconds in an Hour, Minute, and Second
alarm_seconds = sum([a*b for a,b in zip(seconds_hms[:len(alarm_time)], alarm_time)])
# Get the current time of day in seconds
now = datetime.datetime.now()
current_time_seconds = sum([a*b for a,b in zip(seconds_hms, [now.hour, now.minute, now.second])])
# Calculate the number of seconds until alarm goes off
time_diff_seconds = alarm_seconds - current_time_seconds
# If time difference is negative, set alarm for next day
if time_diff_seconds < 0:
time_diff_seconds += 86400 # number of seconds in a day
# Display the amount of time until the alarm goes off
print("Alarm set to go off in %s" % datetime.timedelta(seconds=time_diff_seconds))
# Sleep until the alarm goes off
time.sleep(time_diff_seconds)
# Time for the alarm to go off
print("Wake Up!")
while True:
assistant()
1.Reminder code:
import datetime
import os
import time
import random
def check_alarm_input(alarm_time):
"""Checks to see if the user has entered in a valid alarm time"""
if len(alarm_time) == 1: # [Hour] Format
if alarm_time[0] < 24 and alarm_time[0] >= 0:
return True
if len(alarm_time) == 2: # [Hour:Minute] Format
if alarm_time[0] < 24 and alarm_time[0] >= 0 and \
alarm_time[1] < 60 and alarm_time[1] >= 0:
return True
elif len(alarm_time) == 3: # [Hour:Minute:Second] Format
if alarm_time[0] < 24 and alarm_time[0] >= 0 and \
alarm_time[1] < 60 and alarm_time[1] >= 0 and \
alarm_time[2] < 60 and alarm_time[2] >= 0:
return True
return False
# Get user input for the alarm time
print("Set a time for the alarm (Ex. 06:30 or 18:30:00)")
while True:
alarm_input = input(">> ")
try:
alarm_time = [int(n) for n in alarm_input.split(":")]
if check_alarm_input(alarm_time):
break
else:
raise ValueError
except ValueError:
print("ERROR: Enter time in HH:MM or HH:MM:SS format")
# Convert the alarm time from [H:M] or [H:M:S] to seconds
seconds_hms = [3600, 60, 1] # Number of seconds in an Hour, Minute, and Second
alarm_seconds = sum([a*b for a,b in zip(seconds_hms[:len(alarm_time)], alarm_time)])
# Get the current time of day in seconds
now = datetime.datetime.now()
current_time_seconds = sum([a*b for a,b in zip(seconds_hms, [now.hour, now.minute, now.second])])
# Calculate the number of seconds until alarm goes off
time_diff_seconds = alarm_seconds - current_time_seconds
# If time difference is negative, set alarm for next day
if time_diff_seconds < 0:
time_diff_seconds += 86400 # number of seconds in a day
# Display the amount of time until the alarm goes off
print("Alarm set to go off in %s" % datetime.timedelta(seconds=time_diff_seconds))
# Sleep until the alarm goes off
time.sleep(time_diff_seconds)
# Time for the alarm to go off
print("Wake Up!")
2.Representative assistant code:
def assistant():
command = input('command: ')
if command == '1':
print('is it one')
elif command == '2':
print('is it two')
while True:
assistant()
I am planning such an output
command: 1
is it one
command: 2
is it two
command: alarm
Set a time for the alarm (Ex. 06:30 or 18:30:00)
>> 13:00
Alarm set to go off in 1:30:00
command: 1
is it one
command: 2
is it two
Wake Up!
command: 1
is it one
command: 2
is it two
I'm completely new to Python and I'm trying to set a timer in this game I have... Everything else has been fine but this timer is a headache.
I'll only post the parts associated with the timer to make it easier.
frame_count = 0
second = 0
minute = 5
hour = 1
time = "1 5. 0"
And then in my main loop I have.
font = pygame.font.SysFont('DS-Digital', 50, False, False)
text = font.render(time,True,red)
display.blit(text, [302, 50])
frame_count += 1
if frame_count == 60:
frame_count = 0
second -= 1
elif second == 0:
second = 9
minute -= 1
elif minute == 0:
minute = 9
hour -= 1
elif second == 0 and minute == 0 and hour == 0:
second = 0
minute = 0
hour = 0
hour = time[0]
minute = time[2]
second = time[5]
clock.tick(60)
This gives me back an error for being wrong type but I've tried converting to int and vice versa... So frustrating...
I've looked at so many examples but most examples are actual minutes and seconds.
I need my right number to just countdown from 9 to 0 then minus off middle number and so forth.
If this your whole code then you didn't imported pygame. (import pygame) at the begining and you should loop it all so for example:
import pygame
while True:
...
Your code
...
Specify more your question please, I see that you should use if insted of elif because once it got to 1 1 0 it will turn to 1 0 9 and then into 0 9 9 in two frames.
elif second == 0 and minute == 0 and hour == 0:
second = 0
minute = 0
hour = 0
This doesn't make sence really it's like if you calculate
if I have a = 0 then do a = 0 if you know what I mean (it does nothing).
Edit:
There is working code, you can edit it and replace your old code with it.
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
red = (255, 0, 0)
bg_color = (0, 0, 0)
frame_count = 0
time = "1 5. 0"
while True:
pygame.time.Clock().tick(60)
frame_count += 1
hour = int(time[0])
minute = int(time[2])
second = int(time[5])
if second > 0 and frame_count == 20:
frame_count = 0
second -= 1
if second == 0 and minute > 0 and frame_count == 20:
frame_count = 0
second = 9
minute -= 1
if minute == 0 and hour > 0 and frame_count == 20:
frame_count = 0
minute = 9
second = 9
hour -= 1
time = str(hour) + " " + str(minute) + ". " + str(second)
font = pygame.font.SysFont('DS-Digital', 50, False, False)
text = font.render(time, True, red)
screen.fill(bg_color)
screen.blit(text, (302, 50))
pygame.display.update()
I'm quite sure that there is easier solution or more pythonic one, but it works and that is most important.
Remove these lines:
hour = time[0]
minute = time[2]
second = time[5]
it should work without them. Then ask what you are attempting to do with them
When you assign elements from time to you hour, minute, second variables convert them to an int like this:
hour = int(time[0])
minute = int(time[2]
second = int(time[5])
Here is my solution for simple way to sleep at the end of each iteration for the leftover time for a desired update rate
from timeit import default_timer as timer
from time import sleep as sleep
class loop_timer():
""" simple game loop timer that sleeps for leftover time (if any) at end of each iteration"""
LOG_INTERVAL_SEC=10
def __init__(self, rate_hz:float):
''' :param rate_hz: the target loop rate'''
self.rate_hz=rate_hz
self.start_loop()
self.loop_counter=0
self.last_log_time=0
def start_loop(self):
""" can be called to initialize the timer"""
self.last_iteration_start_time=timer()
def sleep_leftover_time(self):
""" call at start or end of each iteration """
now=timer()
max_sleep=1./self.rate_hz
leftover_time=max_sleep-(now-self.last_iteration_start_time)
if leftover_time>0:
sleep(leftover_time)
self.start_loop()
self.loop_counter+=1
if now-self.last_log_time>self.LOG_INTERVAL_SEC:
self.last_log_time=now
if leftover_time>0:
print('loop_timer slept for {:.1f}ms leftover time for desired loop interval {:.1f}ms'.format(leftover_time*1000,max_sleep*1000))
else:
print('loop_timer cannot achieve desired rate {}Hz, time ran over by {}ms compared with allowed time {}ms'.format(self.rate_hz, -leftover_time*1000, max_sleep*1000))
Use it like this
looper=loop_timer(MODEL_UPDATE_RATE_HZ)
while not self.exit:
# do your stuff here
try:
looper.sleep_leftover_time()
except KeyboardInterrupt:
logger.info('KeyboardInterrupt, stopping')
self.exit=True
continue