| Commit message (Collapse) | Author | Files | Lines |
|
(so 0 to 255 now goes from 0.00V to 5.10V)
|
|
(it used raw ADC units instead of cooked Kelvin units ...
... which was only noticeable on hardware which has different ADC units)
|
|
|
|
internal volt unit
Before this branch, `voltage` was 6 bits: Volts * 10
A couple patches ago, I upgraded it to 16 bits: 65535 * Volts / 10.24
That costs too much extra ROM on attiny85 though, for extra precision
it doesn't even use... so I switched back to an 8-bit value. It's still
more precise than before though: Volts * 40
... and battcheck displays an extra digit now, on devices with ROM for it.
... and battcheck waits a second to get a more accurate measurement
before displaying the first value. It has *much* less variation
between first and later readings now.
Also:
- got t1616 builds working again (tested fc13 and thefreeman-boost-fwaa)
- upgraded t1616 voltage and temp to 12-bit (10 bits + 4x oversampling)
- removed expensive temp conversion from t1616 ADC interrupt
- recalibrated t1616 bogomips again; runs faster after interrupt fix
- increased t1616 internal VDD measurement resolution by 36% (1.5V Vref, not 1.1V)
- fixed sloppy setting of Vref bits
I still need to test / update other t1616 builds,
and fix all the t85 + t1634 code and build targets.
|
|
This patch changes the ADC code to use two internal standard units, and
everything else must convert to these units:
- FSM Volts: centiVolts << 6 (range 0 to 10.24 V per cell)
- FSM Kelvin: Kelvin << 6 (range 0 to 1024 K)
UI-level voltage is still "Volts * 10", and temperature is still Celsius.
FSM expects functions to be provided, to convert from the hardware's
raw ADC measurements to these internal units: `voltage_raw2cooked()`
and `temp_raw2cooked()`. Defaults will be provided by arch/*.[ch] for
each MCU type, or the hwdef can make its own.
Anyway, gotta go fix all the other MCUs and builds now. :(
|
|
|
|
Phew, that's a lot of changes! And there's still a lot more to do...
|
|
(just moved files, didn't change the contents yet,
and nothing will work without updating #includes and build scripts and stuff)
|
|
Amplitude is smaller, frequency is slower, but it can still happen sometimes at
color boundaries on models with bright aux LEDs on high mode. (because that's
not a measurement error, it's actually oscillating voltage)
The Wurkkos TS11 in particular tends to bounce when crossing certain color
boundaries, because the aux LEDs are bright and change the voltage enough
to push it back and forth across the boundary.
Also sped up voltage measurement during first few seconds after turning off,
to compensate for slowdown caused by the lowpass filter... while slowing down
measurements afterward to slow the oscillation.
I tried a bunch of different methods, spanning a range of "stable but slow" to
"fast but unstable", and kept code clauses for three representative methods.
The one enabled by default is the best compromise I found to reduce the issue
as much as possible while keeping readings reasonably responsive.
|
|
https://budgetlightforum.com/t/anduril-2-feature-change-suggestions/218045/467
I was never able to reproduce the issue here, but the fix seems good and others
tested it successfully.
|
|
(oops, it has no "ADC Noise Reduction" mode... needs different setup code)
|
|
(also reduced avg standby power by about 15 uA)
(also fixed oscillating voltage mode colors, I think)
The bug happened because sometimes sleep LVP would get triggered, because the
ADC would read zero under some conditions.
This in turn happened because the ADC needs the MCU to be at least partially
awake in order to finish a measurement. So in standby mode, with the MCU only
waking up very briefly to send a sleep tick and go back to sleep, the ADC
required several cycles (like 375ms to 625ms) to finish a single measurement.
This varied depending on how many instructions the MCU executed while it was
awake. In the single-color mode, so few instructions were being executed that
the ADC seemed to time out and abort its measurement, returning a zero. Then a
low voltage warning was sent, which knocked the light back into "Off" mode.
Adding no-op instructions inside the single-color clause was sufficient to
prevent the ADC from timing out, because it kept the MCU awake just barely long
enough. But it was a kludge, and it still took like half a second to finish a
measurement, and the measurements were noisy. It also used more power, because
it required keeping the ADC powered on far too long.
This fix puts the MCU into "ADC Noise Reduction" mode instead, when a voltage
measurement is needed during sleep. It reduces noise to make measurements more
stable... but more importantly, it lets the measurement finish in like 0.5ms
instead of 500ms. So it uses less power and isn't dependent on the number of
calculations the MCU does during each "sleep tick".
As a bonus, this can also measure voltage much more often, while still using
less total energy than before. It was once every 8 seconds, and now it's once
per second.
Avg power use in aux low mode, on a D4Sv2: (avg of 30k samples each)
- before: 101 uA
- after: 86 uA
|
|
instead of full GPL headers (or all too often, nothing at all)
There are a few "FIXME" entries where I'm not sure about the correct copyright.
|
|
(this also made some parts of the code cleaner)
|
|
|
|
and other devices which use a voltage divider
(it was 0.1V per step, and is now 0.05V per step)
|
|
but it doesn't actually fix the issue I was hoping it'd fix,
so it's disabled by default
(when the battery is right on a threshold between colors for aux LED "voltage" mode,
it can bounce between colors until the cell isn't on the boundary any more...
but a simple lowpass doesn't really help)
(but I also didn't want to throw out the code, in case it's useful later
as a reference for a more effective solution)
|
|
|
|
|
|
|
|
(with no sleep ticks, the voltage value never gets reset to the raw value,
and instead only goes through the lowpass filter)
(this fix is not yet tested... will test before uploading)
(also carries a risk of messing up thermal values after being asleep,
so that needs to be tested too)
|
|
configure
|
|
updates, because it worked well on many hosts before...
|
|
vars, made KR4 rainbow mode faster
|
|
(helps on KR4, but will probably need to add the response magnitude thing to adjust speed per build target)
|
|
|
|
|
|
symbols
|
|
which mostly impacts small errors (and reduces jitter during the flat phase of regulation)
while leaving large errors pretty much unaffected...
also, made acceptable thermal window smaller to make up for this new extra tolerance
|
|
count any more...
... just a boolean flag for whether this is the first sample or a later sample
(so I changed it and reduced the ROM size by ~28 bytes)
|
|
|
|
delay between warnings,
so large warnings can remain frequent while small warnings are separated by more time,
based on a cumulative error counter which must pass a threshold before the next warning is sent
(this is producing good test results so far on D4v2 and D4Sv2)
|
|
it regulates really fast on D4, but once it's stable, the adjustments are too large
|
|
(not complete, but far enough that it installs and runs)
New hardware support features:
- allow using PCINT other than 0 (PCINT1, PCINT2, etc)
- option to ignore voltage ADC while the button is pressed
(because my prototype shorts the voltage divider to 0 while the button is down)
|
|
(also, now treating smoothed ADC values as 11-bit, with the lowest 5 bits chopped off to eliminate noise)
|
|
samples
(because, for some reason, even though 64 samples is plenty in a test program,
it ends up being extremely erratic when used inside Anduril... and I'm not sure why)
also, use 15-bit ADC values instead of 16 bits, in the temperature logic
(to help protect against integer overflows)
... but this code still doesn't work well. It regulates down *very* fast, and then
gradually rises until the next extra-fast drop-down. :(
... also, tempcheck mode sometimes changes by 4-5 C between readouts, which is worrisome.
... and factory reset is still broken.
|
|
(ceiling value was all wrong, and the response magnitude was way too big)
(also, temperatures here are unsigned, since freezing is about 270 in ADC units)
|
|
... doesn't work well, but I'm saving it so I can experiment with other methods and maybe revert back later.
|
|
changed so far:
- removed LVP lowpass and thermal regulation lowpass logic; it's probably redundant now
- slowed ADC deferred logic timing to 4X per second instead of 16X,
because there doesn't seem to be much reason to do it any faster
- reduced thermal event rate-limit to just 1 second, for more responsive regulation
- added "EV_temperature_okay" signal, to help stop adjustments at an appropriate time instead of going to far
- sped up sleep LVP to one measurement every 8 seconds instead of 16,
to help the aux LEDs respond to voltage changes faster
(effect on standby time is negligible)
- make sure the WDT doesn't set the ADC channel or counter... except in standby mode
|
|
back to 64
|
|
sum-of-discrete-window method
|
|
(keeps stable values within ~0.46 to ~0.54 range, so truncated result has no noise)
|
|
eliminate noise and maybe increase precision
(thermal code still needs to be rewritten though)
|
|
|
|
(was 8-bit before)
|
|
|
|
|
|
(but only on attiny1634 devices, since it costs a bit of space and isn't strictly necessary)
|
|
... but factory reset's auto-calibrate still doesn't get the right values for some reason
(manual calibration works, but not auto)
|
|
functions
|