今回はXAIO ESP32C6 SH1106 RDA5708M の構成で組んでみました。I2C で SH1106 RDA5708M を接続するだけで完成です。

コードも AI にお願い
#include <Arduino.h>
#include <Wire.h>
#include <radio.h>
#include <RDA5807.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
#include <RotaryEncoder.h>
// OLEDの設定 (SH1103 128x64)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ロータリーエンコーダのピン設定
#define PIN_IN1 D7 // CLK
#define PIN_IN2 D6 // DT
#define PIN_PUSH D3 // SW
// ラジオとエンコーダのインスタンス作成
RDA5807 radio;
RotaryEncoder *encoder = nullptr;
// ラジオの各種変数
#define MAP_BAND RADIO_BAND_FMWORLD
RADIO_FREQ currentFreq = 8130; // 初期周波数 81.3 MHz
RADIO_FREQ minFreq = 7600; // 最低周波数 76.0 MHz
RADIO_FREQ maxFreq = 10800; // 最高周波数 108.0 MHz
int stepFreq = 10; // 周波数ステップ (0.1 MHz)
int currentVolume = 2; // 初期音量 (0〜15)
const int maxVolume = 15;
const int minVolume = 0;
// モード管理用の定義
enum Mode {
MODE_TUNE, // 周波数変更モード
MODE_VOL // 音量調整モード
};
Mode currentMode = MODE_TUNE; // 起動時は周波数モード
bool shouldUpdateDisplay = true;
// 割り込み処理関数(エンコーダの回転検知)
void IRAM_ATTR checkPosition() {
encoder->tick();
}
// 画面描画関数
void updateDisplay() {
display.clearDisplay();
display.setTextColor(SH110X_WHITE);
// 1. タイトルバー
display.setTextSize(1);
display.setCursor(0, 0);
display.print("XIAO ESP32C6 RADIO");
display.drawLine(0, 12, 127, 12, SH110X_WHITE);
// 2. 周波数表示エリア
if (currentMode == MODE_TUNE) display.print(">"); else display.print(" ");
display.setCursor(10, 22);
display.setTextSize(2);
display.print((float)currentFreq / 100.0, 1);
display.setTextSize(1);
display.print(" MHz");
if (currentMode == MODE_TUNE) display.print(" [TUNE]");
// 3. 音量表示エリア
display.setCursor(10, 42);
if (currentMode == MODE_VOL) display.print(">"); else display.print(" ");
display.print(" VOL: ");
display.print(currentVolume);
// 音量をバーグラフで簡易表示
display.drawRect(65, 43, 50, 7, SH110X_WHITE);
display.fillRect(65, 43, map(currentVolume, 0, 15, 0, 50), 7, SH110X_WHITE);
if (currentMode == MODE_VOL) {
display.setCursor(110, 42);
display.print("*");
}
// 4. 下部ステータス
display.drawLine(0, 53, 127, 53, SH110X_WHITE);
display.setCursor(0, 56);
display.setTextSize(1);
display.print("RSSI: "); display.print(radio.getRssi());
if (radio.isStereo()) display.print(" STEREO");
display.display();
}
void setup() {
Serial.begin(115200);
// OLEDの初期化
if(!display.begin(0x3C, true)) { // アドレスは環境に合わせて調整してください
Serial.println("OLED init failed");
for(;;);
}
display.display();
delay(1000);
// 1. ピンモードの設定(内蔵プルアップを有効化)
pinMode(PIN_IN1, INPUT_PULLUP);
pinMode(PIN_IN2, INPUT_PULLUP);
pinMode(PIN_PUSH, INPUT_PULLUP);
// エンコーダのインスタンス作成
encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::FOUR3); // TWO03
// 2. 割り込みの設定
attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE);
// ラジオの初期化(環境に合わせて設定してください)
Wire.begin();
radio.setup();
radio.setBand(MAP_BAND);
radio.setFrequency(currentFreq);
radio.setVolume(currentVolume);
//選局時のノイズを抑える
radio.setSoftmute(true);
}
void loop() {
static int lastPosition = 0;
static unsigned long lastPushTime = 0;
// エンコーダの回転チェック
encoder->tick();
int newPosition = encoder->getPosition();
if (newPosition != lastPosition) {
int direction = newPosition - lastPosition;
if (currentMode == MODE_TUNE) {
// 周波数変更モード
currentFreq += direction * stepFreq;
if (currentFreq > maxFreq) currentFreq = maxFreq;
if (currentFreq < minFreq) currentFreq = minFreq;
radio.setFrequency(currentFreq);
} else {
// 音量調整モード
currentVolume += direction;
if (currentVolume > maxVolume) currentVolume = maxVolume;
if (currentVolume < minVolume) currentVolume = minVolume;
radio.setVolume(currentVolume);
}
lastPosition = newPosition;
shouldUpdateDisplay = true;
}
// プッシュスイッチのチェック(チャタリング防止付き)
if (digitalRead(PIN_PUSH) == LOW) {
if (millis() - lastPushTime > 300) { // 300msのデバウンス
// モード切り替え
currentMode = (currentMode == MODE_TUNE) ? MODE_VOL : MODE_TUNE;
shouldUpdateDisplay = true;
lastPushTime = millis();
}
}
// 画面の更新
if (shouldUpdateDisplay) {
updateDisplay();
shouldUpdateDisplay = false;
}
delay(10); // 安定化のための僅かなウェイト
}
ESP32C3 ESP32C6 は小型なので活用できそうです。また RDA5708M も使いやすく感度もよさそうです。次は50MH FM に使えないかと AI に相談していますがどうも 25KHz ステップしか出来ないようです。

コメント