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();                      //ディスプレイを表示させる処理(これを入れないと表示しない)

 

}