working on the powerboard firmware, added first draft of one state machine

This commit is contained in:
Lucas Pleß 2014-06-11 01:59:00 +02:00
parent b349c8c9ca
commit 270696d654
3 changed files with 139 additions and 141 deletions

View File

@ -67,7 +67,7 @@ static void work_uart() {
uart_puts_P(" -- \r\n");
#endif
if (cur == 13) { // \n
if (cur == 13 || cur == '\n') {
power = atol(data_in);
if(power > POWER_MAX) power = POWER_MAX;

View File

@ -6,49 +6,122 @@
#include "adc.h"
#include "uart.h"
enum states_t {
EX_ON,
EX_OFF,
Q_ON,
Q_OFF
} current_state;
/* ideensammlung für spätere implementierung:
*
* anstelle der vielen counter bauen wir zwei statemachines (gen/reg).
* states:
* generator_spannung_ok
* generator_überspannung
* generator_unterspannung
*
* regler_spannung_ok
* regler_überspannung
* regler_unterspannung
*
* eingänge:
* modeswitch
* reglerspannung
* generatorspannung
* gen_einaus
* reg_einaus
* bat_einaus
*
* ausgänge:
* relais_bat
* relais_gen
* relais_reg
*
*/
enum opmode_t {
QUICK,
EXHAUST
} mode;
volatile uint16_t syscounter = 0;
uint16_t voltage_reg = 0;
uint16_t voltage_gen = 0;
uint16_t current_gen = 0;
uint16_t u_r = 0;
uint16_t u_g = 0;
uint16_t i_g = 0;
#define UR_MIN 10900
#define UR_MAX 14500
#define UG_MIN 18000
#define UG_MAX 35000
static void statemachine_k2_k3() {
enum states_t next;
switch(current_state) {
case EX_ON:
if(mode == EXHAUST && (u_r <= UR_MIN || u_r >= UR_MAX)) {
next = EX_OFF;
} else if(mode == QUICK && (u_g > UG_MIN && u_g < UG_MAX)) {
next = Q_ON;
} else if(mode == QUICK && (u_g <= UG_MIN || u_g >= UG_MAX)) {
next = Q_OFF;
} else {
next = EX_ON;
}
break;
case EX_OFF:
if(mode == QUICK && (u_g <= UG_MIN || u_g >= UG_MAX)) {
next = Q_OFF;
} else if(mode == QUICK && (u_g > UG_MIN && u_g < UG_MAX)) {
next = Q_ON;
} else if(mode == EXHAUST && (u_r > UR_MIN && u_r < UR_MAX)) {
next = EX_ON;
} else {
next = EX_OFF;
}
break;
case Q_ON:
if(mode == EXHAUST && (u_r <= UR_MIN || u_r >= UR_MAX)) {
next = EX_OFF;
} else if(mode == EXHAUST && (u_r > UR_MIN && u_r < UR_MAX)) {
next = EX_ON;
} else if(mode == QUICK && (u_g <= UG_MIN || u_g >= UG_MAX)) {
next = Q_OFF;
} else {
next = Q_ON;
}
break;
default:
case Q_OFF:
if(mode == EXHAUST && (u_r <= UR_MIN || u_r >= UR_MAX)) {
next = EX_OFF;
} else if(mode == EXHAUST && (u_r > UR_MIN && u_r < UR_MAX)) {
next = EX_ON;
} else if(mode == QUICK && (u_g > UG_MIN && u_g < UG_MAX)) {
next = Q_ON;
} else {
next = Q_OFF;
}
break;
}
#ifdef DEBUG
uart_puts_P("state: ");
uart_print_uint8
#endif
switch(next) {
default:
case Q_OFF:
BAT_OFF;
LOAD_OFF;
#ifdef DEBUG
uart_puts_P("Q_OFF\r\n");
#endif
break;
case Q_ON:
BAT_OFF;
LOAD_ON;
#ifdef DEBUG
uart_puts_P("Q_ON\r\n");
#endif
break;
case EX_OFF:
BAT_ON;
LOAD_OFF;
#ifdef DEBUG
uart_puts_P("EX_OFF\r\n");
#endif
break;
case EX_ON:
BAT_ON;
LOAD_ON;
#ifdef DEBUG
uart_puts_P("EX_ON\r\n");
#endif
break;
}
current_state = next;
}
/*
uint8_t overvoltage_counter = 0;
uint8_t overvoltage_off_counter = 0;
uint8_t undervoltage_counter = 0;
uint8_t undervoltage_off_counter = 0;
uint8_t generator_counter = 0;
uint8_t generator_off_counter = 0;
*/
static void timer_init(void) {
// clock is 8MHz
@ -76,17 +149,19 @@ void measure(void) {
static int16_t temp;
voltage_bat = adc_read_avg(AD_V_BAT, 4);
voltage_bat *= VOLTAGE_PER_TICK;
voltage_bat += 790;
u_r = adc_read_avg(AD_V_REG, 4);
u_r *= VOLTAGE_PER_TICK;
u_r += 790;
voltage_gen = adc_read_avg(AD_V_GEN, 4);
voltage_gen *= VOLTAGE_PER_TICK;
u_g = adc_read_avg(AD_V_GEN, 4);
u_g *= VOLTAGE_PER_TICK;
temp = adc_read_avg(AD_I_GEN, 4);
temp -= CURRENT_OFFSET;
if(temp < 0) temp = 0;
current_in = temp * CURRENT_PER_TICK;
i_g = temp * CURRENT_PER_TICK;
mode = (PIN_TP & TP1) ? EXHAUST : QUICK;
}
uint16_t get_power(uint16_t voltage, int16_t currents) {
@ -94,89 +169,29 @@ uint16_t get_power(uint16_t voltage, int16_t currents) {
}
void pretty_print_all_values(void) {
uart_puts_P("Battery Voltage: ");
uart_print_uint16(voltage_bat);
uart_puts_P("u_r: ");
uart_print_uint16(u_r);
uart_puts_P("mV\r\n");
uart_puts_P("Generator Voltage: ");
uart_print_uint16(voltage_gen);
uart_puts_P("u_g: ");
uart_print_uint16(u_g);
uart_puts_P("mV\r\n");
uart_puts_P("Generator: ");
uart_print_uint16(current_in);
uart_puts_P("i_g: ");
uart_print_uint16(i_g);
uart_puts_P("mA ");
uart_print_uint16(get_power(voltage_bat, current_in));
uart_print_uint16(get_power(u_g, i_g));
uart_puts_P("W\r\n");
uart_puts_P("switches (load, gen): ");
uart_puts_P("l,g,b: ");
uart_putc(48 + (IS_LOAD_ON >> LOADSW));
uart_putc(',');
uart_putc(48 + (IS_GEN_ON >> GENSW));
uart_putc(',');
uart_putc(48 + (IS_BAT_ON >> BATSW));
uart_puts_P("\r\n");
}
void handle_over_and_undervoltage(void) {
/*
if(voltage_bat < UNDERVOLTAGE) {
undervoltage_off_counter = 0;
if(undervoltage_counter<UNDERVOLTAGE_TIMEOUT) undervoltage_counter++;
} else {
undervoltage_counter = 0;
if(undervoltage_off_counter<UNDERVOLTAGEOFF_TIMEOUT) undervoltage_off_counter++;
}
if(voltage_gen > GENERATOR) {
generator_off_counter = 0;
if(generator_counter<GENERATOR_TIMEOUT) generator_counter++;
} else {
generator_counter = 0;
if(generator_off_counter<GENERATOR_OFF_TIMEOUT) generator_off_counter++;
}
if(undervoltage_counter >= UNDERVOLTAGE_TIMEOUT) {
// spannung zu niedrig => abschalten
undervoltage_off_counter = 0;
LOAD_OFF;
} else {
// spannung ist okay
// ist die spannung schon lange genug okay?
if(undervoltage_off_counter >= UNDERVOLTAGEOFF_TIMEOUT) {
undervoltage_counter = 0;
// ja, also schauen ob der generator schon lange genug läuft
if(generator_counter >= GENERATOR_TIMEOUT) {
// ja, also einschalten
LOAD_ON;
} else {
// nein, generator nicht lange genug an
// ist er vielleicht schon lange aus?
if(generator_off_counter >= GENERATOR_OFF_TIMEOUT) {
// ja, also abschalten, egal ob akku okay
LOAD_OFF;
}
}
}
}
#ifdef DEBUG
uart_puts_P("ov1=");
uart_print_uint8(overvoltage_counter1);
uart_puts_P(" ovo1=");
uart_print_uint8 (overvoltage_off_counter1);
uart_puts_P("\r\n");
uart_puts_P("uv =");
uart_print_uint8(undervoltage_counter);
uart_puts_P(" uvo =");
uart_print_uint8(undervoltage_off_counter);
uart_puts_P("\r\n");
#endif
*/
}
static void work_uart(void) {
uint16_t uart_char = uart_getc();
@ -187,23 +202,8 @@ static void work_uart(void) {
pretty_print_all_values();
break;
case 'a':
uart_putc('A');
uart_print_uint16(voltage_bat);
uart_putc(',');
uart_print_uint16(current_in);
uart_putc(',');
uart_print_uint16(0);
uart_putc(',');
uart_print_uint16(get_power(voltage_bat, current_in));
uart_putc(',');
uart_print_uint16(0);
uart_putc(',');
uart_putc(48 + (IS_LOAD_ON));
uart_putc(',');
uart_putc(48 + (IS_BAT_ON);
uart_putc(',');
uart_putc(48 + (IS_GEN_ON));
uart_putc('B');
uart_print_uint16(get_power(u_g, i_g));
uart_putc('\n');
break;
}
}
@ -214,13 +214,13 @@ int main(void) {
ports_init();
adc_init();
timer_init();
uart_init(UART_BAUD_SELECT(19200,F_CPU));
uart_init(UART_BAUD_SELECT(38400,F_CPU));
//LOAD_OFF;
//GEN_ON;
//BAT_ON;
while(1) {
work_uart();
if(syscounter >= 100) {
syscounter = 0;
@ -228,10 +228,8 @@ int main(void) {
//pretty_print_all_values();
handle_over_and_undervoltage();
statemachine_k2_k3();
}
work_uart();
}
return(0);
@ -240,7 +238,7 @@ int main(void) {
// system timer
SIGNAL(TIMER1_COMPA_vect) {
syscounter++;
syscounter %= 60000;
//syscounter %= 60000;
}