このページの目次
端子割り当て
TRYGEARシリーズの開発ボードは、機能や性能により、いくつかのメーカーのMCUを採用しています。このため、使用しているMCUが異なる開発ボードごとに端子の呼び名や配置が異なっています。このため、特段の配慮がない場合、同じ機能のプログラムでも開発ボードごとに使用する端子名が異なってしまい、同じ機能のプログラムでも異なる開発ボードで共通に利用できないという問題があります。
TRYGEARシリーズの開発ボードでは、機能や配置が共通する端子の名前を異なる開発ボードでも同じ名前で使用できるようにライブラリファイル trygear.py を提供しています。trygear.pyを開発ボードの/libフォルダに格納し、プログラムの先頭にimport trygearと記述して使用してください。
from microcontroller import pin
import os
# 実行環境の自動判定
try:
_sysname = os.uname().sysname
except:
_sysname = "unknown"
if "rp2350b" in _sysname:
# --- Viz (RP2350B) Pin Definitions ---
BOARD_NAME = "VIZ/RP2350B"
# Digital Pins (UNO Mapping)
D0, D1, D2, D3 = pin.GPIO1, pin.GPIO0, pin.GPIO2, pin.GPIO3
D4, D5, D6, D7 = pin.GPIO4, pin.GPIO5, pin.GPIO6, pin.GPIO7
D8, D9 = pin.GPIO22, pin.GPIO23
D10, D11, D12, D13 = pin.GPIO9, pin.GPIO11, pin.GPIO8, pin.GPIO10
# Analog Pins
A0, A1, A2, A3, A4, A5 = pin.GPIO40, pin.GPIO41, pin.GPIO42, pin.GPIO43, pin.GPIO46, pin.GPIO47
# Input Functions
SW1, SW2, SW3 = D29, D30, D31
# Output Functions
LED1 = D13 # SCK_S(GP13)と共用
LED2, LED2 = pin.GPIO32, pin.GPIO33
LED4 = pin.GPIO25
SRV1, SRV2 = LED2, LED3
RGB_LED = LED3
SPK = pin.GPIO26
# I2C Bus
SCL, SDA = pin.GPIO21, pin.GPIO20
SCL_A, SDA_A = A5, A4
# SPI Bus (Display: TFT_, Storage: SD_)
TFT_SCK, TFT_MOSI, TFT_MISO, TFT_CS = pin.GPIO38, pin.GPIO39, pin.GPIO36, pin.GPIO37
TFT_DC = TFT_MISO
SD_SCK, SD_MOSI, SD_MISO, SD_CS = D13, D11, D12, pin.GPIO24
# USB HOST
USBHP, USBHM = pin.GPIO34, pin.GPIO35
elif "ESP32S3" in _sysname:
# --- NET (ESP32-S3) Pin Definitions ---
BOARD_NAME = "NET/ESP32-S3"
# Digital Pins (UNO Mapping)
D0, D1, D2, D3 = pin.GPIO44, pin.GPIO43, pin.GPIO1, pin.GPIO2
D4, D5, D6, D7 = pin.GPIO3, pin.GPIO38, pin.GPIO39, pin.GPIO40
D8, D9 = pin.GPIO41, pin.GPIO42
D10, D11, D12, D13 = pin.GPIO10, pin.GPIO11, pin.GPIO13, pin.GPIO12
# Analog Pins
A0, A1, A2, A3 = pin.GPIO4, pin.GPIO5, pin.GPIO6, pin.GPIO7
A4, A5 = pin.GPIO8, pin.GPIO9
# Input Functions
SW1, SW2, SW3 = pin.GPIO1, pin.GPIO47, pin.GPIO48
SW5 = pin.GPIO0
# Output Functions
LED1 = D13 # SCK_S(IO13)と共用
LED2, LED3 = pin.GPIO45, pin.GPIO46
SRV1, SRV2 = LED2, LED3
RGB_LED = LED3
SPK = pin.GPIO21
# I2C Bus
SCL = pin.GPIO9 # A5と共用
SDA = pin.GPIO8 # A4と共用
# SPI Bus (Display: TFT_, Storage: SD_)
TFT_SCK, TFT_MOSI, TFT_MISO, TFT_CS = pin.GPIO15, pin.GPIO16, pin.GPIO17, pin.GPIO18
TFT_DC = TFT_MISO
SD_SCK, SD_MOSI, SD_MISO, SD_CS = D13, D11, D12, pin.GPIO16
# CAN Bus
CAN_TX = pin.GPIO48
CAN_RX = pin.GPIO47
elif ("rp2350a" in _sysname) or ("rp2040" in _sysname):
# --- DASH (RP2350A) Pin Definitions ---
BOARD_NAME = "DASH/RP2350A"
# Digital Pins (UNO Mapping)
D0, D1, D2, D3 = pin.GPIO1, pin.GPIO0, pin.GPIO2, pin.GPIO3
D4, D5, D6, D7 = pin.GPIO4, pin.GPIO5, pin.GPIO6, pin.GPIO7
D8, D9 = pin.GPIO8, pin.GPIO9
D10, D11, D12, D13 = pin.GPIO13, pin.GPIO11, pin.GPIO12, pin.GPIO10
# Analog Pins
A0, A1, A2, A3 = pin.GPIO26, pin.GPIO27, pin.GPIO28, pin.GPIO29
# Input Functions
SW1, SW2, SW3 = pin.GPIO14, pin.GPIO15, pin.GPIO22
# Output Functions
LED1 = D13 # SCK_S(GP13)と共用
LED2, LED3 = D0, D1
LED4 = pin.GPIO25
SRV1, SRV2 = LED2, LED3
RGB_LED = LED3
SPK = pin.GPIO23
# I2C Bus
SCL = pin.GPIO21 # A5と共用
SDA = pin.GPIO20 # S4と共用
# SPI Bus (Display: TFT_, Storage: SD_)
TFT_SCK, TFT_MOSI, TFT_MISO, TFT_CS = pin.GPIO18, pin.GPIO19, pin.GPIO16, pin.GPIO17
TFT_DC = TFT_MISO
SD_SCK_ SD_MOSI, SD_MISO, SD_CS = D13, D11, D12, pin.GPIO24
else:
BOARD_NAME = "Unknown microcontroller"LED
LEDの点灯
TRYGEARには3,4個のLEDが装備されており、LED1,LED2,LED3などの名前が付けられています。それらのLEDをCircuitPythonで操作する方法を示します。
CircuitPythonでは、一般的にはLEDが接続されている端子名(GP25)を使用して、制御用端子の指定や制御を行います。Raspberry Pi PICO用のCircuitPythonでは、'GP25'の他に'LED'の端子名がLEDに割り当てられているため、それを使用してLED用の端子を指定することができます。(もちろん従来通り、端子名(この場合はGP25)で指定することもできます。)
import trygear
import digitalio
import board
import time
led = digitalio.DigitalInOut(trygear.LED4) # board.GP25 でも可
led.direction = digitalio.Direction.OUTPUT
led.value = True
time.sleep(1) # 1秒待つ
led.value = Falseこのプログラムは、単純に1秒だけLEDを点灯させています。
LEDの点滅
LEDを一定間隔で点滅するプログラムを示します。
import trygear
import digitalio
import board
import time
led = digitalio.DigitalInOut(trygear.LED4)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(1) # 1秒待つ
led.value = False
time.sleep(1)LEDの明暗制御
LEDはPWMを使用して、単純に点灯、消灯だけでなく、明暗の度合いを制御できます。
PWMを使用してLEDの明暗を制御するプログラムを示します。
import trygear
import pwmio
import board
import time
led = pwmio.PWMOut(trygear.LED4, frequency = 1000)
delta = 100
duty = 0
while True:
duty += delta
if duty == 65500:
delta = -100
elif duty == 0:
delta = 100
led.duty_cycle = duty # 0-65535
time.sleep(0.002)LEDをPWMで制御するように初期化し、Whileループの中で、PWMのデューティー比を増減させて、LEDの明暗を変化させています。
スイッチ
スイッチによるLEDの点灯
スイッチを押したときにLEDが点灯し、スイッチを離したときにLEDが消灯するプログラムを以下に示します。
import trygear
import digitalio
import board
led = digitalio.DigitalInOut(trygear.LED4)
led.direction = digitalio.Direction.OUTPUT
sw1 = digitalio.DigitalInOut(trygear.SW1)
sw1.direction = digitalio.Direction.INPUT
while True:
led.value = not sw1.valueRP2040-SLIM-PLUSには、ユーザーがプログラムで使用できるスイッチ SW1, SW2が装備されており、それぞれGP8, GP28に接続されています。
RP2040-SLIM-PLUSのSW1は負論理となっており、スイッチが押されたときにFalseもしくは0、離されている時にTrueもしくは1となります。このプログラムでは、正論理のLEDを接続している場合のもので、負論理のスイッチの読み取り結果を 'not' を付けて正論理に変換してLEDの引数としています。
圧電スピーカー
明るく光るLEDは出力装置として魅力的ですが、音を出す圧電スピーカーも電子工作では外せませんね。圧電スピーカーは圧電素子を使ったスピーカーで、RP2040-SLIM-PLUSに搭載されているものは直径が1センチ程度の小さなものです。
RP2040-SLIMには、初期状態では搭載されていませんが、必要に応じて購入して適当な端子(出力端子)に接続して使用することができます。
異なる周波数の音の出力
周波数が100Hzから1000Hzまで、100Hzごとに周波数を上げて音を出力するプログラム例を示します。(実際に出力される音(の高さ)は、圧電スピーカーの特性によるのか、ちょっと違和感があります。)
RP2040-SLIM-PLUSの圧電スピーカーを使用する場合のプログラム例を示します。RP2040-SLIMで圧電スピーカーを使用する場合には、toneの引数として、圧電スピーカー接続した端子の端子名を指定してください。
import trygear
import simpleio
import board
for hz in range(100,1001,100): # 100Hz -1000Hz
simpleio.tone(trygear.SPK, hz, 0.5)RP2040-SLIM-PLUS用の圧電スピーカーはGP23に接続されています。
スイッチによる音の出力
スイッチを押すと音が鳴るプログラム例を示します。
import trygear
import digitalio
import board
import simpleio
sw1 = digitalio.DigitalInOut(trygear.SW1)
sw1.direction = digitalio.Direction.INPUT
while True:
if (sw1.value == 0): # スイッチが押されたとき
simpleio.tone(trygear.SPK, 400, 0.5)メロディーの出力
内臓タイマーを使用した音声出力例です。Arduinoでは、tone()関数の利用に相当します。音のPWM出力と書かれていることも多いのですが、基本的には周波数が重要でデューティーサイクルは問題ではないので、PWMというべきではないですね。
import trygear
import time
import board
from simpleio import tone
# 音符の周波数 (単位: Hz)
NOTES = {
"C4": 261,
"D4": 294,
"E4": 329,
"F4": 349,
"G4": 392,
"A4": 440,
"B4": 493,
"C5": 523,
"REST": 0 # 休符
}
# 「カエルの歌」の楽譜 (音符と長さの組み合わせ)
# 長さは秒単位で指定
SONG = [
("C4", 0.5), ("D4", 0.5), ("E4", 0.5), ("F4", 0.5),
("E4", 0.5), ("D4", 0.5), ("C4", 0.5), ("REST", 0.5),
("E4", 0.5), ("F4", 0.5), ("G4", 0.5), ("A4", 0.5),
("G4", 0.5), ("F4", 0.5), ("E4", 0.5), ("REST", 0.5)
]
print("カエルの歌を演奏します。")
# 楽譜を演奏
while True:
for note, length in SONG:
if NOTES[note] == 0: # 休符の場合
print(f"休符: {length}s")
time.sleep(length) # 秒単位の休符
else:
print(f"再生中: {note}, 長さ: {length}s")
tone(trygear.SPK, NOTES[note], length) # 周波数と長さを指定 (秒単位)
time.sleep(1) # 演奏間に1秒の休止TFTディスプレイ
import trygear
import board
import busio
import displayio
from fourwire import FourWire
import terminalio
from adafruit_st7789 import ST7789
from adafruit_display_text import label
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.rect import Rect
from adafruit_display_shapes.triangle import Triangle
# 以前のディスプレイリソースを解放
displayio.release_displays()
# SPIバスとピンの設定
spi = busio.SPI(clock=trygear.TFT_SCK, MOSI=trygear.TFT_MOSI)
cs_pin = trygear.TFT_CS # チップセレクトピン
dc_pin = trygear.TFT_DC # データ/コマンドピン
# ディスプレイの初期化(rowstart=80、rotation=270で画面を回転)
display_bus = FourWire(spi, command=dc_pin, chip_select=cs_pin)
display = ST7789(display_bus, width=240, height=240, rotation=0, rowstart=80)
# メインの表示グループを作成
main_group = displayio.Group()
# 背景を黒に設定
background = Rect(0, 0, 240, 240, fill=0x000000) # 全体を黒背景に設定
main_group.append(background)
# 図形の表示
# 円(黄色)
circle = Circle(180, 50, 30, fill=0xFFFF00) # 中心座標(180,50), 半径30
main_group.append(circle)
# 四角形(シアン)
rectangle = Rect(100, 120, 60, 60, fill=0x00FFFF) # 左上座標(100,120), 幅60, 高さ60
main_group.append(rectangle)
# 三角形(マゼンタ)
triangle = Triangle(40, 200, 80, 240, 0, 240, fill=0xFF00FF) # 三角形の3頂点を指定
main_group.append(triangle)
# 文字列の表示(文字サイズを2倍に設定)
text_microfan = label.Label(terminalio.FONT, text="MicroFan", color=0xFF0000, x=20, y=30, scale=2) # 赤文字
text_rp2040 = label.Label(terminalio.FONT, text="TRYGEAR-VIZ", color=0x00FF00, x=20, y=90, scale=2) # 緑文字
text_circuitpython = label.Label(terminalio.FONT, text="CircuitPython", color=0x0000FF, x=20, y=150, scale=2) # 青文字
main_group.append(text_microfan)
main_group.append(text_rp2040)
main_group.append(text_circuitpython)
# ディスプレイに描画
display.root_group = main_group
# 無限ループで画面を維持
while True:
passimport trygear
import board
import busio
import displayio
from fourwire import FourWire
from adafruit_st7789 import ST7789
displayio.release_displays()
# SPIバスとピンの設定
spi = busio.SPI(clock=trygear.TFT_SCK, MOSI=trygear.TFT_MOSI)
tft_cs = trygear.TFT_CS # チップセレクトピン
tft_dc = trygear.TFT_DC # データ/コマンドピン
display_bus = FourWire(spi, command=tft_dc, chip_select=tft_cs)
# display = ST7789(display_bus, width=320, height=170, colstart=35, rotation=90) # 1.9 inch 170x320
display = ST7789(display_bus, width=240, height=240, rowstart=80, rotation=0) # 1.54 inch 240x240
group = displayio.Group()
display.root_group = group
# ここまではグラフィックス利用の初期化で今後も共通
import simpleio
from adafruit_display_shapes.circle import Circle
class Ball(Circle):
# 初期座標、縦横速度、色を与える
def __init__(self, x0, y0, r, vx, vy, color):
super().__init__(x0, y0, r, fill=color, outline=0xFFFF00)
self.vx = vx
self.vy = vy
def tick(self):
# 縦横速度分移動して
self.x0 += self.vx
self.y0 += self.vy
# 画面の端に来たら速度を反転させて跳ね返る
if self.x0 <= self.r or self.x0 >= (display.width-1)-self.r:
simpleio.tone(board.GP26, 1000, 0.01)
self.vx = -self.vx
if self.y0 <= self.r or self.y0 >= (display.height-1)-self.r:
simpleio.tone(board.GP26, 500, 0.01)
self.vy = -self.vy
ball = Ball(100, 100, 10, 2, 5, 0x00FF00)
group.append(ball)
import time
while True:
group[0].tick()
time.sleep(0.02)
DVI出力
# 表示システムの初期化を行う
import displayio, picodvi, board, framebufferio
displayio.release_displays()
fb = picodvi.Framebuffer(
width=320, height=240, color_depth=8,
clk_dp=board.GP14, clk_dn=board.GP15,
red_dp=board.GP12, red_dn=board.GP13,
green_dp=board.GP18, green_dn=board.GP19,
blue_dp=board.GP16, blue_dn=board.GP17)
display = framebufferio.FramebufferDisplay(fb)
group = displayio.Group()
display.root_group = group
# 文字列の表示を行う
from adafruit_display_text import label
import terminalio
group.append(label.Label(terminalio.FONT, text="MicroFan", x=0, y=10, scale=2, color=0xFFFFFF))
group.append(label.Label(terminalio.FONT, text="TRYGEAR VIZ:PicoDVI", x=0, y=30, scale=2, color=0xFFFFFF))
# 図形の表示を行う
from adafruit_display_shapes.line import Line
from adafruit_display_shapes.rect import Rect
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.triangle import Triangle
group.append(Line(0, 80, 320, 80, 0xFF00FF))
group.append(Rect(0, 120, 100, 100, fill=0xFF0000, outline=0xFFFF00))
group.append(Circle(160, 170, 50, fill=0x00FF00, outline=0xFFFF00))
group.append(Triangle(260, 120, 210, 220, 310, 220, fill=0x0000FF, outline=0xFFFF00))
import displayio, picodvi, board, framebufferio
displayio.release_displays()
fb = picodvi.Framebuffer(
width=320, height=240, color_depth=8,
clk_dp=board.GP14, clk_dn=board.GP15, # 端子の配置はPICO-HDMI-PLUS用
red_dp=board.GP12, red_dn=board.GP13,
green_dp=board.GP18, green_dn=board.GP19,
blue_dp=board.GP16, blue_dn=board.GP17)
display = framebufferio.FramebufferDisplay(fb)
group = displayio.Group()
display.root_group = group
# ここまではグラフィックス利用の初期化で今後も共通
import simpleio
from adafruit_display_shapes.circle import Circle
class Ball(Circle):
# 初期座標、縦横速度、色を与える
def __init__(self, x0, y0, r, vx, vy, color):
super().__init__(x0, y0, r, fill=color, outline=0xFFFF00)
self.vx = vx
self.vy = vy
def tick(self):
# 縦横速度分移動して
self.x0 += self.vx
self.y0 += self.vy
# 画面の端に来たら速度を反転させて跳ね返る
if self.x0 <= self.r or self.x0 >= (display.width-1)-self.r:
simpleio.tone(board.GP26, 1000, 0.01)
self.vx = -self.vx
if self.y0 <= self.r or self.y0 >= (display.height-1)-self.r:
simpleio.tone(board.GP26, 500, 0.01)
self.vy = -self.vy
ball = Ball(100, 100, 10, 2, 5, 0x00FF00)
group.append(ball)
import time
while True:
group[0].tick()
time.sleep(0.02)OLEDディスプレイ
OLEDディスプレイ
OLEDディスプレイは、CN6に接続して使用します。
OLEDディスプレイを使用するためには、そのドライバーが必要ですが、マイクロファンのMicroPythonファームウェアには、あらかじめOLEDディスプレイ用のドライバーが内蔵されているので、そのインストール作業などを行うことなく利用することができます。
ここで使用例を示すssd1306の説明書を以下に示すので、参考にしてください。
OLEDディスプレイ表示用のドライバは、FrameBufferというクラスをベースに作成されています。したがって、OLEDディスプレイ表示用のドライバで使用できるメソッド(文字の表示やグラフィックス)の多くは、FrameBufferの説明書で確認することができます。以下にFrameBufferの説明書を示すので、参考にしてください。
OLEDディスプレイへの文字表示
コントローラにSSD1306を使用した0.96インチのOLEDディスプレイに文字列を表示するプログラム例を示します。
I2Cクラスの引数は、複数あるI2Cチャネルの番号を指定するだけで、具体的な端子などを指定する必要はありません。RP2040-SLIM(-PLUS)のCN6にOLEDディスプレイを接続する場合には、0番を指定します。
import board
import busio
import adafruit_ssd1306
i2c = busio.I2C(board.GP21, board.GP20)
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
oled.text('-TRYGEAR-VIZ-', 8, 0, True) # 第二引数は文字を出力する横のピクセル座標、第三引数は縦のピクセル座標
oled.text('MicroFan', 32, 8, True)
oled.text('OLED Display', 0, 16, True)
oled.text('Piezo Speaker', 0, 24, True)
oled.text('Brightness SNSR', 0, 32, True)
oled.text('Temp. Hum. SNSR ', 0, 40, True)
oled.text('Accelerometer', 0, 48, True)
oled.text('WS2812 RGB LED', 0, 56, True)
oled.show()ssd1306での文字出力は、文字を出力する座標を毎回指定する必要があります。グラフィックス表示と合わせて文字表示をする場合には役立ちますが、文字だけを出力する場合には、少々面倒です。
また、文字もグラフィックスも、表示の指示をしただけではOLEDディスプレイの画面に表示されず、show()メソッドを呼び出した時点で初めてすべての表示指示が画面に反映されます。
OLEDディスプレイへのグラフィックス表示
OLEDディスプレイにグラフィックス表示するプログラム例です。
import board
import busio
import adafruit_ssd1306
import time
i2c = busio.I2C(board.GP21, board.GP20)
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
oled.fill(0) # 画面のクリア
for y in range(0,64,8):
oled.line(0,0,127,y,1) # 斜線
oled.show()
for x in range(127,0,-8):
oled.line(0,0,x,63,1) # 斜線
oled.show()
time.sleep(0.5)
oled.fill(0) # 画面のクリア
for n in range(0,32,4):
oled.rect(64-n*2,32-n,n*4,n*2,1) # 方形
oled.show()
time.sleep(0.5)
oled.fill(0) # 画面のクリア
for n in range(0,32,2):
oled.fill_rect(64-n*2,32-n,n*4,n*2,1) # 塗潰し方形
oled.show()
time.sleep(0.5)
oled.fill(0) # 画面のクリア
for n in range(2,32,2):
# oled.ellipse(64,32,n*4,n*2,1) # 楕円
oled.circle(64,32,n*2,1)
oled.show()RCサーボ
カラーLED
WS2812カラーLED
RP2040-SLIMは1個のカラーLEDのみを実装しています。
RGB表示
3個のWS2812タイプのカラーLEDに赤、緑、青色を出力するプログラム例です。
各LEDの明るさは、0-255の範囲で指定できますが、LEDの点灯確認目的であれば、10程度の明るさ指定でも十分な明るさで発光します。
# Ws2812 カラーLEDの点灯
import board
import neopixel
rgb = neopixel.NeoPixel(board.GP24, 3)
rgb[0] = (10,0,0) # 赤
rgb[1] = (0,10,0) # 緑
rgb[2] = (0,0,10) # 青温度・湿度センサー
気温・湿度センサーAHT20と明るさセンサーは、RP2040-SLIMには装備されていません。
気温・湿度センサーAHT20のドライバーに関しては以下のページをご参照ください。
気温・湿度・明るさ表示
OLEDディスプレイに気温・湿度センサーAHT20で得られた気温と湿度、明るさセンサー(フォトトランジスタ)で得られた明るさを表示するプログラム例です。
AHT20はI2Cで接続されており、OLEDディスプレイと同じGP20,GP21にに接続されています。
明るさは、フォトトランジスタの出力電圧をAD変換で読み取って表示しています。明るさの範囲は0-1で、1に近い方が明るい状態を表します。
import board
import busio
import analogio
import microcontroller
import adafruit_ahtx0
import adafruit_ssd1306
import time
i2c = busio.I2C(board.GP21, board.GP20)
aht20 = adafruit_ahtx0.AHTx0(i2c)
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
brt = analogio.AnalogIn(board.A3)
while True:
oled.fill(0)
oled.text('CORE TEMP: {:.1f}\''.format(microcontroller.cpu.temperature),0,0,True)
oled.text('TEMP: {:.1f}\''.format(aht20.temperature),0,16,True)
oled.text('HUM: {:.1f}%'.format(aht20.relative_humidity),0,32,True)
oled.text('BRT: {:.3f}'.format(brt.value/65535),0,48,True)
oled.show()
time.sleep(0.1)