Pinecil v2 tune via PID (#1827)
* Start PWM after adc irq fully done * Filter len 4 * Use comparitor 2 on timer for wrap around * Update IRQ.cpp * Tip measurements are uint16_t Update BSP.cpp Update BSP.cpp * WiP PID move pid tuning to config Update PIDThread.cpp * Handle PWM Timer gitchy comparitor * Tuning * Dampen with Kd * Cleaning up * Use TemperatureType_t for getTipTemp() * Add small rolling average to user GUI temp to reduce flicker * Trigger PID when adc is skipped (will use old values)
This commit is contained in:
@@ -19,17 +19,17 @@ extern "C" {
|
||||
}
|
||||
void start_PWM_output(void);
|
||||
|
||||
#define ADC_Filter_Smooth 1
|
||||
#define ADC_Filter_Smooth 4 /* This basically smooths over one PWM cycle / set of readings */
|
||||
history<uint16_t, ADC_Filter_Smooth> ADC_Vin;
|
||||
history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
|
||||
history<uint16_t, ADC_Filter_Smooth> ADC_Tip;
|
||||
volatile uint8_t ADCBurstCounter = 0;
|
||||
void adc_fifo_irq(void) {
|
||||
|
||||
// IRQ is called at the end of the 8 set readings, pop these from the FIFO and send to filters
|
||||
void adc_fifo_irq(void) {
|
||||
if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
|
||||
// Read out all entries in the fifo
|
||||
while (ADC_Get_FIFO_Count()) {
|
||||
ADCBurstCounter++;
|
||||
volatile uint32_t reading = ADC_Read_FIFO();
|
||||
uint32_t reading = ADC_Read_FIFO();
|
||||
// As per manual, 26 bit reading; lowest 16 are the ADC
|
||||
uint16_t sample = reading & 0xFFFF;
|
||||
uint8_t source = (reading >> 21) & 0b11111;
|
||||
@@ -43,23 +43,16 @@ void adc_fifo_irq(void) {
|
||||
case VIN_ADC_CHANNEL:
|
||||
ADC_Vin.update(sample);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ADCBurstCounter >= 8) {
|
||||
ADCBurstCounter = 0;
|
||||
start_PWM_output();
|
||||
|
||||
// unblock the PID controller thread
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (pidTaskNotification) {
|
||||
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
// unblock the PID controller thread
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (pidTaskNotification) {
|
||||
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,16 +93,43 @@ void start_PWM_output(void) {
|
||||
PWM_Channel_Disable(PWM_Channel);
|
||||
switchToFastPWM();
|
||||
}
|
||||
TIMER_Enable(TIMER_CH0);
|
||||
}
|
||||
|
||||
// Timer 0 is used to co-ordinate the ADC and the output PWM
|
||||
void timer0_comp0_callback(void) {
|
||||
TIMER_Disable(TIMER_CH0);
|
||||
ADC_Start();
|
||||
if (PWM_Channel_Is_Enabled(PWM_Channel)) {
|
||||
// So there appears to be a bug _somewhere_ where sometimes the comparator doesn't fire
|
||||
// Its not re-occurring with specific values, so suspect its a weird bug
|
||||
// For now, we just skip the cycle and throw away the ADC readings. Its a waste but
|
||||
// It stops stupid glitches in readings, i'd take slight instability from the time jump
|
||||
// Over the readings we get that are borked as the header is left on
|
||||
// <Ralim 2023/10/14>
|
||||
PWM_Channel_Disable(PWM_Channel);
|
||||
// MSG("ALERT PWM Glitch\r\n");
|
||||
// Triger the PID now instead
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (pidTaskNotification) {
|
||||
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ADC_Start();
|
||||
}
|
||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_0);
|
||||
}
|
||||
void timer0_comp1_callback(void) {
|
||||
// Trigged at end of output cycle; turn off the tip PWM
|
||||
PWM_Channel_Disable(PWM_Channel);
|
||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_1);
|
||||
}
|
||||
void timer0_comp1_callback(void) { PWM_Channel_Disable(PWM_Channel); } // Trigged at end of output cycle; turn off the tip PWM
|
||||
|
||||
void timer0_comp2_callback(void) {
|
||||
// Triggered at end of timer cycle; re-start the tip driver
|
||||
start_PWM_output();
|
||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2);
|
||||
}
|
||||
void switchToFastPWM(void) {
|
||||
inFastPWMMode = true;
|
||||
holdoffTicks = 10;
|
||||
@@ -119,8 +139,8 @@ void switchToFastPWM(void) {
|
||||
|
||||
// ~10Hz
|
||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks);
|
||||
// Set divider to 10 ~= 10.5Hz
|
||||
|
||||
// Set divider to 10 ~= 10.5Hz
|
||||
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
||||
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 10);
|
||||
@@ -139,7 +159,7 @@ void switchToSlowPWM(void) {
|
||||
// Adjust ADC
|
||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks);
|
||||
|
||||
// Set divider to 22
|
||||
// Set divider for ~ 5Hz
|
||||
|
||||
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
||||
|
||||
@@ -193,5 +213,6 @@ uint16_t getADCHandleTemp(uint8_t sample) { return ADC_Temp.average(); }
|
||||
|
||||
uint16_t getADCVin(uint8_t sample) { return ADC_Vin.average(); }
|
||||
|
||||
// Returns either average or instant value. When sample is set the samples from the injected ADC are copied to the filter and then the raw reading is returned
|
||||
// Returns the current raw tip reading after any cleanup filtering
|
||||
// For Pinecil V2 we dont do any rolling filtering other than just averaging all 4 readings in the adc snapshot
|
||||
uint16_t getTipRawTemp(uint8_t sample) { return ADC_Tip.average() >> 1; }
|
||||
|
||||
Reference in New Issue
Block a user