クラス ADC -- アナログ-デジタル変換

Usage:

import pyb

adc = pyb.ADC(pin)                  # ピンからアナログオブジェクトを作成
val = adc.read()                    # アナログ値の読み取り

adc = pyb.ADCAll(resolution)        # ADCAll オブジェクトを作成
adc = pyb.ADCAll(resolution, mask)  # 指定のアナログチャンネルの ADCAll オブジェクトを作成
val = adc.read_channel(channel)     # 指定のチャンネルの読み取り
val = adc.read_core_temp()          # MCU 温度の読み取り
val = adc.read_core_vbat()          # MCU VBAT の読み取り
val = adc.read_core_vref()          # MCU VREF の読み取り
val = adc.read_vref()               # MCU 供給電圧の読み取り

コンストラクタ

class pyb.ADC(pin)

指定したピンに関連付けた ADC オブジェクトを作成します。これにより、指定のピンのアナログ値を読み取れます。

メソッド

ADC.read()

アナログピンの値を読み取って返します。返される値は 0-4095 の間です。

ADC.read_timed(buf, timer)

timer オブジェクトで指定のレートで buf にアナログ値を読み込みます。

buf には、たとえば bytearrayarray.array にできます。 buf の項目のサイズが 16 ビット以上であれば、ADC 値は 12 ビットの分解能を持ち、値を buf に直接格納されます。 buf の項目の幅が 8 ビットしかない場(バイト配列など)、サンプリングの解像度は 8 ビットに減少します。

timer は Timer オブジェクトである必要があります。タイマーがトリガーされるたびにサンプルが読み込まれます。タイマーは予め初期化しておき、目的のサンプリング周波数で実行されている必要があります。

この関数の以前の動作をサポートするため、 timer にはサンプリング周波数(Hz)を整数値で指定することもできます。この場合、指定の周波数で動作するよう Timer(6) が自動的に構成されます。

Timer オブジェクトを使った例(推奨する方法):

adc = pyb.ADC(pyb.Pin.board.X19)    # ピン X19 の ADC を作成
tim = pyb.Timer(6, freq=10)         # 10Hz で動作するタイマーを作成
buf = bytearray(100)                # 採取データを格納するバッファを作成
adc.read_timed(buf, tim)            # 10秒かけて 100 の値を採取

周波数に整数値を使った例:

adc = pyb.ADC(pyb.Pin.board.X19)    # ピン X19 の ADC を作成
buf = bytearray(100)                # 100バイトのバッファを作成
adc.read_timed(buf, 10)             # 10Hz でアナログ値を buf に読込み
                                    #   これは完了するまでに10秒かかります
for val in buf:                     # すべての値を巡回し
    print(val)                      # 値を印字

この関数はヒープメモリを割り当てません。ブロッキングがあり、バッファがいっぱいになるまで、呼び出し元プログラムに戻りません。

ADC.read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer)

これは静的メソッドです。複数の ADC から相対的なタイミングで抽出したり、位相データを抽出するために使われます。

timer オブジェクトで指定したレートで、複数の ADC からアナログ値をバッファに読み込みます。タイマーがトリガーするたびに、順番に各 ADC からサンプルが迅速に読み取ります。

ADC および バッファのインスタンスはタプルで渡し、各 ADC には関連するバッファーがあります。すべてのバッファは同じタイプと長さでなければならず、バッファの数は ADC の数と等しくなければなりません。

バッファは、たとえば bytearrayarray.array にできます。 buf の項目のサイズが 16 ビット以上であれば、ADC 値は 12 ビットの分解能を持ち、値を buf に直接格納されます。 buf の項目の幅が 8 ビットしかない場(バイト配列など)、サンプリングの解像度は 8 ビットに減少します。

timer は Timer オブジェクトである必要があります。タイマーは予め初期化しておき、目的のサンプリング周波数で実行されている必要があります。

3つの ADC を読み取る例:

