16 Commits

Author SHA1 Message Date
Sims
e2c2a38b20 v1.6.4 (#113)
* Fix gcode previews with special chars not loading

* Add .gitignore file (#108)

* Bulletproof ci.py (#107)

* Implement file sorting (implement #89)

* Set chip family to ESP32-S3 for specific models (fix #67)

* Add files menu to params panel while printing (implement #80)

* Update ci.py (#110)

Typo fix for ESP32-S3 boards array name

---------

Co-authored-by: Sebastian Göls <6608231+Abrynos@users.noreply.github.com>
Co-authored-by: Miroslav Zuzelka <mzuzelka@gmail.com>
2024-06-28 19:11:20 +02:00
Sims
c640d7fade Merge pull request #104 from suchmememanyskill/dev
Clear memory before doing OTA
2024-05-28 22:15:23 +02:00
suchmememanyskill
d22a9e1ee4 Clear memory before doing OTA 2024-05-28 22:03:51 +02:00
Sims
98c7364ce7 Merge pull request #103 from suchmememanyskill/dev
v1.6.2
2024-05-28 21:30:19 +02:00
suchmememanyskill
7815a0fbf4 Specify specific version for esp32 platform 2024-05-26 00:26:49 +02:00
suchmememanyskill
bd32fcb81e Allow accessing the parameters/stats panel from unlocked stepper move panel 2024-05-25 12:47:43 +02:00
suchmememanyskill
bc0502745d Allow custom extrude/retract macros 2024-05-25 12:40:07 +02:00
suchmememanyskill
d75cbb65dc Fix #99 2024-05-11 00:05:24 +02:00
Beebles
e004456ee9 Update README.md (#95) 2024-04-28 23:57:29 +02:00
Flaviu Tamas
ae34e91530 Custom API key keymap (#94)
Since the api key is just hex, we can use a keymap with larger buttons
that is easier to use.
2024-04-28 20:23:49 +02:00
Flaviu Tamas
cbd40414c8 Fix segfault on entering IP (#93)
On my esp32-3248S035C, after entering the IP address, I was seeing a
segfault at

lv_mem_free at .pio/libdeps/esp32-3248S035C/lvgl/src/misc/lv_mem.c:179
allocate_btn_areas_and_controls at .pio/libdeps/esp32-3248S035C/lvgl/src/widgets/lv_btnmatrix.c:877
lv_btnmatrix_set_map at .pio/libdeps/esp32-3248S035C/lvgl/src/widgets/lv_btnmatrix.c:94
lv_keyboard_update_map at .pio/libdeps/esp32-3248S035C/lvgl/src/extra/widgets/keyboard/lv_keyboard.c:397
lv_keyboard_set_mode at .pio/libdeps/esp32-3248S035C/lvgl/src/extra/widgets/keyboard/lv_keyboard.c:185
keyboard_event_ip_entry(_lv_event_t*) at src/ui/ip_setup.cpp:81
event_send_core at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:467
lv_event_send at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:63
lv_keyboard_def_event_cb at .pio/libdeps/esp32-3248S035C/lvgl/src/extra/widgets/keyboard/lv_keyboard.c:308
event_send_core at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:467
lv_event_send at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:63
lv_btnmatrix_event at .pio/libdeps/esp32-3248S035C/lvgl/src/widgets/lv_btnmatrix.c:520
lv_obj_event_base at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:91 (discriminator 1)
event_send_core at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:458
lv_event_send at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_event.c:63
indev_proc_release at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_indev.c:970
indev_button_proc at .pio/libdeps/esp32-3248S035C/lvgl/src/core/lv_indev.c:808
lv_timer_exec at .pio/libdeps/esp32-3248S035C/lvgl/src/misc/lv_timer.c:313
set_screen_brightness() at src/core/lv_setup.cpp:191
ip_init() at src/ui/ip_setup.cpp:239
setup() at src/main.cpp:28
loopTask(void*) at /home/user/etc/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:41

This seems to be due to a free-after-free. The solution here is to
potentially change the keymap before running the rest of the logic,
because the later logic may tear down the context.

This change also only changes the keyboard mode on focus change, to
avoid running this code on the many un-related events that this handler
gets called for.
2024-04-28 20:22:06 +02:00
suchmememanyskill
06691df094 Remove esp32-4827S043R-SD from CI builds 2024-04-24 22:23:57 +02:00
suchmememanyskill
9b551915d7 Fix possible nullref in fetch_printer_data 2024-04-15 22:56:57 +02:00
suchmememanyskill
73be7c6c9f Forgot to add device to platformio cfg 2024-04-15 19:39:03 +02:00
suchmememanyskill
e06ea214c4 esp32-4827S043R 2024-04-15 18:02:05 +02:00
suchmememanyskill
9e739de731 Add more clear manual install instructions 2024-04-15 17:37:07 +02:00
26 changed files with 431 additions and 93 deletions

10
.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
_site/out/
_site/OTA.json
_site/esp32-*.json
pyvenv.cfg
bin/
out/
lib
lib64

View File

@@ -0,0 +1,146 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"partitions": "default_16MB.csv",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32S3_DEV'",
"'-D BOARD_HAS_PSRAM'",
"'-D ARDUINO_USB_MODE=1'",
"'-D ARDUINO_RUNNING_CORE=1'",
"'-D ARDUINO_EVENT_RUNNING_CORE=1'",
"'-D ARDUINO_USB_CDC_ON_BOOT=0'",
"'-D ESP32_4827S043R'",
"'-D LCD_WIDTH=480'",
"'-D LCD_HEIGHT=272'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT)'",
"'-D GPIO_BCKL=2'",
"'-D LCD_ST7262_PAR'",
"'-D ST7262_PANEL_CONFIG_CLK_SRC=LCD_CLK_SRC_PLL160M'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_PCLK_HZ=(8*1000000)'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_H_RES=LCD_WIDTH'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_V_RES=LCD_HEIGHT'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_BACK_PORCH=43'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_HSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_PULSE_WIDTH=4'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_BACK_PORCH=12'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_DE_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_ACTIVE_NEG=true'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_PCLK_IDLE_HIGH=false'",
"'-D ST7262_PANEL_CONFIG_DATA_WIDTH=16'",
"'-D ST7262_PANEL_CONFIG_SRAM_TRANS_ALIGN=4'",
"'-D ST7262_PANEL_CONFIG_PSRAM_TRANS_ALIGN=64'",
"'-D ST7262_PANEL_CONFIG_HSYNC_GPIO_NUM=39'",
"'-D ST7262_PANEL_CONFIG_VSYNC_GPIO_NUM=41'",
"'-D ST7262_PANEL_CONFIG_DE_GPIO_NUM=40'",
"'-D ST7262_PANEL_CONFIG_PCLK_GPIO_NUM=42'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R0=8'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R1=3'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R2=46'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R3=9'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_R4=1'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G0=5'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G1=6'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G2=7'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G3=15'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G4=16'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_G5=4'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B0=45'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B1=48'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B2=47'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B3=21'",
"'-D ST7262_PANEL_CONFIG_DATA_GPIO_B4=14'",
"'-D ST7262_PANEL_CONFIG_DISP_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7262_PANEL_CONFIG_FLAGS_DISP_ACTIVE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_RELAX_ON_IDLE=false'",
"'-D ST7262_PANEL_CONFIG_FLAGS_FB_IN_PSRAM=true'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_XPT2046_SPI'",
"'-D XPT2046_SPI_HOST=SPI2_HOST'",
"'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D XPT2046_SPI_BUS_MOSI_IO_NUM=11'",
"'-D XPT2046_SPI_BUS_MISO_IO_NUM=13'",
"'-D XPT2046_SPI_BUS_SCLK_IO_NUM=12'",
"'-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=38'",
"'-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=18'",
"'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D XPT2046_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=10'",
"'-D TF_SPI_MOSI=11'",
"'-D TF_SPI_SCLK=12'",
"'-D TF_SPI_MISO=13'",
"'-DCYD_SCREEN_HEIGHT_PX=272'",
"'-DCYD_SCREEN_WIDTH_PX=480'",
"-DROTATION_INVERTED=LV_DISP_ROT_180",
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
"'-DCYD_SCREEN_GAP_PX=10'",
"'-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=35'",
"'-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'"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"hwids": [
[
"0x303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "esp32s3"
},
"connectivity": [
"wifi"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino",
"espidf"
],
"name": "esp32-4827S043R-SD",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"use_1200bps_touch": true,
"wait_for_upload_port": true,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004788147691.html",
"vendor": "Sunton"
}

View File

@@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html
[env]
platform = espressif32
platform = https://github.com/platformio/platform-espressif32#v6.4.0
board = esp32dev
framework = arduino
monitor_speed = 115200
@@ -78,5 +78,9 @@ board = esp32-3248S035C-smartdisplay
[env:esp32-4827S043C-SD]
board = esp32-4827S043C-smartdisplay
[env:esp32-4827S043R-SD]
board = esp32-4827S043C-smartdisplay
[env:esp32-8048S043C-SD]
board = esp32-8048S043C-smartdisplay

View File

@@ -32,6 +32,8 @@ typedef struct _PRINTER_CONFIG {
bool invert_colors : 1;
unsigned char remaining_time_calc_mode : 2;
unsigned char show_stats_on_progress_panel : 2;
bool custom_filament_move_macros : 1;
};
};
@@ -66,6 +68,7 @@ typedef struct _GLOBAL_CONFIG {
bool on_during_print : 1;
bool display_mode : 1; // Driver specifc usage. Currently only used on ESP32-2432S028R to fix the screen on the usb-c model
bool disable_m117_messaging : 1;
bool sort_macros : 1;
};
};

View File

@@ -16,6 +16,7 @@ int klipper_request_consecutive_fail_count = 999;
char filename_buff[512] = {0};
SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore;
const long data_update_interval = 780;
unsigned char lock_absolute_relative_mode_swap = 0;
void semaphore_init(){
freezeRenderThreadSemaphore = xSemaphoreCreateMutex();
@@ -82,25 +83,29 @@ void move_printer(const char* axis, float amount, bool relative) {
char gcode[64];
const char* extra = (amount > 0) ? "+" : "";
const char* start = "";
const char* end = "";
bool absolute_coords = printer.absolute_coords;
if (absolute_coords && relative) {
send_gcode(true, "G91");
start = "G91\n";
}
else if (!absolute_coords && !relative) {
send_gcode(true, "G90");
start = "G90\n";
}
sprintf(gcode, "G1 %s%s%.3f F6000", axis, extra, amount);
send_gcode(true, gcode);
if (absolute_coords && relative) {
send_gcode(true, "G90");
end = "\nG90";
}
else if (!absolute_coords && !relative) {
send_gcode(true, "G91");
end = "\nG91";
}
sprintf(gcode, "%sG1 %s%s%.3f F6000%s", start, axis, extra, amount, end);
send_gcode(true, gcode);
lock_absolute_relative_mode_swap = 2;
}
int last_slicer_time_query = -15000;
@@ -192,7 +197,16 @@ void fetch_printer_data()
printer.gcode_offset[1] = status["gcode_move"]["homing_origin"][1];
printer.gcode_offset[2] = status["gcode_move"]["homing_origin"][2];
bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
if (lock_absolute_relative_mode_swap > 0)
{
lock_absolute_relative_mode_swap--;
}
else
{
printer.absolute_coords = absolute_coords == true;
}
printer.speed_mult = status["gcode_move"]["speed_factor"];
printer.extrude_mult = status["gcode_move"]["extrude_factor"];
printer.feedrate_mm_per_s = status["gcode_move"]["speed"];
@@ -212,7 +226,7 @@ void fetch_printer_data()
if (status.containsKey("print_stats"))
{
const char *filename = status["print_stats"]["filename"];
strcpy(filename_buff, filename);
strcpy(filename_buff, filename == NULL ? "" : filename);
printer.print_filename = filename_buff;
printer.elapsed_time_s = status["print_stats"]["total_duration"];
printer.printed_time_s = status["print_stats"]["print_duration"];

View File

@@ -9,9 +9,8 @@
// Always has +1 entry with a null'd name
FILESYSTEM_FILE* last_query = NULL;
FILESYSTEM_FILE* get_files(int limit){
freeze_request_thread();
void clear_files()
{
if (last_query != NULL){
FILESYSTEM_FILE* current = last_query;
@@ -21,7 +20,14 @@ FILESYSTEM_FILE* get_files(int limit){
}
free(last_query);
last_query = NULL;
}
}
FILESYSTEM_FILE* get_files(int limit)
{
freeze_request_thread();
clear_files();
Serial.printf("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size());
std::list<FILESYSTEM_FILE> files;

View File

@@ -20,3 +20,4 @@ typedef struct _FILESYSTEM_FILE {
} FILESYSTEM_FILE;
FILESYSTEM_FILE* get_files(int limit);
void clear_files();

View File

@@ -12,6 +12,15 @@ static char* power_devices[16] = {0};
static bool power_device_states[16] = {0};
static unsigned int stored_power_devices_count = 0;
void macros_clear()
{
for (int i = 0; i < macros_count; i++){
free(macros[i]);
}
macros_count = 0;
}
MACROSQUERY macros_query(PRINTER_CONFIG * config)
{
HTTPClient client;
@@ -24,11 +33,7 @@ MACROSQUERY macros_query(PRINTER_CONFIG * config)
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonObject>();
for (int i = 0; i < macros_count; i++){
free(macros[i]);
}
macros_count = 0;
macros_clear();
for (JsonPair i : result){
const char *key = i.key().c_str();
@@ -40,6 +45,13 @@ MACROSQUERY macros_query(PRINTER_CONFIG * config)
}
}
if (global_config.sort_macros)
{
std::sort(macros, macros + macros_count, [](const char* a, const char* b) {
return strcmp(a, b) < 0;
});
}
return {(const char**)macros, (unsigned int)macros_count};
}
else {
@@ -85,6 +97,15 @@ unsigned int macro_count()
return macro_count(get_current_printer_config());
}
void power_devices_clear()
{
for (int i = 0; i < stored_power_devices_count; i++){
free(power_devices[i]);
}
stored_power_devices_count = 0;
}
POWERQUERY power_devices_query(PRINTER_CONFIG * config)
{
HTTPClient client;
@@ -97,11 +118,7 @@ POWERQUERY power_devices_query(PRINTER_CONFIG * config)
deserializeJson(doc, client.getStream());
auto result = doc["result"]["devices"].as<JsonArray>();
for (int i = 0; i < stored_power_devices_count; i++){
free(power_devices[i]);
}
stored_power_devices_count = 0;
power_devices_clear();
for (auto i : result){
const char * device_name = i["device"];
@@ -154,8 +171,6 @@ unsigned int power_devices_count()
return power_devices_count(get_current_printer_config());
}
bool set_power_state(const char* device_name, bool state, PRINTER_CONFIG * config)
{
HTTPClient client;

View File

@@ -23,3 +23,5 @@ unsigned int power_devices_count(PRINTER_CONFIG * config);
unsigned int power_devices_count();
bool set_power_state(const char* device_name, bool state, PRINTER_CONFIG * config);
bool set_power_state(const char* device_name, bool state);
void macros_clear();
void power_devices_clear();

View File

@@ -2,6 +2,7 @@
#include "lvgl.h"
#include "ui_utils.h"
#include <Esp.h>
#include <UrlEncode.h>
#include <ArduinoJson.h>
#include "../conf/global_config.h"
#include "../core/http_client.h"
@@ -10,29 +11,27 @@ static unsigned char * data_png = NULL;
static char img_filename_path[256] = {0};
static lv_img_dsc_t img_header = {0};
bool has_128_128_gcode(const char* filename)
bool has_32_32_gcode_img(const char* filename)
{
if (filename == NULL){
Serial.println("No gcode filename");
return false;
}
SETUP_HTTP_CLIENT("/server/files/thumbnails?filename=" + String(filename));
SETUP_HTTP_CLIENT("/server/files/thumbnails?filename=" + urlEncode(filename));
int httpCode = 0;
try {
httpCode = client.GET();
}
catch (...){
Serial.println("Exception while fetching gcode img location");
return {0};
return false;
}
if (httpCode == 200)
{
String payload = client.getString();
JsonDocument doc;
deserializeJson(doc, payload);
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonArray>();
const char* chosen_thumb = NULL;
@@ -58,6 +57,10 @@ bool has_128_128_gcode(const char* filename)
return true;
}
}
else
{
Serial.printf("Failed to fetch gcode image data: %d\n", httpCode);
}
return false;
}
@@ -71,7 +74,7 @@ lv_obj_t* draw_gcode_img()
return NULL;
}
SETUP_HTTP_CLIENT_FULL("/server/files/gcodes/" + String(img_filename_path), false, 2000);
SETUP_HTTP_CLIENT_FULL("/server/files/gcodes/" + urlEncode(img_filename_path), false, 2000);
int httpCode = 0;
try {
@@ -121,7 +124,7 @@ lv_obj_t* show_gcode_img(const char* filename)
return NULL;
}
if (!has_128_128_gcode(filename)){
if (!has_32_32_gcode_img(filename)){
Serial.println("No 32x32 gcode img found");
return NULL;
}

View File

@@ -2,5 +2,5 @@
#include "lvgl.h"
lv_obj_t* show_gcode_img(const char* filename);
bool has_128_128_gcode(const char* filename);
bool has_32_32_gcode_img(const char* filename);
void clear_img_mem();

View File

@@ -33,6 +33,20 @@ static const lv_btnmatrix_ctrl_t kb_ctrl[] = {
LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6
};
static const char * hex_numpad_map[] = {
"1", "2", "3", "f", LV_SYMBOL_BACKSPACE, "\n",
"4", "5", "6", "e", LV_SYMBOL_OK, "\n",
"7", "8", "9", "d", LV_SYMBOL_LEFT, "\n",
"0", "a", "b", "c", LV_SYMBOL_RIGHT, NULL
};
static const lv_btnmatrix_ctrl_t hex_numpad_ctrl[] = {
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
1, 1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 1,
};
enum connection_status_t {
CONNECT_FAIL = 0,
CONNECT_OK = 1,
@@ -62,6 +76,20 @@ static void keyboard_event_ip_entry(lv_event_t * 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_FOCUSED || code == LV_EVENT_DEFOCUSED) && ta != NULL)
{
// make sure we alter the keymap before taking actions that might
// destroy the keyboard
if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_1))
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);
}
else
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
}
}
if(code == LV_EVENT_FOCUSED) {
lv_keyboard_set_textarea(kb, ta);
lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
@@ -94,15 +122,6 @@ static void keyboard_event_ip_entry(lv_event_t * e) {
{
return;
}
if (lv_obj_has_flag(ta, LV_OBJ_FLAG_USER_1))
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_USER_1);
}
else
{
lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_NUMBER);
}
}
static void keyboard_event_auth_entry(lv_event_t * e) {
@@ -170,8 +189,8 @@ void show_auth_entry()
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);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_2, hex_numpad_map, hex_numpad_ctrl);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_2);
}
void show_ip_entry()

View File

@@ -30,8 +30,11 @@ static void on_state_change(void * s, lv_msg_t * m){
else if (printer.state == PRINTER_STATE_ERROR){
nav_buttons_setup(PANEL_ERROR);
}
else if (printer.state == PRINTER_STATE_IDLE) {
nav_buttons_setup(PANEL_FILES);
}
else {
nav_buttons_setup(PANEL_PRINT);
nav_buttons_setup(PANEL_PROGRESS);
}
}

View File

@@ -58,7 +58,11 @@ static void update_printer_data_time(lv_event_t * e){
}
static void btn_click_files(lv_event_t * e){
nav_buttons_setup(PANEL_PRINT);
nav_buttons_setup(PANEL_FILES);
}
static void btn_click_progress(lv_event_t * e){
nav_buttons_setup(PANEL_PROGRESS);
}
static void btn_click_move(lv_event_t * e){
@@ -115,7 +119,7 @@ void create_button(const char* icon, const char* name, lv_event_cb_t button_clic
lv_obj_add_style(label, &nav_button_text_style, 0);
}
void nav_buttons_setup(unsigned char active_panel){
void nav_buttons_setup(PANEL_TYPE active_panel){
lv_obj_clean(lv_scr_act());
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
@@ -134,7 +138,14 @@ void nav_buttons_setup(unsigned char active_panel){
if (printer.state > PRINTER_STATE_ERROR){
// Files/Print
if (printer.state == PRINTER_STATE_IDLE)
{
create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel);
}
else
{
create_button(LV_SYMBOL_FILE, "Paused", btn_click_progress, update_printer_data_time, root_panel);
}
// Move
create_button(printer.state == PRINTER_STATE_PRINTING ? LV_SYMBOL_EDIT : LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel);
@@ -165,8 +176,8 @@ void nav_buttons_setup(unsigned char active_panel){
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, 0, 0);
switch (active_panel){
case PANEL_PRINT:
print_panel_init(panel);
case PANEL_FILES:
files_panel_init(panel);
break;
case PANEL_MOVE:
move_panel_init(panel);
@@ -192,6 +203,9 @@ void nav_buttons_setup(unsigned char active_panel){
case PANEL_CONNECTING:
connecting_panel_init(panel);
break;
case PANEL_PROGRESS:
progress_panel_init(panel);
break;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);

View File

@@ -1,14 +1,17 @@
#pragma once
#define PANEL_PRINT 0
#define PANEL_MOVE 1
#define PANEL_TEMP 2
#define PANEL_SETTINGS 3
#define PANEL_MACROS 4
#define PANEL_STATS 5
#define PANEL_PRINTER 6
#define PANEL_ERROR 7
#define PANEL_CONNECTING 8
enum PANEL_TYPE {
PANEL_FILES = 0,
PANEL_MOVE = 1,
PANEL_TEMP = 2,
PANEL_SETTINGS = 3,
PANEL_MACROS = 4,
PANEL_STATS = 5,
PANEL_PRINTER = 6,
PANEL_ERROR = 7,
PANEL_CONNECTING = 8,
PANEL_PROGRESS = 9,
};
void nav_buttons_setup(unsigned char active_panel);
void nav_buttons_setup(PANEL_TYPE active_panel);
void nav_style_setup();

View File

@@ -5,6 +5,9 @@
#include "../core/data_setup.h"
#include "../conf/global_config.h"
#include "ota_setup.h"
#include "../core/macros_query.h"
#include "../core/files_query.h"
#include "gcode_img.h"
//const char *ota_url = "https://gist.githubusercontent.com/suchmememanyskill/ece418fe199e155340de6c224a0badf2/raw/0d6762d68bc807cbecc71e40d55b76692397a7b3/update.json"; // Test url
const char *ota_url = "https://suchmememanyskill.github.io/CYD-Klipper/OTA.json"; // Prod url
@@ -74,6 +77,11 @@ void ota_do_update(bool variant_automatic)
lv_timer_handler();
lv_task_handler();
macros_clear();
power_devices_clear();
clear_files();
clear_img_mem();
ota_pull.SetCallback(do_update_callback);
ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::UPDATE_AND_BOOT);
}

View File

@@ -23,6 +23,10 @@ static void btn_print_file(lv_event_t * e){
}
static void btn_print_file_verify(lv_event_t * e){
if (printer.state != PRINTER_STATE_IDLE){
return;
}
const auto button_size_mult = 1.3f;
lv_obj_t * btn = lv_event_get_target(e);
@@ -76,12 +80,7 @@ static void btn_print_file_verify(lv_event_t * e){
}
}
void print_panel_init(lv_obj_t* panel){
if (printer.state == PRINTER_STATE_PRINTING || printer.state == PRINTER_STATE_PAUSED){
progress_panel_init(panel);
return;
}
void files_panel_init(lv_obj_t* panel){
clear_img_mem();
lv_obj_t * list = lv_list_create(panel);

View File

@@ -312,19 +312,30 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){
inline void root_panel_steppers_unlocked(lv_obj_t * root_panel){
lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Steppers unlocked");
lv_obj_t * btn = lv_btn_create(panel);
lv_obj_t * btn_row = lv_create_empty_panel(panel);
lv_obj_set_size(btn_row, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(btn_row, LV_FLEX_ALIGN_CENTER);
lv_obj_t * btn = lv_btn_create(btn_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, home_button_click, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_HOME "Home Axis");
lv_obj_center(label);
btn = lv_btn_create(btn_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);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_SETTINGS "Parameters");
lv_obj_center(label);
}
static void root_panel_state_update(lv_event_t * e){

View File

@@ -5,7 +5,7 @@
void settings_panel_init(lv_obj_t* panel);
void temp_panel_init(lv_obj_t* panel);
void print_panel_init(lv_obj_t* panel);
void files_panel_init(lv_obj_t* panel);
void move_panel_init(lv_obj_t* panel);
void progress_panel_init(lv_obj_t* panel);
void macros_panel_init(lv_obj_t* panel);

View File

@@ -52,6 +52,13 @@ static void light_mode_switch(lv_event_t * e){
set_color_scheme();
}
static void filament_move_mode_switch(lv_event_t * e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
get_current_printer_config()->custom_filament_move_macros = checked;
write_global_config();
}
static void show_stats_on_progress_panel_dropdown(lv_event_t * e){
auto selected = lv_dropdown_get_selected(lv_event_get_target(e));
get_current_printer_config()->show_stats_on_progress_panel = selected;
@@ -103,6 +110,13 @@ static void disable_m117_messaging_switch(lv_event_t* e){
write_global_config();
}
static void sort_macros_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
global_config.sort_macros = checked;
write_global_config();
}
static void rotate_screen_switch(lv_event_t* e){
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
@@ -147,7 +161,7 @@ static void estimated_time_dropdown(lv_event_t * e){
write_global_config();
}
#define PRINTER_SPECIFIC_SETTING global_config.multi_printer_mode ? LV_SYMBOL_PLUS " Stored per printer" : NULL
#define PRINTER_SPECIFIC_SETTING global_config.multi_printer_mode ? "Stored per printer" : NULL
void settings_section_theming(lv_obj_t* panel)
{
@@ -157,7 +171,7 @@ void settings_section_theming(lv_obj_t* panel)
lv_create_custom_menu_dropdown("Theme", panel, theme_dropdown, "Blue\nGreen\nLime\nGrey\nYellow\nOrange\nRed\nPurple", get_current_printer_config()->color_scheme, NULL, PRINTER_SPECIFIC_SETTING);
#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors, NULL, (global_config.multi_printer_mode) ? LV_SYMBOL_PLUS " Stored per printer"
lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors, NULL, (global_config.multi_printer_mode) ? "Stored per printer"
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
"\nIntended for the 2.8\" dual USB model screen" : "Intended for the 2.8\" dual USB model screen"
#else
@@ -196,6 +210,13 @@ void settings_section_behaviour(lv_obj_t* panel)
lv_create_custom_menu_switch("Multi Printer Mode", panel, multi_printer_switch, global_config.multi_printer_mode);
lv_create_custom_menu_switch("Disable M117 Messaging", panel, disable_m117_messaging_switch, global_config.disable_m117_messaging);
lv_create_custom_menu_button("Configure Printer IP", panel, reset_ip_click, "Restart");
lv_create_custom_menu_switch("Custom Filament Move Macros", panel, filament_move_mode_switch, get_current_printer_config()->custom_filament_move_macros, NULL,
global_config.multi_printer_mode
? "Calls FILAMENT_RETRACT and\nFILAMENT_EXTRUDE in temperature menu\nwhen enabled. Stored per printer."
: "Calls FILAMENT_RETRACT and\nFILAMENT_EXTRUDE in temperature menu\nwhen enabled");
lv_create_custom_menu_switch("Sort Macros A->Z", panel, sort_macros_switch, global_config.sort_macros);
}
void settings_section_device(lv_obj_t* panel)
@@ -217,7 +238,12 @@ void settings_section_device(lv_obj_t* panel)
lv_create_custom_menu_switch("Screen Color Fix", panel, dualusb_screen_fix_switch, global_config.display_mode, NULL, "ONLY for the 2.8\" dual USB model screen");
#endif
#if defined(CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY) && !defined(CYD_SCREEN_DISABLE_TOUCH_CALIBRATION)
// TODO: Rotating screen requires different calibration points.
#else
lv_create_custom_menu_switch("Rotate Screen", panel, rotate_screen_switch, global_config.rotate_screen);
#endif
lv_create_custom_menu_switch("Auto Update", panel, auto_ota_update_switch, global_config.auto_ota_update);
lv_create_custom_menu_label("Version", panel, REPO_VERSION " ");

View File

@@ -1,9 +1,14 @@
#include "panel.h"
#include "../ui_utils.h"
#include "../../core/data_setup.h"
#include "../nav_buttons.h"
#include <stdio.h>
#include <Esp.h>
static void swap_to_files_menu(lv_event_t * e) {
nav_buttons_setup(PANEL_FILES);
}
static void set_fan_speed_text(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e);
char data[64];
@@ -249,6 +254,16 @@ void stats_panel_init(lv_obj_t* panel) {
lv_layout_flex_column(right_panel, LV_FLEX_ALIGN_CENTER);
lv_obj_align(right_panel, LV_ALIGN_TOP_RIGHT, -1 * CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
if (printer.state >= PRINTER_STATE_PRINTING){
lv_obj_t * btn = lv_btn_create(right_panel);
lv_obj_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX / 2 - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, swap_to_files_menu, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Files");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}
create_state_button(right_panel, set_fan_speed_text, open_fan_speed_panel);
create_state_button(right_panel, set_zoffset_text, open_zoffset_panel);
create_state_button(right_panel, set_speed_mult_text, open_speed_mult_panel);

View File

@@ -139,9 +139,16 @@ static void btn_extrude(lv_event_t * e){
return;
}
if (get_current_printer_config()->custom_filament_move_macros)
{
send_gcode(true, "FILAMENT_EXTRUDE");
}
else
{
send_gcode(true, "M83");
send_gcode(true, "G1 E25 F300");
}
}
static void set_temp_via_preset(lv_event_t * e){
int target = static_cast<int>(reinterpret_cast<intptr_t>(lv_event_get_user_data(e)));
@@ -173,9 +180,16 @@ static void btn_retract(lv_event_t * e){
return;
}
if (get_current_printer_config()->custom_filament_move_macros)
{
send_gcode(true, "FILAMENT_RETRACT");
}
else
{
send_gcode(true, "M83");
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);

View File

@@ -1,29 +1,38 @@
# Building
# Manual install
## Running a developer build
## Flashing a build via the commandline
On every change made in this repository, [Github Actions](https://github.com/suchmememanyskill/CYD-Klipper/actions) automatically builds the firmware images for various screens. You can run one of these images as follows:
#### Release firmware image
1. Go to [the releases tab](https://github.com/suchmememanyskill/CYD-Klipper/releases), and download the latest `firmware.zip` release.
2. Open the firmware.zip archive you just downloaded, open the corresponding folder for your screen, then extract `merged_firmware.bin`
This merged_firmware.bin file is a ready to flash image. Note that flashing this image does wipe your current configuration.
#### Developer firmware image
On every change made in this repository, [Github Actions](https://github.com/suchmememanyskill/CYD-Klipper/actions) automatically builds the firmware images for various screens.
#### Getting a firmware image
0. Make sure you are logged into github
1. Go to a [Github Actions](https://github.com/suchmememanyskill/CYD-Klipper/actions) build summary, then download the `firmware` Artifact.
2. Open the firmware.zip archive you just downloaded, open the corresponding folder for your screen, then extract `merged_firmware.bin`
This merged_firmware.bin file is a ready to flash image. Note that flashing this image does wipe your current configuration.
#### Flashing merged_firmware.bin
### Flashing merged_firmware.bin
1. Download and extract [esptool](https://github.com/espressif/esptool/releases) to a new folder
- For windows, download `esptool-v4.7.0-win64.zip`
2. Open a terminal window and navigate to this new folder containing esptool
- In windows, you can type cmd and press enter in the address bar in explorer to jump to the folder in cmd ![cmd](readme/cmd.jpg)
3. Move `merged-firmware.bin` into this new folder
4. Connect the display to your computer
5. Execute the command `esptool write_flash 0x0 merged-firmware.bin`
5. Execute the command `esptool write_flash 0x0 merged_firmware.bin`
- Don't forget to hold down the boot button on the display
## Building via PlatformIO
## Building & Flashing via PlatformIO
0. Install [Visual Studio Code](https://code.visualstudio.com/) and install the PlatformIO IDE plugin.
0. Install the following tools:
- [Visual Studio Code](https://code.visualstudio.com/) and install the PlatformIO IDE plugin.
- [Git](https://git-scm.com/download/win)
1. Download the source code of CYD-Klipper
- This can be done via the `git clone https://github.com/suchmememanyskill/CYD-Klipper` command or via the green `<> Code` button on Github
2. Open the CYD-Klipper folder inside the CYD-Klipper folder in Visual Studio Code
@@ -35,3 +44,5 @@ This merged_firmware.bin file is a ready to flash image. Note that flashing this
6. Click 'Upload and Monitor'
- This will start compiling the code, and after upload it to the display
- Don't forget to hold the boot button while flashing. The screen will flash when the firmware is attempted to be flashed
![platformio](readme/platformio.png)

View File

@@ -26,7 +26,7 @@ A ESP32-2432S028R is required to run this project. You can find out where to buy
### Install
[There is a web-based installer available. This is only supported on Chrome, Edge or Opera, and only on Desktop.](https://suchmememanyskill.github.io/CYD-Klipper/)
[There is a web-based installer available. This is only supported on Chrome, Edge, Arc or Opera, and only on Desktop.](https://suchmememanyskill.github.io/CYD-Klipper/)
On initial install, all data should be wiped. On updates, data should be able to be kept without issues.

17
ci.py
View File

@@ -7,17 +7,25 @@ CYD_PORTS = [
"esp32-8048S043C-SD",
"esp32-2432S024C-SD",
"esp32-4827S043C-SD",
"esp32-3248S035C-V"
"esp32-3248S035C-V",
#"esp32-4827S043R-SD",
]
ESP_S3_CHIPS = [
"esp32-8048S043C-SD",
"esp32-4827S043C-SD",
]
BASE_DIR = os.getcwd()
def get_manifest(base_path : str, device_name : str):
return {
"name": f"to {device_name}",
"funding_url": "https://ko-fi.com/suchmememanyskill",
"new_install_prompt_erase": True,
"builds": [
{
"chipFamily": "ESP32",
"chipFamily": "ESP32-S3" if device_name in ESP_S3_CHIPS else "ESP32",
"parts": [
{
"path": f"{base_path}/bootloader.bin",
@@ -79,7 +87,10 @@ for port in CYD_PORTS:
add_configuration(port)
os.chdir(BASE_DIR)
shutil.copytree("./out", "./_site/out")
out_dir = "./_site/out"
if os.path.exists(out_dir):
shutil.rmtree(out_dir)
shutil.copytree("./out", out_dir)
with open("./_site/OTA.json", "w") as f:
json.dump({"Configurations": configurations}, f)

BIN
readme/platformio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB