【Arduino】Tiny RP2350Bを使う

it

RP2350Bを搭載したTiny RP2350Bを使ってみます。
RP2350Aから機能拡張されてたチップですが、基板の使い方で躓いたことを記載しました。
RP2350Aを搭載したRaspberry Pi Pico2との比較を中心に使ってみた内容を記事にしました。

Tiny RP2350B

簡単紹介

◆入手

Ali Express SpotPear Electronicsにて購入。
Ali Express Choice で\1,400前後(With-PSRAM-For-Linux)

LinuxとシルクがありますがLinuxは載りません。

◆関連記事

ピン配置

2.54mmピッチピンヘッダ装着時のピン配置表です。

GPIO30より大きい番号を使うことができませんでした。
専用のボードライブラリがあれば結果が良くなるかもしれません。
ADCは2ピン分使うことができたため、使えた番号を記載します。

外観

使ってみた

◆開発環境

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

スペック

クロック(50~300MHz)やSRAM(520KB)は同じです。

CPU上の主な違いはパッケージのサイズとピン数。
使えるピン数は載せる基板次第なのでRP2350Aよりは基板は幅広な基板になります。

RP2350RP2350A
パッケージサイズ(mm)13 x 13 (QFN)7 x 7 (QFN)
ピン数8060

2.54mmピッチスルーホールか、1.27mmピッチのサイドエッジにピンヘッダを取り付けます。
2.54mmピッチスルーホールはブレッドボードで使いやすいが、通信用のUART, I2C, SPIでは使えるピンに制約があります。

RP2350BとRP2350AのGPIO Off/On速度比較をします。
同じライブラリを使うため単純比較になると思います。

◆外観比較

基板が違うのでパッケージ外観を比較します。
画像左がTiny-RP2350BのRP2350B、右がRaspberry Pi Pico2のRP2350です。
縮尺は目視で合わせています。

パッケージが大きい分基板も大判化していますが、400穴ブレッドボードで使用すると左右1列と2列が使えます。

ピンヘッダはスルーホールで使える2.54mmピッチか、サイドエッジで使える1.27mmピッチです。
今回2.54mmピッチのスルーホールにピンヘッダを実装して使っています。

※注意

2.54mmピンヘッダで使った場合、シリアル通信(UART, I2C, SPI)に制限が発生します。
下図はRP2350で使えるシリアル通信を各規格別に、ペリフェラルインスタンス毎に色分けしたもの。
各シリアル通信に必要な信号が2.54mmのスルーホールに出ていないため、使えないシリアルやペリフェラルインスタンスがあります。

UARTではRX0が使えません。
I2CではI2C0, 1 ともに使えます。
SPIではMOSI1が使えないません。

実質UART0とSPI1は使えないので、考慮した設計が必要です。
2.54mmピッチにこだわらなければ設計に自由度がありますが、ブレッドボードでは使いにくい基板です。

◆プルアップ、プルダウン

RP2350Aを搭載するRaspberry Pi Pico2では、ボタンの押下状態を読み取るために物理的なプルダウン抵抗が必要でした。

RP2350Bではプルダウン抵抗がなく、スケッチ上のPULL_DOWN設定で読み取りができました。
ButtonLEDではプルダウン設定でボタンの押下状態を読み取っています。

※注意

プルアップする場合は、プルダウン抵抗は必要です。

◆実装WS2812

基板上にはユーザLEDとしてWS2812が実装されています。
モジュールライブラリ「Adafruit NeoPixel by Adafruit」を使用し多色発光できました。

WS2812を使ったスケッチはこちら

◆まとめ

Raspberry Pi Pico2と比べると多くのピンを引き出していますが、ブレッドボードで使用すると制約が多く、基板としては使いにくいと感じました。
今回ボードライブラリに 「Raspberry Pi Pico/RP2040/RP2350 by Earle F. Philhower, III」の「Raspberry Pi Pico2」を代用しました。
そのことが原因かはわかりませんが、GPIO30 より大きい番号を使うことができませんでした。
ADCもピン番号マッチングしていないので専用のライブラリが必要かもしれません。

GPIOのプルアップ、プルダウンをするための抵抗が要/不要であったり細かな違いもあり、使っていて混乱気味になってしまいます。

準備

Arduino環境の作成

◆開発環境

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

◆ボードライブラリ

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

注意

Raspberry Pi Pio 2はライブラリバージョン4.0.0から追加されています。
4.0.0以降のバージョンをインストールします。

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

モジュールライブラリ

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

◆SSD1306

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

◆ILI9341

ライブラリ名検索確認時のバージョン
Adafruit ILI9341 by AdafruitILI93411.6.1
Adafruit GFX Library by AdafruitGFX1.11.10

◆WS2812

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

基板の初期化とシリアル認識

