基礎 · 読了まで13分

MicroPythonとは?基本命令、REPL、最初のプログラム

MicroPythonとは何か、Pythonとの違いを解説します。REPL、machine.Pin、PWM、ADC、I2C、ticks_ms、main.py、Thonny、mpremote、mipの使い方と、Pico・ESP32への導入方法を紹介します。

MicroPythonは、マイコン向けにPython 3言語を小さく高速に再実装したものです。Raspberry Pi PicoやESP32などのボードにMicroPythonを書き込むと、ボードが単独でPythonコードを実行します。コンパイルの手順なしで命令を入力すると、すぐにLEDが点灯します。学校やパソコンでPythonを学んだことがあれば、同じ構文でピンの読み取り、モーターの駆動、センサーデータの収集、Wi-Fiへの接続ができます。

このガイドでは、MicroPythonと通常のPythonの違い、ボードとすぐにやり取りできるREPL、よく使うmachine.Pin、PWM、ADC、I2Cの各モジュールを、コード例とともに学びます。続いて、time.sleepとticks_msの違い、起動時に実行されるmain.pyとboot.py、Thonnyとmpremoteでのファイルの書き込み、mipによるライブラリの追加、PicoとESP32へのファームウェアの書き込みを説明します。最後に、MicroPythonとArduino C++を項目ごとに比較します。

MicroPythonを実行するRaspberry Pi Pico
Raspberry Pi Picoは、MicroPythonを最も簡単に始められるボードです。UF2ファイルをドラッグ&ドロップするだけで導入できます。

MicroPythonとは?Pythonとの違い

MicroPythonは、Damien Georgeが2013年に小型ボード向けに始めたオープンソースのプロジェクトで、現在では数十種類のマイコンに対応しています。ボードに書き込むファームウェアには、Pythonのインタプリタ、基本モジュール、小さなファイルシステムが含まれています。コードはまずボード上でバイトコードに変換され、そのバイトコードをインタプリタが順番に実行します。パソコンのPython全体を数百KBのRAMに収めることはできないため、言語自体は同じでも、ほとんどのライブラリは機能が縮小されるか、そもそも含まれていません。その代わりに、デスクトップ版Pythonにはない、ハードウェアに直接アクセスするためのmachineモジュールが追加されています。

項目Python(パソコン)MicroPython(ボード)
動作環境GB単位のRAMを持つパソコン数百KBのRAMを持つマイコン
標準ライブラリ非常に豊富:datetime、threading、urllibなど一部のみ:time、os、json、re、struct、random、mathなど
パッケージpipでnumpy、pandasなど数千種類を利用可能numpyやpandasはなし。mipでmicropython-libのパッケージを利用
ハードウェアへのアクセスなし。追加ライブラリが必要machineモジュール:Pin、PWM、ADC、I2C、SPI、UART、Timer
浮動小数点数64ビット(約15桁)PicoとESP32では32ビット(約7桁)
時刻と時間time.time(), datetime (標準Pythonの時刻関数)time.sleep_ms(), time.ticks_ms(), machine.RTC (MicroPythonの時刻関数)
プログラムの起動コマンドラインから実行する起動時にboot.pyとmain.pyが自動実行される

MicroPythonが動くボード

ボードファームウェアのファイルRAM容量補足
Raspberry Pi Pico (RP2040)RPI_PICO (.uf2)264 KB最も簡単に始められるボード
Raspberry Pi Pico WRPI_PICO_W (.uf2)264 KBWi-Fiにはnetworkモジュールを使用。通常のPico用ファームウェアではWi-Fiを使えない
Raspberry Pi Pico 2 (RP2350)RPI_PICO2 (.uf2)520 KBより高速でメモリも多い
ESP32 (WROOM)ESP32_GENERIC (.bin)520 KB(Wi-Fiが一部を使用)Wi-FiとBluetoothに対応。PSRAM搭載モデルはメモリが大幅に多い
ESP8266 (NodeMCU, Wemos D1 Mini)ESP8266_GENERIC (.bin)約80 KB動作するがメモリに余裕がない。新しいプロジェクトではESP32を選ぶ
Arduino Uno (ATmega328P)なし2 KBMicroPythonは動作しない。C++でプログラミングする

