Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PulseIn - wrong pulse lengths during long time run #9936

Open
gkecskes78 opened this issue Jan 4, 2025 · 2 comments
Open

PulseIn - wrong pulse lengths during long time run #9936

gkecskes78 opened this issue Jan 4, 2025 · 2 comments

Comments

@gkecskes78
Copy link

CircuitPython version

Adafruit CircuitPython 9.2.1 on 2024-11-20; PCA10059 nRF52840 Dongle with nRF52840

Code/REPL

#####	Dongle 1 code - 'controller'	#####
import board,pulseio,time,array,gc
pIn=pulseio.PulseIn(board.P0_17,maxlen=100)
pOut=pulseio.PulseOut(board.P0_15,frequency=60000,duty_cycle=65535)
import adafruit_logging as logging
logger=logging.getLogger('test')
logger.setLevel(logging.INFO)
fails=total=0
expSum=11666
def Read():
    x=[]
    while len(pIn)==0:
        pass
    t1=time.monotonic_ns()
    while True:
        t2=time.monotonic_ns()
        if t2-t1>20000000:
            break
    for i in range(len(pIn)):
        x.append(pIn[i])
    pIn.clear()
    return x

i=1
min=1e9
max=0
while i<=2e6:
    fail=False
    pOut.send(array.array('H',[417,833,417,833,417]))       #   sending 'QUERY' command
    x=Read()
    pIn.pause()
    sum=0
    for s in x:
        sum+=s
    if sum>max:
        max=sum
    if sum<min:
        min=sum
    if sum<expSum*0.95 or sum>expSum*1.05:
        fail=True
        total+=1
    if i%100000==0:
        logger.info(str(i)+" - OK")
    if i==1 or fail:
        logger.info(str(i)+"  Corrupt: "+str(fail)+"  Count:"+str(len(x))+"  "+str(x)+"  Sum: "+str(sum)+"  Min: "+str(min)+"  Max: "+str(max)+"  Total fails: "+str(total)+"  Mem: "+str(gc.mem_free()))
    i+=1
    pIn.resume()








#####	Dongle 2 code - 'DALI driver'	#####
import board,pulseio,time,pwmio,array
pulses=array.array('H',[417,833,417,833,417,833,417,833,417,833,417,833,417,833,417,833,1666])
pIn=pulseio.PulseIn(board.P0_17,maxlen=100)
pOut=pulseio.PulseOut(board.P0_15,frequency=60000,duty_cycle=65535)

def Read():
    x=[]
    while len(pIn)==0:
        pass
    t1=time.monotonic_ns()
    while True:
        t2=time.monotonic_ns()
        if t2-t1>20000000:
            break
    for i in range(len(pIn)):
        x.append(pIn[i])
    pIn.clear()
    return x

while True:
    x=Read()
    pIn.pause()
    if len(x)>=5:
        pOut.send(pulses)
    pIn.resume()

Behavior

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.

