1

I run a Python script on my RPi that manages all the sensors on the board and communicates with another machine using TCP sockets. The project gained in complexity and my script now has 5 threads running at all times (one for networking, one for processing camera images, etc.).

I noticed that while my distance sensor (HC-SR04) is working well with a minimal test script (C.F. below), it starts giving wrong values (values lower than expected) when I run the same code in my real program and when all threads are working.

Distance sensor snippet:

import time
from gpiozero import DistanceSensor

ECHO = 19
TRIG = 26

sensor = DistanceSensor(ECHO, TRIG, max_distance=4.5)

while True:
    print("Distance to nearest object is", sensor.distance, "m")
    time.sleep(1)

If I run only 4 threads or if I put a time.sleep() in my infinite loops (each thread runs an infinite loop), the sensor gives the right values again.

How can this be explained? My hypotheses:

  • The CPU "eats up" all the current when the infinite loops are running and the RPi cannot feed enough current to the sensor?
  • The gpiozero library runs some code in another thread behind the scene that needs to run pretty fast, and since there are a lot of work already going on it can't run as fast as needed?

What do you think? What should I do?

  • 1
    I wrote an answer, but I don't think there is enough information to give more than a simple answer because you haven't given us enough information. At the least, we need the actual code that gives the incorrect results. It might also help you to have used the "python" tag for your question. – NomadMaker Sep 22 '18 at 17:16
  • Python does not have proper threads - these all run under the one interpreter. While I am not an expert in this area, my experience is that there is little gain from multi-threading. You would be better to run a number of independent processes. NOTE posting "snippets" does not really give any idea what you are doing. This is NOT a Pi specific problem. – Milliways Sep 22 '18 at 23:09
2

If you are using a properly-sized power supply, then I believe this to be a timing issue. Since the distance sensors work when you're only using four threads, then I suspect that it's not a power problem.

The SR04 requires precise timing to calculate distance. If one of the other threads is taking too much of the CPU time, then perhaps the thread that reads the SRO4's doesn't get enough time to read the sensors properly.

The Raspberry Pi is more of an SBC (single-board computer) that typically runs Linux. This means that many other processes are running at the same time as your python program, and they may also work to prevent your program from having enough time to calculate the distance.

For that reason, it's usually better to put sensors which need precise timing onto a microcontroller such as an Arduino. You could communicate between the Raspberry Pi and the Arduino with I2C.

Another way to do this is to use sensors that communicate with I2C or SPI. These sensors don't require the precise timing calculations that the SR04's do.

One possible thing for you to look into is Python's GIL (Global Interpreter Lock) which causes only one thread to run at a time. This might cause a difference between how you think your code is running and how it actually runs.

0

The thread which measures the echo time needs to access the CPU more often to make precise measurements. This is normally solved by giving that thread higher priority, but Python doesn't support that.

One possible option would be to run the distance sensor code in a separate process, which could be given arbitrary priority using nice:

nice -n -10 python script.py

Note that negative priorities (higher than default) only work for root. A possible way to avoid running as root is to set lower (positive) priority to the rest of your code, and run the distance sensor code with default priority.

But if simply putting some time.sleep() in your existing code helps, go for it. This call basically self-interrupts a thread, giving other threads a chance to run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.