SAMD21 XIAO互換基板 Adafruit QT Py を使う

コンピュータ、組み込み

Adafruit のQT Pyを紹介します。
SeeedStudioのXIAO SAMD21の互換基板ですが、リセットボタンやQwiicコネクタが搭載されるなどユーティリティ面で強化されています。

紹介するもの

Adafruit QT Py

特徴
接続Type C
CPUArm Cortex-M0+ 32ビット 48 MHz
ROMフラッシュメモリ 256KByte
SRAM32KByte
GPIO11
PWM10 (8bit 0 ~ 255) (GPIO1 ~ GPIO10)
DAC1 (10bit 0 ~ 1023, 3.3V) (GPIO0)
ADC11 (10bit 0 ~ 1023, 3.3V)
UART1
I2C1
SPI1
その他リセットボタン
Qwiicコネクタ

Adafruit QT Py ページ

ピン配置

外観

400穴ブレッドボードでは、左右3列と2列使用することができます。

使ってみて

SeeedStudioのXIAO SAMD21と互換基板ですが、ユーティリティ面で勝っています。
記事にまとめるために久しぶりに触れてみましたが、多機能ですが無駄がないために扱いやすいと思います。
XIAO SAMD21同様これからArduinoを始める方にはおすすめの基板ですが、シルクによるピン番号が明示しているので初心者には尚優しいと思います。

価格はそれほど変わらないと思いますが、XIAO SAMD21のほうが取り扱いを行っているショップやサイトが多いと感じます。

ピン互換はありませんが、上位機種としてAdafruit QT Py RP2040があります。

準備

ライブラリ

ボードライブラリ

ボードマネージャのURLhttps://adafruit.github.io/arduino-board-index/package_adafruit_index.json
検索Qt Py
ボードライブラリAdafruit SAMD Boards By Adafruit バージョン x.x.x
選択するボードAdafruit SAMD Board > Adafruit QT Py M0(SAMD21)
※ x.x.x 動作確認では1.7.11[Feb/2023]

モジュールライブラリ

機能やモジュールを使用しない場合インストールの必要はありません。

機能/モジュールライブラリ名検索確認時のバージョン
SSD1306Adafruit SSD1306 by AdafruitSSD13062.5.1
ST7735Adafruit ST7735 and ST7789
Library by Adafruit
ST77351.9.3
関連
SSD1306
ST7735
Adafruit GFX Library by AdafruitGFX1.11.3
タッチセンサAdafruit Free Touch Library by AdafruitTouch1.1.1

スケッチの書き込み

Arduino IDEの書き込みボタンより書き込みができます。

リセット

リセットボタンを1回押下するとリセットによるプログラムの再起動を行います。

リセットボタンを素早く2回(0.5秒以内に2回程度)押下するとダウンロードモードになります。
プログラムの書き込みができなくなった時や、プログラムを動作させない状態で書き込みを行いたい場合はこの操作を行います。

基本スケッチ

ボタンLED

説明

タクトボタンとLEDの組み合わせの動作をします。

タクトボタンはPULLDOWN設定します。(押下したらHIGH)
タクトボタンを読み取り、押下されるとLEDが点灯します。
ボタンが離されるとLEDは消灯します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
プルダウンしたピンの状態がHighならLEDを点灯、LowならLEDを消灯させます。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)

【準備】
3.3V -> タクトスイッチ -> GPIO0
GPIO1 -> 保護抵抗(200Ω) -> LED -> GND

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

#define LED 1      //LED
#define BUTTON 0    //タクトスイッチ

void setup()
{
  pinMode(LED, OUTPUT);               //ピン出力設定
  pinMode(BUTTON, INPUT_PULLDOWN);    //プルダウンで入力
}

void loop()
{
  int iStat = digitalRead(BUTTON);
  digitalWrite(LED, iStat);           //ボタンの状態をLEDに出力
}
結果

ボタンが押下されるとLEDは点灯しました。
ボタンが離されるとLEDは消灯しました。

PWM,DAC

説明