Raspberry Pi Pico2の初期化で紹介した方法と同じで、Raspberry Pi Pico2用のuf2ファイルを作成し書き込みます。

スケッチの書き込み

Arduino IDEの書き込みボタン、またはuf2ファイルを書き込みます。

1.Arduino IDEからの書き込み

注意
「基板の初期化とシリアル認識」を実施し、パソコンがシリアル認識している必要があります。

書き込みを行うTiny RP2350BのCOMポートを選択し、Arduino IDEの書き込みボタンをクリックすることで書き込みができます。

2.uf2ファイルの書き込み

「基板の初期化とシリアル認識」で作成した.uf2ファイルのように、作成したスケッチをコンパイルし、.uf2ファイルを作成します。

Tiny RP2350BのBOOTボタンを押しながら、USBケーブルを接続し電源を供給します。
Tiny RP2350Bがストレージ認識されるので、.uf2ファイルをドラッグ&ドロップします。

スケッチサンプル

GPIO出力

説明

GPIOの出力Off/Onを繰り返します。
動作中のGPIO出力をオシロスコープ(OWON HDS272)を使いどのくらいの周期で周回しているかモニタします。

今回200MHzでコンパイルしています。

配線

オシロスコープでGPIO0 と GNDをプローブします。

スケッチ

void setup()
{
  pinMode(D0, OUTPUT);
  while(1)
  {
    digitalWrite(D0, HIGH);
    digitalWrite(D0, LOW);
  }
}

void loop()
{
}

結果

RP2350Aを搭載するRaspberry Pi Pico2(青)にも同じスケッチを書き込み、信号をモニタしました。
結果、RP2350AとRP2350Bには差がありませんでした。

双方の基板の同じタイミングで振幅させることが難しいので、停止画面で周期の幅を計測しました。
どちらも1周期944ns(200MHzクロック時)でした。

ButtonLED

説明

タクトボタンを押している間LEDを点灯します。

LEDにはGPIO2を使います。
タクトボタンにはGPIO0をINPUT_PULLDOWNで使います。

RP2350BではINPUT_PULLDOWNを設定することで回路上でプルダウン抵抗を使うことなく入力を読み取ることができました。
INPUT_PULLUPは回路上にプルアップ抵抗が必要なようです。

配線

スケッチ

#define BUTTON_PIN      (D0)
#define LED_PIN         (D2)

void setup() 
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLDOWN);
//  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() 
{
  if(digitalRead(BUTTON_PIN) == LOW)
  {
    digitalWrite(LED_PIN, LOW);
  }
  else
  {
    digitalWrite(LED_PIN, HIGH);
  }
}

結果

ボタンを押すとLEDが点灯、ボタンを離すとLEDは消灯しました。

Raspberry Pi Pico2ではボタンの入力に回路上のプルダウン回路が必要でしたが、RP2350Bを搭載するTiny RP2350Bでは回路上のプルダウン回路は不要でした。

プルアップ側は対応していないようで、回路上のプルアップ抵抗が必要でした。
以下はプルアップ回路の参考配線図です。

PWM出力

説明

ボード実装されたLEDをPWM制御により、ゆっくり点灯ゆっくり消灯を繰り返します。
GPIO0(D0)を使い、1秒ごとにDutyを3パータン変化させます。

配線

スケッチ

#define LED_PIN         (D0)
#define WAIT_MS         (1000)

void setup() 
{
  uint8_t tablePWM[] = {63, 127, 191};
  
  pinMode(LED_PIN, OUTPUT);

  while(1)
  {
    for(int i = 0; i < sizeof(tablePWM); i ++)
    {
      analogWrite(LED_PIN, tablePWM[i]);
      delay(WAIT_MS);
    }
  }
}

void loop()
{}

結果

ADC

説明

Tiny RP2350BではADC(アナログデジタルコンバータ)は8ch。
そのうち2.54mmピッチピンヘッダで使用できるのは4chとなっています。

使えたのは2chでした。
ボードライブラリにTiny RP2350Bが見当たらないため、代用に「Raspberry Pi Pico/RP2040/RP2350 by Earle F. Philhower, III」の「Raspberry Pi Pico2」を使ったことが原因かもしれません。

使えたADCはA0とA2です。
GPIO40と42にアサインされていますが、ピン番号の指定はRaspberry Pi Pico2と同じGPIO26と28です。

今回の動作確認では、A0を使い結果をシリアル出力しています。
入力アナログ電圧はESP32-WROOM32 NodeMCUのDACを使い、約2秒で0 から 3.3V、約2秒で3.3V から 0Vに変化する三角波を入力しました。

配線

スケッチ

#define ADC_PIN (A0)

void setup()
{
  Serial.begin(115200);
  pinMode(ADC_PIN, INPUT);
}

