Seeed XIAO RP2040を試してみました【Arduino使用】

Raspberry Pi/電子工作
スポンサーリンク
スポンサーリンク

こんにちは、あろっちです。

Seeed XIAO RP2040を入手したので試してみました。

Seeed XIAO RP2040は、MCUにRP2040を搭載したXIAOです。Seeeduino XIAOとピン配置/形状に互換性があるのが特徴です。
フラッシュメモリの容量(2MB)などRaspberry Pi Picoに近いスペックに見受けられます。

他のRP2040搭載Seeeduino XIAO互換のマイコンに、Adafruit QT Py RP2040がありますが、こちらは、フラッシュメモリ8MB、QTコネクタ搭載という特徴があります。

Adafruit QT Py RP2040については記事にしていますので、よろしければご覧ください。

特徴

  • Seeeduino XIAO互換のピン配置/形状
  • USB Type-C
  • ユーザLED(RGB 3色)、RGB LED、電源LED
  • リセットボタン
  • ブートローダーセレクトボタン
  • ソフトウェアは、Arduino、MicroPython、CircuitPythonをサポート
MCURP2040 デュアルコア ARM Cortex M0+プロセッサ、最大動作周波数 133 MHz
フラッシュメモリ2MB
GPIO11
・11xディジタル&PWM, 4xアナログ対応(12bit ADC)
サイズ20×17.5×3.5mm
左からSeeeduino XIAO、Adafruit QT Py、Seeed XIAO RP2040、Adafruit QT Py RP2040、Adafruit QT Py ESP32-S2、Seeed XIAO BLE Sense

現在のXIAOシリーズの正式名称について

Seeed XIAO RP2040 - Supports Arduino, MicroPython and CircuitPython
XIAO RP2040 is a microcontroller using the Raspberry RP2040 chip. It runs at up to 133MHz, is built with rich interfaces in a tiny thumb size, and fully suppo...
Overview - Seeed Wiki
Seeed Product Document

Seeed XIAO BLE nRF52840 / Sense(参考サイト)

RP2040搭載ボードまとめ記事(参考サイト)

本記事ではArduino(C/C++)で試してみます。

ちなみに、開発環境としてVS Codeを使うこともできたりします。

PlatformIO IDEでの開発について記事を書きました。

Raspberry Pi Pico/RP2040ボード(earlephilhower版) Ver.1.13.2より正式にSeeed XIAO RP2040ボードがサポートされました。

スポンサーリンク
スポンサーリンク

ピン配列

GPIOのピン番号は、上図(FRONT)のMicropythonで示された番号(Pxx)です。

LEDGPIO(ピン番号)
LED(赤, TX)17
LED(緑, RX)16
LED(青, ユーザLED)25
RGB LED_POWER11
RGB LED12

RGB LEDを使用するには

RGB LEDを使用する場合、電源であるGPIO11をHIGHに引き上げる必要があります。

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

Raspberry Pi Pico/RP2040ボード(earlephilhower版) Ver.1.13.2以降のSeeed XIAO RP2040ボードでは、RGB LED用の定数(NEOPIXEL_POWER)が定義されているので、この定数を使って次のようにHIGHにできます。

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

Seeed XIAO RP2040ボードのバリエーションについて

調べた結果を一覧にまとめました。

ボードSeeed公式ボード
バージョン1.12.0まで
Seeed公式ボード
バージョン2.7.2
Raspberry Pi Pico/RP2040ボード(earlephilhower版)
バージョン2.0.2まで
Raspberry Pi Pico/RP2040ボード(earlephilhower版)
バージョン2.0.3以降
ボード種別(※2)Pico SDKArduino Mbed OS RP2040 BoardsPico SDKPico SDK
I2Cで使用するオブジェクトWire1
(要初期化※)
Wire
(初期化不可)
Wire1
(要初期化※)
Wire
(初期化不要)
SPI初期化不可(※備考参照)不要不要
備考pins_arduino.h

HW SPIのピンアサインがXIAO RP2040のピンに合っていない
定数Dx(D0〜D10)が未定義

※Raspberry Pi Pico/RP2040のデフォルト定義は存在するがXIAO RP2040向けに変更されていない

※Wire1を使う場合に後述の初期化処理が必要になる感じです。

