Low-noise quiet capture for voltmeter and slowest ADC mode#38
Merged
Conversation
Rescoped from issue #13: instead of free-running conversions, the new ADCInput::readMultiQuiet() takes single conversions with the CPU sleeping in SLEEP_MODE_IDLE during each one, engaging the AVR ADC noise canceler to keep core switching noise out of the sample. IDLE rather than SLEEP_MODE_ADC so clkIO (Timer0/micros, PWM test signals) keeps running. The quiet path activates when the previous frame was flat (voltmeter display, reusing the rolling isFlatLine state) or when the slowest ADC mode is selected. The free-running readMulti() hot path is untouched, and non-AVR platforms fall back to it via the ADCBase default. Also fixes a latent curMode shadow in adc_avr.h (ADCInput redeclared the ADCBase member, so base accessors would have read a stale copy) and a double isFlatLine() call in loop() that skewed the rolling Vpp average. Verified: arduino:avr:uno and adafruit:samd:adafruit_feather_m0 build clean with --warnings all (globals unchanged at 490 bytes); make sim-test passes 8/8 against the golden baseline in the devcontainer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rescoped implementation of #13 (see the rescope comment there for full rationale).
What
ADCInput::readMultiQuiet()on AVR: instead of free-running conversions, take single conversions with the CPU sleeping inSLEEP_MODE_IDLEduring each one, engaging the ADC noise canceler to keep core switching noise out of the samples. This sidesteps the 2015 blocker — the noise canceler fundamentally can't work with free-running mode (ADATE), because the next conversion starts before the CPU can sleep.SLEEP_MODE_ADC, deliberately: full ADC noise-reduction mode halts clkIO, which would stop Timer0 (micros()/elapsedusaccounting) and the PWM test signals on pins 9/5. IDLE keeps those running while still stopping the CPU core clock — the dominant on-chip noise source.SLEEP_MODE_ADCremains an escalation path if IDLE isn't enough on hardware.isFlatLinestate) or when the slowest ADC mode is selected. It drops back to free-running the moment the signal moves again.ADCBase::readMultiQuiet()defaults toreadMulti(), so Teensy/SAMD/ESP32 are unaffected — no#ifdefin shared code.Drive-by fixes surfaced during the work
adc_avr.hredeclaredcurMode, shadowing theADCBasemember — base-class accessors would have read a stale copy. Removed the shadow.loop()calledisFlatLine()twice per frame inSIMAVR_TESTbuilds, double-sampling its rolling Vpp average. Now called once and reused.Cost
Zero new RAM (Uno globals unchanged at 490 bytes); flash 21972 bytes (68%) on Uno. The
read()/readFast()/readMulti()hot paths are byte-for-byte untouched.Verification
arduino:avr:uno: builds clean,--warnings all, zero warningsadafruit:samd:adafruit_feather_m0: builds clean, zero warningsmake sim-test: PASS, 8/8 trace lines match the golden baseline (run in the devcontainer)Runtime-affecting — needs hardware flash-test
This changes ADC timing in voltmeter/slow modes. The interesting hardware check: whether the voltmeter's Vpp/% jitter readout visibly drops once the display goes flat, and that scope mode still recovers promptly when a signal reappears.
Agent: claude-fable-5 (Claude Code)
🤖 Generated with Claude Code