adc0 = pyb.ADC(pyb.Pin.board.X1)    # ADC の作成
adc1 = pyb.ADC(pyb.Pin.board.X2)
adc2 = pyb.ADC(pyb.Pin.board.X3)
tim = pyb.Timer(8, freq=100)        # タイマーの作成
rx0 = array.array('H', (0 for i in range(100))) # 16ビット幅の
rx1 = array.array('H', (0 for i in range(100))) # 100 項目のバッファを作成
rx2 = array.array('H', (0 for i in range(100)))
# アナログ値を 100Hz でバッファに読込み(1秒かかる)
pyb.ADC.read_timed_multi((adc0, adc1, adc2), (rx0, rx1, rx2), tim)
for n in range(len(rx0)):
    print(rx0[n], rx1[n], rx2[n])

この関数はヒープメモリを割り当てません。ブロッキングがあり、バッファがいっぱいになるまで、呼び出し元プログラムに戻りません。

すべての採取が正しいタイミングで取得された場合、関数は True を返します。サンプリングレートが高い場合、データセットの取得にかかる時間がタイマー期間を超える可能性があります。この場合、関数は False を返し、サンプリングの精度が失われたことを示します。極端な場合、データ採取が欠落することもあります。

最大レートはデータ幅や読み取られる ADC の数などの要因によって異なります。テストでは、2つの ADC がオーバーランなしで 210kHz のタイマーレートでサンプリングされました。採取データは 215kHz で欠落しました。3つの ADC の制限は約 140kHz で、4つのADCの場合は約 110kHz です。高いサンプルレートでは、その期間中の割り込みを無効にすると、散発的なデータ損失のリスクを減らすことができます。

ADCALL オブジェクト

これをインスタンス化すると、マスクされたすべての ADC ピンがアナログ入力に変更されます。前処理された MCU 温度、VREF、VBAT データは、それぞれ ADC チャネル 16, 17, 18 でアクセスできます。適切なスケーリングは、使用される基準電圧(通常3.3V)に従って処理されます。チップ上の温度センサーは工場で較正されており、ダイ温度を摂氏 +/- 1度の精度で読み取ることができます。これはかなり正確に聞こえますが、MCU の内部温度が測定されることを忘れないでください。処理負荷とアクティブな I/O サブシステムによっては、ダイ温度が周囲温度よりも数十度高くなることがあります。その一方で、長い待機期間から起床した直後の pyboard は、上記の制限内で正しい周囲温度を示します。

ADCAllread_core_vbat(), read_vref(), read_core_vref() メソッドは、それぞれバックアップバッテリー電圧、基準電圧、実際の供給電圧を用いた基準電圧(公称 1.21V)を読み出します。戻り値はどのメソッドも電圧値を示す浮動小数点数です。

read_core_vbat() はバックアップバッテリーの電圧を返します。この電圧も実際の供給電圧に応じて調整されます。アナログ入力の過負荷を避けるため、バッテリー電圧は分圧器を介して計測し、分圧器の値に応じてスケーリングします。バックアップバッテリーへの過度の負荷を防ぐため、分圧器は ADC 変換中のみアクティブになります。

read_vref() は内部基準電圧を計測し、内部基準電圧の工場校正値を使ってバックスケールすることにより求めます。ほとんどの場合、読み取り値は 3.3V に近くなります。pyboard がバッテリーで動作している場合、供給電圧が 3.3V 未満の値に低下する場合があります。動作条件が満たされている限り、pyboard は引き続き正常に動作します。MCU クロック、フラッシュアクセス速度、プログラミングモードを適切に設定することにより、pyboard を 2V まで落として実行しても、有用なADC変換を得ることができます。

アナログ入力電圧が実際の供給電圧を超えないようにすることは非常に重要です。

他のアナログ入力チャンネル (0..15) は、指定の精度で、スケーリングしない整数値を返します。

アナログ入力(チャンネル 0..15)の不要な有効化を回避するために、第2パラメーターを指定できます。このパラメーターは、アナログ入力を望むチャンネルに対応するビットセットを持つバイナリパターンです。デフォルト値は 0xffffffff で、これはすべてのアナログ入力が有効であることを意味します。内部チャネル (16..18) のみが必要な場合、マスク値は 0x70000 でなければなりません。

サンプルコード:

adcall = pyb.ADCAll(12, 0x70000) # 12 ビットの分解能で、内部チャンネルのみtemp = adcall.read_core_temp()