PWMを使ってLEDのフェード点灯(ゆっくり点灯させる)を行います。
XIAOでのDACの分解能は10bit(0~1023)で3.3Vまで出力します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
DACとPWM出力でのフェード点灯(ゆっくり点灯)とフェード消灯(ゆっくり消灯)を行います。
XIAO SAMD21のDAC分解能は10bit(0 ~ 1023)で3.3Vです。
PWMの分解能は8bit(0 ~ 255)です。
同時に点灯と消灯を行いたいので、DACの分解能はPWM256段階にして4倍します。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)

【準備】
GPIO0 -> 保護抵抗(200Ω) -> LED -> GND
GPIO2 -> 保護抵抗(200Ω) -> LED -> GND

LEDを配線で使用する場合の抵抗値は使用するLEDにより適切な抵抗値を求めてください。

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

#define DAC 0         //DAC 出力ピン
#define PWM 2         //PWM 出力ピン


void setup()
{
//  pinMode(DAC, OUTPUT);
  pinMode(PWM, OUTPUT);
}

void loop()
{
  for(int i = 0; i < 256; i ++)
  {
    analogWrite(DAC, (i * 4));
    analogWrite(PWM, i);
    delay(2);
  }

  for(int i = 0; i < 256; i ++)
  {
    analogWrite(DAC, (255 - i) * 4);
    analogWrite(PWM, 255 - i);
    delay(2);
  }
}
結果

LEDがゆっくり点灯、ゆっくり消灯しました。
結果の動画はXIAO SAMD21のものですが同じ結果が得られるために流用します。
左側のLEDがDAC, 右側のLEDがPWM制御での点滅です。
PWMの出力はXIAO SAMD21はGPIO1を使用していますが、QT PyではGPIO2を使用しています。

ADC

説明

DACからの電圧をADCに入力します。
読み取った電圧をCOMに出力します。

QT PyではDACによりアナログ出力ができます。
出力した電圧をADCで読み取ります。

配線

QT PyのGPIO0とGPIO1を直接配線します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
DACからの電圧をADCに入力します。
読み取った電圧をCOMに出力します。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)

【準備】
GPIO0(DAC) <-> GPIO1(ADC)

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

#define DAC 0
#define ADC 1

void setup()
{
  Serial.begin(115200);

  pinMode(ADC, INPUT);
}

void loop()
{
  int iADC = 0;
  //アナログ出力を、アナログ入力で読み取ります。
  //結果はCOM出力します。
  for(int i = 0; i < 1024; i ++)
  {
    analogWrite(DAC, i);
    iADC = analogRead(ADC);
    Serial.printf("(DAC, ADC) = %d, %d\r\n", i, iADC);
    delay(2);
  }

  for(int i = 0; i < 1024; i ++)
  {
    analogWrite(DAC, 1023 - i);
    iADC = analogRead(ADC);
    Serial.printf("(DAC, ADC) = %d, %d\r\n", 1023 - i, iADC);
    delay(2);
  }
}
結果

入力した電圧を読み取った結果をグラフにしました。
電圧の変化は0V -> 3.3Vまでを約500msで上昇し、3.3V -> 0Vまで約500msで下降します。
設定値したDACに対して読み取ったADCの値はほとんど一致しています。
XIAO SAMD21とほとんど差異がないために結果を流用します。

DACでの出力をオシロスコープで確認しました。
3.3Vまできれいに出力されています。

UART

説明

COMから読み取ったデータをUARTに送信します。
UARTから読み取ったデータをCOMに送信します。

配線
QT Py配線FT232RL
GPIO6(TX)RX
GPIO7(RX)TX
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
COMから読み取ったデータをUARTに送信します。
UARTから読み取ったデータをCOMに送信します。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)

【準備】
UARTの通信には、FT232RLを使用します。
QT Py <-> FT232RL
GPIO6(TX) <-> RX
GPIO7(RX) <-> TX

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);  
}

void loop()
{
  if(Serial.available() != 0)          //UART1にデータがあれば、読み取った内容をCOMに送信
  {
      Serial1.write(Serial.read());
  }

    if(Serial1.available() != 0)          //COMにデータがあれば、読み取った内容をUART0に送信
  {
      Serial.write(Serial1.read());
  }
}
結果

結果はTeratermを2つ起動して確認します。
1つはCOM用で、もう一つはUART(FT232RL)用です。
結果は省略します。

COM用のTeratermに入力された文字は、UART用のTeraterm画面に表示されます。
UART用のTeratermに入力された文字は、COM用のTeraterm画面に表示されます。

