ネットを検索していると、RDA5807MでFMラジオが簡単に作れると書いてありましたので、いろいろ調べてFMラジオを作ってみました。今回libraryを使用せずに作りましたが、RDA5807Mの仕様が現在公開されていないようなので苦労しました。
揃えるもの
- RDA5807M aitendo アマゾン 秋月電子
- 変換基盤 aitendo
- アルディーノ nano uno 今回は nano
- 3.5mmステレオミニジャック と DIP化基板セット 秋月電子で購入
- 0.96インチ 128×64ドット有機ELディスプレイ 秋月電子で購入
- ブレッドボード
- タクトスイッチ 2個
回路図
下が回路図ですRDA5807は内部プルアップ抵抗があるようで外部プルアップ抵抗は必要ありません。
また、I2C電圧レベル変換ICも使わなくても正しく動きました。
表示装置AQM1602などはうまく動作しませんでしたので、今回は有機ディスプレイを使用しました。
有機ディスプイSSD1306の使用に関しては私のこちらの記事で確認してください.。
プログラム
RDA5807はI2Cアドレスを3個持つ特殊な機種のようで、今回はその中の(0x11)アドレス、個別レジスター指定を使います。
下記が今回作のプログラムで、RDA5807ライブラリーは使用していません。
#include <Wire.h>
#include <Adafruit_GFX.h> //Adarfuitのライブラリーを読み込む
#include <Adafruit_SSD1306.h> //AdarfuitのSSD1306用ライブラリーを読み込む
const int i2c_ADDRESS = 0x3C; //I2Cのアドレス指定
Adafruit_SSD1306 display(128, 64, &Wire); //ディスプレイ制御用のインスタンスを作成。
float Freg;
float aaa;
void setup() {
Serial.begin(115200);
display.begin(SSD1306_SWITCHCAPVCC, i2c_ADDRESS); //ディスプレイを初期化。
display.clearDisplay(); //画面描写をクリアー
delay(100);
display.clearDisplay();
display.setTextColor(WHITE, BLACK); //文字を白、背景黒
display.setTextSize(2); //文字サイズ
display.setCursor(0, 0); //表示位置
display.print("FM RADIO");
display.display();
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
Wire.begin();
// fm banndo 日本
Wire.beginTransmission(0x11);
Wire.write(0x03);
Wire.write(0x00);
Wire.write(0b00001000);
Wire.endTransmission();
// sennkyuku jidou
Wire.beginTransmission(0x11);
Wire.write(0x02);
Wire.write(0b11000011);
Wire.write(0x05);
Wire.endTransmission();
// set ボりうーム
Wire.beginTransmission(0x11);
Wire.write(0x05);
Wire.write(0b10000100);
Wire.write(0b10000001); // 最小
Wire.endTransmission();
delay(100);
}
void loop() {
if (digitalRead(3) == 0) {
seek_up();
delay(800);
Freg = get_freg();
aaa = Freg / 10;
display.clearDisplay();
display.setCursor(0, 0); //表示位置
display.print("FM RADIO");
display.setCursor(0, 20);
display.print(aaa);
display.display();
delay(300);
}
if (digitalRead(2) == 0) {
seek_down();
delay(800);
Freg = get_freg();
aaa = Freg / 10;
display.clearDisplay();
display.setCursor(0, 0); //表示位置
display.print("FM RADIO");
display.setCursor(0, 20);
display.print(aaa);
display.display();
delay(100);
}
}
void seek_up() {
Wire.beginTransmission(0x11);
Wire.write(0x02);
Wire.write(0b11000011);
Wire.write(0b00000101);
Wire.endTransmission();
}
void seek_down() {
Wire.beginTransmission(0x11);
Wire.write(0x02);
Wire.write(0b11000001);
Wire.write(0b00000101);
Wire.endTransmission();
}
int get_freg() {
Wire.beginTransmission(0x11);
Wire.write(0x0a);
Wire.endTransmission();
Wire.requestFrom(0x11, 2);
while (Wire.available() == 0);
int F = Wire.read();
int F1 = Wire.read();
int freq = 760 + 512 * bitRead(F, 1) + 256 * bitRead(F1, 0) + F1;
return freq;
}
簡単にプログラムを説明します。
まず日本仕様のための周波数設定
// fm banndo 日本
Wire.beginTransmission(0x11);
Wire.write(0x03);
Wire.write(0x00);
Wire.write(0b00001000);
Wire.endTransmission();
自動選局設定
// sennkyuku jidou
Wire.beginTransmission(0x11);
Wire.write(0x02);
Wire.write(0b11000011);
Wire.write(0x05);
Wire.endTransmission();
ボリュームの設定
Wire.beginTransmission(0x11);
Wire.write(0x05);
Wire.write(0b10000100);
Wire.write(0b10000001); // 最小
Wire.endTransmission();
選局アップ
void seek_up() {
Wire.beginTransmission(0x11);
Wire.write(0x02);
Wire.write(0b11000011);
Wire.write(0b00000101);
Wire.endTransmission();
選局ダウン
void seek_down() {
Wire.beginTransmission(0x11);
Wire.write(0x02);
Wire.write(0b11000001);
Wire.write(0b00000101);
Wire.endTransmission();
現在選曲されている周波数を取得(0x0a)から2バイト読みだす
int get_freg() {
Wire.beginTransmission(0x11);
Wire.write(0x0a);
Wire.endTransmission();
Wire.requestFrom(0x11, 2);
while (Wire.available() == 0);
int F = Wire.read();
int F1 = Wire.read();
int freq= 760 + 512*bitRead(F,1)+ 256*bitRead(F1,0)+ F1;
return freq;
}
一応完成はしましたが、選曲が若干不安定なので固定周波数の設定して、タクトスイッチ入力で周波数を選ぶようにした方が良いのかもしれません。