Dealing with ADC readings while perform another operations.
I have read in other topics from this forum, the limitation of LoPy ADC reading rate. I have performed some test for myself and with the lastest firmware I have achieved reading rates of 20Ksamples/s. It could be ok, for the proyect I am interested. I would like to develop a sonometer, and I need to read 20Ksamples/s from the ADC. My main concern is how to manage the information while the ADC is not reading. Basically, I have programmed a Timer to periodically read from the ADC each 1/20000 s and then, I put the read into a circular array. Between two consecutive reading, I need to perform some operations with that array; basically, some sums and multiplications. Considering the limitations reported with the ADC reading rates I do not know if this is posible, since at some point, the micro crases and the REPL does not respond. Is there anyone who has made some similar code/proyect with sucessfull results?
Thank you very much in advance,
robert-hh last edited by robert-hh
@arthurmed So what are the properties of the pulses to receive, and what kind of device is it that you want to connect?
Edit: I just tested that: Even if you specify then number of pulses, it will not return until a timeout happens (and the documentation is still wrong, because pulses_get() does not accept any arguments).
@combaindeft , sadly i have to use this board. This is only one of the multiple nodes existing in the Lora network. I already read that other board's ADCs perform much better...
@arthurmed YOU can use the RMT module to measure pulses. The best resolution is 100ns for pulses up to 3.2768 ms long. See https://docs.pycom.io/firmwareapi/pycom/machine/rmt.html. It receives more than one pulse, but I recall from earlier testing, that it will not return if the series of pulses never stops. But that might have changed
@robert-hh thank you very much for your comments. You are really helping me a lot, so my eternal gratitude!
I have been thinking on possible solutions along the weekend, and checkings for posible interfaces between external ADC and LoPy. I have to use this board, because this is only one of the nodes forming part of the LoRaWan network. I will take a look what you said about the variant of I2S, althoug to be honest, I didnt know how to start porting I2S interface to this board. Indeed, it could be the properly solution, if i knew how to do it. Is there any tutorial or something that I can check?
Also, I have seen that PCM is other posible solucion, since bytes from the external ADC can be decoded measuring the pulse timeing. Is there any way to measure time with precision? I have noted that there are functions like "pulses_get", but again, I remember what you said about the time required to attend an interruption, so I do not know if this is possible to interface this with an external ADC.
rcolistete last edited by
@arthurmed Can you read 20K ADC readings and them process the data with more time ?
See other MicroPython boards with respect to ADC reading speed :
ADC performance of MicroPython boards
The best is Pyboard 1.1/Lite, with 12 bits ADC supporting up to 1,604 ksamples/s.
@arthurmed I just timed the ADC read. A single read takes about 95 µs. An external ADC is faster. It would be good to use the built-in I2S controller. In the micropython.org branch some people just implemented that for the ESP32 platform (https://github.com/micropython/micropython/pull/4471). If you are willing to make your own firmware variant, you could start the attempt to port that. That should not be too difficult, since the Micropython engine and the general code structure is almost the same.
Thank you for your suggestion. I am currently working with that option, but ADC readings are not stable between readings, because depends of the activity of the other thread. I am not sure if this is the solution I am looking for. Anyway, if I'd get something stable, i will report it here.
Thank you vey much.
@robert-hh, thank you very much for your reply and your time responding me. To be honest, I supossed it, but it is better to ask. I am thinking to add an external ADC to the proyect, but all them work with ISC interface, which is not working in micropython ( at the best of my knowledge). Anyway, I am not sure if Mycropython performance could face that data rate receiving samples from an external ADC.
Also, I am trying to use threads, but I am getting nothing stable neither. Is there any way to increase the ADC data reading with micropython? I do not know if this is because mycropython or ESP32. In the datasheet from Espressif, ADC's perform much better. As you said, maybe this is a C-proyect, but I prefer to work with micropython, so any idea is most than welcome.
@arthurmed The problem is the 50µs per sample. Given that a interrupt latency on a ESP32 may range 40µs to 700 µs, with the majority below 200 µs, this is nothing that you can expect to work reliably. Se also the discussion here https://forum.pycom.io/topic/936/pin-interrupt-latency and the links therein.
In scripts I made any sampling beyond 1000Hz was unreliable, and even then it had a lot of timing jitter. That can only be improved if you write your own C-Functions which a placed into the IRAM.
Besides latency, dong math with that data also costs time, which may exceed the 50µs limit too. A single addition or multiplication takes about 1.5 µs each, and indexed array access about 2 µs.
@arthurmed Think you are interested in playing around with Threads ...