ESP32でFMラジオを聞いてみる
今回は、ESP32とPDA5807M FMラジオモジュールを使ったFMラジオ作成を紹介します。
最近FMラジオを聞く機会が少なくなってきました。
車に乗った時くらいでしょうか。
今回は防災グッズの一環でFMラジオを作成していきます。
今回はこちらのFMラジオモジュールを使用します。
(PDA5807M) aitendoさん(変換基盤)
このモジュールはPINのピッチが2mmのためブレッドボードやユニバーサル基板に直接取り付けることができません。
変換基盤がアマゾンやaitendoさんに売っていますのでそちらを利用すると便利です。
PDA5807MのFMラジオモジュールを使う場合、ライブラリが用意されているので
こちらを使うと簡単にFMラジオを作成できるのでとても便利です。
・ライブラリのダウンロードURLはこちらから・・・(https://github.com/mathertel/Radio)
【配線図】
【youtube ESP32でFMラジオを聞いてみる】
【使用材料】
・ESP32-Dev-MOdule (アマゾン)
・PDA5807M (秋月電子)
・スピーカー(アンプ内蔵) (ダイソー)
・アンテナ (アマゾン)
・SSD1306 OLED Display (アマゾン)
・タクトボタン (秋月電子)
・ステレオミニジャック (秋月電子)
・ボリューム抵抗 (秋月電子)
・ブレットボード
・配線ケーブル
上の動画で紹介した各モジュールの配線図を基に木箱でラジオを作成してみました。
【FMラジオを聞いてみる第2弾】
【使用材料】
・ESP32-Module (アマゾン)
・PDA5807M (秋月電子)
・スピーカー (アマゾン)
・アンプ (アマゾン)
・アンテナ (アマゾン)
・SSD1306 OLED Display (アマゾン)
・タクトボタン (アマゾン)
・LED付電源ボタン (アマゾン)
・ボリューム抵抗 (秋月電子)
・ブレットボード
・配線ケーブル
【プログラム】
/****************************************
* 概要:RDA5807MとSSD1306DisplayはI2C接続、ESP32側のSDA-D21,SCL-D22 PINに接続
* プッシュボタンで自動選局
* ボリューム抵抗で音量調整
* RDA5807Mのライブラリ: https://github.com/mathertel/Radio
* 使用機材
* ・ESP32-WROOM-32E
* ・RDA5807M : FMラジオモジュール
* ・SSD1306 : OLED 0.91 128×32
* ・ボリューム抵抗 : 10KΩ
*****************************************/
#include <Arduino.h>
#include <Wire.h>
#include <radio.h>
#include <RDA5807M.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//------- display用 ---------
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ----- RDA5807の設定用 -----
#define FIX_BAND RADIO_BAND_FMWORLD //海外の場合RADIO_BAND_FM
#define FAST_STATION 8190 //最初に起動したときの周波数
#define VOL_MAX 15 //Volune MAX
#define VOL_MIN 0 //Volune MAX
#define FREQ_UP 13 //AutoScan用周波数UPへ
#define FREQ_DOWN 12 //AutoScan用周波数DOWNへ
float FREQ = 0; //FMのチャンネルを格納する変数
int VOLUME = 5; //Voluneの調整(値:0~15 初期値:5)
int REV_VOLUME=0; //一回前のVOLをセット
RDA5807M radio; //オブジェクトを生成
//音量
#define VOL_READ 33 //ボリューム抵抗の読み取りPIN
typedef struct {
float fmfreq;
char* stationname;
} Station_data;
const Station_data myArea[] {
{7650, "IntrerFM"},
{7860, "FM-FUJI"},
{7950, "NACK5"},
{8000, "FM-TOKYO"},
{8130, "J-WAVE"},
{8190, "NHK-FM"},
{8280, "KAMAKURA FM"},
{8440, "FM-YOKOHAMA"},
{8470, "FM-YOKOHAMA"},
};
int numElements = sizeof(myArea) / sizeof(myArea[0]); //配列が何個設定されているか(放送局数)
void setup() {
Serial.begin(115200);
delay(200);
pinMode(VOL_READ, ANALOG); // PINMODEをアナログ入力(今回はD33を設定)
pinMode(FREQ_UP, INPUT_PULLUP); // UPpushボタン用PIN
pinMode(FREQ_DOWN, INPUT_PULLUP); // DOWNpushボタン用PIN
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
// デバッグ用
radio.debugEnable(false);
radio._wireDebug(false);
if (!radio.initWire(Wire)) { //ESP32のwire初期化
Serial.println("no radio chip found.");
delay(4000);
ESP.restart();
}
//PDA5807Mの初期設定
radio.setBandFrequency(FIX_BAND, FAST_STATION); //日本仕様にセット(最初の周波数:FAST_STATION)
radio.setVolume(VOLUME); //ボリュームをセット
radio.setMono(false); //モノラルの設定(false:解除)
radio.setMute(false); //ミュートの設定(false:解除)
display.clearDisplay(); //ディスプレイ画面クリア
FREQ = FAST_STATION; //初期周波数をFREGにセット
freq_disp(FREQ); //DISPLAYに周波数を表示
}
void loop() {
int val=analogRead(VOL_READ); // アナログ入力値(0〜4095)を取得
VOLUME = map(val,0,4095,VOL_MIN,VOL_MAX); //アナログリードでは、0~4095までの値が取得可能なためmap関数でその値を0~15の値に変換する
if(VOLUME != REV_VOLUME){
radio.setVolume(VOLUME); //ボリュームをセット
REV_VOLUME=VOLUME;
}
if(digitalRead(FREQ_DOWN) == LOW){
radio.seekDown(true); //周波数をDOWN
delay(500);
Serial.print("DOWN:");
FREQ = radio.getFrequency();
Serial.println(FREQ);
freq_disp(FREQ); //DISPLAYに周波数を表示
}
if(digitalRead(FREQ_UP) == LOW){
radio.seekUp(true); //周波数をUP
delay(500);
Serial.print("UP:");
FREQ = radio.getFrequency();
Serial.println(FREQ);
freq_disp(FREQ); //DISPLAYに周波数を表示
}
delay(200);
radio.checkRDS(); //RDSのチェック
}
/************************************************
* freq_disp(float num_data)
* 概要:SSD1306に周波数を表示
* 引数:num_data 周波数データ
**********************************/
void freq_disp(float num_data){
String Station_name;
for(int i=0;i<numElements;i++){ //登録されているデータから放送局を取得
if (num_data == myArea[i].fmfreq){ //登録した周波数と一致した場合
Station_name = myArea[i].stationname; //ステーション名を取得
}
}
display.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_BLACK);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.print("STATION : ");
display.println(Station_name); //放送局名を表示
display.setTextSize(3);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,10);
display.println(num_data/100); //周波数を表示
display.setTextSize(2);
display.setCursor(92,15);
display.println(F("MHz"));
display.display(); //ディスプレイを表示させる処理(これを入れないと表示しない)
}