Seeed Studio XIAO MG24 によるピン多重化

XIAO MG24 は、22 本の汎用ピン、18 本のアナログピン、18 本のデジタルピン、2 系統の SPI、2 系統の UART、2 系統の I2C を備え、すべてのピンで PWM をサポートしています。私たちが利用できる豊富な種類のピンを提供します。この Wiki では、これらのピンをどのように制御するかを解説し、効果的に活用できるようにします 😀!
ハードウェア概要
デジタル
ハードウェア準備
| Seeed Studio XIAO MG24 Sense | Seeed Studio Expansion Base for XIAO with Grove OLED | Grove - Relay |
|---|---|---|
![]() | ![]() | ![]() |
XIAO MG24(Sense) を拡張ボードに取り付け、Grove ケーブルを使用してリレーを拡張ボードの A0/D0 インターフェースに接続してください。最後に、USB-C ケーブルで XIAO をコンピュータに接続します。
ソフトウェア実装
この例では、XIAO 拡張ボードに接続されたボタンを使ってリレーのオン/オフ状態を制御します。ボタンが押されるとリレーがオンになり、ボタンを離すとリレーがオフになります。
const int buttonPin = D1; // the number of the pushbutton pin
int buttonState = 0; // variable for reading the pushbutton status
const int relayPin = D0;
void setup() {
// initialize the Relay pin as an output:
pinMode(relayPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn Relay on:
digitalWrite(relayPin, HIGH);
} else {
// turn Relay off:
digitalWrite(relayPin, LOW);
}
}
結果グラフ
すべてが問題なく進めば、プログラムを書き込んだ後に次のような動作が確認できるはずです。

