#はじめに
- 電子工作の初心者としてDSPラジオに挑戦。
- 作例も多いRDA5807シリーズだが、複数のSlaveアドレスがあるなど、難しいところもあった。備忘録もかねて記録を残すもの。ほかのDSPラジオモジュールも解説予定。
#使用したもの
- Aitendoさんのモジュール。RDA5807-M2(http://www.aitendo.com/product/13265)
- IC(RDA5807M)のデータシート
- Arduino Uno互換機(ELEGOO)
#モジュールについて
- Aitendoさんには2種類のモジュールあり。「RDA5807-M2」と「RDA5807-M」。ここではM2を利用したが、Mについても後日更新予定(ほとんど違いがない)。
- モジュールのDIP変換については、先例がいくつかあり。私も手作業でやってみたが、Aitendoさんの専用基盤が扱いやすいと思う。
#配線
#Slaveアドレスについて
- ここが一番わからなかった。結論から書くと以下の通り。
- 0x10 レジスタ連続書込/読込用
- 0X11 個別レジスタ書込/読込用
- 0X60 TEA5767互換モード(ここでは取り扱わず)
- ArduinoのI2C Scanner を使うと、上記の3つのSlaveアドレスが表示される。複数のアドレスが同時に使えるモジュールは珍しいと思う(最後の考察ご参照)。これはArduino用のアドレスなので、他マイコンで利用する場合は適宜変換が必要。
- 0x10 レジスタ連続書込/読込用
- このアドレスを用いると、自動的に以下のレジスタから連続して書き込まれる。個別のレジスタを指定する必要がない。書込:02Hから 読込:0AHから。
- 書込コード例。このコードで02Hと03Hにすべて0が書き込まれる。読込コード例は割愛(ほとんど使わないと思うので)。
Wire.beginTransmission(0X10); //continuous write
//no need to specify register
Wire.write(0X00); // 02h(HighByte02)
Wire.write(0X00); // 02l(LowByte02)
Wire.write(0X00); // 03h
Wire.write(0X00); // 03l
Wire.endTransmission();
- 0x11 個別レジスタ書込/読込用
- このアドレスを用いると、個別のレジスタに書き込むことになる。いわゆる普通のI2Cデバイスを利用するのと同じ。0X10より使いやすいので、0X11だけで十分な気もします。
- 一応書込コード例。レジスタ05Hにデータを書き込めます。読込は割愛。普通のコードで読めます。
Wire.beginTransmission(0X11); //normal i2c
Wire.write(0X05); // specify register 05h
Wire.write(0X88); // 05h
Wire.write(0b10001000); // 05l VOLUMExxxx
Wire.endTransmission();
#コード作成のポイント
- TUNEビット 0→1。ここも解りにくかった。特定周波数をレジスタに書き込む場合、以下の手順を踏む必要がある。
- まず、TUNEビット(03h.4)をゼロにする。
- 次に、特定周波数とともに、TUNEビットを1としてレジスタに書き込む。
- DMUTEビット1(02h.14)。ENABLEビット1(02h.0)。モジュールを起動させるために、この2つのビットを設定する必要がある。
#動作コード
- 特定の周波数を書き込むシンプルなコード。上記のポイントも考慮してざっくり以下の形。詳細はコードとデータシート見てください。
- レジスタ02hと03hに0を書き込む。TUNE、DMUTE、ENABLEがゼロになる。
- 希望する周波数(ここでは80MHz)からCHANビット列を算出。
- このCHANビット列とともに、TUNE、DMUTE、ENABLEを1としてレジスタ(02h、03h)に書き込む。
- 続けて、04hと05hにVolumeなど書き込む。ここまではアドレス0x10を用いて連続書き込み。
- 0x11の練習として、05hのVolumeを個別に書き込み。
#include <Wire.h>
//For Arduino Uno
/*
Simple code for RDA5807M. Sepcify frequency.
For Japanese FM station.
*/
/*
Slave address: let's use I2C scanner.
You will find three slave addresses.
0x10: automatic continuous read/write
read: from 0AH write: from 02H
0x11: specify register (normal i2c)
0x60: tea5767 mode
*/
void setup()
{
delay(100);
Wire.begin();
//reset 02H and 03H
//TUNE set to 0
Wire.beginTransmission(0X10); //continuous write
//no need to specify register
Wire.write(0X00); // 02h(HighByte02) DMUTE0
Wire.write(0X00); // 02l(LowByte02)
Wire.write(0X00); // 03h
Wire.write(0X00); // 03l TUNE0 ENABLE0
Wire.endTransmission();
//write data from 02H to 05H.
// FREQ -> CHAN -> 03
float freq = 80 ;///Frequency! 80 82.5 93 78.2
int chan = freq*10 - 760;
byte h3 = chan >>2; //Highbyte03
byte l3 = chan & 0b00000011;
l3 = l3<<6;
l3 = l3 | 0b00011000; //Lowbyte03 TUNE1 BAND10 SPACE00
Wire.beginTransmission(0X10); //continuous write
Wire.write(0xc2); //02h DMUTE1 SEEK0 水晶利用
Wire.write(0x85); //02l ENABLE1 CLK000(32768hz)
Wire.write(h3); //03h freq
Wire.write(l3); //03l freq TUNE0->1 BAND10
Wire.write(0b00001010); //04h DE50
Wire.write(0x00); //04l
Wire.write(0x88); //05h
Wire.write(0x81); //05l VOLUME0001
Wire.endTransmission();
delay(100);
//0x11: specify 05H. VOL0001->1000
Wire.beginTransmission(0X11); //normal i2c
Wire.write(0X05); // specify register 05h
Wire.write(0X88); // 05h
Wire.write(0b10001000); // 05l VOLUMExxxx
Wire.endTransmission();
}
void loop() {
// put your main code here, to run repeatedly:
}
#考察
- コード作成には、SILICON LABSのAN230が役に立った。
- ここ (https://www.rockbox.org/wiki/FmTunerHardware) によると、RDA58XXシリーズはどうもSilicon LabsのSi47XXと似た作りになっている模様。このSi47XXシリーズ(後日公開予定)だが、発表が古いせいか、連続書込み方式しかサポートしておらず、コード作成が面倒くさい。
- RDA5807はおそらく、この連続書込み方式を引き継ぐとともに、利便性のために個別書込み方式もサポートしたと思われる。これが複数のアドレスを持っている理由と推定しています。
#おまけ
- 本件が上手く動いたため、ラジオモジュールにはまってしまい、以下のモジュール、ICにも手を出してしまいました。順不同でゆっくり公開予定。
- BK1088(癖があって難しい)、AR1019、SP3777、Si4730、Si4702、M6955、RDA5807(SEEK)、KT0915、QN8065/QN8035、TEA5767、RDA5807FP、RTC6218