Changeset - c1b2840961f0
[Not reviewed]
tip default
0 9 0
Ethan Zonca <ethanzonca> - 21 months ago 2023-07-17 17:16:01

Hacking thermostatic mode into operation. This code needs some love.
9 files changed with 49 insertions and 33 deletions:
0 comments (0 inline, 0 general)
.settings/language.settings.xml
Show inline comments
 
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 
<project>
 
	<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1538442532" name="Debug">
 
		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
 
			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 
			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-372386926437939920" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="118157264982881376" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
				<language-scope id="org.eclipse.cdt.core.gcc"/>
 
				<language-scope id="org.eclipse.cdt.core.g++"/>
 
			</provider>
 
		</extension>
 
	</configuration>
 
	<configuration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.1229152259" name="Release">
 
		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
 
			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 
			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-352937073990100134" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="124662482003330422" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
				<language-scope id="org.eclipse.cdt.core.gcc"/>
 
				<language-scope id="org.eclipse.cdt.core.g++"/>
 
			</provider>
 
		</extension>
 
	</configuration>
 
</project>
inc/config.h
Show inline comments
 
@@ -30,46 +30,49 @@
 
//////////////////////////////////////////////////////
 
 
// Add bootloader option to top of idle screen menu
 
#define BOOTLOADER_SHORTCUT
 
 
 
//////////////////////////////////////////////////////
 
// Default Settings
 
//////////////////////////////////////////////////////
 
 
//TODO: add defaults for all settings
 
#define DEFAULT_BOOT_TO_BREW 0
 
#define DEFAULT_TEMP_UNITS TEMP_UNITS_FAHRENHEIT
 
#define DEFAULT_WINDUP_GUARD 300
 
#define DEFAULT_K_P 100
 
#define DEFAULT_K_I 2
 
#define DEFAULT_K_D 0
 
#define DEFAULT_TEMP_OFFSET 0
 
#define DEFAULT_IGNORE_ERROR 0
 
#define DEFAULT_SETPOINT 70
 
#define DEFAULT_HYSTERESIS 1
 
#define DEFAULT_SETPOINT_COUNT 1
 
#define DEFAULT_SETPOINT_AUX_SELECT_ENABLE 0
 
 
#define DEFAULT_CONTROL_MODE 1 // thermostat
 
#define DEFAULT_PLANT_TYPE 1
 
 
 
//////////////////////////////////////////////////////
 
// Watchdog Settings
 
//////////////////////////////////////////////////////
 
//#define WATCHDOG_ENABLE
 
 
 
 
// Internal macros
 
#define hal_init HAL_Init
 
#define MAKE32(by3,by2,by1,by0) ((uint32_t)((((((by3<<8)+by2)<<8)+by1)<<8)+by0))
 
 
#endif
 
 
 
 
 
 
 
 
 
inc/pwmout.h
Show inline comments
 
#ifndef PWMOUT_H
 
#define PWMOUT_H
 

	
 
#include "stm32f3xx_hal.h"
 
#include "gpio.h"
 
#include "flash.h"
 
#include "error.h"
 

	
 
#define SSR_PIN GPIO_PIN_7
 
#define SSR_GPIO_Port GPIOB
 
#define SSR SSR_GPIO_Port, SSR_PIN
 

	
 

	
 

	
 
void pwmout_init(void);
 
void pwmout_process(int16_t duty);
 
TIM_HandleTypeDef* pwmout_get_tim(void);
 

	
 
#endif
inc/system/gpio.h
Show inline comments
 
@@ -22,34 +22,38 @@
 
#define SW_A_Pin GPIO_PIN_6
 
#define SW_A_GPIO_Port GPIOA
 
#define SW_LEFT SW_A_GPIO_Port, SW_A_Pin
 
 
#define SW_C_Pin GPIO_PIN_7
 
#define SW_C_GPIO_Port GPIOA
 
#define SW_DOWN SW_C_GPIO_Port, SW_C_Pin
 
 
#define SW_BTN_Pin GPIO_PIN_0
 
#define SW_BTN_GPIO_Port GPIOB
 
#define SW_BTN SW_BTN_GPIO_Port , SW_BTN_Pin
 
 
#define LED_PIN GPIO_PIN_6
 
#define LED_GPIO_Port GPIOB
 
#define LED LED_GPIO_Port, LED_PIN
 
 
#define AUX_INPUT_Pin GPIO_PIN_10
 
#define AUX_INPUT_GPIO_Port GPIOA
 
#define AUX_INPUT AUX_INPUT_GPIO_Port , AUX_INPUT_Pin
 
 
#define AUX_RETURN_Pin GPIO_PIN_9
 
#define AUX_RETURN_GPIO_Port GPIOA
 
#define AUX_RETURN AUX_RETURN_GPIO_Port , AUX_RETURN_Pin
 
 
#define SSR_PIN GPIO_PIN_7
 
#define SSR_GPIO_Port GPIOB
 
#define SSR SSR_GPIO_Port, SSR_PIN
 
 
 
void user_input(uint16_t* to_modify);
 
