![]() |
Running loop at specific frequency - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Running loop at specific frequency (/thread-33372.html) |
Running loop at specific frequency - mdsousa - Apr-19-2021 Hi I am trying to get my while loop to run at a specific frequency (30Hz) and am having trouble getting it to work. I'm going with 30Hz x 60 seconds should give me a max run of 1800 loops. I am also checking start/end times and taking differences to determine a pause time. Typical output from my script (I'd like to figure out if this can get close to the 1800 mark): This is my test code:#!/usr/bin/env python import time import pause frequency = 30 # Hz period = (1.0/frequency)*1000 timeToRun = 1 # how many minutes to run t_end = time.time() + 60 * timeToRun # run for timeToRun minutes notPaused = 0 numRuns = 0 elapsedDiffList = [] startTime = time.time() while time.time() <= t_end: timeNowMilli = time.time_ns()/1000000 # time from nanoseconds to milliseconds timeEndMilli = time.time_ns()/1000000 pause.milliseconds(1) elapsedDiff = timeEndMilli - timeNowMilli if elapsedDiff < period: # done before our schedule -- pause awhile timeToPause = period-elapsedDiff pause.milliseconds(timeToPause) else: # took longer than scheduled -- send next message right away without pause elapsedDiffList.append(elapsedDiff) # incase I get an extra long loop notPaused += 1 numRuns += 1 endTime = time.time() time_delta = (endTime-startTime) print() print("Number of loops: " + str(numRuns)) print("Not paused: ", str(notPaused)) print('Time delta is : ' + str(time_delta)) print(*elapsedDiffList, sep=", ")It doesn't feel like I'm getting a 30Hz loop out of this. Any idea what I'm missing? Thanks... RE: Running loop at specific frequency - jefsummers - Apr-19-2021 Alternative - the idea here is to burn cpu cycles until you reach the time to leave the gate. Will work as long as you don't have "not paused" cycles. import time start = time.perf_counter() end_time = start + 60 count = 0 for division in range(1800): while time.perf_counter() < start + division/30: pass count = count + 1 elapsed = time.perf_counter() - start print(f'Count {count} Elapsed {elapsed}')
RE: Running loop at specific frequency - mdsousa - Apr-20-2021 Thanks jefsummers I'm giving this a try. I don't quite understand what it's doing in the line: while time.perf_counter() < start + division/30:I'm going to have think about it and see how it gives accurate time pauses. Thanks... RE: Running loop at specific frequency - jefsummers - Apr-21-2021 time.perf_counter() is the current time in seconds, with the decimal part out to the accuracy of the system start is the time everything started division is which "tick" you are on - 60 seconds times 30 ticks per second = 1800 ticks So, division/30 is the amount to add to start to get the time at which the "gate opens" BTW - can eliminate the end_time line - that was in there when I was going a different path. |