【Arduino】XIAO MG24/XIAO MG24 Senseを使う

it

SeeedStudioのXIAO MG24とXIAO MG24 Senseを使ってみました。
XIAOシリーズに追加された無線も使えるマイコンをArduino環境で使いました。
基本的なGPIOと通信の使い方の他、6軸IMU、PDM Microphoneを使いました。

XIAO MG24 / XIAO MG24 Sense

簡単紹介

Seeedstudio のXIAO規格にSilicon Labs EFR32MG24搭載。
無線機能他、XIAO MG24 Senseには、IMU 6軸センサ、PMD Picrophoneを搭載。

メーカーホームページ : Seeed Studio XIAO MG24を始める | Seeed Studio Wiki

◆入手

国内電子部品販売店サイト、AliExpressで入手できます。
Ali Expressで購入する場合、技適マークのない製品が贈られることがあるので商品画像や説明をよく確認する必要あり。

◆パッケージ状態

確実に技適マーク付きを入手するため、スイッチサイエンスから購入しました。
パッケージには本体のほかにピンヘッダ1セット分が同梱されています。

◆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値を表示してみた内容を記事にしました。
XIAO
MG24
XIAO MG24を使った記事
基本的なGPIOの使い方、6軸IMU, PDMを使った内容を記事にしました。

ピン配置

外観

◆XIAO MG24

◆XIAO MG24 Sense

使ってみた

◆開発

Arduino環境で開発します。
ボードライブラリにはSeeed Studioの「Sillicon Labs by Silicon Labs」の「Seeed Studio XIAO MG24 (Sense)」を使いました。

◆性能評価

XIAO間でのCPUクロックについて比べました。
XIAOシリーズに採用されているCPUとしては中盤程度の能力です。

基板名CPUクロック(MHz)
XIAO SAMD21SAMD2148
XIAO RP2040RP2040133(OverClock 300MHz)
XIAO RP2350RP2350133(OverClock 300MHz)
XIAO nRF52840nRF5284064
XIAO ESP32C3ESP32-C3160
XIAO EsP32C6ESP32-C6160
XIAO ESP32S3ESP32-S3240
XIAO RA4M1RA4M148
XIAO MG24EFR32MG2478

◆ユーティリティ

Resetボタンがついていますがとても小さいので指で押すのは難しい。
反発も強いのでだいぶん押しにくいと感じます。
つまようじの後ろ側がほどほどに押せます。

ユーザLEDは単色で橙点灯が使えます。
チャージLED(赤)と一体なのにチャージLEDが勝手に点灯していて見づらい感があります。

UFLアンテナコネクタがついていますが、アンテナは購入時に付属しません。

◆無線

無線機能にはBluetooth、Zigbeeなど搭載されているようです。
Arduino環境でのサンプルをいくつか試してみましたが、いづれもコンパイルエラーが発生し簡単に使うことはできませんでした。
あまり時間を取れないのでこのまま省略します。

◆XIAO MG24と XIAO MG24 Sense

XIAO MS24 Senseには、6軸IMUとアナログマイクが実装されています。
傾きや重力検出、音声検出をしたい場合はSenseを購入します。

◆6軸IMU

6軸IMUを使うために、SeeedStudio公式のライブラリのインストールが必要です。

XIAO MG24の角度と読み取り値をグラフにした関係です。
以前XIAO nRF52480でも同じ確認をしましたが、基板の状態と読み取り値との関係が違っているようです。

◆PDM Microphone

