CircuitPythonプログラミング

CircuitPythonの利用希望者がある程度いらっしゃるようなので、まずはRP2040を対象に、そのプログラミング情報を整備していきます。まだ整備の途中で記述に不備や不足が多数ありますが、ご容赦ください。ライブラリの体系がMicroPythonと結構異なってきているので、単純に同じPythonだろ。。。というわけにはいかないような印象です。

RP2040-SLIM(-PLUS)は基本部分がRaspberry Pi PICOとほぼ共通しているので、Raspbery Pi PICO用のCircuitPythonファームウェアを組み込んで利用することができます。以下にRaspberry Pi PICO用のCircuiPythonファームウェアのダウンロードページを示します。

以下に、Raspbery Pi PICO用のCircuitPythonファームウェアを書き込んだRP2040-SLIM(-PLUS)開発ボードの使用法を説明します。ここでのプログラム例の多くは、RP2040-SLIM(-PLUS)にOLEDディスプレイが接続されていることを前提にしています。また、センサー類や圧電スピーカーは、RP2040-SLIMには装備されていませんが、SENSOR-PLUSを接続することで、RP2040-SLIM-PLUSと同様に利用することができます。

以下にMicroPythonのプログラム例を示しますが、合わせてMicroPythonのサイトのRP2040用クイックリファレンスのページもご参照ください。


LED

LEDの点灯

RP2040-SLIM(-PLUS)開発ボードには、Raspberry Pi PICOと同じ端子GP25にLEDが接続されています。そのLEDをCircuitPythonで操作する方法を示します。

CircuitPythonでは、一般的にはLEDが接続されている端子名(GP25)を使用して、制御用端子の指定や制御を行います。Raspberry Pi PICO用のCircuitPythonでは、’GP25’の他に’LED’の端子名がLEDに割り当てられているため、それを使用してLED用の端子を指定することができます。(もちろん従来通り、端子名(この場合はGP25)で指定することもできます。)

import digitalio
import board
import time

led = digitalio.DigitalInOut(board.LED) # board.GP25 でも可
led.direction = digitalio.Direction.OUTPUT
led.value = True
time.sleep(1) # 1秒待つ
led.value = False

このプログラムは、単純に1秒だけLEDを点灯させています。

LEDの点滅

LEDを一定間隔で点滅するプログラムを示します。

import digitalio
import board
import time

led = digitalio.DigitalInOut(board.LED)
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 pwmio
import board
import time

led = pwmio.PWMOut(board.GP25, 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をPWMで制御するように初期化し、Whileループの中で、PWMのデューティー比を増減させて、LEDの明暗を変化させています。


スイッチ

アプリケーションで使用できるスイッチは、RP2040-SLIMには装備されていません。

スイッチによるLEDの点灯

スイッチを押したときにLEDが点灯し、スイッチを離したときにLEDが消灯するプログラムを以下に示します。

import digitalio
import board

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
sw1 = digitalio.DigitalInOut(board.GP8)
sw1.direction = digitalio.Direction.INPUT
while True:
    led.value = not sw1.value

RP2040-SLIM-PLUSには、ユーザーがプログラムで使用できるスイッチ SW1, SW2が装備されており、それぞれGP8, GP28に接続されています。

RP2040-SLIM-PLUSのSW1は負論理となっており、スイッチが押されたときにFalseもしくは0、離されている時にTrueもしくは1となります。このプログラムでは、正論理のLEDを接続している場合のもので、負論理のスイッチの読み取り結果を ‘not’ を付けて正論理に変換してLEDの引数としています。


圧電スピーカー

アプリケーションで使用できる圧電スピーカーは、RP2040-SLIMには装備されていません。

明るく光るLEDは出力装置として魅力的ですが、音を出す圧電スピーカーも電子工作では外せませんね。圧電スピーカーは圧電素子を使ったスピーカーで、RP2040-SLIM-PLUSに搭載されているものは直径が1センチ程度の小さなものです。

RP2040-SLIMには、初期状態では搭載されていませんが、必要に応じて購入して適当な端子(出力端子)に接続して使用することができます。

異なる周波数の音の出力

周波数が100Hzから1000Hzまで、100Hzごとに周波数を上げて音を出力するプログラム例を示します。(実際に出力される音(の高さ)は、圧電スピーカーの特性によるのか、ちょっと違和感があります。)

RP2040-SLIM-PLUSの圧電スピーカーを使用する場合のプログラム例を示します。RP2040-SLIMで圧電スピーカーを使用する場合には、toneの引数として、圧電スピーカー接続した端子の端子名を指定してください。

import simpleio
import board

for hz in range(100,1001,100): # 100Hz -1000Hz
    simpleio.tone(board.GP23, hz, 0.5)

RP2040-SLIM-PLUS用の圧電スピーカーはGP23に接続されています。

スイッチによる音の出力

スイッチを押すと音が鳴るプログラム例を示します。

import digitalio
import board
import simpleio

sw1 = digitalio.DigitalInOut(board.GP8)
sw1.direction = digitalio.Direction.INPUT

while True:
    if (sw1.value == 0): # スイッチが押されたとき
        simpleio.tone(board.GP23, 400, 0.5)


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('-RP2040-SLIM-', 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()

気温・湿度センサー

気温・湿度センサー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)

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) # 青