I2C(SSD1306)

説明

I2Cを使ってSSD1306(OLED 0.96inch)モニタのサンプルを動作させます。
QT PyではI2Cは固定の位置で使用します。
ピン配置表に従い配線します。

そのほかの図形描画サンプルは、Arduinoサンプルを参照してください。
ファイル(F) > スケッチ例 > Adafruit SSD1306 > ssd1306_128x64_i2c

配線
QT Py配線SSD1306(0.96inch)
3.3VVCC
GNDGND
GPIO5(SCL)SCL
GPIO4(SDA)SDA
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
SSD1306 OLEDの制御をします。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)
Adafruit SSD1306 by Adafruit
Adafruit GFX Library by Adafruit

【準備】
マイコン基板 <-> SSD1306
3V3         <-> VCC
GND         <-> GND
GPIO4(SDA)  <-> SDA
GPIO5(SCL)  <-> SCL

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

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

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
                                        //表示制御にはAdafruit製 SSD1306を使用する。
                                        
void setup()
{  

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

  display.clearDisplay();               //何か表示されている場合に備えて表示クリア

  display.setTextSize(2);               //フォントサイズは2(番目に小さい)
  display.setTextColor(SSD1306_WHITE);  //色指定はできないが必要
  display.setCursor(20, 0);            //テキストの表示開始位置
  display.print(F("TAMANEGI"));         //表示文字列
  display.setCursor(15, 25);
  display.print(F("OLED 0.96"));
  display.setCursor(25, 45);
  display.print(F("SSD1306"));
  

  display.display();                    //バッファ転送(表示)
}

void loop()
{
}
結果

SSD1306のサンプルスケッチが動作しました。

SPI(ST7735)

説明

SPIを使ってST7735(LCD 1.8inch)モニタのサンプルを動作させます。
Teensy 4.0ではSPIを1系統使用できます。

そのほかのグラフィックのサンプルはArduinoサンプルスケッチを参照してください。
ファイル(F) > スケッチ例 > Adafruit ST7735 and ST7789 Library > graphicstest

配線
QT Py配線ST7735(1.8inch)
3.3VVCC
3.3VLED
GNDGND
GPIO0CS
GPIO1RESET
GPIO2AO
GPIO10(SPI MOSI)SDA
GPIO8(SPI SCK )SCK
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
ST7735 LCDの表示制御します。
デフォルトピンを使用しています。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)
Adafruit ST7735 and ST7789 Library
Adafruit GFX Library

【準備】
マイコン基板 <-> ST7735
3V3            <-> VCC
GND            <-> GND
GPIO0(CS)      <-> CS
GPIO1(Reset)   <-> Reset
GPIO2(DC)      <-> AO
GPIO10(MOSI)   <-> SDA
GPIO18(SCK)    <-> SCK

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7735.h>
#include <SPI.h>

#define TFT_CS    0
#define TFT_RST   1
#define TFT_DC    2
#define TFT_MOSI  10
#define TFT_SCK   8

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

//S/W SPIはこちら。遅いが任意のピンを使用できる。
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);

void setup(void) 
{
  tft.initR(INITR_BLACKTAB);                //Init ST7735S初期化
  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし

  //テキスト表示
  tft.setRotation(3);                         //画面回転
  tft.setTextSize(3);                         //サイズ

  tft.setCursor(0, 10);                       //カーソル位置                      
  tft.setTextColor(ST77XX_GREEN);             //緑
  tft.printf("TAMANEGI\n");

  tft.setCursor(0, 50);                       //カーソル位置                      
  tft.setTextSize(2);                         //サイズ
  tft.setTextColor(ST77XX_RED);               //赤
  tft.printf("1.8inch LCD\n");
  tft.setTextColor(ST77XX_YELLOW);            //黄
  tft.printf("Res=128 x 160\n");
  tft.setTextColor(ST77XX_BLUE);              //青
  tft.printf("ST7735\n");
}

void loop()
{
}
結果

ST7735のサンプルスケッチが動作しました。

特別なスケッチ

Neopixel(WS2812)

説明

1秒ごとに、LEDの色を変化させます。
赤->緑->黄->青->紫->水->白

配線