XIAO MG24-Senseに搭載されているアナログマイクです。
購入時にプログラミング(サンプルされている内容では、音を検出するとユーザLEDが点灯します。
音量に比例して明度が変化しました。

拍手の音を徐々に大きくした様子です。
時々光るチャージLED(赤)のおかげで分かりにくい。

サンプルに収録されているスケッチと同じと思います。
File > Examples > SilabsMicrophoneAnalog > MicrophoneVolume

準備

Arduino環境の作成

◆開発環境

当記事ではArduino環境を使って開発します。
Arduino環境の準備はこちらの記事で紹介しています。

◆ボードライブラリ

Arduino IDEのボードマネージャからMG24用のライブラリのインストールとボードの選択をします。

ボードマネージャのURLhttps://siliconlabs.github.io/arduino/package_arduinosilabs_index.json
検索mg24
ボードライブラリSilicon Labs by SiliconLabs
選択するボード
XIAO MG24
XIAO MG24 Sense
Silicon Labs > Seeed Studio XIAO MG24(Sense)
動作確認時のバージョン3.0.0

◆モジュールライブラリ

モジュールや機能を使用しない場合はモジュールライブラリのインストールは不要です。

SSD1306

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

ST7735

ライブラリ名検索確認時のバージョン
Adafruit ST7735 and ST7789 Library by AdafruitST77351.11.0
Adafruit GFX Library by AdafruitGFX1.12.0

6軸IMU(LSM6DS3)

ライブラリ名検索確認時のバージョン
Seeed Arduino LSM6DS3 by Seeed StudioLSM6DS32.0.5

スケッチ : XIAO MG24 / XIAO MG24 Sense共通

デジタル出力

説明

GPIOのデジタル出力を使い信号の出力をモニタします。
GPIO出力のLowとHighの繰り返し速度の計測をします。

GPIO D0(GPIO0)とGNDをオシロスコープ(HDS272)でプローブし、信号間の時間を計測します。

配線

スケッチ

void setup()
{
  pinMode(D0, OUTPUT);
}

void loop()
{
  while(1)
  {
    digitalWrite(D0, HIGH);
    digitalWrite(D0, LOW);
  }
}

結果

オシロスコープ(HDS272)でGPIOのLow/High時間を計測しました。
信号の間隔は4.88us、1秒間に繰り返す周期は204.9kHzでした。
画像右下はマクロで確認した結果です。
約1m秒の周期でなぜか信号が停止する期間がありました。
原因はわかりません。

デジタル出力(ユーザLED 橙)

説明

XIAO MG24のユーザLED(橙)を使います。
LEDは0.5秒点灯、0.5秒消灯を繰り返します。

配線

配線不要

スケッチ

void setup()
{
  pinMode(PIN_LED, OUTPUT);
  while(1)
  {
    digitalWrite(PIN_LED, HIGH);
    delay(500);
    digitalWrite(PIN_LED, LOW);
    delay(500);
  }
}

void loop()
{
}

結果

ユーザLEDは橙で、チャージLED赤と同時点灯することがあります。

GPIOデジタル入出力(ボタンLED)

説明

XIAO MG24のデジタル入力とデジタル出力を使います。

ボタンの入力はINPUT_PULLUPによりプルダウン設定をします。
ボタンを押している間LEDを消灯、ボタンを離すと点灯させます。

ボタンの入力にINPUT_PULLDOWNの設定ができますが、実際には機能していないようです。
プルダウンで読み取りを行う場合、抵抗を使ったプルダウン回路が必要です。

配線

INPUT_PULLUPを設定した場合の回路です。

スケッチ

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

void setup()
{
  Serial.begin(115200);
  delay(1000);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop()
{
  int iStat = digitalRead(BUTTON_PIN);
  Serial.printf("%d\n", iStat);
  digitalWrite(LED_PIN, iStat);
}

結果

ボタンを押していない間LEDが点灯し、ボタンを押すとLEDが消灯しました。

ADC

説明

XIAO MG24のADCを使います。

電圧はXIAO SAMD21のDACを使い0 ~ 3.3Vを入力します。
XIAO MG24のADCで読み取った値はUSBシリアルに出力します。

配線

サンプルスケッチ

#define ADC_PIN   (D0)

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);
}

結果

左下はXIAO SAMD21から入力した電圧をオシロスコープ(HDS272)で読み取ったものです。
右下は読み取った値をプロットしてグラフにしました。
プロットグラフ時間軸は1周期4秒としてリスケーリングしています。

読み取った値はノイズの少ないきれいなリニア波形です。
3.3V印可時のAD値は4000強で精度も十分に思います。

出力結果をリアルタイムでモニタすると、出力がまとまって出てきているように見えました。
ある程度バッファがたまってから出力しているように見えます。
それによりデータが欠損したり、ADCのモニタができていないような現象は起きていないように見えます。

PWM

説明

XIAO MG24のPWM信号をモニタします。
DC「ADC」で使った構成を使い、スケッチは一部修正します。

ADCから読み取った信号(12bit)を、PWMの分解能にリスケーリングして出力します。
ADCの分解能は12bit、PWMは8bitなので、読み取った値を4bit右シフトします。

PWMの信号はオシロスコープ(HDS272)で読み取ります。

配線

オシロスコープのプローブ1ch(黄)でPWMの信号をモニタする。
XIAO MG24のD1、グランドはGNDに接続。

プローブ2chは入力するアナログ信号をモニタする。
XIAO MG24のD0、グランドはGNDに接続。

サンプルスケッチ

