Nejsem nějak spokojen s rozlišením AD převodu.
Jako desetibitový by měl na 27V dávat rozlišení 0.02V, v reálu (po snížení děličem) mi to rozlišení ale přijde výrazně hrubší.
Používám referenci 2.56V s kondenzátorem - viz schéma.
// vstupní dělič:
// Vbat-R1-Vin-R2-//
// Vref = 2.56V
// ADC = Vin * 1024 / Vref
#include<avr/io.h>
#define F_CPU 16500000UL
void adc_setup()
{
DDRB|=(1<<PB1);
TCCR0A=0x00; //Timer0 normal mode
TCCR0B=0x00;
TCCR0B |= (1<<CS00)|(1<<CS02); //prescaling with 1024
TCNT0=0;
ADCSRA|=(1<<ADEN); //Enable ADC module
ADMUX=0x11010001; // configuring PB2 to take input
ADCSRB|=1<<ADTS2; //Timer / Counter 0 overflow triggers the ADC to perform conversion
ADCSRA|=(1<<ADSC)|(1<<ADATE); //Enabling start of conversion and Auto trigger
// set port PB5 for reading
DDRB &= ~(1 << PB3); // Set the pin PB5 as input
PORTB |= (1 << PB3); //activate pull-up resistor for PB5
}
int main()
{
adc_setup();
while(1)
{
int adc_l = ADCL; //value of Input Voltage
int adc_val = (ADCH<<8)|adc_l; //Storing entire ADC value in a variable
bool is_switch = PINB & (1 << PB3); // The switch on PB3 disables the function (output is always OFF)
if (is_switch) {
if (adc_val>=640) //ON if not switch
PORTB|=(1<<PB1);
if (adc_val<=639) //OFF
PORTB &=~(1<<PB1);
}
else
PORTB &=~(1<<PB1);
TIFR|=(1<<TOV0); //Clearing overflow flag
}
}