0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DSP FMラジオ RDA5807FP+ATTINY85+AQM0802A その7 動作コード

Posted at

はじめに

  • 電池駆動DSPラジオのその7。動作スケッチについての解説です。
  • スケッチは4666バイト。ATTINY85でも若干余裕がありました。本記事の一番下に載せてあります。
  • なるべく自前でスケッチを書きましたが、AQM0802Aへの出力につきましてはライブラリを利用させていただきました。
  • 前記事(その1~その6)や過去記事も適宜ご参照ください。

ATTINY85への書き込みについて

  • マイコンにATMEGA328を使うのであれば、ARDUINO UNOをそのまま使って、書き込み後にUNOから外せばよいですが、ATTINY85を利用する場合、書き込みを方法を用意しなければなりません。
  • この点については、先達の記事が多数ありますので、ここでは触れません。本件ではATTINY85を3.3Vで利用しますので、書き込む際も3.3Vで書き込んだほうが良さそうです。
  • 私は、一般的な方法である、UNOを書き込み器として利用する方法を用いました。書込み用のスケッチ(ArduinoISP)をUNOで読込 → ATTINY85を適宜接続 → 設定をATTINY85にして本件スケッチを書き込み。
  • このページを参考にさせてもらいました。電圧は3.3Vに変更しました。

部品の構成

  • スケッチを作成するにあたって、以下の部品構成を前提にしています。
    1. RDA5807FPのGPIO2から、STCトリガを出力させる。
    2. 上記の出力トリガをATTINY85のPin3(PB4)で受け、PCINT4割込みを発生させる。
    3. SEEK開始のタクトスイッチ → ATTINY85のPing2(PB3)
    4. +0.1MHZタクトスイッチ → ATTINY85のPing6(PB1)
    5. 音声出力はモノラル(スピーカー一つ)
    6. AQM0802Aはライブラリ使用
    7. ボリュームは可変抵抗器使用。スケッチではボリューム固定。

スケッチの構成

  • 以下のような構成にしています。
    • ライブラリの宣言: Wire、I2CLiquidCrystal
    • VOLATILE変数の宣言
      • 以下SETUP()
    • LCD初期化
    • PB4、PB3、PB1のINPUT_PULLUP
    • RDA5807の条件設定、GPIO2の設定
    • PCINT4を利用するための設定
    • SEEK機能開始
      • 以下LOOP()
    • STCフラグの監視 → データ表示
    • SEEK開始ピンの監視 → SEEK開始
    • +0.1MHZピンの監視 → +0.1MHZ周波数セット
      • 以下サブルーチン(関数)
    • 割込みで飛ぶ関数: STCフラグの変更
    • SEEK開始関数: RDA5807FPのレジスタに書き込み
    • +0.1MHZ周波数セット関数: 現在の周波数+0.1MHZをレジスタに書き込み
    • データ表示関数: 周波数、RSSIをレジスタから呼び込み、LCDに表示

スケッチ詳細

  • I2CLiquidCrystal
    • このページのライブラリを利用させていただきました。利用方法については同ページをご参照ください。「ST7032iタイプ」を参照しています。外部プルアップ抵抗は用いず、ATTINY85の内部プルアップ抵抗を利用しています。
  • volatile変数
    • 割込み関数で利用する変数(stc)を宣言しています。freq10の方はvolatileでなくてもよいかも。
  • lcd.begin(8,2)
    • 上記のライブラリに従っています。
  • pinMode
    • 本件で使うピンを宣言して、内部プルアップ抵抗を利用します。何も起きていないときはこれらのピンはHighになります。
  • レジスタ03,05,04への書き込み
    • 種々の条件を設定。過去記事、RDA5807FPのデータシートなどご参照ください。
  • GIMASK, PCMSK
    • PCINT4を利用するための設定です。
  • レジスタ02への書き込み
    • seek bitを1にして書き込み → SEEK開始
  • if(stc==1)
    • stcフラグが1になったらデータ表示関数(infodisplay())を実行。
  • if(digitalRead(3)==0)
    • PB3(SEEK開始ボタン)が0になったら、”Sup”を表示して、SEEK開始関数(seekset02H())を実行
  • if(digitalRead(1)==0)
    • PB1(+0.1MHZボタン)が0になったら、”+01”を表示して、+0.1MHZ周波数セット関数(setfreq())を実行
  • ISR(PCINT0_vect)
    • PB4でPCINTが発生(選局完了)した場合に処理される関数。ここでstcが1となり、loop文の中でデータ表示関数が実行されます。
    • 1回目のPCINT(High → Low)の時だけstcを1とするようにしています。
  • void seekset02H()
    • SEEK開始関数。レジスタ02に書き込みことによって、seekを開始(再開)します。RDA5807FPの仕様では現在の周波数からseekを再開することになっています。
  • void setfreq()
    • +0.1MHZ周波数セット関数。「現在の周波数+0.1MHZ」を計算し、レジスタ03に書き込むことによって、その周波数を選局します。Tuneビットを1にする必要あり。
  • void infodisplay()
    • データ表示関数。レジスタ0Aと0Bから情報を読み込み、適当に変換してLCDに表示しています。
    • 選局している周波数とRSSIを表示。他にも読み取れる情報はありますが、この2つだけにしています。