Press any key to enter the REPL. Use CTRL-D to reload.
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
main.py output:
41.205: INFO - 1 Corrupt: False Count:17 [421, 840, 421, 840, 421, 840, 421, 840, 421, 840, 421, 840, 421, 840, 421, 840, 1670] Sum: 11758 Min: 11758 Max: 11758 Total fails: 0 Mem: 126752
4375.998: INFO - 100000 - OK
8631.211: INFO - 198167 Corrupt: True Count:17 [421, 840, 422, 839, 422, 839, 422, 839, 65535, 839, 421, 840, 422, 839, 422, 839, 1670] Sum: 76871 Min: 11718 Max: 76871 Total fails: 1 Mem: 126736
8710.656: INFO - 200000 - OK
13044.984: INFO - 300000 - OK
17380.094: INFO - 400000 - OK
21714.867: INFO - 500000 - OK
25811.633: INFO - 594494 Corrupt: True Count:17 [421, 65535, 422, 839, 422, 839, 422, 839, 422, 839, 421, 840, 422, 839, 422, 839, 1672] Sum: 76455 Min: 11718 Max: 76871 Total fails: 2 Mem: 126768
26050.273: INFO - 600000 - OK
30384.914: INFO - 700000 - OK
34401.844: INFO - 792677 Corrupt: True Count:17 [421, 840, 422, 839, 422, 839, 422, 841, 65535, 839, 422, 839, 422, 839, 422, 839, 1671] Sum: 76874 Min: 11718 Max: 76874 Total fails: 3 Mem: 126768
34719.234: INFO - 800000 - OK
39053.703: INFO - 900000 - OK
43388.406: INFO - 1000000 - OK
47722.813: INFO - 1100000 - OK
52057.219: INFO - 1200000 - OK
55877.359: INFO - 1288127 Corrupt: True Count:17 [421, 841, 421, 839, 422, 839, 422, 839, 422, 839, 422, 839, 422, 839, 422, 65535, 1671] Sum: 76455 Min: 11716 Max: 76874 Total fails: 4 Mem: 126720
56391.984: INFO - 1300000 - OK
60727.172: INFO - 1400000 - OK
64467.578: INFO - 1486285 Corrupt: True Count:17 [421, 840, 422, 839, 422, 65535, 422, 839, 422, 839, 421, 840, 422, 839, 422, 839, 1670] Sum: 76454 Min: 11716 Max: 76874 Total fails: 5 Mem: 126720
65062.234: INFO - 1500000 - OK
69397.375: INFO - 1600000 - OK
73732.125: INFO - 1700000 - OK
78066.438: INFO - 1800000 - OK
82401.188: INFO - 1900000 - OK
85943.094: INFO - 1981713 Corrupt: True Count:17 [421, 840, 421, 840, 422, 65535, 421, 840, 421, 840, 421, 840, 421, 840, 421, 840, 1670] Sum: 76454 Min: 11716 Max: 76874 Total fails: 6 Mem: 126752
86735.719: INFO - 2000000 - OK

Code done running.

Press any key to enter the REPL. Use CTRL-D to reload.

Description

Hi guys,

I am opening here the issue based on the following description in the forum:
https://forums.adafruit.com/viewtopic.php?t=215487

Dear CP community,

first of all I would like to thank to all contributors for the great work,
for example for the pulseio module, which I used to implement the DALI (Digitally Addressable Lighting Interface)
protocol, so I am able to send 16-bit command(forward frame) and receive 8-bit response(backward frame), both manches.ter-encoded, according the standard.
The protocol description you can find for example here https://www.silabs.com/documents/public ... 2-dali.pdf.

I am using the following interface between my nordic dongle and a commercial DALI-driver:
https://eu.mouser.com/applications/ligh ... I463DacDn-

The only issue I am observing, is, that sometimes (approx. after every 100-200 thousand queries) the response contains a wrong pulse length.
According the standard, the pulse length should be either 417ms or 833us with a tolerance of 10%.

In order to simulate the behaviour without a commercial DALI driver and an interface, I replaced the DALI driver with an additional nordic dongle, connected their VBUS and GND, and the pins P0_15 and P0_17 respectively as seen on the attached picture.
From 2 million queries, 6 responses contained wrong pulse length (65535us), as seen from the log below.

My question is, if it is possible to improve the performance and so avoid wrong pulse lengths ?
For example, is my routine for reading the pulses done in correct way ? My intention in the routine is to wait 20ms after no more pulses are registered and return the array of pulses. The general goal is to read the mancheste.r-encoded 8-bit response (backward frame) and return it for decoding.

Another way without waiting after the last pulse would just be to sum up the pulse lengths, as the sum of all pulses of a response is constant (11666us).
But I am not sure, if this would end in high usage of resources and so incorrect pulse reading.

If you need additional information just let me know.
Thank you
Gregory

dongles

Additional information

No response

@gkecskes78 gkecskes78 added the bug label Jan 4, 2025
@gkecskes78
Copy link
Author

Instead of the Nordic dongle, I tried it out on 2x Feather STM32F405 Express (pins D9 and D10 for data) as well, with less success, as none of the queries was answered successfully.
Additionally, on each second save in MU editor, a RunTime error occured - see the screenshot

Feather_STM32F405_Express

@dhalbert
Copy link
Collaborator

dhalbert commented Jan 4, 2025

STM32F405 is not often used and may have bugs. If you have a SAMD or RP2040 board, that would also be a good test.

@dhalbert dhalbert added this to the Long term milestone Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants