bikegenerator/schaltungen/powerboard_v3/software/src/main.c

245 lines
5.2 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "utils.h"
#include "main.h"
#include "adc.h"
#include "uart.h"
enum states_t {
EX_ON,
EX_OFF,
Q_ON,
Q_OFF
} current_state;
enum opmode_t {
QUICK,
EXHAUST
} mode;
volatile uint16_t syscounter = 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;
}
static void timer_init(void) {
// clock is 8MHz
TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10) ; // CTC Mode for Timer 1 (16Bit) with prescale of 64
OCR1A = 1250; // 100Hz
TIMSK = _BV(OCIE1A);
sei();
}
static void ports_init(void) {
// set all switch port to output mode
DDR_SW |= _BV(LOADSW) | _BV(GENSW) | _BV(BATSW);
// set all ports to low
PORT_SW &= ~(_BV(LOADSW) | _BV(GENSW) | _BV(BATSW));
// set inputs
DDR_TP &= ~(_BV(TP1));
// enable pullups for inputs
PORT_TP |= _BV(TP1);
}
void measure(void) {
static int16_t temp;
u_r = adc_read_avg(AD_V_REG, 4);
u_r *= VOLTAGE_PER_TICK;
u_r += 790;
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;
i_g = temp * CURRENT_PER_TICK;
mode = (PIN_TP & TP1) ? EXHAUST : QUICK;
}
uint16_t get_power(uint16_t voltage, int16_t currents) {
return (voltage/100 * (currents/100)) / 100 ;
}
void pretty_print_all_values(void) {
uart_puts_P("u_r: ");
uart_print_uint16(u_r);
uart_puts_P("mV\r\n");
uart_puts_P("u_g: ");
uart_print_uint16(u_g);
uart_puts_P("mV\r\n");
uart_puts_P("i_g: ");
uart_print_uint16(i_g);
uart_puts_P("mA ");
uart_print_uint16(get_power(u_g, i_g));
uart_puts_P("W\r\n");
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");
}
static void work_uart(void) {
uint16_t uart_char = uart_getc();
if(uart_char != UART_NO_DATA) {
switch(uart_char & 0xff) {
case 'p':
pretty_print_all_values();
break;
case 'a':
uart_print_uint16(get_power(u_g, i_g));
uart_putc('\n');
break;
}
}
}
int main(void) {
ports_init();
adc_init();
timer_init();
uart_init(UART_BAUD_SELECT(38400,F_CPU));
while(1) {
work_uart();
if(syscounter >= 100) {
syscounter = 0;
measure();
//pretty_print_all_values();
statemachine_k2_k3();
}
}
return(0);
}
// system timer
SIGNAL(TIMER1_COMPA_vect) {
syscounter++;
//syscounter %= 60000;
}