AVR GCC Attiny Sensor Modules


#define F_CPU 1000000L

#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

// global variables

const uint16_t pwmtable_8D[32]  PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11,
                                    13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76,
                                    91, 108, 128, 152, 181, 215, 255};

int16_t tmp = 0;
int16_t step_time=100;      // delay in millisecond for one fading step
uint16_t result = 0; // Analog Input Value

// long delays

void my_delay(uint16_t milliseconds) {
    for(; milliseconds>0; milliseconds--) _delay_ms(1);
}

// 8-Bit PWM with 32 different settings

void pwm_8_32_up(uint16_t delay){

 if (tmp<=0)
{	
  for(tmp=0; tmp<=31; tmp++){
      OCR0B = pgm_read_word(pwmtable_8D+tmp);
      my_delay(delay);
    }
}

}

void pwm_8_32_down(uint16_t delay){

if (tmp>=31)
{
     for(tmp=31; tmp>=0; tmp--){
      OCR0B = pgm_read_word(pwmtable_8D+tmp);
      my_delay(delay);
    }
}

}

uint16_t readADC(uint8_t channel) {
	uint8_t i;
	uint16_t result = 0;

	// Den ADC aktivieren und Teilungsfaktor auf 64 stellen
	ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

	// Kanal des Multiplexers waehlen
	// Interne Referenzspannung verwenden (also 2,56 V)
	ADMUX = channel | (1<<REFS0);

	// Den ADC initialisieren und einen sog. Dummyreadout machen
	ADCSRA |= (1<<ADSC);
	while(ADCSRA & (1<<ADSC));

	// Jetzt 3x die analoge Spannung and Kanal channel auslesen
	// und dann Durchschnittswert ausrechnen.
	for(i=0; i<3; i++) {
		// Eine Wandlung
		ADCSRA |= (1<<ADSC);
		// Auf Ergebnis warten...
		while(ADCSRA & (1<<ADSC));

		result += ADCW;
	}

	// ADC wieder deaktivieren
	ADCSRA &= ~(1<<ADEN);

	result /= 3;

	return result;
}


int main(void)
{

    DDRB |= (1<<PB1);           // LED uses OC0B
    DDRB |= (1<<PB2);           // IR LED uses PB2

    PORTB = (1<<PB2);           // IR LED on

    // PWM Init
    TCCR0A=0xA3;
    TCCR0B=0x02; 

    while(1) {

        result = readADC(3);	//Auslesen der analogen Spannungen an Pin 3

	if (result > 240)
	{
	    pwm_8_32_up(step_time/8);
	}
	else
	{
	    pwm_8_32_down(step_time/8);
	}
    };

    return 0;
}