【PR】この記事には広告が含まれています。

ラズベリーパイのマイコンとして人気のRaspberry Pi Pico。2023年3月27日、Raspberry Pi Pico Wが日本で発売されました。
これまでのPicoは高性能で低価格だったものの、Wi-Fiが使えないという欠点がありました。今回のモデルで、そんなPicoの使い勝手が大幅に向上しています。
例えば、インターネット経由で時刻を取得し、特定の時間にLEDを光らせる、といった使い方もできます。
この記事ではPico Wの魅力をお伝えするため、その特徴や基本的な使い方をまとめました。Pico W単体で完結する便利な使い方を5つ紹介しています。ひとつずつ実践していただければ、Wi-Fi機能を使いこなすための基礎的な部分がマスターできるはずです。

ぜひ最後まで読んで、Pico Wの世界を堪能してください。
チェックポイント
本記事はWi-Fi機能付きのPico WおよびPico WHの使い方を解説しています。Wi-Fi機能が付いていないPicoおよびPico Hを使用する方は、以下の記事をご覧ください。
≫【レビュー】Raspberry Pi Picoは何ができる?ピコとラズパイ 5つの違いを初心者向けに徹底解説
Picoは高性能なマイコン

はじめにPicoシリーズの特徴を解説します。すでにPicoを使ったことがある方は下のボタンを押して、説明をスキップしてください。
お急ぎの方はこちらをクリック!
Picoはマイコン=電子工作に特化
Picoとラズベリーパイ。どちらもRaspberry Pi財団が開発した基板で見た目も似ていますが、大きな違いがあります。

Picoは電子工作に特化したマイコン(マイクロコントローラー)です。ズパイのようにOSを動かすことはできないため、Pico自体をパソコンのように使うことはできません。
このため、別のパソコンで作成したプログラムをPicoに書き込んで使用します。

電子工作はプログラムでパーツを制御すること
電子工作ではセンサーやモーターといった電子パーツを使って、独自の機能を持った作品が作れます。Picoにプログラムを書き込めば、接続した電子パーツを自在に制御できます。

例えば以下のような「人が通ったことを検知して照明のスイッチを自動で押す」といった装置も、手軽に作れるのが電子工作の魅力です。

単純な動きに見えますが、モーターを動かす角度や動作後の待機時間など緻密な調整が入っています。メイカー(独創的なDIYを楽しむ人)にとってはそこが腕の見せ所であり醍醐味です。
Picoで使える言語
プログラミング言語はMicroPythonまたはC言語が使えます。MicroPythonはマイコンを操作するための言語で、Pythonと同じ文法でプログラミングできます。
Picoとラズパイの使い分け
ラズパイにもGPIOピンが付いているため、電子工作は可能です。Picoでできることは、ほぼラズパイでもできます。しかし比較的シンプルな作品はPicoを使う方がスマートです。

ラズパイに単純な仕事をさせるのはオーパースペックといえます。動作確認で使うならまだしも、長期間運用させると他の用途に使えず、もったいなく感じることがあります。
低価格なPicoシリーズ
ラズパイは高額なため作品完成後に別のものが作りたくなったとき、一度分解して作り直すケースが多いです。一方Picoは低価格なので、複数購入して新しい作品を次々と作るといった用途に向いています。
参考価格 | Wi-Fi機能 | ピンヘッダー | 詳細 | |
![]() Rapberry Pi Pico | 792円 | - | - | 詳細を見る |
![]() Raspberry Pi Pico H | 979円 | - | 〇 | 詳細を見る |
![]() Raspberry Pi Pico 2 | 990円 | - | - | 詳細を見る |
![]() Rspberry Pi Pico W | 1,353円 | 〇 | - | 詳細を見る |
![]() Raspberry Pi Pico WH | 1,496円 | 〇 | 〇 | 詳細を見る |
Wi-Fi機能の有無やピンヘッダーの有無で選択できます。ピンヘッダーが付いていると、電子パーツの接続が容易になります。

通販で購入する場合は、スイッチサイエンスなどの送料の安いショップで購入すると良いでしょう。
ラズパイではなくPicoを使うメリット
低価格だから低品質とは限りません。Picoを使うメリットは次の6つです。
- 低価格
- 低消費電力
- コンパクト
- A/Dコンバーター内蔵
- 起動が速い
- 入手しやすい
事前に書き込んだプログラムを実行する場合、Picoの方が起動が速いです。ラズパイはOSを起動するのに時間がかかりますが、Picoは電源を入れると即座に立ち上がり、プログラムを実行します。電子部品を制御する目的には、Picoが最適な選択肢であると言えるでしょう。

Raspberry Pi Pico | 2秒 |
Raspberry Pi 4 Model B | 30秒 |
Raspberry Pi Zero 2W | 42秒 |
ラズパイの起動時間はモデルやOSの種類、使用するmicroSDにより変わります。
そして今回、Wi-Fi搭載のPico Wが発売され、メリットは大幅に増えることになりました。
Picoとラズパイの違いについてもっと詳しく知りたい方は以下の記事をご覧ください。
≫【レビュー】Raspberry Pi Picoは何ができる?ピコとラズパイ 5つの違い
Raspberry Pi Pico Wの特徴
普通のPicoと同じくRaspberry Pi財団が独自に開発したマイクロコントローラーチップのRP2040が搭載されています。

従来のPicoとの違いはWi-Fiが付いたことだけです。基本スペックは変わっていません。

裏面にはGPIOピンの名前が書いてあります。電子パーツを接続するときにわかりやすいです。
Raspberry Pi Pico Wのスペック
Pico Wのスペックを以下にまとめました。
CPU | Cortex-M0+ 133MHz × 2 |
RAM | 264kB on-chip SRAM |
Flash メモリー | 2MB on-board Quad-SPI |
無線LAN | 2.4GHz IEEE 802.11b/g/n |
Bluetooth | Bluetooth 5.2 |
電源 | 1.8~5.5V |
USB | micro-USB |
サイズ | 51mm × 21mm × 3.9mm |
重量 | 3g |
発売日 | 2023年3月27日 |
参考価格 (スイッチサイエンス) | 1,210円 |
公式のプロモーション動画はこちらからご覧いただけます。
購入できるショップ
Raspberry Pi Pico Wは以下のショップで購入できます。Pico Wはとても小さな商品です。送料ができるだけ安いショップを選ぶことで、お得に購入できます。
ショップ名 | 本体価格 | 送料 | 合計 | 在庫 |
---|---|---|---|---|
スイッチサイエンス | 1,265円 | 200円 | 1,465円 | 〇 |
共立エレショップ | 1,210円 | 280円 | 1,490円 | 〇 |
マルツ | 1,210円 | 385円 | 1,595円 | 〇 |
千石電商 | 1,280円 | 350円 | 1,630円 | 〇 |
KSY | 1,100円 | 550円 | 1,650円 | 〇 |
秋月電子通商 | 1,200円 | 500円 | 1,700円 | 〇 |
パッケージは保管する
Pico Wのパッケージには技術基準適合認定に合格した証である技適シールが貼られています。

Pico WはWi-Fiが使えるため、無線通信機器とみなされます。技適シールは捨てずに保管しておきましょう。技適シールは無線通信機器の正規品であることを示す重要な証拠となるからです。
普通のPicoとPico Wの違い
Pico WのGPIOのピン配置は以下の通りです。普通のPicoとは一部割り当てが異なる部分があります。

Picoの基板にはプログラムを介して制御可能なLEDが搭載されています。ただし、通常のPicoとPico Wでは、このLEDが接続されている位置が異なる点にご注意ください。

普通のPicoはCPUに直接つないでいるのに対して、Pico Wは無線チップ経由でCPUにつながっています。LEDを光らせるためのプログラムも違うので、注意が必要です。
無線機能でできること

