【Arduino】SeeedStudioのXIAO RP2350を使う

it

Seeed StudioのXIAO RP2350を使ってみました。
同じRaspber Pi のRP2040を搭載したXIAO RP2040との比較を中心に使ってみます。
XIAO RP2350のトラブルや、基板に搭載されているLEDの制御について記載します。

XIAO RA4M1

簡単紹介

RP2350搭載のXIAO基板。

◆パッケージ
SeeedStudioのパッケージで、本体に7ピンシングルのピンヘッダが1セット(2本)付属します。

SeeedStudio 製品サイト:https://wiki.seeedstudio.com/getting-started-xiao-rp2350/

◆関連記事

◆XIAOシリーズの記事

XIAO SAMD21XIAO SAMD21を使った記事。
基本的なGPIOの操作とDAC出力、書き込み時のトラブルについてまとめた記事です。
XIAO RP2040XIAO RP2040を使った記事。
使っている時に発生したI2CのWireとWire1問題、WS2812の点灯などトラブルを中心に記載しました。
XIAO ESP32-C3XIAO ESP32-C3を使った記事。
GPIOを使った基本スケッチ、BLE UARTを使った内容を記事にしました。
XIAO ESP32-S3XIAO ESP32-S3/XIAO ESP32-S3 Sense を使った記事。
GPIOを使った基本スケッチの他静電容量タッチセンサ、カメラWebサーバーを使った内容を記事にしました。
XIAO nRF52840XIAO nRF52840/XIAO nRF52840 Senseを使った記事。
GPIOを使った基本スケッチ、BLE UART他、XIAO nRF52840 SenseのIMU 6軸センサ、PDM Microphoneを使った内容を記事にしました。
XIAO RA4M1XIAO RA4M1を使った記事。
基板特有のトラブルと基本的なGPIOの操作について記事にしました。
XIAO RP2350XIAO RP2350を使った記事。
XIAO RP2040との比較を中心に搭載機能を使った内容を記事しました。
XIAO ESP32C6XIAO ESP32C6を使った記事。
基本的なGPIOの使い方からWiFiServerにして読み取ったDA値を表示してみた内容を記事にしました。

ピン配置

外観

使ってみた

◆開発環境

Arduino環境で開発しました。
ボードライブラリに「Raspberry Pi Pico/RP2040 by Earle F. Philhower, III」を使います。

このページではI2Cを使うサンプルにモジュールライブラリを使用します。
使用するライブラリはこちらに記載します。

◆外観の比較(vs XIAO RP2040)

左がXIAO RP2350、右がXIAO RP2040です。
XIAO規格なのでサイズ感は同じです。

実装LED類の移動(WS2812)や、ボタン類の小型化が目につきます。
CPUを覆うシールドカバーが大きくなった影響でボタンが小型になったのか、爪楊枝の後ろ側でようやく押せるサイズです。

背面は利用できるパッドが増えました。
機能パッドもありますが、GPIOが多く使えるようになりました。


◆スケッチの互換 (vs XIAO RP2040)

スケッチの互換はありますが、一部動作に互換が無い。
Raspberry Pi Pico と Raspberry Pi Pico2の互換問題は継続しています。

