Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: LEX_Threaded_Programming_V3
Heater.cpp
- Committer:
- justinbuckland
- Date:
- 2019-09-20
- Revision:
- 34:294adcc3e4b2
- Parent:
- 33:52ab0641f2e6
- Child:
- 35:5acf01897ed6
File content as of revision 34:294adcc3e4b2:
/*------------------------------------------------------------------------------
Library code file for interface to Heater
Date: 16/07/2018
------------------------------------------------------------------------------*/
#include "mbed.h"
#include "MODSERIAL.h"
#include "Heater.h"
#include "ADS8568_ADC.h"
Heater::Heater(const int i_port, const int v_port, FastPWM * drive, FastPWM * guard, ADS8568_ADC * adc, DigitalIn adc_busy, const memspcr_ThermalConfiguration & thermal)
:thermal(thermal), i_port(i_port), v_port(v_port), drive(drive), guard(guard), adc(adc), adc_busy(adc_busy)
{
drive->prescaler(1);
guard->prescaler(1);
drive->period_ticks(1000);
guard->period_ticks(1000);
}
void Heater::read()
{
//Reads R and then resets the drive back to its previous value
int i = 0;
float drive_cal[2] = {0.0, 10.0}; // replace with drive cal passed via Heater class
double drive_prev = drive->read(); //Store previous value of drive
*drive = 1.0f; //Turn the driver on for the measurement
wait_us(thermal.settling_time_us); //Wait for ADC to settle
adc->start_conversion(ADC_CONV_ALL_CH);
//Incremental back off until ADC is free
while(adc_busy == 1) {
wait_us(1);
i++;
}
drive->write(0); //Reset the duty cycle back to what it was
//Get voltage, current and R values from the ADC conversion
adc->read_channels();
curr = adc->read_channel_result(i_port);
v = adc->read_channel_result(v_port);
if (curr > 0) {
R = (float)v/curr; //Avoid dividing by 0
R = drive_cal[0] + drive_cal[1]*R; //Convert to Ohms
}
//Get error values
error = R_ref - R;
//Only allow positive integrated errors and limit change in integrated error
//to help avoid integral windup
if (abs(error) > thermal.pid_wind_up_limit_ohm) {error = error * thermal.pid_wind_up_limit_ohm / abs(error);}
error_integrated += error;
if (error_integrated < 0.0) {
error_integrated = 0.0;
}
}
void Heater::update()
{
//Update PWM from setpoint and resistance
double duty_cycle = (double) thermal.pid_kp_mho * (error + error_integrated/thermal.pid_integral_time_ms);
if (duty_cycle > thermal.pid_pwm_limit) duty_cycle = thermal.pid_pwm_limit;
drive->write(duty_cycle);
guard->write(duty_cycle * thermal.guard_drive_ratio);
}
void Heater::Set_ref(float R)
{
R_ref = R;
}
void Heater::Set_D(float D)
{
drive->write(D);
guard->write(D*thermal.guard_drive_ratio);
}
int Heater::Get_D() const
{
return drive->read();
}
int Heater::Get_i() const
{
return curr;
}
int Heater::Get_v() const
{
return v;
}
float Heater::Get_R() const
{
return R;
}
float Heater::Get_R_ref() const
{
return R_ref;
}
float Heater::Get_error() const
{
return error;
}
float Heater::Get_error_integrated() const
{
return error_integrated;
}
void Heater::turn_on ()
{
*drive = 1;
*guard = thermal.guard_drive_ratio;
}
void Heater::turn_off ()
{
*drive = 0;
*guard = 0;
}