Adafruit QT Py RP2040を試してみました【Arduino使用】

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

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

Adafruit QT Py RP2040を入手したので試してみました。

特徴

  • Seeeduino XIAO、Adafruit QT Py(SAMDベースモデル)互換のピン配置/形状
  • USB Type-C
  • RGB NeoPixel LED内蔵
  • STEMMA QT/Qwiicコネクタ搭載
  • リセットボタン
  • ブートローダーセレクトボタン

スペックはこんな感じです。

MCURP2040 デュアルコア ARM Cortex M0+プロセッサ、最大動作周波数 133 MHz
フラッシュメモリ8MB (Raspberry Pi Pico、Seeed XIAO RP2040は2MB)
GPIO13
・11xブレイクアウト(11xディジタル&PWM, 4xアナログ対応(12bit ADC))
・2xQT
サイズ21.8×17.8×5.8mm
左からSeeeduino XIAO、Adafruit QT Py、Seeed XIAO RP2040、Adafruit QT Py RP2040、Adafruit QT Py ESP32-S2、Seeed XIAO BLE Sense
Adafruit QT Py RP2040
What a cutie pie! Or is it... a QT Py? This diminutive development board comes with one of our new favorite chips, the R...

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

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

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

Adafruit QT Py RP2040に似たようなマイコンにSeeed XIAO RP2040があります。そちらについても記事を書いていますので、よろしければご覧ください。

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

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

スポンサーリンク

ピン配列

GPIOとの対応を記載します。

ピンGPIO
A029/ADC3
A128/ADC2
A227/ADC1
A326/ADC0
SDA24
SCL25
TX20
RX5
SCK6
MISO4
MOSI3
NEOPIXEL POWER11
NEOPIXEL12
BUTTON21

QT

ピンGPIO
SDA122
SCL123

NeoPixelを使用するには

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

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

Raspberry Pi Pico/RP2040ボード(earlephilhower版) Adafruit QT Py RP2040ボードでは、定数(NEOPIXEL_POWER)が定義されているので、この定数を使って次のようにHIGHにできます。

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

参考

PINリファレンス

Adafruit QT Py RP2040
What a cutie pie! Or is it... a QT Py? This diminutive development board comes with one of our new favorite chips, the R...

Arduino IDEの設定

ボードは、RP2040のearlephilhowerボードを使用します。
このボードを使用するには、以下の設定を行います。

Arduino IDEから[ファイル] > [環境設定]の画面を開き、[追加のボードマネージャのURL:]のボックス(赤枠の箇所)に以下のURLを入力し、[OK]をクリックします。

https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

[ツール] > [ボード] > [ボードマネージャ]を開き、検索ボックスにrp2040と入力し、Raspberry Pi Pico/RP2040ボードをインストールします。

画像はRaspberry Pi Pico/RP2040ボードインストール済み

ボードは、[ツール] > [ボード] > [Raspberry Pi RP2040 Boards(Ver)] > [Adafruit QT Py RP2040]を選択します。(画像の赤枠参照)

NeoPixelをLチカしてみる

Adafruit QT Py RP2040の内蔵LEDはNeoPixel。せっかくなので、カラフルにLチカしてみましょう。

#include <Adafruit_NeoPixel.h>

#define LED_POWER 11
#define LED_PIN 12

#define COLOR_REPEAT 2

Adafruit_NeoPixel pixels(1, LED_PIN);

uint8_t color = 0, count = 0;
uint32_t colors[] = {pixels.Color(255, 0, 0), pixels.Color(0, 255, 0), pixels.Color(0, 0, 255), pixels.Color(255, 255, 255)};
const uint8_t COLORS_LEN = (uint8_t)(sizeof(colors) / sizeof(colors[0]));

void setup() {
  pinMode(LED_POWER, OUTPUT);
  digitalWrite(LED_POWER, HIGH);
  pixels.begin();  // initialize the pixel
}

void loop() {
  pixels.setPixelColor(0, colors[color]);
  pixels.show();
  
  delay(1000);
  
  pixels.clear();
  pixels.show();
  
  delay(1000);
  
  count++;

  if(count >= COLOR_REPEAT) {
    count = 0;
    color++;
    if(color >= COLORS_LEN) {
      color = 0;
    }
  }
}

こんな感じで光ります。

NeoPixelをレインボーに光らせてみる

このスケッチもAdafruit NeoPixelライブラリを使っています。

#include <Adafruit_NeoPixel.h>

#define LED_POWER 11
#define LED_PIN 12
#define MAX_BRIGHTNESS 255

Adafruit_NeoPixel pixels(1, LED_PIN);

int rgbValues[] = {MAX_BRIGHTNESS, 0, 0}; // 0=Red, 1=Green and 2=Blue
int upIndex = 0, downIndex = 1;

void setup()
{
  pinMode(LED_POWER, OUTPUT);
  digitalWrite(LED_POWER, HIGH);
  pixels.begin(); // initialize the pixel
}

void loop()
{
  rgbValues[upIndex] += 1;
  rgbValues[downIndex] -= 1;

  if (rgbValues[upIndex] > MAX_BRIGHTNESS)
  {
    rgbValues[upIndex] = MAX_BRIGHTNESS;
    upIndex = upIndex + 1;

    if (upIndex > 2)
    {
      upIndex = 0;
    }
  }

  if (rgbValues[downIndex] < 0)
  {
    rgbValues[downIndex] = 0;
    downIndex = downIndex + 1;

    if (downIndex > 2)
    {
      downIndex = 0;
    }
  }

  pixels.setPixelColor(0, pixels.Color(MAX_BRIGHTNESS - rgbValues[0], MAX_BRIGHTNESS - rgbValues[1], MAX_BRIGHTNESS - rgbValues[2]));
  pixels.show();

  delay(5);
}

