arrow_upward

2023年8月28日更新

MicroPython

MicroPythonはマイクロコントローラ(マイコン)上で動作するPythonと高い互換性があるプログラミング言語です。Raspberry Pi PicoやRaspberry Pi Pico Wなどのマイコンで利用できます。

Raspberry Pi Pico

英ラズベリーパイ財団が開発したマイコンボードで、デュアルARM Cortex-M0+プロセッサを搭載した独自開発のRP2040チップを持ちます。ボード上にある2MBフラッシュメモリ、26本のGPIOピン、オンボードLED、温度センサ、micro USBコネクタなどがそのまま利用できます。

Raspberry Pi Pico W

英ラズベリーパイ財団が開発したマイコンボードで、Raspberry Pi Picoと同等の機能を持ち、追加でインフィニオンCYW43439チップを搭載しているため、Wi-Fi機能が利用できます。

MicroPythonコードサンプル

オンボードLEDを点滅させる

Raspberry Pi PicoとRaspberry Pi Pico Wでは、ボード上の配線が異なるためオンボードLEDのGPIOピンの指定の仕方が異なります。また、GPIOピンの出力値を変更するメソッドは複数用意されています。

出力をHにするメソッド出力をLにするメソッド
Pin.on()Pin.off()
Pin.high()Pin.low()
Pin.value(1)Pin.value(0)
Raspberry Pi Pico用ソースコード
import machine
import time

led = machine.Pin(25, machine.Pin.OUT)

while True:
led.on()
time.sleep(0.5)
led.off()
time.sleep(0.5)
Raspberry Pi Pico W用ソースコード
import machine
import time

led = machine.Pin('LED', machine.Pin.OUT)

while True:
led.on()
time.sleep(0.5)
led.off()
time.sleep(0.5)

内蔵温度センサの値を読み取る

Raspberry Pi Pico用ソースコード
import machine
import time

sensor = machine.ADC(4)

while True:
temp = 27 - (sensor.read_u16() * 3.3 / 65535 - 0.706) / 0.001721

print(temp)
time.sleep(1)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

BOOTSELボタンの状態を読み取る

Raspberry Pi Pico用ソースコード
import time
import rp2

while True:
if rp2.bootsel_button() == 0:
while True:
if rp2.bootsel_button() == 1:
break

time.sleep(0.1)

print('pushed')
else:
while True:
if rp2.bootsel_button() == 0:
break

time.sleep(0.1)

print('released')
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

パルス幅変調(PWM)で制御する

Raspberry Pi Pico用ソースコード
import machine
import time

pwm = machine.PWM(machine.Pin(25))

pwm.freq(1000000)

while True:
for duty in range(4096):
pwm.duty_u16(duty * 16)
time.sleep_us(100)

for duty in range(4096):
pwm.duty_u16(65536 - (duty + 1) * 16)
time.sleep_us(100)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WのオンボードLEDはGPIOピンに接続されていないため、パルス幅変調(PWM)での制御ができません。別途GPIOピンにLEDなどの電子部品を接続すれば、Raspberry Pi Pico同様にパルス幅変調(PWM)で制御できます。

現在時刻を取得する

Raspberry Pi Pico用ソースコード
import machine
import time

rtc = machine.RTC()

while True:
print(rtc.datetime())
time.sleep(1)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

一定間隔で処理を実行する

Raspberry Pi Pico用ソースコード
import machine

timer = machine.Timer()

count = 0

def heartbeat(timer):
global count

if count > 1000:
print('heartbeat')

count = 0
else:
count += 1

timer.init(freq=1000, callback=heartbeat)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

一定時間経過後に処理を実行する

Raspberry Pi Pico用ソースコード
import machine
import time
import rp2

timer = machine.Timer()

def release(timer):
print('timeout')

while True:
if rp2.bootsel_button() == 0:
while True:
if rp2.bootsel_button() == 1:
break