#define ADC_PIN   (D0)
#define PWM_PIN   (D1)
void setup()
{
  Serial.begin(115200);
  pinMode(ADC_PIN, INPUT);
  pinMode(PWM_PIN, OUTPUT);
}

void loop()
{
  int iADC = 0;
  iADC = analogRead(ADC_PIN);
  analogWrite(PWM_PIN, (iADC >> 4));
  Serial.printf("d, %d\r\n", iADC, (iADC >> 4));
  delay(2);
}

結果

PWMの信号出力の波形をオシロスコープ(HDS272)で読み取りました。
PWMの周期は1kHzです。

青線が3.3V付近にある状態(画像左上)ではPWMのDuty高めで、ほとんどHigh出力です。
青線が1.8V付近にある状態(画像中央)ではPWMのDutyはほぼ半分程度になっています。
青線が0V付近にある状態(画像右下)ではPWMのDutyは低めで、一瞬Highの信号が出ています。

UART通信

UART

XIAO USBシリアルとUARTは別々のオブジェクトを使用します。
UARTで使用するピン変更はできません。

ポート(仮称)オブジェクト名UARTピン
USBシリアルSerial
UARTSerial1TX(6), RX(7)

説明

XIAO MG24のUSBシリアルとUARTを使います。

UARTモジュール経由で”1″を入力するとLEDが点灯、”0″を入力するとLEDは消灯します。
タクトボタンを押すとUARTモジュールに”1″を、ボタンを離すと”0″を送信します。
USBシリアルにはUARTからの受信情報、ボタンの押されている状態を出力します。

配線

スケッチ

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

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

  delay(1000);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

}

void loop()
{
  int iStat = digitalRead(BUTTON_PIN);

  while(1)
  {
    int Stat = digitalRead(BUTTON_PIN);
    if(Stat != iStat)
    {
      Serial1.printf("%d\r\n", Stat);
      Serial.printf("Button status is %d\r\n", Stat);
      iStat = Stat;
    }

    if(Serial1.available() != 0)
    {
      char dat = Serial1.read();
      if(dat == '0')
      {
        digitalWrite(LED_PIN, LOW);
      }
      else if(dat == '1')
      {
        digitalWrite(LED_PIN, HIGH);
      }
      Serial.printf("Data received : %c\n", dat);
    }
  }
}

結果

USBシリアルとUART通信、LEDの状態です。
UARTモジュールは”COM7”で認識されました。
Teraterm から”1″を入力するとLEDが点灯し、”0″を入力するとLEDは消灯しました。
ボタンを離すとUARTには”0″、ボタンを押すと”1″が表示されました。

I2C(SSD1306)

説明

I2Cを使ってSSD1306(OLED 0.96inch)モニタを表示制御します。
SSD1306の表示制御にはAdafruit製の「U8G2 by oliver」を使いました。

いつもは「Adafruit SSD1306 by Adafruit」を使いますが、XIAO MG24ではコンパイルできなかったため、「U8G2 by oliver」を使っています。

表示内容は、「バウンドボール」で円が画面端まで移動すると反射します。

配線

スケッチ

#include <Wire.h>
#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

float x = 20;
float y = 20;
float vx = 2.0;
float vy = 1.5;
int radius = 4;

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

void loop() {
  x += vx;
  y += vy;

  if (x <= radius || x >= 128 - radius) vx = -vx;
  if (y <= radius || y >= 64 - radius) vy = -vy;

  u8g2.clearBuffer();
  u8g2.drawDisc((int)x, (int)y, radius);
  u8g2.sendBuffer();

  delay(30);
}

結果

バウンドボールの表示ができました。

SPI(ST7735)

説明

SPIを使ってST7735(LCD 1.8inch)を表示制御します。
表示サンプルはAIにコーディングしてもらいました。

「かっこいいスクリーンセーバー」をテーマにしています。
表示された画像はひし形のグラデーションでした。

使用したモジュールライブラリはAdafruitの「Adafruit ST7735 and ST7789 Library by Adafruit」です。

配線

スケッチ

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

#define TFT_CS   1
#define TFT_RST  2
#define TFT_DC   3

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

float t = 0.0;

uint16_t hsvToRgb(float h, float s, float v) {
  float r, g, b;

  int i = int(h * 6);
  float f = h * 6 - i;
  float p = v * (1 - s);
  float q = v * (1 - f * s);
  float t = v * (1 - (1 - f) * s);

  switch (i % 6) {
    case 0: r = v; g = t; b = p; break;
    case 1: r = q; g = v; b = p; break;
    case 2: r = p; g = v; b = t; break;
    case 3: r = p; g = q; b = v; break;
    case 4: r = t; g = p; b = v; break;
    case 5: r = v; g = p; b = q; break;
  }

  return tft.color565(r * 255, g * 255, b * 255);
}