void loop()
{
  int iADC = 0;

  iADC = analogRead(ADC_PIN);
  Serial.printf("%d\r\n", iADC);
  delay(2);
}

結果

GPIO40の位置がA0になり、A0定義を使用しない場合はマジックナンバーで26を設定します。
なお、デジタルIOとしてGPIO28を使用するときは、GPIO28の位置で機能します。

結果の一部を切り取ってグラフにしました。
ノイズの少ないきれいな波形が観測できました。
若干フロアレベルが高く、最大値は低く感じます。

UART(UARTのピン設定)

説明

RP2350BではUARTを2ポート使用できます。
TinyRP2350Bも2ポート使用できますが2.54mmピッチピンヘッダ実装するスルーホールにはUART0のRXがないため、実質UART1の1ポートしか使えません。

TinyRP2350のUARTは赤字のTX1とRX1の組み合わせで使います。

注意!!
設定できないピンに対して設定を行うとコンパイルと書き込みはできますが、TinyRP2350Bは停止しCOMの認識もできなくなります。
基板の初期化とシリアル認識」を実施することで復旧できます。

設定と開始

Arduino上でのピン設定とUARTの開始。

//USBシリアルを使ってTinyRP2350とパソコンを通信する場合
Serial.begin();

//UART1を使ってTXにGPIO4、RXにGPIO21を設定する。
Serial2.setTX(D4);
Serial2.setRX(D21);
Serial2.begin();

UART通信

説明

UART1を使って電文の送受信をします。
UARTシリアル変換モジュールから受信した文字が
 ”1”ならLEDを点灯し、UART1に”LED On”を送信、
 ”0″ならLEDを消灯し、UART1に”LED Off”を送信します。

Tiny RP2350BのUART通信相手にはFT232RLを使用しました。
ジャンパは3.3V側でショートしています。

Tiny RP2350B基板では、UART0のRXが使えないためUART1を使用しています。

配線

スケッチ

#define UART1_TX    (D4)
#define UART1_RX    (D21)
#define LED_PIN     (D0)

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

  Serial2.setTX(UART1_TX);
  Serial2.setRX(UART1_RX);
  Serial2.begin(115200);
}

void loop()
{
  int8_t c;

  while(1)
  {
    if(Serial2.available())
    {
      c = Serial2.read();

      if('0' == c)
      {
        digitalWrite(LED_PIN, LOW);
        Serial2.printf("LED Off\n");
      }
      else if('1' == c)
      {
        digitalWrite(LED_PIN, HIGH);
        Serial2.printf("LED On\n");
      }
    }
  }
}

結果

Teratermを起動します。
Teratermの「新しい接続」ではUART-シリアル変換アダプタのCOMを選択します。
UART-シリアル変換アダプタは[COM7]でした。

Teratermがアクティブウインドウの状態でキーボードから”1″を入力すると、LEDが点灯しTeratermには”LED On”が表示されました。
続けて”0″を入力すると、LEDは消灯しTeratermには”LED Off”が表示されました。

I2C(I2Cのピン設定)

説明

RP2350BではI2Cを2ポート使用できます。
各ピンに割り当てのできる機能は決められているため、TinyRP2350Bの2.54mmピッチピンヘッダを実装するスルーホールではあまり選択の自由度はありません。

下図はI2Cで設定ができるピン配置図です。
I2C0は黒字のSDAとSCLの位置、I2C1は赤字のSDAとSCLの位置の組み合わせので使用できます。
各I2CともにSCLは画像左下に数ピンある程度です。

注意!!
設定できないピンに対して設定を行うとコンパイルと書き込みはできますが、TinyRP2350Bは停止しCOMの認識もできなくなります。

設定と開始

Arduino上でのピン設定とI2Cの開始。

#include <Wire.h>

//I2C0を使ってSDAにGPIO16、SCLにGPIO21を設定する。
Wire.setSDA(16);
Wire.setSCL(21);
Wire.begin();

//I2C1を使ってSDAにGPIO18、SCLにGPIO23を設定する。
Wire1.setSDA(18);
Wire1.setSCL(23);
Wire1.begin();

I2CでOLED(SSD1306)の表示制御

説明

0.96インチ OLEDディスプレイ SSD1306をTinyRP2350BのI2Cで表示制御します。
スケッチのベースはRaspberry Pi Pico2で紹介した内容からTinyRP2350BのI2Cピンに修正しています。

スケッチではI2C0(SDAにはGPIO16, SCLにはGPIO21)を使います。
I2C1を使う場合「I2C1の場合」のコメント行を解除し、「I2C0の場合」の行をコメント化します。

配線

スケッチ

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


#define PIN0_SDA    (D16)
#define PIN0_SCL    (D21)
#define PIN1_SDA    (D18)
#define PIN1_SCL    (D23)

