diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -9,7 +9,9 @@ #include "watchdog.h" #include "system.h" +#include "display.h" #include "gpio.h" +#include "pid.h" #include "error.h" #include "flash.h" #include "ssd1306.h" @@ -17,16 +19,27 @@ #include "interrupts.h" #include "buttons.h" + +therm_settings_t set; +therm_status_t status; +pid_state_t pid_state; + + int main(void) { sysclock_init(); hal_init(); gpio_init(); + + ssd1306_init(); + + // Startup screen + display_startup_screen(); + HAL_Delay(2000); + ssd1306_drawlogo(); - ssd1306_clearscreen(); - flash_init(); watchdog_init(); //just some example code for getting flash values @@ -37,28 +50,172 @@ int main(void) // ssd1306_drawstring(const char *dataPtr, unsigned char row, unsigned char xPos) // ssd1306_drawstring("[ ProtoFuse ]", 0, 0); + // Default status + status.temp = 0; + status.temp_frac = 0; + status.state_resume = 0; + status.state = STATE_IDLE; + status.setpoint = 70; + status.pid_enabled = 0; + + pid_init(&pid_state); + + flash_init(); + + float temp_counter = 0; // Software timers uint32_t last_screen_update_time = HAL_GetTick(); + // Soft timers + uint32_t last_ssr_on = 0; + uint32_t last_vcp_tx = 0; + uint32_t last_led = 0; + uint32_t last_pid = 0; + uint32_t last_thermostat = 0; + int16_t ssr_output = 0; // Duty cycle of ssr, 0 to SSR_PERIOD + uint8_t thermostat_plant_on = 0; + + while (1) { - // function that checks all the buttons - freaking_debounce(); + + if(set.val.control_mode == MODE_PID && (HAL_GetTick() - last_pid > PID_PERIOD)) + { + +// #ifdef MAX31865_RTD_SENSOR +// max31865_readtemp(spi_get(), &set, &status); +// #else +// max31855_readtemp(spi_get(), &set, &status); // Read MAX31855 +// #endif + + + if(status.pid_enabled) + { + // Get ssr output for next time + int16_t power_percent = pid_update(&set, &status, &pid_state); + + if(set.val.plant_type == PLANT_HEATER) + power_percent *= -1; + + //power-percent is 0-1000? + ssr_output = power_percent; //(((uint32_t)SSR_PERIOD * (uint32_t)10 * (uint32_t)100) * power_percent) / (uint32_t)1000000; + + + // put ssr output on display + ssd1306_drawstring(" ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise + char tempstr[6]; + itoa(ssr_output, tempstr, 10); + ssd1306_drawstring(tempstr, 0, 90); + } + else + { + ssr_output = 0; + } + + last_pid = HAL_GetTick(); + } + +// // Kill SSR once the desired on-time has elapsed +// if(set.val.control_mode == MODE_PID && (HAL_GetTick() - last_ssr_on > ssr_output || ssr_output <= 0)) +// { +// HAL_GPIO_WritePin(SSR_PIN, 0); +// HAL_GPIO_WritePin(LED_POWER, 0); +// } +// +// +// // Every 200ms, set the SSR on unless output is 0 +// if(set.val.control_mode == MODE_PID && HAL_GetTick() - last_ssr_on > SSR_PERIOD) +// { +// // Heat or cool, if we need to +// if(ssr_output > 0) +// { +// HAL_GPIO_WritePin(SSR_PIN, 1); +// HAL_GPIO_WritePin(LED_POWER, 1); +// last_ssr_on = HAL_GetTick(); +// } +// else { +// // Make sure everything is off +// HAL_GPIO_WritePin(SSR_PIN, 0); +// HAL_GPIO_WritePin(LED_POWER, 0); +// } +// +// } + + + // Thermostatic control + if(set.val.control_mode == MODE_THERMOSTAT && HAL_GetTick() - last_thermostat > SSR_PERIOD) + { - // Grab and transmit data - if(HAL_GetTick() - last_screen_update_time > 100) - { - HAL_GPIO_TogglePin(LED_GPIO_Port, LED_PIN); - char buffer[256]; - snprintf(buffer, 256, "Counter: %.1f", temp_counter); - ssd1306_drawstring(buffer, 3, 10); - ssd1306_drawstring("Therm Next Generation", 0, 0); - temp_counter = temp_counter + 0.1; - last_screen_update_time = HAL_GetTick(); - } +// #ifdef MAX31865_RTD_SENSOR +// max31865_readtemp(spi_get(), &set, &status); +// #else +// max31855_readtemp(spi_get(), &set, &status); // Read MAX31855 +// #endif + + // TODO: Migrate this FxP conversion to the readtemp code or similar + int8_t temp_frac = status.temp_frac > 9 ? status.temp_frac / 10 : status.temp_frac; + temp_frac = status.temp > 0 ? temp_frac : temp_frac * -1; + int32_t temp = (status.temp * 10) + temp_frac; + + + // EMZ FIXME: This could be way simpler + if(set.val.plant_type == PLANT_HEATER && status.setpoint * 10 < temp - set.val.hysteresis * 10) + thermostat_plant_on = 1; + else if(set.val.plant_type == PLANT_HEATER && status.setpoint * 10 > temp + set.val.hysteresis * 10) + thermostat_plant_on = 0; + + if(set.val.plant_type == PLANT_COOLER && status.setpoint * 10 > temp + set.val.hysteresis * 10) + thermostat_plant_on = 1; + else if(set.val.plant_type == PLANT_COOLER && status.setpoint * 10 < temp - set.val.hysteresis * 10) + thermostat_plant_on = 0; + + // EMZ: TODO: Refactor to output_enabled or something + if(status.pid_enabled && thermostat_plant_on) + { + // EMZ TODO: functionalize this + // put ssr output on display + ssd1306_drawstring(" ", 0, 90); //fixme: this is bad, but I can't get the old digits to clear otherwise + char tempstr[6]; + itoa(ssr_output, tempstr, 10); + ssd1306_drawstring(tempstr, 0, 90); + + + + HAL_GPIO_WritePin(SSR_PIN, 1); + HAL_GPIO_WritePin(LED_POWER, 1); + } + else + { + HAL_GPIO_WritePin(SSR_PIN, 0); + HAL_GPIO_WritePin(LED_POWER, 0); + } + + last_thermostat = HAL_GetTick(); + } + + +// // Transmit temperature over USB-CDC on a regular basis +// if(HAL_GetTick() - last_vcp_tx > VCP_TX_FREQ) +// { +// // Print temp to cdc +// char tempstr[16]; +// itoa_fp(status.temp, status.temp_frac, tempstr); +// uint8_t numlen = strlen(tempstr); +// tempstr[numlen] = '\r'; +// tempstr[numlen+1] = '\n'; +// +// // if(set.val.usb_plugged) +// // CDC_Transmit_FS(tempstr, numlen+2); +// // while(CDC_Transmit_FS("\r\n", 2) == USBD_BUSY); +// +// last_vcp_tx = HAL_GetTick(); +// } + + // Run state machine + display_process(&set, &status); watchdog_feed(); }