Page 1 of 2
[SOLVED] Polling pin at 13_us rate ?
Posted: Tue Jul 28, 2020 3:24 pm
by pidou46
Hi,
I'm willing to read data from Chinese digital dial gauge.
This have been successfully been done with arduino microcontroller.
Here are some references:
https://www.davidpilling.com/wiki/index.php/DialGauge
http://www.shumatech.com/support/chinese_scales.htm
https://web.archive.org/web/20180730194 ... n-arduino/
On my side I would like to do it with esp32 and micropython.
The communication protocol is based on:
- a clock line : ticking at 77Hz to 90Hz depending on exact device used
- a data line : bits are read synchronically with clock line
Is there a way to poll a pin at this rate (13_us) ?
Either pcnt or rmt devices from esp32 would be a good way to do it but they are not supported yet.
Re: Polling pin at 13_us rate ?
Posted: Tue Jul 28, 2020 11:54 pm
by jimmo
Is it 77 Hz or kHz -- if it's only Hz then its 13ms, which might be fine to just poll.
Sounds like what you want is SPI peripheral mode, but unfortunately I don't think that's supported on ESP32 MicroPython? RMT receive would also be useful.
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 5:28 am
by pythoncoder
The rates on those web references vary. The dial gauge ref shows 5 clocks in a 2ms period i.e. 400μs interval which should be manageable. For the faster devices I'd recommend a Pyboard (V1.1 or any D series).
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 6:47 am
by pidou46
Thanks for your answers,
I've made a typo, the clock is rated at 13_us (77_kHz)
But it's quite different from one device to another.
I've made some test to check if I would be able to manage the dial gauge case (400_us)
Code: Select all
from machine import Pin
import time
pin=Pin(12)
while True:
pin.value()
print(time.ticks_us())
result:
Code: Select all
92386809
92387675
92388534
92389400
92390259
92391125
92391984
92392857
92393709
92394575
So about 860_us, quite disappointing...
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 7:15 am
by pidou46
pcnt support would help a lot in this case.
There have been some attempt to implement it, but what I have understand is that it's not wanted to add it to the firmware like it have been done with RMT to avoid bloating it.
https://github.com/micropython/micropython/pull/5496
On an other hand, it have been some effort to find a mechanism to call platform-dependent functions but it stall (the PR is closed)
https://github.com/micropython/micropython/pull/5653
Does I understand it well ? maybe I could rise an issue on github, but I don't want to beat a dead horse.
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 7:20 am
by Roberthh
In your example printing 8 digits + CR + NL at 115200 baud takes about 860 µs (100 bits / 115200 bits/s).
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 9:13 am
by pidou46
good point Robethh !
With a modified version of the test script:
Code: Select all
from machine import Pin
import time
data=[]
pin=Pin(12)
for _ in range(10):
#time.sleep_us(1500)
pin.value()
data.append(time.ticks_us())
print(data)
I get:
Code: Select all
[code][395274683, 395274763, 395274800, 395274837, 395274873, 395275040, 395275077, 395275113, 395275150, 395275232]
[/code]
This gives between 36 and 167_us
So as pythoncoder have stated I may be able to manage 400us signal ?
Disabling IRQ would help to get more stable result ?
Now I've to order a dial gauge and try.
Still, PCNT would be a nice addition and would allow to read from several devices...
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 9:29 am
by pidou46
I've tried to disable IRQ:
Code: Select all
from machine import Pin
import machine
import time
data=[]
pin=Pin(12)
state=machine.disable_irq()
for _ in range(10):
#time.sleep_us(1500)
pin.value()
data.append(time.ticks_us())
machine.enable_irq(state)
print(data)
It doesn't really help, I get result from 29 to 158_us
I have tried to disable the garbage collector, but it doesn't help much neither
Is there some tricks to get a better result ?
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 10:19 am
by Roberthh
- data.append() is slow. Better add to a pre-defined array.
- you might try native or viper code.
Re: Polling pin at 13_us rate ?
Posted: Wed Jul 29, 2020 10:43 am
by Roberthh
So I have a version is is slightly faster, at least from the second sample on. Sampling times are 119µs(first pair) and 7 µs (following pairs) on a non-spiram board and 161 / 20µs on a SPIRAM board.
Edit: Code improved to 138/5µs on spiram board and 119/5 on a non-spiram board.
Code: Select all
from machine import Pin
import machine
import time
from array import array
data=array("l", 10*[0])
pin=Pin(12)
@micropython.viper
def sample(data, p, t):
state=machine.disable_irq()
for _ in range(10):
p()
data[_]=t()
machine.enable_irq(state)
def run():
sample(data, pin, time.ticks_us)
for _ in range(9):
print(data[_ + 1] - data[_])