こんにちは、あろっちです。
Raspberry Pi Pico Wを入手したのでArduinoとMicroPythonで試してみたいと思います。
参考URL:
デバッガー使用方法は次の記事を参考にしてください。
Arduino IDE以外の開発環境についての記事はこちら
特徴
無線通信モジュールを搭載したRaspberry Pi Picoです。
※1 WPA3は通信を暗号化するためのセキュリティプロトコルです。
※2 SoftAP、Stationモードについて
SoftAP(ソフトウェアアクセスポイント)
→サーバー(ルーター)として振る舞うモードです。
平たく言うと単独でWi-Fiを動作させることができるモードです。
最大4台までクライアントを接続できます。
Station
→クライアントとして動作するモードです。
平たく言うと、他のWi-Fi(自宅のルーターなど)に接続して動作するモードです。
MCU | RP2040 デュアルコア ARM Cortex M0+プロセッサ、最大動作周波数 133 MHz |
フラッシュ メモリ | 2MB |
GPIO | 26(ピン配列はRaspberry Pi Pico互換) |
RP2040搭載ボードまとめ記事(参考サイト)
ピン配列

ギャラリー
技適マークは梱包材に貼られています。そのため保管しておく必要があります。

表

裏

ピンヘッダー実装後

USBマスストレージモード
以下の記事を参考にしてください。
Arduino IDEの設定
- Arduino IDEにボードを追加
※実施済みの場合、この手順は不要です。
事前にRaspberry Pi Pico/RP2040ボード(Arduino-Pico)を追加します。
追加方法は、以下の記事をご覧ください。
- Raspberry Pi Pico/RP2040ボード(Arduino-Pico)のインストール
[ツール] > [ボード] > [ボードマネージャ]をクリックし、検索ボックスに「rp2040」と入力し、[Raspberry Pi Pico/RP2040]ボードをインストールします。
- ボードの選択
[ツール] > [ボード] > [Raspberry Pi RP2040(Ver)※] > [Raspberry Pi Pico W]を選択します。
※(Ver)の表示はArduino IDE 1系のみ
- シリアルポートの選択
[ツール] > [シリアルポート]からRaspberry Pi Pico Wが接続されているシリアルポートを選択します。
Chromebookなどシリアルポートから書き込みできない環境の場合、手動でスケッチを書き込みできます。
サンプルプログラム (Arduinoスケッチ)
スケッチ例
Arduino IDEのスケッチ例をいくつか試してみます。
SPI接続のLCDに関しましてLovyanGFX定義例の記事を書きました。
Blink
ファイル > スケッチ例 > 01.Basics > Blinkを開きRaspberry Pi Pico Wに書き込みます。

HelloServer
ファイル > スケッチ例 > WebServer > HelloServer
以下の箇所(your-ssid、your-password)を接続先Wi-FiのSSIDとパスワードに書き換えてスケッチを書き込みます。
#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK "your-password"
#endif
シリアルモニターを開くとHelloServerのIPアドレスが確認できます。
※確認できない場合はRaspberry Pi Pico Wを再起動してください。

接続してみる
ブラウザからIPアドレスを入力します。
http://IPアドレス

http://IPアドレス/inline

http://IPアドレス/適当な文字列
以下は文字列の指定例: http://IPアドレス/test?p=aloseed

