first release of working firmware

This commit is contained in:
Lucas Pleß 2014-06-13 21:04:19 +02:00
parent 270696d654
commit 5e12e742ba
5 changed files with 129 additions and 60 deletions

Binary file not shown.

View File

@ -6,8 +6,8 @@ void adc_init(void) {
// AVCC with external capacitor at AREF pin // AVCC with external capacitor at AREF pin
ADMUX = _BV(REFS0); ADMUX = _BV(REFS0);
// set frequency prescaler to 8 // set frequency prescaler to 64
ADCSRA = _BV(ADPS1) | _BV(ADPS0); ADCSRA = _BV(ADPS2) | _BV(ADPS1);
// enable ADC // enable ADC
ADCSRA |= _BV(ADEN); ADCSRA |= _BV(ADEN);
@ -22,21 +22,22 @@ void adc_init(void) {
} }
uint16_t adc_read_single(uint8_t channel) { uint16_t adc_read_single(const uint8_t channel) {
ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F); // strip all MUX bits, keep the 3 msb (REFS1, REFS0, ADLAR)
ADCSRA |= _BV(ADSC); ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
while (ADCSRA & (1<<ADSC) ) { ADCSRA |= _BV(ADSC);
} while (ADCSRA & _BV(ADSC) ) {
return ADCW; }
return ADCW;
} }
uint16_t adc_read_avg(const uint8_t channel, const uint8_t nsamples) { uint16_t adc_read_avg(const uint8_t channel, const uint8_t nsamples) {
uint16_t sum = 0; uint16_t sum = 0;
uint8_t count = nsamples % 60; uint8_t count = nsamples % 60;
for (uint8_t i=0; i<count;++i ) { for (uint8_t i=0; i<count;++i ) {
sum += adc_read_single(channel); sum += adc_read_single(channel);
} }
return (sum / count); return (sum / count);
} }

View File

