スペース1999のイーグル号にリモコンによる電飾を載せるにあたって今までの赤外線リモコン受信プログラムを一新してみました。
その際に単純な機能だけのプログラムも作ってみました。
正直、私のようにまだプログラムを0から作る能力のない人間にとってはネットは宝の山で、いろいろと公開されているプログラムを使用させていただいているのですが、いかんせん皆さん高度すぎて難しい^^;
私の望んでいること以上の機能がそのプログラムに仕込まれていて逆に使い方がわからないwという状態になっています^^;そこで、私が一番初期にこんなプログラムがあったらな〜と望んでいたような単純な機能のプログラムを作ってみました。
機能はリモコンの押されたボタンに応じてそれに対応するAVRのポートがON,OFFになるだけのプログラムです。
ポートにLEDをつなげればLEDが光りますし、トランジスタやリレーをつなげればスイッチとして使えます。
PIC使いの方には申し訳ないのですが、使用したのはAVRのATtiny2313です。
とりあえずPB0~PB5までLEDを繋げて動かしてみた動画がこちら。
このような感じで、まずは電源ボタンを押すとフラッシュして教えてくれます。
その後リモコン操作が可能となり、対応した番号を1回押すとON(LED点灯)となり再度押すとOFF(LED消灯)となります。
再度電源ボタンを押すと始めとは違うパターンのフラッシュをしてすべての端子がOFFとなります。
リモコンはアマゾンのこちら「5pcs ミニリモコン 赤外線リモコン 車載リモコン 20キー [並行輸入品]」
ちなみにリモコンが変わると赤外線受信プロトコールが変わったり信号が変わったりするので動かない場合があります。
赤外線センサーは秋月のこちら「赤外線リモコン受信モジュール GP1UXC41QS」
赤外線センサー部分のコンデンサーは秋月のこちら「積層セラミックコンデンサー4.7μF25V±10%」
マイコンのATtiny2313も秋月のこちら「AVRマイコン ATTINY2313-20PU」
ピン配置はこのようになっています
PD2がINT0指定ですのでここに赤外線センサーからの信号が入るようにします。
電源は5vです。
次に肝心のプログラムがこちらです。素人のプログラムですので、ここを直した方がいいとかありましたらお教えいただけたらありがたいです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
/* * IR_NEC_tiny2313.cpp * Created: 2016/11/11 21:56:14 * Author: 6jiro *赤外線受信部分はdiorama111さんのプログラム */ //ATtiny2313 clock:8MHz #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #define F_CPU 8000000UL #include <util/delay.h> int cti,ads,cmd,v=0; char ifd=0x04,bt,ib; int z1=0x30CF,z2=0x18E7,z3=0x7A85,z4=0x10EF,z5=0x38C7,z6=0x5AA5; int z7=0x42BD,z8=0x4AB5,z9=0x52AD,z0=0x6897; int zd=0xA25D,zn=0xE21D,zg=0x22DD,zs=0xC23D,zc=0xB04F;//電源:zd,MENU:zn,TEST:zg,回転矢印:zs,C:zc int zu=0xE01F,zw=0x906F,zv=0xA857,zp=0x02FD,zm=0x9867;//巻き戻し:zu,早送り:zw,再生:zv:+:zp,-:zm void start(){ PORTB|=(1<<PB0);_delay_ms(100); PORTB|=(1<<PB2);_delay_ms(100); PORTB|=(1<<PB4);_delay_ms(300); PORTB&=~((1<<PB0)|(1<<PB2)|(1<<PB4)); } void end(){ PORTB|=((1<<PB0)|(1<<PB1)|(1<<PB2));_delay_ms(50); PORTB&=~((1<<PB0)|(1<<PB1)|(1<<PB2));_delay_ms(50); PORTB|=((1<<PB0)|(1<<PB1)|(1<<PB2));_delay_ms(50); PORTB&=~((1<<PB0)|(1<<PB1)|(1<<PB2)); PORTA&=~((1<<PA0)|(1<<PA1)); PORTB&=~((1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6)|(1<<PB7)); PORTD&=~((1<<PD0)|(1<<PD1)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)); } void ope(){ if(ads==0x00FF){ if(cmd==zd){ if(v==0){v=1;start();}else{v=0;end();} } if(cmd==z1 && v){PORTB^=(1<<PB0);}//数字番号 if(cmd==z2 && v){PORTB^=(1<<PB1);} if(cmd==z3 && v){PORTB^=(1<<PB2);} if(cmd==z4 && v){PORTB^=(1<<PB3);} if(cmd==z5 && v){PORTB^=(1<<PB4);} if(cmd==z6 && v){PORTB^=(1<<PB5);} if(cmd==z7 && v){PORTB^=(1<<PB6);} if(cmd==z8 && v){PORTB^=(1<<PB7);} if(cmd==z9 && v){PORTD^=(1<<PD0);} if(cmd==z0 && v){PORTD^=(1<<PD1);} /* if(cmd==zm && v){PORTA^=(1<<PA1);}// 記号:- if(cmd==zc && v){PORTA^=(1<<PA0);}// 記号:C if(cmd==zu && v){PORTD^=(1<<PD3);}// 記号:巻き戻し if(cmd==zv && v){PORTD^=(1<<PD4);}// 記号:再生 if(cmd==zw && v){PORTD^=(1<<PD5);}// 記号:早送り if(cmd==zg && v){PORTD^=(1<<PD6);}// 記号:TEST */ } } ISR(INT0_vect){ cti=0;while(~PIND & ifd){cti++;_delay_ms(0.1);} //leader(16T) check if(cti>80 && cti<100){ //cti:90(16T) cti=0;while((PIND & ifd)&&(cti<55)){cti++;_delay_ms(0.1);} //blank(8T) check if(cti>35){ //cti:45(8T) for(ib=0;ib<32;ib++){ while(~PIND & ifd); cti=0;while((PIND & ifd)&&(cti<20)){cti++;_delay_ms(0.1);} if(cti>10){bt=1;}else{bt=0;} //cti:16(3T) cmd=cmd<<1; //cmd:command cmd|=bt; if(ib==15){ads=cmd;cmd=0;} //ads:address } ope(); cti=0;while((PIND & ifd)&&(cti<10)){cti++;_delay_ms(0.1);} while(~PIND & ifd); //stop bit }//if(cti>35 }//if(cti>80 cti=0;while((PIND & ifd)&&(cti<1500)){cti++;_delay_ms(0.1);} //blank check if(cti>1400){cmd=0;} }//ISR int main(void){ DDRA =0b00000011;//PA0,PA1出力 PA2はリセット端子のため除外 PORTA=0b00000000; DDRB =0b11111111;//PBはすべて出力 PORTB=0b00000000; DDRD =0b01111011;//PD2以外出力 PORTD=0b00000000; GIMSK=0b01000000; // INT0(PD2) 有効 MCUCR=0b00110000; sei();//割り込み許可 while(1){ } return 0; } |
AtmelStudioを使用してコンパイルしました。多分コピペでいけると思います。
簡単にプログラムを解説しますと、
16〜21行までが使用する変数の設定です。18行からリモコンの出している信号が書かれています。
24〜30行までが電源ボタンが最初に押された時のLEDの動きです。
32〜42行までが再度電源ボタンが押されて全体がOFFになる時の動きです。動画では全部がフラッシュしますが今回は3つまでとしています。この辺は好きなように書き換え可能です。
45〜70行がリモコンからの信号に対応した動作が書かれています。
この辺も好きなようにリモコン番号とポート番号(103行以下のメインで出力設定されているポートのみ)の組み合わせができます。
ちなみに現在はリモコンボタンの0〜9までに対応したものが有効になっています。
61行の/*と68行の*/を消せば記号のボタンに対応した部分も有効になります。
73〜101行はNECプロトコールに沿った赤外線リモコンの信号を受信するためのもので、このプログラムの肝です。この部分はdiorama111さんのものを使用させていただいています。理解はできるのですが、とてもこのような込み入ったプログラムは私には作れません^^;途中にope()関数足しただけですw
103行からがメインのプログラムですが、今回はAVRのレジスターの設定のみで動作の記述はありません。
割り込みだけで処理しています^^;
それとこれも重要なのですが、プログラムをATtiny2313に書き込むときにフューズの設定も必要です。
CKDIV8のチェックを外し、programを押してフューズ設定を必ず書き込んでください。このチェックが入っているとATtiny2313は8MHzで動いてくれません。
実は初期の頃、これが分からずに1ヶ月近く悩みましたw
回路図はまたまた手書きで申し訳ないのですが、こんな感じです。
プログラムに従って10個ほどLED付けていますがこの辺はお好みで^^。
私も初めてリモコンでLEDが光った時には感動しました^^。無意味に点けたり消したりしばらくしていましたw
関連すると思われる記事:
- None Found
こんばんは!
いよいよ電飾の山場ですね!
この赤外線リモコンによる制御は、おっしゃるようにSWがいらないので便利ですよね。今度何かの模型でチャレンジさせていただこうと思っています。
プログラムはAVRのCは、作法がPICと違って、さっぱりです(笑)
たぶん、信号を受光して割込みにとび、一ビットずつON/OFFを判断して、受信バイトをシフトして命令コードと照合してLED点滅に分岐していると想像します(笑)
今日は、神戸は晴天無風で、一日スケールRCヘリを飛ばして遊んできました!
こんにちは!
機種変手続き中でフリースポットからの投稿ですw
AVRも分かりにくいところに設定変更があるんですね。
PICも書き込みの時に電圧が足りなくて供給するためのチェックが最初オフになっているのがあります。事例が無いと厳しいですよね。
意味なく点灯、凄くよく分かります。作った人にしか味わえない達成感ww
Vividさん こんばんは!
プログラムについてはVividさんのおっしゃる通りです^^。
これはNECの赤外線プロトコールに沿ってリーダー、ブランク、データーを受信して最初の16ビットをadsに格納後、後半の16ビットをcmdに格納して命令コードと照合していますす^^。さすがVividさんです!
私もこの週末大阪に行っていました^^。いい天気でしたのでRCヘリ飛ばすには最高でしたでしょうね^^。
あせんちゅ(汗人)さん こんにちは!
PICの書き込みのときの電源私も最初はまりましたw
ネットで調べてどうにかことなきを得ましたが、いろいろと細かなところでハマってしまう事ってありますよね〜。
AVRのこのフューズ設定のチェックを外さずに、8MHzのプログラムを1MHzで動かしていて全く動作がおかしくて相当悩みました。まっそのおかげでかなりプログラムの勉強にはなったんですけどねw
プログラムが思い通りに動いてくれた時は嬉しくて意味なく点灯しちゃいますよねw
こんばんは!
AVRの詳しい解説とプログラムの掲載ありがとうございました。
AVRは未知の世界ですが、6jiroさんのおかげで、このままなら意識せずに使わせていただく事が出来そうなので、しっかり画像やプログラムを保存させていただきました!w
自分などは、意気込みにアタマが付いていかず、空回りばかりなので助かります(^-^;)
ご使用のソフトはAtmelStudioというもののようですが、書き込み用のライターは何を使っていらっしゃるのでしょうか?
AVRライタの件ですが、おぃおぃ聞く前に自分で調べろよ!(^^;)というワケで、調べてみましたが、秋月の7000円位のものから、aitendoのUSB接続の900円(品切れのようでしたが…)なんていうのまで、ピンキリで色々あるようですね。
お騒がせしました~(^o^;)
yangminさん こんばんは!
AVRも慣れればPICと同じですし、ネットにもいろいろプログラムがありで、もしよかったらチャレンジしてみてください^^。まっマイナーではあるんですけどねw
ところでyangminさんに私の使っている秋月で買ったライターAVRISP mkⅡをご紹介しようと思ったのですが、なんと!販売終了になっているではないですか!!
で、ネットでいろいろ調べてみると最新のAtmelStudio7ではそのAVRISP mkⅡでは対応していないとか・・・・。
まっ、その辺は古いバージョンの物を使っていただければいいかとAVRISP mkⅡを探してみるとアマゾンにありました。よかった~と思って値段を見ると・・・・・ちょw秋月で売っていた時の10倍の値段にw
3万円近くしていますwこれは絶対買えない^^;
ということでいろいろ調べましたら、こちら(http://www.aitendo.com/product/9558)に純正ではないですが、ライターありました。
とりあえず使えるか私が購入してみましたので、また報告させていただきますね。ちなみに値段は950円です。今使用中のAVRISP mkⅡが壊れた時用に使えるようになっておかないといけませんからね^^;
ちなみに古いバージョンのAtmel StudioもしくAVR Studioはこちらhttp://www.atmel.com/ja/jp/tools/STUDIOARCHIVE.aspxで入手できます。今病院なので、家に帰ってから私の使っているバージョン見てみますね。のちほどこのコメント欄に追記しますね。
Atmel Studio6を使用していました^^。
yangminさんの質問がなければ全く気が付きませんでした。ホントありがとうございます!
こんばんは!
引き続きARVライターについても詳しくご説明いただきまして、ありがとうございました。
一口にARVライターと入っても、新旧の対応の有無など…色々あるんですね(-.-;)
mkⅡが秋月の10倍の3万円!?
最近のアマゾンはホント転バイヤーが増えてしまい、風紀が乱れ気味ですね(=_=)
ご紹介いただいたaitendoのAVRライターは自分が調べた物の後継機種なのかな?
これだとVividさんに教えていただいたなんちゃってPickit3同様、使い勝手も似ていそうで手を出しやすそうですね(^-^)
情報ありがとうございます!
現在Atmel StudioはVer7.0のようですね。
早速インストーラーだけでもダウンロードしておきますね!
自分などは、ただの「教えて君」で色々と伺っただけなので、何のお役にも立っておりませんよ(^.^;)
それなにそのように言っていただける6jiroさんは、やはりさすがの人徳者であらせられまする!(^o^)
yangminさん こんばんは!
いやいやw褒めすぎですw本当気がつきませんでしたから、助かりました^^。
yangminさんが質問してくれるからいろいろと知識も増えていくので本当ありがたいですよ^^。
アマゾンの転売屋には困ったものですよね・・・。あの金額で購入する人がいるんでしょうかねw?
aitendoのAVRライターは多分後継機とかなんかなんでしょうね〜。形がほぼ一緒でカバーが付いただけみたいな感じもありますがw
とりあえず注文してみましたので来たらレビューしておきますね。
AVRは確かにVividさんの言われるように、レジスターの設定が違ったり、多少c言語の作法が違う部分もありますが、慣れれば結構簡単ですよ^^。