PicoとESP32にMicroPythonのファームウェアを書き込む

  1. Pico:ボードのBOOTSELボタンを押したままUSBケーブルを接続し、その後ボタンを離します。パソコンにRPI-RP2というドライブが表示されます(Pico 2ではRP2350)。
  2. MicroPythonの公式ダウンロードページから、ボードに合った.uf2ファイル(PicoはRPI_PICO、Pico WはRPI_PICO_W)をダウンロードし、そのドライブにドラッグします。
  3. コピーが終わるとボードが自動的に再起動し、ドライブが消えます。これでMicroPythonのインストールは完了です。Thonnyの「ツール」>「オプション」>「インタプリタ」で、MicroPython (Raspberry Pi Pico)を選びます。
  4. ESP32:パソコンにPythonがインストールされていれば、コマンドラインにpip install esptoolと入力します。ボードを接続し、ポートを確認します(例えばWindowsではCOM3、Linuxでは/dev/ttyUSB0)。
  5. まずフラッシュを消去します。コマンドはesptool.py --chip esp32 --port COM3 erase_flashです。ボードに接続できない場合は、コマンドの実行中にBOOTボタンを押し続けてください。
  6. ファームウェアを書き込みます。コマンドはesptool.py --chip esp32 --port COM3 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC-....binです。ESP32-S3とESP32-C3では、アドレスは0x0です。Thonnyの「MicroPythonをインストールまたは更新(esptool)」でも、ウィンドウから同じ操作ができます。
ファームウェアを書き込むと、Arduino IDEから書き込んだコードも含め、ボード内の古いプログラムやファイルが消去されます。逆に、MicroPythonが動いているボードにArduino IDEからコードを書き込むと、MicroPythonが消去されます。戻すにはファームウェアを再度書き込む必要があります。Picoのファイルシステムが破損したり、ボードが応答しなくなったりした場合は、公式のflash_nuke.uf2ファイルでフラッシュを完全に消去できます。Picoのピン配置と、画面ごとに説明した初期設定の手順は、Raspberry Pi Picoとは?に掲載しています。

REPL:ボードとその場でやり取りする

REPL(Read-Eval-Print Loop)は、ボードがシリアルポート経由で提供するコマンドラインです。Thonnyの下部にあるシェルウィンドウに表示される>>>プロンプトは、REPLが入力を待っていることを示します。1 + 1と入力するとボードが計算して2を返し、from machine import Pinに続けてPin("LED", Pin.OUT).value(1)と入力すると、その瞬間にPicoのLEDが点灯します。コンパイルや書き込みを待たずにセンサーの値を読んだり、ピンの配線が正しいか確かめたり、ライブラリの動作を調べたりするには、REPLが最も手早い方法です。

ショートカットまたは命令動作
Ctrl+C実行中のプログラムを停止し(KeyboardInterrupt)、REPLに戻る
Ctrl+Dソフトリセット。boot.pyとmain.pyを再実行する
Ctrl+E貼り付けモード。インデントを崩さずに長いコードを貼り付け、Ctrl+Dで実行する
Tab自動補完。machine.と入力してTabを押すと、モジュール内の項目を一覧表示する
help("modules")ファームウェア内のすべてのモジュールを一覧表示する
import gc; gc.mem_free()プログラムが使える空きRAMをバイト単位で表示する
import os; os.listdir()ボード上のファイルを一覧表示する

最初のプログラムとArduino C++での同等のコード

MicroPython
1# İlk program: dahili LED'i yakıp söndür / First program: blink the onboard LED
2from machine import Pin
3import time
4
5led = Pin("LED", Pin.OUT)        # Pico ve Pico W; ESP32'de Pin(2, Pin.OUT) / Pico and Pico W; Pin(2, Pin.OUT) on ESP32
6
7while True:
8    led.value(1)                 # yak / on
9    time.sleep(0.5)              # saniye cinsinden / in seconds
10    led.value(0)                 # söndür / off
11    time.sleep(0.5)
C++ (Arduino IDE)
1// Aynı program Arduino C++ ile / The same program in Arduino C++
2void setup() {
3  pinMode(LED_BUILTIN, OUTPUT);
4}
5
6void loop() {
7  digitalWrite(LED_BUILTIN, HIGH);
8  delay(500);                    // milisaniye cinsinden / in milliseconds
9  digitalWrite(LED_BUILTIN, LOW);
10  delay(500);
11}

