【MBC-08】PICでつくる息で吹き消せるLED

概要

息で吹き消せるLED

・息を吹きかけると点灯していたLEDが消えてしまう!ロウソクのようなLEDランプをPICマイコンでつくってみました。

・通常、圧電サウンダは電気信号により圧電素子を振動させて音を鳴らす部品として使います。本機では、この圧電サウンダを、息のセンサとして使ってみました。息で振動させた圧電素子に生じる電気信号を取り出します。

・圧電サウンダからの電気信号は、マイコンのAD変換回路を通じて、マイコンに入力されます。マイコンが信号を受け取ったと判断すると、LEDを消灯するようなプログラムになっています。

・回路図やファームウェアのソース、バイナリ(Hex)ファイルは、添付ファイルを参照してください。

使用部品

PICマイコン Microchip社製 PIC12F1822

LED

カーボン抵抗器 150Ω, 10kΩ

圧電サウンダ他励振 PKM13EPYH4000-A0

バッテリースナップ

電池ボックス 単3×2本用(プログラムの書込み時は、NiMH電池3〜4本使用)

ミニブレッドボード BB-601

部品

回路図

回路図

実体配線図

実体配線図

ファームウェア(MPLAB XC8 コンパイラ用)

Version 2

・(1) 電源を入れると、ブザが鳴る。

・(2) プログラムで設定した間隔でLEDが点滅する。

・(2) 息を吹きかける(振動を与える)と音をたてて、LEDが点滅しながら消灯する。

・(3) 次に振動を与えると、(2)に戻る。

/*
 * File:   blow-out-led-12f1822.c
 * Author: kaimu
 *
 * Created on 2013/04/13, 16:15
 */
#include <xc.h>
#define led()       ( RA4 ^= 1 )
#define led_on()    ( RA4 = 0 )
#define led_off()    ( RA4 = 1 )
#define buz()       ( RA1 ^= 1 )
__CONFIG(
        FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF
        & CPD_OFF & BOREN_ON & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF
);
//__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_HI & LVP_OFF); // VDD High
__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_LO & LVP_OFF); // VDD LOW
#define ON  1
#define OFF 0
volatile char FLAG_LIGHT = OFF;
void wait(volatile unsigned long t)
// Delay
{

while(t-- > 0) NOP();

}
unsigned char adc(void)
{
    unsigned char d;
    //ADC
    wait(10);
    GO_nDONE = 1;
    while (GO_nDONE);
    d = ADRESH;
    return d;
}
volatile unsigned int T0COUNTER = 0; // Counter for Timer0 Interrupt
void interrupt intr(void) {
    if (T0IF) {
        // Timer 0 Interrupt
        T0IF = 0; // Clear Timer0 interrupt flag
        T0COUNTER++;
    }
}
void main(void)
{
    volatile unsigned long i, j;
    unsigned char d;
    //Initialization
    OSCCON = 0b01101010; // PLL disable, 4MHz internal clock
    //OSCCON = 0b00111010; // PLL disable, 500kHz internal clock

GIE = 0; //Interrupt disable

    ANSELA = 0b00000010;         //RA1 Analog port, others digital port
    ADCON0 = 0b00000101;    //0:unimp, 000001:AN1, 0:GOnDone, 1:ADC enable
    ADCON1 = 0b01000000;    //0:Left jutified (8bit res.), 100:Fosc/4 ,0:Reserved, 00:AVDD=VREF
    CM1CON0 = 0x00;     //Comparator disable

// 76543210

TRISA = 0b00001010; //I/O Direction. RA0,2,4-5 : output, RA1,3 : Input

LATA = 0b00001100; // PORTA Latch Settings

    // Timer0 Settings
    //OPTION_REG = 0xc7; // Prescaler 1:256, Intterupt on rising edge
    OPTION_REG = 0xc3; // Prescaler 1:16, Intterupt on rising edge
    //OPTION_REG = 0xc1; // Prescaler 1:4, Intterupt on rising edge
    //OPTION_REG = 0xc2; // Prescaler 1:8, Intterupt on rising edge
    TMR0 = 0x00;
    T0IE = 1; // Timer 0 interrupt enable
    GIE = 1; // General interrupt enable
    // Start up LED Blinking
    TRISA1 = 0; // RA1 Output mode
    for (i = 20; i > 0; i--) {
        for (j = 0; j <= 100; j++) { led(); buz();  wait(5); }
        for (j = 0; j < 100; j++) { wait(10); }
    }
    TRISA1 = 1; // RA1 Input mode
    led_on();
    FLAG_LIGHT = ON;
    while(1){
        d = adc();
        switch (FLAG_LIGHT) {
            case ON:
                if ( d > 3 ) {
                   TRISA1 = 0; // RA1 Output mode
                   for (i = d<<1 ; i > 0; i--) {
                         led();
                         for (j = 0; j <= 50; j++) { buz(); wait(40); }
                   }
                   led_off();
                   FLAG_LIGHT = OFF;
                   wait(10000);
                   TRISA1 = 1; // RA1 Input mode
                } else {
                    if (T0COUNTER < 0x80) {
                        led_on();
                    } else if (T0COUNTER < 0xff) {
                        led_off();
                    } else {
                        T0COUNTER = 0x00;
                    }
                }
                break;
            case OFF:
                if ( d > 8 ) {
                   TRISA1 = 0; // RA1 Output mode
                   for (i = d ; i > 0; i--) {
                         for (j = 0; j <= 50; j++) { buz(); led(); wait(10); }
                   }
                   TRISA1 = 1; // RA1 Input mode
                   led_on();
                   FLAG_LIGHT = ON;
                   wait(10000);
                } else {
                    led_off();
                }
                break;
        }
    }
}