※2 ボード種別について
ArduinoにはRP2040ボードが2種類あり、それについては以下の記事で少し触れていますのでご参考になればと思います。

Seeed公式ボードについて

バージョン2.7.2Arduino Mbed OS RP2040ベースのボードです。
バージョン1.12.0Raspberry Pi Pico/RP2040ボード(earlephilhower版)ベースのボードです。

Raspberry Pi Pico/RP2040ボード(earlephilhower版)について

Raspberry Pi Pico/RP2040ボード(earlephilhower版) Ver.1.13.2より正式にSeeed XIAO RP2040ボードがサポートされました。

バージョン2.0.3以降ではI2CをWireで使用できるように変更されたようです。

Pico SDKベースのボードを使いたい場合、本記事に記載のI2CやSPIの初期化処理が不要になるように修正されたRaspberry Pi Pico/RP2040ボード(earlephilhower版)(バージョン2.0.3以降)のSeeed XIAO RP2040ボードのご使用をおすすめします。
※2022年9月8日

ボードの判定方法について

ボードのバリエーションを判定するためのコード例を記載します。

// Seeed公式 Seeed XIAO RP2040ボード(バージョン1.12.0まで)の判定条件
#define XIAO_RP2040_OFFICIAL_OLD_BOARD (!(defined(ARDUINO_SEEED_XIAO_RP2040) || defined(ARDUINO_SEEED_XAIO_RP2040)))

// Seeed公式 Seeed XIAO RP2040ボード(バージョン2.7.2)の判定条件
#define XIAO_RP2040_OFFICIAL_NEW_BOARD (defined(ARDUINO_SEEED_XIAO_RP2040) && defined(ARDUINO_ARCH_MBED))

// Seeed XIAO RP2040ボード(earlephilhower版)(バージョン2.0.2まで)の判定条件
#define XIAO_RP2040_OLD_BOARD (defined(ARDUINO_SEEED_XAIO_RP2040) && !defined(__WIRE0_DEVICE))

// Seeed XIAO RP2040ボード(earlephilhower版)(バージョン2.0.3以降)の判定条件
#define XIAO_RP2040_BOARD ((defined(ARDUINO_SEEED_XIAO_RP2040) && !defined(ARDUINO_ARCH_MBED)) || (defined(ARDUINO_SEEED_XAIO_RP2040) && defined(__WIRE0_DEVICE)))

// Seeed公式 Seeed XIAO RP2040ボード(バージョン2.7.2)、Seeed XIAO RP2040ボード(earlephilhower版)(バージョン2.0.3以降)の判定条件
#define XIAO_RP2040_NEW_BOARD (defined(ARDUINO_SEEED_XIAO_RP2040) || (defined(ARDUINO_SEEED_XAIO_RP2040) && defined(__WIRE0_DEVICE)))

// 上記定数を使った判定
#if !XIAO_RP2040_NEW_BOARD
// Seeed公式 Seeed XIAO RP2040ボード(バージョン1.12.0)、Seeed XIAO RP2040ボード(earlephilhower版)(バージョン2.0.2まで)の場合
#else
// Seeed公式 Seeed XIAO RP2040ボード(バージョン2.7.2)、Seeed XIAO RP2040ボード(earlephilhower版)(バージョン2.0.3以降)の場合
#endif

こちらの判定を用いたサンプルプログラムとして、本記事に「I2Cスキャナ」「OLEDディスプレイを表示してみる(Adafruit SSD1306ライブラリ編)」「OLEDディスプレイを表示してみる(U8g2ライブラリ編)」を掲載しました。※2022年9月8日

Raspberry Pi Pico/RP2040ボードの判定方法や定義名を記事にまとめました。

I2Cについて

Raspberry Pi Pico/RP2040ボード(earlephilhower版)(バージョン2.0.3以降)やSeeed公式 Seeed XIAO RP2040ボード(バージョン2.7.2)の場合Wireをそのまま使用できます。

本記事にSeeed XIAO RP2040全ボードに対応した(※2022年9月8日時点)「I2Cスキャナ」「OLEDディスプレイを表示してみる(U8g2ライブラリ編)」を掲載しました。

初期化方法(Wire1使用ボード対象)

