-
Notifications
You must be signed in to change notification settings - Fork 119
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
Improve reliability, especially at low clock speed #3
base: master
Are you sure you want to change the base?
Conversation
I found that the library was not working reliably with my 8 MHz Seeeduino Stalker. Some investigation with an oscilloscope showed that the input polling loop was quite slow (maybe 8us), and timer interrupts were taking ~10us. This meant that the polling loop commonly missed the first sensor- driven transition after pullup, and any transitions which occur close to timer interrupts. So: * Use pulseIn() instead of our own loop. This is a little bit faster than what was done before, is calibrated correctly, and could potentially be optimised upstream to provide better resolution in future. It makes the code a bit simpler and avoids the need to watch for the first sensor pulldown. * Disable interrupts during pulseIn(), to provide accurate timing. * Disabling interrupts, and the fact that I was using sleep mode, meant that millis() was not accurate. So instead of depending on millis() to determine whether to do a sensor read, require the caller to explicitly trigger a sensor read, and rely on the caller to wait the requisite sampling period. This means removing resetTimer() and making readSensor() public. Also: * Use INPUT_PULLUP, which was introduced in Arduino 1.0.1. Tested on DHT11 and RHT03 (like DHT22) in autodetect mode. Gathered data from the RHT03 for 6 days, 1800 samples, with no timeout or checksum errors.
Looks good, disabling interrupts to get a more precise timing. Your changes alter the core of the original code, so I want to test it on the hardware I have too before merging it. |
I can split it up if you only want to merge part of it. It will more or less work with the old lastReadTime system, it's just that the sampling interval will be a few milliseconds longer due to the missed timer interrupts. And of course it won't work for me, since I am using sleep mode. In my application, the RTC wakes up the CPU every 5 minutes, with only a few milliseconds added to millis() each time. Explicitly triggering a read seems like a good policy, it is used by a lot of other sensor libraries, but if you really need backwards compatibility then I can fork instead. Alternatively you could make a branch in your repo for the legacy interface, and merge the full patch into master. |
I wonder if disabling interrupts is a good idea? Having interrupts I was going to argue that changing the low-high threshold from > 30 to,
This didn't work as well as I'd expected. Additionally, raising the I think that some fiddlery with disabling interrupts for a part of the Thinking on this more closely, I realize that ensuring over- or under- So, perhaps disabling interrupts is the right approach after all... If
Is this really needed? Disabling interrupts prevents millis() from |
I found that the library was not working reliably with my 8 MHz Seeeduino Stalker. Some investigation with an oscilloscope showed that the input polling loop was quite slow (maybe 8us), and timer interrupts were taking ~10us. This meant that the polling loop commonly missed the first sensor-driven transition after pullup, and any transitions which occur close to timer interrupts. So:
than what was done before, is calibrated correctly, and could
potentially be optimised upstream to provide better resolution in
future. It makes the code a bit simpler and avoids the need to watch
for the first sensor pulldown.
meant that millis() was not accurate. So instead of depending on
millis() to determine whether to do a sensor read, require the caller
to explicitly trigger a sensor read, and rely on the caller to wait
the requisite sampling period. This means removing resetTimer() and
making readSensor() public.
Also:
Tested on DHT11 and RHT03 (like DHT22) in autodetect mode. Gathered data from the RHT03 for 6 days, 1800 samples, with no timeout or checksum errors.