2つのプログラムは同じ動作をしますが、構成が異なります。MicroPythonにはsetup()やloop()がありません。ファイルを上から下まで1回実行し、無限ループはwhile True:で自分で作ります。波かっこやセミコロンの代わりにインデントを使い、ループ内の各行は同じ幅(通常はスペース4個)だけ字下げする必要があります。待ち時間の単位も異なります。time.sleep(0.5)は秒単位、Arduinoのdelay(500)はミリ秒単位です。MicroPythonでは、ミリ秒にはtime.sleep_ms()、マイクロ秒にはtime.sleep_us()を使います。Arduino側の基本は、Arduinoプログラミングの基本で説明しています。

machine.Pin:デジタル入出力

MicroPythonArduino C++での同等のコード説明
led = Pin(15, Pin.OUT)pinMode(15, OUTPUT)ピンを出力に設定する
led.value(1)またはled.on()digitalWrite(15, HIGH)ピンをHIGHにする。value(0)またはoff()でLOWにする
buton = Pin(14, Pin.IN, Pin.PULL_UP)pinMode(14, INPUT_PULLUP)内部プルアップ抵抗を有効にした入力
buton.value()digitalRead(14)0または1を返す
led.toggle()digitalWrite(15, !digitalRead(15))状態を反転する。Picoで使用可能。ESP32ではvalue(not led.value())を使う
buton.irq(trigger=Pin.IRQ_FALLING, handler=f) (MicroPythonの割り込み設定)attachInterrupt(..., f, FALLING)ピンの状態が変わると関数fを呼び出す

time.sleepとticks_ms:処理を止めずに時間を測る

time.sleep()はボードの処理を完全に待機させます。その間はボタンの読み取りもセンサーの確認も行われません。複数の処理を並行して進めるには、Arduinoのmillis()と同じ考え方をMicroPythonでも使います。time.ticks_ms()で起動からのミリ秒数を取得し、time.ticks_diff(new, old)で2つの時点の差を計算します。単純な引き算ではなく、ticks_diffで差を求めることが重要です。カウンターは一定の値に達すると折り返すため、その時点で単純に引き算すると結果が正しくなくなります。下のコードは処理を止めずにLEDを点滅させながら、割り込み(IRQ)でボタン入力を監視します。押すたびに点滅速度が変わります。

MicroPython
1# delay kullanmadan iki iş: LED yanıp söner, buton kesmeyle modu değiştirir
2# Two jobs without blocking: the LED blinks, a button interrupt switches the mode
3from machine import Pin
4import time
5
6led = Pin(15, Pin.OUT)                       # LED + 220 Ω, GP15
7buton = Pin(14, Pin.IN, Pin.PULL_UP)         # buton GP14 ile GND arasında / button between GP14 and GND
8
9hizli = False
10son_basma = 0
11son_degisim = time.ticks_ms()
12
13def buton_kesme(pin):                        # kesme fonksiyonu kısa olmalı / keep the handler short
14    global hizli, son_basma
15    simdi = time.ticks_ms()
16    if time.ticks_diff(simdi, son_basma) > 200:   # 200 ms debounce / 200 ms debounce
17        son_basma = simdi
18        hizli = not hizli
19
20buton.irq(trigger=Pin.IRQ_FALLING, handler=buton_kesme)   # basınca HIGH'dan LOW'a iner / goes HIGH to LOW when pressed
21
22while True:
23    aralik = 100 if hizli else 500
24    if time.ticks_diff(time.ticks_ms(), son_degisim) >= aralik:   # taşmaya karşı güvenli / safe against wrap-around
25        son_degisim = time.ticks_ms()
26        led.value(not led.value())
27    # burada başka işler yapılabilir / other work can run here
割り込みハンドラは短くしてください。フラグを切り替えるかタイムスタンプを記録するだけにし、時間のかかる処理はメインループに任せます。割り込み内で変更する変数は、関数の先頭でglobalを宣言するのを忘れないでください。宣言しないと、Pythonは関数内に同じ名前の新しいローカル変数を作るため、メインループには変更が伝わりません。同じ考え方をArduinoで使う方法は、millis()とdelay()の違いで説明しています。

PWM:明るさ、サーボ、音

