aboutsummaryrefslogtreecommitdiff
path: root/fsm
diff options
context:
space:
mode:
authorSelene ToyKeeper2023-11-21 02:52:00 -0700
committerSelene ToyKeeper2023-11-21 02:52:00 -0700
commitfdb47b96e86924bf81852205b2b3078b8b21d040 (patch)
treeed8337b4619bb86ffb40c63767a32ae58e9b4dcc /fsm
parent1.55V AA battery should not show as "white" voltage color, only purple (diff)
downloadanduril-fdb47b96e86924bf81852205b2b3078b8b21d040.tar.gz
anduril-fdb47b96e86924bf81852205b2b3078b8b21d040.tar.bz2
anduril-fdb47b96e86924bf81852205b2b3078b8b21d040.zip
got ADC voltage+temp working on avrdd... but broke all other builds/MCUs
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. :(
Diffstat (limited to 'fsm')
-rw-r--r--fsm/adc.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/fsm/adc.c b/fsm/adc.c
index 13a76b6..73e282d 100644
--- a/fsm/adc.c
+++ b/fsm/adc.c
@@ -30,6 +30,7 @@ void adc_voltage_mode() {
}
+#if 0
#ifdef USE_VOLTAGE_DIVIDER
static inline uint8_t calc_voltage_divider(uint16_t value) {
// use 9.7 fixed-point to get sufficient precision
@@ -44,6 +45,7 @@ static inline uint8_t calc_voltage_divider(uint16_t value) {
return result;
}
#endif
+#endif
// Each full cycle runs ~2X per second with just voltage enabled,
// or ~1X per second with voltage and temperature.
@@ -67,7 +69,6 @@ ISR(ADC_vect) {
// update the latest value
#ifdef MCU_ADC_RESULT_PER_TYPE
- // thermal, convert ADC reading to left-aligned Kelvin
if (channel) m = mcu_adc_result_temp();
else m = mcu_adc_result_volts();
#else
@@ -208,6 +209,19 @@ static inline void ADC_voltage_handler() {
#endif
else measurement = adc_smooth[0];
+ // convert raw ADC value to FSM voltage units: (V * 100) << 6
+ // 0 .. 65535 = 0.0V .. 10.24V
+ measurement = voltage_raw2cooked(measurement) / (10 << 5);
+
+ // calculate actual voltage: volts * 10
+ // TODO: should be (volts * 40) for extra precision
+ voltage = (measurement + VOLTAGE_FUDGE_FACTOR
+ #ifdef USE_VOLTAGE_CORRECTION
+ + VOLT_CORR - 7
+ #endif
+ ) >> 1;
+
+ #if 0
// values stair-step between intervals of 64, with random variations
// of 1 or 2 in either direction, so if we chop off the last 6 bits
// it'll flap between N and N-1... but if we add half an interval,
@@ -231,6 +245,7 @@ static inline void ADC_voltage_handler() {
#endif
) >> 1;
#endif
+ #endif
// if low, callback EV_voltage_low / EV_voltage_critical
// (but only if it has been more than N seconds since last call)
@@ -290,8 +305,14 @@ static inline void ADC_temperature_handler() {
}
// latest 16-bit ADC reading
- uint16_t measurement = adc_smooth[1];
+ // convert raw ADC value to Kelvin << 6
+ // 0 .. 65535 = 0 K .. 1024 K
+ uint16_t measurement = temp_raw2cooked(adc_smooth[1]);
+ // (Kelvin << 6) to Celsius
+ temperature = (measurement>>6) + THERM_CAL_OFFSET + (int16_t)TH_CAL - 275;
+
+ #if 0
// values stair-step between intervals of 64, with random variations
// of 1 or 2 in either direction, so if we chop off the last 6 bits
// it'll flap between N and N-1... but if we add half an interval,
@@ -313,6 +334,12 @@ static inline void ADC_temperature_handler() {
// external sensor
temperature = EXTERN_TEMP_FORMULA(measurement>>1) + THERM_CAL_OFFSET + (int16_t)TH_CAL;
#endif
+ #endif
+
+ // instead of (K << 6), use (K << 1) now
+ // TODO: use more precision, if it can be done without overflow in 16 bits
+ // (and still work on attiny85 without increasing ROM size)
+ measurement = measurement >> 5;
// how much has the temperature changed between now and a few seconds ago?
int16_t diff;
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.