SAMD21/SAMD51 ファミリー用クイックリファレンス¶
The Adafruit ItsyBitsy M4 Express board.
以下は、SAMD21/SAMD51 ベースのボードのためのクイックリファレンスです。このボードを初めて使う場合は、まず次のマイクロコントローラの概要を確認してみてください。
MicroPython のインストール¶
チュートリアルの章: SAMD での MicroPython の始め方 を参照してください。そこにはトラブルシューティングについても記載されています。
ボードの一般的な制御¶
MicroPython REPL は VCP モードに設定した USB ポートで利用できます。タブ補完は、オブジェクトにどのようなメソッドがあるかを調べるのに便利です。貼り付けモード(ctrl-E)は、大きめの Pythonコードを REPL に貼り付けるのに便利です。
machine
モジュール
import machine
machine.freq() # CPU の現在の周波数を取得
machine.freq(96_000_000) # CPU の周波数を 96 MHz に設定
この関数コールが受け付ける範囲は、SAMD51 の場合は 1_000_000 から 200_000_000 (1 MHz から 200 MHz)、SAMD21 の場合は 1_000_000 から 54_000_000 (1 MHz から 54 MHz)です。データシートによると、SAMD51 の安全範囲は最大 120 MHz、SAMD21 では最大 48 MHz です。48Mhz以下の周波数は、48Mhzを整数で割った、24Mhz、16Mhz、12MHz などの離散的な周波数に限定して設定されます。8 MHz 未満の周波数では、USB が無効になります。48 MHz 未満の周波数を変更すると、UART, I2C, SPI のボーレートに影響があります。CPU の周波数を変更した後は、これらを再度設定する必要があります。ms および µs タイマーは、周波数変更の影響を受けません。
遅延とタイミング¶
time
モジュールを使います:
import time
time.sleep(1) # 1秒間、一時停止する
time.sleep_ms(500) # 500ミリ秒間、一時停止する
time.sleep_us(10) # 10マイクロ秒間、一時停止する
start = time.ticks_ms() # ミリ秒カウンター値を取得
delta = time.ticks_diff(time.ticks_ms(), start) # 時差を計算
注記: time.sleep_us()
はビジーウェイトによって遅延を発生させます。この間、他のタスクはスケジュールされません。
クロックとタイム¶
時間情報については、2つの関数群を用意しています。すべてのボードに datetime(), mktime(), time() 関数があります。32kHz の水晶振動子を持つボードは、RTC() モジュールも提供します。エポックのスタートは、2000.1.1です。
time
モジュールを使います:
import time
date_time = time.localtime() # 現在の日時情報を取得
date_time = time.localtime(seconds) # 秒数の値から日時をデコード
seconds = time.mktime(date_time_tuple) # 日時のタプルから秒数に変換
second = time.time() # 現在のシステムタイムを返す
date_time タプルのフォーマットは標準にしたがいます。date_time タプルの µs 値は無視されます。RTC モジュールがないボードにおいて、time.localtime() はシステムタイムを返します。RTC は、RTC
モジュールを使います。
from machine import RTC
rtc = RTC()
date_time = rtc.datetime() # 現在の日時を返す
rtc.datetime(date_time_tuple) # 日時を設定。weekday は無視
date_time = rtc.now() # Unix オーダで日時を返す
rtc.calibration(value) # キャリブレーション係数を設定
weekday (曜日)設定は無視され、実際の日付から返されるタプルで計算されます。rtc.now() は、SAMD51 ボードでのみ提供されます。rtc.calibration() で指定する値は -127 から 127 までの範囲です。これはおおよその ppm 量を定義していて、これによってクロックを高速化したり低速化したりすることができます。
タイマー¶
SAMD21/SAMD51 はソフトウェアタイマーをサポートします。 machine.Timer クラスを使います:
from machine import Timer
tim0 = Timer()
tim0.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(0))
tim1 = Timer()
tim1.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(1))
period の単位はミリ秒です。
ピンと GPIO¶
machine.Pin クラスを使います:
from machine import Pin
p0 = Pin('D0', Pin.OUT) # GPIO0 の出力ピンを作成
p0.on() # ピンを "on" (high) レベルに設定
p0.off() # ピンを "off" (low) レベルに設定
p0.value(1) # ピンを on/high に設定
p2 = Pin('D2', Pin.IN) # GPIO2 の入力ピンを作成
print(p2.value()) # 値 0 または 1 を取得
p4 = Pin('D4', Pin.IN, Pin.PULL_UP) # 内部プルアップ抵抗を有効化
p7 = Pin('PA07', Pin.OUT, value=1) # 作成時にピンを high に設定
ピンは文字列または数字で表すことができます。文字列は "D0" や "SDA" などの各ボードのピンラベル、または "Pxnn" という形式で、x は A,B,C,D、nn は 0-31 の範囲の 2 桁の数値です。例:"PA03"、"PD31"
ピン番号は、次の範囲の MCU ポート番号です:
PA0..PA31: 0..31
PB0..PB31: 32..63
PC0..PC31: 64..95
PD0..PD31: 96..127
注記: Adafruit 社の Feather と ItsyBity ボードでは、D5 ピンが外部ゲート出力に接続されているため、入力としてのみ使用可能です。
UART (シリアルバス)¶
machine.UART を参照
# ItsyBitsy M4 board の UART 3 を使用
from machine import UART
uart3 = UART(3, tx=Pin('D1'), rx=Pin('D0'), baudrate=115200)
uart3.write('hello') # 5バイト書き出す
uart3.read(5) # 5バイトまで読み込む
SAMD21/SAMD51 MCU には、最大 8 つのハードウェア SERCOM デバイスがあり、UART、SPI、I2C デバイスとして使えますが、すべての MCU 製品とボードで、すべての TX および RX ピンをユーザーが使えるわけではありません。デバイスと UART 信号へのピンの割り当てについては SAMD の入出力ピン を参照してください。
PWM (パルス幅変調)¶
SAMD21/SAMD51 MCU の最大5つのタイマーデバイスが PWM 信号の作成に使われます。
PWM 機能は machine.PWM クラスによって提供されます。そのクラスにリストされているすべての基本メソッドをサポートします。
# Adafruit ItsyBitsy M4 Express 用のサンプル
from machine import Pin, PWM
# ピンから PWM オブジェクトを作成し、周波数とデューティ比を設定
pwm = PWM(Pin('D7'), freq=2000, duty_u16=32768)
pwm.freq() # 現在の周波数を取得
pwm.freq(1000) # 周波数を設定/変更
pwm.duty_u16() # 現在のデューティ比(0-65535 の範囲)を取得
pwm.duty_u16(200) # 0-65535 の範囲でデューティ比を設定
pwm.deinit() # このピンの PWM を無効化
pwm # PWM オブジェクトのプロパティを表示
PWM コンストラクタ¶
- class PWM(dest, *, freq, duty_u16, duty_ns, invert, device)
以下のパラメータで新しいPWMオブジェクトを構築して、返します。
dest は PWM が出力されるエンティティです。
PWM オブジェクトは TCC タイマーモジュールによって提供されます。TCC タイマーモジュールは、最大で 6 チャンネル、8 出力を備えています。モジュールのすべてのチャンネルは同じ周波数で動作しますが、異なるデューティサイクルを許容します。出力は、モジュロ n 方式でチャンネルに割り当てられます(nはチャンネル数)。チャンネルの出力は、周波数とデューティレートは同じですが、極性は異なる場合があります。たとえば、モジュールに4つのチャンネルがある場合、出力 0 と 4、1 と 5、2 と 6、3 と 7 は、同じ周波数とデューティーレートを共有します。
duty_u16 と duty_ns は、一度に1つだけ指定する必要があります。
キーワード引数:
freq は PWM 周期の周波数を Hz 単位で設定する整数でなければなりません。有効な周波数範囲はそれぞれ 1Hz から 最大 24MHz までです
duty_u16 は、デューティ比を
duty_u16 / 65536
の比率で設定します。duty_ns は、パルス幅をナノ秒単位で設定します。X チャンネルに対する制限も同様に適用されます。
invert=True|False: ビットを設定することにより、それぞれの出力が反転されます。
device=n: TCC モジュール n が利用可能であれば使用する。ピンによっては2つの TCC モジュールを使えます。デバイスが指定されていない場合は、PWM 信号にまだ使用されていないモジュールを使おうとします。しかし、ピンの周波数やデューティサイクルが同じであれば、同じ TCC モジュールで駆動しなければなりません。
PWM メソッド¶
メソッドは汎用的な machine.PWM クラスと同じですが、init() メソッドのキーワード引数が追加され、コンストラクタの引数と同じになります。
PWM のピン割当て¶
ピンは Pin クラスと同様に指定します。PWM 信号線のピン割当てについては SAMD の入出力ピン を参照してください。
ADC (アナログ/デジタル変換)¶
On the SAMD21/SAMD51 ADC functionality is available on Pins labelled 'Ann'.
machine.ADC クラスを使います:
from machine import ADC
adc0 = ADC(Pin('A0')) # create ADC object on ADC pin, average=16
adc0.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
adc1 = ADC(Pin('A1'), average=1) # create ADC object on ADC pin, average=1
ADC の分解能は12bitで、read_u16() が返す値とは関係なく、10~11bit の精度を持ちます。より高い分解能や精度が必要な場合は、外部 ADC を使用してください。
ADC コンストラクタ¶
- class ADC(dest, *, average=16, vref=n)
次のパラメータを使って新しい ADC オブジェクトを構築して返します:
dest is the Pin object on which the ADC is output.
キーワード引数:
average はノイズを減らすために使われます。値が16の場合、LSBノイズは1桁程度です。
vref は ADC の基準電圧を設定します。
デフォルトの設定は 3.3V です。他に設定できる値は次のとおりです:
vref
SAMD21
SAMD51
0
1.0V 基準電圧
内部バンドギャップリファレンス(1V)
1
1/1.48 アナログ電圧供給
アナログ電圧供給
2
1/2 アナログ電圧供給
1/2 アナログ電圧供給
3
外部リファレンス A
外部リファレンス A
4
外部リファレンス B
外部リファレンス B
5
外部リファレンス C
ADC メソッド¶
- read_u16()¶
1つの ADC 値を符号なし16ビット量として読み出します。電圧範囲はコンストラクタの vref オプションで、分解能は bits オプションで定義します。
DAC (デジタル/アナログ変換)¶
DAC クラスは、デジタルからアナログへの高速変換を実現します。使用例:
from machine import DAC
dac0 = DAC(0) # DAC ピン A0 の DAC オブジェクトを作成
dac0.write(1023) # 電圧範囲 0.0V~3.3V を 0~4095の値で書込み
dac1 = DAC(1) # DAC ピン A1 の DAC オブジェクトを作成
dac1.write(2000) # 電圧範囲 0.0V~3.3V を 0~4095の値で書込み
DAC の解像度は、SAMD51 の場合は 12 ビット、SAMD21 の場合は 10 ビットです。SAMD21 デバイスは GPIO PA02 に 1 つの DAC チャンネルを持ち、SAMD51 デバイスは GPIO PA02 と PA05 に 2 つの DAC チャンネルを持っています。
DAC コンストラクタ¶
- class DAC(id, *, vref=3)
引数 vref は出力電圧範囲を定義し、callback オプションは dac_timed() で使われます。vref に適した値は次のとおりです:
vref |
SAMD21 |
SAMD51 |
---|---|---|
0 |
内部基準電圧 |
内部バンドギャップリファレンス(〜1V) |
1 |
アナログ電圧供給 |
アナログ電圧供給 |
2 |
外部リファレンス |
バッファなし外部リファレンス |
3 |
バッファあり外部リファレンス |
DAC メソッド¶
- write(value)¶
選択した DAC 出力に1つの値を書き込みます。値の範囲は、SAMD21 の場合は 0-1023 で、SAMD51 の場合は 0-4095 です。電圧範囲は、vref の設定に依存します。
ソフトウェア SPI バス¶
ソフトウェア SPI (ビットバンギング)はすべてのピンで動作し、 machine.SoftSPI クラスを介してアクセスします:
from machine import Pin, SoftSPI
# 与えたピンから SoftSPI バスを構築
# 極性 polarity は SCK のアイドル状態
# phase=0 は SCK の第1エッジでサンプルを意味、chase=1 は第2を意味
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin('D7'), mosi=Pin('D9'), miso=Pin('D10'))
spi.init(baudrate=200000) # ボーレートを設定
spi.read(10) # MISO で 10 バイト読込み
spi.read(10, 0xff) # 10 バイト読込み、その間 MOSI に 0xff を出力
buf = bytearray(50) # バッファを作成
spi.readinto(buf) # 与えたバッファに読込み(この場合は 50 バイト)
spi.readinto(buf, 0xff) # 与えたバッファに読込み、MOSI に 0xff を出力
spi.write(b'12345') # MOSI に 5 バイト書込み
buf = bytearray(4) # バッファを作成
spi.write_readinto(b'1234', buf) # MOSI に書き込み、MISO からバッファに読み込み
spi.write_readinto(buf, buf) # MOSI に buf を書き込み、MISO から buf に読み込み
サポートしている最大ボーレートは 500000 です。
ハードウェア SPI バス¶
SAMD21/SAMD51 MCU には、最大 8 つのハードウェア SERCOM デバイスがあり、UART、SPI、I2C デバイスとして使えますが、すべての MCU 製品とボードがすべての信号ピンをユーザーに公開しているわけではありません。ハードウェア SPI は machine.SPI クラスを使ってアクセスしますこのクラスには先述のソフトウェア SPI と同じメソッドがあります:
from machine import SPI
spi = SPI(1, sck=Pin("SCK"), mosi=Pin("MOSI"), miso=Pin("MISO"), baudrate=10000000)
spi.write('Hello World')
miso を指定しなければ、それは使われません。SPI 信号線のピン割当てについては SAMD の入出力ピン を参照してください。
注記: 現時点で最も信頼性の高いボーレートが 24MHz 程度であっても、特に高いボーレートでは、ボーレートの設定が必ずしもその通りの周波数になるとは限りません。
ソフトウェア I2C バス¶
ソフトウェア I2C (ビット・バンギングを使用)は、出力可能なすべてのピンで動作し、 machine.SoftI2C クラスを使ってアクセスします。
from machine import Pin, SoftI2C
i2c = SoftI2C(scl=Pin('D10'), sda=Pin('D11'), freq=100000)
i2c.scan() # scan for devices
i2c.readfrom(0x3a, 4) # read 4 bytes from device with address 0x3a
i2c.writeto(0x3a, '12') # write '12' to device with address 0x3a
buf = bytearray(10) # create a buffer with 10 bytes
i2c.writeto(0x3a, buf) # write the given buffer to the slave
サポートしている最大周波数は 400000 です。
ハードウェア I2C バス¶
SAMD21/SAMD51 MCU には、最大 8 つのハードウェア SERCOM デバイスがあり、UART、SPI、I2C デバイスとして使えますが、すべての MCU 製品とボードがすべての信号ピンをユーザーに公開しているわけではありません。デバイスと I2C 信号線のピン割当てについては SAMD の入出力ピン を参照してください。
ハードウェア I2C は machine.I2C クラスを使ってアクセスしますこのクラスには先述のソフトウェア I2C と同じメソッドがあります:
from machine import I2C
i2c = I2C(2, scl=Pin("SCL"), sda=Pin("SDA"), freq=400_000)
i2c.writeto(0x76, b"Hello World")
OneWire ドライバー¶
OneWire ドライバーはソフトウェアで実装され、すべてのピンで動作します:
from machine import Pin
import onewire
ow = onewire.OneWire(Pin('D12')) # GPIO12 で OneWire バスを作成
ow.scan() # バス上のデバイスリストをスキャン
ow.reset() # バスをリセット
ow.readbyte() # 1バイト読込み
ow.writebyte(0x12) # バスに1バイト書込み
ow.write('123') # バスに複数バイト書込み
ow.select_rom(b'12345678') # ROM コードで指定したデバイスを選択
DS18S20 と DS18B20 のデバイスに対応したドライバが用意されています:
import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(ds.read_temp(rom))
4.7k のプルアップ抵抗をデータラインに接続してください。convert_temp()
メソッドは、温度をサンプリングするたびに呼び出す必要があることに注意してください。
DHT ドライバー¶
DHT ドライバーはソフトウェアで実装され、すべてのピンで動作します:
import dht
import machine
d = dht.DHT11(machine.Pin('D4'))
d.measure()
d.temperature() # 例: 23 (°C)
d.humidity() # 例: 41 (% RH)
d = dht.DHT22(machine.Pin('D4'))
d.measure()
d.temperature() # 例: 23.6 (°C)
d.humidity() # 例: 41.3 (% RH)
4.7k のプルアップ抵抗をデータラインに接続してください。DHT モジュールの中にはプルアップ抵抗が実装済みのものもあります
APA102 LED の駆動¶
一部の Adafruit ボードにある APA102 は SoftSPI で制御できます:
from machine import SoftSPI, Pin
# SPI オブジェクトを作成。miso は未使用のピンのどれでもよい。
spi=SoftSPI(sck=Pin('D25'), mosi=Pin('D26'), miso=Pin('D14'))
# プリアンブルとポストフィックスを持つデータを書き込むための# 小さな関数を定義
def write(red, green, blue):
spi.write(b"\x00\x00\x00\x00\xff")
spi.write(bytearray((blue, green, red)))
spi.write(b"\xff\xff\xff")
# LED を赤に設定
write(128, 0, 0)
SoftSPI では miso を未定義にできないため、miso を未使用のピンに割り当てる必要があります。
Neopixel LED の駆動¶
組込みの machine.bitstream() メソッドは、MicroPython ドライバーライブラリにあるNeopixel ドライバーと組み合わせて、NeoPixel LED の駆動をサポートします:
import neopixel
import machine
# Adafruit Feather ボードの Pin D8 に繋げられている 1 LED
p = machine.Pin(8, machine.Pin.OUT)
n = neopixel.NeoPixel(p, 1)
# LED を赤に設定
n[0] = (128, 0, 0)
# LED の表示を更新
n.write()
machine.bitstream() は、SAMD21 のクロック周波数 48MHz と SAMD51 のクロック周波数 120MHz を想定して設定されています。他のクロック周波数では、タイミングが合いません。
ファイル転送¶
mpremote ツールを使って、SAMD21/SAMD51 デバイスにファイルを転送できます。SAMD21/SAMD51 ボードにファイルを転送する方法として、コミュニティがサポートする代替手段(rshell や Thonny など)については MicroPython フォーラムを参照してください。