MicroPython
1# PWM: LED parlaklığı ve servo açısı / PWM: LED brightness and servo angle
2from machine import Pin, PWM
3import time
4
5led = PWM(Pin(15))
6led.freq(1000)                               # 1 kHz: titreme görünmez / no visible flicker
7
8for d in range(0, 65536, 2048):              # duty_u16: 0 (kapalı) ... 65535 (tam) / 0 (off) ... 65535 (full)
9    led.duty_u16(d)
10    time.sleep_ms(20)
11led.duty_u16(0)
12
13servo = PWM(Pin(16))
14servo.freq(50)                               # servolar 50 Hz (20 ms) ister / servos expect 50 Hz (20 ms)
15
16def servo_aci(derece):
17    us = 500 + derece * 2000 // 180          # 0° = 0,5 ms, 180° = 2,5 ms; servona göre ayarla / tune for your servo
18    servo.duty_ns(us * 1000)
19
20for a in (0, 90, 180, 90):
21    servo_aci(a)
22    time.sleep(1)

PWMオブジェクトはピンを非常に高速にオン・オフし、平均電力を調整します。freq()で1秒あたりの繰り返し回数を設定し、duty_u16()でオンになっている時間の割合を0〜65535の値で設定します。32768は約50%を意味します。この範囲では、ArduinoのanalogWriteの0〜255よりもはるかに細かく調整できます。サーボは50 Hzの信号と0.5〜2.5 msのパルス幅を必要とします。duty_ns()ならパルス幅をナノ秒単位で直接指定できるため、サーボのコードを大幅に簡単にできます。パッシブブザーに異なるfreq()の値を与えれば、音階も鳴らせます。デューティ比と周波数の詳しい説明は、PWMとは?を参照してください。

ADC:アナログ値の読み取り

MicroPython
1# ADC: potansiyometre ve Pico'nun dahili sıcaklık sensörü
2# ADC: a potentiometer and the Pico's internal temperature sensor
3from machine import ADC, Pin
4import time
5
6pot = ADC(Pin(26))                           # GP26 = ADC0; ESP32'de ADC(Pin(34)) / ADC(Pin(34)) on ESP32
7yonga = ADC(4)                               # 4. kanal: dahili sıcaklık / channel 4: internal temperature
8
9def ortalama(adc, n=16):                     # gürültüyü azalt / reduce noise
10    toplam = 0
11    for _ in range(n):
12        toplam += adc.read_u16()
13    return toplam // n
14
15while True:
16    ham = ortalama(pot)                      # 0-65535 (12 bit ölçüm 16 bite ölçeklenir) / 12-bit reading scaled to 16 bits
17    volt = ham * 3.3 / 65535
18    v_t = ortalama(yonga) * 3.3 / 65535
19    derece = 27 - (v_t - 0.706) / 0.001721   # RP2040 veri sayfasındaki formül / formula from the RP2040 datasheet
20    print("Pot: {} ({:.2f} V)  Yonga / chip: {:.1f} C".format(ham, volt, derece))
21    time.sleep(1)

read_u16()はどのボードでも0〜65535の値を返すため、同じコードをPicoとESP32で使えます。PicoのADCは実際には12ビットで、読み取り値を16ビットに拡大しています。Picoで外部から使えるアナログピンは、GP26(ADC0)、GP27(ADC1)、GP28(ADC2)の3本です。4番目のチャンネルはチップ内部の温度センサーで、室温ではなくチップの温度を測ります。ESP32で0〜3.3 Vの全範囲を読むには、adc.atten(ADC.ATTN_11DB)が必要です。また、Wi-Fi使用中はADC2のピンが使えないため、GPIO 32〜39のADC1のピンを選んでください。コード内で16回の測定値を平均すると、ADCのノイズを目に見えて減らせます。分解能や基準電圧などの考え方は、ADCとは?で説明しています。

I2C:センサーやディスプレイを接続する

MicroPython
1# I2C: hattı tara ve SSD1306 OLED'e yaz / I2C: scan the bus and write to an SSD1306 OLED
2from machine import Pin, I2C
3import ssd1306                               # önce: mpremote mip install ssd1306 / first: mpremote mip install ssd1306
4
5i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)   # Pico; ESP32'de I2C(0, sda=Pin(21), scl=Pin(22))
6adresler = i2c.scan()
7print("Bulunan / found:", [hex(a) for a in adresler])   # OLED genelde 0x3c / OLED is usually 0x3c
8
9if 0x3C in adresler:
10    oled = ssd1306.SSD1306_I2C(128, 64, i2c)
11    oled.fill(0)
12    oled.text("MicroPython", 0, 0)
13    oled.text("I2C: " + hex(adresler[0]), 0, 16)
14    oled.show()

