Merge pull request #51 from suchmememanyskill/dev

v1.4.0
This commit is contained in:
Sims
2024-02-21 23:33:13 +01:00
committed by GitHub
27 changed files with 917 additions and 218 deletions

View File

@@ -12,6 +12,8 @@
"algorithm": "cpp",
"cstddef": "cpp",
"functional": "cpp",
"*.tcc": "cpp"
}
"*.tcc": "cpp",
"cmath": "cpp"
},
"cmake.configureOnOpen": false
}

View File

@@ -0,0 +1,126 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S022C'",
"'-D LCD_WIDTH=240'",
"'-D LCD_HEIGHT=320'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/8)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D BCKL=0'",
"'-D LCD_ST7789_I80'",
"'-D ST7789_I80_BUS_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-D ST7789_I80_BUS_CONFIG_DC=16'",
"'-D ST7789_I80_BUS_CONFIG_WR=4'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D8=15'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D9=13'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D10=12'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D11=14'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D12=27'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D13=25'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D14=33'",
"'-D ST7789_I80_BUS_CONFIG_DATA_GPIO_D15=32'",
"'-D ST7789_I80_BUS_CONFIG_BUS_WIDTH=8'",
"'-D ST7789_I80_BUS_CONFIG_MAX_TRANSFER_BYTES=(LVGL_BUFFER_PIXELS * sizeof(lv_color_t))'",
"'-D ST7789_I80_BUS_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7789_I80_BUS_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7789_IO_I80_CONFIG_CS_GPIO_NUM=17'",
"'-D ST7789_IO_I80_CONFIG_PCLK_HZ=55000000'",
"'-D ST7789_IO_I80_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7789_IO_I80_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7789_IO_I80_CONFIG_LCD_PARAM_BITS=8'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_IDLE_LEVEL=0'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_CMD_LEVEL=0'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DUMMY_LEVEL=0'",
"'-D ST7789_IO_I80_CONFIG_DC_LEVELS_DC_DATA_LEVEL=1'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_CS_ACTIVE_HIGH=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_REVERSE_COLOR_BITS=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_SWAP_COLOR_BYTES=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_ACTIVE_NEG=0'",
"'-D ST7789_IO_I80_CONFIG_FLAGS_PCLK_IDLE_LOW=0'",
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
"'-D ST7789_RD_GPIO=2'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=false'",
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_CST816S_I2C'",
"'-D CST816S_I2C_HOST=0'",
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=21'",
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=22'",
"'-D CST816S_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_ENABLE'",
"'-D CST816S_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_ENABLE'",
"'-D CST816S_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D CST816S_I2C_CONFIG_CLK_FLAGS=0'",
"'-D CST816S_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_CST816S_ADDRESS'",
"'-D CST816S_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D CST816S_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D CST816S_IO_I2C_CONFIG_LCD_CMD_BITS=8'",
"'-D CST816S_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D CST816S_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D CST816S_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D CST816S_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D CST816S_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=GPIO_NUM_NC'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=false'",
"'-D TOUCH_SWAP_X=false'",
"'-D TOUCH_SWAP_Y=false'",
"'-D BOARD_HAS_TF'",
"'-D TF_CS=5'",
"'-D TF_SPI_MOSI=23'",
"'-D TF_SPI_SCLK=18'",
"'-D TF_SPI_MISO=19'",
"'-D BOARD_HAS_SPEAK'",
"'-D SPEAK=26'",
"-DCYD_SCREEN_GAP_PX=8",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-2432S022C",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005006284154750.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,126 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S028Rv3'",
"'-D LCD_WIDTH=240'",
"'-D LCD_HEIGHT=320'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D BCKL=21'",
"'-D LCD_ST7789_SPI'",
"'-D ST7789_SPI_HOST=SPI2_HOST'",
"'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ST7789_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ST7789_SPI_BUS_MISO_IO_NUM=GPIO_NUM_NC'",
"'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ST7789_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ST7789_SPI_BUS_MAX_TRANSFER_SZ=0'",
"'-D ST7789_SPI_BUS_FLAGS=0'",
"'-D ST7789_SPI_BUS_INTR_FLAGS=0'",
"'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'",
"'-D ST7789_SPI_CONFIG_PCLK_HZ=55000000'",
"'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ST7789_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ST7789_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ST7789_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ST7789_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
"'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=false'",
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_XPT2046_SPI'",
"'-D XPT2046_SPI_HOST=SPI3_HOST'",
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=32'",
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=39'",
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=25'",
"'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=33'",
"'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'",
"'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'",
"'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'",
"'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
"'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=36'",
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=true'",
"'-D TOUCH_SWAP_X=true'",
"'-D TOUCH_SWAP_Y=false'",
"'-D BOARD_HAS_TF'",
"'-D TF_CS=5'",
"'-D TF_SPI_MOSI=23'",
"'-D TF_SPI_SCLK=18'",
"'-D TF_SPI_MISO=19'",
"'-D BOARD_HAS_RGB_LED'",
"'-D RGB_LED_R=4'",
"'-D RGB_LED_G=16'",
"'-D RGB_LED_B=17'",
"'-D BOARD_HAS_CDS'",
"'-D CDS=34'",
"'-D BOARD_HAS_SPEAK'",
"'-D SPEAK=26'",
"-DCYD_SCREEN_GAP_PX=8",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=35",
"-DCYD_SCREEN_FONT=lv_font_montserrat_14",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_10",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=40",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",
"flash_mode": "dio",
"mcu": "esp32",
"variant": "esp32"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet",
"can"
],
"debug": {
"openocd_board": "esp-wroom-32.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-2432S028Rv3",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004502250619.html",
"vendor": "Sunton"
}

View File

@@ -16,9 +16,6 @@
"-DTFT_DC=2",
"-DTFT_RST=-1",
"-DLOAD_GCLD=1",
"-DLOAD_FONT2=1",
"-DLOAD_GFXFF=1",
"-DSMOOTH_FONT=1",
"-DSPI_FREQUENCY=55000000",
"-DSPI_READ_FREQUENCY=20000000",
"-DSPI_TOUCH_FREQUENCY=2500000",

View File

