Changeset - b42e15fadfde
[Not reviewed]
cortex-f0
0 1 2
Ethan Zonca - 9 years ago 2015-11-28 13:37:11
ez@ethanzonca.com
Add new pid files
3 files changed with 69 insertions and 8 deletions:
main.c
5
8
pid.c
56
pid.h
8
0 comments (0 inline, 0 general)
main.c
Show inline comments
 
@@ -16,10 +16,6 @@
 
#include "usb_device.h"
 
#include "usbd_cdc_if.h"
 
 
 
// Prototypes
 
void process();
 
 
therm_settings_t set;
 
therm_status_t status;
 
 
@@ -32,7 +28,8 @@ int main(void)
 
    systemclock_init();
 
 
    // Unset bootloader option bytes (if set)
 
    void bootloader_unset(void);
 
    // FIXME this was never getting called. Try again sometime.
 
    //bootloader_unset();
 
 
    // Init GPIO
 
    gpio_init();
 
@@ -42,7 +39,7 @@ int main(void)
 
//    set.val.usb_plugged = 
 
 
    // USB startup delay
 
    HAL_Delay(1000);
 
    HAL_Delay(500);
 
    HAL_GPIO_WritePin(LED_POWER, 1);
 
 
    // Enter into bootloader if up button pressed on boot
 
@@ -86,11 +83,11 @@ int main(void)
 
    ssd1306_DrawString("therm v0.2", 1, 40);
 
    ssd1306_DrawString("protofusion.org/therm", 3, 0);
 
 
    HAL_Delay(1500);
 
    HAL_Delay(1000);
 
 
    flash_restore(&set);
 
 
    HAL_Delay(1500);
 
    HAL_Delay(1000);
 
    ssd1306_clearscreen();
 
 
    // Soft timers
pid.c
Show inline comments
 
new file 100644
 
#include "stm32f0xx_hal.h"
 
#include "states.h"
 

	
 
// PID implementation
 
// TODO: Make struct that has the last_temp and i_state in it, pass by ref. Make struct that has other input values maybe.
 
static int16_t last_pid_temp = 0;
 
static uint8_t last_pid_temp_frac = 0;
 
static int32_t i_state = 0;
 

	
 
int16_t pid_update(uint16_t k_p, uint16_t k_i, uint16_t k_d, int16_t temp, uint8_t temp_frac, int16_t setpoint, therm_settings_t* set, therm_status_t* status) 
 
{
 
  // Calculate instantaneous error
 
  int16_t error = setpoint - temp; // TODO: Use fixed point fraction
 

	
 
  // Proportional component
 
  int32_t p_term = k_p * error;
 

	
 
  // Error accumulator (integrator)
 
  i_state += error;
 

	
 
  // to prevent the iTerm getting huge from lots of 
 
  //  error, we use a "windup guard" 
 
  // (this happens when the machine is first turned on and
 
  // it cant help be cold despite its best efforts)
 
  // not necessary, but this makes windup guard values 
 
  // relative to the current iGain
 
  int32_t windup_guard_res = set->val.windup_guard / k_i;  
 

	
 
  // Calculate integral term with windup guard 
 
  if (i_state > windup_guard_res) 
 
    i_state = windup_guard_res;
 
  else if (i_state < -windup_guard_res) 
 
    i_state = -windup_guard_res;
 

	
 
  int32_t i_term = k_i * i_state;
 

	
 
  // Calculate differential term (slope since last iteration)
 
  int32_t d_term = (k_d * (status->temp - last_pid_temp));
 

	
 
  // Save temperature for next iteration
 
  last_pid_temp = status->temp;
 
  last_pid_temp_frac = status->temp_frac;
 

	
 
  int16_t result = p_term + i_term - d_term;
 

	
 
  // Put out tenths of percent, 0-1000. 
 
  if(result > 1000)
 
    result = 1000;
 
  else if(result < -1000)
 
    result = -1000;
 

	
 
  // Return feedback
 
  return result;
 
}
 

	
 

	
pid.h
Show inline comments
 
new file 100644
 
#ifndef PIDS_H
 
#define PIDS_H
 

	
 
#include "states.h"
 

	
 
int16_t pid_update(uint16_t k_p, uint16_t k_i, uint16_t k_d, int16_t temp, uint8_t temp_frac, int16_t setpoint, therm_settings_t* set, therm_status_t* status);
 

	
 
#endif
0 comments (0 inline, 0 general)