@ -6,12 +6,17 @@
#include "adc.h" #include "adc.h"
#include "uart.h" #include "uart.h"
enum states_t { enum states_k2k3 {
EX_ON, EX_ON,
EX_OFF, EX_OFF,
Q_ON, Q_ON,
Q_OFF Q_OFF
} current_state; } current_state_k2k3;
enum states_k1 {
G_ON,
G_OFF
} current_state_k1;
enum opmode_t { enum opmode_t {
QUICK, QUICK,
@ -31,9 +36,9 @@ uint16_t i_g = 0;
static void statemachine_k2_k3() { static void statemachine_k2_k3() {
enum states_t next; enum states_k2k3 next;
switch(current_state) { switch(current_state_k2k3) {
case EX_ON: case EX_ON:
if(mode == EXHAUST && (u_r <= UR_MIN || u_r >= UR_MAX)) { if(mode == EXHAUST && (u_r <= UR_MIN || u_r >= UR_MAX)) {
next = EX_OFF; next = EX_OFF;
@ -83,45 +88,91 @@ static void statemachine_k2_k3() {
} }
#ifdef DEBUG #ifdef DEBUG
uart_puts_P("state: "); if(current_state_k2k3 != next) uart_puts_P("new state: ");
uart_print_uint8
#endif #endif
switch(next) { switch(next) {
default: default:
case Q_OFF: case Q_OFF:
BAT_OFF; //BAT_OFF;
BAT_ON;
LOAD_OFF; LOAD_OFF;
#ifdef DEBUG #ifdef DEBUG
uart_puts_P("Q_OFF\r\n"); if(current_state_k2k3 != next) uart_puts_P("Q_OFF\r\n");
#endif #endif
break; break;
case Q_ON: case Q_ON:
BAT_OFF; //BAT_OFF;
BAT_ON;
LOAD_ON; LOAD_ON;
#ifdef DEBUG #ifdef DEBUG
uart_puts_P("Q_ON\r\n"); if(current_state_k2k3 != next) uart_puts_P("Q_ON\r\n");
#endif #endif
break; break;
case EX_OFF: case EX_OFF:
BAT_ON; BAT_ON;
LOAD_OFF; LOAD_OFF;
#ifdef DEBUG #ifdef DEBUG
uart_puts_P("EX_OFF\r\n"); if(current_state_k2k3 != next) uart_puts_P("EX_OFF\r\n");
#endif #endif
break; break;
case EX_ON: case EX_ON:
BAT_ON; BAT_ON;
LOAD_ON; LOAD_ON;
#ifdef DEBUG #ifdef DEBUG
uart_puts_P("EX_ON\r\n"); if(current_state_k2k3 != next) uart_puts_P("EX_ON\r\n");
#endif #endif
break; break;
} }
current_state = next; current_state_k2k3 = next;
} }
static void statemachine_k1() {
enum states_k1 next;
switch(current_state_k1) {
default:
case G_OFF:
if(u_g > UG_MIN && u_g < UG_MAX) {
next = G_ON;
} else {
next = G_OFF;
}
break;
case G_ON:
if(u_g <= UG_MIN || u_g > UG_MAX) {
next = G_OFF;
} else {
next = G_ON;
}
break;
}
#ifdef DEBUG
if(current_state_k1 != next) uart_puts_P("new state k1: ");
#endif
switch(next) {
default:
case G_OFF:
GEN_OFF;
#ifdef DEBUG
if(current_state_k1 != next) uart_puts_P("G_OFF\r\n");
#endif
break;
case G_ON:
GEN_ON;
#ifdef DEBUG
if(current_state_k1 != next) uart_puts_P("G_ON\r\n");
#endif
break;
}
current_state_k1 = next;
}
static void timer_init(void) { static void timer_init(void) {
// clock is 8MHz // clock is 8MHz
@ -148,20 +199,50 @@ static void ports_init(void) {
void measure(void) { void measure(void) {
static int16_t temp; static int16_t temp;
static uint32_t vtemp;
u_r = adc_read_avg(AD_V_REG, 4); // Regulator Voltage has a Voltage-Divider R1 = 56k, R2 = 27k
u_r *= VOLTAGE_PER_TICK; // U2 = U * ( R2 / (R1+R2) )
u_r += 790; // U = U2 / ( R2 / (R1+R2) )
// U = 5V / ( 27k / 83k ) = 15.37V -> Umax
// 27k / 83k = 0.3253
// ADC = (Ur * 0.325 * 1024) / 5V
// ADC = Ur * 66,56
// ADC = ( Ur * 10 * 1000 ) / 665 -> Ur in mV
vtemp = adc_read_avg(AD_V_REG, 20);
vtemp = vtemp * 10 * 1000;
u_r = vtemp / (665 - 1); // -1 to calibrate the resistors
u_r = u_r + 143; // 143 resistor offset
u_g = adc_read_avg(AD_V_GEN, 4);
u_g *= VOLTAGE_PER_TICK; // Generator Voltage has a Voltage-Divider R1 = 68k, R2 = 10k
// U2 = U * ( R2 / (R1+R2) )
// U = U2 / ( R2 / (R1+R2) )
// U = 5V / ( 10k / 78k ) = 39V -> Umax
// 10k / 78k = 0.128
// ADC = (Ur * 0.128 * 1024) / 5V
// ADC = Ur * 131,1 / 5V
// ADC = Ur * 26,2
// ADC = ( Ur * 10 * 1000 ) / 262 -> Ur in mV
vtemp = adc_read_avg(AD_V_GEN, 20);
vtemp = vtemp * 10 * 1000;
u_g = vtemp / (262 - 3); // -3 to calibrate the resistors
u_g = u_g + 85; // 85 resistor offset
temp = adc_read_avg(AD_I_GEN, 4);
temp -= CURRENT_OFFSET; temp = adc_read_avg(AD_I_GEN, 20);
temp -= 511; // substract Sensor offset (2,5V)
if(temp < 0) temp = 0; if(temp < 0) temp = 0;
i_g = temp * CURRENT_PER_TICK; //i_g = (temp * 151510) / 2048;
i_g = temp * (74 - 2);
if(i_g > 210) {
i_g = i_g - 210;
} else {
i_g = 0;
}
mode = (PIN_TP & TP1) ? EXHAUST : QUICK; mode = (PIN_TP & _BV(TP1)) ? QUICK : EXHAUST;
} }
uint16_t get_power(uint16_t voltage, int16_t currents) { uint16_t get_power(uint16_t voltage, int16_t currents) {
@ -184,11 +265,11 @@ void pretty_print_all_values(void) {
uart_puts_P("W\r\n"); uart_puts_P("W\r\n");
uart_puts_P("l,g,b: "); uart_puts_P("l,g,b: ");
uart_putc(48 + (IS_LOAD_ON >> LOADSW)); uart_putc(48 + IS_LOAD_ON);
uart_putc(','); uart_putc(',');
uart_putc(48 + (IS_GEN_ON >> GENSW)); uart_putc(48 + IS_GEN_ON);
uart_putc(','); uart_putc(',');
uart_putc(48 + (IS_BAT_ON >> BATSW)); uart_putc(48 + IS_BAT_ON);
uart_puts_P("\r\n"); uart_puts_P("\r\n");
} }
@ -228,7 +309,8 @@ int main(void) {
//pretty_print_all_values(); //pretty_print_all_values();
statemachine_k2_k3(); statemachine_k1();
statemachine_k2_k3();
} }
} }

View File

@ -26,24 +26,10 @@
#define BAT_ON PORT_SW |= _BV(BATSW) #define BAT_ON PORT_SW |= _BV(BATSW)
#define BAT_OFF PORT_SW &= ~_BV(BATSW) #define BAT_OFF PORT_SW &= ~_BV(BATSW)
#define IS_LOAD_ON (PIN_SW & _BV(LOADSW)) >> LOADSW #define IS_LOAD_ON ( (PIN_SW & _BV(LOADSW)) >> LOADSW )
#define IS_GEN_ON (PIN_SW & _BV(GENSW)) >> GENSW #define IS_GEN_ON ( (PIN_SW & _BV(GENSW)) >> GENSW )
#define IS_BAT_ON (PIN_SW & _BV(BATSW)) >> BATSW #define IS_BAT_ON ( (PIN_SW & _BV(BATSW)) >> BATSW )
#define GENERATOR 13000
#define GENERATOR_TIMEOUT 3
#define GENERATOR_OFF_TIMEOUT 1
#define UNDERVOLTAGE 11200
#define OVERVOLTAGE 15000
#define OVERVOLTAGE_TIMEOUT 5
#define OVERVOLTAGEOFF_TIMEOUT 3
#define UNDERVOLTAGE_TIMEOUT 5
#define UNDERVOLTAGEOFF_TIMEOUT 3
#define CURRENT_OFFSET 511
#define CURRENT_PER_TICK 72
#define VOLTAGE_PER_TICK 15
#endif #endif

View File

@ -3,7 +3,7 @@
extern void wait(uint8_t count); extern void wait(uint8_t count);
extern void uart_print_voltage(uint16_t); extern void uart_print_voltage(uint16_t);
extern void uart_print_uint8_t(uint8_t); extern void uart_print_uint8(uint8_t);
extern void uart_print_uint16(uint16_t); extern void uart_print_uint16(uint16_t);
#endif #endif