はじめに
M5StickCに搭載されているESP32のADCは完全に線形ではなく、SoCごとに特性が異なるようです。そのため、ADCの性能を確認する必要があります。今回は手持ちの半固定抵抗(10kΩ)を使用して、印可される電圧を監視し、その値をプロットして性能を確認します。
M5StickCに半固定抵抗を接続する
M5StickCから出力されている3V3をG33ピンで読み込むように配線します。
アナログ値を取得するコードを書く
適当にアナログ値を取得するコードを書き、M5StickCに書き込みます。
#include <M5StickC.h>
const int INPUT_PIN = 33;
const int SAMPLE_COUNT = 1000;
void setup() {
M5.begin();
M5.Lcd.begin();
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setRotation(1);
M5.Lcd.setTextDatum(4);
pinMode(INPUT_PIN, ANALOG);
}
void loop() {
int data = 0;
for (int i = 0; i < SAMPLE_COUNT; i++){
data = data + int(analogRead(INPUT_PIN));
}
data = data /SAMPLE_COUNT;
if(millis() > (5000)){
M5.Lcd.fillScreen(BLACK);
M5.Lcd.drawString(String(data),80,40,4);
}
delay(50);
}
C++データの記録
M5StickCのモニターに表示させた値を表計算ソフトに記録していきます。
散布図にすると、ADCの値にばらつきがある事がわかったので、回帰分析を行い近似式から電圧を求められるようにしておきます。
ADC (0~4,095) | 電圧V( 0~3.3) |
0 | 0.117 |
19 | 0.139 |
165 | 0.26 |
235 | 0.316 |
425 | 0.472 |
565 | 0.584 |
778 | 0.757 |
946 | 0.893 |
1151 | 1.054 |
1273 | 1.152 |
1353 | 1.214 |
1606 | 1.417 |
1723 | 1.511 |
1853 | 1.617 |
1978 | 1.719 |
2155 | 1.86 |
2253 | 1.94 |
2527 | 2.165 |
2681 | 2.285 |
2945 | 2.489 |
3210 | 2.671 |
3511 | 2.843 |
3826 | 2.993 |
3955 | 3.05 |
4095 | 3.207 |
x軸:ADC y軸:電圧
近似式から関数を作っておく
記録したデータから近似式を求めておきます。なお、”e-001″や”e-004″は指数表記です。
$$y = 1.2084919200554808e-001 \\ + 7.9843295692827053e-004 * ADC \\+ 2.5633217181176420e-007 * ADC^2 \\ -6.8943814226029298e-010 * ADC^3 \\+ 7.9306335402267309e-013 * ADC^4 \\ -4.8165629389753582e-016 * ADC^5 \\ + 1.6114120108468767e-019 * ADC^6 \\ -2.7991037343006793e-023 * ADC^7 \\ + 1.9618321439790049e-027 * ADC^8$$
得られた近似式を元に関数を作成しておきます。
// ADCから電圧を求める
double adcTovoltage( double adc ) {
double coef_list[] = {
1.2084919200554808e-001,
7.9843295692827053e-004,
2.5633217181176420e-007,
-6.8943814226029298e-010,
7.9306335402267309e-013,
-4.8165629389753582e-016,
1.6114120108468767e-019,
-2.7991037343006793e-023,
1.9618321439790049e-027
};
double multiplier = 1;
double result = 0;
for (double coef : coef_list) {
result += coef * multiplier;
multiplier *= adc;
}
return result;
}
C++まとめ
今回は、M5StickCのADCを校正しました。ESP32のADCは出力にばらつきがあるようで、気休めでも校正を行った方がいいかもしれません。