MicroPythonのマイクロファン専用ファームウェア

ドライバとライブラリ

MicroPythonで入出力装置やセンサーを使用したプログラミングを行う際には、一般的に、あらかじめそれらを制御するドライバーやライブラリを開発ボードに組み込んでおく必要があります。このため、使用する入出力装置やセンサーに対応した適切なドライバーやライブラリを探して取得し、さらに開発ボードのファイルシステムに登録しておくことは、特に初心者にとっては面倒な作業になります。

マイクロファンは、このような面倒な準備作業を軽減できるように、マイクロファンの開発ボード専用のMicroPythonファームウェアを配布しています。このファームウェアには、マイクロファンの開発ボードで標準的に使用する入出力装置やセンサーなどのドライバーやライブラリがあらかじめ組み込まれており、開発ボードに専用ファームウェアを書き込めば、その開発ボードで使用する様々な入出力装置やセンサーを使用したプログラムをすぐに開発することができるようになります。

専用ファームウェアの取得

マイクロファンの専用ファームウェアは以下のページから取得できるので、マイクロファンの開発ボードに書き込んでご利用ください。下記のページには、ドライバーやライブラリの組込み以外のマイクロファンの専用ファームウェアの追加機能なども記載されているのでご確認ください。

ファームウェアの書き込み

マイクロファン専用ファームウェアの開発ボードへの書き込みは、オリジナルのファームウェアの書き込み同様に行うことができます。

具体的には、BOOTボタンを押した状態で、開発ボードをUSBケーブルでPCに接続します。そうすると、開発ボードはPCによってUSBディスクとして認識され、ディスクの中身を示すファイルエクスプローラーのウィンドウが開きます。

このウィンドウに専用ファームウェアのファイルをドラッグアンドドロップすることにより、開発ボードへのファームウェアの書き込みを行うことができます。


MicroPythonプログラミング

以下に、専用ファームウェアを書き込んだ開発ボードの使用法を説明します。専用ファームウェアの固有機能を使っている部分があるので、MicroPythonのオリジナルのファームウェアを書き込んだ開発ボードではここで示す方法では利用できないことがあります。

ここでのプログラム例のいくつかは、RP2040-ROBOにOLEDディスプレイが接続されていることを前提にしています。

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


LED

LEDの点灯

RP2040を使用したPICOのMicroPythonでは、LEDが接続されている端子番号を使用して、制御用端子の指定や制御を行います。マイクロファンのRP2040-ROBO用ファームウェアでは、LED1の制御用の端子25に、’LED’, ‘LED1’という機能名が付けられており、端子番号ではなく機能名で指定することができます。もちろん従来通り、端子番号(この場合は25)で指定することもできます。

from machine import Pin
import time

led1 = Pin('LED1', Pin.OUT) # 25でもよい
led1.on()
time.sleep_ms(1000) # 1000ms, 1秒待つ
led1.off()

このプログラムは、単純に1秒ごとにLEDのON, OFFを行っています。

マイクロファンはいくつかのRP2040開発ボードを提供しており、開発ボードによってLEDが接続されている端子番号が異なります。このため、LEDの操作をしようとすると、LEDの端子番号を確認したり、プログラムを他の開発ボードに移植しようとすると、端子番号を変更する必要があります。

しかしながら、マイクロファンのMicroPythonファームウェアでは、このように機能名でLEDを指定できるので、端子番号を調べたり、移植の際に端子番号を変更したりする必要がありません。

LEDの点滅

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

from machine import Pin
import time

led1 = Pin('LED1', Pin.OUT)
while True:
    led1.on()
    time.sleep_ms(1000) # 1000ms, 1秒待つ
    led1.off()
    time.sleep_ms(1000)

# CTRL-Cで中断

LEDの明暗制御

LEDはPWMを使用して、単純に点灯、消灯だけでなく、明暗の度合いを制御できます。

PWMを使用してLEDの明暗を制御するプログラムを示します。

from machine import Pin, PWM
import time

led1 = PWM(Pin('LED1'), freq=1000)

