Search code examples
pythonwaitsleep

Appropriate strategy to avoid busy or inefficient waiting when displaying static content on e-paper screen?


My application updates an e-paper screen with various "plugin" objects. Each object represents one module with its own worker that creates the image. The image is displayed for a time, then switched to the next in the queue. Each object has its own timer that depends on data that its associated worker produces. This timer can change in response to various external inputs (e.g. user starts music playing, weather alert occurs).

The workers are queued and updated in one go, then the updates are made to the screen when needed.

I currently use sleep(1) at the end of the update/display loop to avoid busy waiting while nothing is happening. Is there a better strategy to improve the resources consumed by this? Experimentally, I've discovered that by increasing the sleep() value the CPU load of this process drops down a bit (as monitored with top).

Question: Is there a more resource efficient way to set up the display loop (see below)?

I've read up on threading and using join, but those don't seem appropriate here because the wait period is known and the code isn't waiting for some external resource to become available. It's simply waiting for a timer to expire.

Here's a sample of the display loop:

# list objects 
plugins = [updater_obj1, updater_obj2, updater_obj3]


plugin_cycle = itertools.cycle(plugins)
this_plugin = next(plugin_cycle)

while True:
   
   # update each object to ensure there is fresh data to display on demand
   for i in plugins:
      i.update()

   # only update the display when the object's timer has run down
   if this_plugin.timer_expired():
      this_plugin = next(plugin_cycle) # move to the next item in the list
      this_plugin.set_timer() # reset the timer
      epd.write(plugin.image) # update the E-paper display with a new image
   
   sleep(1)

Solution

  • add a method like timer_expires() that returns the timestamp for when the timer expires to each of the plugins, then it could sleep until it expires so that it dosn't have to keep checking

    while True:
       
       # update each object to ensure there is fresh data to display on demand
       for i in plugins:
          i.update()
       
       # sleep for the right amount of time
       sleep(this_plugin.timer_expires() - time())
       
       # update the display
       this_plugin = next(plugin_cycle) # move to the next item in the list
       this_plugin.set_timer() # reset the timer
       epd.write(plugin.image) # update the E-paper display with a new image