デジタルを PWM として使用
XIAO MG24(Sense) のすべての GPIO ピンは PWM 出力をサポートしています。そのため、任意のピンを使用して PWM を出力し、照明の明るさ調整やサーボ制御などを行うことができます。
ハードウェア準備
| Seeed Studio XIAO MG24 Sense | Seeed Studio Expansion Base for XIAO with Grove OLED | Grove - Variable Color LED |
|---|---|---|
![]() | ![]() | ![]() |
XIAO MG24(Sense) を拡張ボードに取り付け、その後 Grove ケーブルを使用して Variable Color LED を拡張ボードの A0/D0 インターフェースに接続してください。最後に、USB-C ケーブルで XIAO をコンピュータに接続します。
ソフトウェア実装
この例では、PWM 出力を使用してライトの明るさを制御する方法を示します。
int LED_pin = D0; // LED connected to digital pin 10
void setup() {
// declaring LED pin as output
pinMode(LED_pin, OUTPUT);
}
void loop() {
// fade in from min to max in increments of 5 points:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 3) {
// sets the value (range from 0 to 255):
analogWrite(LED_pin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
// fade out from max to min in increments of 5 points:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 3) {
// sets the value (range from 0 to 255):
analogWrite(LED_pin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
}
結果グラフ
プログラムが正常に動作すると、次のような動作結果が確認できます。

アナログ
XIAO MG24(Sense) 開発ボードには 12 ビット ADC が搭載されており、アナログセンサー値を高分解能で読み取ることができます。これにより、より正確な値を取得するのに役立ちます。
次に、ADC の特性を反映するために 2 つのセンサーを選択します。
ハードウェア準備
| Seeed Studio XIAO MG24 Sense | Grove-Variable Color LED | Grove-Rotary Angle Sensor | Seeed Studio Grove Base for XIAO |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
ソフトウェア実装
- DMA なしの analogRead
- DMA ありの analogRead
const int analogInPin = D1; // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to
int sensorValue = 0; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
void setup() {
Serial.begin(115200);
}
void loop() {
sensorValue = analogRead(analogInPin);
outputValue = map(sensorValue, 0, 4095, 0, 255);
analogWrite(analogOutPin, outputValue);
Serial.print("sensor = ");
Serial.print(sensorValue);
Serial.print("\t output = ");
Serial.println(outputValue);
delay(100);
}
#define ANALOG_VALUE_MIN 0 // Define the minimum analog value
#define ANALOG_VALUE_MAX 4095 // Define the maximum analog value for 12-bit ADC
#define NUM_SAMPLES 128 // Define the number of samples to collect each time
const int analogInPin = D1; // Analog input pin that the potentiometer is attached to
const int analogOutPin = LED_BUILTIN; // Analog output pin that the LED is attached to
// Buffers for storing samples
uint32_t analog_buffer[NUM_SAMPLES]; // Global buffer to store sampled values
uint32_t analog_buffer_local[NUM_SAMPLES]; // Local buffer to store sampled values for calculations
volatile bool data_ready_flag = false; // Data ready flag indicating new sample data is available
void analog_samples_ready_cb(); // Callback function called when samples are ready
void calculate_and_display_analog_level(); // Function to calculate and display the analog level
float getAverage(uint32_t *buffer, uint32_t buf_size); // Function to compute the average of the given buffer
void setup() {
Serial.begin(115200);
pinMode(analogOutPin, OUTPUT);
// Start DMA sampling, storing samples in analog_buffer, with callback on completion
analogReadDMA(analogInPin, analog_buffer, NUM_SAMPLES, analog_samples_ready_cb);
Serial.println("Sampling started...");
}
void loop() {
// If data is ready, process it
if (data_ready_flag) {
data_ready_flag = false;
calculate_and_display_analog_level();
}
}
void analog_samples_ready_cb() {
// Copy data to the local buffer in order to prevent it from overwriting
memcpy(analog_buffer_local, analog_buffer, NUM_SAMPLES * sizeof(uint32_t));
data_ready_flag = true;
}
void calculate_and_display_analog_level() {
// Rolling average for smoothing the analog level
static uint32_t rolling_average = 0u;
// Stop sampling in order to prevent overwriting the current data
ADC.scan_stop();
// Get the average of the sampled values
uint32_t analog_level = (uint32_t)getAverage(analog_buffer_local, NUM_SAMPLES);
// Adjust the analog level
analog_level = constrain(analog_level, ANALOG_VALUE_MIN, ANALOG_VALUE_MAX);
// Calculate the rolling average
rolling_average = (analog_level + rolling_average) / 2;
// Map the current average level to brightness
int brightness = map(rolling_average, ANALOG_VALUE_MIN, ANALOG_VALUE_MAX, 0, 255);
if (LED_BUILTIN_ACTIVE == LOW) {
analogWrite(analogOutPin, 255 - brightness);
} else {
analogWrite(analogOutPin, brightness);
}
// Print the average analog level and brightness output
Serial.print("sensor = ");
Serial.print(rolling_average);
Serial.print("\t output = ");
Serial.println(brightness);
// Restart sampling
analogReadDMA(analogInPin, analog_buffer, NUM_SAMPLES, analog_samples_ready_cb);
}
// Gets the average value of the provided samples
float getAverage(uint32_t *buffer, uint32_t buf_size) {
if (!buffer) {
return 0.0f;
}
float sum = 0.0f;
for (uint32_t i = 0u; i < buf_size; i++) {
sum += buffer[i];
}
return sum / buf_size;
}
アナログ信号の読み取りに DMA を使用したい場合は、ライブラリのバージョンが 2.2.0 より新しい必要があることに注意してください。現在、新しいバージョンはまだ承認されていないため、手動でインストールする必要があります。
結果グラフ
すべてが順調に進めば、プログラムを書き込んだ後、次のような効果が確認できるはずです。

UART
Arduino IDE を使用する場合、Serial 通信は多くのプロジェクトで不可欠な要素です。Arduino IDE で Serial を使用するには、まず Serial Monitor ウィンドウを開く必要があります。これは、ツールバーの Serial Monitor アイコンをクリックするか、ショートカットキー Ctrl+Shift+M を押すことで行えます。
一般的な Serial の使い方
一般的によく使用される Serial 関数には次のようなものがあります:
Serial.begin()-- 指定したボーレートで通信を初期化します。Serial.print()-- 読み取り可能な形式でデータを Serial ポートに送信します。Serial.write()-- バイナリデータを Serial ポートに送信します。Serial.available()-- Serial ポートから読み取ることができるデータがあるかどうかを確認します。Serial.read()-- Serial ポートから 1 バイトのデータを読み取ります。Serial.flush()-- 送信中のシリアルデータの送信完了を待機します。
これらの Serial 関数を使用することで、Arduino ボードとコンピュータ間でデータを送受信でき、インタラクティブなプロジェクトを作成する多くの可能性が広がります。
以下にサンプルプログラムを示します:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
void loop() {
// send data to the serial port
Serial.println("Hello World!");
// read data from the serial port
if (Serial.available() > 0) {
// read the incoming byte:
char incomingByte = Serial.read();
// print the incoming byte to the serial monitor:
Serial.print("I received: ");
Serial.println(incomingByte);
}
// wait for a second before repeating the loop
delay(1000);
}
Serial1 の使用方法
上記の XIAO MG24(Sense) のピン配置図に基づくと、特定のパラメータとして TX ピンと RX ピンがあることがわかります。 これは通常の Serial 通信とは異なりますが、いくつかのパラメータを追加する必要がある点を除けば、使い方は非常によく似ています。 そこで次に、チップから引き出されたピンを使用してシリアル通信を行います。
#define BAUD 115200
void setup() {
Serial1.begin(BAUD);
}
void loop() {
if(Serial1.available() > 0)
{
char incominByte = Serial1.read();
Serial1.print("I received : ");
Serial1.println(incominByte);
}
delay(1000);
}
I2C
XIAO MG24(Sense) には I2C インターフェースがあり、多くのセンサーのデータ送信および解析、さらには一部の OLED 画面の使用に利用できます。
ハードウェアの準備
| Seeed Studio XIAO MG24 Sense | Seeed Studio Expansion Base for XIAO with Grove OLED |
|---|---|
![]() | ![]() |
XIAO 拡張ボード上の OLED ディスプレイは I2C プロトコルを使用しており、ボード上の I2C 回路を介して XIAO の I2C インターフェースに接続されています。したがって、XIAO を拡張ボードに直接挿し込み、画面にコンテンツを表示するようにプログラムすることができます。
ソフトウェア実装
この例では、Seeed Studio Expansion Base for XIAO MG24(Sense) 上の OLED ディスプレイの使用方法を紹介します。
ステップ 1. Seeed Studio XIAO MG24(Sense) を拡張ボードに取り付け、Type-C ケーブルを接続します。
ステップ 2. u8g2 ライブラリをインストールします。
ステップ 3. コードをコピーして Arduino IDE に貼り付け、アップロードします。
- 以下の zip ファイルをダウンロードします
📄 [ZIP] smiley_face ヘッダー
- "smiley_face. h" という名前のヘッダーファイルを作成し、ダウンロードした zip ファイルの内容を作成したヘッダーファイルにコピーします

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include "smiley_face.h"
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
int xx = 20;
int yy = 10;
void setup() {
u8g2.begin();
}
void loop() {
smeil_display();
delay(500);
}
void smeil_display() {
const unsigned char* smileImages[] = {
semil1, semil2, semil3, semil4, semil5,
semil6, semil7, semil8, semil9, semil10,
semil11, semil12, semil13, semil14, semil15,
semil16, semil17, semil18, semil19, semil20,
semil21, semil22, semil23, semil24, semil25,
semil26, semil27
};
int delays[] = {
40, 50, 40, 40, 40,
40, 40, 50, 40, 40,
40, 40, 40, 50, 40,
40, 50, 40, 40, 50,
40, 50, 40, 40, 50,
50, 50, 40, 50
};
for (int i = 0; i < sizeof(smileImages) / sizeof(smileImages[0]); i++) {
u8g2.firstPage();
do {
u8g2.drawXBMP(xx, yy, 48, 48, smileImages[i]);
} while (u8g2.nextPage());
delay(delays[i]);
}
}
結果グラフ

SPI
XIAO MG24(Sense) チップには複数のペリフェラルが統合されており、その中には SPI インターフェースも含まれます。これを使用して、フラッシュメモリ、ディスプレイ、センサーなどの外部 SPI デバイスを接続できます。
Arduino ライブラリ概要
Waveshare が提供する Arduino のサンプルプログラムに基づき、XIAO シリーズ全体で使用できる Arduino ライブラリを作成しました。以下のボタンから、このライブラリの Github に直接アクセスできます。
ハードウェアの準備
ピン接続
上記のようにハードウェアを準備したら、ジャンパーワイヤーを使用して XIAO と OLED の SPI インターフェースを接続します。配線方法については、次の図を参照してください。

インストール
zip ライブラリをダウンロードしたら、Arduino IDE を開き、Sketch > Include Library > Add .ZIP Library をクリックします。先ほどダウンロードした zip ファイルを選択し、ライブラリが正しくインストールされると、通知ウィンドウに Library added to your libraries と表示されます。これはライブラリが正常にインストールされたことを意味します。

ソフトウェア実装
ライブラリを正しくダウンロードしてインストールすると、examples フォルダ内に helloworld.ino と bgcolor.ino という 2 つのサンプルプログラムが見つかります。bgcolor.ino は背景色を表示するサンプルで、デフォルトでは赤に設定しています。helloworld.ino は弊社ロゴのアニメーションを表示するサンプルで、このサンプルには bgcolor のサンプルが持つ効果も含まれています。
#include <st7789v2.h>
#include "SPI.h"
#include "seeed.h"
st7789v2 Display;
void setup() {
// put your setup code here, to run once:
Display.SetRotate(270);
Display.Init();
Display.SetBacklight(100);
Display.Clear(WHITE);
}
void loop() {
// put your main code here, to run repeatedly:
// Display.SetPixel(100, 100, RED);
// Display.DrawPoint(50, 50, YELLOW, DOT_PIXEL_8X8, DOT_FILL_AROUND);
Display.DrawImage(gImage_seeed, 20, 90, 240, 47);
Display.DrawLine(15, 65, 65, 65, MAGENTA, DOT_PIXEL_2X2, LINE_STYLE_SOLID);
Display.DrawLine(15, 70, 80, 70, MAGENTA, DOT_PIXEL_2X2, LINE_STYLE_SOLID);
Display.DrawRectangle(15, 80, 265, 150, GRAY, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 10, 25, BLUE, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 10, 20, BLACK, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 10, 15, RED, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 10, 10, GREEN, DOT_PIXEL_2X2, DRAW_FILL_FULL);
Display.DrawCircle(270, 10, 25, BLUE, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(270, 10, 20, BLACK, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(270, 10, 15, RED, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(270, 10, 10, GREEN, DOT_PIXEL_2X2, DRAW_FILL_FULL);
Display.DrawCircle(10, 230, 25, BLUE, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 230, 20, BLACK, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 230, 15, RED, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(10, 230, 10, GREEN, DOT_PIXEL_2X2, DRAW_FILL_FULL);
Display.DrawCircle(270, 230, 25, BLUE, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(270, 230, 20, BLACK, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(270, 230, 15, RED, DOT_PIXEL_2X2, DRAW_FILL_EMPTY);
Display.DrawCircle(270, 230, 10, GREEN, DOT_PIXEL_2X2, DRAW_FILL_FULL);
Display.DrawLine(200, 160, 265, 160, GRAYBLUE, DOT_PIXEL_2X2, LINE_STYLE_SOLID);
Display.DrawLine(215, 165, 265, 165, GRAYBLUE, DOT_PIXEL_2X2, LINE_STYLE_SOLID);
Display.DrawString_EN(20, 180, "By: Jason", &Font20, WHITE, BLACK);
// Display.DrawNum(100, 220, 123456, &Font24, RED, BRED);
Display.DrawFloatNum(100, 210, 1.00, 2, &Font16, WHITE, BLACK);
}
ディスプレイ上に Seeed Studio のロゴが動的に表示されるのがわかります。

まとめ
XIAO MG24 (Sense) のピンの基本的な機能を学びました。次は、内蔵センサーをさらに探ってみましょう。

技術サポート & 製品ディスカッション
弊社製品をお選びいただきありがとうございます。弊社は、製品をできるだけスムーズにご利用いただけるよう、さまざまなサポートを提供しています。お好みやニーズに合わせて選べる、いくつかのコミュニケーションチャネルをご用意しています。










