● 実験テーマ78

「PIC18F_DSP FMラジオの、製作実験記」
(Aitendoの、DSPラジオモジュール
BK1088-102BC-1.5V」を使って、FMラジオを作ってみました。)

※ 160609: メインソースの、BK_FM_Add_LCD.cを更新し置き替えました。
→ これで、ワイドFMの受信が出来るようになりました。
  
6月9日の記事を参照してください。

※ 160617: 液晶に、次に示すステータス表示を追加しました。
   @ 受信レベルを、外字登録したアンテナキャラクタの横に3段階のバー(携帯電話式)で表示
      そして、その上に、当該レジスタ読み値(RSSIビット)の HEX値(00〜7F)を表示
   A Stereo/mono表示
   メインソースの、BK_FM_Add_LCD.cを更新し、「BK_FM_Add_LCD_V1a.c」としました。
  また、外字表示が出来るようにしたので、ライブラリの方も更新し置き換えました。
  
6月10日からの記事を参照してください。

以下、この実験の顛末記です。

■ 2016.5.22
  ・ここんところ、DSPに関連したテーマが続いている。
   今回もその繋がりで、DSPラジオにしてみる。
   実用的なテーマなのでやってもよいかなと思った。

  ・最初のきっかけは、「初めてのPIC」サイトの岩本さんの記事の中に、PIC18F+BK1088による
   このテーマが公開されていたことです。
   このサイトには、次の2つのプロジェクトが公開されています。
    @ BK_Simple: FM放送局1局に絞って簡潔に記述されている。
    A BK_FM: 実用的に使えるプログラム(選局SWによる選局/音量SWによるUP,DWN/
             設定変更時、EEPROMにその値を保存、P_ON時、以前の設定が再現される等)

   このまま作るのでは能が無いので、これにI2C液晶を追加して選局している放送局名と周波数
   を表示出来るようにしました。
   幸い、PIC18Fでの、I2C液晶のライブラリも岩本さんのサイトに公開されて
   いたので、それを使わさせて頂きました。(若干の変更有)

   以下に、オリジナルとの相違点をまとめました。
    @ PICの、MCLRピンを、RA3(選局SW)ポートとして使っているが
       外部リセットピンとして使うように変更。
    A 選局SWは、RA5に変更した。
    B デバッグ用のLEDポート(RC2)を追加
    C 音量調整は、追加したパワーアンプのハードVRにて行うように したので、
       VOL UP/DOWNのSWは削除した。(Line(DAC)出力レベルは固定にした)
    D 受信周波数と、放送局名を、I2C液晶(ストリナ)に表示

   最初の計画では、自作の、PIC18F14K50トレーニングボードを使って、岩本さんの、ソースを
   試そうと思っていたが・・・