void user_input_min_max(uint16_t* to_modify, uint16_t min, uint16_t max);
 
void user_input_signed(int32_t* to_modify);
 
void user_input_float(float* to_modify);
 
 
void gpio_init(void);
 
void gpio_led_blueblink(uint8_t num_blinks);
 
 
#endif
src/main.c
Show inline comments
 
@@ -59,60 +59,60 @@ int main(void)
 
    uint32_t last_thermostat = 0;
 
    uint32_t last_1hz = 0;
 
    uint32_t last_5hz = 0;
 
 
    int16_t duty = 0;
 
 
    while (1)
 
    {
 
 
        if(HAL_GetTick() - last_1hz > 750)
 
        {
 
            display_1hz();
 
            last_1hz = HAL_GetTick();
 
        }
 
 
        if(HAL_GetTick() - last_5hz > 200)
 
        {
 
            tempsense_readtemp();
 
            runtime_status()->temp = tempsense_gettemp();
 
            last_5hz = HAL_GetTick();
 
        }
 
 
        if(flash_getsettings()->val.control_mode == MODE_PID && (HAL_GetTick() - last_pid > PID_PERIOD))
 
        {
 
            duty = pid_process();
 
            //duty = pid_process();
 
            last_pid = HAL_GetTick();
 
        }
 
 
        // Thermostatic control
 
        if(flash_getsettings()->val.control_mode == MODE_THERMOSTAT && HAL_GetTick() - last_thermostat > SSR_PERIOD)
 
        {
 
            duty = thermostat_process();
 
            last_thermostat = HAL_GetTick();
 
        }
 
 
        pwmout_process((int16_t)duty);
 
        //pwmout_process((int16_t)duty);
 
        display_process();
 
        watchdog_feed();
 
 
 
        //        // 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();
 
        //        }
 
 
    }
 
}
 
src/pwmout.c
Show inline comments
 
@@ -67,40 +67,40 @@ void pwmout_init(void)
 
    sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
 
    if (HAL_TIMEx_ConfigBreakDeadTime(&htim17, &sBreakDeadTimeConfig) != HAL_OK)
 
    {
 
        error_assert(ERR_PERIPHINIT);
 
    }
 

	
 
    HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, 0, 0);
 
    HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn);
 

	
 

	
 
    HAL_TIM_OC_Start_IT(&htim17, TIM_CHANNEL_1);
 
    __HAL_TIM_ENABLE_IT(&htim17, TIM_IT_UPDATE);
 

	
 
}
 

	
 

	
 
// freaking integral term isn't compatible with both heating and cooling... due to the discard
 
// functionality. this is a problem.
 

	
 
// also duty cycling isn't working correctly...
 
void pwmout_process(int16_t duty)
 
{
 
    if(duty == 0)
 
    {
 
        HAL_GPIO_WritePin(SSR, 0);
 
        HAL_GPIO_WritePin(LED, 0);
 
//        HAL_GPIO_WritePin(SSR, 0);
 
//        HAL_GPIO_WritePin(LED, 0);
 
    }
 
    if(duty < 0)
 
        duty = 0;
 

	
 

	
 
    htim17.Instance->CCR1 = duty; //duty;
 
}
 

	
 

	
 
// Accessor for timer handle
 
TIM_HandleTypeDef* pwmout_get_tim(void)
 
{
 
    return &htim17;
 
}
src/system/flash.c
Show inline comments
 
@@ -56,39 +56,41 @@ void flash_savesettings()
 
 
// Restore configuration from flash memory, if any was previously saved
 
void flash_restoresettings(void)
 
{
 
    // Check for magic flash value
 
    if(eeprom_emulation[FLASH_MAGIC_LOC] == FLASH_MAGIC_VALUE)
 
    {
 
        // Read page of flash into settings structure
 
        uint16_t readctr = 0;
 
        for(readctr = 0; readctr < 128; readctr++)
 
        {
 
            settings.data[readctr] = eeprom_emulation[readctr];
 
        }
 
    }
 
    // No data in flash! Set defaults here
 
    //TODO: Set all defaults
 
    else
 
    {
 
        settings.val.k_p = DEFAULT_K_P;
 
        settings.val.k_i = DEFAULT_K_I;
 
        settings.val.k_d = DEFAULT_K_D;
 
        settings.val.windup_guard = DEFAULT_WINDUP_GUARD;
 
        settings.val.sensor_type = 1;
 
        settings.val.setpoint_count = DEFAULT_SETPOINT_COUNT;
 
        settings.val.control_mode = DEFAULT_CONTROL_MODE;
 
        settings.val.plant_type = DEFAULT_PLANT_TYPE;
 
    }
 
}
 
 
 
// Accessor to retrieve settings structure
 
inline therm_settings_t* flash_getsettings(void)
 
{
 
    return &settings;
 
}
 
 
inline therm_status_t* runtime_status(void)
 
{
 
    return &status;
 
}
 
src/system/interrupts.c
Show inline comments
 
