見出し画像

8Bitマイコンでイルミネーション

8Bitマイコン(ATtiny13a)と光センサーを使って、イルミネーションを作ってみた。
周りが暗くなると自動でスイッチON、明るくなると切れます。

ATtiny13aマイコンのプログラムメモリは 1kB です。 1GBでも1MBでもなく、1kB(1024バイト)です。
RAMは64バイト、コーディングは空きメモリーとの闘いでした。

実際に動作している動画です。


とりあえず、ソースコードです。

#include <avr/io.h>
#include <avr/interrupt.h>

#define _CNT 0xFF		// 10msカウンター

#define LEFTLEDPIN 7
#define RIGHTTLEDPIN 12

#define GREENPIN  0
#define BLUEPIN 1
#define REDPIN  2
#define LIGHTONVAL 2
#define LIGHTOFFVAL 6

#define AUTO_OFF_VAL 100000000 // 40分 * 10

// TIMER TABLE
//
volatile int timetable[5];

long		timecount = 0;		// イルミネーションONからの経過時間 タイマー割り込みごとにカウント
volatile unsigned int pwmpins[3];
volatile bool pwmpinOnOff[3];
volatile bool rightOnOff = true;

unsigned char AnalogRead8bit(unsigned char Ch)
{

	DIDR0
	= (0<<ADC0D)	
	| (0<<ADC1D)	
	| (1<<ADC2D)	
	| (0<<ADC3D);	

	ADMUX
	= (0<<REFS0)	
	| (1<<ADLAR)	
	| (Ch);		

	
	ADCSRA
	= (1<<ADEN)	
	| (1<<ADSC)	
	| (0<<ADATE)	
	| (0<<ADIF)	
	| (0<<ADIE)	
	| (0b100);	

	loop_until_bit_is_set(ADCSRA,ADIF);

	return ADCH;
}

void vpwm()
{
	for(int i=0; i<16; i++)
	{
		int pwm = 0;
		if ( ( pwmpins[GREENPIN] & (1 << i) ) > 0 )
		{
			pwm = 0b00000001;
		}
		if ( ( pwmpins[BLUEPIN] & (1 << i) ) > 0 )
		{
			pwm |= 0b00000010;
		}
		if ( ( pwmpins[REDPIN] & (1 << i) ) > 0 )
		{
			pwm |= 0b00000100;
		}
		PORTB = pwm;
	}
	
}


ISR(TIM0_OVF_vect)
{
	for(int i=0; i < 5; i++)
	{
		if ( timetable[i] > 0 )
		timetable[i]--;
	}
	timecount++;
	
	vpwm();

	TCCR0B = 0x02;
	TCNT0 = _CNT;
}


int main(void)
{
	cli();
	
	TCNT0 = _CNT;
	TCCR0B = 0x01;
	TIMSK0 = (1<<TOIE0);
	
	sei();							// 割り込み許可

	DDRB =  (1<<PB2) | (1<<PB1)| (1<<PB0);			// 出力に設定します。
	PORTB = (1<<DDB2)| (1<<DDB1) | (1<<DDB0);		// 'H'を出力します。

	PORTB ^= 0b00001111;              // 'L'


	pwmpins[GREENPIN] = 0xffff;
	pwmpins[BLUEPIN] = 0xfff0;
	pwmpins[REDPIN] = 0xff00;
	
	pwmpinOnOff[GREENPIN] = true;
	pwmpinOnOff[BLUEPIN] = true;
	pwmpinOnOff[REDPIN] = true;
	while(1)
	{
		unsigned char ana = AnalogRead8bit(2) ;
		if( ana < LIGHTONVAL || (rightOnOff == true && ana < LIGHTOFFVAL))
		{
			if ( timecount > AUTO_OFF_VAL)
			{
				TIMSK0 = 0;
				PORTB = 0b00000111;              // 'L'
				continue;
			}
			TIMSK0 = (1<<TOIE0);
			
			rightOnOff = true;
			for(int i=0; i<3; i++)
			{
				if ( timetable[i] <= 0 )
				{
					if ( pwmpinOnOff[i] )
					{
						pwmpins[i]	= (pwmpins[i] << 1) ;
					}
					else
					{
						pwmpins[i]	= (pwmpins[i] >> 1) | 0x8000 ;
					}
					unsigned int rdata = AnalogRead8bit(3) ;
					unsigned int p = rdata % 3;
					timetable[p] = rdata * 2 + 1000;
				}
				if ( pwmpins[i] == 0 )
				{
					pwmpinOnOff[i] = false;
				}
				else if ( pwmpins[i] == 0xffff)
				{
					pwmpinOnOff[i] = true;
				}
			
			}
		}
		else
		{
			TIMSK0 = 0;
			PORTB = 0b00000111;              // 'L'
			rightOnOff = false;
			timecount = 0;			// タイムトータルカウントリセット
		}
	}
	return 0;
}


Task "RunOutputFileVerifyTask"
		Program Memory Usage 	:	782 bytes   76.4 % Full
		Data Memory Usage 	:	25 bytes   39.1 % Full

この記事が気に入ったらサポートをしてみませんか?