こんな感じで光ります。思ったより明るくて眩しいです。

一撃入魂

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

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

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

RGB LEDの状態について

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

#include <Adafruit_NeoPixel.h>

#define BTN 21

#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(A2));
  randNumber = (int16_t)random(0xffff + 1);

  readyLED();

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

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

void loop()
{
}

落選時

当選時

STEMMA QT/Qwiicコネクタを試してみました

QTコネクタが搭載されているので、試してみました。

Lチカ

GroveのLEDモジュールを使ってLチカしてみました。

QTコネクタとGroveモジュールの接続にはGroveアダプタケーブルを使います。

Groveアダプタケーブルはスイッチサイエンスさんで入手しました。

#define LED 23

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED as an output.
  pinMode(LED, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(LED, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

QTコネクタのGPIO 23のオン/オフでLチカできます。

RGB LEDテープを光らせてみる

Grove – WS2813搭載防水RGB LEDテープ1m(60LED)を光らせてみました。

https://www.seeedstudio.com/Grove-WS2813-RGB-LED-Strip-Waterproof-60-LED-m-1m.html

QTとRGB LEDテープのGroveコネクタを接続するのにGrove – Qwiicハブを使用しました。

https://www.seeedstudio.com/Grove-Qwiic-Hub-p-4531.html

スケッチはAdafruit NeoPixelライブラリのスケッチ例「strandtest」を使っています。

[スケッチ例] > [Adafruit NeoPixel] > [strandtest]

LED_PINとLED_COUNTを以下のように修正しました。

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    23

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 60

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

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

※現在、秋月電子通商、マルツオンラインなどで入手できそうです。

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

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

ちなみにSeeeduino XIAOも保有していて、なにか試したい時によく使うボードですね。

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

OLEDディスプレイを表示してみる

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

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

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

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

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

#define OLED_RESET 4
#define SCREEN_ADDRESS 0x3D

#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C

に変更し、スケッチを書き込みます。

以下、抜粋です。

#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

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

ちなみに、Seeeduino XIAOでもこのスケッチを書き込めば同じように表示されます。

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

メロディは、恥ずかしながらオリジナルだったりします。

int duration = 250;
int pin = A3;

void do1(int k) {
  tone(pin, 261, k);
  delay(k);
  noTone(pin);
}

void re(int k) {
  tone(pin, 293, k);
  delay(k);
  noTone(pin);
}

void mi(int k) {
  tone(pin, 329, k);
  delay(k);
  noTone(pin);
}

void fa(int k) {
  tone(pin, 349, k);
  delay(k);
  noTone(pin);
}

void so(int k) {
  tone(pin, 391, k);
  delay(k);
  noTone(pin);
}

void ra(int k) {
  tone(pin, 440, k);
  delay(k);
  noTone(pin);
}

void si(int k) {
  tone(pin, 494, k);
  delay(k);
  noTone(pin);
}

void do2(int k) {
  tone(pin, 523, k);
  delay(k);
  noTone(pin);
}

void logo1() {
  mi(duration / 2);
  mi(duration / 2);
  mi(duration / 2);
  mi(duration / 2);
  mi(duration / 2);
  mi(duration / 2);
  delay(duration * 2);
  so(duration * 2);
  so(duration * 2);
  do2(duration * 2);
}

void logo2() {
  so(duration);
  delay(duration);
  do2(duration);
  ra(duration);
  si(duration);
  delay(duration);
  ra(duration);
  so(duration);

  so(duration);
  do2(duration);
  delay(duration);
  si(duration);
  do2(duration);
}

void title() {
  re(duration);
  do1(duration);
  re(duration * 2);
  mi(duration * 2);
  fa(duration * 2);

  ra(duration);
  ra(duration);
  so(duration * 2);
  re(duration * 2);
  mi(duration * 2);

  ra(duration);
  ra(duration);
  so(duration * 2);
  re(duration * 2);
  mi(duration * 2);
  fa(duration * 2);
}

void mainbgm() {
  so(duration);
  delay(duration);
  do2(duration);
  ra(duration);
  si(duration);
  delay(duration);
  ra(duration);
  so(duration);

  so(duration);
  do2(duration);
  delay(duration);
  si(duration);
  do2(duration * 2);
  delay(duration * 2);

  so(duration);
  delay(duration);
  do2(duration);
  delay(duration);
  ra(duration);
  ra(duration);
  si(duration);
  delay(duration);

  so(duration);
  do2(duration);
  delay(duration);
  si(duration);
  do2(duration * 2);
  delay(duration * 2);
}

void setup() {
 do1(duration);
 re(duration);
 mi(duration);
 fa(duration);
 so(duration);
 ra(duration);
 si(duration);
 do2(duration);
  delay(2000);

  logo1();
  delay(2000);

  logo2();
  delay(2000);

  title();
  delay(2000);

  mainbgm();
  delay(2000);
}

void loop() {
}

ちなみにSeeeduino XIAOやSeeed XIAO RP2040でも鳴らせます。

PWMでオーディオ再生してみました

ライブラリを作ってみました。

ダウンロード&インストール方法は以下の記事をご参照ください。

スケッチ例 typewriter

スケッチ例はそのまま書き込めばOKです。

まとめ

Adafruit QT Py RP2040は、小さくて高性能。今では、お気に入りのマイコンの一つです。

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

コメント

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