I2C(0, sda=..., scl=...)は、選んだピンでハードウェアI2Cユニットを起動します。scan()は、バス上で応答したすべてのデバイスのアドレスをリストで返します。センサーが動かないときは、まずこのスキャンを行ってください。リストが空なら配線に問題があり、予想と違うアドレスが見つかったらコード内のアドレスを修正します。Picoでは、各I2Cユニットに使えるピンが決まっています。例えばI2C0ではGP0-GP1、GP4-GP5、GP8-GP9の組み合わせが使え、間違った組み合わせを選ぶとValueErrorになります。ESP32では、ほぼどのピンにもI2Cを割り当てられます。ディスプレイの詳細はOLEDディスプレイ、通信方式自体はI2Cとは?で説明しています。

main.pyとboot.py:起動時に実行されるコード

Thonnyで「実行」を押しただけでは、コードはボードに保存されず、その場で実行されるだけです。USBを抜くと失われます。ボードの起動時に毎回自動で実行するには、ファイルをボード上にmain.pyという名前で保存する必要があります。起動時はboot.pyが先に実行され、続いてmain.pyが実行されます。boot.pyはWi-Fiへの接続や時計の設定など、最初に1回だけ行う準備のためのファイルです。ESP32のファームウェアは自動的にこのファイルを作りますが、Picoには通常存在しません。実際のプログラムは常にmain.pyに記述します。別のファイルに書いた関数はimportでmain.pyに読み込めます。また、open()で測定値をボードのファイルシステムに保存できます。

MicroPython
1# main.py: kart her açıldığında otomatik çalışır / runs automatically every time the board starts
2import time
3from machine import Pin
4
5time.sleep(3)                                # Ctrl+C ile durdurmak için güvenlik payı / a safety window for Ctrl+C
6led = Pin("LED", Pin.OUT)
7sayac = 0
8
9try:
10    while True:
11        sayac += 1
12        led.value(sayac % 2)
13        print("Calisiyor / running", sayac)
14        time.sleep(1)
15except KeyboardInterrupt:                    # Thonny'de Stop ya da Ctrl+C / Stop in Thonny or Ctrl+C
16    led.value(0)
17    print("Durduruldu / stopped")
main.pyに待ち時間がまったくない無限ループがあると、Thonnyがボードに接続できず、Device is busy or does not respond(デバイスが使用中、または応答しません)と表示することがあります。まずThonnyの「停止」ボタンを数回押すか、シェルでCtrl+Cを試してください。それでもだめなら、PicoをBOOTSELで起動してflash_nuke.uf2で消去するか、ESP32のフラッシュを消去してファームウェアを書き直す必要があります。コードにある起動時の3秒間の待ち時間は、こうした状態になる前にプログラムを停止する時間を確保するためのものです。

ファイルの書き込み:Thonnyとmpremote

初めてならThonnyが最も簡単です。コードを書き、「ファイル」>「名前を付けて保存」を選びます。開いたウィンドウでRaspberry Pi PicoまたはMicroPythonデバイスを選び、ファイル名をmain.pyにします。「表示」>「ファイル」を開くと、パソコンとボードのファイルを並べて表示でき、右クリックで一方からもう一方へコピーできます。コマンドラインを好み、VS Codeなどのエディターを使う場合は、公式ツールのmpremoteが使えます。pip install mpremoteでインストールすると、最初に見つかったMicroPythonボードに自動接続します。

mpremoteの命令動作
mpremote最初に見つかったボードに接続し、REPLを開く(終了はCtrl+X)
mpremote lsボード上のファイルを一覧表示する
mpremote cp main.py :main.py (ファイルをボードへコピーするコマンド)パソコンからボードにファイルをコピーする。コロン(:)はボードを表す
mpremote run test.py (ファイルを実行するコマンド)ボードに保存せずにファイルを実行し、出力を表示する
mpremote mip install ssd1306 (ライブラリをインストールするコマンド)パソコンのインターネット接続でライブラリをダウンロードし、ボードの/libフォルダーにインストールする
mpremote resetボードを再起動する
mpremote connect COM3 ls指定したポートのボードに接続する(macOSやLinuxでは/dev/ttyACM0など)

ライブラリの追加:mip

