Browse Source

ESP32 HAL - Dynamic ADC attenuation (#14623)

pull/1/head
Simon Jouet 6 years ago
committed by Scott Lahteine
parent
commit
f0de56a797
  1. 53
      Marlin/src/HAL/HAL_ESP32/HAL.cpp

53
Marlin/src/HAL/HAL_ESP32/HAL.cpp

@ -67,7 +67,9 @@ uint16_t HAL_adc_result;
// Private Variables // Private Variables
// ------------------------ // ------------------------
esp_adc_cal_characteristics_t characteristics; esp_adc_cal_characteristics_t characteristics[ADC_ATTEN_MAX];
adc_atten_t attenuations[ADC1_CHANNEL_MAX] = {};
uint32_t thresholds[ADC_ATTEN_MAX];
volatile int numPWMUsed = 0, volatile int numPWMUsed = 0,
pwmPins[MAX_PWM_PINS], pwmPins[MAX_PWM_PINS],
pwmValues[MAX_PWM_PINS]; pwmValues[MAX_PWM_PINS];
@ -129,49 +131,74 @@ adc1_channel_t get_channel(int pin) {
return ADC1_CHANNEL_MAX; return ADC1_CHANNEL_MAX;
} }
void adc1_set_attenuation(adc1_channel_t chan, adc_atten_t atten) {
if (attenuations[chan] != atten) {
adc1_config_channel_atten(chan, atten);
attenuations[chan] = atten;
}
}
void HAL_adc_init() { void HAL_adc_init() {
// Configure ADC // Configure ADC
adc1_config_width(ADC_WIDTH_12Bit); adc1_config_width(ADC_WIDTH_12Bit);
// Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects // Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects
#if HAS_TEMP_ADC_0 #if HAS_TEMP_ADC_0
adc1_config_channel_atten(get_channel(TEMP_0_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_TEMP_ADC_1 #if HAS_TEMP_ADC_1
adc1_config_channel_atten(get_channel(TEMP_1_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_TEMP_ADC_2 #if HAS_TEMP_ADC_2
adc1_config_channel_atten(get_channel(TEMP_2_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_TEMP_ADC_3 #if HAS_TEMP_ADC_3
adc1_config_channel_atten(get_channel(TEMP_3_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_TEMP_ADC_4 #if HAS_TEMP_ADC_4
adc1_config_channel_atten(get_channel(TEMP_4_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_TEMP_ADC_5 #if HAS_TEMP_ADC_5
adc1_config_channel_atten(get_channel(TEMP_5_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_HEATED_BED #if HAS_HEATED_BED
adc1_config_channel_atten(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db);
#endif #endif
#if HAS_TEMP_CHAMBER #if HAS_TEMP_CHAMBER
adc1_config_channel_atten(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db);
#endif #endif
#if ENABLED(FILAMENT_WIDTH_SENSOR) #if ENABLED(FILAMENT_WIDTH_SENSOR)
adc1_config_channel_atten(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db); adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db);
#endif #endif
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail. // Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
// That's why we're not setting it up here. // That's why we're not setting it up here.
// Calculate ADC characteristics i.e. gain and offset factors // Calculate ADC characteristics (i.e., gain and offset factors for each attenuation level)
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, V_REF, &characteristics); for (int i = 0; i < ADC_ATTEN_MAX; i++) {
esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t)i, ADC_WIDTH_BIT_12, V_REF, &characteristics[i]);
// Change attenuation 100mV below the calibrated threshold
thresholds[i] = esp_adc_cal_raw_to_voltage(4095, &characteristics[i]);
}
} }
void HAL_adc_start_conversion(uint8_t adc_pin) { void HAL_adc_start_conversion(uint8_t adc_pin) {
const adc1_channel_t chan = get_channel(adc_pin);
uint32_t mv; uint32_t mv;
esp_adc_cal_get_voltage((adc_channel_t)get_channel(adc_pin), &characteristics, &mv); esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
// Change the attenuation level based on the new reading
adc_atten_t atten;
if (mv < thresholds[ADC_ATTEN_DB_0] - 100)
adc1_set_attenuation(chan, ADC_ATTEN_DB_0);
else if (mv > thresholds[ADC_ATTEN_DB_0] - 50 && mv < thresholds[ADC_ATTEN_DB_2_5] - 100)
adc1_set_attenuation(chan, ADC_ATTEN_DB_2_5);
else if (mv > thresholds[ADC_ATTEN_DB_2_5] - 50 && mv < thresholds[ADC_ATTEN_DB_6] - 100)
adc1_set_attenuation(chan, ADC_ATTEN_DB_6);
else if (mv > thresholds[ADC_ATTEN_DB_6] - 50)
adc1_set_attenuation(chan, ADC_ATTEN_DB_11);
HAL_adc_result = mv * 1023.0 / 3300.0; HAL_adc_result = mv * 1023.0 / 3300.0;
} }

Loading…
Cancel
Save