Version 1

/*
 * File:   blow-out-led-12f1822.c
 * Author: kaimunantai
 *
 * Created on 2012/11/27, 18:45
 */
#include <xc.h>
#define led()       ( RA4 ^= 1 )
#define led_on()    ( RA4 = 0 )
#define buz()       ( RA1 ^= 1 )
__CONFIG(
        FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF
        & CPD_OFF & BOREN_ON & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF
);
//__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_HI & LVP_OFF); // VDD High
__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_LO & LVP_OFF); // VDD LOW
void wait(volatile unsigned long t)
// Delay
{

while(t-- > 0) NOP();

}
unsigned char adc(void)
{
    unsigned char d;
    //ADC
    wait(10);
    GO_nDONE = 1;
    while (GO_nDONE);
    d = ADRESH;
    return d;
}
void main(void)
{
    volatile unsigned long i, j;
    unsigned char d;
    //Initialization
    OSCCON = 0b01101010; // PLL disable, 4MHz internal clock
    //OSCCON = 0b00111010; // PLL disable, 500kHz internal clock

GIE = 0; //Interrupt disable

    ANSELA = 0b00000010;         //RA1 Analog port, others digital port
    ADCON0 = 0b00000101;    //0:unimp, 000001:AN1, 0:GOnDone, 1:ADC enable
    ADCON1 = 0b01000000;    //0:Left jutified (8bit res.), 100:Fosc/4 ,0:Reserved, 00:AVDD=VREF
    CM1CON0 = 0x00;     //Comparator disable

// 76543210

TRISA = 0b00001010; //I/O Direction. RA0,2,4-5 : output, RA1,3 : Input

LATA = 0b00001100; // PORTA Latch Settings

    // Start up LED Blinking
    TRISA1 = 0; // RA1 Output mode
    for (i = 3; i > 0; i--) {
        for (j = 0; j <= 100; j++) { led(); buz();  wait(5); }
        for (j = 0; j < 100; j++) { wait(10); }
    }
    TRISA1 = 1; // RA1 Input mode
    led_on();
    
    while(1){
        d = adc();
        if ( d > 2 ) {
           TRISA1 = 0; // RA1 Output mode
           for (i = 3; i > 0; i--) {
                 for (j = 0; j <= 100; j++) { buz(); led(); wait(d); }
           }
            wait(10000);
            TRISA1 = 1; // RA1 Input mode
        }
    }
}