CubeCell-Arduino
CubeCell-Arduino copied to clipboard
Terrible timing while reading pulses
Hey, I bought a CubeCell recently. The (battery/solar powered) device will read data from an external (wind) sensor and send received data via LoRaWan (TTN). LoRa-uplink works fine (except some frame counter problem after power lost), but I have much more timing problems reading sensor data.
The sensor sends its data with a proprietary "pulsed" protocol (2ms/4ms for a 0/1-bit, some high between...) and is connected on a standard CubeCell-GPIO-Pin. I use an interrupt handler to decode the pulses. This is done by measuring pulse lengths using micros() function. On FALLING I store the current microseconds, on next falling I calculate the pulse length. Not very difficult. The data come in correctly (tested with logic analyser and even with mirroring the input in my interrupt handler to another GPIO-Output works well. Also tested with logic analyser).
The Problem - It is almost impossible to get valid pulse lengths. The calculated pulse length are off by 1000 up to 1500us!!!! Hard to decide if a pulse with 3ms is a low (2ms) or an high (4ms). it is completely impossible to decode it on a CubeCell.
I even tried a different CubeCell with same result. And not only on this device: I used the same code (!!!) on a standard ESP32, a Wemos D1 mini and even an Heltec Wifi Kit v2. All those devices work like a charm!
I guess, the problem is causes by a horrible microsecond implementation. Micros is the only function I use in the ISR-Handler. I read something about 1.7% inaccuracy .... but this wouldn't be a problem in my case. I tried it with 500us+/- but the calculated length (2000us or 4000us) would still result in errors.
So... Does anybody has an Idea to get clean and correct'ish micros?
Some additional comment:
I implemented the pulse reading via GPIO-polling function and it worked accurate. If I call my method via attachInterruptPIN, pollPin, CHANGE) it ends in same timing problem. So I guess there is some limitation/problem with using micros() within an interrupt service routine.