Raspberry Pi Pico Wは無線LAN(Wi-Fi)と接続できます。無線機能を使ってできることは以下の通りです。
- ネットワーク経由でPico Wに指令を送る
- ネットワーク経由でPico Wの状態を確認する
- WebサービスへPico Wの状態をアップロードする
- インターネットから情報を取得する
- ChatGPT APIを使ってAIロボットを作る
以下の事例では、電子ペーパーに時刻やビットコインの価格を表示しています。時刻はインターネットを経由して取得しているため、時刻合わせが不要で正確です。ビットコインの価格はコインチェックのAPIから取得しています。

また、話題の文章生成AIであるChatGPTを使って「AIが生成した文章」を表示する装置を作ることが可能です。

Raspberry Pi Pico WでChatGPT APIを使う方法は、以下の記事で詳しく説明してします。
≫ AIと電子工作の融合!Raspberry Pi Pico WでChatGPT APIを使用する方法
以下は東京証券取引所の電光掲示板「チッカー」をイメージして作成した表示装置です。
Raspberry Pi Pico Wの使い方(基礎編)
Picoを使ったことがある方はクリック
ここからはPico Wを使用する準備をして、実際にプログラムを実行してみます。
パソコンとPico Wを接続する
パソコンとPico Wの接続には以下のようなUSBケーブルを使います。

Pico WのBOOTSELボタンを押しながらパソコンと接続します。先にパソコン側を接続しておくと、ボタンを押しやすくなります。

チェックポイント
BOOTSELボタンを押しながら接続すると、Picoが外部ストレージとして認識されます。
RPI-RP2(D:)としてパソコンが認識します。

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

Pico WでMicroPythonを使えるようにするために、まずファームウェアを書き込む必要があります。ファームウェアはPico Wを動作させるためのソフトウェアです。
パソコンが認識したRPI-RP2(D:)を開くと以下のように表示されます。
INDEXというファイルを開きます。

するとブラウザでRaspberry Pi財団のサイトが立ち上がります。
MicroPythonをクリックします。

画面を少し下にスクロールして、Raspberry Pi Pico Wと書かれたリンクをクリックするとuf2ファイルがパソコンにダウンロードされます。

ダウンロードしたuf2ファイルをRPI-RP2(D:)にドラッグアンドドロップします。

以上の操作でMicroPythonファームウェアの書き込みが完了しました。Pico Wはプログラムが書き込める状態になっています。
パソコンにThonnyをインストールする

パソコンでプログラムを作成するための準備としてThonnyをインストールします。ThonnyはPythonプログラムを書くためのソフトです。Thonnyでは以下の4つの操作ができます。
- プログラムの作成・編集
- プログラムの実行
- Picoへファイルの書き込み
- Picoに保存されたファイルの管理
Thonnyはこちらのサイトからダウンロードできます。Raspberry Pi OSではあらかじめThonnyが使える状態になっているのでインストール不要です。
Windowsを使っている方はWindowsの部分をクリックして、インストールファイルをダウンロードします。

インストールしたファイルをクリックして実行します。

Install for me only (recommended)をクリック

しばらくNextを押していきます。

デスクトップ画面にThonnyのアイコンを設置したい場合はチェックを入れます。

Installを押すとインストール開始です。

インストールが完了したらThonnyを開いてみましょう。
Languageを日本語に設定します。

Pico Wでプログラムを実行する準備
画面右下部分をクリックします。

Raspberry Pi Picoと記載された部分をクリックします。

以下のような表示になれば、プログラムの実行対象がPicoに切り替わっています。

Pico W本体のLEDをプログラミングで点滅させる
Pico Wの基板にはプログラムで制御できるLEDが付いています。まずはこのLEDを点滅させて、プログラムを実行するまでの手順を確認してみましょう。

以下のプログラムをコピーしてThonnyの画面にペーストします。
import machine
import utime
led = machine.Pin("LED", machine.Pin.OUT)
while True:
led.on()
utime.sleep(1)
led.off()
utime.sleep(1)
プログラムは以下の場所へペーストしてください。

チェックポイント
LEDを点滅させるためのプログラムは普通のPicoと同じではありません。基板上のLEDの接続方法が違うからです。普通のPicoはCPUに接続されているのに対して、Pico Wは無線LANのGPIOに接続されています。
実行する前にプログラムをPico Wに書き込みます。

名前はmain.pyで保存します。

プログラムが保存出来たら、実行ボタンを押してみましょう。

以下のようにLEDが点滅するはずです。

「main.py」は自動で実行される
一度パソコンからPico Wを外して、今度はBOOTSELボタンを押さずにパソコンにつないでみましょう。するとLED点滅が始まります。
今度は以下のようなACアダプターをPico Wに接続してみましょう。パソコンにつながっていなくても、LED点滅が実行されます。Pico Wにプログラムが書き込まれていることが確認できました。

チェックポイント
Picoは電源供給時に「main.py」と いう名前で保存したプログラムを自動で実行します。
再度パソコンに接続してプログラムを編集する方法
Pico WのBOOTSELボタンを押さずにパソコンに接続したら、Thonnyを立ち上げます。
「main.py」のプログラムが実行されるので、停止ボタンを押します。

以下の表示が出れば接続成功です。

これで、プログラムの編集ができる状態になりました。
Raspberry Pi Pico Wの使い方(Wi-Fi編)
Pico WのWi-Fi機能の活用方法について説明します。あらかじめ自宅のWi-FiのSSIDとパスワードを調べておきましょう。Pico Wは2.4GHz帯のWi-Fiにのみ対応しており、5GHz帯のWi-Fiは使用できませんので注意しましょう。
Pico W本体のLEDをWi-Fi経由で操作する