@@ -45,46 +45,46 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPI
 
            //				HAL_GPIO_TogglePin(GATE_DRIVE);
 
            //				last_button_press = HAL_GetTick();
 
            //			}
 
        } break;
 
    }
 
}
 
 
void TIM1_TRG_COM_TIM17_IRQHandler(void)
 
{
 
    /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 0 */
 
 
    /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */
 
 
    HAL_TIM_IRQHandler(pwmout_get_tim());
 
    /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */
 
 
    /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */
 
}
 
 
 
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
 
{
 
    if(htim == pwmout_get_tim())
 
    {
 
        HAL_GPIO_WritePin(SSR, 0);
 
        HAL_GPIO_WritePin(LED, 0);
 
//        HAL_GPIO_WritePin(SSR, 0);
 
//        HAL_GPIO_WritePin(LED, 0);
 
    }
 
}
 
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
 
{
 
    if(htim == pwmout_get_tim())
 
    {
 
        if(htim->Instance->CCR1 == 0)
 
        {
 
            HAL_GPIO_WritePin(LED, 0);
 
            HAL_GPIO_WritePin(SSR, 0);
 
//            HAL_GPIO_WritePin(LED, 0);
 
//            HAL_GPIO_WritePin(SSR, 0);
 
        }
 
        else
 
        {
 
            HAL_GPIO_WritePin(LED, 1);
 
            HAL_GPIO_WritePin(SSR, 1);
 
//            HAL_GPIO_WritePin(LED, 1);
 
//            HAL_GPIO_WritePin(SSR, 1);
 
        }
 
    }
 
}
 
src/thermostat.c
Show inline comments
 
//
 
// Thermostat: Thermostatic controller
 
//
 

	
 
#include "thermostat.h"
 
#include "gpio.h"
 

	
 
// PID implementation
 
// Thermostatic control implementation
 
static uint8_t thermostat_plant_on = 0;
 

	
 
float thermostat_process(void)
 
{
 

	
 
    //            #ifdef MAX31865_RTD_SENSOR
 
    //            max31865_readtemp(spi_get(), &set, &status);
 
    //			#else
 
    //			max31855_readtemp(spi_get(), &set, &status); // Read MAX31855
 
    //			#endif
 

	
 
    float ssr_output = 0.0;
 
    uint8_t thermostat_plant_on = 0;
 

	
 
    // TODO: Migrate this FxP conversion to the readtemp code or similar
 
    float temp = runtime_status()->temp;
 

	
 
    float temp = runtime_status()->temp; // (scale to whole degrees)
 
    uint32_t hyst = flash_getsettings()->val.hysteresis;
 

	
 
    // EMZ FIXME: This could be way simpler
 
    if(flash_getsettings()->val.plant_type == PLANT_HEATER && runtime_status()->setpoint * 10 < temp - flash_getsettings()->val.hysteresis * 10)
 
        thermostat_plant_on = 1;
 
    else if(flash_getsettings()->val.plant_type == PLANT_HEATER && runtime_status()->setpoint * 10 > temp + flash_getsettings()->val.hysteresis * 10)
 
        thermostat_plant_on = 0;
 

	
 
    if(flash_getsettings()->val.plant_type == PLANT_COOLER && runtime_status()->setpoint * 10 > temp + flash_getsettings()->val.hysteresis * 10)
 
        thermostat_plant_on = 1;
 
    else if(flash_getsettings()->val.plant_type == PLANT_COOLER && runtime_status()->setpoint * 10 < temp - flash_getsettings()->val.hysteresis * 10)
 
        thermostat_plant_on = 0;
 
    if(flash_getsettings()->val.plant_type == PLANT_HEATER)
 
    {
 
    	if(temp < runtime_status()->setpoint - hyst)
 
        		thermostat_plant_on = 1;
 
    	if(temp > runtime_status()->setpoint + hyst)
 
    		thermostat_plant_on = 0;
 
    }
 

	
 
    if(flash_getsettings()->val.plant_type == PLANT_COOLER)
 
	{
 
    	if(temp < runtime_status()->setpoint - hyst)
 
			thermostat_plant_on = 0;
 
    	if(temp > runtime_status()->setpoint + hyst)
 
    		thermostat_plant_on = 1;
 
	}
 

	
 
    // EMZ: TODO: Refactor to output_enabled or something
 
    if(runtime_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);
 
        itoa(thermostat_plant_on, tempstr, 10);
 
        ssd1306_drawstring(tempstr, 0, 90);
 

	
 

	
 

	
 
        //                HAL_GPIO_WritePin(SSR_PIN, 1);
 
		HAL_GPIO_WritePin(SSR, 1);
 
        HAL_GPIO_WritePin(LED, 1);
 
    }
 
    else
 
    {
 
        //                HAL_GPIO_WritePin(SSR_PIN, 0);
 
        HAL_GPIO_WritePin(LED, 0);
 
		HAL_GPIO_WritePin(SSR, 0);
 
		HAL_GPIO_WritePin(LED, 0);
 
    }
 

	
 
    return ssr_output;
 
    if(thermostat_plant_on)
 
    	return 1000.0f;
 
    else
 
    	return 0.0f;
 
}
 

	
 

	
0 comments (0 inline, 0 general)