・pinMode()
INPUT_PULLDOWN, INPUT_PULLUPを設定できますが機能しません。
実回路でのプルアップ、プルダウン抵抗が必要です。(回路サンプル

◆ピン互換 (vs XIAO RP2040)

概ね互換あります。

RP2350のGPIO5位置は、RP2040のGPIO29です。
GPIO5とGPIO29では使用できるSPIのピンとしてはSPI0 CSとSPI1 CSの違いがありますが、CSは実質SPI0でもSPI1でも使用できるのであまり気にする必要はありません。

実装LEDは単色LED、WS2812の電源、DIN端子のGPIO番号の違いがあります。

ピンヘッダGPIO番号については、「Raspberry Pi Pico/RP2040 by Earle F. Philhower, III」の「Seeed XIAO RP2350」のピン定義D3を使用することで互換性が確保できます。

また、RP2040と同じでXIAO基板のI2Cピン位置は「wire1(I2C1)」ですが、ボードライブラリ「Raspberry Pi Pico/RP2040 by Earle F. Philhower, III」の「Seeed XIAO RP2350」によって「Wire(I2C0)」オブジェクトに書き換えられています。

I2CでOLEDを制御しました。
XIAO規格のI2C位置から「Wire」オブジェクトを使って「I2C1」を制御しています。

◆性能

Raspberry Pi Pico2 (RP2350) と Raspberry Pi Pico (RP2040) の比較と同じと判断し、XIAO RP2350とXIAO RP2040との比較は省略します。

準備

Arduino環境の作成

◆開発環境

開発環境はArduinoを使用します。
Arduino環境の作り方はこちらを参照します。

◆ボードライブラリ

Arduino IDEのボードマネージャからRP2350用のライブラリのインストールとボードの選択をします。
ボードライブラリには「Raspberry Pi Pico/RP2040/RP2350 by EarleF.Philhower, III」を使用します。

追加のボードマネージャのURLhttps://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
検索RP2350
ボードライブラリRaspberry Pi Pico/RP2040/RP2350 by EarleF.Philhower, III
選択するボードRaspberry Pi Pico/RP2040/RP2350 > Seeed XIAO RP2350
※動作確認はバージョン 4.4.3です

◆モジュールライブラリ

I2CのサンプルではOLED(SSD1306)を使用します。
サンプルを使用しない場合はインストール不要です。

SSD1306

OLED(SSD1306)を使用する場合にインストールします。

ライブラリ名検索確認時のバージョン
Adafruit SSD1306 by AdafruitSSD13062.5.11
Adafruit GFX Library by AdafruitGFX1.11.10

WS2812B

WS2812Bを使用する場合にインストールします。

ライブラリ名検索確認時のバージョン
Adafruit NeoPixel by Adafruitnexpixel1.12.3

コンパイルと書き込み

Arduino IDEの書き込みボタンから書き込みができます。

トラブル

プルアップ/プルダウンできない

◆症状

GPIOの入出力方向を設定する関数pinMode()のパラメータではINPUT_PULLDOWN, INPUT_PULLUPを設定できるが機能しない。

◆対応

実回路でプルアップ、プルダウン抵抗を使う。
プルダウンのサンプルは「GPIOデジタル入出力」で紹介します。

ユーザーLEDの点灯

◆症状

ユーザLEDを使用しないスケッチで発生する。
スケッチを実行させるとユーザLEDが半点灯状態になる。

黄LEDの点灯状態です。
画像左上は半点灯状態です。
左下が点灯(GPIO出力はLow)、右は消灯(GPIO出力はHigh)の状態です。

◆対応

Setup()で出力をLowにする。
以下2行追記することで解消します。

  pinMode(25, OUTPUT);
  digitalWrite(25, HIGH);

スケッチ

GPIOデジタル入出力

◆説明

GPIOのデジタル入出力をします。
ボタンを反している間UserLED(GPIO25)を点灯、押している間LEDを消灯します。
UserLEDは電圧がLowの状態で点灯します。

XIAO RP2350ではpinModeにINPUT_PULLDOWN, INPUT_PULLUPを設定できますが、電圧はプルダウン、プルアップしません。
デジタル入力を正確に読み取るためにはプルダウン、プルアップ抵抗により実回路で実現します。

◆配線

ボタンの入力状態をプルダウンして読み取る回路

◆スケッチ

#define LED_PIN     (PIN_LED)
#define BUTTON_PIN  (D1)

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT);

  while(1)
  {
    digitalWrite(LED_PIN, digitalRead(BUTTON_PIN));
  }
}

void loop()
{}

◆結果

UserLEDはLow状態(ボタンを離している状態)で点灯、Hight状態(ボタンを押している状態)で消灯です。

WS2812

◆説明

WS2812を点灯させます。
赤>緑>黄>青>紫>水>白の順に点灯します。
輝度は0 ~ 255段階で設定できますが、半値の128を設定します。

XIAO RP2350のWS2812を使用するために、電源をON(GPIO23をHigh)にします。

◆XIAO RP2040との差分

ピンアサインに違いがあります。