time.sleep(0.1)

timer.init(mode=machine.Timer.ONE_SHOT, period=10000, callback=release)

print('pushed')
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

割込処理を実行する

割込処理はGPIOの状態変化に基づいて実行されます。そのため、別途GPIOピンにスイッチなどの電子部品を接続すれば利用できます。

Raspberry Pi Pico用ソースコード
import machine

button1 = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)
button2 = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_UP)

def push(pin):
if pin == button1:
print('falling')
elif pin == button2:
print('rising')

button1.irq(handler=push, trigger=machine.Pin.IRQ_FALLING)
button2.irq(handler=push, trigger=machine.Pin.IRQ_RISING)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

正常に動作していない場合にリセットする

Raspberry Pi Pico用ソースコード
import machine
import time

wdt = machine.WDT(timeout=2000)

print('reset')

while True:
wdt.feed()
print('fed')
time.sleep(1)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

ファイルを読み書きする

Raspberry Pi Pico用ソースコード
import os

buffer = ''

print('list:', os.listdir())

try:
file = open('data.txt', 'r')
buffer = file.read()
file.close()

print('before:', buffer)
except:
print('failed')

if buffer != '':
count = int(buffer) + 1
else:
count = 1

buffer = str(count)

try:
file = open('data.txt', 'w')
file.write(buffer)
file.close()

print('after:', buffer)
except:
print('failed')
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

スレッドで並列処理する

Raspberry Pi Pico用ソースコード
import _thread
import time

def ping(core, num, delay):
print('core%d start' % core)

for i in range(num):
print('core%d ping' % core)
time.sleep(delay)

print('core%d done' % core)

_thread.start_new_thread(ping, (1, 8, 0.75))

time.sleep(0.1)

ping(0, 5, 1.25)
Raspberry Pi Pico W用ソースコード

Raspberry Pi Pico WはRaspberry Pi Picoと同様のコードで動作します。

ネットワーク経由で時刻同期する

Raspberry Pi Pico用ソースコード

Raspberry Pi PicoはWi-Fi機能に対応していません。

Raspberry Pi Pico W用ソースコード
import machine
import network
import ntptime
import time

ssid = 'ここにSSIDを記載'
key = 'ここにパスワードを記載'

timezone = 9

wlan = network.WLAN(network.STA_IF)

rtc = machine.RTC()

wlan.active(True)
wlan.connect(ssid, key)

while not wlan.isconnected() and wlan.status() >= 0:
time.sleep(1)

print('connected:', wlan.ifconfig()[0])

ntptime.host = 'ntp.nict.jp'
ntptime.settime()

wlan.disconnect()

print('disconnected')

utc = rtc.datetime()

year = utc[0]
month = utc[1]
date = utc[2] + int((utc[4] + timezone + 24) / 24) - 1
hour = (utc[4] + timezone + 24) % 24

if not month in [2, 4, 6, 9, 11] and date > 31:
month += 1
date -= 31
elif month in [4, 6, 9, 11] and date > 30:
month += 1
date -= 30
elif ((year % 4 == 0 and year % 100 != 0) or year % 400 == 0) and month == 2 and date > 29:
month += 1
date -= 29
elif (year % 4 != 0 or year % 100 == 0) and year % 400 != 0 and month == 2 and date > 28:
month += 1
date -= 28

if not month in [3, 5, 7, 10, 12] and date < 1:
month -= 1
date += 31
elif month in [5, 7, 10, 12] and date < 1:
month -= 1
date += 30
elif ((year % 4 == 0 and year % 100 != 0) or year % 400 == 0) and month == 3 and date < 1:
month -= 1
date += 29
elif (year % 4 != 0 or year % 100 == 0) and year % 400 != 0 and month == 3 and date < 1:
month -= 1
date += 28

year = year + int((month + 11) / 12) - 1
month = (month + 11) % 12 + 1

rtc.datetime((year, month, date, utc[3], hour, utc[5], utc[6], utc[7]))