先ほど点滅させた基板上のLEDをWi-Fiから操作してみましょう。
以下のコードをコピペしてください。10行目と11行目のYOUR NETWORK SSIDとYOUR NETWORK PASSWORDの部分は自宅Wi-FiのSSIDとパスワードに変更する必要があります。
import time
import network
import socket
from machine import Pin
led = Pin("LED", machine.Pin.OUT)
ledState = 'LED State Unknown'
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
html = """<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
.buttonGreen { background-color: #4CAF50; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
.buttonRed { background-color: #D11D53; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
</style></head>
<body><center><h1>Raspberry Pi Pico W</h1></center><br><br>
<form><center>
<center> <button class="buttonGreen" name="led" value="on" type="submit">LED ON</button>
<br><br>
<center> <button class="buttonRed" name="led" value="off" type="submit">LED OFF</button>
</form>
<br><br>
<br><br>
<p>%s<p></body></html>
"""
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
# Handle connection error
if wlan.status() != 3:
raise RuntimeError('network connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print( 'ip = ' + status[0] )
# Open socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)
print('listening on', addr)
# Listen for connections, serve client
while True:
try:
cl, addr = s.accept()
print('client connected from', addr)
request = cl.recv(1024)
print("request:")
print(request)
request = str(request)
led_on = request.find('led=on')
led_off = request.find('led=off')
print( 'led on = ' + str(led_on))
print( 'led off = ' + str(led_off))
if led_on == 8:
print("led on")
led.value(1)
if led_off == 8:
print("led off")
led.value(0)
ledState = "LED is OFF" if led.value() == 0 else "LED is ON" # a compact if-else statement
# Create and send response
stateis = ledState
response = html % stateis
full_response = 'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n' + response
cl.send(full_response)
cl.close()
except OSError as e:
cl.close()
print('connection closed')
参考にしたサイト:Raspberry Pi Pico W | Create a Simple HTTP Server
このコードは、Pico Wを使用してWi-Fi経由でLEDを制御するウェブサーバーを立ち上げるためのものです。はじめに、自宅のWi-Fiに接続する設定を行います。次に、HTMLを使ったシンプルなウェブページを用意し、このページを通じてLEDをオンまたはオフにするボタンを表示します。ウェブサーバーはユーザーからのリクエストを待ち受け、そのリクエストに応じてLEDの状態を変更し、現在のLEDの状態(オンかオフか)を表示するページを返します。ネットワーク接続の設定、ソケットプログラミング(ネットワーク経由でのデータの送受信を可能にする技術)、HTMLの基礎知識が含まれます。このコードはデバイスをインターネット経由で操作するIoT(Internet of Things)アプリケーションの基本的な例を示しています。
IPアドレスを確認する
Wi-Fi接続が成功するとシェルに以下のような表示が出ます。

上の画像中の赤線部分がPico WのIPアドレスです。
チェックポイント
IPアドレスとはネットワーク内で自動的に割り振られた番号のことです。この場合はプライベートIPアドレスといい、自宅のネットワーク内での番号となります。IPアドレスを使ってPCやスマホからPicoにアクセスします。

IPアドレスをブラウザのアドレスバーに入力してください。ブラウザはChromeでもEdgeでも何でも構いません。

すると以下の画面が表示されます。

LED ONやLED OFFのボタンをクリックすると、Pico WのLEDが点灯したり消えたりします。Wi-Fiにつながっていれば、スマートフォンやタブレットのブラウザでも操作可能です。

温度センサーの数値をWi-Fi経由で確認する

Pico WのマイコンチップRP2040には温度センサーが内蔵されています。この温度をWi-Fiネットワーク経由で確認してみましょう。
温度取得の基本
温度センサーの数値を取得するプログラムは以下の通りです。
import time
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / 65535
while True:
reading = sensor_temp.read_u16() * conversion_factor
temp = 27 - (reading - 0.706)/0.001721
temp = round(temp, 1)
print(temp)
time.sleep(1)
このコードは温度センサーからの読み取り値を利用して、現在の温度を計算し、それをコンソールに表示するものです。
実行するとPico Wの温度が1秒おきに表示されます。

IC内部の温度なので、室温より少し高めに表示されることが多いです。
温度をWi-Fi経由で見る方法
Pico Wの温度をWebページに表示させるプログラムは以下のようになります。
import time
import network
import socket
from machine import Pin
led = Pin("LED", machine.Pin.OUT)
ledState = 'LED State Unknown'
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
html = """<!DOCTYPE html>
<html>
<head> <title>Pico W</title> </head>
<body> <h1>Pico W HTTP Server</h1>
<p>Hello, World!</p>
<p>%s</p>
</body>
</html>
"""
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
# Handle connection error
if wlan.status() != 3:
raise RuntimeError('network connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print( 'ip = ' + status[0] )
# Open socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)
print('listening on', addr)
# Listen for connections, serve client
while True:
try:
cl, addr = s.accept()
print('client connected from', addr)
request = cl.recv(1024)
print("request:")
print(request)
request = str(request)
reading = sensor_temp.read_u16() * conversion_factor
temp = 27 - (reading - 0.706)/0.001721
temp = round(temp, 1)
temp = str(temp)
# Create and send response
stateis = "Pico Temp: " + temp
response = html % stateis
full_response = 'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n' + response
cl.send(full_response)
cl.close()
except OSError as e:
cl.close()
print('connection closed')
このコードはPico Wの温度センサーの値を読み取り、その値をウェブサーバーを通じて表示するためのものです。前述のLED制御のコードとの主な違いは、LEDのオンオフを制御する代わりに、温度センサーの値を読み取る点です。この例はPico Wがセンサーからのデータを収集し、それをインターネットを通じてリアルタイムで共有するIoTの基本的な仕組みを示しています。
プログラムを実行してブラウザからアクセスすると、以下の画面が表示されます。Pico Wの温度が確認できます。

ページを更新すると最新の温度が表示されます。
LED操作と温度確認を同時にできるようにする
先ほどのLEDをブラウザから操作するプログラムと合体すると以下のようになります。
import time
import network
import socket
from machine import Pin
led = Pin("LED", machine.Pin.OUT)
ledState = 'LED State Unknown'
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
html = """<!DOCTYPE html><html>
<head><meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
.buttonGreen { background-color: #4CAF50; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
.buttonRed { background-color: #D11D53; border: 2px solid #000000;; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; margin: 4px 2px; cursor: pointer; }
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
</style></head>
<body><center><h1>Raspberry Pi Pico W</h1></center><br><br>
<form><center>
<center> <button class="buttonGreen" name="led" value="on" type="submit">LED ON</button>
<br><br>
<center> <button class="buttonRed" name="led" value="off" type="submit">LED OFF</button>
</form>
<br><br>
<br><br>
<p>%s<p></body></html>
"""
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
# Handle connection error
if wlan.status() != 3:
raise RuntimeError('network connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print( 'ip = ' + status[0] )
# Open socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)
print('listening on', addr)
# Listen for connections, serve client
while True:
try:
cl, addr = s.accept()
print('client connected from', addr)
request = cl.recv(1024)
print("request:")
print(request)
request = str(request)
led_on = request.find('led=on')
led_off = request.find('led=off')
print( 'led on = ' + str(led_on))
print( 'led off = ' + str(led_off))
if led_on == 8:
print("led on")
led.value(1)
if led_off == 8:
print("led off")
led.value(0)
ledState = "LED is OFF" if led.value() == 0 else "LED is ON" # a compact if-else statement
reading = sensor_temp.read_u16() * conversion_factor
temp = 27 - (reading - 0.706)/0.001721
temp = round(temp, 1)
temp = str(temp)
# Create and send response
stateis = ledState + "<br><br>Pico Temp: " + temp
response = html % stateis
full_response = 'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n' + response
cl.send(full_response)
cl.close()
except OSError as e:
cl.close()
print('connection closed')
画面下に温度が表示されれば成功です。

BOOTSELボタンを押してメールを送る

Pico WのWi-Fi機能を活用すれば、プログラムを通じてメールを送信することができます。例えば、Pico Wのボタンを使って簡単な呼び出しボタンを作成し、押されたときにメール送信する仕組みも実現可能です。ここでは、GmailのSMTPサーバーを使用してメールを送信する方法について説明します。
Googleのアプリパスワードを取得する
ブラウザで Googleのアプリパスワードの設定ページ を開きます。Google アカウントのログインが求められる場合、使用するメールアドレスとパスワードを入力してログインしてください。

アプリ名を入力します。「Raspberry Pi Pico W」など分かりやすい名前を入力することをおすすめします。「作成」をクリックするとアプリパスワードが生成されます。

表示された16桁のアプリパスワードをコピーして、Pico Wのプログラムやその他のアプリケーションで使用します。このパスワードは再表示ができないため、必要に応じて安全な場所に控えておいてください。
メールを送信するコード
import network
import time
import socket
import ssl
import ubinascii
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# GmailのSMTP設定
SMTP_SERVER = "smtp.gmail.com" # SMTPサーバーのホスト名(Gmailの場合は固定)
SMTP_PORT = 465 # SMTPサーバーのSSL接続用ポート(Gmailでは465)
GMAIL_USER = "****@gmail.com" # Gmailの送信元メールアドレス
GMAIL_PASSWORD = "****" # Gmailのアプリパスワード
# メールの設定
TO_EMAIL = "****@gmail.com" # メールの送信先アドレス
SUBJECT = "Raspberry Pi Pico Wからのメール" # メールの件名
BODY = "このメールはRaspberry Pi Pico Wから送信されました。" # メールの本文
DEFAULT_TIMEOUT = 10
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def __init__(self, host, port, use_ssl=False, username=None, password=None):
self.username = username
addr = socket.getaddrinfo(host, port)[0][-1]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if use_ssl:
sock = ssl.wrap_socket(sock)
code_line = sock.readline().strip().decode()
code = int(code_line[:3])
assert code == 220, 'サーバーに接続できません: %d, %s' % (code, code_line)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d' % code
if not use_ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code == 220, 'STARTTLS失敗: %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def cmd(self, cmd_str):
self._sock.write((cmd_str + '\r\n').encode())
resp_lines = []
while True:
code_bytes = self._sock.read(3)
if not code_bytes:
break
code = code_bytes.decode()
dash_or_space = self._sock.read(1)
line = self._sock.readline().strip().decode()
resp_lines.append(line)
if dash_or_space != b'-':
return int(code), resp_lines
return 0, ['']
def login(self, username, password):
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths is not None, '認証メソッドが見つかりません'
b64 = ubinascii.b2a_base64
if AUTH_PLAIN in auths:
credential = b64(b"import network
import time
import socket
import ssl
import ubinascii
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# GmailのSMTP設定
SMTP_SERVER = "smtp.gmail.com" # SMTPサーバーのホスト名(Gmailの場合は固定)
SMTP_PORT = 465 # SMTPサーバーのSSL接続用ポート(Gmailでは465)
GMAIL_USER = "****@gmail.com" # Gmailの送信元メールアドレス
GMAIL_PASSWORD = "****" # Gmailのアプリパスワード
# メールの設定
TO_EMAIL = "****@gmail.com" # メールの送信先アドレス
SUBJECT = "Raspberry Pi Pico Wからのメール" # メールの件名
BODY = "このメールはRaspberry Pi Pico Wから送信されました。" # メールの本文
DEFAULT_TIMEOUT = 10
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def __init__(self, host, port, use_ssl=False, username=None, password=None):
self.username = username
addr = socket.getaddrinfo(host, port)[0][-1]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if use_ssl:
sock = ssl.wrap_socket(sock)
code_line = sock.readline().strip().decode()
code = int(code_line[:3])
assert code == 220, 'サーバーに接続できません: %d, %s' % (code, code_line)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d' % code
if not use_ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code == 220, 'STARTTLS失敗: %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def cmd(self, cmd_str):
self._sock.write((cmd_str + '\r\n').encode())
resp_lines = []
while True:
code_bytes = self._sock.read(3)
if not code_bytes:
break
code = code_bytes.decode()
dash_or_space = self._sock.read(1)
line = self._sock.readline().strip().decode()
resp_lines.append(line)
if dash_or_space != b'-':
return int(code), resp_lines
return 0, ['']
def login(self, username, password):
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths is not None, '認証メソッドが見つかりません'
b64 = ubinascii.b2a_base64
if AUTH_PLAIN in auths:
credential = b64(b"\0" + username.encode() + b"\0" + password.encode())[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, credential))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username.encode())[:-1].decode()))
assert code == 334, 'ユーザー名エラー: %d, %s' % (code, resp)
code, resp = self.cmd(b64(password.encode())[:-1].decode())
else:
raise Exception("サポートされていない認証方式: %s" % ', '.join(auths))
assert code == 235 or code == 503, '認証エラー: %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from is None else mail_from
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code == 250, '送信元が拒否されました: %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
refused_count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code not in (250, 251):
print('%s が拒否されました: %s' % (addr, resp))
refused_count += 1
assert refused_count != len(addrs), '全ての送信先が拒否されました: %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code == 354, 'DATAコマンドが拒否されました: %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content.encode())
def send(self, content=''):
if content:
self.write(content)
self._sock.write(b'\r\n.\r\n')
line = self._sock.readline().decode()
return (int(line[:3]), line[4:].strip())
def quit(self):
self.cmd("QUIT")
self._sock.close()
#無線LANへの接続
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print('IPアドレス = ' + status[0])
# Wi-Fiに接続
connect_to_wifi(ssid, password)
# メール送信
smtp = SMTP(SMTP_SERVER, SMTP_PORT, use_ssl=True, username=GMAIL_USER, password=GMAIL_PASSWORD)
smtp.to(TO_EMAIL)
smtp.write("From: <%s>\n" % GMAIL_USER)
smtp.write("Subject: %s\n\n" % SUBJECT)
smtp.write(BODY)
smtp.send()
smtp.quit()
print("メールが送信されました")
" + username.encode() + b"import network
import time
import socket
import ssl
import ubinascii
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# GmailのSMTP設定
SMTP_SERVER = "smtp.gmail.com" # SMTPサーバーのホスト名(Gmailの場合は固定)
SMTP_PORT = 465 # SMTPサーバーのSSL接続用ポート(Gmailでは465)
GMAIL_USER = "****@gmail.com" # Gmailの送信元メールアドレス
GMAIL_PASSWORD = "****" # Gmailのアプリパスワード
# メールの設定
TO_EMAIL = "****@gmail.com" # メールの送信先アドレス
SUBJECT = "Raspberry Pi Pico Wからのメール" # メールの件名
BODY = "このメールはRaspberry Pi Pico Wから送信されました。" # メールの本文
DEFAULT_TIMEOUT = 10
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def __init__(self, host, port, use_ssl=False, username=None, password=None):
self.username = username
addr = socket.getaddrinfo(host, port)[0][-1]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if use_ssl:
sock = ssl.wrap_socket(sock)
code_line = sock.readline().strip().decode()
code = int(code_line[:3])
assert code == 220, 'サーバーに接続できません: %d, %s' % (code, code_line)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d' % code
if not use_ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code == 220, 'STARTTLS失敗: %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def cmd(self, cmd_str):
self._sock.write((cmd_str + '\r\n').encode())
resp_lines = []
while True:
code_bytes = self._sock.read(3)
if not code_bytes:
break
code = code_bytes.decode()
dash_or_space = self._sock.read(1)
line = self._sock.readline().strip().decode()
resp_lines.append(line)
if dash_or_space != b'-':
return int(code), resp_lines
return 0, ['']
def login(self, username, password):
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths is not None, '認証メソッドが見つかりません'
b64 = ubinascii.b2a_base64
if AUTH_PLAIN in auths:
credential = b64(b"\0" + username.encode() + b"\0" + password.encode())[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, credential))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username.encode())[:-1].decode()))
assert code == 334, 'ユーザー名エラー: %d, %s' % (code, resp)
code, resp = self.cmd(b64(password.encode())[:-1].decode())
else:
raise Exception("サポートされていない認証方式: %s" % ', '.join(auths))
assert code == 235 or code == 503, '認証エラー: %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from is None else mail_from
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code == 250, '送信元が拒否されました: %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
refused_count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code not in (250, 251):
print('%s が拒否されました: %s' % (addr, resp))
refused_count += 1
assert refused_count != len(addrs), '全ての送信先が拒否されました: %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code == 354, 'DATAコマンドが拒否されました: %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content.encode())
def send(self, content=''):
if content:
self.write(content)
self._sock.write(b'\r\n.\r\n')
line = self._sock.readline().decode()
return (int(line[:3]), line[4:].strip())
def quit(self):
self.cmd("QUIT")
self._sock.close()
#無線LANへの接続
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print('IPアドレス = ' + status[0])
# Wi-Fiに接続
connect_to_wifi(ssid, password)
# メール送信
smtp = SMTP(SMTP_SERVER, SMTP_PORT, use_ssl=True, username=GMAIL_USER, password=GMAIL_PASSWORD)
smtp.to(TO_EMAIL)
smtp.write("From: <%s>\n" % GMAIL_USER)
smtp.write("Subject: %s\n\n" % SUBJECT)
smtp.write(BODY)
smtp.send()
smtp.quit()
print("メールが送信されました")
" + password.encode())[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, credential))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username.encode())[:-1].decode()))
assert code == 334, 'ユーザー名エラー: %d, %s' % (code, resp)
code, resp = self.cmd(b64(password.encode())[:-1].decode())
else:
raise Exception("サポートされていない認証方式: %s" % ', '.join(auths))
assert code == 235 or code == 503, '認証エラー: %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from is None else mail_from
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code == 250, '送信元が拒否されました: %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
refused_count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code not in (250, 251):
print('%s が拒否されました: %s' % (addr, resp))
refused_count += 1
assert refused_count != len(addrs), '全ての送信先が拒否されました: %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code == 354, 'DATAコマンドが拒否されました: %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content.encode())
def send(self, content=''):
if content:
self.write(content)
self._sock.write(b'\r\n.\r\n')
line = self._sock.readline().decode()
return (int(line[:3]), line[4:].strip())
def quit(self):
self.cmd("QUIT")
self._sock.close()
#無線LANへの接続
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print('IPアドレス = ' + status[0])
# Wi-Fiに接続
connect_to_wifi(ssid, password)
# メール送信
smtp = SMTP(SMTP_SERVER, SMTP_PORT, use_ssl=True, username=GMAIL_USER, password=GMAIL_PASSWORD)
smtp.to(TO_EMAIL)
smtp.write("From: <%s>\n" % GMAIL_USER)
smtp.write("Subject: %s\n\n" % SUBJECT)
smtp.write(BODY)
smtp.send()
smtp.quit()
print("メールが送信されました")
このコードは、Raspberry Pi Pico Wを使ってGmailのSMTPサーバーを介し、メールを送信するものです。まず、GmailのSMTPアドレスやポート番号、送信元メールアドレス、アプリパスワードを設定します。次に、メールの送信先アドレス、件名、本文を指定します。
SMTPクラスを用いて、サーバーとの接続を確立し、必要に応じてSSLを適用してセキュアな通信を行います。その後、Gmailのアカウント情報を使ってサーバーにログインし、送信先アドレスとメール内容をSMTPプロトコルを用いて送信します。最後に、サーバーとの通信を終了させ、送信が完了したことを確認します。