RP2350RP2040
WS2812電源2311
WS2812 DIN2212

◆配線

配線不要

◆スケッチ

#include <Adafruit_NeoPixel.h>

#define POWER_PIN     (23)
#define DIN_PIN       (22)
#define LED_COUNT     (1)
#define WAIT_MS       (1000)
#define BRIGHTNESS    (128)
Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  pinMode(POWER_PIN, OUTPUT);
  digitalWrite(POWER_PIN, HIGH);

  pixels.begin();
}

void loop()
{
  pixels.clear();
  
  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, 0, 0));
  pixels.show();
  delay(WAIT_MS);

  pixels.setPixelColor(0, pixels.Color(0, BRIGHTNESS, 0));
  pixels.show();
  delay(WAIT_MS);

  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, BRIGHTNESS, 0));
  pixels.show();
  delay(WAIT_MS);

  pixels.setPixelColor(0, pixels.Color(0, 0, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);

  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, 0, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);

  pixels.setPixelColor(0, pixels.Color(0, BRIGHTNESS, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);

  pixels.setPixelColor(0, pixels.Color(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS));
  pixels.show();
  delay(WAIT_MS);
}

◆結果

各色要素半値(0~255のうちの128)を使用しています。
小型のWS2812ですが十分な輝度があります。

I2C(SSD1306)

◆説明

XIAO RP2350のI2CからSSD1306を表示制御します。

XIAO規格のI2Cのピン番号はGPIO6(I2C1 SDA)とGPIO7(I2C1 SCL)が割り当てられています。


本来「Wire1」オブジェクトを使用することになりますが、「Raspberry Pi Pico/RP2040/RP2350 by EarleF.Philhower, III」の「Seeed XIAO RP2350」を使用すると「Wire」オブジェクトを使用できます。

使用するモジュールライブラリはAdafruitの「Adafruit SSD1306 by Adafruit」です。
SSD1306のI2Cアドレスは3c(h)です。

画面にはRaspbery Piのロゴを表示します。

◆配線

◆スケッチ

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH    (128)
#define SCREEN_HEIGHT   (64)

#define OLED_RESET      (-1)
#define SCREEN_ADDRESS  (0x3C)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


#define LOGO_HEIGHT     (64)
#define LOGO_WIDTH      (64)