MicroPythonにはpipがなく、代わりに小さなパッケージマネージャのmipを使います。Pico WやESP32のようにインターネットに接続できるボードでは、まずWi-Fiに接続し、REPLにimport mip、続いてmip.install("ssd1306")と入力します。公式のmicropython-libリポジトリからパッケージがダウンロードされ、ボードの/libフォルダーに配置されます。mip.install("github:user/repo")でGitHubからドライバをインストールすることもできます。Wi-FiのないPicoでは、パソコンからmpremote mip install命令か、Thonnyの「ツール」>「パッケージを管理」メニューで同じ操作を行います。単一ファイルのドライバ(例えばセンサー用に書かれた.pyファイル)をボードにコピーする方法も使えます。ルートまたは/libにファイルがあれば、importで読み込めます。Wi-Fiへの接続手順は、Pico WのWi-Fiで説明しています。

MicroPythonとArduino C++、どちらを選ぶ?

項目MicroPythonArduino C++
言語Python 3の構文C++とArduinoコア
実行方法ボード上のインタプリタがバイトコードを実行パソコンで機械語にコンパイル
変更から実行までの時間REPLなら即座に実行。保存は1〜2秒変更のたびにコンパイルと書き込みが必要で、10〜60秒
速度純粋なPythonのループは約10〜100倍遅いネイティブの実行速度
タイミングの精度ガベージコレクターにより、ときどき短い停止が発生マイクロ秒単位まで予測可能
ファイルシステムあり。main.py、データ、設定ファイルを保存なし。EEPROMまたは追加ライブラリが必要
ライブラリmicropython-libとコミュニティ製ドライバ豊富なArduinoライブラリの環境
対応ボードPico, ESP32, ESP8266Uno、Nano、Megaを含むほぼすべて
エラーメッセージ実行時に行番号付きで分かりやすいメッセージを表示コンパイルエラーを表示。実行時はSerial.printで動作を追う
得意な用途学習、手早い実験、Wi-Fi、データ処理精密なタイミング、メモリの少ないボード、豊富な既存ライブラリの活用

実際には、プロジェクトの内容で決まります。センサーを読んでWi-Fiでデータを送る、Webページを提供する、ディスプレイを動かすといった用途は、MicroPythonなら少ない行数で手早く実装できます。マイクロ秒の精度で信号を生成する、数百個のLEDを非常に高速に更新する、Unoのような小型ボードしか使えないといった場合は、C++が有利です。遅い関数は@micropython.nativeデコレーターで高速化できます。また、ループ内で新しいリストや文字列を作らないようにすると、ガベージコレクターによる停止を減らせます。ボード選びについては、ArduinoとESP32の違いは?も参照してください。

よくあるエラーと対処法

エラーまたは症状原因対処法
ImportError: no module named 'ssd1306'(ssd1306モジュールがない)ライブラリがボードにないmipかmpremote mipでインストールするか、.pyファイルをボードにコピーする
IndentationError(インデントのエラー)インデントが不統一で、スペースとタブが混在しているファイル全体でスペース4個に統一する。Thonnyでは自動的に調整される
OSError: [Errno 5] EIO (I2C)(I2Cの入出力エラー)デバイスが応答しない。配線、アドレス、電源に問題があるscan()でアドレスを確認し、SDAとSCLを確認する
ValueError: bad SCL pin(SCLピンの指定が不正)選んだピンが、そのI2Cユニットに対応していないPicoのピン配置から、I2C0またはI2C1の正しい組み合わせを選ぶ
Thonnyでは動くが、USBを抜くと動かないファイルをmain.pyとしてボードに保存していない「名前を付けて保存」で、ボードにmain.pyとして保存する
MemoryError: memory allocation failed(メモリの確保に失敗)大きなリスト、長い文字列、大容量のバッファによりRAMがいっぱいになっているデータを分割して処理し、gc.collect()を呼び出し、bytearrayを使う
Thonny:Device is busy or does not respond(デバイスが使用中、または応答しない)main.pyが待ち時間のないループを実行している、または別のプログラムがポートを使っている「停止」かCtrl+Cを使い、別のプログラムを閉じる。必要ならフラッシュを消去する

すでにPythonを知っているなら、MicroPythonはマイコンの世界への最短の入り口です。REPLでピンを試すとその場で結果が分かり、数行でセンサーの読み取りやWi-Fiへの接続ができます。基本モジュール、main.pyの役割、ticks_msを使った処理を止めない時間管理を学べば、プロジェクトをどんどん発展させられます。BlueGraysアプリには、LED、信号機、ボタン、PWMを使うRaspberry Pi Picoのプロジェクトがあり、手順ごとの配線図とMicroPythonコードを掲載しています。

