LoginSignup
0

More than 3 years have passed since last update.

RDA5807M Arduinoで制御 SEEK機能編 DSP FMラジオ

Posted at

はじめに

  • RDA5807では、特定周波数の受信には成功したので、SEEK機能に挑戦。
  • モジュールは、Aliexpressにて調達してみた。1枚40円。送料込みで4枚で250円。安すぎ。
  • SEEK機能での選局だが、単純な形であればそれほど難しくなかった。

使用したもの

  • RDA5807Mモジュール (Aliexpress)。
  • IC(RDA5807M)のデータシート
  • AN230(Silicon Labs)
  • Arduino Uno互換機(ELEGOO)

モジュールについて

  • Aliexpressで入手したモジュールだが、Aitendoさんで「取り扱い終了版」となっているものと同じように見える。また、AMAZONで売っているものとも同じ外見。
  • ピン配置は、AITENDOさんの「RDA5807-M」と同じ(「RDA5807-M2」とは異なる)。 RDA5807M_Ali.jpg

配線

Slaveアドレスについて

  • ここでは 0X11(個別レジスタ書込/読込用)を使います。普通のコードで読み書きできます。

コード作成のポイント

  • RDA5807はSi4702の上位互換のようなICなので、Si4702のProgramming Guide(AN230)が参考になる。SEEKの場合、Table 14を参照すればよい。具体的には以下を設定する。
    • SKMODE:SEEKを周波数帯の端で止めるか、1周して続けるか(Wrap)。→ Wrap
    • SEEKUP:SEEK方向を上にするか、下にするか。→ 上にする。
    • SEEK bit:SEEKを開始するときに1にする。
    • その他の設定はそのまま。BAND、SPACEを特定周波数を受信するときと同様に設定する。
  • SEEK機能はこれだけでOK。これで何かしら放送を受信するはず。ただし、ICから情報を読み取らないと、何を受信しているかがわからない。

情報の読み取り

  • 必要な情報はレジスタ0Ahと0Bhに格納されるので、これらのレジスタを読みだす必要がある。ここでは、シリアルモニタに表示することにするが、LCDに表示するのも容易。
    • 受信している周波数(CHAN): 0Ah.[9:0]
    • 受信完了フラグ(STC): 0Ah.[14]
    • SEEK失敗フラグ(SEEKFAIL): 0Ah.[13]
    • 受信強度(RSSI): 0Bh.[15:9]
    • 局かどうか(STATION): 0Bh.[8]
  • これらをレジスタから読み込んで、適当に表示をすればよい。

プログラムの構造

  • 上記の情報は、選局(SEEK)が完了(STC==1)してから読み出すべきだが、選局は直ぐ終わる場合も、時間がかかる場合もあり、情報を読み出すタイミングがわからない。早く読み出しすぎると、受信が完了していない時点の周波数を読んでしまう。
  • なので、一定時間ごと(0.5秒)に0Ahを読み込み、STCフラグが1になればそこで、読み取りを終わらせることにした。
  • なお、本ICのファミリーである5807FPには、STC==1になるとパルスを出すGPIOピンがあり、このピンで割り込みをかけることもできるようになっている。
  • コードはloop()は使わず、setup()の中で処理しています。
  • プログラムは、1回選局するとそこで終わりになります。プログラムを続けて走らせると、前回に選局した局からSEEKを開始します。

選局基準(SEEKTH)

  • レジスタ05h.[11:8]に選局の基準となるSEEKTHが定められている。大きすぎると、弱小局を拾わないような気がしたので、少し小さくしています(詳細はよくわかりません)。

動作コード

  • 76 → 108MHzの間でSEEKし、最初に見つけた局の周波数などをシリアルモニタに表示し、そこで終了する簡単なコードです。
  • 選局終了後、もう一度走らせると、前回選局した周波数からまた、SEEKを開始します。上限まで行って見つからないと、下限からSEEKを続けます。詳細はコードとデータシート見てください。
#include <Wire.h>

int buffer1;
int buffer2;
int buffer3;
int buffer4;

void setup()
{
delay(200);
Wire.begin();

Wire.beginTransmission(0X11);
   Wire.write(0X03);
   Wire.write(0b00000000); //  CHAN NA 
   Wire.write(0b00001000); // TUNE0, BAND10, SPACE00
Wire.endTransmission();

Wire.beginTransmission(0X11);
   Wire.write(0X05);
   Wire.write(0x84); //SeekTh 0100  
   Wire.write(0x8F); //VOL1111
Wire.endTransmission();

Wire.beginTransmission(0X11);
   Wire.write(0X02);
   Wire.write(0xc3); //seek up, seek on  
   Wire.write(0x05); //seekmode0(wrap)
Wire.endTransmission();

delay(100);

boolean stc=0;

while (stc==0)
{
Wire.begin();
  Wire.beginTransmission(0X11);
  Wire.write(0X0a);
  Wire.endTransmission(false);
  Wire.requestFrom(0x11,4); //reading 5807
  Wire.endTransmission(true);

  buffer1= Wire.read(); //0AH
  buffer2= Wire.read(); //0AL
  buffer3= Wire.read(); //0BH
  buffer4= Wire.read(); //0BL

int freq= 760 + 512*bitRead(buffer1,1)+ 256*bitRead(buffer1,0)+ buffer2;
stc=bitRead(buffer1,6);
boolean seekfail=bitRead(buffer1,5);
byte rssi = buffer3>>1;
boolean station = bitRead(buffer3,0);

Serial.begin(9600);   
   Serial.print("STC:");
   Serial.print(stc);
   Serial.print("  SeekFail:");
   Serial.println(seekfail);
   Serial.print("Freq*10:");
   Serial.print(freq,DEC);
   Serial.print("  RSSI:");
   Serial.print(rssi,DEC);
   Serial.print("  Station:");
   Serial.println(station);

delay(500);
}
}

void loop() {
  // put your main code here, to run repeatedly:
}

おまけ

  • 天井から垂らした電線をアンテナにしていますが、当方の環境(東京)では、主要な局はちゃんと選局できています。どこの局かわからない周波数を選局するときもありますが…
  • 割込みによるプログラムも試してみたかったので、RDA5807FPも使ってみました。5807FPについては、乾電池駆動の箱ラジオを作成したので、後日公開予定です。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0