専用ファームウェア

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

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

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


LEDとスイッチ

LEDの点灯

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

from machine import Pin
import time

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

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

マイクロファンはいくつかのESP32開発ボードを提供しており、開発ボードによって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'という機能名が割り当てられているため、その機能名で端子を指定することができます。

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


圧電スピーカー

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

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

異なる周波数の音の出力

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

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

from tone import TONE
import time

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

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') # 端子番号の23でもよい
sw1=Pin('SW1', Pin.IN) # 端子番号の0でもよい

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サーボのドライバの詳細は以下のページをご参照ください。

ESP32-ROBOでは、RCサーボをS1-S3に4個づつ12個接続して制御することができます。

RCサーボを制御するGPIO端子の番号は不連続で分かりにくいのですが、コネクタ端子の位置の順番に、SRV1-SRV12の機能名が付けられており、機能名で指定すれば簡単に指定できます。

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

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

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

from machine import Pin
from rcservo import RCServo
import time

sv0=RCServo('SRV1')

sw1=Pin('SW1', Pin.IN)
sw3=Pin('SW3', Pin.IN)

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

12個のRCサーボの有効化

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

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

from machine import Pin
from rcservo import RCServo
import time

servo = []

sw1=Pin('SW1', Pin.IN)
sw3=Pin('SW3', 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 (sw3.value() == 0):
        servo[0].pos(80)
    else:
        servo[0].pos(0)
    time.sleep_ms(100)

DCモーター

DCモーターのドライバの詳細は以下のページをご参照ください。

DCMotorの使用例

DCMotorの使用例を示します。DCモーターの回転速度を変えながら、正転と逆転を繰り返すプログラム例です。

from dcmotor import DCMotor
import time

ma = DCMotor('MA1', 'MA2') # もう一つの回路として、MB1, MB2を使用できます。

v = 0
delta = 1
while True:
    if v >= 100:
        delta = -1
    if v <= -100:
        delta = 1
    v = v + delta
    ma.speed(v)
    time.sleep_ms(20)

上記の例では1回路のみの操作ですが、RP2040-ROBOでは2回路のHブリッジを操作できるので、例えば車の両輪をそれぞれ異なるモーターで操作することができます。