
M5StickCPlusとM5StackCore2とiphone(イメージ)
はじめに
Bluetoothの無変調出力をしてアンテナの測定に利用したいというリクエストがあったので、M5StackCore2及びM5StickCPlusを使って簡単な送信機の試作をしてみました。
実験
M5SackCore2(M5StickCPlus)に下記コードを書き込んで動作させました。※アプリが起動するとシリアル出力へテキストが送信されるので動作確認が出来ます。
結果
スペアナを使ったキャリアの確認は出来てませんが、下記iOSアプリ(BLE SCANNER)でキャリアの確認が出来ました!
https://apps.apple.com/jp/app/ble-scanner-4-0/id1221763603

動作説明
「M5Stack Core2(ESP32搭載)」を使い、BLEアドバタイズ(広告パケット)を高速かつ連続送信して、スペアナ上で“ほぼ固定キャリア”のように見せる方法です。
※BLE仕様上、完全な無変調キャリア(CW)は出せませんが、
アドバタイズを高速繰り返しすることで「固定波に近い連続出力」を確認できます。
コード説明
このコードはBLEのアドバタイズパケットを最短間隔(20ms)で出します。
出力をスペアナやSDR(Software Defined Radio)で観測すると、2.4GHz帯に「細かく点滅するようなピーク」が現れます。
→ 拡大して見るとパルス的な出力ですが、やや広いRBWで見るとほぼキャリアのように見える波形になると思います。
esp_ble_tx_power_set() を使って送信強度を変更可能です。
M5StackCore2用コード
#include <M5Core2.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEAdvertising.h>
BLEAdvertising *pAdvertising;
void setup() {
M5.begin();
Serial.begin(115200);
Serial.println("BLE carrier-like advertisement test");
BLEDevice::init("BLE_Carrier");
pAdvertising = BLEDevice::getAdvertising();
// 広告間隔を最短に設定(単位は0.625ms)
pAdvertising->setMinInterval(0x20); // 32 × 0.625ms = 20ms
pAdvertising->setMaxInterval(0x20);
// 出力パワー設定(オプション)
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9); // 最大出力 (+9dBm)
// 簡単なダミーデータを設定
BLEAdvertisementData advData;
advData.setFlags(0x06);
advData.setManufacturerData("1234567890123456");
pAdvertising->setAdvertisementData(advData);
// 連続アドバタイズ開始
pAdvertising->start();
}
void loop() {
// 再送を防ぐために定期的に再スタート
static unsigned long last = 0;
if (millis() - last > 10000) {
pAdvertising->stop();
delay(10);
pAdvertising->start();
last = millis();
}
}
M5StickCPlus用コード
#include <M5StickCPlus.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEAdvertising.h>
BLEAdvertising *pAdvertising;
void setup() {
M5.begin();
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setTextSize(2);
M5.Lcd.println("BLE Carrier Test");
Serial.begin(115200);
Serial.println("BLE carrier-like advertisement test (M5StickC Plus)");
// BLE初期化
BLEDevice::init("BLE_Carrier");
pAdvertising = BLEDevice::getAdvertising();
// 広告間隔を最短に設定(単位は0.625ms)
pAdvertising->setMinInterval(0x20); // 20ms
pAdvertising->setMaxInterval(0x20);
// 出力パワーを最大に設定
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);
// ダミーデータを設定
BLEAdvertisementData advData;
advData.setFlags(0x06);
advData.setManufacturerData("1234567890123456");
pAdvertising->setAdvertisementData(advData);
// アドバタイズ開始
pAdvertising->start();
M5.Lcd.println("Advertising...");
}
void loop() {
M5.update();
static unsigned long last = 0;
if (millis() - last > 10000) {
// 定期的に再送信リセット
pAdvertising->stop();
delay(10);
pAdvertising->start();
last = millis();
Serial.println("Restart advertising");
}
}
以上です。
