完成しているのに未だにネタとして活用していますw
今回はプログラム関係です。プログラムの掲載がありますので長いですので、適当に読み飛ばしてください^^。
プログラムはdiorama111さんのプログラムを参考に作らせていただきました。
今回のマイコンはイーグル号のエンジンのコントロール以外はATmega168Pを3つ使用しました。
左からDF Playerをコントロールする回路とAVR
中央がイーグル号本体の回路とAVR
右が展示台のメインの回路とAVR
です。
まずはDF Playerのプログラムですが、元はArduino用のものなのですが、これをyoutubeでdiorama111さんがAVRで動かす用にこちらでプログラムを公開されていました。これをスイッチバージョンに改変させていただき、メインのAVRと連携できるようにしました。
プログラムはこちら
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 |
/* * space1999_DF_player.c * * Created: 2016/11/22 23:00:38 * Author: 6jiro *diorama111さんのプログラムを改変 */ // ATmega168P clock:8MHz // http://www.picaxe.com/docs/spe033.pdf #include <avr/io.h> #define F_CPU 8000000UL #include <util/delay.h> #define uart while(!(UCSR0A & 0b00100000));UDR0=data[i]; unsigned int i,ads,cmd,bt,cti,ib,eq; unsigned char vol,rpt,ifd; void ope6(unsigned char dfcmd6){ //Start Ver Length Cmd Res End uint8_t data[]={0x7E,0xFF,0x04,dfcmd6,0x00,0xEF}; for(i=0;i<6;i++){uart} //if(rpt){_delay_ms(300);} //Volume speed } void ope8(unsigned char dfcmd8,unsigned char value){ //Start Ver Length Cmd Res byteH byteL End uint8_t data[]={0x7E,0xFF,0x06,dfcmd8,0x00,0x00,value,0xEF}; for(i=0;i<8;i++){uart;} } //------------------------------------------------------------------- int main(void){ DDRC =0b00000000; PORTC =0b00111111; DDRB =0b00000000; PORTB =0b00000001; UBRR0 =51; // 8000000Hz/(16*9600bps)-1 UCSR0A=0b00000000; UCSR0B=0b10011000; UCSR0C=0b00000110; //----- Initialize ------------------------------------------- _delay_ms(1100); //Volume vol=0x10; //(0x00-0x1E) ope8(0x06,vol); _delay_ms(100); //----------------------------------------------------------- while(1){ if (~PINC & 0x01){cmd=1;} if (~PINC & 0x02){cmd=2;} if (~PINC & 0x04){cmd=3;} if (~PINC & 0x08){cmd=4;} if (~PINC & 0x10){cmd=5;} if (~PINC & 0x20){cmd=6;} switch(cmd){ case 1:ope8(0x03,1);break; //1 case 2:ope8(0x03,2);break; //2 case 3:ope8(0x03,3);break; //3 case 4:ope6(0x04);break; //Vol up case 5:ope6(0x05);break; //Vol down case 6:ope6(0x0E);break; //Stop } //cmd=0; }//while }//int main |
曲は3曲であとは必要なコマンドであるボリュームの増減と曲を止めるためのコマンドのみです。
ただ私のプログラムが未熟なためか3局目の曲が流れないという欠陥を抱えていますw
プログラム自体は難しいところはあまりなくて、mainの所でポートCの0〜5までのスイッチの変化に応じてDF Playerにコマンドが送信されます。
if文の後にわざわざswitch文は必要なかったと思いますがとりあえずこれで行ってみましたw
次に展示台メインのプログラム
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
/* * space1999_display.c * * Created: 2016/11/22 22:16:51 * Author: 6jiro * IR受信プログラムはdiorama111さんのものを使用 */ //ATmega168P clock:8MHz #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #define F_CPU 8000000UL #include <util/delay.h> #define uart while(!(UCSR0A & 0b00100000));UDR0=data[i]; void wait(uint16_t w){while(w--){volatile uint16_t i=1;while(i--);}} int cti,ads,cmd; char bt,ib; int b,c,d,h,i,j,k,n,r,duty,s,t,u,v=0,w,e; unsigned char eq,vol,rpt,ifd; int z1=0x30CF,z2=0x18E7,z3=0x7A85,z4=0x10EF,z5=0x38C7,z6=0x5AA5; int z7=0x42BD,z8=0x4AB5,z9=0x52AD,z0=0xD42B; int zd=0xA25D,zn=0xE21D,zg=0x22DD,zs=0xC23D,zc=0x6897;//電源:zd,MENU:zn,TEST:zg,回転矢印:zs int zu=0xE01F,zw=0x906F,zv=0xA857,zp=0x02FD,zm=0x9867;//巻き戻し:zu,早送り:zw,再生:zv:+:zp,-:zm unsigned int m=10,q; //--------- timer ------------------------------------------------------------ void ts(){for(h=0;h<60;h++){wait(10000);}} void ti(){for(h=0;h<10;h++){wait(10000);}} void t1(){for(h=0;h<4;h++){wait(10000);}} void t2(){for(h=0;h<1;h++){wait(10000);}} //---------- all off ---------------------------------------------- void off(){ n=0;c=0;b=0; PORTD|=(1<<PD0);_delay_ms(50);PORTD&=~(1<<PD0);//sound stop PORTC&=~(1<<PC2);ti();ti();ti(); PORTC&=~(1<<PC3);ti();ti();ti(); PORTC&=~(1<<PC4);ti();ti();ti(); PORTC&=~(1<<PC5); OCR0A=0; OCR2A=255; while(!(~PINC &0x01)){} if (~PINC & 0x01){OCR2A=0;}//lift down }//off void start(){ PORTC|=(1<<PC5);ti();ti();ti(); PORTC|=(1<<PC4);ti();ti();ti(); PORTC|=(1<<PC3);ti();ti();ti(); PORTC|=(1<<PC2); } void end(){ PORTD|=(1<<PD0);_delay_ms(50);PORTD&=~(1<<PD0); PORTC|=((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)); ti();ti(); PORTC&=~((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)); ti();ti(); PORTC|=((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)); ti();ti(); PORTC&=~((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2)); } void deci(){ if(cmd==zd) { //power if(v==0){v=1;start();n=0;}else{v=0;n=0;off();} } /* if(cmd==z1 && n==0 && v) {PORTC^=(1<<PC1);} //コクピット if(cmd==z3 && n==0 && v) {PORTB^=(1<<PB6);} //メインエンジン if(cmd==z2 && n==0 && v) {d^=1;} //ポジション if(cmd==z4 && n==0 && v) {r^=1;if(r){OCR0A=100;}else{OCR0A=0;}}//コンテナ窓 if(cmd==z5 && n==0 && v){PORTD^=(1<<PD3);} //VTOLエンジン if(cmd==z6 && n==0 && v){PORTB^=(1<<PB1);} //ランディングライト */ if(cmd==z7 && n==0 && v){PORTB|=(1<<PB6);_delay_ms(50);PORTB&=~(1<<PB6);}//music1 if(cmd==z8 && n==0 && v){PORTD|=(1<<PD4);_delay_ms(50);PORTD&=~(1<<PD4);}//music2 if(cmd==z9 && n==0 && v){PORTD|=(1<<PD3);_delay_ms(50);PORTD&=~(1<<PD3);}//music3 if(cmd==zw && v){PORTD|=(1<<PD2);_delay_ms(20);PORTD&=~(1<<PD2);}//volup if(cmd==zu && v){PORTD|=(1<<PD1);_delay_ms(20);PORTD&=~(1<<PD1);}//vol down if(cmd==zv && v){PORTD|=(1<<PD0);_delay_ms(50);PORTD&=~(1<<PD0);}//stop if(cmd==zp && n==0 && v){OCR2A=0; r^=1;//up if(r){ if(~PINC & 0x02){OCR0A=0;} else{OCR0A=250;}} else{OCR0A=0;}} if(cmd==zm && n==0 && v){OCR0A=0; t^=1;//down if(t){ if(~PINC & 0x01){OCR2A=0;} else{OCR2A=250;}} else{OCR2A=0;}} if(cmd==zn && v){n^=1;q=0;u=0;if(n==0){u=99;}}//demo mode if(cmd==z0 && n && v) {m=m+4;if(m>28){m=28;}} //demo slow if(cmd==zc && n && v) {m=m-4;if(m<4 ){m=4; }} //demo fast wait(30000); } //--------- lead -------------------------------------------------------- ISR(PCINT0_vect){ cti=0;while(~PINB & 0x01){cti++;_delay_ms(0.1);} //leader(16T) check if(cti>80 && cti<100){ //cti:90(16T) cti=0;while((PINB & 0x01)&&(cti<55)){cti++;_delay_ms(0.1);} //blank(8T) check if(cti>35){ //cti:45(8T) for(ib=0;ib<32;ib++){ while(~PINB & 0x01); cti=0;while((PINB & 0x01)&&(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 } deci(); cti=0;while((PINB & 0x01)&&(cti<10)){cti++;_delay_ms(0.1);} while(~PINB & 0x01); //stop bit }//if(cti>35 }//if(cti>80 cti=0;while((PINB & 0x01)&&(cti<1500)){cti++;_delay_ms(0.1);} //blank check if(cti>1400){cmd=0;} }//ISR ISR(PCINT1_vect){ wait(100); if(~PINC & 0x01){OCR2A=0;} //down stop if(~PINC & 0x02){OCR0A=0;} //up stop } ISR(TIMER1_COMPA_vect){ w++; if (w==1 && b){PORTC&=~((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2));PORTC|=(1<<PC5);}//take-off if (w==2 && b){PORTC&=~(1<<PC5);PORTC|=(1<<PC4);} if (w==3 && b){PORTC&=~(1<<PC4);PORTC|=(1<<PC3);} if (w==4 && b){PORTC&=~(1<<PC3);PORTC|=(1<<PC2);} if (w==1 && c){PORTC&=~((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2));PORTC|=(1<<PC2);}//landing if (w==2 && c){PORTC&=~(1<<PC2);PORTC|=(1<<PC3);} if (w==3 && c){PORTC&=~(1<<PC3);PORTC|=(1<<PC4);} if (w==4 && c){PORTC&=~(1<<PC4);PORTC|=(1<<PC5);} if (w>=4){w=0;} q++;if(q>=m){q=0;u++;if(u>36){u=99;}} } //---------------------------------------------------------------------------- int main(){ DDRB =0b01111110; PORTB =0b00000001; DDRC =0b00111100; PORTC =0b00000011; DDRD =0b11111111; PORTD =0b00000000; TCCR0A=0b10000011; //up 高速PWM、比較一致でLow BOTTONでHigh TCCR0B=0b00000001;//分周なし OCR0A =0; TCCR2A=0b10000011; //down TCCR2B=0b00000001; OCR2A =0; PCICR =0b00000011; //PCINT setting PCMSK0=0b00000001; //remote control read PCMSK1=0b00000011; //PCINT8,9 //SMCR =0b00000100; //power down mode TCCR1A=0b00000000; //demo,psitoion TCCR1B=0b00001100; //比較一致タイマ CTC top=OCR1A TIMSK1=0b00000010; //割り込み許可 OCR1A =16500; sei(); //------------------------------------------------------------------------- while(1){ //----------- demo --------- u=0; while(n){ //if(u==0){PORTC|=(1<<PC1);OCR0A=140;}//コクピット,CONTAINER if(u==0){PORTC&=~((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2));} if(u==1){PORTC|=(1<<PC5);ti();ti(); PORTC|=(1<<PC4);ti();ti(); PORTC|=(1<<PC3);ti();ti(); PORTC|=(1<<PC2);} //if(u==1){d=1;PORTB|=(1<<PB1);}//COK.CON,POSI if(u==2){} if(u==3){w=0;b=1;ts();ti();ti();ts();PORTD|=(1<<PD4);_delay_ms(50);PORTD&=~(1<<PD4);} //if(u==2){}//COK,CON,POSI,LAND //if(u==3){PORTD|=(1<<PD3);}//COK,CON,POSI,LAND,VTOL if(u==6){ts();OCR0A=170;} if(u==7){OCR0A=250;} if(u==9){ti();ti(); if(~PINC & 0x02){OCR0A=0;}else{OCR0A=200;}} //if(u==5){PORTB|=(1<<PB6);ti();ti();PORTD&=~(1<<PD3);PORTB&=~(1<<PB1);} //COK,CON,POSI,MAIN if (u==10){w=0;b=0;if(~PINC & 0x02){OCR0A=0;}else{OCR0A=220;}ts();OCR0A=0; PORTC&=~((1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5));} //if(u==9){PORTB|=(1<<PB1);ti();ti();PORTD|=(1<<PD3);PORTB&=~(1<<PB6);} //COK,CON,POSI,LAND,VTOL if(u==20){OCR2A=200;w=0;c=1;} if(u==22){OCR2A=250;} //if(u==12){PORTB&=~(1<<PB1);ti();ti();PORTD&=~(1<<PD3);} //COK,CON,POSI, if(u==24){if(~PINC & 0x01){OCR2A=0;}else{OCR2A=220;}} if(u==25){OCR2A=0;} if(u==27){c=0; PORTC|=((1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)); PORTD|=(1<<PD0);_delay_ms(50);PORTD&=~(1<<PD0); ts();ts();ts();ts();} //if(u==14){d=0;ti();ti();ti();ti();OCR0A=0;}//COK //if(u==15){PORTC&=~(1<<PC1);} if(u==31){PORTC&=~((1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5));} if(u==99){off();PORTC|=((1<<PC5)|(1<<PC4)|(1<<PC3)|(1<<PC2));n=0;} } }//while(1) //------------------------------------------------------------ return 0; }//int main() |
メインプログラムは赤外線リモコンにより、滑走路のLED、昇降装置、先ほどのDF Player用のマイコンスイッチのオンオフをコントロールしています。
基本的には以前ご紹介した単純な赤外線リモコンのプログラムを改変しているだけです。
70〜112行までのvoid deci()が赤外線リモコンの信号を読み取ってコマンドを実行しています。
145〜149行のISR(PCINT1_vect){}がピン割り込みで前回書いていた昇降装置の安全装置でポートCの0、1番に接続してあるリードスイッチの信号を読み取ってOCR0AとOCR2AのPWM信号を制御しています。
152行〜168行のISR(TIMER1_COMPA_vect){}がタイマー1の割り込みでOCR1Aの数値を基本に一定時間が来るたびにここの処理を実行します。これによって滑走路のLEDの点滅制御とデモモードの時間を決定しています。
171〜200行までがAVRの設定でポートの設定、タイマー0、1、2の設定、割り込みの設定が書かれています。
203行から下がデモモードの時のプログラムが書かれています。
次にイーグル号本体のプログラムは
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
/* * space1999_main_program_mega168P.cpp * * Created: 2016/11/11 21:25:34 * Author: 6jiro * IR受信プログラムはdiorama111さんのものを使用 */ //ATmega168P clock:8MHz #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #define F_CPU 8000000UL #include <util/delay.h> #define uart while(!(UCSR0A & 0b00100000));UDR0=data[i]; void wait(uint16_t w){while(w--){volatile uint16_t i=1;while(i--);}} int cti,ads,cmd; char bt,ib; int d,h,i,j,k,n,r,duty,s,u,v=0,w; unsigned char eq,vol,rpt,ifd; int z1=0x30CF,z2=0x18E7,z3=0x7A85,z4=0x10EF,z5=0x38C7,z6=0x5AA5; int z7=0x42BD,z8=0x4AB5,z9=0x52AD,z0=0xD42B; int zd=0xA25D,zn=0xE21D,zg=0x22DD,zs=0xC23D,zc=0x6897;//電源:zd,MENU:zn,TEST:zg,回転矢印:zs int zu=0xE01F,zw=0x906F,zv=0xA857,zp=0x02FD,zm=0x9867;//巻き戻し:zu,早送り:zw,再生:zV:+:zp,-:zm unsigned int m=10,q; //---------- all off ---------------------------------------------- void off(){ PORTB&=~((1<<PB1)|(1<<PB6)); PORTD&=~(1<<PD3); PORTC&=~((1<<PC0)|(1<<PC1)); OCR0A=0; d=0;r=0; } //--------- timer ------------------------------------------------------------ void ts(){for(h=0;h<60;h++){wait(10000);}} void ti(){for(h=0;h<10;h++){wait(10000);}} void t1(){for(h=0;h<4;h++){wait(10000);}} void t2(){for(h=0;h<1;h++){wait(10000);}} //-------- start -------------------------------------------------- void start(){ PORTC|=(1<<PC1);ti();ti(); OCR0A=200; PORTB|=(1<<PB1);;ti();ti(); PORTC|=(1<<PC0);t1(); PORTC&=~(1<<PC0);t1(); PORTC|=(1<<PC0);t1(); PORTC&=~(1<<PC0);t1(); PORTB&=~(1<<PB1); PORTC&=~((1<<PC0)|(1<<PC1)); OCR0A=0; } //-------- end ---------------------------------------------------- void end(){ off(); wait(60000); PORTC|=(1<<PC0);ti(); PORTC&=~(1<<PC0);ti(); PORTC|=(1<<PC0);ti(); PORTC&=~(1<<PC0); } //---------- decision --------------------------------------------- void deci(){ if(cmd==zd) { //power if(v==0){v=1;start();n=0;}else{v=0;n=0;off();end();} } if(cmd==z1 && n==0 && v) {PORTC^=(1<<PC1);} //コクピット if(cmd==z3 && n==0 && v) {PORTB^=(1<<PB6);} //メインエンジン if(cmd==z2 && n==0 && v) {d^=1;} //ポジション if(cmd==z4 && n==0 && v) {r^=1;if(r){OCR0A=100;}else{OCR0A=0;}}//コンテナ窓 if(cmd==z5 && n==0 && v){PORTD^=(1<<PD3);} //VTOLエンジン if(cmd==z6 && n==0 && v){PORTB^=(1<<PB1);} //ランディングライト if(cmd==zn && v){off();n^=1;q=0;u=0;if(n==0){u=99;}}//demo mode if(cmd==z0 && n && v) {m=m+4;if(m>28){m=28;}} //demo slow if(cmd==zc && n && v) {m=m-4;if(m<4 ){m=4; }} //demo fast wait(30000); } //--------- lead -------------------------------------------------------- ISR(PCINT0_vect){ cti=0;while(~PINB & 0x01){cti++;_delay_ms(0.1);} //leader(16T) check if(cti>80 && cti<100){ //cti:90(16T) cti=0;while((PINB & 0x01)&&(cti<55)){cti++;_delay_ms(0.1);} //blank(8T) check if(cti>35){ //cti:45(8T) for(ib=0;ib<32;ib++){ while(~PINB & 0x01); cti=0;while((PINB & 0x01)&&(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 } deci(); cti=0;while((PINB & 0x01)&&(cti<10)){cti++;_delay_ms(0.1);} while(~PINB & 0x01); //stop bit }//if(cti>35 }//if(cti>80 cti=0;while((PINB & 0x01)&&(cti<1500)){cti++;_delay_ms(0.1);} //blank check if(cti>1400){cmd=0;} }//ISR ISR(TIMER1_COMPA_vect){ w^=1; if(w && d){PORTC|=(1<<PC0);} else{PORTC&=~(1<<PC0);} q++;if(q>=m){q=0;u++;if(u>15){u=99;}} } //---------------------------------------------------------------------------- int main(){ DDRB =0b01111110; PORTB =0b00000001; DDRC =0b00000011; PORTC =0b00111100; DDRD =0b11111000; PORTD =0b00000000; TCCR0A=0b10000001; //contena TCCR0B=0b00000010; OCR0A =0; PCICR =0b00000011; //PCINT setting PCMSK0=0b10000001; //remote control read PCMSK1=0b00111100; // TCCR1A=0b00000000; //demo TCCR1B=0b00001100; //比較一致タイマ CTC top=OCR1A TIMSK1=0b00000010; //割り込み許可 OCR1A =33000; sei(); //------------------------------------------------------------------------- while(1){ //----------- demo --------- //if(n){ u=0; while(n){ if(u==0){PORTC|=(1<<PC1);OCR0A=140;}//コクピット,CONTAINER if(u==1){d=1;PORTB|=(1<<PB1);}//COK.CON,POSI,LAND if(u==2){}//COK,CON,POSI,LAND if(u==3){ti();PORTD|=(1<<PD3);}//COK,CON,POSI,LAND,VTOL if(u==5){PORTB|=(1<<PB6);ti();ti();PORTD&=~(1<<PD3);PORTB&=~(1<<PB1);} //COK,CON,POSI,MAIN if(u==9){PORTB|=(1<<PB1);ti();ti();PORTD|=(1<<PD3);PORTB&=~(1<<PB6);} //COK,CON,POSI,LAND,VTOL if(u==12){PORTB&=~(1<<PB1);ti();ti();PORTD&=~(1<<PD3);} //COK,CON,POSI, if(u==14){d=0;ti();ti();ti();ti();OCR0A=0;}//COK if(u==15){PORTC&=~(1<<PC1);} if(u==99){off();} } //---------- manu ----------- }//while(1) //------------------------------------------------------------ return 0; }//int main() |
先ほどの展示台のプログラムと多少の動作が違うくらいで、基本的にはプログラムはほぼ同じです。
これらのプログラムを組んで、基盤の作成してみました。
こちらがメイン基盤です。白と赤の配線がDF playerをコントロールするマイコンに行きます。
電源は右下の減圧回路で12vと一部減圧して5vを取り出す予定にしていたのですが、この減圧回路まともに動いていなくて一時かなり悩みましたw結局動画を撮影した時には12vと5vのアダプラーを2つ使用していましたw現在この減圧回路を交換して12vのアダプター1つで動かせるようになりました。
基盤右上のものがモータードライバーで、左上の部分が滑走路の LEDを動かすためのトランジスタへの配線です。
こちらがDF Playerの回路です。
このDF Playerは以前レッサーかずさんがご紹介してくださったものです。値段も安くて、結構細かい操作まで行えるので非常に重宝しました^^。
基盤とプログラムができましたのでいよいよ全体のタイミング合わせを行いました。
今までもなんども書いていますが、これが結構大変でしたw
動かしてみてはプログラムのタイミング修正したり、効果音を伸ばしたり短くしたりを繰り返します。
上昇下降も実はプログラムを見てもらうとわかるのですが、途中からスピードが変化してるので簡単に計算できないタイミングもあるんですよね^^;
例えば、開始直後のタイミング合わせはデモをスタートさせてすぐにわかりますが、デモの後半の着陸時のタイミング合わせはデモが終わり近くなるまで待たないといけませんwデモをスタートさせて2分ぐらい待ってようやく修正したプログラムと効果音が合っているのかがわかりますw合っていないときはこれを再度繰り返しますので、時間がむちゃくちゃかかりましたw
その間、効果音がしますので家族からは「お父さんうるさい!」との非難の声がw
さらに12vと5vを使っていますのでつなぎ間違えAVRとDF Playerが昇天してしまうとかw
DF Playerの裏側のICが溶けて穴が空いていますwおまけに基盤には焦げた跡もw
ちなみにこの間違い2回行いましたwつまりDF Player2個とATmega168P4個昇天させましたw
アホすぎる・・・・w
ちなみに前回ご紹介したリードスイッチですが、
実はこのリードスイッチも配線を引っ張ってしまったりして4個くらい割ってしまいましたw
その後リードスイッチの配線は瞬着で固めて動かなくしましたw
とま、いろいろ散々な目に遭いながらどうにか展示台にギミックを詰め込んでなんとか撮影です^^;
ただ、今回の展示台とイーグル号の機体はそれぞれの赤外線センサーで受信していますので、たまに片方だけ受信して片方が受信していないということもありますw機体だけスイッチが入ってデモを始めているのに展示台の方はシ〜〜ンと動かないwてなこともたまに起こります。
本来なら展示台のマイコンとイーグル号本体のマイコンを1つにまとめた方が簡単だったのですが、どうしても機体と展示台の間に配線を見せたくないことと、イーグル号単体でも遊べるようにしたかったのでこのような方法をとりました。
長々となりましたが、これでスペース1999 イーグル号の製作終了です^^。
おつきあいありがとうございました^^。
関連すると思われる記事:
- None Found
こんにちは!
プログラムの公開ありがとうございます。
3個のAVRを駆使した、素晴らしい模型です。
プログラムを拝見して、二番目と三番目のプログラムで、変数uの値で分岐している様ですが、値が一部しか使用されていないなぁと思っていたら、プログラムを共有されていたのですね。(納得です)
赤外線の受信状況が、イーグル号と展示台でケースによっては同時受信できないとのこと、わかります(笑)
音はすれど、イーグル号は「お休み」なんでしょうね!(笑)
イーグル号を持ち上げる棒に非接触で何か信号を送信できる回路が仕込めれば、展示台の赤外線受信だけで行けそうですが、難しいでしょうね。
Vividさん こんにちは!
さすがVividさんです!おっしゃるように2,3番目のプログラムを共有しています。2番目の方がタイマーカウンターの値が半分なのでデモの段階として変数uが3番目のプログラムが10なら2番目のプログラムは20に相当します。
ここのuの数字を変えたりしてあのデモのタイミング合わせをしています。
赤外線受信がケースによっては同時受信しないのは少し情けないですが、殆どの場合は大丈夫なのでこれで良しとしています^^;
実は展示台の方にも赤外線発信用のLED仕込んで、イーグル号に送るか?とも考えたのですが、面倒なのであきらめましたw
Vividさんが研究中の非接触のコイルによる情報伝達があればもしかして・・・・。距離的に難しいですかね^^;
こんばんは。
今までも夜中に見られない事が数回ありましたが、6jiroさんが使用されているブログシステムのデータベースは頻繁にクラッシュしますね(>_<)
データやコメントが無くならないのが幸いですが(-o-;)
プログラムの公開と解説をありがとうございます。
AVRでコントロール出来るmp3プレイヤーというものがあるんですねぇ。
モータードライブICまで連動していて素晴らしいギミックです!
初歩的な質問で申し訳ないのですが、
展示台のプログラムの40行目以降などに出てくるPORTC&=~(1<<PC2);ti();ti();ti();部分などの「ti();ti();ti()」とは、どのような意味になるのでしょうか?
お手数をお掛けしますが、もしよろしければ教えていただけると嬉しいですm(_ _;)m
話は全く変わるんですけど、ここ4~5年歯医者に行ってなかったのですが、歯磨き時、奥歯ばかり気にしていて前歯がおろそかになっていたようで、久し振りに鏡で前歯をしげしげと見たところ、歯と歯茎の辺りに白い歯石のようなものが付いていて、歯全体も茶色くなっていたのでビックリし、先週は歯医者に行って、歯石を取って貰いました(苦笑)
結構メンテナンスを怠けていたようで(^-^;)一度で全部は取り切れないとの事で、来週は上の歯列を清掃して貰う予定デス(^+++^;)
yangminさん こんばんは!
ブログシステムのクラッシュはほとんど私が要らない事をして壊していますw
データーの更新中に再起動したりw
自業自得でwordpressが悪いわけではないんですよ^^;
MP3プレイヤーはなかなかいいいですよ〜。結構細かいコマンドが送れます。
モータードライブICは初め電流値とかよくわからなくて苦労しました^^;
ti();は何もしない時間を取っています。delayと同じで、プログラムの初めごろのtimerの設定でti();のdelay時間を設定しています。
プログラムを勉強し始めた最初からこの時間設定を使っていたのでこの時間感覚に慣れているので、ti();が3個分間をあけたいなと言う時にスマートではないのですが、ti();ti();ti();と書いています^^;
特にデモの時なんかの時間調節部分ではこれらのものが頻発してきています^^;
歯科院に通われ始めたんですね〜。とてもいい事ですね^^
痛くなっていくよりも、メンテナンスで通っていい状態をできるだけ維持してもらって下さいね。長く健康な口腔内を保って美味しいものを食べて行きたいですよね^^。
早速の回答をありがとうございました。
ということは、ti();ti();ti();というのは、その上の「void ti(){for(h=0;h<10;h++){wait(10000);}}」を3回実行しているという考え方で良いのでしょうか?
MP3プレイヤーまで操作可能とはAVRは便利ですね~。
電流値に悩んだと言う事ですが、それでもモータードライブまで使いこなされるとは流石ですよ。
自分は買ったとはいえ手も付けていないので、まだちんぷんかんぷんです(^o^;)
口腔内は子供の頃治療して以来、虫歯が無いのだけは取り柄です!(笑)
yangminさん こんにちは!
yangminさんのおっしゃる通りです。
void ti(){for(h=0;h<10;h++){wait(10000);}}
はti()というこんな関数を定義しますよ。ということで、その後ti()というコマンドが出たら、この関数を実行しますので、今回の場合は3回この関数を実行します。
ちなみに新たにvoid t3(){for(h=0;h<30;h++){wait(10000);}}という関数をもし作っていたら、t3();と書けばti();ti();ti();と同じことにはなるのですが、関数増やすの面倒で3回書きました^^;
MP3はシリアル通信なのでVividさんなら簡単にPICでも可能になると思います。
モーターについてはホントなめていました^^;あの子供のころから使っているようなモーターと違って大型の物はいろいろと大変なんだなと勉強になりました^^。
面倒とは思いますが、歯科医院でしっかりとメンテナンスしてもらってくださいね^^。
すんげー大作ですね!
動画でギミック拝見しましたが、音楽との同期とか結構苦労されたんだろうなぁと漠然と思ってました。ご苦労様でした。
にしても、AVRのプログラムって可読性が高いですね。
PICだとC言語でもレジスタを管理するのでアセンブラに寄った感じの記載も多く、しかも機種ごとにちょっとずつ違うので割とメンドクサイんですよね。
このモーターはステッピングモーターでしょうか?
モータードライバーICは実験的に使ってはみたのですが、ファルコンでは搭乗ベイどうしようか皆さん悩んでらっしゃいますので、純正のユニットから変更できないかなんて思ったりしてます。
あせんちゅ(汗人)さん こんばんは!
完成後あまりにも大きくて邪魔になっていますw
音楽とギミックの同期は結構時間食いました^^;ちゃんとストップウオッチとかで測ればよかったのかもしれませんが適当にやっていたので^^;
PICの経験が浅いのであまりよくわかっていないのですが、なるほど~結構違うんですね・・・・。AVRの場合も機首によって多少設定で違いがありますが、基本のプログラムには特に違いはないような感じです^^。
モーターは通常のDCモーターでギアで回転数を落としてあるものです。ファルコンの搭乗口のユニットは通常のモーターにリミットスイッチが付いているだけのようなので、市販のモータードライバーで動かせそうな感じですね。プログラム的には今回のものがそのまま使えそうな感じです。あとはどのようなギミックにするかですよね^^;まっ、そこが一番の難題であるんですけどね^^;