■ 2016.5.23
  ・実験用のパーツを手配した。
   主役の、DSPラジオモジュールであるが、このままでは、インチメッシュの基板に実装しにくい。
   この変換基板が、aitendoさんで販売されているので、これ(ラジオモジュール変換基板:IFB-F102BC
   を活用することにした。

  ・ここで気が付いた事あり。
   
PIC18F14K50トレーニングボードは、VCC= 5V、一方、サイトのは、3.3V(PIC・BK1088共)で動かしている。
   aitendoサイトの当該部品のページの概要によれば、動作電源= 2.5〜5.5Vとなっているが?
   よくよくその下の、機能概要の欄を見ると、動作電源= 2.4〜3.6V(推奨3.3V)となっている。
   念の為、BK1088のデータシートを見ると、以下のように明記されていた。

   デジタル・アナログ電圧の上限は、5.5Vであるが、インターフェース電源の上限は、3.6Vである。
   なので、VCC=3.3Vで動かさないといけない。
   今回は、最初から、使える形に組んだ方がよいと思う。
   アンプも含めて、回路図から作成することにした。


■ 2016.5.24
  ・作業の進め方について、今回も、Step分けしていくことにした。
   Step1: BK_Simple(FM放送局1局に絞って簡潔に記述)で基本動作確認
   Step2: BK_FM(LCD抜きの、実用プログラム)で動作確認
   Step3: I2C LCDの単体表示動作確認
   Step4: LCDを加えた実用プログラムの検討〜 動作確認


■ 2016.5.25
  ・Step1: BK_Simple(FM放送局1局に絞って簡潔に記述)で基本動作確認から始めた。
   岩本さんのソフトが、MPLAB X で作成されているので、それに従がってみる。
   MPLAB X で、PIC18Fは初めて。PIC16Fの時、初めて使っている。
   オリジナルから若干の修正はあるが、難しいことはないので説明は省く。
   (何時ものように、ソースを公開しているので、そちらを参照してください。)

   早速、MPLAB X にてプロジェクトを組み、コンパイルを行った。
   エディタで扱える文字を、「Sift JIS」に設定したが、何故か、テラ・パッドで編集したコメントで、
   @ A Bとしたところが、X IDEでソースを開く時に、引っかかった。
   X IDEの、エディタでは、@ A Bのところが、□ □ □ と表示される。
   @ A Bと打ち直せるが、再び、IDEを開くと、その部分が?となってしまうので、
   半角で、(1) (2) (3)に修正でOKになる。(たぶん扱い対象外の文字なのだろう?)
   コンパイルは、1発でOK。


■ 2016.5.26
  ・未だ部品が揃わないので、先に他のステップのプロジェクトも組んで、HEXを用意
   しておくことにする。
   Step2, 3のそれは用意できた。

  ・BK_FMに、I2C液晶を追加するソース案を考える。
   まず、PICのI2Cラインに、スレーブデバイスとしてBK1088と、ストリナの液晶がチェーン接続
   される訳だが、液晶ユニットの方にプルアップ抵抗が接続されているので、PICのI2Cポート
   の内部プルアップは使わない設定にする。
   ちなみにスレーブアドレスは、液晶は、0x7C(書込み時)で、BK1088は、0x80で区別される。
   以下に、ソース案を検討した時のメモを示します。

   ● BK_FMに、I2C液晶を追加するソース案           160526

    @ まずメインに置いてる、PIC側のI2C初期化関数は共通に使うことにする。
       ただ、用意されているI2Cライブラリソースでの、I2C初期化処理には
       液晶の設定も含まれるので、それは削除する。

       //--------- L_i2cLCD.hより
       #define BaudConst 0x09 // BRG Value for 4MHz


       //-------- 初期化:L_i2cLCD.cより
       void LCD_int(void){
       /*
        SSPCON1 = 0x28; //I2Cマスターモード指定
        SSPSTAT = 0x00;
        SSPADD = BaudConst; //Board Rate 
        Delay_100mS;
       */
        LCD_cmd(0x38); // 8bit 2行 表示命令モード
        LCD_cmd(0x39); // 8bit 2行 拡張命令モード
        LCD_cmd(0x14); // OSC BIAS 設定1/5
        // コントラスト設定 
        LCD_cmd(0x70 + (CONTRAST & 0x0F));
        LCD_cmd(0x5C + (CONTRAST >> 4));
        LCD_cmd(0x6B); // Ffollwer
        Delay_100mS;
        Delay_100mS;
        LCD_cmd(0x38); // 表示命令モード 
        LCD_cmd(0x0C); // Display On 
        LCD_cmd(0x01); // Clear Display 
       }


    A メインに置いてる、PIC側のI2C初期化関数は、
       SSPADD = BaudConst; //Board Rate
       としてないで、ダイレクトに、
       SSPADD = 9; // クロックの設定 100k@4MHz
       としているので、ここはせっかくなので
       SSPADD = BaudConst; //Board Rate
       と置換える。

     //********************************************************************
     // SSPを I2C Master mode、SCL 100kHz @ 4MHz に設定 
     //********************************************************************
     void i2cintl(void){
      SSPCON1 = 0b00001000; // I2C Master modeにする
      SSPCON2 = 0x00; // PowerOn初期値にする
      SSPSTAT = 0b10000000; // スルーレート制御はOff
      // SSPADD = 9; // クロックの設定 100k@4MHz
      SSPADD = BaudConst; // クロックの設定 100k@4MHz

      SSPCON1bits.SSPEN = 1; // SSP 有効にする bit5
     }

    B 選局した局の周波数は、あらかじめ局番:st=0〜7に登録された以下の7つの周波数
       となる。
        define presetFreq 7610,7710,7810,8000,8130,8250,8470,0

       これが、周波数配列としてプリセットされてる。つまり以下の通り
       int FM_FREQ[] = {presetFreq}; // 周波数プリセット なので

       ※ 変数:stの値で周波数判断が出来る。

        FM_FREQ[0] = 7610 // インターFM、JODW-FM-------> 10kW ×
        FM_FREQ[1] = 7710 // 放送大学、JODM-FM-------> 10kW  △
//       FM_FREQ[2] = 7810 // 関東エリアではこの周波数なし??
//             FM_FREQ[2] = 7800 // bay-fm-------> 5kW ×
        FM_FREQ[2] = 7950 // NACK5-------> 5kW △
        FM_FREQ[3] = 8000 // TOKYO-FM-------> 10kW ○
        FM_FREQ[4] = 8130 // J-WAVE, JOAU-FM-------> 10kW ○ 
        FM_FREQ[5] = 8250 // NHK-FM, JOAV-FM-------> 10kW ○
        FM_FREQ[6] = 8470 // FM横浜-------> 5kW ×
        FM_FREQ[7] = 0000 // 0を終端として使っている。なので登録曲は、全7局

       これを基に液晶に、曲名と周波数を表示するように考えれば良いはず。

       尚、eepromに書込む局番は、選局の都度なので、p_on後は最後にp_off
       した時の、局が、p_on時、再生されることになる。


■ 2016.5.27〜 2016.5.29
  ・5/27に部品が揃い、5/29に実装が上がった。


■ 2016.5.30
  ・Step1: BK_Simple(FM放送局1局に絞って簡潔に記述)で基本動作確認を行う。
   @ 電源チェックOK
   A PIC認識〜 HEX書込みまでOK
   B SPからは、放送大学がノイズに埋もれながらも聞こえるが、何故か、GNDにクリップを
      接続すると感度が良くなる?
      しかし、周波数設定を、東京FMに書替えても、変わらず。
   C 基本的にPICが動いているかのチェックを、Lチカ(LED点滅)にて確認してみたが、
      Lチカせず。
      どうも、PICがまともに動いてないようだ。

  ・原因は今のところ不明。
   しかし以下の疑問点がある。
   今回初めて、PIC18F14K50を、+5Vでなく、3.3Vで動かしている。
   その時に、ハード・ソフト的に変える点があるかどうか?
   (実績があるのは、+5V動作、MPLAB IDE v8.6、PICkit2での開発
    今回は、+3.3V動作、MPLAB X、PICkit2)


■ 2016.5.31
  ・昨日の疑問点を解くために、いろいろと試してみた。
   PIC18Fトレーニングボード(VCC=+5V)+MPLAB IDE v8.6+PICkit2にて、PICに
   HEXを書込んだのを、そのまま今回製作したBKボード(VCC= +3.3V)に入れ替えて
   Lチカテストを行ったが正常に動いた。
   またBKボード上で、MPLAB IDE v8.6でコンパイルしたHEXを、PICkit2で書込んでも
   正常に動いた。
   つまり、VCCの差異は関係なくハードには問題なさそう。

   試に簡単な、SW ON/OFFに連動した、LED ON/OFFのプロジェクトを、MPLAB Xで
   組んでコンパイル〜動作チェックしたが、OKになる。(BKボード)
   ところが、BK_Simpleプロジェクトで生成したHEXでは動かない。
   もうこれは、動かない方のプロジェクトが何らかの理由で正しく構築されてない可能性が大
   と考えざるを得ない。
   何ということはなかった。
   BK_Simpleプロジェクトを最初から組み直したら、本来のラジオ動作もOKになった。

  ・いくつかの放送局の周波数に置換えて受信状況を確認してみた。
   当方、東京都足立区在住だが、関東を代表する、FM東京:80MHz、J-WAVE:81.3MHz、
   NHK-FM:82.5MHzは、ノイズも少なく良好に受信出来た。
   しかし、放送大学:77.1MHzは、かすかに受信できるがノイズが多いので△
   また、FM横浜:84.7MHzは受信不可で×であった。
   尚、アンテナは、約1mのビニール線を適当に垂れ下げて使っています。

   このラジオモジュール:BK1088のスペックによると、ワイドFM(上限周波数:108MHz)対応
   と書いてあったので、試しに、ワイドFM-TBS:90.5MHzに設定してみたが、残念ながら受信
   出来なかった。


■ 2016.6.1
  ・Step2: BK_FM(LCD抜きの、実用プログラム)で動作確認を行う。
   これもStep1のプロジェクトと同時期に組んだものなので、最初は動かなかった。
   プロジェクトを組み直したら動いた。


   このプログラムの中に、興味を引くものとして、PIC内部のEEPROMに、設定値(受信局番と音量値)を
   書込み、P_ON時、それを読み出して実行というものがあった。
   書込み時の記述は、__EEPROM_DATA(3,28,0,0,0,0,0,0); //0番地:局、1番地:音量(今回音量値は未使用)
   読込時の記述は、st = eeprom_read(0); // 起動時受信局番号 3:FM東京
              vol = eeprom_read(1); // 起動時音量:28
   だけでよい。
   また、MPLAB Xにて、EEPROM内に書込まれたデータを読出して確認する方法も知った。
   以下に、その時の、MPLAB X画面のキャプチャをアップしました。

  ・次に、Step3: PIC18F_I2C_LCD_TEST: I2C LCDの単体表示動作確認を行う。
   これは、岩本さんのサイトに公開されているライブラリとテストプログラムを殆どそのまま
   使わせて頂きまして、問題なく動きました。


■ 2016.6.2
  ・Step4: BK_FM_Add_LCD:LCDを加えた実用プログラムの検討〜 動作確認を行う。
   プログラム案は大方、済んでいたので、今日はその局番変数:stを引数とした、
   受信周波数と、放送局名を液晶に表示する関数を書き上げた。
   コンパイルすると、その新しく追加した関数のところで、未宣言エラーが多数発生。
   どうも、括弧()を全角で打込んでいたようで、打ち直したらエラーは無くなった。(またまたイージーミス)
   動作も問題なく液晶への表示もうまく行った。
   受信状況も特に液晶を追加したことによる影響はなく、主要な放送局の3局(NHK-FM,J-WAVE,TOKYO-FM)
   はノイズも少なく良好に受信出来た。
   最後に稼働時の電源コンディションを書いておく。
   入力:5.22V 約30mA
   VCC= 3.29V
     AVCC= 3.28V


■ 2016.6.3
  ・これで形にはなったが、ワイドFMが聞けないのが残念。
   まあ今回はあきらめて、前後アクリル板の加工から組立てに入ることにした。
   最終的な外観は、このページトップの写真をご覧ください。


---<ここから、追試1:「ソフト更新」の記事>-------------------------------------

■ 2016.6.9
  ・あきらめ切れず、ワイドFMが受信出来ない件を、WEB上の情報と、BK1088のデータシート
   を頼りに調査することにしました。
   WEB検索をしていたら、YAHOO!!プログ「じじいの電子実験室」さんの記事のコメントの
   やりとりの中で、90MHz〜108MH帯が受信出来たとのコメントを見付けた。

   ※ 40個あるレジスタの内、0x21番地(33番地)のレジスタに、0x0600を書込まないと、
      受信出来ないようである。(現ソースは、そのアドレスのレジスタにはアクセスしてない。)

   このレジスタのビットの意味を知りたかったので、BK1088のデータシートを見てみたが、
   0x1E以降のレジスタは、テスト用で設定は不要?というような旨の説明があるだけで
   ビットマップ表なるものはなく、その意味も解らず仕舞いであった。

   ※ 結局、5番地のレジスタ設定値を、0x3740 + volから、0x3640 + volに変更して
      日本エリアの、76〜 91MHz設定を、FULL設定の、64〜108MHzにし、
      さらに0x21番地(33番地)のレジスタに、0x0600を書込んだらワイドFMが受信出来る
      ようになった。
      3局とも、受信状況はノイズも少なく良好です。

      現状のソースからの主な変更は、 次の5点です。
      @ 最低周波数の定義を、6400に変更。
      A プリセット周波数テーブルに、9050,9160,9300を追加。
      B 5番地のレジスタ設定値を、0x3740 + volから、0x3640 + volに変更。
      C 0x21番地(33番地)のレジスタに、0x0600を書込むのを追加。
      D 局名表示関数に、Wide_FM-TBS, 90.5MHz/Wide_FM-Bunka, 91.6MHz/HappyFM93, 93.0MHzを追加。

     
 


---<ここから、追試2:「ソフト更新_V1a:ステータス表示追加」の記事>-------------------------------------

■ 2016.6.10
  ・液晶に、受信レベル等のステータスを表示してみたくなった。
   それには、BK1088の、I2Cでの、レジスタ・リード関数を考えないといけない。
   信号強度に関するレジスタは、10番地の、status2レジスタである。
   16bitあるが、その中の、bit0〜bit6の、RSSI(電界強度)値を、適当な周期で読み取って
   表示すればよいはずである。
   また、bit7には、stereo/mono受信の情報も入っているので、これを読み出して、表示
   してみる。


■ 2016.6.11
  ・レジスタ・リード関数を考えることも必要だが、
   受信レベルをグラフィカルに表示するために、携帯電話式に
   アンテナ・キャラクタの横に、3本のバーが並んだ、あれで表示することとしたいため
   このアンテナキャラクタと、3本のバー(低レベル・中レベル・高レベル)を液晶コントローラ
   に、外字登録することを先に考え、その表示テストを行うことにした。
   尚この時点では、stereo/mono表示はLEDにするつもりだった。

   ところで、今回使用のI2C液晶(SB1602B)には、アンテナ・アイコンが用意されているが、
   その横には、バーアイコンは無い。アイコンでレベル表示出来るのは、バッテリ残量だけ
   なので、アンテナアイコンは使用しないことにした。

  ・外字登録についていろいろと調べてみた。
   @ 「SB1602B」は、仕様的に外字登録・表示可能を確認。
   A CGROMに登録すれば良いのも、他の液晶と同じ。
   B 岩本さんのライブラリには、CGROMにアクセスする関数は含まれない。
      後閑さんのライブラリにも無かった。

   というような事が判った。

  ・手順としては、CGROMに、キャラクタ・パターンを書込んで、そのキャラクタ・コードを指定して
   1文字表示すれば良いはず。
   普通の4ビットバス+制御信号の、キャラクタ液晶「SC1602BS」ではやったことある。
   たぶん手順は同じはず。


■ 2016.6.12
  ・
結局どちらの液晶も、使っているコントローラは、HD44780と互換があることが
   判り、以前から使っている、CGRAMへの書込み関数等を、ほぼそのまま使えたので
   割と簡単に外字表示することが出来た。
   以下に、テスト表示プログラムのよる外字の表示例を示す。


■ 2016.6.13
  ・BK1088 I2C リード関数を考える。
   @ PIC側のI2Cポート(SSP)を、I2Cマスタモードで動かしている。(ハードI2C)
      なので、PIC18FのI2Cライブラリ関数を利用して記述することになる。
   A 岩本さんのBK1088 I2C関数は、書込みしか用意されてない。

  ・まず書込み関数から復習し、BK1088のデータシートを眺めながら読込み関数を考えてみる。
   ※ BK1088の、I2C仕様は特殊
      通常のI2Cと異なる点(BK1088の特異な点のみ示す。)
      @ 書込み
       a. 2byte目のレジスタアドレス送信時の、LSBにライトビット'0'を付加して送信する。
         (1byte目は、デバイスIDのみ送信する。)

      A 読込み
       a. @-a.と同じ。
       b. リスタートの概念が無く、レジスタ・アドレス+リードビット'1'を送信後、バス上に
         スレーブから、リードデータが送られるので、それを、上位バイトリード後、ACK送信、
         下位バイトリード後、NACK送信の順で送って、最後にストップコンディションを送れば
         よさそう。

  ・おおよそ理解できたので、サイトのソース
   (岩本さんeepromリードソース及び、じじいの電子工作さんのBK1088ソース)も参考にして、
   ソースを書き上げた。
    → 大きなミスはなく、何とか動いているようである。


■ 2016.6.14
  ・受信レベルバー表示であるが、現在は暫定的に次のような閾値にしている。
   @ レジスタのRSSI値:0 → バー全消灯
   
A レジスタのRSSI値:1〜42 → 低レベルバーのみ表示
   
B レジスタのRSSI値:43〜64 → 低レベルバー+中レベルバー表示
   
C レジスタのRSSI値:65〜127 → 低レベルバー+中レベルバー+高レベルバー表示

   これで実際に各局を受信してみた。
   ざっとだが、Inter-FM、放送大学は、A/J-WAVE、NHK-FM、NACK5、東京FM、横浜FMは、B/
   90.5MHz以上の、ワイドFMの、3局は、Bであった。
   ただ、アンテナ線を抜いても、リード値は0にはならならず、低レベルバーが表示されるのは不自然。
   閾値については、実際のレジスタ読み値を液晶に表示させることにして、一度、実際のリアルな
   受信レベルを実測してみてから再検討することにした。
   実測の結果、23min(17Hmin:アンテナを外した状態)〜 67max(43Hmax)であった。

   これを基に次のような、閾値に修正した。
   @ レジスタのRSSI値:0〜25(19H) → バー全消灯
   
A レジスタのRSSI値:26(1AH)〜39(27H) → 低レベルバーのみ表示
   
B レジスタのRSSI値:40(28H)〜53(35H) → 低レベルバー+中レベルバー表示
   
C レジスタのRSSI値:54(36H)〜127(7FH) → 低レベルバー+中レベルバー+高レベルバー表示

   この修正で良くなる。
   アンテナ外すと、バー全消灯する。(受信レベルが低い場合に限る。)
   あと、LEDでやっていた、stereo/mono表示も、レジスタ読み値の横に、"s:"/ "m":"と表示させる
   ようにソフトを変更した。

   以下に、全受信局の、レベル表示状況を示しました。
   Inter-FMの右側の写真は、アンテナ線を外した状態です。
   Inter-FMは、ノイズが多く放送内容は殆ど聞き分けられない状態でした。
   放送大学とNACK5は、2本レベルですが、空中線の状況がよいと、何とか聞けました。
   Yokohama-FMは、ノイズが多く放送内容は殆ど聞き分けられない状態でした。
   その他の放送局は、3本レベルでノイズも少なく良好に受信出来ています。

 


<最終回路図>
 ・こちらから、どうぞ→ 「PIC18F_DSP(BK1088)ラジオ」


<最終ソース及び、ヘッダファイル>
 ・こちらから、どうぞ→ @ 「BK_Simple.c」
                   A  「BK_FM.c」

                   B 「BK_FM_Add_LCD.c」 160609更新(第1回目の更新:ワイドFM対応にした。)
                     「BK_FM_Add_LCD_V1a.c」 160614更新(第2回目の更新:ステータス表示を追加した。)

                     「L_i2cLCD.c」 160614更新(CGRAMへのユーザーキャラクタ書込み関数追加に伴い置換えました。)
                     「L_i2cLCD.h」 160614更新(CGRAMへのユーザーキャラクタ書込み関数追加に伴い置換えました。)


← 実験テーマ1に戻る   TOP PAGEに戻る   実験テーマ79へ →