@@ -21,7 +21,7 @@
"'-D ST7796_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ST7796_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ST7796_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ST7796_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ST7796_SPI_CONFIG_PCLK_HZ=80000000'",
"'-D ST7796_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ST7796_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'",
@@ -74,7 +74,17 @@
"'-D BOARD_HAS_CDS'",
"'-D CDS=34'",
"'-D BOARD_HAS_SPEAK'",
"'-D SPEAK=26'"
"'-D SPEAK=26'",
"-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40",
"-DCYD_SCREEN_FONT=lv_font_montserrat_16",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=50",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
"-DCYD_SCREEN_DISABLE_INVERT_COLORS=1"
],
"f_cpu": "240000000L",
"f_flash": "40000000L",

View File

@@ -16,9 +16,6 @@
"-DTFT_DC=2",
"-DTFT_RST=-1",
"-DLOAD_GCLD=1",
"-DLOAD_FONT2=1",
"-DLOAD_GFXFF=1",
"-DSMOOTH_FONT=1",
"-DSPI_FREQUENCY=80000000",
"-DSPI_READ_FREQUENCY=20000000",
"-DSPI_TOUCH_FREQUENCY=2500000",

View File

@@ -15,11 +15,17 @@ except:
version = "Unknown"
flag = "-D REPO_VERSION=\\\"" + version + "\\\""
dev_flag = "-DREPO_DEVELOPMENT=1"
print(f"Version: {version}")
print(f"Flag: {flag}")
flags = [flag]
if ('(' in version):
flags.append(dev_flag)
Import("env")
env.Append(
BUILD_FLAGS=[flag]
BUILD_FLAGS=flags
)

View File

@@ -21,7 +21,7 @@ monitor_filters = esp32_exception_decoder
build_flags =
-DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
extra_scripts =
pre:extract_commit.py
pre:extract_commit.py
[env:esp32-2432S028R]
board = esp32-2432S028R
@@ -43,17 +43,8 @@ lib_deps =
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
# Terribly slow. Only use for development
# [env:esp32-3248S035C-smartdisplay]
# board = esp32-3248S035C-smartdisplay
# build_flags =
# -DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
# -DCYD_SCREEN_HEIGHT_PX=320
# -DCYD_SCREEN_WIDTH_PX=480
# -DCYD_SCREEN_GAP_PX=10
# -DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=40
# -DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=40
# -DCYD_SCREEN_FONT=lv_font_montserrat_16
# -DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_12
# -DCYD_SCREEN_SIDEBAR_SIZE_PX=50
# -DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1
[env:esp32-3248S035C-smartdisplay]
board = esp32-3248S035C-smartdisplay
[env:esp32-2432S028R-smartdisplay]
board = esp32-2432S028R-smartdisplay

View File

@@ -5,6 +5,12 @@
#define CONFIG_VERSION 4
enum {
REMAINING_TIME_CALC_PERCENTAGE = 0,
REMAINING_TIME_CALC_INTERPOLATED = 1,
REMAINING_TIME_CALC_SLICER = 2,
};
typedef struct _GLOBAL_CONFIG {
unsigned char version;
union {
@@ -21,6 +27,10 @@ typedef struct _GLOBAL_CONFIG {
bool rotateScreen : 1;
bool onDuringPrint : 1;
bool autoOtaUpdate : 1;
unsigned char remaining_time_calc_mode : 2;
// Internal
bool auth_configured : 1;
};
};
float screenCalXOffset;
@@ -40,6 +50,8 @@ typedef struct _GLOBAL_CONFIG {
unsigned short hotend_presets[3];
unsigned short bed_presets[3];
char klipper_auth[33];
} GLOBAL_CONFIG;
typedef struct _COLOR_DEF {

View File

@@ -242,8 +242,12 @@
* Others
*-----------*/
#ifndef REPO_DEVELOPMENT
#define REPO_DEVELOPMENT 0
#endif
/*1: Show CPU usage and FPS count*/
#define LV_USE_PERF_MONITOR 0
#define LV_USE_PERF_MONITOR REPO_DEVELOPMENT
#if LV_USE_PERF_MONITOR
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
#endif
@@ -497,7 +501,7 @@
#define LV_USE_MSG 1
#define LV_USE_CHART 0
#define LV_USE_CHART 1
#define LV_USE_COLORWHEEL 0

View File

@@ -50,6 +50,9 @@ void send_gcode(bool wait, const char *gcode)
HTTPClient client;
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
if (!wait)
{
client.setTimeout(1000);
@@ -65,6 +68,63 @@ void send_gcode(bool wait, const char *gcode)
}
}
int get_slicer_time_estimate_s()
{
if (printer.state == PRINTER_STATE_IDLE)
return 0;
delay(10);
char buff[256] = {};
sprintf(buff, "http://%s:%d/server/files/metadata?filename=%s", global_config.klipperHost, global_config.klipperPort, urlEncode(printer.print_filename).c_str());
HTTPClient client;
client.useHTTP10(true);
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.GET();
if (httpCode != 200)
return 0;
JsonDocument doc;
deserializeJson(doc, client.getStream());
int time_estimate_s = doc["result"]["estimated_time"];
Serial.printf("Got slicer time estimate: %ds\n", time_estimate_s);
return time_estimate_s;
}
void move_printer(const char* axis, float amount, bool relative) {
if (!printer.homed_axis || printer.state == PRINTER_STATE_PRINTING)
return;
char gcode[64];
const char* extra = (amount > 0) ? "+" : "";
bool absolute_coords = printer.absolute_coords;
if (absolute_coords && relative) {
send_gcode(true, "G91");
}
else if (!absolute_coords && !relative) {
send_gcode(true, "G90");
}
sprintf(gcode, "G1 %s%s%.3f F6000", axis, extra, amount);
send_gcode(true, gcode);
if (absolute_coords && relative) {
send_gcode(true, "G90");
}
else if (!absolute_coords && !relative) {
send_gcode(true, "G91");
}
}
int last_slicer_time_query = -15000;
void fetch_printer_data()
{
freeze_request_thread();
@@ -73,6 +133,10 @@ void fetch_printer_data()
HTTPClient client;
client.useHTTP10(true);
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.GET();
delay(10);
if (httpCode == 200)
@@ -122,6 +186,7 @@ void fetch_printer_data()
printer.extruder_target_temp = status["extruder"]["target"];
bool can_extrude = status["extruder"]["can_extrude"];
printer.pressure_advance = status["extruder"]["pressure_advance"];
printer.smooth_time = status["extruder"]["smooth_time"];
printer.can_extrude = can_extrude == true;
}
@@ -175,7 +240,11 @@ void fetch_printer_data()
const char *state = status["print_stats"]["state"];
if (strcmp(state, "printing") == 0)
if (state == nullptr)
{
printer_state = PRINTER_STATE_ERROR;
}
else if (strcmp(state, "printing") == 0)
{
printer_state = PRINTER_STATE_PRINTING;
}
@@ -194,7 +263,36 @@ void fetch_printer_data()
if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0)
{
printer.remaining_time_s = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s;
float remaining_time_s_percentage = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s;
float remaining_time_s_slicer = 0;
if (printer.slicer_estimated_print_time_s > 0)
{
remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.elapsed_time_s;
}
if (remaining_time_s_slicer <= 0 || global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE)
{
printer.remaining_time_s = remaining_time_s_percentage;
}
else if (global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_INTERPOLATED)
{
printer.remaining_time_s = remaining_time_s_percentage * printer.print_progress + remaining_time_s_slicer * (1 - printer.print_progress);
}
else if (global_config.remaining_time_calc_mode == REMAINING_TIME_CALC_SLICER)
{
printer.remaining_time_s = remaining_time_s_slicer;
}
}
if (printer.remaining_time_s < 0)
{
printer.remaining_time_s = 0;
}
if (printer.state == PRINTER_STATE_IDLE)
{
printer.slicer_estimated_print_time_s = 0;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);
@@ -205,6 +303,13 @@ void fetch_printer_data()
printer.state = printer_state;
lv_msg_send(DATA_PRINTER_STATE, &printer);
}
if (printer.state == PRINTER_STATE_PRINTING && millis() - last_slicer_time_query > 30000 && printer.slicer_estimated_print_time_s <= 0)
{
delay(10);
last_slicer_time_query = millis();
printer.slicer_estimated_print_time_s = get_slicer_time_estimate_s();
}
unfreeze_render_thread();
}