BOOTSELボタンを読み取る
Pico Wに付いているBOOTSELボタンが押されたことをプログラムで読み取ることが可能です。

以下のプログラムを実行すると、BOOTSELボタンが押されたときにPico WのLEDが光ります。
import time
# 無限ループでボタンの状態を監視
while True:
# BOOTSELボタンが押された場合
if rp2.bootsel_button() == 1:
machine.Pin('LED', machine.Pin.OUT).on() # LEDを点灯
else:
machine.Pin('LED', machine.Pin.OUT).off() # BOOTSELボタンが押されていない場合はLEDを消灯
time.sleep(0.1) # 0.1秒待機して次のループへ
参考にさせていただいたサイト:BOOTSELボタンでLチカ【Raspberry Pi Pico W】

BOOTSELボタンでメールを送信するプログラム
BOOTSELボタンが押されたときにメールを送るプログラムは以下のようになります。
import network
import time
import socket
import ssl
import ubinascii
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# GmailのSMTP設定
SMTP_SERVER = "smtp.gmail.com" # SMTPサーバーのホスト名(Gmailの場合は固定)
SMTP_PORT = 465 # SMTPサーバーのSSL接続用ポート(Gmailでは465)
GMAIL_USER = "****@gmail.com" # Gmailの送信元メールアドレス
GMAIL_PASSWORD = "****" # Gmailのアプリパスワード
# メールの設定
TO_EMAIL = "****@gmail.com" # メールの送信先アドレス
SUBJECT = "Raspberry Pi Pico Wからのメール" # メールの件名
BODY = "このメールはRaspberry Pi Pico Wから送信されました。" # メールの本文
DEFAULT_TIMEOUT = 10
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def __init__(self, host, port, use_ssl=False, username=None, password=None):
self.username = username
addr = socket.getaddrinfo(host, port)[0][-1]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if use_ssl:
sock = ssl.wrap_socket(sock)
code_line = sock.readline().strip().decode()
code = int(code_line[:3])
assert code == 220, 'サーバーに接続できません: %d, %s' % (code, code_line)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d' % code
if not use_ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code == 220, 'STARTTLS失敗: %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def cmd(self, cmd_str):
self._sock.write((cmd_str + '\r\n').encode())
resp_lines = []
while True:
code_bytes = self._sock.read(3)
if not code_bytes:
break
code = code_bytes.decode()
dash_or_space = self._sock.read(1)
line = self._sock.readline().strip().decode()
resp_lines.append(line)
if dash_or_space != b'-':
return int(code), resp_lines
return 0, ['']
def login(self, username, password):
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths is not None, '認証メソッドが見つかりません'
b64 = ubinascii.b2a_base64
if AUTH_PLAIN in auths:
credential = b64(b"import network
import time
import socket
import ssl
import ubinascii
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# GmailのSMTP設定
SMTP_SERVER = "smtp.gmail.com" # SMTPサーバーのホスト名(Gmailの場合は固定)
SMTP_PORT = 465 # SMTPサーバーのSSL接続用ポート(Gmailでは465)
GMAIL_USER = "****@gmail.com" # Gmailの送信元メールアドレス
GMAIL_PASSWORD = "****" # Gmailのアプリパスワード
# メールの設定
TO_EMAIL = "****@gmail.com" # メールの送信先アドレス
SUBJECT = "Raspberry Pi Pico Wからのメール" # メールの件名
BODY = "このメールはRaspberry Pi Pico Wから送信されました。" # メールの本文
DEFAULT_TIMEOUT = 10
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def __init__(self, host, port, use_ssl=False, username=None, password=None):
self.username = username
addr = socket.getaddrinfo(host, port)[0][-1]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if use_ssl:
sock = ssl.wrap_socket(sock)
code_line = sock.readline().strip().decode()
code = int(code_line[:3])
assert code == 220, 'サーバーに接続できません: %d, %s' % (code, code_line)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d' % code
if not use_ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code == 220, 'STARTTLS失敗: %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def cmd(self, cmd_str):
self._sock.write((cmd_str + '\r\n').encode())
resp_lines = []
while True:
code_bytes = self._sock.read(3)
if not code_bytes:
break
code = code_bytes.decode()
dash_or_space = self._sock.read(1)
line = self._sock.readline().strip().decode()
resp_lines.append(line)
if dash_or_space != b'-':
return int(code), resp_lines
return 0, ['']
def login(self, username, password):
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths is not None, '認証メソッドが見つかりません'
b64 = ubinascii.b2a_base64
if AUTH_PLAIN in auths:
credential = b64(b"\0" + username.encode() + b"\0" + password.encode())[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, credential))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username.encode())[:-1].decode()))
assert code == 334, 'ユーザー名エラー: %d, %s' % (code, resp)
code, resp = self.cmd(b64(password.encode())[:-1].decode())
else:
raise Exception("サポートされていない認証方式: %s" % ', '.join(auths))
assert code == 235 or code == 503, '認証エラー: %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from is None else mail_from
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code == 250, '送信元が拒否されました: %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
refused_count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code not in (250, 251):
print('%s が拒否されました: %s' % (addr, resp))
refused_count += 1
assert refused_count != len(addrs), '全ての送信先が拒否されました: %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code == 354, 'DATAコマンドが拒否されました: %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content.encode())
def send(self, content=''):
if content:
self.write(content)
self._sock.write(b'\r\n.\r\n')
line = self._sock.readline().decode()
return (int(line[:3]), line[4:].strip())
def quit(self):
self.cmd("QUIT")
self._sock.close()
#無線LANへの接続
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print('IPアドレス = ' + status[0])
# Wi-Fiに接続
connect_to_wifi(ssid, password)
# ボタンの状態を保持する変数
last_state = 0
while True:
current_state = rp2.bootsel_button()
if last_state == 0 and current_state == 1:
machine.Pin('LED', machine.Pin.OUT).on()
time.sleep(0.5)
machine.Pin('LED', machine.Pin.OUT).off()
# メール送信
smtp = SMTP(SMTP_SERVER, SMTP_PORT, use_ssl=True, username=GMAIL_USER, password=GMAIL_PASSWORD)
smtp.to(TO_EMAIL)
smtp.write("From: <%s>\n" % GMAIL_USER)
smtp.write("Subject: %s\n\n" % SUBJECT)
smtp.write(BODY)
smtp.send()
smtp.quit()
print("メールが送信されました")
" + username.encode() + b"import network
import time
import socket
import ssl
import ubinascii
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# GmailのSMTP設定
SMTP_SERVER = "smtp.gmail.com" # SMTPサーバーのホスト名(Gmailの場合は固定)
SMTP_PORT = 465 # SMTPサーバーのSSL接続用ポート(Gmailでは465)
GMAIL_USER = "****@gmail.com" # Gmailの送信元メールアドレス
GMAIL_PASSWORD = "****" # Gmailのアプリパスワード
# メールの設定
TO_EMAIL = "****@gmail.com" # メールの送信先アドレス
SUBJECT = "Raspberry Pi Pico Wからのメール" # メールの件名
BODY = "このメールはRaspberry Pi Pico Wから送信されました。" # メールの本文
DEFAULT_TIMEOUT = 10
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'
class SMTP:
def __init__(self, host, port, use_ssl=False, username=None, password=None):
self.username = username
addr = socket.getaddrinfo(host, port)[0][-1]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(DEFAULT_TIMEOUT)
sock.connect(addr)
if use_ssl:
sock = ssl.wrap_socket(sock)
code_line = sock.readline().strip().decode()
code = int(code_line[:3])
assert code == 220, 'サーバーに接続できません: %d, %s' % (code, code_line)
self._sock = sock
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d' % code
if not use_ssl and CMD_STARTTLS in resp:
code, resp = self.cmd(CMD_STARTTLS)
assert code == 220, 'STARTTLS失敗: %d, %s' % (code, resp)
self._sock = ssl.wrap_socket(sock)
if username and password:
self.login(username, password)
def cmd(self, cmd_str):
self._sock.write((cmd_str + '\r\n').encode())
resp_lines = []
while True:
code_bytes = self._sock.read(3)
if not code_bytes:
break
code = code_bytes.decode()
dash_or_space = self._sock.read(1)
line = self._sock.readline().strip().decode()
resp_lines.append(line)
if dash_or_space != b'-':
return int(code), resp_lines
return 0, ['']
def login(self, username, password):
code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
assert code == 250, 'EHLOエラー: %d, %s' % (code, resp)
auths = None
for feature in resp:
if feature[:4].upper() == CMD_AUTH:
auths = feature[4:].strip('=').upper().split()
assert auths is not None, '認証メソッドが見つかりません'
b64 = ubinascii.b2a_base64
if AUTH_PLAIN in auths:
credential = b64(b"\0" + username.encode() + b"\0" + password.encode())[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, credential))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username.encode())[:-1].decode()))
assert code == 334, 'ユーザー名エラー: %d, %s' % (code, resp)
code, resp = self.cmd(b64(password.encode())[:-1].decode())
else:
raise Exception("サポートされていない認証方式: %s" % ', '.join(auths))
assert code == 235 or code == 503, '認証エラー: %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from is None else mail_from
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code == 250, '送信元が拒否されました: %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
refused_count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code not in (250, 251):
print('%s が拒否されました: %s' % (addr, resp))
refused_count += 1
assert refused_count != len(addrs), '全ての送信先が拒否されました: %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code == 354, 'DATAコマンドが拒否されました: %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content.encode())
def send(self, content=''):
if content:
self.write(content)
self._sock.write(b'\r\n.\r\n')
line = self._sock.readline().decode()
return (int(line[:3]), line[4:].strip())
def quit(self):
self.cmd("QUIT")
self._sock.close()
#無線LANへの接続
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print('IPアドレス = ' + status[0])
# Wi-Fiに接続
connect_to_wifi(ssid, password)
# ボタンの状態を保持する変数
last_state = 0
while True:
current_state = rp2.bootsel_button()
if last_state == 0 and current_state == 1:
machine.Pin('LED', machine.Pin.OUT).on()
time.sleep(0.5)
machine.Pin('LED', machine.Pin.OUT).off()
# メール送信
smtp = SMTP(SMTP_SERVER, SMTP_PORT, use_ssl=True, username=GMAIL_USER, password=GMAIL_PASSWORD)
smtp.to(TO_EMAIL)
smtp.write("From: <%s>\n" % GMAIL_USER)
smtp.write("Subject: %s\n\n" % SUBJECT)
smtp.write(BODY)
smtp.send()
smtp.quit()
print("メールが送信されました")
" + password.encode())[:-1].decode()
code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, credential))
elif AUTH_LOGIN in auths:
code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username.encode())[:-1].decode()))
assert code == 334, 'ユーザー名エラー: %d, %s' % (code, resp)
code, resp = self.cmd(b64(password.encode())[:-1].decode())
else:
raise Exception("サポートされていない認証方式: %s" % ', '.join(auths))
assert code == 235 or code == 503, '認証エラー: %d, %s' % (code, resp)
return code, resp
def to(self, addrs, mail_from=None):
mail_from = self.username if mail_from is None else mail_from
code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
assert code == 250, '送信元が拒否されました: %d, %s' % (code, resp)
if isinstance(addrs, str):
addrs = [addrs]
refused_count = 0
for addr in addrs:
code, resp = self.cmd('RCPT TO: <%s>' % addr)
if code not in (250, 251):
print('%s が拒否されました: %s' % (addr, resp))
refused_count += 1
assert refused_count != len(addrs), '全ての送信先が拒否されました: %d, %s' % (code, resp)
code, resp = self.cmd('DATA')
assert code == 354, 'DATAコマンドが拒否されました: %d, %s' % (code, resp)
return code, resp
def write(self, content):
self._sock.write(content.encode())
def send(self, content=''):
if content:
self.write(content)
self._sock.write(b'\r\n.\r\n')
line = self._sock.readline().decode()
return (int(line[:3]), line[4:].strip())
def quit(self):
self.cmd("QUIT")
self._sock.close()
#無線LANへの接続
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print('IPアドレス = ' + status[0])
# Wi-Fiに接続
connect_to_wifi(ssid, password)
# ボタンの状態を保持する変数
last_state = 0
while True:
current_state = rp2.bootsel_button()
if last_state == 0 and current_state == 1:
machine.Pin('LED', machine.Pin.OUT).on()
time.sleep(0.5)
machine.Pin('LED', machine.Pin.OUT).off()
# メール送信
smtp = SMTP(SMTP_SERVER, SMTP_PORT, use_ssl=True, username=GMAIL_USER, password=GMAIL_PASSWORD)
smtp.to(TO_EMAIL)
smtp.write("From: <%s>\n" % GMAIL_USER)
smtp.write("Subject: %s\n\n" % SUBJECT)
smtp.write(BODY)
smtp.send()
smtp.quit()
print("メールが送信されました")
152行目では、last_state
という変数を使って、ボタンの前回の状態を記録します。last_state
を使用しないと、ボタンが押されている間ずっとメール送信処理が繰り返されてしまい、意図せず複数回のメールが送信されることがあります。
ループ内では、rp2.bootsel_button()
関数を使用して、ボタンの現在の状態を取得します。この関数は、ボタンが押されている場合は1、押されていない場合は0を返します。そして、前回の状態が0(押されていない)で現在の状態が1(押された)に変化したことを確認すると、メールが送信されます。
インターネットから情報を取得する