基板実装WS2812を使用するので配線不要。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
基板実装WS2812を点灯させます。
1秒間隔で、赤->緑->黄->青->紫->水->白 の順で点灯させます。

QT Py のWS2812は電源としてGPIO12を使用します。
電源をONしないと点灯しません。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)
Adafruit NeoPixel by Adafruit 1.10.6

【準備】
配線不要

【バージョン情報】
2023/2/5 : 新規
**********************************************************************/

#include <Adafruit_NeoPixel.h>

#define POWER 12
#define DIN_PIN 11            // NeoPixel の出力ピン番号
#define LED_COUNT 1           // LEDの連結数
#define WAIT_MS 1000          // 次の点灯までのウエイト
#define BRIGHTNESS 128        // 輝度
Adafruit_NeoPixel pixels(LED_COUNT, DIN_PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  //WS2812の電源をONする
  pinMode(POWER, OUTPUT);
  digitalWrite(POWER, HIGH);

  pixels.begin();             //NeoPixel制御開始
}

void loop()
{
  pixels.clear();
  
  //pixels.Color(Red, Green, Blue)で、パレット情報を作成する。
  //赤点灯
  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);
}
結果

Nexpixelが1秒毎に色の変化をしました。

Touchセンサ

説明

タッチされているピンの状態をCOMに出力します。
Adafruit QT Pyでは
GPIO0, 1, 2, 3, 6, 7 でタッチセンサを使用することができます。

タッチセンサを使用するためにAdafruitの Free Touch Library by Adafruitを使用します。

配線

GPIO0 にジャンパワイヤを1本接続する。
今回は端子の先にアルミ箔を巻き付けました。
アルミ箔と端子の接触が悪いとセンサーへの感度が悪くなります。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
タッチセンサの状態をCOMに出力します。

タッチの状態は温度や環境によりばらつきが発生します。
非接触の状態と接触の状態の値を確認したうえで、タッチ判定を行う閾値を決めてください。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)
Adafruit Free Touch by Adafruit

【準備】
GPIO0 にジャンパワイヤを1本接続する。

接触時は端子を指でつまむなど接触する。
非接触時は端子に触らない。

【バージョン情報】
2023/2/5 : 新規
***********************************************************************/
#include "Adafruit_FreeTouch.h"

Adafruit_FreeTouch qt_0 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);

void setup() 
{
  Serial.begin(115200);

  if (! qt_0.begin())  
    Serial.println("Failed to begin qt on pin A0");
}

void loop() 
{
  Serial.printf("%d, %d\r\n", millis(), qt_0.measure());
 delay(100);
}
結果

タッチセンサーを読み取り、結果をプロットしました。
非接触の状態では読み取り値は500~600の間。
接触状態ではおおむね900を超えたあたりで少しばらつきがみられます。

おまけ

Qwiicコネクタ

説明

I2CスレーブにはQwiic対応させたコントローラモジュールを使用します。
現在のボタン押下状態を読み取りCOMに表示します。


使用するQwiicコントローラモジュールは以前作成したこちらを使用します。

配線

QwiicコネクタとコントローラモジュールのQwiicコネクタと接続します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Adafruit QT Py

【スケッチの説明】
I2CスレーブにはQwiic対応させたコントローラモジュールを使用します。
現在のボタン押下状態を読み取りCOMに表示します。

【ライブラリ】
Adafruit SAMD Board > Adafruit QT Py M0(SAMD21)

【準備】
QT Py <-> I2Cコントローラモジュール
Qwiic <-> Qwiic(JST SH 1mm 4pin)

【バージョン情報】
2023/2/5 : 新規
***********************************************************************/

#include "Wire.h"

#define I2C_ADDR  0x10            //スレーブ側に指定するI2Cアドレス

void setup()
{
  //I2Cマスター通信開始
  Wire.begin();
  
  Serial.begin(115200);
}

void loop() 
{
  char cStat = 0;
  //I2C コントローラから現在のボタン押下状態を読み取る
  if(Wire.requestFrom(I2C_ADDR, 2) != 0)
  {
    cStat = Wire.read();
  }
  Serial.printf("%02x\r\n",cStat);
}
結果

コントローラのボタンを適当に押します。
シリアルモニタにはボタンの押下状態が表示されました。

コメント

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