Quantcast
Viewing all articles
Browse latest Browse all 14069

Running final function after stopping a loop seems to have a time difference in Python

I am writing a Python script that will show me running data when running on my treadmill because the display panel is broken. It's going to use GPIO pins on a Raspberry Pi, so whenever the belt on the treadmill goes around, it can have a metal piece that shorts pins (they act as a button). It calculates speed depending on how fast the belt went around.

This means time is very important here. I've set up a loop in rev_counter() that gets the time and then when the "button" is pressed, it records the time again. Just to test it while I'm writing this program, I've simulated a button press with sleep(). I set it to 1.27841272276 seconds because this would be the time the belt would go around for a 7:30-minute mile pace. I've been trying to get it as close to that pace as possible.

I have gotten it to work pretty well. It is right on or maybe one second off while showing the info in the middle of the workout. The problem is, when I end the workout with CTRL+C so it goes to the results, the average mile pace ends up being off. It should be 7:30-7:31, but it ends up being 7:34-7:36. I'm pretty sure the time gets offset between when I stop the rev_counter() loop and when it calculates the results in results(). For some reason, when I ran the update_display() function in rev_counter() with Thread, it seemed to help. Could stopping in the middle of this loop be causing a problem? Why does only results() and not both rev_counter() and results() not get the time issue?

Here is my Python script:

import mathimport osimport time# from gpiozero import Buttonfrom threading import Threadfrom time import sleep# belt_button = Button(2)def display(original_time=None, total_distance=None, current_speed=None, prev_rev_time=None):    os.system('clear')    print('Current Workout Information')    print('')    if original_time is None:        print(f'Time elapsed: --:--:--')        print('')        print('Distance')        print(f'Miles: --')        print(f'Kilometers: --')        print('')        print('Current Speed')        print(f'M/H: --')        print(f'KM/H: --')        print('')        print('Pace')        print(f'Mile: --')        print(f'Kilometer: --')    else:        seconds_elapsed = prev_rev_time - original_time        time_elapsed = increment(seconds_elapsed)        mi = total_distance / 5280        km = total_distance / 3280.84        mph = current_speed / 1.46667        kmph = current_speed * 1.09728        min_mi = 60 / mph        min_km = 60 / kmph        mi_pace_min = math.floor(min_mi)        mi_pace_sec = round((min_mi * 60) % 60)        if mi_pace_sec < 10:            mi_pace_sec = f'0{mi_pace_sec}'        km_pace_min = math.floor(min_km)        km_pace_sec = round((min_km * 60) % 60)        if km_pace_sec < 10:            km_pace_sec = f'0{km_pace_sec}'        print(f'Time elapsed: {time_elapsed}')        print('')        print('Distance')        print(f'Miles: {round(mi, 2)}')        print(f'Kilometers: {round(km, 2)}')        print('')        print('Current Speed')        print(f'M/H: {round(mph, 2)}')        print(f'KM/H: {round(kmph, 2)}')        print('')        print('Pace')        if current_speed == 0:            print(f'Mile: 0')            print(f'Kilometer: 0')        else:            print(f'Mile: {mi_pace_min}:{mi_pace_sec}')            print(f'Kilometer: {km_pace_min}:{km_pace_sec}')def increment(seconds_elapsed):    seconds_elapsed = math.floor(seconds_elapsed)    h = seconds_elapsed // 3600    m = (seconds_elapsed // 60) % 60    s = seconds_elapsed % 60    if h < 10:        h = f'0{h}'    if m < 10:        m = f'0{m}'    if s < 10:        s = f'0{s}'    return f'{h}:{m}:{s}'def rev_counter():    revolutions = 0    prev_rev_time = 0    original_time = time.time()    try:        while True:            prev_rev_time = time.time()            # GPIO stuff            # sleep(0.25)            # belt_button.wait_for_press()            sleep(1.27841272276)            rev_time = time.time()            revolutions += 1            update_display(original_time, prev_rev_time, rev_time, revolutions)            # Alternate code            # thread = Thread(target=update_display, args=(original_time, prev_rev_time, rev_time, revolutions))            # thread.start()    except KeyboardInterrupt:        os.system('clear')        total_distance = 15 * revolutions        results(original_time, prev_rev_time, total_distance)def update_display(original_time, prev_rev_time, rev_time, revolutions):    # feet * rev count    # 15 = Length of my treadmill in feet    total_distance = 15 * revolutions    # feet / second    rev_seconds = rev_time - prev_rev_time    current_speed = 15 / rev_seconds    display(original_time, total_distance, current_speed, prev_rev_time)def results(original_time, prev_rev_time, total_distance):    try:        os.system('clear')        seconds_elapsed = prev_rev_time - original_time        time_elapsed = increment(seconds_elapsed)        print('Workout Results')        print('')        if total_distance == 0:            print(f'Total time: {time_elapsed}')            print('')            print('Distance')            print(f'Miles: 0')            print(f'Kilometers: 0')            print('')            print('Average Speed')            print(f'M/H: 0')            print(f'KM/H: 0')            print('')            print('Average Pace')            print(f'Mile: 00:00')            print(f'Kilometer: 00:00')        else:            average_speed = total_distance / seconds_elapsed            mi = total_distance / 5280            km = total_distance / 3280.84            mph = average_speed / 1.46667            kmph = average_speed * 1.09728            min_mi = 60 / mph            min_km = 60 / kmph            mi_pace_min = math.floor(min_mi)            mi_pace_sec = round((min_mi * 60) % 60)            if mi_pace_sec < 10:                mi_pace_sec = f'0{mi_pace_sec}'            km_pace_min = math.floor(min_km)            km_pace_sec = round((min_km * 60) % 60)            if km_pace_sec < 10:                km_pace_sec = f'0{km_pace_sec}'            print(f'Total time: {time_elapsed}')            print('')            print('Distance')            print(f'Miles: {round(mi, 2)}')            print(f'Kilometers: {round(km, 2)}')            print('')            print('Average Speed')            print(f'M/H: {round(mph, 2)}')            print(f'KM/H: {round(kmph, 2)}')            print('')            print('Average Pace')            print(f'Mile: {mi_pace_min}:{mi_pace_sec}')            print(f'Kilometer: {km_pace_min}:{km_pace_sec}')        print('')        input('Exit ')        os.system('clear')    except KeyboardInterrupt:        os.system('clear')def main():    os.system('clear')    while True:        try:            print('AC Treadmill Workout Program')            print('')            input('Start Workout ')            display()            rev_counter()        except KeyboardInterrupt:            print('\n')            print('Quitting... ')            breakif __name__ == '__main__':    main()

To run this program without any issues, run it in a Unix environment or Windows if you change all the os.system('clear') lines to os.system('cls'). Also make sure to run it in the terminal because my IDE (PyCharm) doesn't allow it to clear even when I set the TERM environment variable.


Viewing all articles
Browse latest Browse all 14069

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>