Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
297e84bedThis file is pinned to the selected release. Download the original to open it in your design tool.
/*
* screen_PID.c
*
* Created on: 2019-09-26
* Author: Radek Vana
*/
#include "config.h"
#ifdef PIDCALIBRATION
#include "gui.h"
#include "status_footer.h"
#include "math.h"
#include "../Marlin/src/module/temperature.h"
#include "marlin_client.h"
#define SPIN_DIGITS 6
#define SPIN_PRECISION 2
#define SPIN_INT_DIGITS (SPIN_DIGITS - SPIN_PRECISION)
enum {_BED = -1, _EXTRUDER = 0};
typedef enum
{
AT_idle,
AT_extruder,
AT_bed//,
//AT_extruder_done,
//AT_bed_done
}
autotune_state_t;
#pragma pack(push)
#pragma pack(1)
struct _PID_t
{
int16_t ID;
float* autotune_temp;
float raw_Ki;
float raw_Kd;
float* p_Kp;
float* p_Ki;
float* p_Kd;
float Kp_last;
float Ki_last;
float Kd_last;
};
typedef struct
{
window_frame_t frame;
window_text_t textMenuName;
window_text_t btAutoTuneApply_E;
window_spin_t spinAutoTn_E;
window_list_t list_RW_E;//choose read write PID
window_spin_t spinKp_E[SPIN_DIGITS];
window_spin_t spinKi_E[SPIN_DIGITS];
window_spin_t spinKd_E[SPIN_DIGITS];
window_text_t btAutoTuneApply_B;
window_spin_t spinAutoTn_B;
window_list_t list_RW_B;//choose read write PID
window_spin_t spinKp_B[SPIN_DIGITS];
window_spin_t spinKi_B[SPIN_DIGITS];
window_spin_t spinKd_B[SPIN_DIGITS];
window_text_t textExit;
status_footer_t footer;
size_t list_RW_E_index_actual;
size_t list_RW_E_index_last;
size_t list_RW_B_index_actual;
size_t list_RW_B_index_last;
uint16_t dot_coordsKp_E[2];
uint16_t dot_coordsKi_E[2];
uint16_t dot_coordsKd_E[2];
uint16_t dot_coordsKp_B[2];
uint16_t dot_coordsKi_B[2];
uint16_t dot_coordsKd_B[2];
rect_ui16_t rect_E;
rect_ui16_t rectKp_E;
rect_ui16_t rectKi_E;
rect_ui16_t rectKd_E;
rect_ui16_t rect_B;
rect_ui16_t rectKp_B;
rect_ui16_t rectKi_B;
rect_ui16_t rectKd_B;
int16_t idsDigits_Kp_E[6];
int16_t idsDigits_Ki_E[6];
int16_t idsDigits_Kd_E[6];
int16_t idsDigits_Kp_B[6];
int16_t idsDigits_Ki_B[6];
int16_t idsDigits_Kd_B[6];
float autotune_temp_B;
float autotune_temp_E;
_PID_t _PID_E;
_PID_t _PID_B;
autotune_state_t autotune_state;
int redraw;
} screen_PID_data_t;
#pragma pack(pop)
#define pd ((screen_PID_data_t*)screen->pdata)
#define AUTO_TN_DEFAULT_CL COLOR_WHITE
#define AUTO_TN_ACTIVE_CL COLOR_RED
enum {
TAG_QUIT = 10,
TAG_AUTOTUNE_APPLY_E,
TAG_CHANGE_VAL_E,
TAG_AUTOTUNE_APPLY_B,
TAG_CHANGE_VAL_B,
TAG_RW_E,
TAG_RW_B
};
//-----------------------------------------------------------------------------
//methods
//-----------------------------------------------------------------------------
//pid
void _PID_copy_and_scale_PID_i(_PID_t* ths);
void _PID_copy_and_scale_PID_d(_PID_t* ths);
void _PID_autotune(_PID_t* ths);
//0 the contents of both memory blocks are equal
int _PID_actualize(_PID_t* ths);
void _PID_ctor(_PID_t* ths, int16_t id, float* autotune_temp);
void _PID_set(_PID_t* ths, float Kp, float Ki, float Kd);
//-----------------------------------------------------------------------------
//autotune
bool __autotune(screen_t* screen, autotune_state_t* a_tn_st);
void _autotune_B(screen_t* screen, autotune_state_t* a_tn_st);
void _autotune_E(screen_t* screen, autotune_state_t* a_tn_st);
//-----------------------------------------------------------------------------
//gui spins
void generate_spin_single_digit(int16_t &id0, int16_t &id, window_spin_t& spin,
uint16_t &col, uint16_t row, uint16_t offset, uint16_t row_h );
void enable_digits_write_mode(int16_t *ids, size_t sz);
void disable_digits_write_mode(int16_t *ids, size_t sz);
//i am not using size_t numOfDigits, size_t precision
//need to be signed because of for cycles
void generate_spin_digits(screen_t* screen, int numOfDigits, int precision,
int16_t &id0, int16_t *ids, window_spin_t* pSpin, uint16_t dot_coords[2],
uint16_t col, uint16_t row, uint16_t row_h);
//-----------------------------------------------------------------------------
//list
const char* list_RW_strings[] = {"READ", "WRITE"};
#define list_RW_strings_sz (sizeof(list_RW_strings)/sizeof(const char*))
void window_list_RW_item(window_list_t* pwindow_list, uint16_t index,
const char** pptext, uint16_t* pid_icon);
//-----------------------------------------------------------------------------
//screen update methods
void disp_single_PID_digit(uint8_t singlePIDdigit, int16_t id);
void disp_single_PID_param(uint32_t singlePIDparam,
int16_t* ids, size_t numOfDigits);
void dispPID(_PID_t& PID, int16_t* KpIds, int16_t* KiIds, int16_t* KdIds,
size_t numOfDigits, size_t precision);
uint8_t get_single_PIDdigitFromDisp(int16_t id);
//i am not using size_t, need negative values in for cycle
float get_single_PIDparamFromDisp(int16_t* ids, int numOfDigits, int precision);
//-----------------------------------------------------------------------------
//btn autotune / apply
static const char* btnAutoTuneOrApplystrings[] = {"AutTn", "Apply"};
#define btnAutoTuneOrApplystrings_sz (sizeof(btnAutoTuneOrApplystrings)/sizeof(const char*))
void screen_PID_init(screen_t* screen)
{
pd->redraw = 1;
pd->list_RW_E_index_actual = 0;
pd->list_RW_E_index_last = 0;
pd->list_RW_B_index_actual = 0;
pd->list_RW_B_index_last = 0;
pd->autotune_state = AT_idle;
pd->autotune_temp_E = 150;
pd->autotune_temp_B = 70;
_PID_ctor(&(pd->_PID_E), _EXTRUDER, &pd->autotune_temp_E);
_PID_ctor(&(pd->_PID_B), _BED, &pd->autotune_temp_B);
int16_t id;
uint16_t col = 2;
uint16_t row2draw = 0;
uint16_t row_h = 22;
int16_t id0 = window_create_ptr(WINDOW_CLS_FRAME,
-1, rect_ui16(0,0,0,0), &(pd->frame));
id = window_create_ptr(WINDOW_CLS_TEXT,
id0, rect_ui16(0, 0, display->w, row_h), &(pd->textMenuName));
pd->textMenuName.font=resource_font(IDR_FNT_BIG);
window_set_text(id, (const char*)"PID adjustment");
//EXTRUDER
row2draw = row_h;
pd->rect_E = rect_ui16(col, row2draw, 100, row_h);
row2draw += row_h;
id = window_create_ptr(WINDOW_CLS_LIST,
id0, rect_ui16(col, row2draw, 100, row_h), &(pd->list_RW_E));
window_set_item_count(id, list_RW_strings_sz);
window_set_item_index(id, 0);
window_set_item_callback(id, window_list_RW_item);
window_set_tag(id, TAG_RW_E);
row2draw += 25;
pd->rectKp_E = rect_ui16(col, row2draw, 25, row_h);
generate_spin_digits(screen, SPIN_DIGITS, SPIN_PRECISION,
id0, pd->idsDigits_Kp_E, pd->spinKp_E, pd->dot_coordsKp_E,
col + 25, row2draw, row_h);
row2draw += row_h;
pd->rectKi_E = rect_ui16(col, row2draw, 30, row_h);
generate_spin_digits(screen, SPIN_DIGITS, SPIN_PRECISION,
id0, pd->idsDigits_Ki_E, pd->spinKi_E, pd->dot_coordsKi_E,
col + 25, row2draw, row_h);
row2draw += row_h;
pd->rectKd_E = rect_ui16(col, row2draw, 50, row_h);
generate_spin_digits(screen, SPIN_DIGITS, SPIN_PRECISION,
id0, pd->idsDigits_Kd_E, pd->spinKd_E, pd->dot_coordsKd_E,
col + 25, row2draw, row_h);
row2draw += row_h;
id = window_create_ptr(WINDOW_CLS_TEXT,
id0, rect_ui16(col, row2draw, 68, row_h),
&(pd->btAutoTuneApply_E));
window_set_text(id, btnAutoTuneOrApplystrings[0]);
window_enable(id);
window_set_tag(id, TAG_AUTOTUNE_APPLY_E);
id = window_create_ptr(WINDOW_CLS_SPIN ,
id0, rect_ui16(col + 70, row2draw, 40, row_h),
&(pd->spinAutoTn_E));
window_set_format(id, "%f");
window_set_min_max_step(id, 100.0F, 250.0F, 5.0F);
window_set_value(id, pd->autotune_temp_E);
row2draw += row_h;
//BED
col = 122;
row2draw = row_h;
pd->rect_B = rect_ui16(col, row2draw, 100, row_h);
row2draw += row_h;
id = window_create_ptr(WINDOW_CLS_LIST, id0,
rect_ui16(col, row2draw, 100, row_h), &(pd->list_RW_B));
window_set_item_count(id, list_RW_strings_sz);
window_set_item_index(id, 0);
window_set_item_callback(id, window_list_RW_item);
window_set_tag(id, TAG_RW_B);
row2draw += 25;
pd->rectKp_B = rect_ui16(col, row2draw, 25, row_h);
generate_spin_digits(screen, SPIN_DIGITS, SPIN_PRECISION,
id0, pd->idsDigits_Kp_B, pd->spinKp_B, pd->dot_coordsKp_B,
col + 25, row2draw, row_h);
row2draw += row_h;
pd->rectKi_B = rect_ui16(col, row2draw, 30, row_h);
generate_spin_digits(screen, SPIN_DIGITS, SPIN_PRECISION,
id0, pd->idsDigits_Ki_B, pd->spinKi_B, pd->dot_coordsKi_B,
col + 25, row2draw, row_h);
row2draw += row_h;
pd->rectKd_B = rect_ui16(col, row2draw, 50, row_h);
generate_spin_digits(screen, SPIN_DIGITS, SPIN_PRECISION,
id0, pd->idsDigits_Kd_B, pd->spinKd_B, pd->dot_coordsKd_B,
col + 25, row2draw, row_h);
row2draw += row_h;
id = window_create_ptr(WINDOW_CLS_TEXT,
id0, rect_ui16(col, row2draw, 68, row_h),
&(pd->btAutoTuneApply_B));
window_set_text(id, btnAutoTuneOrApplystrings[0]);
window_enable(id);
window_set_tag(id, TAG_AUTOTUNE_APPLY_B);
id = window_create_ptr(WINDOW_CLS_SPIN ,
id0, rect_ui16(col + 70, row2draw, 40, row_h),
&(pd->spinAutoTn_B));
window_set_format(id, "%.0f");
window_set_min_max_step(id, 50.0F, 110.0F, 5.0F);
window_set_value(id, pd->autotune_temp_B);
row2draw += row_h;
//exit and footer
id = window_create_ptr(WINDOW_CLS_TEXT,
id0, rect_ui16(2, 245, 60, 22), &(pd->textExit));
pd->textExit.font=resource_font(IDR_FNT_BIG);
window_set_text(id, (const char*)"EXIT");
window_enable(id);
window_set_tag(id, TAG_QUIT);
status_footer_init(&(pd->footer), id0);
dispPID((pd->_PID_E), pd->idsDigits_Kp_E, pd->idsDigits_Ki_E, pd->idsDigits_Kd_E,
SPIN_DIGITS,SPIN_PRECISION);
dispPID((pd->_PID_B), pd->idsDigits_Kp_B, pd->idsDigits_Ki_B, pd->idsDigits_Kd_B,
SPIN_DIGITS,SPIN_PRECISION);
}
void screen_PID_done(screen_t* screen)
{
window_destroy(pd->frame.win.id);
}
void screen_PID_draw(screen_t* screen)
{
}
int screen_PID_event(screen_t* screen, window_t* window, uint8_t event, void* param)
{
if (status_footer_event(&(pd->footer), window, event, param)){
return 1;
}
status_footer_event(&(pd->footer), window, event, param);
if (event == WINDOW_EVENT_CLICK)
switch ((int)param){
case TAG_QUIT:
if (pd->autotune_state != AT_idle) return 0;//button should not be accessible
screen_close();
return 1;
case TAG_AUTOTUNE_APPLY_E:
if(pd->list_RW_E_index_actual == 0){
//run autotune
_autotune_E(screen, &(pd->autotune_state));
}else{
//apply values
_PID_set(&(pd->_PID_E),
get_single_PIDparamFromDisp(pd->idsDigits_Kp_E,
SPIN_DIGITS,SPIN_PRECISION),
get_single_PIDparamFromDisp(pd->idsDigits_Ki_E,
SPIN_DIGITS,SPIN_PRECISION),
get_single_PIDparamFromDisp(pd->idsDigits_Kd_E,
SPIN_DIGITS,SPIN_PRECISION)
);
marlin_gcode("M500");//store to eeprom
}
break;
case TAG_AUTOTUNE_APPLY_B:
if(pd->list_RW_B_index_actual == 0){
//run autotune
_autotune_B(screen, &(pd->autotune_state));
}else{
//apply values
_PID_set(&(pd->_PID_B),
get_single_PIDparamFromDisp(pd->idsDigits_Kp_B,
SPIN_DIGITS,SPIN_PRECISION),
get_single_PIDparamFromDisp(pd->idsDigits_Ki_B,
SPIN_DIGITS,SPIN_PRECISION),
get_single_PIDparamFromDisp(pd->idsDigits_Kd_B,
SPIN_DIGITS,SPIN_PRECISION)
);
marlin_gcode("M500");//store to eeprom
}
break;
case TAG_CHANGE_VAL_E:
//not used, there is apply button
break;
case TAG_CHANGE_VAL_B:
//not used, there is apply button
break;
}
if (event == WINDOW_EVENT_CHANGE){
switch ((int)param){
case TAG_RW_E:
break;
case TAG_RW_B:
break;
}
}
if (event == WINDOW_EVENT_LOOP)
{
if (pd->autotune_state != AT_idle)
{
if (marlin_event(MARLIN_EVT_Ready)) //wait for MARLIN_EVT_READY
{
window_set_color_text(pd->btAutoTuneApply_B.win.id, AUTO_TN_DEFAULT_CL);
window_set_color_text(pd->btAutoTuneApply_E.win.id, AUTO_TN_DEFAULT_CL);
window_set_color_text(pd->textExit.win.id, AUTO_TN_DEFAULT_CL);
window_enable(pd->textExit.win.id);
pd->autotune_state = AT_idle;
}
}
pd->autotune_temp_E = window_get_value(pd->spinAutoTn_E.window.win.id);
pd->autotune_temp_B = window_get_value(pd->spinAutoTn_B.window.win.id);
pd->list_RW_E_index_actual = window_get_item_index(pd->list_RW_E.win.id);
if(pd->list_RW_E_index_actual != pd->list_RW_E_index_last){
if (pd->list_RW_E_index_actual == 0){
disable_digits_write_mode(pd->idsDigits_Kp_E,
sizeof(pd->idsDigits_Kp_E)/sizeof(pd->idsDigits_Kp_E[0]));
disable_digits_write_mode(pd->idsDigits_Ki_E,
sizeof(pd->idsDigits_Ki_E)/sizeof(pd->idsDigits_Ki_E[0]));
disable_digits_write_mode(pd->idsDigits_Kd_E,
sizeof(pd->idsDigits_Kd_E)/sizeof(pd->idsDigits_Kd_E[0]));
window_set_text(pd->btAutoTuneApply_E.win.id,
btnAutoTuneOrApplystrings[0]);
}else{
enable_digits_write_mode(pd->idsDigits_Kp_E,
sizeof(pd->idsDigits_Kp_E)/sizeof(pd->idsDigits_Kp_E[0]));
enable_digits_write_mode(pd->idsDigits_Ki_E,
sizeof(pd->idsDigits_Ki_E)/sizeof(pd->idsDigits_Ki_E[0]));
enable_digits_write_mode(pd->idsDigits_Kd_E,
sizeof(pd->idsDigits_Kd_E)/sizeof(pd->idsDigits_Kd_E[0]));
window_set_text(pd->btAutoTuneApply_E.win.id,
btnAutoTuneOrApplystrings[1]);
}
pd->list_RW_E_index_last = pd->list_RW_E_index_actual;
}
pd->list_RW_B_index_actual = window_get_item_index(pd->list_RW_B.win.id);
if(pd->list_RW_B_index_actual != pd->list_RW_B_index_last){
if (pd->list_RW_B_index_actual == 0){
disable_digits_write_mode(pd->idsDigits_Kp_B,
sizeof(pd->idsDigits_Kp_B)/sizeof(pd->idsDigits_Kp_B[0]));
disable_digits_write_mode(pd->idsDigits_Ki_B,
sizeof(pd->idsDigits_Ki_B)/sizeof(pd->idsDigits_Ki_B[0]));
disable_digits_write_mode(pd->idsDigits_Kd_B,
sizeof(pd->idsDigits_Kd_B)/sizeof(pd->idsDigits_Kd_B[0]));
window_set_text(pd->btAutoTuneApply_B.win.id,
btnAutoTuneOrApplystrings[0]);
}else{
enable_digits_write_mode(pd->idsDigits_Kp_B,
sizeof(pd->idsDigits_Kp_B)/sizeof(pd->idsDigits_Kp_B[0]));
enable_digits_write_mode(pd->idsDigits_Ki_B,
sizeof(pd->idsDigits_Ki_B)/sizeof(pd->idsDigits_Ki_B[0]));
enable_digits_write_mode(pd->idsDigits_Kd_B,
sizeof(pd->idsDigits_Kd_B)/sizeof(pd->idsDigits_Kd_B[0]));
window_set_text(pd->btAutoTuneApply_B.win.id,
btnAutoTuneOrApplystrings[1]);
}
pd->list_RW_B_index_last = pd->list_RW_B_index_actual;
}
if (pd->redraw){
pd->redraw = 0;
display->fill_rect(rect_ui16(pd->dot_coordsKp_E[0],
pd->dot_coordsKp_E[1],2,2), COLOR_WHITE);
display->fill_rect(rect_ui16(pd->dot_coordsKi_E[0],
pd->dot_coordsKi_E[1],2,2), COLOR_WHITE);
display->fill_rect(rect_ui16(pd->dot_coordsKd_E[0],
pd->dot_coordsKd_E[1],2,2), COLOR_WHITE);
display->draw_text(pd->rect_E,"NOZZLE", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->draw_text(pd->rectKp_E,"Kp", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->draw_text(pd->rectKi_E,"Ki", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->draw_text(pd->rectKd_E,"Kd", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->fill_rect(rect_ui16(pd->dot_coordsKp_B[0],
pd->dot_coordsKp_B[1],2,2), COLOR_WHITE);
display->fill_rect(rect_ui16(pd->dot_coordsKi_B[0],
pd->dot_coordsKi_B[1],2,2), COLOR_WHITE);
display->fill_rect(rect_ui16(pd->dot_coordsKd_B[0],
pd->dot_coordsKd_B[1],2,2), COLOR_WHITE);
display->draw_text(pd->rect_B,"BED", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->draw_text(pd->rectKp_B,"Kp", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->draw_text(pd->rectKi_B,"Ki", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
display->draw_text(pd->rectKd_B,"Kd", resource_font(IDR_FNT_NORMAL),
COLOR_BLACK, COLOR_ORANGE);
}
if (_PID_actualize(&(pd->_PID_E)) != 0){
dispPID((pd->_PID_E), pd->idsDigits_Kp_E, pd->idsDigits_Ki_E, pd->idsDigits_Kd_E,
SPIN_DIGITS,SPIN_PRECISION);
}
if (_PID_actualize(&(pd->_PID_B)) != 0){
dispPID((pd->_PID_B), pd->idsDigits_Kp_B, pd->idsDigits_Ki_B, pd->idsDigits_Kd_B,
SPIN_DIGITS,SPIN_PRECISION);
}
}
return 0;
}
extern "C"
{
screen_t screen_PID =
{
0,
0,
screen_PID_init,
screen_PID_done,
screen_PID_draw,
screen_PID_event,
sizeof(screen_PID_data_t), //data_size
0, //pdata
};
const screen_t* pscreen_PID = &screen_PID;
}
//-----------------------------------------------------------------------------
void _PID_copy_and_scale_PID_i(_PID_t* ths)
{
*ths->p_Ki = scalePID_i(ths->raw_Ki);
thermalManager.updatePID();
}
void _PID_copy_and_scale_PID_d(_PID_t* ths)
{
*ths->p_Kd = scalePID_d(ths->raw_Kd);
thermalManager.updatePID();
}
void _PID_autotune(_PID_t* ths)
{
marlin_gcode_printf("M303 U1 E%i S%i", ths->ID, int(*ths->autotune_temp));
marlin_gcode("M500");
}
//0 the contents of both memory blocks are equal
int _PID_actualize(_PID_t* ths)
{
int ret_Kp = memcmp ( &(ths->Kp_last), ths->p_Kp, sizeof(ths->Kp_last) );
int ret_Ki = memcmp ( &(ths->Ki_last), ths->p_Ki, sizeof(ths->Ki_last) );
int ret_Kd = memcmp ( &(ths->Kd_last), ths->p_Kd, sizeof(ths->Kd_last) );
int ret = ret_Kp | ret_Ki | ret_Kd;
if (ret != 0){
ths->raw_Ki = unscalePID_i(*ths->p_Ki);// 0.01f, 9990
ths->raw_Kd = unscalePID_d(*ths->p_Kd);//1, 9990
//ths->raw_Ki = unscalePID_i(PID_PARAM(Ki, ths->ID));// 0.01f, 9990
//ths->raw_Kd = unscalePID_d(PID_PARAM(Kd, ths->ID));//1, 9990
ths->Kp_last = *ths->p_Kp;
ths->Ki_last = *ths->p_Ki;
ths->Kd_last = *ths->p_Kd;
}
return ret;
}
void _PID_ctor(_PID_t* ths, int16_t id, float* autotune_temp)
{
ths->ID = id;
ths->autotune_temp = autotune_temp;
//stupid Marlin has bed PID defined unlike extruder
if (id>=0){
ths->p_Kp = &PID_PARAM(Kp, ths->ID);
ths->p_Ki = &PID_PARAM(Ki, ths->ID);
ths->p_Kd = &PID_PARAM(Kd, ths->ID);
}else{
//should i use temp_bed.pid or tune_pid?
ths->p_Kp = &Temperature::temp_bed.pid.Kp;
ths->p_Ki = &Temperature::temp_bed.pid.Ki;
ths->p_Kd = &Temperature::temp_bed.pid.Kd;
}
ths->raw_Ki = unscalePID_i(*ths->p_Ki);
ths->raw_Kd = unscalePID_d(*ths->p_Kd);
//to be able to check changes
ths->Kp_last = *ths->p_Kp;
ths->Ki_last = *ths->p_Ki;
ths->Kd_last = *ths->p_Kd;
}
void _PID_set(_PID_t* ths, float Kp, float Ki, float Kd) {
*ths->p_Kp = Kp;
ths->raw_Ki = Ki;
ths->raw_Kd = Kd;
_PID_copy_and_scale_PID_i(ths);
_PID_copy_and_scale_PID_d(ths);
}
//-----------------------------------------------------------------------------
//autotune
bool __autotune(screen_t* screen, autotune_state_t* a_tn_st)
{
if ((*a_tn_st) != AT_idle) return 0;
window_disable(pd->textExit.win.id);
window_set_color_text(pd->textExit.win.id, AUTO_TN_ACTIVE_CL);
return 1;
}
void _autotune_B(screen_t* screen, autotune_state_t* a_tn_st)
{
if(__autotune(screen, a_tn_st))
{
_PID_autotune(&(pd->_PID_B));
window_set_color_text(pd->btAutoTuneApply_B.win.id, AUTO_TN_ACTIVE_CL);
*a_tn_st = AT_extruder;
}
}
void _autotune_E(screen_t* screen, autotune_state_t* a_tn_st)
{
if(__autotune(screen, a_tn_st))
{
_PID_autotune(&(pd->_PID_E));
window_set_color_text(pd->btAutoTuneApply_E.win.id, AUTO_TN_ACTIVE_CL);
*a_tn_st = AT_bed;
}
}
//-----------------------------------------------------------------------------
//gui spins
void generate_spin_single_digit(int16_t &id0, int16_t &id, window_spin_t& spin,
uint16_t &col, uint16_t row, uint16_t offset, uint16_t row_h )
{
id = window_create_ptr(WINDOW_CLS_SPIN , id0,
rect_ui16(col, row, offset, row_h), &spin);
spin.window.win.flg |= WINDOW_FLG_NUMB_FLOAT2INT;
window_set_format(id, "%d");
window_set_min_max_step(id, 0.0F, 9.0F, 1.0F);
window_set_value(id, 0.0F);
col += offset;
};
void enable_digits_write_mode(int16_t *ids, size_t sz){
for (size_t i = 0; i < sz; ++i) window_enable(ids[i]);
}
void disable_digits_write_mode(int16_t *ids, size_t sz){
for (size_t i = 0; i < sz; ++i) window_disable(ids[i]);
}
//i am not using size_t numOfDigits, size_t precision
//need to be signed because of for cycles
void generate_spin_digits(screen_t* screen, int numOfDigits, int precision,
int16_t &id0, int16_t *ids, window_spin_t* pSpin, uint16_t dot_coords[2],
uint16_t col, uint16_t row, uint16_t row_h ){
int16_t offset = 12;
dot_coords[0] = col+offset*(numOfDigits - precision)+1;
dot_coords[1] = row + 14;
for (int i = numOfDigits - 1; i >= precision; --i){
generate_spin_single_digit(id0, ids[i], pSpin[i], col, row, offset, row_h );
}
col += 3;
for (int i = precision - 1; i >= 0; --i){
generate_spin_single_digit(id0, ids[i], pSpin[i], col, row, offset, row_h );
}
disable_digits_write_mode(ids,numOfDigits);
}
//-----------------------------------------------------------------------------
//screen update methods
void disp_single_PID_digit(uint8_t singlePIDdigit, int16_t id){
if (window_get_item_index(id)!=singlePIDdigit){
window_set_item_index(id,singlePIDdigit);
//window_set_value(id,singlePIDdigit);
}
}
void disp_single_PID_param(uint32_t singlePIDparam,
int16_t* ids, size_t numOfDigits)
{
for (size_t i = 0; i < numOfDigits; ++i){
disp_single_PID_digit(singlePIDparam%10, ids[i]);
singlePIDparam = singlePIDparam/10;
}
}
void dispPID(_PID_t& PID, int16_t* KpIds, int16_t* KiIds, int16_t* KdIds,
size_t numOfDigits, size_t precision)
{
float multiplier = pow(10.0F,float(precision));
uint32_t Kp = PID.Kp_last * multiplier;
uint32_t Ki = PID.raw_Ki * multiplier;//scaled
uint32_t Kd = PID.raw_Kd * multiplier;//scaled
disp_single_PID_param(Kp, KpIds, numOfDigits);
disp_single_PID_param(Ki, KiIds, numOfDigits);
disp_single_PID_param(Kd, KdIds, numOfDigits);
}
uint8_t get_single_PIDdigitFromDisp(int16_t id){
return window_get_item_index(id);
}
//i am not using size_t, need negative values in for cycle
float get_single_PIDparamFromDisp(int16_t* ids, int numOfDigits, int precision)
{
int val = 0;
for (int i = numOfDigits-1; i >= 0; --i){
val *= 10;
val += get_single_PIDdigitFromDisp(ids[i]);
}
float multiplier = pow(10.0F,float(precision));
return float(val)/multiplier;
}
//-----------------------------------------------------------------------------
//list
void window_list_RW_item(window_list_t* pwindow_list, uint16_t index,
const char** pptext, uint16_t* pid_icon)
{
if (index < list_RW_strings_sz) *pptext = list_RW_strings[index];
else *pptext = "Index ERROR";
*pid_icon = 0;
}
#endif //PIDCALIBRATION