View File

@@ -23,8 +23,8 @@ typedef struct _Printer {
float elapsed_time_s;
float remaining_time_s;
float filament_used_mm;
char* print_filename; // 0 -> 1
float print_progress;
char* print_filename;
float print_progress; // 0 -> 1
float fan_speed; // 0 -> 1
float gcode_offset[3];
float speed_mult;
@@ -32,7 +32,9 @@ typedef struct _Printer {
int total_layers;
int current_layer;
float pressure_advance;
float smooth_time;
int feedrate_mm_per_s;
int slicer_estimated_print_time_s;
} Printer;
extern Printer printer;
@@ -45,6 +47,7 @@ extern int klipper_request_consecutive_fail_count;
void data_loop();
void data_setup();
void send_gcode(bool wait, const char* gcode);
void move_printer(const char* axis, float amount, bool relative);
void freeze_request_thread();
void unfreeze_request_thread();

View File

@@ -25,71 +25,6 @@ static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
TFT_eSPI tft = TFT_eSPI();
TS_Point touchscreen_point()
{
TS_Point p = touchscreen.getPoint();
p.x = round((p.x * global_config.screenCalXMult) + global_config.screenCalXOffset);
p.y = round((p.y * global_config.screenCalYMult) + global_config.screenCalYOffset);
return p;
}
void touchscreen_calibrate(bool force)
{
if (global_config.screenCalibrated && !force)
{
return;
}
tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 140);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextSize(2);
tft.println("Calibrate Screen");
TS_Point p;
int16_t x1, y1, x2, y2;
while (touchscreen.touched())
;
tft.drawFastHLine(0, 10, 20, ILI9341_WHITE);
tft.drawFastVLine(10, 0, 20, ILI9341_WHITE);
while (!touchscreen.touched())
;
delay(50);
p = touchscreen.getPoint();
x1 = p.x;
y1 = p.y;
tft.drawFastHLine(0, 10, 20, ILI9341_BLACK);
tft.drawFastVLine(10, 0, 20, ILI9341_BLACK);
delay(500);
while (touchscreen.touched())
;
tft.drawFastHLine(300, 230, 20, ILI9341_WHITE);
tft.drawFastVLine(310, 220, 20, ILI9341_WHITE);
while (!touchscreen.touched())
;
delay(50);
p = touchscreen.getPoint();
x2 = p.x;
y2 = p.y;
tft.drawFastHLine(300, 230, 20, ILI9341_BLACK);
tft.drawFastVLine(310, 220, 20, ILI9341_BLACK);
int16_t xDist = 320 - 20;
int16_t yDist = 240 - 20;
global_config.screenCalXMult = (float)xDist / (float)(x2 - x1);
global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult);
global_config.screenCalYMult = (float)yDist / (float)(y2 - y1);
global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult);
global_config.screenCalibrated = true;
WriteGlobalConfig();
}
void screen_setBrightness(byte brightness)
{
// calculate duty, 4095 from 2 ^ 12 - 1
@@ -116,7 +51,7 @@ void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
if (touchscreen.tirqTouched() && touchscreen.touched())
{
TS_Point p = touchscreen_point();
TS_Point p = touchscreen.getPoint();
data->state = LV_INDEV_STATE_PR;
data->point.x = p.x;
data->point.y = p.y;
@@ -152,8 +87,6 @@ void screen_setup()
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);
touchscreen_calibrate(false);
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10);
/*Initialize the display*/

View File

@@ -7,11 +7,8 @@
#include "lvgl.h"
#include "../lv_setup.h"
void touchscreen_calibrate(bool force)
{
// TODO: Stubbed
return;
}
typedef void (*lv_disp_drv_t_flush_cb)(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
static lv_disp_drv_t_flush_cb original_screen_driver;
void screen_setBrightness(byte brightness)
{
@@ -19,13 +16,34 @@ void screen_setBrightness(byte brightness)
}
void set_invert_display(){
// Stubbed
lv_obj_invalidate(lv_scr_act());
}
void lv_screen_intercept(_lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
if (global_config.invertColors) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
for (int i = 0 ; i < w * h; i++){
color_p[i].full ^= 0xFFFF;
}
}
original_screen_driver(disp_drv, area, color_p);
}
void screen_setup()
{
smartdisplay_init();
#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
if (original_screen_driver == NULL){
original_screen_driver = lv_disp_get_default()->driver->flush_cb;
lv_disp_get_default()->driver->flush_cb = lv_screen_intercept;
}
#endif // CYD_SCREEN_DISABLE_INVERT_COLORS
lv_disp_set_rotation(lv_disp_get_default(), (global_config.rotateScreen) ? LV_DISP_ROT_270 : LV_DISP_ROT_90);
}