delta = 100
duty = 0
while True:
    duty += delta
    if duty == 65500:
        delta = -100
    elif duty == 0:
        delta = 100
    led1.duty_u16(duty) # 0-65535
    time.sleep_ms(2)

# CTRL-Cで中断

LEDをPWMで制御するように初期化し、Whileループの中で、PWMのデューティー比を増減させて、LEDの明暗を変化させています。


スイッチ

スイッチによるLEDの点灯

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

from machine import Pin

led1 = Pin('LED1', Pin.OUT)
sw1 = Pin('SW1', Pin.IN)
while True:
    led1.value(not sw1.value())

# CTRL-Cで中断

スイッチもLEDと同様に、端子番号で指定・制御することができますが、マイクロファンのファームウェアでは、SW1に’SW1’という機能名が割り当てられているため、その機能名で端子を指定することができます。

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


圧電スピーカー

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

圧電スピーカーを操作するTONEドライバーは、マイクロファンのファームウェアにあらかじめ組み込まれているため、改めて導入する必要などはありません。

異なる周波数の音の出力

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

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

from tone import TONE
import time

snd = TONE('SND') # 端子番号の11でもよい

for hz in range(100,1001,100): # 100Hz -1000Hz
    snd.on(hz)
    time.sleep_ms(500)
    
snd.off()

スイッチによる音の出力

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

from machine import Pin
from tone import TONE
import time

snd=TONE('SND') # 端子番号の11でもよい
sw1=Pin('SW1', Pin.IN) # 端子番号の22でもよい

while True:
    if (sw1.value() == 0): # スイッチが押されたとき
        snd.on(400)
    else:
        snd.off()
    time.sleep_ms(100)

# CTRL-Cで中断

カエルの歌

TONEでは、音の周波数だけでなく音名を指定することができます。

皆様ご存じカエルの歌です。お楽しみください。

以下のサイトの音符を利用させていただきました。

from tone import TONE
import time

snd=TONE('SND')

kaeru = [ 'ド4', 'レ4', 'ミ4', 'ファ4', 'ミ4', 'レ4', 'ド4', 'ド4',
'ミ4', 'ファ4', 'ソ4', 'ラ4', 'ソ4', 'ファ4', 'ミ4', 'ミ4',
'ド4', '休符', 'ド4', '休符', 'ド4', '休符', 'ド4', '休符', 
'ド4', 'レ4', 'ミ4', 'ファ4', 'ミ4', 'レ4', 'ド4', 'ド4']

for s in kaeru:
    snd.on(s)
    time.sleep_ms(400)

snd.off()

圧電スピーカーの周波数特性なのか、方形波の高調波成分のせいなのか、そもそも、周波数リストの数値誤りなのか、ちょっと違う感じもありますが、楽しめましたか?

それから、音符の長さを一定にしている都合で、あからさまに表現が異なるところがありますがご容赦ください。:-P


RCサーボ

マイクロファンのRCサーボドライバを対象にRCサーボの制御法を説明します。

RCサーボのドライバの詳細は以下のページをご参照ください。

RP2040-ROBOでは、RCサーボをD0-D9に10個接続して制御することができます。RCサーボの信号線には、コネクタ端子の位置の順番に、SRV1-SRV10の機能名が付けられており、機能名で指定すれば簡単に指定できます。

RCサーボのコネクタの基板の外側がGNDで内側が制御信号になるので、コネクタの接続を間違えないように注意してください。

D10はD11に接続されている圧電スピーカーと同じタイマーをPWM制御に使用するため、RCサーボの制御には使用できません。

1つのRCサーボの有効化と回転

1つのRCサーボを有効化し回転させるプログラム例を示します。

from machine import Pin
from rcservo import RCServo
import time

sv0=RCServo('SRV1')

sw1=Pin('SW1', Pin.IN)
sw2=Pin('SW2', Pin.IN)

while True:
    if (sw1.value() == 0):
        sv0.pos(-80)
    elif (sw2.value() == 0):
        sv0.pos(80)
    else:
        sv0.pos(0)
    time.sleep_ms(100)

10個のRCサーボの有効化

SRV1-SRV10の10個のサーボをすべて初期化する方法を示します。

下記の方法では、SRV1-SRV10をservo[0]-servo[9]で操作することができます。

from machine import Pin
from rcservo import RCServo
import time

servo = []

sw1=Pin('SW1', Pin.IN)
sw2=Pin('SW2', Pin.IN)

for i in range(1,13):
    servo.append(RCServo('SRV'+str(i)))
    
while True:
    if (sw1.value() == 0):
        servo[0].pos(-80)
    elif (sw2.value() == 0):
        servo[0].pos(80)
    else:
        servo[0].pos(0)
    time.sleep_ms(100)

DCモーター

D12-D15あるいはMA1,MA2,MB1,MA2の4つの信号で制御


WS2812カラーLED

RGB表示

3個のWS2812タイプのカラーLEDに赤、緑、青色を出力するプログラム例です。

各LEDの明るさは、0-255の範囲で指定できますが、LEDの点灯確認目的であれば、10程度の明るさ指定でも十分な明るさで発光します。

# Ws2812 カラーLEDの点灯
from neopixel import NeoPixel
from machine import Pin

rgb = NeoPixel(Pin('RGB', Pin.OUT), 3)
rgb[0] = (10,0,0) # 赤
rgb[1] = (0,10,0) # 緑
rgb[2] = (0,0,10) # 青
rgb.write() # 全ピクセルにデータ書込み

neopixelライブラリの利用法は、以下のページをご参照ください。

1/fゆらぎを利用したLEDキャンドル

1/fゆらぎを利用して、1個のカラーLEDをキャンドルの様に光らせるプログラム例です。


加速度センサー

加速度センサーKXTJ3のドライバーに関しては以下のページをご参照ください。

3軸の傾きを3個のカラーLEDで表示

加速度センサーのKXTJ3ドライバーは、3軸の加速度の計測値をそれぞれ-32768-32767の範囲で返します。また、計測加速度の設定値は2-16Gで設定できますが、初期状態では2Gの設定になっています。加速度の方向は、X軸が基板の縦方向、Y軸が横方向、Z軸が上下方向になっています。

以下のプログラムでは、各軸に対応するカラーLEDが、各軸の加速度がほぼ0の場合に青、正の値だと大きいほど明るい赤、負の値だと絶対値が大きいほど明るい緑に光ります。

水平の机の上などに基板を置くと、X,Y軸に対応する1番目と2番目のカラーLEDが青色に光ります。

from machine import Pin, I2C
from kxtj3 import KXTJ3
from neopixel import NeoPixel
import time

i2c = I2C(0)
acc = KXTJ3(i2c)

rgb = NeoPixel(Pin('RGB', Pin.OUT), 3) # 3ピクセル用の NeoPixel ドライバーをRGB端子に設定

while True:
    vacc = acc.getXYZ()
    x = int(vacc[0] / 32768 * 255) # 最大変位量を255に
    y = int(vacc[1] / 32768 * 255)
    z = int(vacc[2] / 32768 * 255)
    if abs(x) < 10: # ほぼ水平
        rgb[0] = (0,0,100) # 青で表示
    elif x > 0:
        rgb[0] = (x,0,0) # 傾きに応じて赤で表示
    else:
        rgb[0] = (0,-x,0) # 傾きに応じて緑で表示
    if abs(y) < 10:
        rgb[1] = (0,0,100)
    elif y > 0:
        rgb[1] = (y,0,0)
    else:
        rgb[1] = (0,-y,0)
    if abs(z) < 10:
        rgb[2] = (0,0,100)
    elif z > 0:
        rgb[2] = (z,0,0)
    else:
        rgb[2] = (0,-z,0)
    rgb.write() # 全ピクセルにデータ書込み
    time.sleep_ms(100)

単純な計測

水平儀

計測値を使用したRCサーボの制御


温度、湿度センサー

単純な計測

計測値を使用したサーボの制御


明るさセンサー

BRT, ADC3,D29