動作スケッチ

// ATTINY85,AQM0802,Mono,Seek,+0.1MHZ

# include <Wire.h>
# include <I2CLiquidCrystal.h>
// initialize the library
I2CLiquidCrystal lcd(32, (bool)false);
//  contrast (0-63)
//  set true if the power suply is 5V, false if it is 3.3V

volatile bool stc=0;
volatile int freq10=0;

void setup()
{
lcd.begin(8,2);

pinMode(4,INPUT_PULLUP);//STC PCInterupt
pinMode(3,INPUT_PULLUP);//Tact Switch seekup
pinMode(1,INPUT_PULLUP);//Tact Switch +100khz

Wire.begin();
  delay(20);
  Wire.beginTransmission(0X11);
   Wire.write(0X03);
   Wire.write(0x00); //CHAN0  
   Wire.write(0b00001000); //TUNE0 BAND10 SPACE00
  Wire.endTransmission();
  Wire.beginTransmission(0X11);
   Wire.write(0X05);
   Wire.write(0b00000100); //INT_MODE1 SeekTh 0100  
   Wire.write(0b10001111); // vol1111
  Wire.endTransmission();
  Wire.beginTransmission(0X11);
   Wire.write(0X04);
   Wire.write(0b01001010); //STCINT1,DE50 
   Wire.write(0b00000100); //GPIO2:01 
  Wire.endTransmission();

GIMSK = B00100000; //PCINT ENABLE
PCMSK = B00010000; //PCINT4 ONLY
  Wire.beginTransmission(0X11);
   Wire.write(0X02);
   Wire.write(0b11100011); //mono seek up, seek on  
   Wire.write(0x05); //seekmode0(wrap)
  Wire.endTransmission();
}

void loop() {
  if(stc==1){
  infodisplay();
  stc=0;  
  }
  delay(10);
  
  if(digitalRead(3)==0){
      lcd.setCursor(0, 0);
      lcd.print("Sup");
    seekset02H();
    delay(50);
  }
  if(digitalRead(1)==0){
      lcd.setCursor(0, 0);
      lcd.print("+01");
    setfreq();
    delay(50);
   }
  delay(100);
}

ISR(PCINT0_vect){
 if(digitalRead(4)==0)
      stc=1;
}

void seekset02H(){
  Wire.beginTransmission(0X11);
   Wire.write(0X02);
   Wire.write(0b11000011); //seek up, seek on  
   Wire.write(0b00000101); //seekmode0(wrap)
  Wire.endTransmission();
}

void setfreq(){
int chan = freq10 - 760+1; //周波数+0.1MH
byte h3 = chan >>2; //Highbyte03
byte l3 = chan & 0b00000011;
l3 = l3<<6;
l3 = l3 | 0b00011000; //Lowbyte03 TUNE1 BAND10 SPACE00
  Wire.beginTransmission(0X11);
   Wire.write(0X03);
   Wire.write(h3); //03h freq  
   Wire.write(l3); //03l Tune1
  Wire.endTransmission();
}

void infodisplay(){
//Serial.begin(9600);
  delay(50);   //RSSIが安定するまでdelay
  Wire.begin();
  Wire.beginTransmission(0X11);
  Wire.write(0X0a);
  Wire.endTransmission(false);
  Wire.requestFrom(0x11,4); //reading 5807
  byte bufferAH= Wire.read();
  byte bufferAL= Wire.read();
  byte bufferBH= Wire.read();

freq10= 760 + 512*bitRead(bufferAH,1)+ 256*bitRead(bufferAH,0)+ bufferAL;
unsigned char freq = freq10/10 ;
byte rssi = bufferBH>>1;
    lcd.clear(); 
    lcd.setCursor(0, 0);
    lcd.print("STC");
    lcd.print(freq); 
    lcd.print("."); 
    lcd.print(freq10 - 10*freq); 
    lcd.setCursor(0, 1);
    lcd.print("RSSI:");
    lcd.print(rssi);
}

おまけ

  • 昔はラジオ工作と言えばAMラジオのことで、FMラジオを自作するのは難しかったと思います。しかし、DSPラジオチップは、マイコンと組み合わせれば、取り扱いも簡単かつ安価で、むしろFMラジオの方が作りやすいと感じました。
  • 今はAM放送もFMバンドで放送していますし、民放ラジオ局はFM放送にシフトする意向、というのも聞いたことがあります。なのでFMラジオで十分、とは言えると思います。
  • とは言え、今はradikoもありますから、今回作成したラジオも実用性があるかと言えば疑問です。乾電池だけで動くので災害時には使えるかもしれませんが…
  • ATMEGA328を使えば、もっと高機能なステレオラジオも作れそうですが、とりあえずDSPラジオCHIPについては一区切りついた感じです。
  • ちゃんとした回路図を作成していなかったので、時間を見つけて作成してみようと思います。
0
0
0

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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?