uneasy
Posts: 6
Joined: Sun Feb 11, 2018 11:01 pm

Threading - Thread not consistent

Sun Feb 11, 2018 11:08 pm

Hi everyone.
I have probably really simple problem, but I am trying to build something that has to be really reliable.
I already made it using Pi and Arduino through USB Serial to communicate with each other, however that was not reliable.
So I decided to go fully Pi and use GPIOs instead of Arduino.

I realised how easy is to use threads so I was thinking it will be good idea to run my program with threads.

However, pretty simple thing such as beeping buzzer in while loop, in thread is already not working as I wanted to.

So in while loop I have sleep and GPIO LOW and HIGH - simple
But thread is not running smoothly, sometimes buzzer stays on for longer than sleep, etc.

Why is that happening? Is there any other solution? Or best is just don't use threads ?

I looked in to multiproccessing but I don't think it's something I should use for my simple program.

Any suggestions will be much appreciated.

ghans
Posts: 7878
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: Threading - Thread not consistent

Mon Feb 12, 2018 9:16 am

You really need to look into GPIO libraries and their advanced features. I suggest pigpio because it has further features which may also be useful in you scenario.

pigpio can cleverly use specialised hardware contained inside the Pi (PWM / DMA engines) to guarantee precise timing with low CPU load, something Linux and/or Python threading can not to do quite as easily if at all.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

uneasy
Posts: 6
Joined: Sun Feb 11, 2018 11:01 pm

Re: Threading - Thread not consistent

Mon Feb 12, 2018 9:26 am

I did have a look in that library. And I know I will be using PWM for that "impulses". However I am still trying to understand that threading issue, as I have other thread with constant checking GPIO states and if that is so inconsistent too, its not really good.

I could stop using threads, but I just want to understand the problem here.

ghans
Posts: 7878
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: Threading - Thread not consistent

Mon Feb 12, 2018 9:39 am

sleep() in Linux and Python always puts a minimum bound on how long your program sleeps. This is because Linux is a interactive pre-emptive multitasking system and NOT a realtime system as used in aviation or automobile. If "deadlines" are not met on such systems people are gonna die and those specialised operating systems are designed with that in mind, Linux (and Windows) don't care as much. Python itself probably exacerbates this thanks to language features like garbage collection and the Global Interpreter Lock.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

User avatar
bertlea
Posts: 301
Joined: Wed Dec 07, 2016 6:33 am
Location: Hong Kong

Re: Threading - Thread not consistent

Mon Feb 12, 2018 9:45 am

How accurate your system need for the timing (time-resolution) in Thread for sleep and GPIO High/Low calls? Say, the sleep need to be 500ms with tolerance only +/- 2ms?
Generally, the sleep/loop timing in Threads is not guaranteed and it depends on CPU loading at the time and the OS’s task scheduling and priority. It may help if you set the priority of your process to higher priority, but it is a relative, not absolute. If you really need high time-resolution and very reliable process schedule, I doubt Linux on Pi is suitable, maybe you need some real-time OS / system for that.

ghans
Posts: 7878
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany

Re: Threading - Thread not consistent

Mon Feb 12, 2018 9:52 am

Dropping Linux for real-time OS is not a decision to be taken lightly, especially because pigpio exists and works with Linux already.

I suggest that the OP reads up on "GPIO callbacks" and perhaps on the Linux poll() functionality.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org

uneasy
Posts: 6
Joined: Sun Feb 11, 2018 11:01 pm

Re: Threading - Thread not consistent

Mon Feb 12, 2018 9:56 am

Thank you, I am reading about callbacks now. I will also check poll()

Idahowalker
Posts: 445
Joined: Wed Jan 03, 2018 5:43 pm

Re: Threading - Thread not consistent

Tue Feb 13, 2018 12:05 am

uneasy wrote:
Mon Feb 12, 2018 9:26 am
as I have other thread with constant checking GPIO states
Interrupts?

Code: Select all

def fDoTheThing():

    try:
        fSetup()

        # event to read serial port
        GPIO.add_event_detect(iPinIn2, GPIO.RISING, callback=fCallBack)
        #event to clear latch
        GPIO.add_event_detect(iPinIn3, GPIO.RISING, callback=fCallBack, bouncetime = 20)
        GPIO.output(iPinOut3, GPIO.HIGH)
        #wait for stop signal
        GPIO.wait_for_edge(iPinIn1, GPIO.FALLING)
        
    finally:
        GPIO.cleanup() #clean up on kbd exit
        serialPort.close()
    return;

    
Call back:

Code: Select all


