ブレッドボードチャレンジ! 2013
【BC2013-001】衝撃センサ付きLEDマーカ&近接感知ブザー(ATTiny26/861)
概要
・マイコン工作の第一歩といえば、LEDピカピカ……LEDを点滅させる回路だ。次の一歩は、A/Dコンバータで、センサに反応してLEDが光る回路だろうか。
・久しぶりに、フツーのサイズ(小さい方のカテゴリに分類されると思うが……)のブレッドボードで、マイコン工作の第二歩のための回路を紹介しよう。
・起動時の明るさをフォトトランジスタで検出し、明るいときと暗いときで動作を切り替えてみた。
・起動時、周囲が明るい場合…ブザーの鳴動が光センサの明るさで変わる。センサに手を近づけて暗くするほど、ブザーの鳴る間隔が短くなる。
・起動時、周囲が暗い場合…LEDが高速に点滅する。このとき、ブザー(圧電サウンダ)を叩いたり、息を吹きかけたりして衝撃を与えると、ブザが鳴った後でLEDが短い間消灯する。
使用部品
AVRマイコン ATTiny26L/261/861
カーボン抵抗器 100kΩ、10kΩ、150Ω
フォトトランジスタ NJL7502L
圧電スピーカ SPT08-Z185
LED 5mmφ
ブレッドボード
電池ボックス 単3×2本用、バッテリースナップタイプ
バッテリースナップ
回路図
※TINY26Lは、ATTINY261やATTINY861に置き換えることができる。
実体配線図
※ATTINY26Lは、ATTINY261やATTINY861に置き換えることができる。
ファームウェア (AVR-GCC用)
#ATtiny26L用
// ATTINY26
// ADC0 : A-D Convertor Input
// PA7(ADC6) : Speaker
// PB5 : LED1 1:ON 0:OFF
#include <avr/io.h>
#define
led_on()
PORTB |= (1<<PB5)
#define
led_off()
PORTB &= ~(1<<PB5)
#define
led()
PORTB ^= (1<<PB5)
#define buz()
PORTA ^= (1<<PA7);
#define buz_off()
PORTA &= ~(1<<PA7);
#define MODE_TERUMEEN
0x00
#define MODE_CANDLE
0xff
#define buz_output_mode()
DDRA |= (1<<PA7)
#define buz_input_mode()
DDRA &= ~(1<<PA7)
volatile char mode = MODE_TERUMEEN; // Mode Switch
void wait(volatile long i)
{
while (i-- > 0);
}
int adconv0(void)
/* AD Convertor */
{
int adata;
ADCSR |= (1<<ADEN) | (1<<ADSC); // A-D convertor enable,
ADMUX = (1<<ADLAR) | 0x00; /* ADLAR=1, ADC0 SingleEndedInput */
while ( !(ADCSR & (1<<ADIF)) );
adata = ADCH;
ADCSR &=~(1<<ADIF);
return adata;
}
int adconv6(void)
/* AD Convertor */
{
int adata;
buz_input_mode();
ADCSR |= (1<<ADEN) | (1<<ADSC); // A-D convertor enable,
ADMUX = (1<<ADLAR) | 0x06; /* ADLAR=1, ADC6 SingleEndedInput */
while ( !(ADCSR & (1<<ADIF)) );
adata = ADCH;
ADCSR &=~(1<<ADIF);
return adata;
}
void beep(void)
{
volatile int i, j;
buz_output_mode();
for ( i = 0; i < 10; i++ ) {
for (j = 0; j < 100; j++) {
buz(); wait(5);
}
buz_off(); wait(1000);
}
}
int main(void)
{
unsigned int adc, i;
// Initialize I/O Port
DDRB = (1<<PB3) | (1<<PB5);
for ( i = 0 ; i < 5; i++ ) {
led_on();
wait(3000);
led_off();
wait(3000);
}
adc = adconv0();
if ( adc > 0x40 ) {
buz_input_mode();
mode = MODE_CANDLE;
} else {
buz_output_mode();
mode = MODE_TERUMEEN;
}
while (1)
{
switch (mode) {
case MODE_TERUMEEN:
DDRA |= (1<<PA7);
adc = adconv0();
adc = 0xff - adc;
led_on();
for ( i = 0; i < (adc>>1); i++) {
buz();
wait(adc);
}
led_off();
wait(adc * 100);
break;
default:
led();
wait(100);
adc = adconv6();
if (adc > 0x03) {
led_off();
beep();
wait(200000);
}
}
}
return 0;
}
#ATtiny261/861用
// ATTINY261/861
// ADC0 : A-D Convertor Input
// PA7(ADC6) : Speaker
// PB5 : LED1 1:ON 0:OFF
#include <avr/io.h>
#define
led_on()
PORTB |= (1<<PB5)
#define
led_off()
PORTB &= ~(1<<PB5)
#define
led()
PORTB ^= (1<<PB5)
#define buz()
PORTA ^= (1<<PA7);
#define buz_off()
PORTA &= ~(1<<PA7);
#define MODE_TERUMEEN
0x00
#define MODE_CANDLE
0xff
#define buz_output_mode()
DDRA |= (1<<PA7)
#define buz_input_mode()
DDRA &= ~(1<<PA7)
volatile char mode = MODE_TERUMEEN; // Mode Switch
void wait(volatile long i)
{
while (i-- > 0);
}
int adconv0(void)
/* AD Convertor */
{
int adata;
ADCSRA |= (1<<ADEN) | (1<<ADSC); // A-D convertor enable,
ADMUX = (1<<ADLAR) | 0x00; /* ADLAR=1, ADC0 SingleEndedInput */
while ( !(ADCSRA & (1<<ADIF)) );
adata = ADCH;
ADCSRA &=~(1<<ADIF);
return adata;
}
int adconv6(void)
/* AD Convertor */
{
int adata;
buz_input_mode();
ADCSRA |= (1<<ADEN) | (1<<ADSC); // A-D convertor enable,
ADMUX = (1<<ADLAR) | 0x06; /* ADLAR=1, ADC6 SingleEndedInput */
while ( !(ADCSRA & (1<<ADIF)) );
adata = ADCH;
ADCSRA &=~(1<<ADIF);
return adata;
}
void beep(void)
{
volatile int i, j;
buz_output_mode();
for ( i = 0; i < 10; i++ ) {
for (j = 0; j < 100; j++) {
buz(); wait(5);
}
buz_off(); wait(1000);
}
}
int main(void)
{
unsigned int adc, i;
// Initialize I/O Port
DDRB = (1<<PB3) | (1<<PB5);
for ( i = 0 ; i < 5; i++ ) {
led_on();
wait(3000);
led_off();
wait(3000);
}
adc = adconv0();
if ( adc > 0x40 ) {
buz_input_mode();
mode = MODE_CANDLE;
} else {
buz_output_mode();
mode = MODE_TERUMEEN;
}
while (1)
{
switch (mode) {
case MODE_TERUMEEN:
DDRA |= (1<<PA7);
adc = adconv0();
adc = 0xff - adc;
led_on();
for ( i = 0; i < (adc>>1); i++) {
buz();
wait(adc);
}
led_off();
wait(adc * 100);
break;
default:
led();
wait(100);
adc = adconv6();
if (adc > 0x03) {
led_off();
beep();
wait(200000);
}
}
}
return 0;
}