#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);     //I2C0の場合
//Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);     //I2C1の場合

                                        
void setup()
{
  
  //I2C0の場合
  Wire.setSDA(PIN0_SDA);
  Wire.setSCL(PIN0_SCL);

  //I2C1の場合
  // Wire1.setSDA(PIN1_SDA);
  // Wire1.setSCL(PIN1_SCL);


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

  display.clearDisplay();
  
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.print(F("Pico2"));
  display.setCursor(25, 25);
  display.print(F("SSD1306"));

  display.display();
}

void loop()
{
}

結果

SSD1306 OLEDの表示ができました。

SPI(SPIのピン設定)

説明

RP2350BではSPIを2ポート使用できます。
SPIで使用するMOSIとMISOとSCKは決められたピンの範囲内で任意のピンに設定できますが、TinyRP2350Bの2.54ピッチスルーホールにはSPI1のMOSIが引き出されていないため、実質SPI0の1ポートのみ使うことができます。
ピン配置表にCSの位置が書かれていますが、GPIOならどのピンにでも設定することができます。

注意!!
設定できないピンに対して設定を行うと、コンパイルと書き込みはできますがTinyRP2350Bは停止し、COMの認識もできなくなります。
基板の初期化とシリアル認識」を実施することで復旧できます。

設定と開始

Arduino上でのピン設定とSPIの開始。

//SPI0を使ってMOSIにGPIO23, MISOにGPIO16, SCKにGPIO18を設定する。
SPI.setTX(23);
SPI.setRX(16);
SPI.setSCK(18);
SPI.begin();

SPI通信(LCDの表示)

説明

スケッチのベースはRaspberry Pi Pico2でも使用した”Adafruit ILI9341 by Adafruit”を使用します。

2.4インチ LCDディスプレイ ILI9341をTinyRP2350BのI2Cで表示制御します。
スケッチのベースはRaspberry Pi Pico2で紹介した内容からTinyRP2350BのSPIピンに修正しています。

配線

スケッチ

#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <SPI.h>

//SPI0の場合
#define TFT_CS                (D0)    // CS
#define TFT_RST               (D2)    // Reset 
#define TFT_DC                (D4)    // D/C
#define TFT_MOSI              (D23)   // SDI(MOSI)
#define TFT_SCK               (D18)   // SCK


//SPI0の場合
Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI, TFT_DC, TFT_CS, TFT_RST);


void setup(void) 
{
  //SPI0の場合
  SPI.setTX(TFT_MOSI);
  SPI.setSCK(TFT_SCK);

  tft.begin();
  
  tft.fillScreen(ILI9341_BLACK);
  
  tft.setRotation(3);
  tft.setTextSize(4);
  
  tft.setCursor(0, 10);
  tft.setTextColor(ILI9341_GREEN);
  tft.printf("TAMANEGI\n\n");

  tft.setTextSize(3);
  tft.setTextColor(ILI9341_RED);
  tft.printf("2.4inch LCD\n");
  tft.setTextColor(ILI9341_YELLOW);
  tft.printf("Res=320 x 240\n");
  tft.setTextColor(ILI9341_BLUE);
  tft.printf("ILI9341\n");
}

void loop()
{
}

結果

TinyRP2350Bスケッチ

WS2812

説明

RGB LED(WS2812)を使います。
モジュールライブラリに「Adafruit NeoPixel by Adafruit」を使いました。

WS2812を使うためのGPIOは20です。
1秒ごとに「赤->緑->黄->青->紫->水->白->消灯」の変化を繰り返します。

配線

配線不要

スケッチ

#include <Adafruit_NeoPixel.h>

#define DIN_PIN     (D20)
#define LED_COUNT   (1)
#define BRIGHTNESS  (16)

Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup(void) 
{
  pixels.begin();
}

void loop(void)
{
  int32_t Palette = 0;
  for(int16_t i = 0; i < 8; i ++)
  {
    switch(i)
    {
      case 0: Palette = pixels.Color(0, 0, 0);break;
      case 1: Palette = pixels.Color(BRIGHTNESS, 0, 0); break;
      case 2: Palette = pixels.Color(0, BRIGHTNESS, 0); break;
      case 3: Palette = pixels.Color(BRIGHTNESS, BRIGHTNESS, 0); break;
      case 4: Palette = pixels.Color(0, 0, BRIGHTNESS); break;
      case 5: Palette = pixels.Color(BRIGHTNESS, 0, BRIGHTNESS); break;
      case 6: Palette = pixels.Color(0, BRIGHTNESS, BRIGHTNESS); break;
      case 7: Palette = pixels.Color(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); break;
    }
    pixels.setPixelColor(0, Palette);
    pixels.show();

    delay(1000);
  }
}

結果

1秒ごとにLEDの発色が変化しました。
輝度の設定は最大255ですが、まぶしいので各色要素の最大を16に設定しています。

コメント

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