0
deeagle

OPI zero gpio libs miss edges

Recommended Posts

Hello fellas,

 

I would like to borrow your experience to compete with my task which counts (and measures) pulses on GPIO with Orange Pi zero.

 

 

Currently, my simple solution is to register a callback to a specific edge and increment a global variable.

I would like to catch a few hundreds of pulses in one burst which have in a 5-100 us length.

However, even the number of counted pulses is not okay. Some of them are missed sometimes, which leads to an unreliable solution.

 

I used different libs and all of them fall into the same issue.

 

I tried the following libs:
* ArmbianIO (C)

* ArmbianIO (Python: original API)

* ArmbianIO (Python: RPi compatibility API)

* OPi

 

I have missed the pyH3 forks intentionally as they do not offer callback functionality.

 

I see on an oscilloscope that all the pulses arrive in the GPIO pin.

The signal has a nice square shape and has the good level.

 

I tried the ArmbianIO RPi compatibility API version to run on real Raspberry, and it is reliable works there.

 

I noticed, that when it misses some pulses, the htop shows CPU usage peek. What was visible is the network manager, so I blacklisted Wifi modul and killed the wpa agent. I only use cable.

The problem still appears.

 

I also tried to raise the nice level, but it did not help, so I am out of ideas.

 

Could it really be CPU load problem?

Or does anybody has any idea what can go wrong and how it can be fixed?

 

Thank you in advance!

 

My actual implementation is here:

from __future__ import print_function
import time

from armbianio.armbianio import *

import atexit

DETECT_GPIO_CH = 3

active = True
started = False

tick_count = 0


def catch_code():
    print("Waiting for code...")
    global started
    global active
    while not started:
        time.sleep(10.0e-3)
    time.sleep(550.0e-3)
    started = False
    active = False
    print("Code: {}".format(tick_count))


def edge_detected(channel):
    if active:
        global started
        global tick_count
        if not started:
            tick_count = 0
            started = True
        else:
            tick_count += 1


def cleanup():
    AIORemoveGPIOCallback(DETECT_GPIO_CH)
    AIOWriteGPIOEdge(DETECT_GPIO_CH, EDGE_NONE)
    AIOShutdown()


def main():
    AIOInit()
    AIOAddGPIO(DETECT_GPIO_CH, GPIO_IN)
    AIOWriteGPIOEdge(DETECT_GPIO_CH, EDGE_FALLING)

    time.sleep(1)
    AIOAddGPIOCallback(DETECT_GPIO_CH, AIOCALLBACK(edge_detected))

    atexit.register(cleanup)
    catch_code()


if __name__ == "__main__":
    main()

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
0