AVRホタル
暗いところに持っていくと点滅します。
部品はtiny2313とLEDを1個ずつ。
LEDを光センサーとして使っています。
// AVR Hotaru #include <avr/io.h> //#include <avr/interrupt.h> #include <util/delay.h> #define nop() __asm__ __volatile__ ("nop") #define SERIAL_DEBUG 0 #if SERIAL_DEBUG #define BAUD 2400 //#define SET_PORT(PORT, MASK, VALUE) PORT = (VALUE & MASK)|((~MASK) & PORT) void usart_init(void) { #define _UBRR (F_CPU/16/BAUD-1) UBRRH = _UBRR>>8; UBRRL = _UBRR; UCSRB = 0b00011000; UCSRC = 0b00000110; } #endif #define LED_DEBUG 1 int main(void) { char ac0; int count = 0; int on_count = 0; int on_rate = 0; int i,j,k; int bright = 0; int led_on = 1; #if SERIAL_DEBUG usart_init(); #endif #if LED_DEBUG DDRD = 0b01111100; PORTD = 0b00000000; #endif for(;;){ // 参考) http://elm-chan.org/junk/leddet/report.html // LEDポートに短時間"L"レベルを出力して接合容量Cjや浮遊容量Csを放電する。 DDRB = 0b00000001; PORTB = 0b00000000; _delay_ms(1); // LEDポートを入力に設定する→光電流により容量が充電され、入力電圧が直線的に上昇してくる。 DDRB = 0b00000000; PORTB = 0b00000000; // 4ms待ってから入射有りか判断 _delay_ms(4); ac0 = ACSR & 0b00100000; if(ac0){ on_count++; } count++; if(50<=count){ on_rate = 100*on_count/count; // 50サンプル取って平均 count = 0; on_count = 0; } #if SERIAL_DEBUG while(!(UCSRA & 0b00100000)); UDR = ac0 ? '*' : '.'; #endif #if LED_DEBUG { unsigned char d = 0; if(on_rate<45){ d |= (1<<2); } if(on_rate<40){ d |= (1<<3); } if(on_rate<35){ d |= (1<<4); } if(on_rate<30){ d |= (1<<5); } if(on_rate<25){ d |= (1<<6); } PORTD = d; } #endif DDRB = 0b00000001; if(0){ // 閾値でON/OFF if(on_rate<20){ PORTB = 0b00000001; }else{ PORTB = 0b00000000; } _delay_ms(30); }else{ // 明るさ 0-100,100-0 のこぎり型に明滅 int b; bright++; b = bright; if(100<bright){ b = 200-bright; if(200<bright){ bright = 0; led_on = (on_rate<20); } } //b = 100-on_rate; for(j=0; j<10; j++){ if(led_on){ PORTB = 0b00000001; } for(i=0; i<b; i++){ _delay_ms(0.01); } PORTB = 0b00000000; for(i=0; i<100-b; i++){ _delay_ms(0.01); } } } } }