背景
STM32Arduinoのアナログ読み取り機能で電圧が読み取れなかったので仕様を調べたところ、読み取り間隔(サンプリングレート)によって測定可能な回路の抵抗値が異なると分かりました。仕様、書き方、試したことを記事に残します。
使ったもの
- STM32L4
NUCLEO-L432KCを利用しました。 - プログラムを書き込むためのPC
ubuntu22.04にplatformioとvscodeをインストールしたものを利用しました。 - USBケーブル
- ブレッドボード
- 抵抗
- ジャンパワイヤ
ADC_SAMPLINGTIMEに指定可能な値は各ボードの設定ファイルにあり、標準は8.5~19.5サイクル(106.25~243.75n秒)
HALのDriverファイルに指定可能なsamplingtimeが定義されており、stm32l4の場合は下記のファイルです。Arduino_Core_STM32/system/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h#L571-L581
ADC_SAMPLINGTIMEを指定しない場合は8.5~19.5サイクルの最も短いサイクルが適用されます。(106.25~243.75n秒)
今回利用するstm32l4の場合は12.5サイクル(156.25ns ADC_SAMPLETIME_12CYCLES_5)がADC_SAMPLINGTIME未指定時に定義されます。
Arduino_Core_STM32/src/stm32/analog.cpp#L33-L49
今回利用するstm32l4の最長の測定間隔は640.5サイクルを意味するADC_SAMPLETIME_640CYCLES_5です。
platformioの設定ファイルで下記のようにマクロを定義して値を指定可能です。
platformio.ini
build_flags =
-D ADC_SAMPLINGTIME=ADC_SAMPLETIME_640CYCLES_5
アナログ読み取り可能な回路の抵抗: STM32L4の場合標準が820か560Ω、最高50KΩ
マイコンstm32l432のデータシート(PDF)に読み取り間隔ごとの最高抵抗値が記載されています。8botか6bitの分解能で設定可能な最長の640サイクル(80MHz駆動の場合8μ秒間隔)にした場合、50KΩの回路抵抗でも精度を保って電圧を読み取ってくれるようです。
1m秒間隔とかで良いのでMΩの抵抗の回路を読んでくれたら嬉しかったのですが、対応してないようでした。
stm32arduinoでstm32l4を動かすと標準設定では分解能10bit、80MHz駆動、最速の12.5サイクル(156.25nm@80MHz)なので、期待通りに読み取り可能な抵抗値はADCのfastチャンネルで820Ω、slowチャンネルでは560Ωです。
STM32L4の場合、fast channelはPC0,PC1,PC2,PC3,PA0,PA1で、それ以外はslow channelです。
この記述は上記のR_AINの表の下にありました。
読み取り間隔設定による測定値のずれを見てみる: 許容抵抗の100倍を超えると誤差が1%を超えてくる
抵抗で3.3Vを分圧して、利用している抵抗の値と測定間隔による測定値のずれを見てみました。slowt channelのADCのPA3が繋がっているNUCLEO-L432KCのA2ピンで読み取りました。
利用した回路はこちらです。
大小の抵抗で3.3Vを分圧した抵抗を測定します。
ブレッドボードにマイコンと抵抗を取り付けてジャンパワイヤで配線しつつ値を測定しました。
抵抗大 | 抵抗小 | 測定場所 | 理論値 | 12.5サイクル | 640.5サイクル | ||||
---|---|---|---|---|---|---|---|---|---|
測定値 | 誤差% | 抵抗の関係 (許容560Ω) | 測定値 | 誤差% | 抵抗の関係 (許容39KΩ) | ||||
1K | - | A | - | - | - | - | - | - | - |
B | - | - | - | - | - | - | - | ||
C | 1.650 | 1.648 | 0.121 | 許容外 | 1.648 | 0.121 | 許容内 | ||
10K | 1K | A | 3.025 | 3.023 | 0.066 | 許容外 | 3.026 | 0.033 | 許容内 |
B | 0.275 | 0.274 | 0.364 | 許容外 | 0.274 | 0.364 | 許容内 | ||
C | 1.650 | 1.645 | 0.303 | 許容外 | 1.655 | 0.303 | 許容内 | ||
100K | 10K | A | 3.025 | 2.955 | 2.314 | 許容外 | 3.029 | 0.132 | 上側許容内 下側許容外 |
B | 0.275 | 0.281 | 2.18 | 許容外 | 0.271 | 1.45 | 下側許容内 上側許容外 | ||
C | 1.65 | 1.503 | 8.91 | 許容外 | 1.645 | 0.303 | 許容外 | ||
1M | 100K | A | 3.025 | 2.648 | 12.4 | 許容外 | 3.026 | 0.033 | 許容外 |
B | 0.275 | 0.310 | 12.7 | 許容外 | 0.274 | 0.364 | 許容外 | ||
C | 1.65 | 1.435 | 11.9 | 許容外 | 1.606 | 2.67 | 許容内 |
サイクルを長くしている方が想定通り抵抗が大きくなっても測定誤差を小さく維持できています。
許容抵抗を超えたら即座に誤差が発生するのではなく、許容抵抗の100倍を超えたあたりから誤差が1%を超える印象です。
マイコンのロットによって異なる可能性があるので、測定対象は許容内の抵抗にするのが良いと思います。
終わり
STM32Arduinoで動かすマイコンでマクロADC_SAMPLINGTIMEを通してアナログ値読み取り間隔を長くして、より高い抵抗の回路の電圧を測定できました。データシートの抵抗値の100倍弱の回路でも誤差1%未満で測定できはしましたがマイコンのロットによって異なる可能性があるので、測定対象は許容内の抵抗にするのが良いと思います。
参考
アナログ読み取り機能の周波数変更に関する議論スレッドですADC clock tuning #558
ADCの内部の抵抗を意識するきっかけになった記事です
マイクロマウス研修(のり)[33]STM32F446 STEP3-2 ADC(複数チャンネル)
STM32L4の読み取り間隔設定マクロ値一覧です
Arduino_Core_STM32/system/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h#L571-L581
読み取り間隔標準値設定箇所です
Arduino_Core_STM32/src/stm32/analog.cpp#L33-L49
0 件のコメント :
コメントを投稿