Wire1を使うボードを対象とした情報となります。※2022年9月8日

I2Cは、I2C1(SDA=GPIO6、SCL=GPIO7)です。
setup関数内で以下のように初期化します。

  Wire1.setSDA(SDA);
  Wire1.setSCL(SCL);

()内のSDA、SCLは、ArduinoのSeeed XIAO RP2040ボード(pins_arduino.h)に定義された定数です。
したがって、次のように直接GPIOのピン番号に置き換えることもできます。

  Wire1.setSDA(6);
  Wire1.setSCL(7);

ボードバリエーションに対応する場合の例

// Seeed公式 Seeed XIAO RP2040ボード(バージョン2.7.2)、Seeed XIAO RP2040ボード(earlephilhower版)(バージョン2.0.3以降)の判定条件
#define XIAO_RP2040_NEW_BOARD (defined(ARDUINO_SEEED_XIAO_RP2040) || (defined(ARDUINO_SEEED_XAIO_RP2040) && defined(__WIRE0_DEVICE)))

// WireとWire1を透過的に扱えるようにするには共通のマクロ(ここではWIREとします)を定義します
#if XIAO_RP2040_NEW_BOARD
#define WIRE Wire
#else
#define WIRE Wire1
#endif

void setup()
{
#if !XIAO_RP2040_NEW_BOARD
  WIRE.setSDA(SDA);
  WIRE.setSCL(SCL);
#endif
// マクロWIREを使ってコーディングします
  WIRE.begin();

SPIについて

Raspberry Pi Pico/RP2040ボード(earlephilhower版)の場合SPIをそのまま使用できます。

初期化方法

Seeed公式 Seeed XIAO RP2040ボード(バージョン1.12.0まで)を対象とした情報となります。
※2022年9月8日

RP2040では、MOSIがTX、MISOがRXという名称になっているようです。
※Raspberry Pi PicoのPinoutにて確認

SPIはsetup関数内で次のように初期化できます。

  SPI.setTX(MOSI);
  SPI.setRX(MISO);
  SPI.setSCK(SCK);

()内のMOSI、MISO、SCKは、ArduinoのSeeed XIAO RP2040ボード(pins_arduino.h)に定義された定数です。
したがって、次のように直接GPIOのピン番号に置き換えることもできます。

  SPI.setTX(3);
  SPI.setRX(4);
  SPI.setSCK(2);

Seeed公式 Seeed XIAO RP2040ボード(バージョン1.12.0まで)を初期化対象とする場合の例

// Seeed公式 Seeed XIAO RP2040ボード(バージョン1.12.0まで)の判定条件
#define XIAO_RP2040_OFFICIAL_OLD_BOARD (!(defined(ARDUINO_SEEED_XIAO_RP2040) || defined(ARDUINO_SEEED_XAIO_RP2040)))

void setup()
{
#if XIAO_RP2040_OFFICIAL_OLD_BOARD
  SPI.setTX(MOSI);
  SPI.setRX(MISO);
  SPI.setSCK(SCK);
#endif

※本記事のGPIOについては、Raspberry Pi Pico(RP2040のリファレンスボード)のPinoutを参考にしています。
例えば、I2Cについては、GPIO6、GPIO7がI2C1であることが読み取れます。

XIAO RP2040 回路図

内容物

1 x XIAO RP2040
2 x ピンヘッダ 7ピン

初回起動はこんな感じです。

ピンヘッダー装着後

他のXIAO系ボードと並べてみました。

左からSeeeduino XIAO、Adafruit QT Py、Seeed XIAO RP2040、Adafruit QT Py RP2040、Adafruit QT Py ESP32-S2、Seeed XIAO BLE Sense

現在のXIAOシリーズの正式名称について

Seeed XIAO BLE nRF52840 / Sense(参考サイト)

USBマスストレージモード

BOOTボタンを押した状態で、リセットボタンを押すと、USBマスストレージモード(RPI-RP2)になります。

USBマスストレージモードの時に、PCからMicroPythonやCircuitPythonのファームウェアなどがインストールできます。

MicroPythonでPicoインベーダーを再現するとこんな感じです。

Seeeduino XIAO 拡張ボードにGroveのボリュームを使っています。
電源には、リチウムイオンバッテリーを使ってみました。

Picoインベーダーについては、以下の記事をご覧ください。※XIAO RP2040の例も掲載しました。

XIAO RP2040 with MicroPython(公式Wiki)

XIAO RP2040 with MicroPython - Seeed Wiki
Seeed Product Document

XIAO RP2040 with CircuitPython(公式Wiki)

XIAO RP2040 with CircuitPython - Seeed Wiki
Seeed Product Document

Arduinoボード設定

Seeed XIAO RP2040ボードの場合

  • Arduino IDEにボードを追加
    ※実施済みの場合、この手順は不要です。

事前にSeeeduino XIAOボードを追加します。
追加方法は、以下の記事をご参照ください。

  • Seeed XIAO RP2040ボードのインストール

[ツール] > [ボード] > [ボードマネージャ]をクリックし、検索ボックスに「XIAO RP2040」と入力し、[Seeed XIAO RP2040]をインストールします。

バージョンによるボードの違いについて

バージョン2.7.2は、Arduino Mbed OS RP2040ベースのボードです。
バージョン1.12.0は、Raspberry Pi Pico/RP2040ボード(earlephilhower版)ベースのボードです。

  • ボードの選択

[ツール] > [ボード] > [Seeed RP2040 Boards] > [Seeed XIAO RP2040]を選択します。

  • シリアルポートの選択

[ツール] > [シリアルポート]からXIAO RP2040が接続されているシリアルポートを選択します。

Chromebookでシリアルポートから書き込みできない場合、手動でスケッチを書き込みできます。

Raspberry Pi Pico/RP2040ボード(earlephilhower版) Ver.1.13.2以降の場合

  • Arduino IDEにボードを追加
    ※実施済みの場合、この手順は不要です。

事前にRaspberry Pi Pico/RP2040ボード(earlephilhower版)を追加します。
追加方法は、以下の記事をご覧ください。

[ツール] > [ボード] > [ボードマネージャ]をクリックし、検索ボックスに「rp2040」と入力し、[Raspberry Pi RP2040 Boards(Ver.1.13.2以降)]をインストールします。

画像はRaspberry Pi Pico/RP2040ボード(earlephilhower版) Ver.2.0.1をインストール済み
  • ボードの選択

[ツール] > [ボード] > [Raspberry Pi RP2040 Boards(Ver)] > [Seeed XIAO RP2040]を選択します。
バージョン2.4.0より前は、ボード名が「XIAO」ではなく「XAIO」であることに注意してください。
バージョン2.4.0でスペルが修正されたようです。※2022年8月18日追記

  • シリアルポートの選択

[ツール] > [シリアルポート]からXIAO RP2040が接続されているシリアルポートを選択します。

Chromebookでシリアルポートから書き込みできない場合、手動でスケッチを書き込みできます。

サンプルプログラム(Arduinoスケッチ)

公式WikiサイトにArduinoの情報やサンプルスケッチがあります。

XIAO RP2040 with Arduino - Seeed Wiki
Seeed Product Document

また、Arduino IDEにスケッチ例([ファイル] > [スケッチ例] > [Seeed XIAO RP2040用のスケッチ例])があります。

RGB LEDを試してみました

上記のXIAO RP2040 Wikiに掲載されているRGB LEDのスケッチを試してみました。

LEDをLチカしてみる

XIAO RP2040のユーザLEDはRGB3色あります。それぞれの色をLチカするスケッチを書いてみました。
ポイントとして、ユーザLEDは、HIGHで消灯LOWで点灯となっています。

#define LED_COUNT 3
#define LED_RED 17
#define LED_GREEN 16
#define LED_BLUE 25

#define COLOR_REPEAT 2

uint8_t led[LED_COUNT] = {LED_RED, LED_GREEN, LED_BLUE};
uint8_t repeatCount = 0, ledCount = 0;

void setup()
{
  for (int i = 0; i < LED_COUNT; i++)
  {
    pinMode(led[i], OUTPUT);
    digitalWrite(led[i], HIGH); // LEDをOFFにする(HIGHでOFF)
  }
}

void loop()
{
  digitalWrite(led[ledCount], LOW);  // LOWでON
  delay(1000);                       // wait for a second
  digitalWrite(led[ledCount], HIGH); // HIGHでOFF
  delay(1000);                       // wait for a second

  repeatCount++;
  if (repeatCount >= COLOR_REPEAT)
  {
    repeatCount = 0;
    ledCount++;
    if (ledCount >= LED_COUNT)
    {
      ledCount = 0;
    }
  }
}

一撃入魂

BOOTボタンを押すと、1/2でRGB LEDがレインボーに光るというスケッチです。

後述の「Seeeduino XIAO 拡張ボードを試してみました」に掲載のスケッチを以下のように修正します。

117行目(入力ボタンをBOOTボタンになるよう修正します。)

//  while (digitalRead(BTN) == HIGH)
  while (!BOOTSEL)
  {

以下、落選時と当選時の流れです。

QT Py RP2040のサンプルスケッチを試してみる

RGB LEDのピン番号は、QT Py RP2040のNeoPixelと同じということが分かりました。
ということで、試しにQT Py RP2040の以下の記事のサンプルスケッチを動かしてみます。

RGB LED Lチカ

「NeoPixelをLチカしてみる」に掲載しているスケッチを書き込みました。

このようにLチカできました。スケッチの修正は不要でした。

レインボー

「NeoPixelをレインボーに光らせてみる」に掲載のスケッチを書き込みました。

こちらもスケッチの修正は不要でした。

眩しいですね。

I2Cスキャナ

以下のページのI2CスキャナをXIAO RP2040用に修正してみました。

Arduino Playground - I2cScanner

Seeed XIAO RP2040全ボード(※2022年9月8日時点)対応版 ※2022年9月8日

#include <Wire.h>

#define XIAO_RP2040_NEW_BOARD (defined(ARDUINO_SEEED_XIAO_RP2040) || (defined(ARDUINO_SEEED_XAIO_RP2040) && defined(__WIRE0_DEVICE)))

#if XIAO_RP2040_NEW_BOARD
#define WIRE Wire
#else
#define WIRE Wire1
#endif

void setup()
{
#if !XIAO_RP2040_NEW_BOARD
  WIRE.setSDA(SDA);
  WIRE.setSCL(SCL);
#endif
  WIRE.begin();
 
  Serial.begin(115200);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    WIRE.beginTransmission(address);
    error = WIRE.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}

シリアルモニターを開くと接続されているI2Cデバイスのアドレスが確認できます。

Seeeduino XIAO 拡張ボードを試してみました

XIAO RP2040は、Seeeduino XIAO互換ということで、Seeeduino XIAO 拡張ボードという便利なボードが使えます。

※2021年12月28日現在 秋月電子通商やマルツオンラインなどで入手できそうです。

Seeeduino XIAO 拡張ボードは、以下のような豊富なインターフェースが備わっています。

  • OLEDディスプレイ
  • RTC
  • 拡張可能なメモリスペース
  • パッシブブザー
  • ユーザーボタン
  • Groveコネクタ
  • オンボードバッテリー管理チップなど

なにか試したい時によく使うボードですね。

こちらの例を以下の記事に掲載してみました。

OLEDディスプレイを表示してみる(Adafruit SSD1306ライブラリ編)

スケッチ例(ssd1306_128x64_i2c)を使った表示方法を紹介します。

Seeed公式 Seeed XIAO RP2040(バージョン2.7.2)は非対応です。
※Adafruit SSD1306ライブラリでコンパイルエラーが発生するようです。

Raspberry Pi Pico/RP2040ボード(earlephilhower版) Seeed XIAO RP2040ボードに対応するように修正方法を一部変更しました。※2022年9月8日

ボード搭載のOLEDディスプレイは、0.96インチ(128×64)、制御IC: SSD1306、通信: I2Cのものです。

単体でもよく見かけるポピュラーなOLEDディスプレイですね。

事前にライブラリマネージャから、Adafruit SSD1306ライブラリをインストールしておきます。

スケッチ例から、[Adafruit SSD1306] > [ssd1306_128x64_i2c]を選択します。

Seeed公式 Seeed XIAO RP2040ボード(バージョン1.12.0まで)やRaspberry Pi Pico/RP2040ボード(earlephilhower版)
(バージョン2.0.2まで)ではWire1を使用します。

これ以降のバージョンではI2CをWireで使用できるように変更されたようです。

ここでは、このようなボードのバージョン差異に対応した修正例を記載します。

コードの修正箇所は、大きく2箇所です。
以下のように修正します。

修正箇所1(OLED初期化)

修正前

#define OLED_RESET 4
#define SCREEN_ADDRESS 0x3D
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

修正後

#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C

#define XIAO_RP2040_NEW_BOARD (defined(ARDUINO_SEEED_XIAO_RP2040) || (defined(ARDUINO_SEEED_XAIO_RP2040) && defined(__WIRE0_DEVICE)))

#if XIAO_RP2040_NEW_BOARD
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#else
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);
#endif

修正箇所2(setup関数にI2C1(Wire1)のピン(SDA、SCL)を明示するコードを追記)

void setup() {
#if !XIAO_RP2040_NEW_BOARD
  Wire1.setSDA(SDA);
  Wire1.setSCL(SCL);
#endif

修正したのち、スケッチを書き込みます。

こんな感じで、表示されます。

OLEDディスプレイを表示してみる(U8g2ライブラリ編)

スケッチ例(GraphicsTest)を使った表示方法を紹介します。
※Seeed XIAO RP2040全ボード(※2022年9月8日時点)に対応するための修正方法を記載しました。
※2022年9月8日

ここでは、H/W(ハードウェア) I2CでU8g2ライブラリを使う場合のライブラリとスケッチの修正例を掲載します。

事前にライブラリマネージャから、U8g2ライブラリをインストールしておきます。

U8g2ライブラリ(U8x8lib.h)の修正(Wire1対応用修正)

U8g2ライブラリ(バージョン2.33.15 ※2022年9月15日現在)は、RP2040ボードのWire1を認識しないコードとなっているため、これに対処するための修正となります。
Wire1を使用しないボードのみを対象にする場合この修正は不要です。

U8g2ライブラリは、Arduinoスケッチ保存フォルダ配下の[libraries] > [U8g2] > [src]にソースファイルがあります。

今回、XIAO RP2040のWire1をU8g2ライブラリで有効化するため、「U8x8lib.h」を以下のように修正します。

U8x8lib.h

修正前

以下の箇所

/* define U8X8_HAVE_2ND_HW_I2C if the board has a second wire interface*/
#ifdef U8X8_HAVE_HW_I2C
#ifdef WIRE_INTERFACES_COUNT
#if WIRE_INTERFACES_COUNT > 1
#define U8X8_HAVE_2ND_HW_I2C
#endif
#endif
#endif /* U8X8_HAVE_HW_I2C */

修正後

この箇所を以下のように修正します。

/* define U8X8_HAVE_2ND_HW_I2C if the board has a second wire interface*/
#ifdef U8X8_HAVE_HW_I2C
#ifdef PIN_WIRE1_SDA
#define WIRE_INTERFACES_COUNT 2
#endif
#ifdef WIRE_INTERFACES_COUNT
#if WIRE_INTERFACES_COUNT > 1
#define U8X8_HAVE_2ND_HW_I2C
#endif
#endif
#endif /* U8X8_HAVE_HW_I2C */
スケッチの修正

スケッチ例から、[U8g2] > [full_buffer] > [GraphicsTest]を選択します。

修正箇所1

U8g2のコンストラクタを次のよう定義します。(0.96インチ OLEDの場合)

#define XIAO_RP2040_NEW_BOARD (defined(ARDUINO_SEEED_XIAO_RP2040) || (defined(ARDUINO_SEEED_XAIO_RP2040) && defined(__WIRE0_DEVICE)))

#if !XIAO_RP2040_NEW_BOARD
U8G2_SSD1306_128X64_NONAME_F_2ND_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#else
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
#endif

ポイントはプリプロセッサでボードを判定し使用するコンストラクタを変えているところです。

修正箇所2(setup関数にI2C1(Wire1)のピン(SDA、SCL)を明示するコードを追記)

void setup() {
#if !XIAO_RP2040_NEW_BOARD
  Wire1.setSDA(SDA);
  Wire1.setSCL(SCL);
#endif
  u8g2.begin();
}

プリプロセッサ(#if、#endif)を入れることで、ボードのバージョン差異に対応するようにしています。

修正したのち、スケッチを書き込みます。

こんな感じで、表示されます。

キーボードショートカット(USB HIDキーボードデバイス)を再現してみました

ボタンを押すとWindowsデスクトップ表示がされるUSBキーボードを作成してみました。

#include <Keyboard.h>

#define BTN D1
#define LED LED_BUILTIN

void setup()
{
  pinMode(BTN, INPUT_PULLUP);
  pinMode(LED, OUTPUT);

  Keyboard.begin();
}

void loop()
{
  if (digitalRead(BTN) == LOW)
  {
    digitalWrite(LED, HIGH);

    //Windowsキー(KEY_LEFT_GUI)+'D'の同時押しを再現
    Keyboard.press(KEY_LEFT_GUI);
    delay(10);           //Windowsキー押下後ウエイト
    Keyboard.write('d'); //※大文字'D'はではなく、小文字の'd'を送信

    Keyboard.releaseAll();

    while (digitalRead(BTN) == LOW); //ボタンがリリースされるまで待機

    digitalWrite(LED, LOW);
  }
  delay(10);
}

一撃入魂

ボタンを押すと、1/2でレインボーに光るというスケッチです。

ルール
チャンスは1回、ボタン押下時に抽選

ということで、今回のスケッチは、あえてボタン入力の受付は1回のみとしてみました。
再チャレンジしたい場合は、リセットボタンを押してみてください。

RGB LEDの状態について

ボタン入力受付は、白点滅
抽選演出は、赤で表現
抽選結果は、当選時 > レインボー、落選時 > フェードアウト

動画は、落選時の流れです。

後述のボタン製作のところに当選時の動画を掲載しています。

#include <Adafruit_NeoPixel.h>

#define BTN D1

#define LED_POWER 11
#define LED_PIN 12

#define TOGGLE_PERIOD (1000u)

#define LED_STAND_BY_COLOR 0xffffff
#define LED_READY_COLOR 0xff0000

Adafruit_NeoPixel pixels(1, LED_PIN);

uint8_t rgbValues[7][3] = {
    {255, 0, 0}, {255, 165, 0}, {255, 255, 0}, {0, 128, 0}, {0, 255, 255}, {0, 0, 255}, {128, 0, 128}};

int16_t randNumber;

int16_t brightness = 0;
int16_t fadeAmount = 10;

void toggleLED_nb(void)
{
  static bool toggle = true;
  static auto lastToggle = millis(); // saved between calls
  auto now = millis();

  if (now - lastToggle > TOGGLE_PERIOD)
  {
    if (toggle)
    {
      pixels.setPixelColor(0, LED_STAND_BY_COLOR);
      pixels.setBrightness(18);
      pixels.show();
    }
    else
    {
      pixels.clear();
      pixels.show();
    }
    toggle = !toggle;
    lastToggle = now;
  }
}

void readyLED()
{
  for (uint8_t i = 0; i < 3; i++)
  {
    brightness = 0;
    pixels.clear();
    pixels.show();
    delay(100);

    for (uint8_t j = 0; j < (100 / fadeAmount); j++)
    {
      pixels.setPixelColor(0, LED_READY_COLOR);
      pixels.setBrightness(brightness);
      pixels.show();

      brightness = brightness + fadeAmount;
      delay(80);
    }

    delay(1000);
  }
  brightness = 150;
  pixels.setPixelColor(0, LED_READY_COLOR);
  pixels.setBrightness(brightness);
  pixels.show();
  delay(3000);
}

void successLED()
{
  for (uint8_t i = 0; i < 8; i++)
  {
    for (uint8_t j = 0; j < 7; j++)
    {
      pixels.setPixelColor(0, pixels.Color(rgbValues[j][0], rgbValues[j][1], rgbValues[j][2]));
      pixels.setBrightness(18);
      pixels.show();
      delay(50);
    }
  }
}

void failureLED()
{
  while (0 < brightness)
  {
    pixels.setPixelColor(0, LED_READY_COLOR);
    pixels.setBrightness(brightness);
    pixels.show();

    brightness = brightness - fadeAmount;
    delay(80);
  }

  pixels.clear();
  pixels.show();
  delay(200);
  pixels.setPixelColor(0, LED_READY_COLOR);
  pixels.setBrightness(10);
  pixels.show();
  delay(150);
}

void setup()
{
  pinMode(BTN, INPUT_PULLUP);
  pinMode(LED_POWER, OUTPUT);

  digitalWrite(LED_POWER, HIGH);
  pixels.begin();
  while (digitalRead(BTN) == HIGH)
  {
    toggleLED_nb();
    delay(10);
  }

  // 抽選
  randomSeed(analogRead(A0));
  randNumber = (int16_t)random(0xffff + 1);

  readyLED();

  if (randNumber < 0)
  {
    // おめでとう
    successLED();
  }
  else
  {
    // 残念
    failureLED();
  }

  pixels.clear();
  pixels.show();
}

void loop()
{
}

バッテリーで動かしてみました

拡張ボードに搭載のI2CのOLEDディスプレイとSPIのTFT(IPS) 1.54インチディスプレイを同時に表示するスケッチをバッテリーで動かしてみました。

バッテリーは、コネクタがJST PH 2.0のリチウムイオンバッテリーが使用できます。
Seeeduino XIAO 拡張ボードは、充電にも対応しています。

XIAO拡張ボードのバッテリーコネクタではなく、電圧変換モジュールを使ってTFT 4.0インチ(ILI9486)のベンチマーク(LovyanGFXのスケッチ例 > test > TFT_graphicstest_PDQ)をバッテリーで動かしてみました。

単三乾電池2本

リチウムイオンバッテリー

テスターは、以下のUD24 USBテスターを使用しています。

結構高機能なシロモノで個人的にお気に入りの一品です。

なお、電圧変換モジュールの製作については以下の記事をご覧ください。

パッシブブザーでメロディを鳴らしてみる

※注意点
Seeed XIAO RP2040ボード(バージョン1.9.3)においてTone関数を使った一部のスケッチにて、動作が途中で止まるという現象が確認されています。
バージョン1.12.0であれば、正常動作するようです。

まずは、スケッチ例を使って試してみました。

スケッチ例から、[rp2040] > [ToneHappyBirthday]を選択します。

ブザーのピンをパッシブブザーのA3に書き換えて、スケッチを書き込みます。

// pin_buzzer should be defined by the supported variant e.g CPlay Bluefruit or CLUE.
// Otherwise please define the pin you would like to use for tone output
#ifndef PIN_BUZZER
#define PIN_BUZZER    A3
#endif

QT Py RP2040の記事に掲載している「パッシブブザーでメロディを鳴らしてみる」のスケッチも試してみました。

こちらもメロディー再生できました。

ボタンを製作してみました

タクトスイッチを組み込んだボタンを製作してみました。

製作過程については、こちらの記事にまとめてみました。

ガチャポンボタンで手元スイッチを作る(参考サイト)

キーボードショートカット(USB HIDキーボードデバイス)を再現してみました

本記事に掲載のボタンを押すとWindowsデスクトップ表示がされるUSBキーボードのスケッチをこのボタンに組み込んであるXIAO RP2040に書き込んで動かしてみました。

一撃入魂

本記事に掲載の一撃入魂スケッチをこのボタンで動かしてみました。

このボタンでは、直接リセットボタンを押せないため、ガチの1回抽選を再現できたかなと思っています。

まとめ

デバイス等への組み込み、USBデバイス(マウスやキーボードHIDデバイスなど)の作成、Seeeduino XIAO 拡張ボードなどを使ったラピッドプロトタイピングなど、いろいろと応用できそうですよね。

RP2040搭載ボードの中では比較的安価なのも、嬉しいポイントですね。

ということで、お気に入りのマイコンがまた一つ増えました。

当ブログのマイコン記事です。ぜひご覧ください。

この記事を書いた人
あろっち

元ITエンジニア
エンジニア時代は大手企業などでSE・プログラマを経験してきました。

当ブログでは、経験や日々の暮らしの中で、興味があること、役に立ちそうなこと、気になったことを発信していきます。

IT関係(技術的な内容もあります) / スマホ・PC / ガジェット / 生活に役立ちそうなこと ... etc

あろっちをフォローする
Raspberry Pi/電子工作IT
スポンサーリンク
あろっちをフォローする
あろしーど

コメント

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