Quellcode durchsuchen

ESP32 HAL - Dynamic ADC attenuation (#14623)

Simon Jouet vor 4 Jahren
Ursprung
Commit
f0de56a797
1 geänderte Dateien mit 40 neuen und 13 gelöschten Zeilen
  1. 40
    13
      Marlin/src/HAL/HAL_ESP32/HAL.cpp

+ 40
- 13
Marlin/src/HAL/HAL_ESP32/HAL.cpp Datei anzeigen

@@ -67,7 +67,9 @@ uint16_t HAL_adc_result;
67 67
 // Private Variables
68 68
 // ------------------------
69 69
 
70
-esp_adc_cal_characteristics_t characteristics;
70
+esp_adc_cal_characteristics_t characteristics[ADC_ATTEN_MAX];
71
+adc_atten_t attenuations[ADC1_CHANNEL_MAX] = {};
72
+uint32_t thresholds[ADC_ATTEN_MAX];
71 73
 volatile int numPWMUsed = 0,
72 74
              pwmPins[MAX_PWM_PINS],
73 75
              pwmValues[MAX_PWM_PINS];
@@ -129,49 +131,74 @@ adc1_channel_t get_channel(int pin) {
129 131
   return ADC1_CHANNEL_MAX;
130 132
 }
131 133
 
134
+void adc1_set_attenuation(adc1_channel_t chan, adc_atten_t atten) {
135
+  if (attenuations[chan] != atten) {
136
+    adc1_config_channel_atten(chan, atten);
137
+    attenuations[chan] = atten;
138
+  }
139
+}
140
+
132 141
 void HAL_adc_init() {
133 142
   // Configure ADC
134 143
   adc1_config_width(ADC_WIDTH_12Bit);
135 144
 
136 145
   // Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects
137 146
   #if HAS_TEMP_ADC_0
138
-    adc1_config_channel_atten(get_channel(TEMP_0_PIN), ADC_ATTEN_11db);
147
+    adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db);
139 148
   #endif
140 149
   #if HAS_TEMP_ADC_1
141
-    adc1_config_channel_atten(get_channel(TEMP_1_PIN), ADC_ATTEN_11db);
150
+    adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db);
142 151
   #endif
143 152
   #if HAS_TEMP_ADC_2
144
-    adc1_config_channel_atten(get_channel(TEMP_2_PIN), ADC_ATTEN_11db);
153
+    adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db);
145 154
   #endif
146 155
   #if HAS_TEMP_ADC_3
147
-    adc1_config_channel_atten(get_channel(TEMP_3_PIN), ADC_ATTEN_11db);
156
+    adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db);
148 157
   #endif
149 158
   #if HAS_TEMP_ADC_4
150
-    adc1_config_channel_atten(get_channel(TEMP_4_PIN), ADC_ATTEN_11db);
159
+    adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db);
151 160
   #endif
152 161
   #if HAS_TEMP_ADC_5
153
-    adc1_config_channel_atten(get_channel(TEMP_5_PIN), ADC_ATTEN_11db);
162
+    adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db);
154 163
   #endif
155 164
   #if HAS_HEATED_BED
156
-    adc1_config_channel_atten(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db);
165
+    adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db);
157 166
   #endif
158 167
   #if HAS_TEMP_CHAMBER
159
-    adc1_config_channel_atten(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db);
168
+    adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db);
160 169
   #endif
161 170
   #if ENABLED(FILAMENT_WIDTH_SENSOR)
162
-    adc1_config_channel_atten(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db);
171
+    adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db);
163 172
   #endif
164 173
 
165 174
   // Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
166 175
   // That's why we're not setting it up here.
167 176
 
168
-  // Calculate ADC characteristics i.e. gain and offset factors
169
-  esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, V_REF, &characteristics);
177
+  // Calculate ADC characteristics (i.e., gain and offset factors for each attenuation level)
178
+  for (int i = 0; i < ADC_ATTEN_MAX; i++) {
179
+    esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t)i, ADC_WIDTH_BIT_12, V_REF, &characteristics[i]);
180
+    
181
+    // Change attenuation 100mV below the calibrated threshold
182
+    thresholds[i] = esp_adc_cal_raw_to_voltage(4095, &characteristics[i]);
183
+  }
170 184
 }
171 185
 
172 186
 void HAL_adc_start_conversion(uint8_t adc_pin) {
187
+  const adc1_channel_t chan = get_channel(adc_pin);
173 188
   uint32_t mv;
174
-  esp_adc_cal_get_voltage((adc_channel_t)get_channel(adc_pin), &characteristics, &mv);
189
+  esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
190
+
191
+  // Change the attenuation level based on the new reading
192
+  adc_atten_t atten;
193
+  if (mv < thresholds[ADC_ATTEN_DB_0] - 100)
194
+    adc1_set_attenuation(chan, ADC_ATTEN_DB_0);
195
+  else if (mv > thresholds[ADC_ATTEN_DB_0] - 50 && mv < thresholds[ADC_ATTEN_DB_2_5] - 100)
196
+    adc1_set_attenuation(chan, ADC_ATTEN_DB_2_5);
197
+  else if (mv > thresholds[ADC_ATTEN_DB_2_5] - 50 && mv < thresholds[ADC_ATTEN_DB_6] - 100)
198
+    adc1_set_attenuation(chan, ADC_ATTEN_DB_6);
199
+  else if (mv > thresholds[ADC_ATTEN_DB_6] - 50)
200
+    adc1_set_attenuation(chan, ADC_ATTEN_DB_11);
201
+
175 202
   HAL_adc_result = mv * 1023.0 / 3300.0;
176 203
 }
177 204
 

Laden…
Abbrechen
Speichern