【MBC-06】息で吹き消せ!LEDライト


概要

blow-out-led

・ロウソクのように、息を吹きかけると消えるLEDライトを作ってみた。
・圧電スピーカに振動を与えると、わずかだが電圧が発生する。その電圧をマイコンのアナログコンパレータで検出すると、LEDが消える。
・ファームウェアRev.1では、本当のロウソクと違って、もう一度息を吹きかけると点灯してしまう。もっとも、この動作はプログラムでどうにでもなるわけだが。
・そこで、ファームウェアRev.2では、1回吹いただけでは点灯しないように変更。1秒程度の間隔をあけてセンサを2回たたくと点灯する。効果音も追加してみた。

使用部品

parts list
ミニブレッドボード BB-601
AVRマイコン ATTINY2313-20PU またはATTINY2313V-10PU
5mm径LED
圧電スピーカ (13mm)PKM13EPYH4000-A0
カーボン抵抗器 150Ω、1/4W 2個
カーボン抵抗器 100kΩ、1/4W
カーボン抵抗器 10kΩ、1/4W
バッテリースナップ
単3電池2本用電池ボックス
ジャンパ線1本

回路図

schematics

実体配線図

breadboard-001


ファームウェア (AVR-GCC)

(Rev.2 吹くと音が鳴って点滅しながら消灯、約1秒間隔で2回たたくと、音がなり、点滅しながら点灯する。)

// Analog Cmparator Application ( Blow Out LED )

// TARGET : ATTINY2313 (Internal OSC : 8MHz / 8 ( Factory default ) 

// AIN1 : Resistor

// AIN0 ( PB0 ) : Piezo speaker

// PB3 : LED (0:ON, 1:OFF)


#include <avr/io.h>

#include <avr/interrupt.h>


#define led_off() ( PORTB |= (1<<PB3) )

#define led_on() ( PORTB &= ~(1<<PB3) )

#define led() ( PORTB ^= (1<<PB3) )

#define buz() ( PORTB ^= (1<<PB0) )


#define is_analog_in() ( ACSR & (1<<ACO) ) // Analog Comparator Output


void wait(volatile long i)

{

while (i-- > 0);

}


void init_timer0(void)

{

    //Set Timer Counter Control Register A (TCCR0A)

// (WGM02) WGM01 WGM00

// (  0   )    0     0 // Normal mode

// (  0   )    1     1 // Fast PWM mode

// (  0   )    1     0 // CTC mode

// (  1   )    1     1 // Fast PWM mode TOP is OCR0A

// (  1   )    0     1 // PWM Phase correct TOP is OCR0A

// COM0A1  COM0A0 COM0B1 COM0B0

    //    0      0       0      0   // Normal Port Operation, OC0A Disconnected.

//    1      0       1      0   // Clear OC0A on Compare Match, set OC0A at TOP


    TCCR0A = (0<<WGM02) | (0<<WGM00) | (0<<WGM00) |

                (0<<COM0A0) | (0<<COM0A1) | (0<<COM0B0) | (0<<COM0B1);

            // Normal mode, OC0A/B no output


  //Set Timer Counter Control Register B (TCCR0B)

// FOC0A FOC0B

//   0     0              ... TCCR0A, TCCR0B is written.

//  CS02 CS01 CS00

//   0    0    1     ...  No prescaling

//   0    1    0     ...  clki/o / 8

//   0    1    1     ...  clki/o / 64

//   1    0    0     ...  clki/o / 256

//   1    0    1     ...  clki/o / 1024

   TCCR0B = (0<<CS02) | (1<<CS01) | (0<<CS00) ; // Clock Prescale : Clki/o  / 8

    // 1 interrrupt = 2.048ms


    TIMSK |= (1<<TOIE0); // TIMER0 interrupt enable

}


volatile unsigned long TCOUNTER = 0; // Timer 0 Counter

#define TC500MS 25

#define TC2S 1000


ISR(TIMER0_OVF_vect)

{

    TCOUNTER++;

}


void waitms(volatile unsigned long t)

// Pause Execution about t[ms]

{

    volatile unsigned long limit;

    limit = t / 2;

    TCOUNTER = 0;

    while (TCOUNTER < limit);

}


