こんにちは、あろっちです。
Raspberry Pi Pico Wを入手したのでArduinoで試してみたいと思います。
参考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ボード(earlephilhower版)を追加します。
追加方法は、以下の記事をご覧ください。
- Raspberry Pi Pico/RP2040ボード(earlephilhower版)のインストール
[ツール] > [ボード] > [ボードマネージャ]をクリックし、検索ボックスに「rp2040」と入力し、[Raspberry Pi Pico/RP2040]ボードをインストールします。
- ボードの選択
[ツール] > [ボード] > [Raspberry Pi RP2040 Boards(Ver)※] > [Raspberry Pi Pico W]を選択します。
※Boards(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も使えました。

スケッチ
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とパスワードに書き換えてスケッチを書き込んでください。
OLEDの配線について
OLED(I2C) | ピン/GPIO | 備考 |
---|---|---|
GND | GND | |
VCC | 3.3V | |
SCL | 5 | I2C SCL デフォルト |
SDA | 4 | I2C SDA デフォルト |
関連記事
当ブログのマイコン記事です。ぜひご覧ください。
コメント