よくある質問

MicroPythonとは何ですか?

MicroPythonは、マイコン向けに作られたPython 3言語の小型版です。ボードに書き込んだファームウェアによって、Raspberry Pi PicoやESP32などのボードがPythonコードを直接実行します。machineモジュールを使えば、ピン、PWM、ADC、I2Cにアクセスできます。

MicroPythonはPythonと同じですか?

構文は同じですが、MicroPythonはデスクトップ版Pythonの機能を絞ったものです。numpyやpandasのような大きなライブラリはなく、標準ライブラリも縮小されています。PicoとESP32では浮動小数点数が32ビットです。その代わり、ハードウェアに直接アクセスするためのmachineモジュールが追加されています。

MicroPythonとArduinoはどちらがよいですか?

目的によって異なります。学習、手早い実験、Wi-Fiでデータを送るプロジェクトにはMicroPythonが使いやすいです。Arduino C++は実行が速く、タイミングをより精密に制御でき、既存のライブラリもはるかに豊富です。PicoとESP32は、どちらの方法でもプログラミングできます。

Arduino UnoでMicroPythonは動きますか?

動きません。Arduino UnoのATmega328PチップにはRAMが2 KB、フラッシュが32 KBしかなく、MicroPythonのインタプリタが収まりません。MicroPythonを使うなら、Raspberry Pi PicoやESP32のような、より高性能なボードを選んでください。

MicroPythonにライブラリをインストールするには?

インターネットに接続したボードでは、REPLにimport mipとmip.install("package_name")を入力します。Wi-Fiのないボードでは、パソコンからmpremote mip install package_name命令かThonnyのパッケージマネージャで同じ操作を行います。単一ファイルのドライバをボードにコピーする方法も使えます。

Picoにコードを保存して電源を入れ直しても実行できるようにするには?

Thonnyの「ファイル」>「名前を付けて保存」でRaspberry Pi Picoを選び、ファイル名をmain.pyにします。ボードの起動時には毎回、まずboot.py、続いてmain.pyが自動実行されます。パソコンからUSBを抜いて別の5 V電源につないでも、プログラムは動きます。

全プロジェクトを見る
Raspberry Pi Picoの内蔵LEDを点滅(PicoとPico W)
#147初級

Raspberry Pi Picoの内蔵LEDを点滅(PicoとPico W)

Raspberry Pi Picoシリーズの最初のプロジェクトです!ボード上の緑色LEDを点滅させて動作を確認する、定番の「Hello World」に相当する実験です。外付け部品は不要で、PicoとUSBケーブルだけで始められます。コードはMicroPython(Raspberry Pi Foundationが公式にサポートする言語)で書きます。Thonny IDEでmachine.Pinクラス、Pin.OUTモード、led.on()/off()メソッド、time.sleep()を学びます。シリアル(REPL)出力で、切り替わる様子をリアルタイムに確認できます。

5.0(1)
10
Raspberry Pi Picoで外付けLEDを点灯(ブレッドボード)
#148初級

Raspberry Pi Picoで外付けLEDを点灯(ブレッドボード)

Picoの内蔵LEDの次は、ブレッドボードに外付けLEDを接続し、GP14ピンで制御します。このプロジェクトでは、Picoの汎用GPIOピンを出力として使う方法、LEDの極性(長い足=アノード/+、短い足=カソード/−)、電流制限抵抗(220Ω)が必要な理由を学びます。抵抗を入れないと、LEDに過大な電流が流れて壊れることがあります。回路はとても簡単です。Pico GP14 → 220Ω抵抗 → LED(+)→ LED(−)→ Pico GND。Wokwiでシミュレーションできます。

4.5(2)
7
Raspberry Pi Picoで2個のLEDを交互に点滅
#149初級

Raspberry Pi Picoで2個のLEDを交互に点滅

PicoでLEDを1個点滅させた次は、2個のLEDを交互に点滅させる定番のフリップフロップパターンです。一方が消えるともう一方が点灯する、複数のGPIOを連動させる最も基本的な例です。このプロジェクトでは、色の異なる2個のLED(GP14に赤、GP13に緑)が500msごとに点灯状態を入れ替えます。MicroPythonのPin.toggle()メソッドを使うと、コードを短く読みやすくできます。同じ基本的な仕組みが、信号機、パトカーの点滅灯、流れるLEDなど、複数のLEDを使ったアニメーションの基礎になります。回路はとても簡単で、各LEDに220Ωの抵抗を使います。

