ボーイング737でLチカ
提供:泣かないでゆり子
ナビゲーションに移動検索に移動半組み立て状態の機体に、ブレッドボードに載せたマイコンを繋いで点滅プログラムの開発中。書き込みにはSTK500クローンを使用。
後輩からボーイング737-800のプラモデル(ハセガワ製 1/144 No.10690)を頂いたので、ただ作るだけじゃ飽き足らずAVRマイコンを内蔵して翼端灯と衝突防止灯を点滅させてみた♪ なかなか贅沢なLチカ。
AVRマイコンのスリープ(パワーダウン)機能を使って、タクトスイッチPUSHで電源ON/OFFできるようにしてみた。
回路
2.4~3Vの乾電池動作のため、マイコンはATtiny13A又はATtiny13Vを使用。無印のATtiny13は電源電圧範囲が2.7~5.5Vなため、乾電池動作(特に充電池)には不向き・・・
- 内蔵したLEDの詳細
- 尾灯 白
- 衝突防止灯(上面/下面) 赤×2
- 機内灯 白×2
- 右翼端航法灯 緑
- 左翼端航法灯 赤
- 翼端閃光灯 白×2
- 着陸灯 白×2
欲を言えばロゴライトとか、外側着陸灯なんかもつけたかったけど、このスケールでそれはキビシイ・・・
点滅させるLEDはマイコンに接続、それ以外のLEDはカソードをGNDに落としておくことで、常時点灯とした。全LEDのアノードをトランジスタに接続、トランジスタのベースをマイコンに接続して、全LEDの点灯、消灯を一括でできるようにした。
C言語コード
8ビットタイマにCTC動作をさせ、一定間隔(32ms)で割り込みを発生させてLED点滅の間隔を生成。INT0割り込みを使って、スリープからの復帰、スリープへの移行を行い、電源ON/OFFの代わりとする。
INT0割り込みは、割り込み発生の瞬間に割り込みを無効化cli()し、500ms待ってから割り込み有効に戻すsei()ことで、チャタリング対策にしている。500msも待つ必要はないけどw
ヒューズビット設定
- HIGH: 0xFD LOW: 0x6B
- SPIEN *
- BODLEVEL 1V8
- CKDIV8 *
- SUT_CKSEL INTRCOSC_128KHZ_14CK_64MS
コード
/*
* B737.c
*
* Created: 2016/03/28 17:56:56
* Author: 市川ゆり子
*/
/*
--PIN Connection--
1 RESET: N/C
2 PB3: Beacon light LED Cathode
3 PB4: N/C
4 GND: GND
5 PB2: Right Wing Strobe LED Cathode
6 PB1/INT0: Push SW to GND
7 PB0: Left Wing Strobe LED Cathode
8 Vcc: +5V
*/
#define F_CPU 16000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <avr/fuse.h>
FUSES =
{
.low = (FUSE_SPIEN & FUSE_CKDIV8 & FUSE_SUT0),
.high = FUSE_BODLEVEL0,
};
void goToSleep();
ISR(INT0_vect) {
cli();
_delay_ms(500); //Chattering Killer
sei();
//If PushSW pushed go to sleep.
//But When PushSW pushed for resume from sleep, do not go sleep.
if(bit_is_clear(MCUCR, SE)) {
goToSleep();
}
sleep_disable();
PORTB &= ~_BV(PORTB4); //Land, Nav, Interior lights on
}
static uint8_t strobe_state = 0;
static uint8_t beacon_state = 0;
//Timer interrupt routine
ISR(TIM0_COMPA_vect) {
switch (strobe_state)
{
case 0:
//All Strobe off
PORTB |= _BV(PORTB0);
PORTB |= _BV(PORTB2);
break;
case 3:
PORTB &= ~_BV(PORTB0); //Left wing strobe on
PORTB |= _BV(PORTB2);
break;
case 4:
//All Strobe off
PORTB |= _BV(PORTB0);
PORTB |= _BV(PORTB2);
break;
case 15:
PORTB |= _BV(PORTB0);
PORTB &= ~_BV(PORTB2); //Right wing strobe on
break;
}
switch(beacon_state) {
case 0:
PORTB &= ~_BV(PORTB3); //Beacon light on
break;
case 1:
PORTB |= _BV(PORTB3); //Beacon light off
break;
}
strobe_state++;
if (strobe_state == 16)
{
strobe_state = 0;
}
beacon_state++;
if(beacon_state == 48) {
beacon_state = 0;
}
}
void goToSleep() {
PORTB = 0b00111111; //All lights off.
set_sleep_mode(_BV(SM1)); //Power down mode
sleep_enable();
sleep_bod_disable();
sleep_cpu();
}
int main(void)
{
//Peripheral initialize.
DDRB = 0b00111101; //DDRB1 is in. other is out.
PORTB = 0b00000010; //PORTB1 pull up.
OCR0A = (unsigned int) 8; //init Counter Compare Register (for 32ms interrupt interval)
TCCR0A = (1 << WGM01); //CTC counter mode.
TCCR0B = (1 << CS01) + (1 << CS00); //Counter clock source clkI/O(128kHz / 8) / 64.
TIMSK0 = _BV(OCIE0A);
//INT0 interrupt
GIMSK = _BV(INT0); //INT0 enable
sei();
goToSleep();
sleep_disable();
PORTB &= ~_BV(PORTB4); //Land, Nav, Interior lights on
while(1)
{
}
}