enum LED {ON, OFF};

enum BOOLEAN {FALSE, TRUE};


int main(void)

{

int i, j;

    unsigned int flag_light, flag_analog_in;

    

// Initialize I/O Port

DDRB = (1<<PB3) | (1<<PB0); // PB0: Output mode


// Initialize TIMER0

    init_timer0();

    //Enable Interrupt

    sei();

    

for (i = 0; i < 3; i++) {

led_on(); waitms(100);

for ( j = 0; j < 500; j++) { buz(); wait(5); }

led_off(); waitms(100);

}


DDRB &= ~(1<<PB0); // PB0: Input mode

led_on();   flag_light = ON;


while (1) {

        

        switch (flag_light) {

            case OFF:

                // Light OFF -> ON

                // When Input Signal is H->L->H, LED light on.

                if (is_analog_in()) {

                    waitms(500);

                    flag_analog_in = FALSE;

                    TCOUNTER = 0;

                    while (TCOUNTER < TC500MS) {

                        if (is_analog_in()) {

                            flag_analog_in = TRUE;

                            break;

                        }

                    }

                    if (flag_analog_in == FALSE) {

                        TCOUNTER = 0;

                        while (TCOUNTER < TC2S) {

                            if (is_analog_in()) {

                                for (i = 150; i > 0; i--) {buz(); led(); wait(i); }

                                led_on(); flag_light = ON;

                                waitms(1000);

                                break;

                            }

                        }

                    }

                }

                break;

            case ON:

                // Light ON -> OFF

                // When Input Signal is detected, LED light on.

                if (is_analog_in()) {

                    for (j = 1; j < 5; j++) {

                        for (i = j * 100; i > 0; i--) {

                             buz();

                             wait(5);

                         }

                         led();

                    }

                    led_off(); flag_light = OFF;

                    waitms(1000);

                }

                break;

            default :

                led_off();  flag_light = OFF;

        }

}

return 0;

}


(Rev.1 単純に吹いたとき消灯、次に吹くと点灯)
// Analog comparator test
// TARGET : ATTINY2313
// AIN1 : Resistor
// AIN0 ( PB0 ) : Piezo speaker
// PB3 : LED (0:ON, 1:OFF)

#include <avr/io.h>

#define led_off() ( PORTB |= (1<<PB3) )
#define led_on() ( PORTB &= ~(1<<PB3) )
#define led() ( PINB |= (1<<PB3) )
#define buz() ( PINB |= (1<<PB0) )


#define is_analog_in() ( ACSR & (1<<ACO) ) // Analog Comparator Output

void wait(volatile long i)
{
while (i-- > 0);
}


int main(void)
{
int i, j;
// Initialize I/O Port
DDRB = (1<<PB3) | (1<<PB0); // PB0: Output mode
for (i = 0; i < 3; i++) {
led_on(); wait(5000);
for ( j = 0; j < 1000; j++) { buz(); wait(10); }
led_off(); wait(5000);
}

DDRB &= ~(1<<PB0); // PB0: Input mode
led_on();

while (1) {
if (is_analog_in()) {
led();
wait(10000);
}
}
return 0;
}

Makefile (AVR-GCC (Linux, OS X Cross-Pack) 用)

# AVR-GCC Makefile
PROJECT=anacmp-2313
SOURCES=$(PROJECT).c
CC=avr-gcc
OBJCOPY=avr-objcopy
MMCU=attiny2313
TARGETDEV=t2313

CFLAGS=-mmcu=$(MMCU) -Wall

$(PROJECT).hex: $(PROJECT).out
$(OBJCOPY) -j .text -O ihex $(PROJECT).out $(PROJECT).hex

$(PROJECT).out: $(SOURCES)
$(CC) $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program: $(PROJECT).hex
sudo avrdude -p $(TARGETDEV) -P usb -c avrispmkII -e -U flash:w:$(PROJECT).hex
clean:
rm -f $(PROJECT).out
rm -f $(PROJECT).hex

ċ
mbc06-blow-out-led-2313-rev2.zip
(3k)
kaimu nantai,
2012/11/22 21:18
ċ
mbc06-blow-out-led.zip
(297k)
kaimu nantai,
2012/11/10 19:29
Comments