void setup() {
  tft.initR(INITR_GREENTAB);
  tft.fillScreen(ST77XX_BLACK);
}

void loop() {
  for (int y = 0; y < tft.height(); y++) {
    for (int x = 0; x < tft.width(); x++) {

      float nx = (float)x / tft.width();
      float ny = (float)y / tft.height();

      float wave = sin(nx * 10 + t) + sin(ny * 10 + t * 1.3);
      float hue = fmod((wave + 2.0) * 0.25, 1.0);

      uint16_t color = hsvToRgb(hue, 1.0, 1.0);
      tft.drawPixel(x, y, color);
    }
  }

  t += 0.05;
}

結果

実行結果です。
ひし形のグラデーション画像が表示されました。

スケッチ : XIAO MG24 Sense のみ

6軸IMU

説明

XIAO MG24 Senseの6軸IMUセンサを使います。

ボードライブラリ以外にモジュールライブラリのインストールが必要です。
モジュールライブラリは「Seeed Arduino LSM6DS3」を使用しました。
「Examples > Seeed Arduino LSM6DS3 > LowLevelExample」ベースに修正をしています。

X, Y, Z軸の情報を10ms毎に読み取りシリアル出力します。
各軸を2秒程度で180°回転させる目標で手作業で回転させています。

スケッチ

#include "LSM6DS3.h"
#include "Wire.h"
#include "SPI.h"

uint16_t errorsAndWarnings = 0;

LSM6DS3Core myIMU(I2C_MODE, 0x6A);    //I2C device address 0x6A

void setup() {

    Serial.begin(9600);
    while (!Serial);

    //Call .beginCore() to configure the IMU
    if (myIMU.beginCore() != 0) {
        Serial.print("\nDevice Error.\n");
    } else {
        Serial.print("\nDevice OK.\n");
    }

    uint8_t dataToWrite = 0;  //Temporary variable

    //Setup the accelerometer******************************
    dataToWrite = 0; //Start Fresh!
    dataToWrite |= LSM6DS3_ACC_GYRO_BW_XL_100Hz;
    dataToWrite |= LSM6DS3_ACC_GYRO_FS_XL_8g;
    dataToWrite |= LSM6DS3_ACC_GYRO_ODR_XL_104Hz;

    //Now, write the patched together data
    errorsAndWarnings += myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, dataToWrite);

    //Set the ODR bit
    errorsAndWarnings += myIMU.readRegister(&dataToWrite, LSM6DS3_ACC_GYRO_CTRL4_C);
    dataToWrite &= ~((uint8_t)LSM6DS3_ACC_GYRO_BW_SCAL_ODR_ENABLED);

}

void loop() {
    int16_t temp;

    if (myIMU.readRegisterInt16(&temp, LSM6DS3_ACC_GYRO_OUTX_L_XL) != 0) {
        errorsAndWarnings++;
    }
    Serial.print(" X, Y, Z = ");
    Serial.print(temp);
    Serial.print(", ");
    //Acelerometer axis Y
    if (myIMU.readRegisterInt16(&temp, LSM6DS3_ACC_GYRO_OUTY_L_XL) != 0) {
        errorsAndWarnings++;
    }
    Serial.print(temp);
    Serial.print(", ");

    //Acelerometer axis Z
    if (myIMU.readRegisterInt16(&temp, LSM6DS3_ACC_GYRO_OUTZ_L_XL) != 0) {
        errorsAndWarnings++;
    }
    Serial.print(temp);
    Serial.println("");
    delay(100);
}

結果

モジュールの角度状態と読み取った結果をグラフにしました。
静止状態でも5~10程度のばらつきがありました。

PDM Microphone

説明

XIAO nRF52840 SenseのPDM Microphoneを使います。

XIAO nRF52840 ボードライブラリ「Seeed nRF52 Boards by Seeed Studio」のサンプルスケッチ
「Examples > nRF52840 PDM – Adafruit Fork > PDMSerialPlotter」
を使います。

実行すると検出した音情報をUSBシリアルに出力します。

スケッチ

File > Examples > SilabsMicrophoneAnalog > MicrophoneVolume

結果

徐々に手拍子を大きくしています。
音量に応じLEDの発行が強くなる様子がわかります。

チャージLEDと同じ個所が点滅するので少しわかりにくいです。

コメント

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