Pico WはWi-Fiが使えるため、Web上で公開されているさまざまな情報を自動で取得できます。今回はビットコインの価格を取得して表示してみましょう。ビットコインの価格はコインチェックという仮想通貨取引所のAPIから取得します。
チェックポイント
APIとはApplication Programming Interface(アプリケーションプログラミングインタフェース)の略です。コインチェックのAPIでは、取引所の注文状況や取引の履歴などが、自動で取得しやすい形式で公開されています。APIを利用すれば、必要な情報を比較的簡単に取得できます。
コインチェックのAPIから現在のビットコイン価格を取得するプログラムは以下の通りです。
import utime
import urequests as requests
import network
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
utime.sleep(1)
# Define blinking function for onboard LED to indicate error codes
def blink_onboard_led(num_blinks):
led = machine.Pin('LED', machine.Pin.OUT)
for i in range(num_blinks):
led.on()
utime.sleep(.2)
led.off()
utime.sleep(.2)
# Handle connection error
# Error meanings
# 0 Link Down
# 1 Link Join
# 2 Link NoIp
# 3 Link Up
# -1 Link Fail
# -2 Link NoNet
# -3 Link BadAuth
wlan_status = wlan.status()
blink_onboard_led(wlan_status)
if wlan_status != 3:
raise RuntimeError('Wi-Fi connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print('ip = ' + status[0])
#コインチェックのAPIのURL
url = 'https://coincheck.com/api/ticker'
#コインチェックのAPIからデータを取得
cc = requests.get(url).json()
#必要なデータを取り出して見やすくなるように加工する
cc_last = '{:,}'.format(int(cc['last']))
print("Coincheck 現在のビットコインの価格 =", cc_last, "円")
参考にしたサイト:【Python】ビットコインの価格を取得する(Coincheck編)
プログラムを実行すると、以下のように結果が表示されます。

ディスプレイに表示
別売りの有機ELディスプレイ(OLED)にビットコインの価格を表示させることも可能です。
参考までにコードを載せておきます。
import utime
import urequests as requests
import network
import machine
import ssd1306
sda = machine.Pin(0)
scl = machine.Pin(1)
i2c = machine.I2C(0,sda=sda, scl=scl, freq=400000)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
# Wait for connect or fail
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
utime.sleep(1)
# Define blinking function for onboard LED to indicate error codes
def blink_onboard_led(num_blinks):
led = machine.Pin('LED', machine.Pin.OUT)
for i in range(num_blinks):
led.on()
utime.sleep(.2)
led.off()
utime.sleep(.2)
# Handle connection error
# Error meanings
# 0 Link Down
# 1 Link Join
# 2 Link NoIp
# 3 Link Up
# -1 Link Fail
# -2 Link NoNet
# -3 Link BadAuth
wlan_status = wlan.status()
blink_onboard_led(wlan_status)
if wlan_status != 3:
raise RuntimeError('Wi-Fi connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print('ip = ' + status[0])
#コインチェックのAPIのURL
url = 'https://coincheck.com/api/ticker'
while True:
cc = requests.get(url).json()
cc_last = '{:,}'.format(int(cc['last']))
print("Coincheck 現在のビットコインの価格 =", cc_last, "円")
oled.fill(0)
oled.text("BTC/JPY", 0, 5)
oled.hline(0, 20, 128, 1)
oled.text(str(cc_last), 30, 30)
oled.show()
utime.sleep(20)
Picoで有機ELディスプレイを使う方法は、以下のサイトが参考になります。
≫【Raspberry Pi Pico】OLEDディスプレイ(I2C)に文字を描画する方法【MicroPython】
インターネットから時刻を取得する

時刻同期を行うことで、センサーデータやログデータなどのタイムスタンプを正確に記録することができます。以下のコードはNTP(Network Time Protocol)を使用して時刻同期を行い、現在の日付と時刻を出力するものです。
import time
import network
import ntptime
import machine
#自宅Wi-FiのSSIDとパスワードを入力
ssid = 'YOUR NETWORK SSID'
password = 'YOUR NETWORK PASSWORD'
# Wi-Fi設定
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('接続待ち...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('ネットワーク接続失敗')
else:
print('接続完了')
status = wlan.ifconfig()
print( 'IPアドレス = ' + status[0] )
# NTPサーバーとして"time.cloudflare.com"を指定
ntptime.host = "time.cloudflare.com"
# 時間の同期を試みる
try:
# NTPサーバーから取得した時刻でPico WのRTCを同期
ntptime.settime()
except:
print("時間の同期に失敗しました。")
raise
# 世界標準時に9時間加算し日本時間を算出
tm = time.localtime(time.time() + 9 * 60 * 60)
# 現在の日付と時刻を「年/月/日 時:分:秒」の形式で表示
print("{0}/{1:02d}/{2:02d} {3:02d}:{4:02d}:{5:02d}".format(tm[0], tm[1], tm[2], tm[3], tm[4], tm[5]))
NTPサーバーはインターネット経由で正確な時間情報を提供するサーバーです。”time.cloudflare.com”は、Cloudflareが提供する信頼性の高いNTPサーバーで、多くのデバイスやアプリケーションで使用されています。
上記のコードを実行すると、現在の日付と時刻が出力されます。

このコードはインターネットから現在の日時を取得し、日本の時間帯に合わせて日時を調整するものです。最後に、調整した日時を「年/月/日 時:分:秒」の形式で表示します。
ピンヘッダーを取り付ければ可能性は無限大
Wi-Fiの便利さは偉大です。Pico W本体だけでも多くの楽しみ方があります。今回の記事ではPico W本体のLEDをWi-Fi経由で操作する方法やLINEへメッセージを送る方法を解説しました。

Pico Wには40か所の入出力があります。ここに別売りのピンヘッダーをはんだ付けすれば、さまざまな電子パーツを簡単に接続可能です。スマホからモーターを操作したり、センサーの値を通知をしたりと活用の幅が大きく広がります。
はんだ付けに自信がない方は、Raspberry Pi Pico WHというピンヘッダー付きのモデルを検討してみましょう。

Pico Wの本を書きました

Pico Wの活用方法をさらに知りたい方におすすめなのが、私の書籍「ラズパイPico WかんたんIoT電子工作レシピ(技術評論社)」です。
この本は無線機能付のPico Wに特化した内容となっています。これから電子工作をはじめる人や、ラズパイは使ったことがあるけどPico Wは初めてという方に向けて書きました。あまり難しい技術には触れず、応用しやすいシンプルなテクニックを多数紹介しています。
書籍の詳細はこちらの記事にまとめています。
コメント一覧
I have to say that your attention to detail is truly impressive. Every aspect of your website is so well-crafted and thought-out, from the layout to the content to the images. It’s clear that you have a real passion for what you do, and it shows in every aspect of your work. Thank you for setting such a high standard for excellence!
とてもわかりやすい記事,参考になりました.ページ内で公開されているサンプルコードですぐにHTTPサーバ動作を確認することができました.ありがとうございます!
ところで.. Thonnyの場合,「print( ‘ip = http://‘ + status[0] )」のように,IPアドレス前に「http://」を足しておくとシェル表示内でハイパーリンクになってくれるようです.コピペの手間が減って便利です(^^)
先日,国内でも各社からの供給が始まったみたいなので,今後のユーザの拡大が楽しみです!
この記事を参考にしてPicoのボード上のLEDを点滅させることができました。
助かりました。ありがとうございます
https://twitter.com/Tanuki_Bayashin/status/1645435957641113600
ブログ記事を読んでいただき、ありがとうございます。
Picoのボード上のLEDを点滅させることができたとのことで、大変うれしく思います。
読者の皆様に役立つ情報を提供できることが喜びであり、励みです。
またご質問やご意見がございましたら、いつでもお気軽にコメントください。
分かりやすい記事ありがとうございます。
インターネットから時刻を取得するプログラムで、以下のエラーが発生するのですが、どのようにすればよろしいでしょうか。
Connected
ip = 192.168.0.19
Traceback (most recent call last):
File “”, line 53, in
File “ntptime.py”, line 1, in settime
File “ntptime.py”, line 1, in time
OSError: -2
ブログを見ていただきありがとうございます。
このエラーはネットワーク接続が不安定でNTPサーバに接続できないようです。
まず、49行目(while True:の前)にutime.sleep(5)を追加して、
5秒待ってからNTPサーバに接続するよう変更してみてください。
utime.sleep(5) # 5秒待ってからNTPサーバに接続
while True:
timZone = 9
ntptime.host = “ntp.nict.jp”
ntptime.settime()
またファームウェアに関して、古いものを使っている場合は、
最新のファームウェアをインストールしてみてください。
色々マイコン関係の記事はありますが 経験者はともかく、初心者は記事を頼りに手探りで学習しています。
初心者向けの記事といいながら実は初心者の心を見事に折る記事が散見される中
こちらの記事は本当に初心者が見てもわかりやすく安定感があり、素晴らしいの一言です
コメントをいただきありがとうございます。
私の記事が少しでもお手伝いできているとのこと、とても嬉しいです。
初心者向けに記事を書くのは難しい部分もありますが、読者の方々からのフィードバックを通じて
より良い記事作りに励んでいます。
「初心者が見てもわかりやすく安定感がある」との評価、大変励みになります。
これからも初心者の方が取り組みやすい内容を心掛け、皆様のお役に立てるような記事を提供します。
コメント失礼します。電子工作の初心者です
このブログを拝読しまして pico w のセットアップやサンプルプログラムを実行できるようになりました
いつもためになる記事をありがとうございます
ところで乾電池の駆動について質問です
ピンヘッダーをはんだ付けし、ブレッドボード上で単三乾電池 3 本を直列でプラスを VSYS (39) 、マイナスを GND (38) に接続したところ、ラズパイ本体から「ジー」という音が聞こえてきます
USB からの給電ではそういった音は聞こえてこないのですが、原因がわかりません
はんだ付けがうまくいってなくてそういう音が聞こえてくることがあるのでしょうか?
もし何かご存知のことございましたらご教示いただきたいと思いました
お忙しいところ大変恐縮ですが、どうぞよろしくお願いいたします
コメントありがとうございます。
接続方法は問題ないと思われます。調べたところ
ハンダ付けが不完全であったり、冷却が不十分だったりすると、
部品間の接続が不安定になり、ノイズが発生することがあるようです。
ハンダ付けの状態を再確認し、必要であれば修正してみてください。
はんだ付けは一筋縄ではいかないですね・・
お返事いただきありがとうございます!
これからも面白い記事を楽しみにしております!私もいろいろチャレンジしてみたいと思います!
通信初心者にて教えてください。
インターネットに接続せずに、ルータを経由してWifi端末同士での通信は可能でしょうか?
古いルータで”LEDのon/off+CPU温度取得”のPRG例で試したのですが、
PC側はルータに接続できるのですが、PICO側は接続エラーとなります。
原因は何でしょうか?
返信が遅くなりまして申し訳ございません。
お問い合わせの内容についてですが、インターネットに接続せずに、ルータを経由してWifi端末同士での通信は基本的に可能です。
しかし、ご質問の通りRaspberry Pi Pico Wからルータへの接続がうまく行かないとのことで、その原因については以下の可能性が考えられます。
SSIDとパスワード: Raspberry Pi Pico Wで設定しているルータのSSIDとパスワードが正しいか確認してみてください。大文字・小文字の区別、スペル、スペースなど正しいか再確認ください。
Wi-Fi信号: Raspberry Pi Pico WがWi-Fiの信号範囲内にあることを確認してみてください。
ルータの設定: ルータが新しいデバイスの接続を許可する設定になっているか確認してみてください。また、ルータが2.4GHzのWi-Fiをサポートしていることも確認が必要です。Raspberry Pi Pico Wは2.4GHzのWi-Fiのみに対応しており、5GHzのWi-Fiには接続できません。
MicroPythonのバージョン: Raspberry Pi Pico WにインストールされているMicroPythonのバージョンが最新であることを確認してみてください。バージョンが古いか、ハードウェアとの互換性がない場合、接続に問題が生じることがあります。
これらの点をチェックしてみてください。
それでも問題が解決しない場合、具体的なエラーメッセージなどを教えていただけると、より具体的なアドバイスが可能となります。
最近ラズパイを初め、参考にさせて頂いています。
Pico W本体のLEDをWi-Fi経由で操作する をしようとしたのですが以下エラーとなってしまいます。
MPY: soft reboot
Traceback (most recent call last):
File “”, line 41
IndentationError: unindent doesn’t match any outer indent level
これはどのようなエラーなのでしょうか。
連絡が遅くなり申し訳ありません。
エラーメッセージによれば、「IndentationError: unindent doesn’t match any outer indent level」
という問題が発生しています。
このエラーは、Pythonのインデント(字下げ)が不正確であることを示しています。
具体的には、41行目でインデントが他の行と合っていない可能性が高いです。
Pythonではインデントが重要なので、この問題を解消するには以下の点に注意してください。
・タブとスペースを混用しない。
・同じブロック内のインデントは統一する。
コードを見直し、インデントが正確であるか確認してみてください。
回答ありがとうございます。
勉強になります。
よく見ると39行目のスペースが1つ多くインデントが不正確でした。
LEDがスマホで点灯するようになりました!
嬉しいです。
初心者にも大変わかりやすくて助かりました!
HTTPサーバの例など、無限ループするプログラムで停止したあともう一度実行するときにEADDRINUSEが出てしまうのは、KeyboardInterruptを捕まえてソケットを閉じてやるといいようです。
except KeyboardInterrupt:
s.close()
print(‘Freed the socket.’)
break
また、Visual Studio CodeでもMicro Picoというエクステンションを入れると似たような開発環境が手に入るようです。
https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go
ただターミナルでCtrl+CしてもKeyboardInterruptが投げられないので、その点はちょっと不便です。
コメントいただき、ありがとうございます。
EADDRINUSEの件は、いろいろ試した結果、
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
を追加することにしました。
socket.SO_REUSEADDR:というオプションを有効にすることで、
ソケットを閉じた直後でも、そのアドレスを再利用できるようです。
Thonnyの停止ボタンでプログラムを終了した場合でも、エラー回避できます。
自分も勉強になり、記事を改善できました。
ありがとうございました。
7月にコメントさせていただいた者です。前回の問題はクリアできました。SSIDが5Gを指定していました。 ありがとうございました。
今回は、wifiを使い、PI4を主局としてPICOWを子局(複数)として主局よりコマンドを発行し、子局よりデータを受信したいのです。 RS485などのシリアル通信しか経験がないので、具体的な方法がわかりません。
できればご指導いただけませんか?
前回のSSIDの5G設定の問題が解決してよかったです。
新しい質問に対して、Raspberry Pi 4(主局)とRaspberry Pi Pico W(子局)間での通信は、
ソケット通信を使うと良いでしょう。ソケット通信はWi-Fi経由でデータの送受信が可能です。
通常、Raspberry Pi Pico Wが「サーバー」役、Raspberry Pi 4が「クライアント」役になります。
Pythonの「socket」ライブラリを使えば、クライアントからサーバーへコマンドを送ることができます。
ぜひチャレンジしてみてください。
回答ありがとうございます。 ネットワーク通信の経験が無いので、通信規則からの勉強になりますが、教えていただいた「socket」ライブラリから挑戦してみます。
・すいませんが教えてください。
・pico-W同士で、一方はクライアント、もう一方はサーバとしてwifiルータ経由socket通信を行っています。
・1)5文字程度のデータをクライアントからサーバーに送信
・2)サーバーで受信して受領データをクライアントに送信
・3)クライアントでサーバーからの返信を受信
・いずれもsocketのクローズは無し。言語はmicropython
・1往復での処理時間を図ると250msec程かかっています。
・これが通常なのか?、もっと高速にするにはどのようにすればよいかアドバイスありましたらお教えください。
コメントいただきありがとうございます。
Pico W同士でのWi-Fiルーター経由のSocket通信において、処理時間が250ミリ秒かかっていることについてですが、
これは環境によりますが通常の範囲内と考えます。
特にWi-Fiの速度、ルーターの性能、通信の安定性などは処理速度に大きく影響するようです。
また、MicroPythonはC言語などの低レベル言語と比較して実行効率が若干落ちることがあり、
これが処理時間に影響を与える可能性があります。
しかし、高速化する方法については私の知識範囲を超えているため、具体的なアドバイスを提供することが難しいです。
記事の中でtiny_line.pyをコピペしてraspberry pi pico に書き込み、次のプログラムの from tiny_line import tiny_lineでエラーが出ます。なぜかわからない。
BOOTSELボタンを押してLINEにメッセージを送るのプログラムです。エラーは、from tiny_line import tiny_lineです
エラーの原因として、いくつかの点を確認していただきたいと思います。
まず、tiny_line.pyというファイル名で正しく保存されているかどうかをご確認ください。ファイル名に余分なスペースが入っていたり、拡張子が間違っている場合、エラーの原因となることがあります。
次に、そのファイルがプログラムを実行しているディレクトリ(フォルダ)に正しく保存されているかも重要です。MicroPythonでは、使用するモジュールファイルが実行するファイルと同じ場所に存在する必要があります
解決しない場合は、エラーの具体的なメッセージ(例:ModuleNotFoundErrorなど)を教えていただければ、より詳しいサポートが可能です。
よろしくお願いいたします。
>>> %Run -c $EDITOR_CONTENT
Traceback (most recent call last):
File “”, line 1, in
File “tiny_line.py”, line 2, in
ImportError: no module named ‘ussl’
このような結果です。
プロパティでみるとパス ./tiny_line.py ./sora.py です
きたな pico W
電子工作 最強ですね
楽しみです