5.0(2)
19
Raspberry Pi Picoで信号機(3個のLEDを順に点灯)
#150初級

Raspberry Pi Picoで信号機(3個のLEDを順に点灯)

赤・黄・緑のLEDで本物の信号機を再現する、Picoシリーズ初の3個のLEDを使うプロジェクトです!緑が4秒間「進め」、黄が1.5秒間「準備」、赤が3秒間「止まれ」、赤と黄が1秒間「発進準備」を示します(ヨーロッパの信号機のパターン)。関数の定義(def all_off())、状態機械の仕組み(順序)、複数のGPIOの同期を学びます。回路はとても簡単です。GP11(緑)、GP12(黄)、GP13(赤)に3個のLEDを接続し、それぞれに220Ωの電流制限抵抗を使います。

4.0(1)
12
Raspberry Pi Picoでボタンを押してLEDを点灯
#155初級
プレミアム

Raspberry Pi Picoでボタンを押してLEDを点灯

Picoで初めての入力プロジェクト、ボタンの読み取りです!ボタンを押している間はLEDが点灯し、離すと消灯します。LEDアニメーションから一歩進んで、外部からPicoに信号を入力する方法を学びます。Pin.IN(入力モード)、Pin.PULL_UP(ボタンで一般的に使う内蔵プルアップ抵抗)、button.value()による読み取りを扱います。LEDはGP14、ボタンはGP2(内蔵PULL_UP)に接続します。押すとLOW(0)、離すとHIGH(1)になります。この逆の論理は最初は戸惑いますが、業界で標準的に使われています。

0.0(0)
11
Raspberry Pi Picoのボタンのチャタリング対策:IRQとソフトウェアポーリングの比較
#159中級
プレミアム

Raspberry Pi Picoのボタンのチャタリング対策:IRQとソフトウェアポーリングの比較

ボタンを1回押しただけで、コードでは3~4回と数えられますか?原因はチャタリングです。金属接点がマイクロ秒単位で振動します!シリアルモニタで、2つのカウント方法を並べて比較します。未処理のポーリングは振動も検出して多く数え、IRQとソフトウェアによるチャタリング対策は正確に数えます。接点が振動する仕組み、ソフトウェアによる対策(ticks_diff() > 50ms)、Pin.irq()による割り込みの登録、IRQ_FALLINGトリガー、ISRハンドラー、globalとISRの安全な扱い方を学びます。IRQでLEDを切り替え、動作を目で確認できます。シリアルモニタには押すたびに両方のカウントが表示されます。

0.0(0)
12
Raspberry Pi PicoのPWMでLEDをフェード(呼吸のような明滅)
#160初級

Raspberry Pi PicoのPWMでLEDをフェード(呼吸のような明滅)

LEDを単に点滅させるだけでなく、呼吸するように明滅させます!Raspberry Pi PicoのPWM(パルス幅変調)を使い、スリープ中のMacBookのランプのように、明るさをゆっくり上げてからゆっくり下げます。machine.PWMクラス、duty_u16()(0–65535の16ビットの明るさ)、PWM周波数(freq(1000)で1秒間に1000回オン・オフし、ちらつきを感じさせない)、range()による段階的なループ(増加と減少)、デジタルピンからのアナログのような出力を学びます。PWMはRGBの混色やモーターなどに使われる、組み込み開発の基本技術です。

0.0(0)
4
Raspberry Pi PicoでRGB LEDの色を順に切り替える(3チャンネルPWM)
#161初級

Raspberry Pi PicoでRGB LEDの色を順に切り替える(3チャンネルPWM)

1つのLEDで何百万もの色を表現できます!RGB LEDには、実は赤、緑、青の3つのLEDが入っています。それぞれをPicoの個別のPWMチャンネルで制御すると、赤+緑=黄、緑+青=シアン、3色すべて=白のように色を混ぜられます。このプロジェクトでは、LEDの色を8色に順番に切り替えます。複数のPWMチャンネル、関数の定義(def set_color(...))、RGBの混色(画面やスマート電球の仕組み)、8ビットから16ビットへの変換(x257で0–255を0–65535に変換)、LEDのカソードコモンとアノードコモンの違いを学びます。

0.0(0)
6