HelloServer AP(アクセスポイント)版
AP(アクセスポイント)の例としてスケッチ例のHelloServerを改修してアクセスポイント版を作成しました。
接続先Wi-Fi不要で単独で動きます。
以下のWi-Fi(SSID)にスマホなどから接続してください。
ネットワーク名 (SSID) | PicoW |
パスワード | 0123456789 |
IPアドレスおよびデフォルトゲートウェイ | 192.168.40.1 |
サブネットマスク | 255.255.255.0 |
接続後、ブラウザから「http://192.168.40.1/」にアクセスするとHelloServerの画面が表示されます。

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <LEAmDNS.h>
#ifndef STASSID
#define STASSID "PicoW"
#define STAPSK "0123456789"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
const IPAddress ip(192, 168, 40, 1);
const IPAddress subnet(255, 255, 255, 0);
WebServer server(80);
const int led = LED_BUILTIN;
void handleRoot() {
digitalWrite(led, 1);
server.send(200, "text/plain", "hello from pico w!\r\n");
digitalWrite(led, 0);
}
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void setup(void) {
pinMode(led, OUTPUT);
digitalWrite(led, 0);
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(ip, ip, subnet);
WiFi.begin(ssid, password);
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("picow")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/inline", []() {
server.send(200, "text/plain", "this works as well");
});
server.on("/gif", []() {
static const uint8_t gif[] = {
0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x10, 0x00, 0x10, 0x00, 0x80, 0x01,
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x10, 0x00, 0x00, 0x02, 0x19, 0x8c, 0x8f, 0xa9, 0xcb, 0x9d,
0x00, 0x5f, 0x74, 0xb4, 0x56, 0xb0, 0xb0, 0xd2, 0xf2, 0x35, 0x1e, 0x4c,
0x0c, 0x24, 0x5a, 0xe6, 0x89, 0xa6, 0x4d, 0x01, 0x00, 0x3b
};
char gif_colored[sizeof(gif)];
memcpy_P(gif_colored, gif, sizeof(gif));
// Set the background to a random set of colors
gif_colored[16] = millis() % 256;
gif_colored[17] = millis() % 256;
gif_colored[18] = millis() % 256;
server.send(200, "image/gif", gif_colored, sizeof(gif_colored));
});
server.onNotFound(handleNotFound);
/////////////////////////////////////////////////////////
// Hook examples
server.addHook([](const String & method, const String & url, WiFiClient * client, WebServer::ContentTypeFunction contentType) {
(void)method; // GET, PUT, ...
(void)url; // example: /root/myfile.html
(void)client; // the webserver tcp client connection
(void)contentType; // contentType(".html") => "text/html"
Serial.printf("A useless web hook has passed\n");
return WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
server.addHook([](const String&, const String & url, WiFiClient*, WebServer::ContentTypeFunction) {
if (url.startsWith("/fail")) {
Serial.printf("An always failing web hook has been triggered\n");
return WebServer::CLIENT_MUST_STOP;
}
return WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
server.addHook([](const String&, const String & url, WiFiClient * client, WebServer::ContentTypeFunction) {
if (url.startsWith("/dump")) {
Serial.printf("The dumper web hook is on the run\n");
// Here the request is not interpreted, so we cannot for sure
// swallow the exact amount matching the full request+content,
// hence the tcp connection cannot be handled anymore by the
auto last = millis();
while ((millis() - last) < 500) {
char buf[32];
size_t len = client->read((uint8_t*)buf, sizeof(buf));
if (len > 0) {
Serial.printf("(<%d> chars)", (int)len);
Serial.write(buf, len);
last = millis();
}
}
// Two choices: return MUST STOP and webserver will close it
// (we already have the example with '/fail' hook)
// or IS GIVEN and webserver will forget it
// trying with IS GIVEN and storing it on a dumb WiFiClient.
// check the client connection: it should not immediately be closed
// (make another '/dump' one to close the first)
Serial.printf("\nTelling server to forget this connection\n");
static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter
return WebServer::CLIENT_IS_GIVEN;
}
return WebServer::CLIENT_REQUEST_CAN_CONTINUE;
});
// Hook examples
/////////////////////////////////////////////////////////
server.begin();
Serial.println("HTTP server started");
}
void loop(void) {
server.handleClient();
MDNS.update();
}
OLEDクロック
OLED(I2C)を使った時計です。
Raspberry Pi Pico Wということで、Wi-Fiを通してNTPで時刻合わせを行うように実装してみました。
こちらの動画では自作のボードを使っていますが、以下の動画のようにブレッドボードで製作できます。

OLEDの配線について
OLED(I2C) | ピン/GPIO | 備考 |
---|---|---|
GND | GND | |
VCC | 3.3V | |
SCL | 5 | I2C SCL デフォルト |
SDA | 4 | I2C SDA デフォルト |
透明OLEDも使えました。

自作のプリント基板でも実装してみました。
このプリント基板の記事を書きました。ぜひご覧ください。
スケッチ
Arduino IDEのライブラリマネージャーから検索してインストールできます。

#include <WiFi.h>
#include <Wire.h>
#include <U8g2lib.h>
// WiFi接続情報
const char *ssid = "your-ssid";
const char *password = "your-password";
// 曜日表示文字
const char *weekChar[7] = { "日", "月", "火", "水", "木", "金", "土" };
// U8g2コンストラクタ
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
// NTPによる時刻同期関数
bool setClock() {
NTP.begin("ntp.nict.jp", "time.google.com");
return NTP.waitSet();
}
void setup() {
Serial.begin(115200);
Wire.begin();
Wire.setClock(400000);
u8g2.begin(); // OLED初期化
u8g2.setContrast(1);
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_crox1hb_tf);
u8g2.drawStr(0, 17, "WiFi connecting...");
u8g2.sendBuffer();
// WiFi接続
WiFi.begin(ssid, password);
if (WiFi.status() != WL_CONNECTED) {
u8g2.clearBuffer();
u8g2.drawStr(0, 17, "WiFi Connection failed");
u8g2.sendBuffer();
// Serial.println("WiFi Connection failed");
for (;;)
yield();
}
// NTP時刻同期
if (setClock()) {
// 時刻取得失敗時は停止
u8g2.clearBuffer();
u8g2.drawStr(0, 17, "Failed to obtain time");
u8g2.sendBuffer();
// Serial.println("Failed to obtain time");
for (;;)
yield();
}
// WiFi切断
WiFi.disconnect(true);
// 日本標準時をセット
setenv("TZ", "JST-9", 1);
tzset();
}
void loop() {
static time_t now;
static struct tm *timeinfo;
static int lastSec = -1;
static char buf[20];
// 現在時を取得
time(&now);
timeinfo = localtime(&now);
// 時刻が変わっているか判定
if (lastSec != timeinfo->tm_sec) {
lastSec = timeinfo->tm_sec;
// Serial.print(asctime(timeinfo));
// 時刻が変わった時に描画する
u8g2.clearBuffer();
// 時計用フォントをセット
u8g2.setFont(u8g2_font_crox5h_tn);
// 時分秒の描画
sprintf(buf, "%2d", timeinfo->tm_hour);
u8g2.drawStr(0, 17, buf);
sprintf(buf, "%02d", timeinfo->tm_min);
u8g2.drawStr(45, 17, buf);
sprintf(buf, "%02d", timeinfo->tm_sec);
u8g2.drawStr(87, 17, buf);
// 年月日の描画
sprintf(buf, "%4d", timeinfo->tm_year + 1900);
u8g2.drawStr(0, 40, buf);
sprintf(buf, "%2d", timeinfo->tm_mon + 1);
u8g2.drawStr(0, 64, buf);
sprintf(buf, "%2d", timeinfo->tm_mday);
u8g2.drawStr(48, 64, buf);
// 曜日()の描画
u8g2.setFont(u8g2_font_crox4h_tf);
u8g2.drawStr(96, 60, "(");
u8g2.drawStr(122, 60, ")");
// 年月日時分秒の描画
// 日本語フォントをセット
u8g2.setFont(u8g2_font_b16_b_t_japanese1);
u8g2.drawUTF8(28, 15, "時");
u8g2.drawUTF8(71, 15, "分");
u8g2.drawUTF8(113, 15, "秒");
u8g2.drawUTF8(54, 38, "年");
u8g2.drawUTF8(28, 62, "月");
u8g2.drawUTF8(76, 62, "日");
u8g2.drawUTF8(104, 62, weekChar[timeinfo->tm_wday]);
u8g2.sendBuffer();
}
yield();
}
your-ssid、your-passwordを接続先Wi-Fi(ご自宅のルーターなど)のSSIDとパスワードに書き換えてスケッチを書き込んでください。
サンプルプログラム (MicroPython)
OLEDクロック
OLED(I2C)を使った時計です。
Wi-Fiを通してNTPで時刻合わせを行うように実装しています。
MicroPython版はシンプルにssd1306ライブラリの標準フォントで表示しています。


OLEDの配線について
OLED(I2C) | ピン/GPIO | 備考 |
---|---|---|
GND | GND | |
VCC | 3.3V | |
SCL | 5 | I2C SCL デフォルト |
SDA | 4 | I2C SDA デフォルト |
from machine import I2C
import ssd1306
import ntptime
import time
import network
# WiFi接続情報
SSID = "your-ssid"
PASSWORD = "your-password"
# 画面サイズ
WIDTH = 128
HEIGHT = 64
# I2C設定とOLED初期化
i2c = I2C(0)
oled = ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c)
# 任意のNTPサーバー設定 (time.google.com)
ntptime.host = "time.google.com"
# 自動改行をする関数
def textln(text, x, y):
# 1行の文字数(画面幅に合わせて設定)
max_line_length = WIDTH // 8 # 1文字あたり8ピクセルとして計算
lines = [] # 改行された文字列を保持
# 文字列を最大行数で分割
for i in range(0, len(text), max_line_length):
lines.append(text[i : i + max_line_length])
# 各行を表示
for i, line in enumerate(lines):
oled.text(line, x, y + i * 8) # 8ピクセル(文字の高さ)ごとに改行
# WiFi接続
def connect_wifi():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(SSID, PASSWORD)
oled.fill(0) # 画面をクリア
textln("WiFi connecting...", 0, 10)
oled.show()
for _ in range(10): # 10秒以内に接続できなければ失敗
if wlan.isconnected():
oled.fill(0) # 画面をクリア
textln("WiFi connected!", 0, 10)
oled.show()
return wlan
time.sleep(1)
oled.fill(0) # 画面をクリア
textln("WiFi Failed", 0, 10)
oled.show()
return None
# NTPによる時刻同期
def sync_time():
try:
ntptime.settime()
except:
oled.fill(0)
textln("Failed to sync time", 0, 0)
oled.show()
raise
# 日本時刻の取得
def get_jst_time():
t = time.localtime(time.time() + 9 * 60 * 60) # JST: UTC + 9時間
return t
# 時刻をフォーマットしてOLEDに描画
def display_time():
now = get_jst_time()
hour, minute, second = now[3], now[4], now[5]
year, month, day, weekday = now[0], now[1], now[2], now[6]
weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
oled.fill(0)
# 年月日(曜日)の描画
oled.text(f"{year}-{month:02}-{day:02} ({weekdays[weekday]})", 0, 20)
# 時分秒の描画
oled.text(f"{hour:02}:{minute:02}:{second:02}", 0, 30)
oled.show()
# メイン処理
def main():
if not (wlan := connect_wifi()):
return
try:
sync_time()
except:
return
finally:
if wlan.isconnected():
wlan.disconnect()
last_sec = -1 # 秒が変わるまで待つための記録
while True:
now = get_jst_time()
current_sec = now[5] # 現在の秒
if current_sec != last_sec:
# 秒が変わった場合のみOLEDに描画
last_sec = current_sec
display_time()
time.sleep(0)
main()
your-ssid、your-passwordを接続先Wi-Fi(ご自宅のルーターなど)のSSIDとパスワードに書き換えてください。
関連記事
当ブログのマイコン記事です。ぜひご覧ください。
コメント