前回はFMラジオの選局をSeek up Seek down方式で作りましたが、今回はタクトスイッチでFMの周波数を直接指定する方法で作ってみました。こちらの方式のほうが安定して実用になるのではないかと思われます。
概要
構成
- アルディーノ nano
- RDA5807
- SSD1306
- ブレッドボード
回路図
回路図は前回の記事とほぼ同じですが、今回はボリュームのレベルも変えるタクトスイッチをつけてみました。
- D2スイッチで周波数を設定 SSD1306 に周波数とステーション名を表示する
- D3スイッチでボリュームアップ SSD1306にボリュームのレベルを表示する最大8です
- D4スイッチでボリュームダウンです SSD1306ボリュームのレベルを表示する最小1です
プログラム
こちらが今回作ったプログラムで、SSD1306用ライブラリーの使いかたに関しては私のブログこちらOLELディスプレイSSD1306使い方で確認してください。
#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); //ディスプレイ制御用のインスタンスを作成。
// japanese FM station.
byte Fh;
byte Fl;
byte vm;
int vol;
int freg_set;
int ch_set;
float freq;
float fm_chan[6] = { 800, 813, 825, 905, 916, 930 };
String ch_name[6] = { "TOKYO FM", "J-WAVE", "NHK.FM", "TBS_RADIO", "BUNKA", "NIPON" };
void setup() {
Wire.begin();
vol = 2; //デフォルト値
freg_set = 0;
//Serial.begin(9600);
ch_set = 1; // デフォルト値
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(4, INPUT_PULLUP);
vm = vol | 0b10000000;
set_freq1(ch_set);
Wire.beginTransmission(0X10);
Wire.write(0xc2); //02h DMUTE1 水晶利用
Wire.write(0x85); //02l ENABLE1 CLK000(32768hz)
Wire.write(Fh); //03h freq
Wire.write(Fl); //03l freq TUNE0->1 BAND10
Wire.write(0b00001010); //04h DE50
Wire.write(0x00); //04l
Wire.write(0x88); //05h
Wire.write(vm); //VOLUMESET
Wire.endTransmission();
display.begin(SSD1306_SWITCHCAPVCC, i2c_ADDRESS); //ディスプレイを初期化。
display.clearDisplay(); //画面描写をクリアー
delay(200);
display.clearDisplay();
display.setTextColor(WHITE, BLACK); //文字を白、背景黒
display.setTextSize(2); //文字サイズ
display.setCursor(0, 0); //表示位置
display.print("FM RADIO");
display.setCursor(0, 20);
display.print(fm_chan[ch_set] / 10);
display.setCursor(64, 20);
display.print("M");
display.setCursor(96, 20);
display.print(vol);
display.setCursor(0, 40);
display.print(ch_name[ch_set]);
display.display();
delay(50);
}
int set_freq1(int x) {
freq = fm_chan[x];
freq = freq / 10;
int chan = freq * 10 - 760;
Fh = chan >> 2;
Fl = chan & 0b00000011;
Fl = Fl << 6;
Fl = Fl | 0b00011000;
if (freg_set != 0) {
Wire.beginTransmission(0X11);
Wire.write(0X03);
Wire.write(Fh);
Wire.write(Fl);
Wire.endTransmission();
} else {
freg_set = 1;
}
}
int set_volum(int y) {
vol = y;
vm = vol | 0b10000000;
Wire.beginTransmission(0X11);
Wire.write(0X05);
Wire.write(0x88);
Wire.write(vm);
Wire.endTransmission();
}
void loop() {
if (digitalRead(2) == 0) {
if (ch_set >= 5) {
ch_set = 0;
} else {
ch_set += 1;
}
set_freq1(ch_set);
display.clearDisplay();
display.setCursor(0, 0); //表示位置
display.print("FM RADIO");
display.setCursor(0, 20);
display.print(fm_chan[ch_set] / 10);
display.setCursor(64, 20);
display.print("M");
display.setCursor(96, 20);
display.print(vol);
display.setCursor(0, 40);
display.print(ch_name[ch_set]);
display.display();
delay(400);
}
if (digitalRead(3) == 0) {
if (vol >= 8) {
vol = 8;
} else {
vol += 1;
}
set_volum(vol);
display.setCursor(96, 20);
display.print(vol);
display.display();
delay(400);
}
if (digitalRead(4) == 0) {
if (vol <= 1) {
vol = 1;
} else {
vol -= 1;
}
set_volum(vol);
display.setCursor(96, 20);
display.print(vol);
display.display();
delay(400);
}
}
プログラムの説明をします。
電源が投入された時点でチャンネルは2番目ボリュームのレベルも2となります。
私は首都圏に住んでいますので、エフエムチャンネルは下記の設定にしましたが、自分の地域に合わせて設定を変えてください。
float fm_chan[6] = { 800, 813, 825, 905, 916, 930 }; // 自分の地域
String ch_name[6] = { "TOKYO FM", "J-WAVE", "NHK.FM", "TBS_RADIO", "BUNKA", "NIPON" }; //自分の地域
連続でデータを書き込めるアドレス(0x10)を使用して初期設定をします。
Wire.beginTransmission(0X10);
Wire.write(0xc2); //02h DMUTE1 水晶利用
Wire.write(0x85); //02l ENABLE1 CLK000(32768hz)
Wire.write(Fh); //03h freq
Wire.write(Fl); //03l freq TUNE0->1 BAND10
Wire.write(0b00001010); //04h DE50
Wire.write(0x00); //04l
Wire.write(0x88); //05h
Wire.write(vm); //VOLUMESET
Wire.endTransmission();
周波数を設定する関数は、電源投入後の最初の呼び出しの時は設定せずスキップします。
int set_freq1(int x) {
freq = fm_chan[x];
freq = freq / 10;
int chan = freq * 10 - 760;
Fh = chan >> 2;
Fl = chan & 0b00000011;
Fl = Fl << 6;
Fl = Fl | 0b00011000;
if (freg_set != 0) {
Wire.beginTransmission(0X11);
Wire.write(0X03);
Wire.write(Fh);
Wire.write(Fl);
Wire.endTransmission();
} else {
freg_set = 1;
}
ボリュームを設定する関数です。
int set_volum(int y) {
vol = y;
vm = vol | 0b10000000;
Wire.beginTransmission(0X11);
Wire.write(0X05);
Wire.write(0x88);
Wire.write(vm);
Wire.endTransmission();
}
感想
動画です
予想どうり今回作成した固定周波数方式は安定して動作し、またSSD 1306に情報を表示することで実用的なFMラジオが完成した気がします。
興味ある方はぜひ作ってみてください。