time.sleep(0.5)

while True:
print(rtc.datetime())
time.sleep(1)

ネットワーク経由でソケット通信する

Raspberry Pi Pico用ソースコード

Raspberry Pi PicoはWi-Fi機能に対応していません。

Raspberry Pi Pico W用ソースコード
import network
import socket
import time

ssid = 'ここにSSIDを記載'
key = 'ここにパスワードを記載'

wlan = network.WLAN(network.STA_IF)

wlan.active(True)
wlan.connect(ssid, key)

while not wlan.isconnected() and wlan.status() >= 0:
time.sleep(1)

print('connected:', wlan.ifconfig()[0])

sock = socket.socket()

sock.connect(socket.getaddrinfo('example.com', 80)[0][-1])
sock.send(b'GET / HTTP/1.0\r\n\r\n')

while True:
buffer = sock.recv(1024)

if buffer == b'':
break

print(buffer)

sock.close()

wlan.disconnect()

ネットワーク経由でJSON形式のデータを取得する

Raspberry Pi Pico用ソースコード

Raspberry Pi PicoはWi-Fi機能に対応していません。

Raspberry Pi Pico W用ソースコード
import network
import urequests
import time

ssid = 'ここにSSIDを記載'
key = 'ここにパスワードを記載'

wlan = network.WLAN(network.STA_IF)

wlan.active(True)
wlan.connect(ssid, key)

while not wlan.isconnected() and wlan.status() >= 0:
time.sleep(1)

print('connected:', wlan.ifconfig()[0])

response = urequests.get('example.com')

print('status:', response.status_code)
print(response.json())

wlan.disconnect()

非同期処理のサーバを立てる

Raspberry Pi Pico用ソースコード

Raspberry Pi PicoはWi-Fi機能に対応していません。

Raspberry Pi Pico W用ソースコード
import machine
import network
import uasyncio
import time

ssid = 'ここにSSIDを記載'
key = 'ここにパスワードを記載'

wlan = network.WLAN(network.STA_IF)

led = machine.Pin('LED', machine.Pin.OUT)

html = '''<!DOCTYPE html><html><head>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Pico W Server</title>%s
</head><body>
<h1>Pico W Server</h1><p>Push any button to change led status!</p>
<button style="font-size: x-large;" onclick="location.href='/on'">on</button>
<button style="font-size: x-large;" onclick="location.href='/off'">off</button>
</body></html>
'''

def connect():
wlan.active(True)
wlan.config(pm = 0xa11140)
wlan.connect(ssid, key)

wait = 10

while wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break

wait -= 1
time.sleep(1)

if wlan.status() != 3:
raise RuntimeError('failed')
else:
print('connected:', wlan.ifconfig()[0])

async def serve(reader, writer):
request = await reader.readline()
print('request:', request)

while await reader.readline() != b'\r\n':
pass

if str(request).find('/on') == 6:
led.on()
response = html % '<meta http-equiv="refresh" content="0;URL=/">'
elif str(request).find('/off') == 6:
led.off()
response = html % '<meta http-equiv="refresh" content="0;URL=/">'
else:
response = html % ''

writer.write('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n')
writer.write(response)

await writer.drain()
await writer.wait_closed()

async def main():
print('connecting')
connect()

print('setting up')
uasyncio.create_task(uasyncio.start_server(serve, '0.0.0.0', 80))

print('ready')
while True:
await uasyncio.sleep(0.5)

try:
uasyncio.run(main())
finally:
uasyncio.new_event_loop()

 

 

小さな会社のデジタル化のことなら

斑鳩情報開発 へご相談を

 

お電話でのお問い合わせ
050-1808-5018

受付時間: 平日10:00から18:00まで(年末年始を除く)

 

メールでのお問い合わせはこちら

24時間受付/お送りいただいた内容は営業時間内に順次確認いたします

 

関連情報