Skip to content

Commit

Permalink
Add touch calibration. Unload/Load takes temp/extrude len. Fixed spoo…
Browse files Browse the repository at this point in the history
…lman optional field. Fixed current layer count resets. Fixed mini print status not showing when the same file is printed repeatedly.
  • Loading branch information
ballaswag committed Apr 10, 2024
1 parent bcfa539 commit e21b163
Show file tree
Hide file tree
Showing 15 changed files with 999 additions and 205 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ include $(LVGL_DIR)/lvgl/lvgl.mk
include $(LVGL_DIR)/lv_drivers/lv_drivers.mk

CSRCS += $(wildcard $(LVGL_DIR)/assets/*.c)

CSRCS += $(wildcard $(LVGL_DIR)/lv_touch_calibration/*.c)

ASSET_DIR = material
ifdef GUPPY_SMALL_SCREEN
Expand Down Expand Up @@ -76,7 +76,7 @@ DEPS = $(addprefix $(BUILD_OBJ_DIR)/, $(patsubst %.o, %.d, $(
OBJS = $(AOBJS) $(COBJS) $(MAINOBJ)
TARGET = $(addprefix $(BUILD_OBJ_DIR)/, $(patsubst ./%, %, $(OBJS)))

INC := -I./ -I./lvgl/ -I./spdlog/include -Ilibhv/include -Iwpa_supplicant/src/common
INC := -I./ -I./lvgl/ -I./lv_touch_calibration -I./spdlog/include -Ilibhv/include -Iwpa_supplicant/src/common
LDLIBS := -lm

DEFINES += -D _GNU_SOURCE -DSPDLOG_COMPILED_LIB
Expand Down
23 changes: 23 additions & 0 deletions k1/scripts/guppy_cmd.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,26 @@ gcode:
command: /etc/init.d/S50dropbear
timeout: 600.0
verbose: True


#### k1 load and unload ###
[gcode_macro _GUPPY_LOAD_MATERIAL]
gcode:
{% set extruder_temp = params.EXTRUDER_TEMP|default(240)|int %}
{% set extrude_len = params.EXTRUDE_LEN|default(35)|int %}
LOAD_MATERIAL_CLOSE_FAN2
M109 S{extruder_temp}
G91
G1 E{extrude_len} F180
LOAD_MATERIAL_RESTORE_FAN2 # k1 stuff

[gcode_macro _GUPPY_QUIT_MATERIAL]
gcode:
{% set extruder_temp = params.EXTRUDER_TEMP|default(240)|int %}
SAVE_GCODE_STATE NAME=myMoveState
M109 S{extruder_temp}
G91
G1 E20 F180
G1 E-30 F180
G1 E-50 F2000
RESTORE_GCODE_STATE NAME=myMoveState
193 changes: 193 additions & 0 deletions lv_touch_calibration/lv_tc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*********************
* INCLUDES
*********************/

#include "lv_tc.h"

#include "math.h"

#ifdef ESP_PLATFORM
#include "esp_log.h"
#endif

/**********************
* DEFINES
*********************/
#define TAG "lv_tc"

/**********************
* STATIC PROTOTYPES
**********************/

static void lv_tc_indev_drv_read_cb(lv_indev_drv_t *indevDrv, lv_indev_data_t *data);


/**********************
* STATIC VARIABLES
**********************/

static lv_tc_coeff_t calibResult = {false, 0, 0, 0, 0, 0, 0};

static lv_obj_t *registeredTCScreen = NULL;
static bool (*registeredInputCb)(lv_obj_t *screenObj, lv_indev_data_t *data) = NULL;
static void (*registeredSaveCb)(lv_tc_coeff_t coeff) = NULL;


/**********************
* GLOBAL FUNCTIONS
**********************/

void lv_tc_indev_drv_init(lv_indev_drv_t *indevDrv, void (*readCb)(lv_indev_drv_t *indevDrv, lv_indev_data_t *data)) {
lv_indev_drv_init(indevDrv);
indevDrv->type = LV_INDEV_TYPE_POINTER;
indevDrv->read_cb = lv_tc_indev_drv_read_cb;
indevDrv->user_data = readCb;
}

void _lv_tc_register_input_cb(lv_obj_t *screenObj, bool (*inputCb)(lv_obj_t *screenObj, lv_indev_data_t *data)) {
registeredTCScreen = screenObj;
registeredInputCb = inputCb;
}

void lv_tc_register_coeff_save_cb(void (*saveCb)(lv_tc_coeff_t coeff)) {
registeredSaveCb = saveCb;
}

lv_tc_coeff_t* lv_tc_get_coeff() {
return &calibResult;
}

void lv_tc_set_coeff(lv_tc_coeff_t coeff, bool save) {
calibResult = coeff;

if(save) {
lv_tc_save_coeff();
}
}

#if defined CONFIG_USE_CUSTOM_LV_TC_COEFFICIENTS
void lv_tc_load_coeff_from_config() {
lv_tc_coeff_t coeff = {
true,
atoff(CONFIG_LV_TC_COEFFICIENT_A),
atoff(CONFIG_LV_TC_COEFFICIENT_B),
atoff(CONFIG_LV_TC_COEFFICIENT_C),
atoff(CONFIG_LV_TC_COEFFICIENT_D),
atoff(CONFIG_LV_TC_COEFFICIENT_E),
atoff(CONFIG_LV_TC_COEFFICIENT_F)
};
lv_tc_set_coeff(coeff, false);
}
#endif

void lv_tc_save_coeff() {
if(registeredSaveCb) {
registeredSaveCb(calibResult);
}
}

void lv_tc_compute_coeff(lv_point_t *scrP, lv_point_t *tchP, bool save) { //The computation is explained here: https://www.maximintegrated.com/en/design/technical-documents/app-notes/5/5296.html
const lv_tc_val_t divisor = (
(lv_tc_val_t)tchP[0].x * ((lv_tc_val_t)tchP[2].y - (lv_tc_val_t)tchP[1].y)
- (lv_tc_val_t)tchP[1].x * (lv_tc_val_t)tchP[2].y
+ (lv_tc_val_t)tchP[1].y * (lv_tc_val_t)tchP[2].x
+ (lv_tc_val_t)tchP[0].y * ((lv_tc_val_t)tchP[1].x - (lv_tc_val_t)tchP[2].x)
);

lv_tc_coeff_t result = {
true,
(
(lv_tc_val_t)scrP[0].x * ((lv_tc_val_t)tchP[2].y - (lv_tc_val_t)tchP[1].y)
- (lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].y
+ (lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].y
+ ((lv_tc_val_t)scrP[1].x - (lv_tc_val_t)scrP[2].x) * (lv_tc_val_t)tchP[0].y
) / divisor,
- (
(lv_tc_val_t)scrP[0].x * ((lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x)
- (lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].x
+ (lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].x
+ ((lv_tc_val_t)scrP[1].x - (lv_tc_val_t)scrP[2].x) * (lv_tc_val_t)tchP[0].x
) / divisor,
(
(lv_tc_val_t)scrP[0].x * ((lv_tc_val_t)tchP[1].y * (lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x * (lv_tc_val_t)tchP[2].y)
+ (lv_tc_val_t)tchP[0].x * ((lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].y - (lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].y)
+ (lv_tc_val_t)tchP[0].y * ((lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].x - (lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].x)
) / divisor,
(
(lv_tc_val_t)scrP[0].y * ((lv_tc_val_t)tchP[2].y - (lv_tc_val_t)tchP[1].y)
- (lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].y
+ (lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].y
+ ((lv_tc_val_t)scrP[1].y - (lv_tc_val_t)scrP[2].y) * (lv_tc_val_t)tchP[0].y
) / divisor,
- (
(lv_tc_val_t)scrP[0].y * ((lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x)
- (lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].x
+ (lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].x
+ ((lv_tc_val_t)scrP[1].y - (lv_tc_val_t)scrP[2].y) * (lv_tc_val_t)tchP[0].x
) / divisor,
(
(lv_tc_val_t)scrP[0].y * ((lv_tc_val_t)tchP[1].y * (lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x * (lv_tc_val_t)tchP[2].y)
+ (lv_tc_val_t)tchP[0].x * ((lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].y - (lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].y)
+ (lv_tc_val_t)tchP[0].y * ((lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].x - (lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].x)
) / divisor
};

lv_tc_set_coeff(result, save);

#ifdef ESP_PLATFORM
ESP_LOGI(TAG, "touch calibration coefficients -> [a: %f, b: %f, c: %f, d: %f, e: %f, f: %f]", result.a, result.b,
result.c, result.d, result.e, result.f);
#endif
}

lv_point_t _lv_tc_transform_point_indev(lv_indev_data_t *data) {
if(data->state == LV_INDEV_STATE_PRESSED) {
return lv_tc_transform_point(data->point);
} else {
//Reject invalid points if the touch panel is in released state
lv_point_t point = {0, 0};
return point;
}
}

lv_point_t lv_tc_transform_point(lv_point_t point) {
lv_point_t transformedPoint = point;
if (calibResult.isValid) {
transformedPoint.x = roundf((lv_tc_val_t)point.x * calibResult.a + (lv_tc_val_t)point.y * calibResult.b + calibResult.c);
transformedPoint.y = roundf((lv_tc_val_t)point.x * calibResult.d + (lv_tc_val_t)point.y * calibResult.e + calibResult.f);

lv_disp_t *disp = lv_disp_get_default();
if (disp->driver->rotated == LV_DISP_ROT_90 || disp->driver->rotated == LV_DISP_ROT_270) {
lv_coord_t tmp = transformedPoint.y;
transformedPoint.y = transformedPoint.x;
transformedPoint.x = lv_disp_get_ver_res(NULL) - tmp - 1;
}
}

return transformedPoint;
}

/**********************
* STATIC FUNCTIONS
**********************/

static void lv_tc_indev_drv_read_cb(lv_indev_drv_t *indevDrv, lv_indev_data_t *data) {
if(!indevDrv->user_data) return;

//Call the actual indev read callback
((void (*)(lv_indev_drv_t*, lv_indev_data_t*))indevDrv->user_data)(indevDrv, data);

//Pass the results to an ongoing calibration if there is one
if(registeredTCScreen && registeredInputCb && registeredTCScreen == lv_scr_act()) {
if(!registeredInputCb(registeredTCScreen, data)) {
//Override state and point if the input has been handled by the registered calibration screen
data->state = LV_INDEV_STATE_RELEASED;
lv_point_t point = {0, 0};
data->point = point;

return;
}
}

data->point = _lv_tc_transform_point_indev(data);
}
115 changes: 115 additions & 0 deletions lv_touch_calibration/lv_tc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

/*********************
* INCLUDES
*********************/

#include "stdbool.h"
#include "lvgl.h"


/**********************
* TYPEDEFS
**********************/

typedef float lv_tc_val_t;

typedef struct {
bool isValid;

lv_tc_val_t a;
lv_tc_val_t b;
lv_tc_val_t c;
lv_tc_val_t d;
lv_tc_val_t e;
lv_tc_val_t f;
} lv_tc_coeff_t;


/**********************
* GLOBAL PROTOTYPES
**********************/

/**
* Initialize a calibrated touch input driver.
* @param indevDrv pointer to an input driver
* @param readCb function pointer to read input driver data
*/
void lv_tc_indev_drv_init(lv_indev_drv_t *indevDrv, void (*readCb)(struct _lv_indev_drv_t *indevDrv, lv_indev_data_t *data));

/**
* Register a calibration screen to the modified input driver.
* NOT TO BE CALLED IN APPLICATION CODE
* @param screenObj pointer to the screen object
* @param inputCb function pointer to handle the input
*/
void _lv_tc_register_input_cb(lv_obj_t *screenObj, bool (*inputCb)(lv_obj_t *screenObj, lv_indev_data_t *data));


/**
* Register a calibration coefficients save callback.
* It will be called on completion of the calibration steps.
* @param saveCb function pointer to save the coefficients (a lv_tc_coeff_t structure)
*/
void lv_tc_register_coeff_save_cb(void (*saveCb)(lv_tc_coeff_t coeff));


/**
* Get the current calibration coefficients.
* @returns pointer to the coefficients structure (lv_tc_coeff_t*)
*/
lv_tc_coeff_t* lv_tc_get_coeff();

/**
* Set the current calibration coefficients.
* @param coeff the new coefficients structure (lv_tc_coeff_t)
* @param save select whether to save the coefficients or just to keep them in volatile storage
*/
void lv_tc_set_coeff(lv_tc_coeff_t coeff, bool save);

/**
* Load previously calibrated coefficient data if defined in the config
*/
#if defined CONFIG_USE_CUSTOM_LV_TC_COEFFICIENTS
void lv_tc_load_coeff_from_config();
#endif

/**
* Save the current calibration coefficients.
*/
void lv_tc_save_coeff();

/**
* Compute calibration coefficients for a given set of points on the screen and touch panel.
* @param scrP pointer to the first element of an array containing the screen points
* @param tchP pointer to the first element of an array containing the touch panel points
* @param save select whether to save the coefficients or just to keep them in volatile storage
*/
void lv_tc_compute_coeff(lv_point_t *scrP, lv_point_t *tchP, bool save);


/**
* Transform a point read by an input driver into a point on the screen.
* NOT TO BE CALLED IN APPLICATION CODE
* @param data pointer to data from the input driver (lv_indev_data_t*)
* @returns the point (lv_point_t)
*/
lv_point_t _lv_tc_transform_point_indev(lv_indev_data_t *data);

/**
* Transform a point on the touch panel into a point on the screen.
* @param point the point on the touch panel (lv_point_t)
* @returns the point on the screen (lv_point_t)
*/
lv_point_t lv_tc_transform_point(lv_point_t point);




#ifdef __cplusplus
}
#endif
Loading

0 comments on commit e21b163

Please sign in to comment.