ESP32 校正 ADC
網路上已經有善心人士幫我們把校正版本的 MicroPython 模組寫好了, 可以在這裡找到 MicroPython-ADC_Cal , 它提供一個繼承自
ADC
ADC1Cal
類別, 內建有 voltage
屬性可以取得校正後以 V 為單位的電壓值, 使用範例如下:from machine import Pin, ADC
from adc1_cal import ADC1Cal
import time
DIV = 1 # div = V_measured / V_input; here: no input divider
ubatt = ADC1Cal(
Pin(36), # 腳位
1, # 分壓電路的倍數 (分壓後的電壓/原始電壓), 1 表示沒有使用分壓電路
None, # 參考電壓, None 表示從 eFuse 中取得參考電壓
10, # 平均值計算的取樣次數
"ADC1 Calibrated"
)
ubatt.width(ubatt.WIDTH_10BIT)
ubatt.atten(ubatt.ATTN_6DB) # 不支援 11dB
# 顯示參考電壓
print('ADC Vref: {:4}mV'.format(ubatt.vref))
while True:
print('Voltage: {:4.1f}mV'.format(ubatt.voltage))
time.sleep(0.3)
不過這個模組原本因為想要減少記憶體用量以及計算複雜度.6 , 加入了衰減設為 11dB 時針對非線性區域以查表及 esp-idf 的原始碼方式求值的功能.
更新:2021/12/06 我的修改版本已經提交並且併入原作者的版本中了, 所以已經沒有不支援 11dB 的限已
雙線性內插 ESP32 ADC1의 ADC
ESP32 中對於 ADC 的校正, 是把 ADC 值都應對到 12 位元的解析度, 公然後將 ADC 值以線性方式對應到電:
mV = (a * adc + 32768) / 65536 + b
而對ADC1 來說:
a = (vref * atten_scales[atten]) / 4096
b = atten_offsets[atten]
其中 atten_scales 與 atten_offsets 就是根據衰減值決定的倍率與位移, 對照表如下, DB照表如下, 個別元素分別對應刈
vref_atten_scale = [57431, 76236, 105481, 196602];
vref_atten_offset = [75, 78, 107, 142];
非線性區間的處理
如果 如果 adc.attn_11db, 那麼 在 在 adc 值 在 在 2880 ~ 4095 的 區間, 則 是 非 非 區域 區域 區域, 它 提供 參考 參考 電壓 為 為 1000mv 和 1200mv 時 以 以 adc 值 64 為 區隔 的 的 對應 電 壓值 表格 供 參考 參考 表格 表格 表格 表格 表格 表格 表格 表格 表格 表格 表格 表格내측:
# LUT for VREF 1000mV
lut_adc1_low = [2240, 2297, 2352, 2405, 2457, 2512, 2564, 2616, 2664, 2709,
2754, 2795, 2832, 2868, 2903, 2937, 2969, 3000, 3030, 3060]
# LUT for VREF 1200mV
lut_adc1_high = [2667, 2706, 2745, 2780, 2813, 2844, 2873, 2901, 2928, 2956,
2982, 3006, 3032, 3059, 3084, 3110, 3135, 3160, 3184, 3209]
由於 由於 從 從 2880 ~ 4096 間隔 為 為 64, 所以 共 有 有 (4096-2880)/64 = 20 項 資料.. 當 當 adc 值落入 特定 區間 時, 就 以 參考 參考 電壓 x 軸 軸 、 、 adc 值 為 為 y 軸, 電壓值 為 為z 雙線性, 以 軸 內 內 插法 求 得 得 電 電 壓值 舉例 舉例 來說 來說 來說, 若 adc 值 為 3040, 從 efuse 取得 取得 參考 參考 電壓 為 為 1070, 那麼 首先 可 知 知 知 知 2976 是 2880+ 64 + 64 + 32, 所以得知落在第 3 個線區間, 即可以 (1000, 3008, 2352), (1000, 3072, 2405) 及 (1200, 3008, 2740, 3008, 2740)、(180)性內插求 (1070, 3040) 對應的 Z 值:
ADC
^
| 2405 R2 2780
3072 +----●----●--------●
| | | |
| | P |
3040 +----|----●--------|
| | | |
| 2352 R1 2745
3008 +----●----●--------●
| | | |
+----+----+--------+--->VREF
1000mV 1070mV 1200mV
過程如下:
先在 Y 軸 2880+64 這條線上求內插值:
R1 = ((1070-1000) * 2745 + (1200-1070) * 2352)/ (1200-1000)
R1 = 2489.55
再在 Y 軸 2880+128 這條線上求內插值:
R2 = ((1070-1000) * 2780 + (1200-1070) * 2405)/ (1200-1000)
R2 = 2536.25
再在 X 軸 1070mV 這條線上求內插值:
P = ((3040 - 3008) * 2536.25 + (3072 - 3040) * 2489.55)/ 64
P = 2512.9
線性到非線性的交界區
對於 adc.attn_11db 的 處理 處理, 除了 上述 非線性 非線性 區間 外 外 外, 如果 adc 值落 在 在 在 2880 ~ 2880+64 的 這 個 區間 區間, 因為 是 從 線性 線性 區 區 往 非線性區 邊緣 邊緣 邊緣 所以 還 會 會 再 再 以 上述 提到 的 方式 方式分別計算出線性值與非線性值後, 用 ADC 值在 (2880, 線性值) 與 (2880+64, 非線性值) 間以內插法再求倣畛成實
Reference
이 문제에 관하여(ESP32 校正 ADC), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/codemee/esp32-xiao-zheng-adc-5m2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)