Si4735 ラジオモジュール、液晶の電源を変更してみました。

2012-12-16 15.42.24

I2C 液晶モジュールの電源を I/O ポートから取っていましたが、電源ラインからトランジスタ(2SA1015と2SC1815)のスイッチ回路経由で供給するように変更して動くか確認。とりあえずは問題なし、液晶に供給される電圧も電池の電圧になりますのでコントラストが濃くなりました。

ということで、液晶モジュール、Si4735ラジオモジュール、I2Cプルアップの電源をトランジスタスイッチ経由に配線を変更しました。プログラムは 0.0.2 のまま(液晶コントラストの値は修正必要ですが)変更していません。回路図が加筆修正されています。回路図は下記リンクより

[ダウンロードが見つかりません]

“Si4735 ラジオモジュール、液晶の電源を変更してみました。” への18件の返信

  1. Masahiro様
    更新お疲れ様でした。
    PORTD3で、Power OFFになる事は全然考えてませんでした。
    早速テストした所 Power OFFになり POWER時には
    リセットボタンで復帰出来ました。 それも以前の状態になってますので
    電源関係の問題解決です。ただ主電源を切るとダメなようです。
    回路を見ましたが誤配線は無く解りませんが スタンバイ状態なら
    出来るようです。有難うございました。
    TRでの追加回路も後でテストしてみようと思います。
    次は SW短波切り替えです。ステップが5KなのでMODE切り替えした方が
    よさそうです。単に case SW:
    AMPowerOn();
    setProperty(0x3400, 0x1388);
    setProperty(0x3401, 0x17A7);
    setProperty(0x3402, 0x0005); 9kHz

    }
    とSWボタン定義を入れただけではダメなようです。 コンパイルエラーは出てませんが切り替わりません。 
    まだ調べないと解らないようです。 有難うございました。

  2. 追記

    AVR 5PINで電源OFFした所 主電源からONしても正常動作しました。
    前の状態は覚えておらずFM76.0Mhzにはなってますが、
    どうやらマイコンが誤動作してたようです。
    お手数かけました。スタンパイ状態でも電流は殆ど流れないので
    そのままでも問題ありませんね!

  3. skynet さん

    ラジオモジュールいじりお疲れ様です。
    私のプログラムの仕様では、PORTD3 の電源OFFボタンを押すと、その時の
    AMモードの周波数
    FMモードの周波数
    AM/FM のモード値
    ボリュームの値
    液晶のコントラスト値
    をATMEGA328の内蔵EEPROMに書き込みしてから、PowerDownモードのsleepになって停止します。
    なので、電源OFFボタン押した後に、resetで再スタートした場合は以前の状態が復元されます。しかし、いきなり電源切った場合や RESET した場合はEEPROMに保存されません。
    また、プログラム修正してマイコンに書き込みした場合も、書き込みソフトによっては、EEPROMの上書きが発生しますので初期状態に戻ることがあるかと思います。

    短波モード 5kHz ステップの setProperty のパラメタは間違いないです。なのでコメントでいただいたコーディングは大丈夫です。あとは、モード設定ボタンが押された時の切り替え処理、マイコンリセット時の初期化処理、loop()内の 周波数表示など行なっている switch文の中を書けばなんとかなるかなとは思いますが… Si4735Radio.cpp に全体の動きが書かれていますので、よく読んでいただければと思います。

    以上よろしくお願いします。

  4. masahiro様

    助言有難う御座います。今まで、やってみましたが
    仮にFM部分をSW短波で書き換えてみましたら、切り替えが出来るように
    なりましたがFMも入れる事が出来ないようです。
    このプログラムがモード切り替えなのですが、
    btnMode.update();
    if(btnMode.isPress()) {
    if(mode == 1) {
    radio.PowerDown();
    radio.begin(SW);
    radio.mute();
    radio.setAMFreq(afreq);
    radio.setVolume(vol);
    _delay_ms(500);
    radio.unmute();
    mode = 3;
    } else {

    radio.PowerDown();
    radio.begin(AM);
    radio.mute();
    radio.setAMFreq(Sfreq);
    radio.setVolume(vol);
    _delay_ms(500);
    radio.unmute();
    mode = 1;
    この else 文 条件文と思うんですが2つ使うとエラーになり
    コンプリート出来ないのです。Si4735Radio.cpp Si4735.cpp hファイルを
    書き換えましたが主にはSi4735Radio.cppになります。
    色々試してみますが、もう少しのとこで先に進めません><
    申し訳ないのですがプログラムがあるので こちらに書き込みしました。
    宜しくお願いします。 電源関係はクリアー出来ました。有難うございます。

  5. skynet さん

    プログラムの修正お疲れ様です。
    個人的に短波は、ダイレクトチューニングとロータリーエンコーダーなどによるダイヤルチューニングもしたいところなので今回のサンプルでは実装していませんでした。

    Si4735Rajio.cpp で使用している mode という変数は 0がFM, 1がAM になっています。define は、Si4735.h でFM,AM,SW,LWでとりあえず定義してます。

    で、
    btnMode.update();
    if(btnMode.isPress()) {
    if(mode == 0) {
    // FM モードでmode切替えボタン押されたら AM に切替えてmode=1にする
    } else {
    // それ以外は、FMに戻すので、mode=0にする
    }
    }

    というのが現状です。さらに短波を増やすのであれば
    btnMode.update();
    if(btnMode.isPress()) {
    if(mode == 0) {
    // FM モードでmode切替えボタン押されたら AM に切替えてmode=1
    } else if(mode == 1) {
    // AM モードでmode切替えボタン押されたら SW に切替えてmode=2
    } else {
    // SW モードでmode切替えボタン押されたら FM に切替えてmode=0
    }

    というふうに、if 文を書いてみてください。
    あと同様の処理としては if 文のかわりに switch – case 文でも問題ありません。

    btnMode.update();
    if(btnMode.isPress()) {
    switch(mode) {
    case 0: // FMからAMの切り替え
    case 1: // AMからSWの切り替え
    case 2: // SWからFMへ戻る
    }
    }

    こういう表現でソース書いてある場所が何箇所かあります。いづれも C 言語の基本的な条件判断文ですので解説サイトなども参考にされると良いかと思います。以上よろしくお願いします。

  6. masahiro様
    有難う御座いました。 無事 3BAND切り替え出来るようになりました。
    プログラムをいじくりすぎた為 今までMODE初期化出来てたのが
    初期化が出来なくなってます。一度 デフォルトに戻して
    変更部分だけ修正した方が良さそうです。
    有難うございました。

  7. skynet さん

    Si4735 ラジオモジュールいじりお疲れ様です。3BAND切り替え成功おめでとうございます。
    blog に書かれていたようですが、電源OFF時のSWモードの状態保存の eeprom 書き込みは、増やしたSW用周波数などについて、電源OFFボタン押下時の処理内でのEEPROM書き込み追加と、setup()内での読み出し。で、それ用のEEPROM領域の追加をすればいいので、余裕があればチャレンジされてはと思います。

    個人的にSWモードは操作面でのこだわりみたいなのがありまして、今回は入れなかったこと理解ください。キット化して商売するなら、オプション扱いみたいなもんで儲けさせていただきます、というやつです(^^)

  8. masahiro 様
    EEPROMの保存方法は又挑戦してみます。
    短波帯は 確かにエンコーダー選局が有利になりますね!
    今回 勉強になりました。ずーとmasahiro様に頼ってしまってたのですが
    最後に助言だけ貰えたらと思います。
    前から ずーと やってきたのですがマニュアル選局が出来ません。
    ボタンを押した時だけスキャンで離すと止まると言う感じです。
    場所は解るのですが
    if(btnDown.isPress()) {
    radio.seekDownAMFreq();
    の部分は モジュルで定義されたコマンドなので
    別にプログラムを作らないとダメかもしれませんね!
    有難うございました。

  9. skynet さん

    ボタン押している間は周波数up/downさせたいというのは実装したい機能のひとつだと思います。(ボタンかエンコーダーかの違いはありますが仕組みは同じなので) が、私も手がついていないところですので、以下参考までという内容となります。ご容赦ください。

    配布プログラムの中に button.cpp というのがありまして、これがタクトスイッチが押されたかを認識するプログラムになります。しかしながら、チャタリング除去回路などを省略した簡便化のために、「押された」という状態を識別するだけです。タイマーを使って長押しされたか判別する仕組みを入れていません。(ハードと兼ね合いで実装しないといけないため確定してませんし個人的にはAM/FMでシーク動作が出来れなよかったため)

    なので、タイマーを使った長押し判定出来るボタンを作って、それが押されている間は、FM/AM/SW の周波数を各周波数ステップに従って(例えば FMなら±100kHz, SWなら±5kHz、AMなら±9kHz)増減させた周波数をset[FM/AM]Freq() に都度セットする方式かとは思います。ただ、個人的な検証でラジオモジュールの反応がそこそこ早いかどうかはやっていないため、周波数をセットする方法が良いのか、シーク停止のシグナル強度(スケルチのようなパラメタを探さないといけませんが)を変更した状態で無理矢理サーチさせるほうが効率的なのかは実験していません。
    Si4735搭載ラジオの商品例を見ましても、短波入れようと思いますと結構実装しないといけない項目が多かったりますのでトライ アンド トライでやっていただかないと駄目かなとは思います。

  10. masahiro様
    お世話になりました。
    やはりマニュアル選局は難しいようですね! SEEKの方で色々試してみましたら
    このコマンドで調節出来るようです。
     setProperty(AM_SEEK_TUNE_SNR_THRESHOLD, 0);
    setProperty(AM_SEEK_TUNE_RSSI_THRESHOLD, 5);
    SNR値を上げると、まったく受かりませんでした。0にするとデフォルトより
    感度が良いみたいです。スキャンが止まる事は無く無信号はスキャンしました。
    ここまで出来るだけでも凄い事なので妥協します。
    組立工程に入ろうかと思います。 有難うございました。 skynet

  11. 追記

    短波帯のEEPRM保存が出来ました。
    radio.begin(mode);
    radio.mute();
    if(mode == 0) {
    radio.setFMFreq(ffreq);
    } else if(mode == 1) {
    radio.setAMFreq(afreq);
    } else if(mode == 3){
    radio.setAMFreq(Sfreq);
    の記載忘れでした。Sfreqは短波帯に作った定義です。
    報告まで!

  12. masahiro様
    お世話になりました。
    どうにか理想の方法で選択も出来るようになったのでプログラム改造は
    終了です。詳しくはブログを見てくださいね!
    何回もコメして助言を頂きまして迷惑だったかもしれませんが
    勉強させて貰いました。 C言語は解りやすく改造も楽ですね!
    それと関係ないのですがパーツショップが近くにあって良いですね!
    うちの所は 車でもJR線でも1時間以上かかる所なので、まとめ買いしてます。
    それに特殊な部品とかは置いてないので通販が殆どです。
    AVRも置いてないのです>< 松本無線 広島本店です。
    広島には ここしかパーツとか扱ってるとこは無いようです。
    プログラムですが、
    ASMとかになると難しくなります。又 何かありましたら宜しくお願い致します。
    有難うございました。

  13. skynetさん

    ブログ見ました、短波帯の4バンド追加成功おめでとうございます。なお、各ソースの頭のコメントにskynetさんの修正日を追記いただいた形でこの成果(プログラム)は公開なさってはいかがでしょう。そういう形であればいいと思います。
    電子部品は日本橋で買い物することが多いです。行くのに電車、車どちらも1時間程度かかります。普通のパーツは問題ないですが、半導体はやっぱり秋月,RS,Digi-key などでしか買えないというパターンは結構あります。RSオンライン, Digi-keyなども送料無料のしきい値が低ければいいのですが、そこでしか買えないときは止むなしです。
    広島は以前に日帰りではちょくちょく行くことはありましたが最近は行けてないです。松本無線はちょっと時間作って行った記憶はあります。AVRマイコン置いてないですか、それは知りませんでした。秋月が安いですね。日本橋でもあんな値段では買えません。
    AVRマイコンなどのプログラミングでアセンブラは慣れてしまえば書けると思いますが、個人的には C, C++ で書いてます。C のソース見たらなんとなくわかると思いますし、Arduino の開発環境もCで書けますので知っていると便利かと思います。
    この件やこれ以外のことでも質問などありましたら言ってください。わかる範囲という条件はありますが対応します。また、blogのリンクをさせていただいてます(事後ですいません)。問題ありましたらお知らせ下さい。

  14. masahiro様
    有難うございます。 改造ファイルの公開ですがリクエストがあれば
    載せるようにしたいと思います。それほど難しくは無く BAND部分を
    増やしたのと それに伴う表示部分 hファイルの記載 EEPROMの
    BAND事に記載してるだけなので解る人は理解出来ると思います。
    パーツも廃盤品とか出てて入手出来なくなってますね!身近では トリマーも
    生産してないとか! 自作ではお金がかかるので作る人も少なくなってきたのかも
    ですね! 今日 秋月のLCD ACM1602NI LCDを ストリナ(ストロベリーリナックス)
    ストリナ互換にしてテストしてみたんですがダメでした。ブログでも載せてますが
    そのまま表示すると思ってたのですが甘かったようです。ACM1602NIのPICは
    プロテクトが、かかっていて1回のみ書き込みが出来るPICなので
    また書き込み又は元に戻すには何回も書き込めるPICに交換する必要があるようです。
    秋月でも100円ちょとなので買って交換しようかな?と思ったりします。
    そういえば もうケースに入れる作業してるんですね!
    もう終わりって言って まだやってます^^; 妥協も必要なんですけどね
    それと PICマイコンと 78K2マイコンは置いてるんですy 不思議です。
    以前は サトー電気通販を利用してました。でも廃盤が多くて入手困難な
    部品が出てます。RSオンライン, Digi-keyの存在は知ってましたが
    まだ通販した事は無いです。在庫は豊富なようですけどね!大阪は 共立電子とか
    マルツパーツを良く利用してます。

  15. 追記
    申し訳ないのですが、Hello Worldだけ表示出来るソースを貰えないでしょうか?
    解析したいと思います。
    宜しくお願いします。

  16. skynet さん

    I2C 液晶の件です。エアーバリアブルさんのページを見まして最初に気になったのは、秋月液晶(ファーム書き換え版)の I2C スレーブアドレスは 0x3E でストロベリー液晶も 0x3E です。skynet さんの blog では2台同時に接続されてますか? もしそうならアドレス重複するためパラで接続しては動きません。I2C の液晶にデータを送るだけでなく、送達確認の ACK などのやりとりもあり双方向で通信しているためです。

    次に、コントラスト調整などは使えませんとあるのですが、単に無視されるのかどうかがよくわからないので、lcd.cpp からコントラスト調整のコマンドは送らないようにする。

    秋月の製品説明にあるデータシートを確認。I2Cの通信速度は 100kHz までのようですが、こちらは 1MHz / 16+(2*TWBR) = 62.5kHz なので速度は OK のはず。

    今デスクトップPCの前におらずコンパイル確認出来てないですが、以下ラジオモジュール si4735rajio.cpp と lcd.cpp の修正イメージです。


    /*
    * Si4735Radio.cpp
    *
    * Created: 2012/11/30 16:10:04
    * Author: mkusunoki
    */

    #include
    #include
    #include
    #include
    #include "Wire.h"
    #include "lcd.h"

    void setup();
    void loop();

    // -----------------------------------------------------------------------------
    // Constractor
    // -----------------------------------------------------------------------------
    Wire i2c;
    Lcd charLcd;

    // -----------------------------------------------------------------------------
    // Initial setup
    // -----------------------------------------------------------------------------
    void setup() {

    i2c.begin();
    charLcd.begin(0);
    charLcd.cls();
    charLcd.write("Hello World");
    }

    // -----------------------------------------------------------------------------
    // main loop
    // -----------------------------------------------------------------------------
    void loop() {

    ;
    }

    // -----------------------------------------------------------------------------
    // main
    // -----------------------------------------------------------------------------
    int main(void) {

    setup();
    while(1) {
    loop();
    }
    }


    /*
    * lcd.cpp
    *
    * Created: 2012/12/01 19:52:47
    * Author: mkusunoki
    */

    #include
    #include
    #include
    #include "lcd.h"
    #include "Wire.h"

    extern Wire i2c;

    Lcd::Lcd() {

    ;
    }

    void Lcd::begin(char contrast) {

    _delay_ms(500);

    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x38);
    i2c.endTransmission();
    _delay_ms(1);

    //PORTC |= (1< >4) & 0x3));
    //i2c.endTransmission();
    //_delay_ms(1);

    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x6C);
    i2c.endTransmission();
    _delay_ms(300);

    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x38);
    i2c.endTransmission();
    _delay_ms(1);

    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x0C);
    i2c.endTransmission();
    _delay_ms(1);

    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x01);
    i2c.endTransmission();
    _delay_ms(2);
    }

    void Lcd::write(char ch) {
    i2c.beginTransmission(LCD);
    i2c.write(0x40);
    i2c.write(ch);
    i2c.endTransmission();
    _delay_ms(1);
    }

    void Lcd::write(char *str) {
    i2c.beginTransmission(LCD);
    i2c.write(0x40);
    i2c.write(str, strlen(str));
    i2c.endTransmission();
    _delay_ms(1);

    }

    void Lcd::setCursor2() {
    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0xC0);
    i2c.endTransmission();
    _delay_ms(1);
    }

    void Lcd::setCursor1() {
    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x80);
    i2c.endTransmission();
    _delay_ms(1);
    }

    void Lcd::cls() {
    i2c.beginTransmission(LCD);
    i2c.write(0x00);
    i2c.write(0x01);
    i2c.endTransmission();
    _delay_ms(1);
    }

    void Lcd::setContrast(char contrast) {

    ;
    }

  17. Masahiro様
    またお世話になります。
    早速テストした所 Hello Worldの表示が Hと3番目のl それとoしか
    表示されてませんでした。解析の見通しが出来たように思います。
    色々 いじくってみます^^; ちなみに純正のLCDは コントラスト
    調整出来ないので まったく表示出来ませんでした。
    秋月の改造LCDの表示結果です。勿論 単続で接続してます。

    結果報告まで 

  18. Skynetさん

    現物持っていないので、なかなかわかりません。液晶側にプルアップ抵抗内蔵されているなら、マイコン側につけてるプルアップ抵抗は不要です。また、液晶にプルアップ抵抗無い場合ですが、マイコン側の抵抗値を2.2kや1kくらいにして改善するかがハードの対応と思います。

    ソフトのほうは、delay関数の待ちが短くて、液晶側取りこぼしがあるかも。F_CPU の define モレ無いでしょうか。無いなら define して下さい。また delay 時間長くして表示が改善するかが手っ取り早い確認のステップかと思います。

    以上よろしくお願いします。

コメントを残す

メールアドレスが公開されることはありません。