View File

@@ -33,6 +33,10 @@ FILESYSTEM_FILE* get_files(int limit){
client.useHTTP10(true);
client.setTimeout(5000);
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.GET();
auto timer_parse = millis();

View File

@@ -2,6 +2,7 @@
#include "screen_driver.h"
#include "../conf/global_config.h"
#include "lvgl.h"
#include "../ui/ui_utils.h"
#include <Esp.h>
#ifndef CPU_FREQ_HIGH
@@ -13,8 +14,131 @@
typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
bool isScreenInSleep = false;
lv_timer_t *screenSleepTimer;
bool is_screen_in_sleep = false;
lv_timer_t *screen_sleep_timer;
lv_coord_t point[2] = {0};
static lv_indev_drv_read_cb_t original_touch_driver = NULL;
void lv_touch_intercept_calibration(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
original_touch_driver(indev_driver, data);
if (data->state == LV_INDEV_STATE_PR){
point[0] = data->point.x;
point[1] = data->point.y;
while (data->state == LV_INDEV_STATE_PR){
original_touch_driver(indev_driver, data);
delay(20);
}
}
data->state = LV_INDEV_STATE_REL;
}
void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
original_touch_driver(indev_driver, data);
if (data->state == LV_INDEV_STATE_PR) {
if (is_screen_asleep()) {
while (data->state == LV_INDEV_STATE_PR) {
original_touch_driver(indev_driver, data);
delay(20);
}
data->state = LV_INDEV_STATE_REL;
}
screen_timer_wake();
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
data->point.x = round((data->point.x * global_config.screenCalXMult) + global_config.screenCalXOffset);
data->point.y = round((data->point.y * global_config.screenCalYMult) + global_config.screenCalYOffset);
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
}
}
void lv_do_calibration(){
if (global_config.screenCalibrated){
return;
}
lv_indev_t * display_driver = lv_indev_get_next(NULL);
display_driver->driver->read_cb = lv_touch_intercept_calibration;
lv_obj_clean(lv_scr_act());
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Calibrate Screen");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * line = lv_line_create(lv_scr_act());
static lv_point_t line_points_x[] = { {0, 10}, {21, 10} };
static lv_point_t line_points_y[] = { {10, 0}, {10, 21} };
lv_line_set_points(line, line_points_x, 2);
lv_obj_align(line, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_t * line2 = lv_line_create(lv_scr_act());
lv_line_set_points(line2, line_points_y, 2);
lv_obj_align(line2, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_line_width(line2, 1, 0);
while (true){
lv_timer_handler();
lv_task_handler();
if (point[0] != 0 && point[1] != 0){
break;
}
}
lv_coord_t x1 = point[0];
lv_coord_t y1 = point[1];
point[0] = 0;
point[1] = 0;
lv_obj_del(line);
lv_obj_del(line2);
line = lv_line_create(lv_scr_act());
lv_line_set_points(line, line_points_x, 2);
lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, 1, -10);
lv_obj_set_style_line_width(line, 1, 0);
line = lv_line_create(lv_scr_act());
lv_line_set_points(line, line_points_y, 2);
lv_obj_align(line, LV_ALIGN_BOTTOM_RIGHT, -10, 1);
while (true){
lv_timer_handler();
lv_task_handler();
if (point[0] != 0 && point[1] != 0){
break;
}
}
lv_coord_t x2 = point[0];
lv_coord_t y2 = point[1];
int16_t xDist = CYD_SCREEN_WIDTH_PX - 20;
int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20;
global_config.screenCalXMult = (float)xDist / (float)(x2 - x1);
global_config.screenCalXOffset = 10.0 - ((float)x1 * global_config.screenCalXMult);
global_config.screenCalYMult = (float)yDist / (float)(y2 - y1);
global_config.screenCalYOffset = 10.0 - ((float)y1 * global_config.screenCalYMult);
global_config.screenCalibrated = true;
WriteGlobalConfig();
lv_obj_clean(lv_scr_act());
}
void set_screen_brightness()
{
@@ -27,13 +151,13 @@ void set_screen_brightness()
void screen_timer_wake()
{
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
lv_timer_reset(screenSleepTimer);
lv_timer_reset(screen_sleep_timer);
if (!isScreenInSleep){
if (!is_screen_in_sleep){
return;
}
isScreenInSleep = false;
is_screen_in_sleep = false;
set_screen_brightness();
// Reset cpu freq
@@ -46,7 +170,7 @@ void screen_timer_sleep(lv_timer_t *timer)
{
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
screen_setBrightness(0);
isScreenInSleep = true;
is_screen_in_sleep = true;
// Screen is off, no need to make the cpu run fast, the user won't notice ;)
setCpuFrequencyMhz(CPU_FREQ_LOW);
@@ -56,23 +180,23 @@ void screen_timer_sleep(lv_timer_t *timer)
void screen_timer_setup()
{
screenSleepTimer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL);
lv_timer_pause(screenSleepTimer);
screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL);
lv_timer_pause(screen_sleep_timer);
}
void screen_timer_start()
{
lv_timer_resume(screenSleepTimer);
lv_timer_resume(screen_sleep_timer);
}
void screen_timer_stop()
{
lv_timer_pause(screenSleepTimer);
lv_timer_pause(screen_sleep_timer);
}
void screen_timer_period(unsigned int period)
{
lv_timer_set_period(screenSleepTimer, period);
lv_timer_set_period(screen_sleep_timer, period);
}
void set_screen_timer_period()
@@ -100,41 +224,28 @@ void set_color_scheme()
lv_disp_set_theme(dispp, theme);
}
static lv_indev_drv_read_cb_t original_driver = NULL;
void lv_touch_intercept(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
original_driver(indev_driver, data);
if (data->state == LV_INDEV_STATE_PR) {
if (is_screen_asleep()) {
while (data->state == LV_INDEV_STATE_PR) {
original_driver(indev_driver, data);
delay(20);
}
data->state = LV_INDEV_STATE_REL;
}
screen_timer_wake();
}
}
void lv_setup()
{
screen_timer_setup();
screen_timer_start();
lv_indev_t * display_driver = lv_indev_get_next(NULL);
if (original_touch_driver == NULL)
{
original_touch_driver = display_driver->driver->read_cb;
}
set_color_scheme();
if (original_driver != NULL)
return;
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_do_calibration();
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_indev_t * display_driver = lv_indev_get_next(NULL);
original_driver = display_driver->driver->read_cb;
display_driver->driver->read_cb = lv_touch_intercept;
screen_timer_setup();
screen_timer_start();
}
bool is_screen_asleep()
{
return isScreenInSleep;
return is_screen_in_sleep;
}

View File

@@ -18,6 +18,10 @@ static void _macros_query_internal(){
HTTPClient client;
client.useHTTP10(true);
client.begin(url.c_str());
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
@@ -42,23 +46,32 @@ static void _macros_query_internal(){
}
}
void power_devices_clear(){
for (int i = 0; i < power_devices_count; i++){
free(power_devices[i]);
}
power_devices_count = 0;
}
void _power_devices_query_internal(){
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/machine/device_power/devices";
HTTPClient client;
client.useHTTP10(true);
client.setTimeout(500);
client.setConnectTimeout(1000);
client.begin(url.c_str());
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"]["devices"].as<JsonArray>();
for (int i = 0; i < power_devices_count; i++){
free(power_devices[i]);
}
power_devices_count = 0;
power_devices_clear();
for (auto i : result){
const char * device_name = i["device"];
@@ -85,6 +98,10 @@ bool set_power_state(const char* device_name, bool state) {
HTTPClient client;
client.useHTTP10(true);
client.begin(url.c_str());
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
if (client.POST("") != 200)
return false;

View File

@@ -15,4 +15,5 @@ MACROSQUERY macros_query();
POWERQUERY power_devices_query();
void macros_query_setup();
bool set_power_state(const char* device_name, bool state);
void _power_devices_query_internal();
void _power_devices_query_internal();
void power_devices_clear();

View File

@@ -1,7 +1,6 @@
#pragma once
// Adapted from https://github.com/xperiments-in/xtouch/blob/main/src/devices/2.8/screen.h
void touchscreen_calibrate(bool force = false);
void screen_setBrightness(unsigned char brightness);
void screen_setup();
void set_invert_display();

View File

@@ -29,20 +29,35 @@ static const lv_btnmatrix_ctrl_t kb_ctrl[] = {
void ip_init_inner();
bool verify_ip(){
enum connection_status_t {
CONNECT_FAIL = 0,
CONNECT_OK = 1,
CONNECT_AUTH_REQUIRED = 2,
};
connection_status_t verify_ip(){
HTTPClient client;
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
int httpCode;
try {
Serial.println(url);
client.setTimeout(500);
client.setConnectTimeout(1000);
client.begin(url.c_str());
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
httpCode = client.GET();
return httpCode == 200;
Serial.printf("%d %s\n", httpCode, url.c_str());
if (httpCode == 401)
return CONNECT_AUTH_REQUIRED;
return httpCode == 200 ? CONNECT_OK : CONNECT_FAIL;
}
catch (...) {
Serial.println("Failed to connect");
return false;
return CONNECT_FAIL;
}
}
@@ -64,12 +79,19 @@ static void ta_event_cb(lv_event_t * e) {
strcpy(global_config.klipperHost, lv_textarea_get_text(hostEntry));
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry));
if (verify_ip())
connection_status_t status = verify_ip();
if (status == CONNECT_OK)
{
global_config.ipConfigured = true;
WriteGlobalConfig();
connect_ok = true;
}
else if (status == CONNECT_AUTH_REQUIRED)
{
label = NULL;
global_config.ipConfigured = true;
WriteGlobalConfig();
}
else
{
lv_label_set_text(label, "Failed to connect");
@@ -148,6 +170,77 @@ void redraw_connect_screen(){
}
}
static bool auth_entry_done = false;
static void keyboard_event_auth_entry(lv_event_t * e) {
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t * ta = lv_event_get_target(e);
lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e);
if (code == LV_EVENT_READY)
{
const char * txt = lv_textarea_get_text(ta);
int len = strlen(txt);
if (len > 0)
{
global_config.auth_configured = true;
strcpy(global_config.klipper_auth, txt);
WriteGlobalConfig();
auth_entry_done = true;
}
}
else if (code == LV_EVENT_CANCEL)
{
auth_entry_done = true;
}
}
void handle_auth_entry(){
auth_entry_done = false;
global_config.klipper_auth[32] = 0;
lv_obj_clean(lv_scr_act());
lv_obj_t * root = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(root);
lv_obj_t * top_root = lv_create_empty_panel(root);
lv_obj_set_width(top_root, CYD_SCREEN_WIDTH_PX);
lv_layout_flex_column(top_root);
lv_obj_set_flex_grow(top_root, 1);
lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0);
lv_obj_t * label = lv_label_create(top_root);
lv_label_set_text(label, "Enter API Key");
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_t * keyboard = lv_keyboard_create(root);
lv_obj_t * passEntry = lv_textarea_create(top_root);
lv_textarea_set_max_length(passEntry, 32);
lv_textarea_set_one_line(passEntry, true);
if (global_config.auth_configured)
lv_textarea_set_text(passEntry, global_config.klipper_auth);
else
lv_textarea_set_text(passEntry, "");
lv_obj_set_width(passEntry, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_add_event_cb(passEntry, keyboard_event_auth_entry, LV_EVENT_ALL, keyboard);
lv_obj_set_flex_grow(passEntry, 1);
lv_keyboard_set_textarea(keyboard, passEntry);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
while (!auth_entry_done) {
lv_timer_handler();
lv_task_handler();
}
redraw_connect_screen();
}
void ip_init_inner(){
if (global_config.ipConfigured) {
redraw_connect_screen();
@@ -203,6 +296,7 @@ int retry_count = 0;
void ip_init(){
connect_ok = false;
retry_count = 0;
int prev_power_device_count = 0;
ip_init_inner();
@@ -212,15 +306,25 @@ void ip_init(){
lv_task_handler();
if (!connect_ok && global_config.ipConfigured && (millis() - last_data_update_ip) > data_update_interval_ip){
connect_ok = verify_ip();
connection_status_t status = verify_ip();
connect_ok = status == CONNECT_OK;
last_data_update_ip = millis();
retry_count++;
String retry_count_text = "Connecting to Klipper (Try " + String(retry_count + 1) + ")";
lv_label_set_text(label, retry_count_text.c_str());
if (label != NULL){
String retry_count_text = "Connecting to Klipper (Try " + String(retry_count + 1) + ")";
lv_label_set_text(label, retry_count_text.c_str());
}
_power_devices_query_internal();
if (power_devices_query().count >= 1)
if (status != CONNECT_AUTH_REQUIRED)
_power_devices_query_internal();
else
handle_auth_entry();
if (power_devices_query().count != prev_power_device_count) {
prev_power_device_count = power_devices_query().count;
redraw_connect_screen();
}
}
}
}
@@ -228,6 +332,7 @@ void ip_init(){
void ip_ok(){
if (klipper_request_consecutive_fail_count > 5){
freeze_request_thread();
power_devices_clear();
ip_init();
unfreeze_request_thread();
klipper_request_consecutive_fail_count = 0;

View File

@@ -2,8 +2,8 @@
#include "panels/panel.h"
#include "../core/data_setup.h"
#include "nav_buttons.h"
#include <HTTPClient.h>
#include "ui_utils.h"
#include <stdio.h>
static lv_style_t nav_button_style;
@@ -137,6 +137,9 @@ void nav_buttons_setup(unsigned char active_panel){
case 4:
macros_panel_init(panel);
break;
case 5:
stats_panel_init(panel);
break;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);

View File

@@ -104,6 +104,7 @@ void macros_panel_init(lv_obj_t* panel) {
}
lv_obj_t * root_panel = lv_create_empty_panel(panel);
lv_obj_set_scrollbar_mode(root_panel, LV_SCROLLBAR_MODE_OFF);
lv_obj_set_size(root_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_MIN_BUTTON_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_align(root_panel, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX + CYD_SCREEN_GAP_PX * 2);
lv_layout_flex_column(root_panel);

View File

@@ -1,48 +1,28 @@
#include "lvgl.h"
#include "panel.h"
#include "../../core/data_setup.h"
#include "../nav_buttons.h"
#include "../ui_utils.h"
#include <stdio.h>
static bool last_homing_state = false;
static void move_printer(const char* axis, float amount) {
if (!printer.homed_axis || printer.state == PRINTER_STATE_PRINTING)
return;
char gcode[64];
const char* extra = (amount > 0) ? "+" : "";
bool absolute_coords = printer.absolute_coords;
if (absolute_coords) {
send_gcode(true, "G91");
}
sprintf(gcode, "G1 %s%s%.1f F6000", axis, extra, amount);
send_gcode(true, gcode);
if (absolute_coords) {
send_gcode(true, "G90");
}
}
static void x_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e);
float data = *data_pointer;
move_printer("X", data);
move_printer("X", data, true);
}
static void y_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e);
float data = *data_pointer;
move_printer("Y", data);
move_printer("Y", data, true);
}
static void z_line_button_press(lv_event_t * e) {
float* data_pointer = (float*)lv_event_get_user_data(e);
float data = *data_pointer;
move_printer("Z", data);
move_printer("Z", data, true);
}
char x_pos_buff[12];
@@ -103,6 +83,11 @@ static void disable_steppers_click(lv_event_t * e) {
send_gcode(true, "M18");
}
static void switch_to_stat_panel(lv_event_t * e) {
lv_obj_t * panel = lv_event_get_target(e);
nav_buttons_setup(5);
}
inline void root_panel_steppers_locked(lv_obj_t * root_panel){
const auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
@@ -121,7 +106,7 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
lv_obj_set_flex_grow(btn, 1);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_HOME "Home Axis");
lv_label_set_text(label, LV_SYMBOL_HOME "Home");
lv_obj_center(label);
btn = lv_btn_create(home_button_row);
@@ -130,7 +115,16 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Disable Step");
lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Unlock");
lv_obj_center(label);
btn = lv_btn_create(home_button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, switch_to_stat_panel, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_EDIT " Params");
lv_obj_center(label);
for (int row = 0; row < 3; row++) {

View File

@@ -37,6 +37,10 @@ static void btn_print_file(lv_event_t * e){
HTTPClient client;
client.begin(buff);
if (global_config.auth_configured)
client.addHeader("X-Api-Key", global_config.klipper_auth);
int httpCode = client.POST("");
Serial.printf("Print start: HTTP %d\n", httpCode);
}

View File

@@ -29,6 +29,7 @@ static void reset_calibration_click(lv_event_t * e){
static void reset_wifi_click(lv_event_t * e){
global_config.wifiConfigured = false;
global_config.ipConfigured = false;
global_config.auth_configured = false;
WriteGlobalConfig();
ESP.restart();
}
@@ -99,6 +100,14 @@ static void auto_ota_update_switch(lv_event_t* e){
WriteGlobalConfig();
}
const char* estimated_time_options = "Percentage\nInterpolated\nSlicer";
static void estimated_time_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
global_config.remaining_time_calc_mode = lv_dropdown_get_selected(dropdown);
WriteGlobalConfig();
}
const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} };
void create_settings_widget(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true){
@@ -122,13 +131,19 @@ void create_settings_widget(const char* label_text, lv_obj_t* object, lv_obj_t*
}
void settings_panel_init(lv_obj_t* panel){
lv_obj_t * toggle = NULL;
lv_obj_t * btn = NULL;
lv_obj_t * label = NULL;
lv_obj_t * dropdown = NULL;
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(panel);
lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF);
lv_obj_t * btn = lv_btn_create(panel);
btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, reset_wifi_click, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
@@ -145,7 +160,8 @@ void settings_panel_init(lv_obj_t* panel){
create_settings_widget("Calibrate Touch", btn, panel);
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_obj_t * toggle = lv_switch_create(panel);
#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
toggle = lv_switch_create(panel);
lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2);
lv_obj_add_event_cb(toggle, invert_color_switch, LV_EVENT_VALUE_CHANGED, NULL);
@@ -153,7 +169,7 @@ void settings_panel_init(lv_obj_t* panel){
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Invert Colors", toggle, panel);
#endif // CYD_SCREEN_DISABLE_INVERT_COLORS
toggle = lv_switch_create(panel);
lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2);
@@ -164,7 +180,7 @@ void settings_panel_init(lv_obj_t* panel){
create_settings_widget("Light Mode", toggle, panel);
lv_obj_t * dropdown = lv_dropdown_create(panel);
dropdown = lv_dropdown_create(panel);
lv_dropdown_set_options(dropdown, "Blue\nGreen\nGrey\nYellow\nOrange\nRed\nPurple");
lv_dropdown_set_selected(dropdown, global_config.color_scheme);
lv_obj_add_event_cb(dropdown, theme_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
@@ -199,6 +215,13 @@ void settings_panel_init(lv_obj_t* panel){
create_settings_widget("Wake Timeout", dropdown, panel);
#endif
dropdown = lv_dropdown_create(panel);
lv_dropdown_set_options(dropdown, estimated_time_options);
lv_obj_add_event_cb(dropdown, estimated_time_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
lv_dropdown_set_selected(dropdown, global_config.remaining_time_calc_mode);
create_settings_widget("Estimated Time", dropdown, panel);
toggle = lv_switch_create(panel);
lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2);
lv_obj_add_event_cb(toggle, rotate_screen_switch, LV_EVENT_VALUE_CHANGED, NULL);
@@ -219,6 +242,15 @@ void settings_panel_init(lv_obj_t* panel){
create_settings_widget("Screen On During Print", toggle, panel);
#endif
toggle = lv_switch_create(panel);
lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2);
lv_obj_add_event_cb(toggle, auto_ota_update_switch, LV_EVENT_VALUE_CHANGED, NULL);
if (global_config.autoOtaUpdate)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Auto Update", toggle, panel);
label = lv_label_create(panel);
lv_label_set_text(label, REPO_VERSION " ");
@@ -240,13 +272,4 @@ void settings_panel_init(lv_obj_t* panel){
create_settings_widget("Device", label, panel, false);
}
toggle = lv_switch_create(panel);
lv_obj_set_width(toggle, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2);
lv_obj_add_event_cb(toggle, auto_ota_update_switch, LV_EVENT_VALUE_CHANGED, NULL);
if (global_config.autoOtaUpdate)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Auto Update", toggle, panel);
}

View File

@@ -36,19 +36,42 @@ static void set_zoffset_text(lv_event_t * e) {
lv_label_set_text(label, data);
}
static void set_zoffset_text_ex(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e);
char data[64];
sprintf(data, "Z Offset: %.03f, Z: %.03f", printer.gcode_offset[2], printer.position[2]);
lv_label_set_text(label, data);
}
static void set_zoffset(lv_event_t * e){
char* offset = (char*)lv_event_get_user_data(e);
char gcode[64];
sprintf(gcode, "SET_GCODE_OFFSET Z_ADJUST=%s", offset);
sprintf(gcode, "SET_GCODE_OFFSET Z_ADJUST=%s MOVE=1", offset);
send_gcode(true, gcode);
}
const char* zoffsets[] = { "-0.005", "-0.01", "-0.025", "-0.05" };
const char* zoffsets_2[] = { "+0.005", "+0.01", "+0.025", "+0.05" };
static void set_z(lv_event_t * e){
void* ptr = lv_event_get_user_data(e);
float value = *(float *)(&ptr);
if (value < 0) {
send_gcode(true, "SET_GCODE_OFFSET Z=0 MOVE=1");
return;
}
move_printer("Z", value, false);
}
const char* zoffsets[] = { "-0.01", "-0.025", "-0.05", "-0.2" };
const char* zoffsets_2[] = { "+0.01", "+0.025", "+0.05", "+0.2" };
const char* zabs[] = { "Z=0", "Z=0.1", "Z=1", "Clear" };
const float zabsvalues[] = { 0, 0.1f, 1.0f, -1.0f };
lv_button_column_t zoffset_columns[] = {
{ set_zoffset, zoffsets, (const void**)zoffsets, 4},
{ set_zoffset, zoffsets_2, (const void**)zoffsets_2, 4}
{ set_zoffset, zoffsets_2, (const void**)zoffsets_2, 4},
{ set_z, zabs, (const void**)zabsvalues, 4}
};
static void set_speed_mult_text(lv_event_t * e){
@@ -126,7 +149,7 @@ static void open_fan_speed_panel(lv_event_t * e){
}
static void open_zoffset_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text, zoffset_columns, 2);
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_zoffset_text_ex, zoffset_columns, (printer.state == PRINTER_STATE_IDLE) ? 3 : 2);
lv_msg_send(DATA_PRINTER_DATA, &printer);
}
@@ -175,7 +198,7 @@ static void label_total_layers(lv_event_t * e){
static void label_pressure_advance(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char pressure_buff[32];
sprintf(pressure_buff, "%.3f", printer.pressure_advance);
sprintf(pressure_buff, "%.3f (%.2fs)", printer.pressure_advance, printer.smooth_time);
lv_label_set_text(label, pressure_buff);
}
@@ -211,8 +234,12 @@ void stats_panel_init(lv_obj_t* panel) {
lv_obj_align(left_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
create_stat_text_block(left_panel, "Position:", label_pos);
create_stat_text_block(left_panel, "Filament Used:", label_filament_used_m);
create_stat_text_block(left_panel, "Layer:", label_total_layers);
if (printer.state != PRINTER_STATE_IDLE){
create_stat_text_block(left_panel, "Filament Used:", label_filament_used_m);
create_stat_text_block(left_panel, "Layer:", label_total_layers);
}
create_stat_text_block(left_panel, "Pressure Advance:", label_pressure_advance);
create_stat_text_block(left_panel, "Feedrate:", label_feedrate);

View File

@@ -207,22 +207,100 @@ static void btn_retract(lv_event_t * e){
send_gcode(true, "G1 E-25 F300");
}
static void set_chart_range(lv_event_t * e) {
lv_obj_t * chart_obj = lv_event_get_target(e);
lv_chart_t * chart = (lv_chart_t *)chart_obj;
int max_temp = 0;
lv_chart_series_t * prev = NULL;
do {
prev = lv_chart_get_series_next(chart_obj, prev);
if (prev != NULL)
for (int i = 0; i < chart->point_cnt; i++)
if (prev->y_points[i] > max_temp)
max_temp = prev->y_points[i];
} while (prev != NULL);
int range = ((max_temp + 49) / 50) * 50;
if (range < 100)
range = 100;
lv_chart_set_range(chart_obj, LV_CHART_AXIS_PRIMARY_Y, 0, range);
}
static void set_hotend_temp_chart(lv_event_t * e){
lv_obj_t * chart = lv_event_get_target(e);
lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e);
lv_chart_set_next_value(chart, series, printer.extruder_temp);
}
static void set_hotend_target_temp_chart(lv_event_t * e){
lv_obj_t * chart = lv_event_get_target(e);
lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e);
lv_chart_set_next_value(chart, series, printer.extruder_target_temp);
}
static void set_bed_temp_chart(lv_event_t * e){
lv_obj_t * chart = lv_event_get_target(e);
lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e);
lv_chart_set_next_value(chart, series, printer.bed_temp);
}
static void set_bed_target_temp_chart(lv_event_t * e){
lv_obj_t * chart = lv_event_get_target(e);
lv_chart_series_t * series = (lv_chart_series_t *)lv_event_get_user_data(e);
lv_chart_set_next_value(chart, series, printer.bed_target_temp);
}
void temp_panel_init(lv_obj_t * panel){
const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
root_panel = panel;
edit_mode = false;
lv_obj_t * root_temp_panel = lv_create_empty_panel(panel);
lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, LV_SIZE_CONTENT);
lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_obj_align(root_temp_panel, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_style_pad_all(root_temp_panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(root_temp_panel);
lv_obj_set_flex_align(root_temp_panel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER);
lv_obj_set_scrollbar_mode(root_temp_panel, LV_SCROLLBAR_MODE_OFF);
lv_obj_t * chart = lv_chart_create(root_temp_panel);
lv_obj_set_size(chart, element_width - CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * 3);
lv_chart_set_type(chart, LV_CHART_TYPE_LINE);
lv_chart_set_point_count(chart, 120);
lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);
lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, CYD_SCREEN_GAP_PX / 2, CYD_SCREEN_GAP_PX / 4, 4, 3, true, CYD_SCREEN_MIN_BUTTON_WIDTH_PX);
lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_ORANGE), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_all_value(chart, ser1, printer.extruder_target_temp);
lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_all_value(chart, ser2, printer.extruder_temp);
lv_chart_series_t * ser3 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_TEAL), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_all_value(chart, ser3, printer.bed_target_temp);
lv_chart_series_t * ser4 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_PRIMARY_Y);
lv_chart_set_all_value(chart, ser4, printer.bed_temp);
lv_obj_add_event_cb(chart, set_hotend_target_temp_chart, LV_EVENT_MSG_RECEIVED, ser1);
lv_obj_add_event_cb(chart, set_hotend_temp_chart, LV_EVENT_MSG_RECEIVED, ser2);
lv_obj_add_event_cb(chart, set_bed_target_temp_chart, LV_EVENT_MSG_RECEIVED, ser3);
lv_obj_add_event_cb(chart, set_bed_temp_chart, LV_EVENT_MSG_RECEIVED, ser4);
lv_obj_add_event_cb(chart, set_chart_range, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subscribe_obj(DATA_PRINTER_DATA, chart, NULL);
lv_obj_t * single_screen_panel = lv_create_empty_panel(root_temp_panel);
lv_obj_set_size(single_screen_panel, element_width, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2 - CYD_SCREEN_GAP_PX / 2);
lv_layout_flex_column(single_screen_panel);
lv_obj_t * temp_rows[2] = {0};
lv_obj_t * button_temp_rows[2] = {0};
for (int tempIter = 0; tempIter < 2; tempIter++){
temp_rows[tempIter] = lv_create_empty_panel(root_temp_panel);
temp_rows[tempIter] = lv_create_empty_panel(single_screen_panel);
lv_layout_flex_column(temp_rows[tempIter]);
lv_obj_set_size(temp_rows[tempIter], element_width, LV_SIZE_CONTENT);
@@ -259,16 +337,17 @@ void temp_panel_init(lv_obj_t * panel){
lv_obj_center(label);
}
lv_obj_t * bottom_panel = lv_create_empty_panel(panel);
lv_obj_set_size(bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(bottom_panel, LV_ALIGN_BOTTOM_MID, 0, -1 * CYD_SCREEN_GAP_PX);
lv_layout_flex_row(bottom_panel, LV_FLEX_ALIGN_SPACE_EVENLY);
lv_obj_t * gap = lv_create_empty_panel(single_screen_panel);
lv_obj_set_flex_grow(gap, 1);
lv_obj_t * one_above_bottom_panel = lv_create_empty_panel(panel);
lv_obj_t * one_above_bottom_panel = lv_create_empty_panel(single_screen_panel);
lv_obj_set_size(one_above_bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(one_above_bottom_panel, LV_ALIGN_BOTTOM_MID, 0, -1 * CYD_SCREEN_MIN_BUTTON_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
lv_layout_flex_row(one_above_bottom_panel, LV_FLEX_ALIGN_SPACE_EVENLY);
lv_obj_t * bottom_panel = lv_create_empty_panel(single_screen_panel);
lv_obj_set_size(bottom_panel, element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(bottom_panel, LV_FLEX_ALIGN_SPACE_EVENLY);
lv_obj_t * btn = lv_btn_create(bottom_panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_extrude, LV_EVENT_CLICKED, NULL);
@@ -306,5 +385,6 @@ void temp_panel_init(lv_obj_t * panel){
lv_label_set_text(label, "Edit Presets");
lv_obj_center(label);
lv_obj_scroll_to_y(root_temp_panel, 9999, LV_ANIM_OFF);
lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer);
}