static const unsigned char PROGMEM logo_bmp[] =
{
0x00, 0x07, 0xE0, 0x01, 0xF8, 0x00, 0x00, 0x00,    //0
0x00, 0x7F, 0xF8, 0x07, 0xFF, 0x00, 0x00, 0x00,    //1
0x01, 0xE0, 0x1E, 0x1C, 0x01, 0xC0, 0x00, 0x00,    //2
0x01, 0x80, 0x03, 0x30, 0x00, 0x60, 0x00, 0x00,    //3
0x01, 0x80, 0x01, 0x20, 0x00, 0x60, 0x00, 0x00,    //4
0x01, 0x80, 0x01, 0xE0, 0x00, 0x60, 0x00, 0x00,    //5
0x00, 0x80, 0x80, 0xC0, 0x00, 0x40, 0x00, 0x00,    //6
0x00, 0xC0, 0x60, 0xC0, 0x80, 0xC0, 0x00, 0x00,    //7
0x00, 0xC0, 0x10, 0xE2, 0x00, 0xC0, 0x00, 0x00,    //8
0x00, 0x60, 0x0D, 0xE4, 0x01, 0x80, 0x00, 0x00,    //9
0x00, 0x60, 0x07, 0xF8, 0x01, 0x80, 0x00, 0x00,    //10
0x00, 0x30, 0x07, 0xF8, 0x03, 0x00, 0x00, 0x00,    //11
0x00, 0x18, 0x07, 0xFC, 0x06, 0x00, 0x00, 0x00,    //12
0x00, 0x0E, 0x1F, 0xFE, 0x1C, 0x00, 0x00, 0x00,    //13
0x00, 0x07, 0xFE, 0x1F, 0xF8, 0x00, 0x00, 0x00,    //14
0x00, 0x0E, 0x18, 0x06, 0x3C, 0x00, 0x00, 0x00,    //15
0x00, 0x18, 0x30, 0x02, 0x0E, 0x00, 0x00, 0x00,    //16
0x00, 0x30, 0x70, 0x03, 0x07, 0x00, 0x00, 0x00,    //17
0x00, 0x20, 0xF8, 0x03, 0x83, 0x00, 0x00, 0x00,    //18
0x00, 0x61, 0xFC, 0x0F, 0xC3, 0x00, 0x00, 0x00,    //19
0x00, 0x63, 0xFF, 0xF8, 0xF1, 0x80, 0x00, 0x00,    //20
0x00, 0x6F, 0x03, 0xF0, 0x39, 0x80, 0x00, 0x00,    //21
0x00, 0x7E, 0x01, 0xE0, 0x1F, 0x80, 0x00, 0x00,    //22
0x00, 0xFC, 0x00, 0xC0, 0x0F, 0xC0, 0x00, 0x00,    //23
0x01, 0x9C, 0x00, 0xC0, 0x0C, 0x60, 0x00, 0x00,    //24
0x03, 0x18, 0x00, 0xC0, 0x04, 0x70, 0x00, 0x00,    //25
0x03, 0x18, 0x00, 0xC0, 0x04, 0x30, 0x00, 0x00,    //26
0x02, 0x18, 0x00, 0xE0, 0x04, 0x30, 0x00, 0x00,    //27
0x06, 0x18, 0x01, 0xE0, 0x04, 0x38, 0x00, 0x00,    //28
0x06, 0x1C, 0x03, 0xF0, 0x0E, 0x38, 0x00, 0x00,    //29
0x02, 0x1C, 0x07, 0xF8, 0x1E, 0x30, 0x00, 0x00,    //30
0x02, 0x3F, 0x0C, 0x0E, 0x3E, 0x30, 0x00, 0x00,    //31
0x03, 0x3F, 0xF8, 0x07, 0xFF, 0x70, 0x00, 0x00,    //32
0x01, 0xE7, 0xF0, 0x03, 0xF1, 0xE0, 0x00, 0x00,    //33
0x01, 0xE1, 0xF0, 0x03, 0xE0, 0xE0, 0x00, 0x00,    //34
0x00, 0xC0, 0xE0, 0x01, 0xC0, 0xC0, 0x00, 0x00,    //35
0x00, 0xC0, 0x60, 0x01, 0x80, 0xC0, 0x00, 0x00,    //36
0x00, 0xC0, 0x70, 0x01, 0x00, 0xC0, 0x00, 0x00,    //37
0x00, 0x40, 0x30, 0x03, 0x00, 0x80, 0x00, 0x00,    //38
0x00, 0x60, 0x30, 0x02, 0x01, 0x80, 0x00, 0x00,    //39
0x00, 0x60, 0x30, 0x0E, 0x01, 0x80, 0x00, 0x00,    //40
0x00, 0x30, 0x3F, 0xFE, 0x03, 0x00, 0x00, 0x00,    //41
0x00, 0x18, 0x3F, 0xFE, 0x06, 0x00, 0x00, 0x00,    //42
0x00, 0x0F, 0xFC, 0x0F, 0xFC, 0x00, 0x00, 0x00,    //43
0x00, 0x03, 0xF0, 0x03, 0xF0, 0x00, 0x00, 0x00,    //44
0x00, 0x01, 0xF0, 0x03, 0xE0, 0x00, 0x00, 0x00,    //45
0x00, 0x00, 0x70, 0x07, 0x80, 0x00, 0x00, 0x00,    //46
0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x00, 0x00,    //47
0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00,    //48
0x00, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00,    //49
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //50
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //51
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //52
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //53
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //54
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //55
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //56
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //57
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //58
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //59
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //60
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //61
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //62
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    //63
};

void testdrawbitmap(void);

void setup()
{
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  display.clearDisplay();

  display.drawBitmap(32, 0, logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

void loop()
{
}

◆結果

XIAO規格のI2C位置からI2C1をWireオブジェクトで使いました。
遜色なく使えています。

コメント

タイトルとURLをコピーしました