2

Hello stackoverflow community!

I am writing a python script to repeatedly retrieve a value from a PiHat sensor. I found this answer on stack overflow Run a python function every second but I run into the following error after it completes one loop: ValueError: sleep length must be non-negative

Here is the code

from sense_hat import SenseHat
import time

start_time = time.time()
interval = 1
sense = SenseHat()
# humidity = sense.get_humidity() *move this to loop

for i in range(20):
  humidity = sense.get_humidity()
  sense.clear()
  print(humidity)
  time.sleep(start_time + i*interval - time.time())
  # f()

*edited the above code to fetch sensor values in the loop in case anyone wants to run similar code. Otherwise, it will just display the same value repeatedly I have kept everything else the same for reference and so you can see where I went wrong. Also commented out f().

No one seemed to have mentioned the issue on the thread I found it on. I have run data science projects with python but not many traditional programs so I apologize if the formatting is off.

Basically, could you explain why it does this and maybe some possible solutions to make it work. If you can explain why, it would really help my understanding of python. The sample code I found this on is very old and possibly an outdated method? I am running this on a raspberry Pi 4 b so it is possibly not executing fast enough?

I appreciate the help

PiGarret
  • 23
  • 4
  • 1
    In the first iteration of the for-loop, "i" is 0. Generally you should take into account that the calculated value may become negative. You can use something like `max(0, ...)` to prevent this from happening. – Michael Butscher Mar 04 '22 at 06:30
  • Hi Michael, thanks for the help! Perhaps it is executing too quickly therefor creating a negative integer. However, when I strip all the sensor code out and just run a loop with a simple print value, I realized it properly executes 20 times on windows with Pycharm. However, it doesn't execute without an error on the Pi. Any ideas why? – PiGarret Mar 04 '22 at 06:42
  • 1
    For "i == 0" the sleep expression reduces to "start_time - time.time()" and usually the current time is greater than the start time (on a fast PC they may be equal). First iteration must start with 1 for "i". – Michael Butscher Mar 04 '22 at 06:50
  • I see now. I guess I wasn't looking at the formula close enough. It makes total sense that it would end up negative. That explains why my faster windows PC doesn't turn negative. Perhaps if I overclock the Pi..... lol just kidding I will write proper code. Thanks for all the help! – PiGarret Mar 04 '22 at 06:58

2 Answers2

1

As mentioned in the comments, in the first iteration of the for-loop, "i" is 0. You should take into account that the calculated value may become negative (hence the ValueError: sleep length must be non-negative).

You can use max(0, start_time + i*interval - time.time()) or change the range to range(1,21) to prevent this from happening.

As far as the differences between Pycharm and on the Raspberry, it might have to do with the clock precision of the two machines (different time yield by time.time())

rikyeah
  • 1,896
  • 4
  • 11
  • 21
  • Thanks rikyeah! It definitely makes sense that the value could turn negative. I really didn't expect to run into any major differences between a Pi and a pc with such a simple script but it definitely highlights the importance of writing proper code! – PiGarret Mar 04 '22 at 07:03
1

This seems to be due to the fact that the range starts at 0, and with any number of time (0.1s-0.2)<0 it's going to be negative. So change the range, a fix could look like this

from sense_hat import SenseHat
import time

start_time = time.time()
interval = 1
sense = SenseHat()
humidity = sense.get_humidity()

for i in range(1,21):
  sense.clear()
  print(humidity)
  time.sleep(start_time + i*interval - time.time())
  f()
35308
  • 575
  • 5
  • 17