def fCallBack(iChannel):

    sReceive = b""

    global iPinIn2
    global iPinIn3

   if iChannel == iPinIn2:      
     fProcessTHData(sReceive.decode('utf-8'))
                
            except:
                pass
            finally:
                #RASPBERRY PI READY
                GPIO.output(iPinOut3, GPIO.HIGH)
        else:
            print("Port", sPortToUse, " !open")
    if serialPort.open:
        try:
            serialPort.flushInput()
        except serial.serialutil.SerialException:
            pass
            
    #Reset latch
    if iChannel == iPinIn3:
       GPIO.output(iPinOut1, GPIO.LOW)

    return;
    

This code is hooked to a button on a pin:
#wait for stop signal
GPIO.wait_for_edge(iPinIn1, GPIO.FALLING)

If I press the button the code stops running. Otherwise the code waits for the GPIO pins to tell this code that they have data to process. Instead of wasting clock cycles polling the GPIO pins. I let the GPIO pins tell the code there is something to do.

This is the call back function that runs when a GPIO pin interrupts:
def fCallBack(iChannel):

The "iChannel" is the GPIO pin producing the interrupt.

In this code the Pi sends a signal out to an Arduino to tell the Arduino to stop processing and stop sending the Pi data: fProcessTHData(sReceive.decode('utf-8'))

In this code the Pi tells the Arduino to proceed with processing and sending data, as the pi is ready for new input: GPIO.output(iPinOut3, GPIO.HIGH)

These two lines of code are the setup for which GPIO pins produce interrupt and what to do when an interrupt is received:

# event to read serial port
GPIO.add_event_detect(iPinIn2, GPIO.RISING, callback=fCallBack)
#event to clear latch
GPIO.add_event_detect(iPinIn3, GPIO.RISING, callback=fCallBack, bouncetime = 20)

There is quite a bi of info on the web and on this site about using interrupts. Also, in the functions that are called from the call back there are two threads in operation. I do not use sleeps or loops.
Without knowing why you are deleting my postings, I will not know how...

uneasy
Posts: 6
Joined: Sun Feb 11, 2018 11:01 pm

Re: Threading - Thread not consistent

Tue Feb 13, 2018 3:45 pm

Thank you for that.

After earlier suggestion of callbacks, I started to put my project together and eventually I tested callbacks, which works like it should.

However I have a problem more hardware than software.
In my system I have 3v3,5V amd 12V all on common ground, as that is how it's supplied from PSU.

Everything is driven by ground on my PI. and I have only 3 inputs that I am monitoring.
I set internal pull down resistor.

As for the tests there is nothing going to those inputs, but when I trigger 12V to be used (there no 12V going to the pi at any point).
That triggers my callbacks functions. I notices it's just a spike and I could fixe it in software just by placing time.sleep(0.25).

But my concern is, what is value of that spike and where is it coming from - I don't want anything more than 3v3 on GPIO of course. There is nothing physically plugged to inputs yet. only wires with dead end.

I guess that is hardware issue so probably not a place here for that. I found topic about false edge detection and someone suggested to place 0.1 uF capacitor on inputs to filter any spikes. I think I will try that.

Callbacks it's exactly what I needed anyway and many many thanks for that.

Idahowalker
Posts: 445
Joined: Wed Jan 03, 2018 5:43 pm

Re: Threading - Thread not consistent

Wed Feb 14, 2018 1:59 am

The 12V and RPi are connected through their common (gnd)? How so? A wire?

Does the 12V have motors, relays?
Without knowing why you are deleting my postings, I will not know how...

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Threading - Thread not consistent

Wed Feb 14, 2018 10:55 am

First of all, how good are your grounds? You need a star earth to one point, but I doubt I need to tell you that.
The RFI must be coming through wiring and there's a limited amount of that. It wouldn't be a bad idea to put some RF chokes on the Pi power lead.
Since you say you had problems with USB communication, I start to suspect that you've got earth loops. Everything must only be earthed once. If that's impossible, such as with the Pi and Arduino being connected by the USB cable screen, put a huge RF choke on the cable. It won't affect the signals because they are balanced and so their magnetic fields cancel out.

http://rsgb.org/main/technical/emc/usin ... -ferrites/

uneasy
Posts: 6
Joined: Sun Feb 11, 2018 11:01 pm

Re: Threading - Thread not consistent

Wed Feb 14, 2018 4:32 pm

I don't think there is a Ground issues. There is not much grounding anyway and everything has common point as well.

I think detecting GPIO events is just working as it should. I have read multiple topics and there is a lot of people having false edge detects.
But also, it only triggers when I turn 12V thorugh the relay. if there is nothing on 12V end there is no trigger.
All the wires are really close to each other, but is that enough ?

Solution is either filters and software or Schmitt trigger, as for now I will use software 25ms sleep plus recheck gpio states.

My Serial problems were different kind and I think it was my fault, handling serial communication in the software.
But because I am making something that has to be super reliable in terms of always operating, I decided to keep it as simple as possible.

Return to “Python”