Skip to content
This repository has been archived by the owner on Apr 16, 2021. It is now read-only.

clockCyclesPerMicrosecond, clockCyclesToMicroseconds(a), microsecondsToClockCycles(a) missing from Arduino.h #101

Closed
tjpetz opened this issue Aug 26, 2020 · 3 comments

Comments

@tjpetz
Copy link

tjpetz commented Aug 26, 2020

The functions clockCyclesPerMicrosecond, clockCyclesToMicroseconds(a), microsecondsToClockCycles(a) are missing from Arduino.h. These functions/defines are present in the other cores (e.g. AVR, SAM, SAMD, ...).

Some libraries (e.g. Adafruit DHT_Sensor_Library, and others on GitHub) use one or more of these functions. This results in an undefined error when building for the Nano 33 BLE.

Do you consider this a bug in the core or an incorrect assumption that these are defined by some library creators?

If these should be defined in the core I'm happy to submit a PR to add them.

@facchinm
Copy link
Member

facchinm commented Aug 27, 2020

Hi @tjpetz ,
while we can add that macros using the CPU frequency as base, the result will almost never be correct (since there's an RTOS under the hood and the user thread can be interrupted at any time) .
For example, the call in https://github.com/adafruit/DHT-sensor-library/blob/master/DHT.cpp#L380-L382 can be replaced with a safer (and more precise) timeout based on micros() .

@tjpetz
Copy link
Author

tjpetz commented Aug 27, 2020

Hi @facchinm,

Yes, that makes sense, I forgot this is running on an RTOS. So it would have to be "fixed" in any library making use of those calls rather than in Arduino.h.

Thanks!

@tjpetz tjpetz closed this as completed Aug 27, 2020
@tjpetz
Copy link
Author

tjpetz commented Sep 8, 2020

Hi @facchinm,

I've done a bit more research and some thinking on this point. It's probably a philosophical discussion if/where clockCyclesPerMicroseconds belongs (in Arduino.h or somewhere else).

I'm adding this additional information should someone else happen upon this thread.

In the AdaFruit library for the DHT sensor they are not using the clockCyclesPerMicrosecond to measure time. The algorithm isn't directly using time measurements. Rather they are relying on the sensor which emits a fixed low (50 uS for the DHT11) followed by a variable length high pulse to indicate 1 or 0. To measure the relative time of the low and high portion of the pulses they increment an integer counter variable and "count" the low and the high portions of the pulse. The low should always (within a range) be the same value for each pulse. The high portion of the pulse indicates a sensor value of 0 if the high is less than the time of the low and indicates a 1 if the high portion is longer than the low. This accounts rather nicely for imprecision in any clock and also variability in the sensor performance.

The algorithm uses the clockCyclesPerMicroseconds() macro only to pick a reasonably large but not too large value to indicate a timeout error when reading the sensor. It appears the algorithm is assuming you can't increment the counter faster than 1 count per cycle (a reasonable assumption on most CPUs). So it's not being used for an exact timeout, rather just as a max reasonable count.

Timing the pulse with micros() doesn't work directly on the Nano 33 BLE because the precision of the clock is insufficient. By default the timer for micros() is running off the low frequency clock (which makes sense to save power and enable sleep) but only has a precision of 30.517 uS. This makes it difficult to accurately measure pulses near that time range. (The DHT11 sensor may have pulse widths as narrow as 16 uS).

Interestingly when using the Nano 33 IoT board the micros() precision is on the order of 2 uS and thus is sufficient to measure the pulse width. (There are other DHT11 libraries that directly use micros() which work fine on the IoT but not BLE boards.)

For the BLE Sense board I was able to use the Timer() class of mbed OS which provides access to the high precision timer. He's a simple example in case anyone else is interested in doing this: https://github.com/tjpetz/EnvironmentSensorTests/tree/master/EnvironmentSensorTestsMBed

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants