Created
January 28, 2014 21:58
-
-
Save snilard/8677343 to your computer and use it in GitHub Desktop.
Ovládací SW k vyhřívaným vložkám do bot.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#define F_CPU 1000000UL | |
//----- Include Files --------------------------------------------------------- | |
#include <avr/io.h> // include I/O definitions (port names, pin names, etc) | |
#include <avr/sleep.h> | |
#include <avr/eeprom.h> | |
#include <avr/wdt.h> | |
#include <avr/interrupt.h> | |
#include <avr/power.h> | |
#include <util/delay.h> | |
#include <util/delay_basic.h> | |
//----- Begin Code ------------------------------------------------------------ | |
// dělička 39 kOhm + 10kOhm | |
// napětí * 20,4 = voltage | |
#define LED1 PB0 | |
#define LED2 PB2 | |
#define WIRE PB1 | |
#define VOLT_PIN PB3 | |
#define INTE_PIN PB4 | |
#define PWM_MAX 128 | |
#define PWM_CEIL 120 | |
#define INTENSITY_MIN 120 | |
#define INTENSITY_MAX 240 | |
#define INTENSITY_STEPS (INTENSITY_MAX - INTENSITY_MIN) | |
#define WANTED_MIN (60*60) | |
#define WANTED_MAX (140*140) | |
#define WANTED_STEPS (WANTED_MAX - WANTED_MIN) | |
#define LOW_VOLTAGE 137 // 6,7 V | |
#define WARNING_VOLTAGE 151 // 7,4 V | |
uint8_t voltage_load; | |
uint8_t voltage_no_load; | |
uint8_t intensity; | |
uint8_t pwm; | |
uint8_t counter; | |
uint8_t yellow; | |
//uint16_t mega_counter; | |
#ifdef LOGGING | |
uint16_t log_count = 0; | |
void log_init(void) { | |
log_count = eeprom_read_byte((uint8_t *) 126); | |
if (log_count > 0) { | |
uint8_t data = eeprom_read_byte((uint8_t *) log_count); | |
eeprom_write_byte((uint8_t *)log_count, data); | |
} | |
} | |
void log_byte(uint8_t data) { | |
if (log_count < 125) { | |
log_count++; | |
wdt_reset(); | |
eeprom_busy_wait(); | |
eeprom_write_byte((uint8_t *)log_count, data); | |
wdt_reset(); | |
eeprom_busy_wait(); | |
eeprom_write_byte((uint8_t *)126, log_count); | |
} | |
} | |
#endif | |
//initialize watchdog | |
void WDT_Init(void) { | |
//disable interrupts | |
cli(); | |
//reset watchdog | |
wdt_reset(); | |
//set up WDT interrupt | |
WDTCR = (1<<WDCE)|(1<<WDE); | |
//Start watchdog timer with 250ms prescaller | |
WDTCR |= (1<<WDIE)|(1<<WDE)|(1<<WDP2); | |
//Enable global interrupts | |
sei(); | |
} | |
ISR(WDT_vect) { | |
WDTCR |= (1<<WDIE); | |
} | |
void timer_init(void) { | |
power_timer0_enable(); | |
// disable global interrupts | |
cli(); | |
// Set to CTC Mode | |
TCCR0A = (1 << WGM01); | |
// set prescaler to 64 | |
TCCR0B = (1 << CS01)|(1 << CS00); | |
// init timer | |
TCNT0 = 0; | |
// set top 64/1000 * 100 = 1,9ms | |
OCR0A = 30; | |
//Set interrupt on compare match | |
TIMSK |= (1 << OCIE0A); | |
// enable interrupts | |
sei(); | |
} | |
ISR (TIM0_COMPA_vect) { | |
} | |
void sleep(void) { | |
cli(); | |
sleep_enable(); | |
sleep_bod_disable(); | |
sei(); | |
sleep_cpu(); | |
sleep_disable(); | |
} | |
void yellow_LED(void) { | |
PORTB |= (1<<LED1); | |
PORTB &= ~(1<<LED2); | |
} | |
void red_LED(void) { | |
PORTB |= (1<<LED2); | |
PORTB &= ~(1<<LED1); | |
} | |
void invert_yellow_LED(void) { | |
PORTB ^= (1<<LED1); | |
PORTB &= ~(1<<LED2); | |
} | |
void invert_red_LED(void) { | |
PORTB ^= (1<<LED2); | |
PORTB &= ~(1<<LED1); | |
} | |
void no_LED(void) { | |
PORTB &= ~((1<<LED1) | (1<<LED2)); | |
} | |
uint8_t measure_voltage(void) { | |
uint8_t volt; | |
power_adc_enable(); | |
// setup A/D convertor | |
ADMUX = (1<< REFS2) | (1<< REFS1) | (1<<MUX0) | (1<<MUX1) | (1 << ADLAR); // 2,56 V reference, no cap, PB3 | |
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // enable, 1:8 clock | |
ADCSRA |= (1<<ADSC); | |
while (! (ADCSRA & (1<<ADIF))); // wait for conversion complete | |
ADCSRA |= (1<<ADIF); | |
volt = ADCH; | |
ADCSRA &= ~(1<<ADEN); // disable converter to save power | |
power_adc_disable(); | |
return volt; | |
} | |
void measure_intensity(void) { | |
power_adc_enable(); | |
// setup A/D convertor | |
ADMUX = (1<< REFS2) | (1<< REFS1) | (1<<MUX1) | (1 << ADLAR); // 2,56 V reference, no cap, PB4 | |
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // enable, 1:8 clock | |
ADCSRA |= (1<<ADSC); | |
while (! (ADCSRA & (1<<ADIF))); // wait for conversion complete | |
ADCSRA |= (1<<ADIF); | |
intensity = ADCH; | |
ADCSRA &= ~(1<<ADEN); // disable converter to save power | |
power_adc_disable(); | |
} | |
void calculate_pwm(uint8_t volt) { | |
uint32_t wanted = 0; | |
if (intensity > INTENSITY_MIN) { | |
wanted = intensity - INTENSITY_MIN; | |
} | |
wanted *= WANTED_STEPS; | |
wanted /= INTENSITY_STEPS; | |
wanted += WANTED_MIN; | |
uint32_t power = volt * volt; | |
pwm = (uint8_t)(wanted * PWM_MAX / power); | |
if (pwm >= PWM_CEIL) { | |
pwm = PWM_CEIL; | |
} | |
} | |
int main(void) { | |
DDRB = (1<<LED1) | (1<<LED2) | (1<<WIRE); | |
PORTB &= ~((1<<LED1) | (1<<LED2) | (1<<WIRE)); | |
intensity = 0; | |
counter = 0; | |
voltage_no_load = 0; | |
voltage_load = 0; | |
pwm = 0; | |
yellow = 1; | |
//max_intensity = 255; | |
//mega_counter = 0; | |
power_all_disable(); | |
set_sleep_mode(SLEEP_MODE_IDLE); | |
#ifdef LOGGING | |
log_init(); | |
#endif | |
no_LED(); | |
/*uint8_t i = 0; | |
for (i = 0; i < 100; i++) { | |
_delay_ms(100); | |
} | |
log_byte(0); | |
log_byte(0); | |
log_byte(0);*/ | |
voltage_no_load = measure_voltage(); | |
measure_intensity(); | |
calculate_pwm(voltage_no_load); | |
//WDT_Init(); | |
timer_init(); | |
SREG |= (1<<7); // enable interrupts | |
while(1) { | |
counter++; | |
//mega_counter++; | |
//if (mega_counter >= 25000) { | |
// mega_counter = 0; | |
// log_byte(voltage_no_load); | |
//} | |
if (counter <= pwm) { | |
PORTB |= (1<<WIRE); | |
//yellow_LED(); | |
if (counter == pwm) { | |
voltage_load = measure_voltage(); | |
//log_byte(voltage); | |
} | |
} else { | |
PORTB &= ~(1<<WIRE); | |
//no_LED(); | |
} | |
if (counter >= PWM_MAX) { | |
counter = 0; | |
voltage_no_load = measure_voltage(); | |
measure_intensity(); | |
calculate_pwm(voltage_load); | |
if (voltage_no_load <= WARNING_VOLTAGE) { | |
yellow = 0; | |
} else { | |
yellow = 1; | |
} | |
if (voltage_no_load < LOW_VOLTAGE) { | |
break; | |
} | |
//log_byte(voltage); | |
} | |
//if (log_count >= 120) { | |
// red_LED(); | |
//} else | |
if (yellow) { | |
invert_yellow_LED(); | |
} else { | |
invert_red_LED(); | |
} | |
sleep(); | |
} | |
PORTB &= ~(1<<WIRE); | |
power_timer0_disable(); | |
WDT_Init(); | |
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | |
while(1) { | |
invert_red_LED(); | |
sleep(); | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment