BLE Nano + mbed での ADC の基準電圧は VDD の 1/3 になっています。当然ながら VDD が変動するケースではこの基準は受け入れられません。BLE Nano は性質的に電池駆動するケースも多々あるでしょうから、デフォルトでVDD基準なのは解せない仕様です。

mbed には基準を変更する API などがないので、自力で設定します。BLE Nano には内部バンドギャップリファレンスの 1.2V もあるので、これを使うようにします。

	NRF_ADC->CONFIG =
		(ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
		(ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
		(ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
		(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);

ADC_CONFIG_REFSEL_VBG がバンドギャップリファレンスを使うようにする部分です。あとの部分は元のままです。なお、アナログ入力側には1/3の分圧が入っています。

mbed のライブラリ側ではこれらのオプションを保持して ADC を行うようなコードに(今のところは)なっているので、AnalogIn 初期化後に一度設定すればずっと有効です。

備考:VDD の電圧を測りたい場合

VDD の電圧をADCしたい場合は、外部接続しなくとも INPSEL を ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling にすればできそうです。mbed 側では対応していませんが、現状の実装だと、CONFIG を書きかえてから、AnalogIn (なんでもいい) を read すればいけそうな雰囲気です。

備考:mbed 側の実装

TARGET_MCU_NRF51822 の analogin_api.c に実装があります。

    NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
                      (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
                      (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) |
                      (analogInputPin << ADC_CONFIG_PSEL_Pos) |
  1. トップ
  2. tech
  3. BLE Nano + mbed の ADC の基準電圧
▲ この日のエントリ