Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
230884c2cc | ||
|
|
f2d232d9eb | ||
|
|
1e3f0ab637 | ||
|
|
e15c7e37ff | ||
|
|
e15ba8d852 | ||
|
|
a759ccbbf7 | ||
|
|
84662a8fab | ||
|
|
cb47286784 | ||
|
|
6717e53fc9 | ||
|
|
dc5a3b5efd | ||
|
|
48520f652a | ||
|
|
dccb10cc6f | ||
|
|
c5d08253a7 | ||
|
|
5224e34f8c | ||
|
|
fb65bc8068 | ||
|
|
c0651a50a7 | ||
|
|
e04e3204eb | ||
|
|
ecc9e5ea99 | ||
|
|
ed024077ee | ||
|
|
91db5036c0 |
42
.github/workflows/compile.yaml
vendored
@@ -1,5 +1,9 @@
|
|||||||
name: PlatformIO CI
|
name: PlatformIO CI
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -24,22 +28,44 @@ jobs:
|
|||||||
|
|
||||||
- name: Build PlatformIO Project
|
- name: Build PlatformIO Project
|
||||||
run: |
|
run: |
|
||||||
cd CYD-Klipper-Display
|
cd CYD-Klipper
|
||||||
pio run
|
pio run
|
||||||
|
|
||||||
- name: Make output dir
|
- name: Make output dir
|
||||||
run: mkdir -p output
|
run: |
|
||||||
|
mkdir -p output
|
||||||
|
|
||||||
- name: Build Binary
|
- name: Build Binary
|
||||||
run: |
|
run: |
|
||||||
cp ./CYD-Klipper-Display/.pio/build/esp32dev/bootloader.bin output
|
cp ./CYD-Klipper/.pio/build/esp32dev/bootloader.bin output
|
||||||
cp ./CYD-Klipper-Display/.pio/build/esp32dev/partitions.bin output
|
cp ./CYD-Klipper/.pio/build/esp32dev/partitions.bin output
|
||||||
cp ./CYD-Klipper-Display/.pio/build/esp32dev/firmware.bin output
|
cp ./CYD-Klipper/.pio/build/esp32dev/firmware.bin output
|
||||||
cp ~/platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin output
|
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin output
|
||||||
esptool --chip esp32 merge_bin -o ./output/merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 ./output/bootloader.bin 0x8000 ./output/partitions.bin 0xe000 ./output/boot_app0.bin 0x10000 ./output/firmware.bin
|
python3 -m esptool --chip esp32 merge_bin -o ./output/merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 ./output/bootloader.bin 0x8000 ./output/partitions.bin 0xe000 ./output/boot_app0.bin 0x10000 ./output/firmware.bin
|
||||||
|
cp -r ./output ./_site
|
||||||
|
|
||||||
- name: Upload artefact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: firmware
|
name: firmware
|
||||||
path: ./output
|
path: ./output
|
||||||
|
|
||||||
|
- name: Upload GitHub Page Artifact
|
||||||
|
uses: actions/upload-pages-artifact@v2
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||||
|
steps:
|
||||||
|
- name: Print GitHub event name
|
||||||
|
run: |
|
||||||
|
echo "${{ github.event_name }}"
|
||||||
|
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v2
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
void ip_setup();
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
#include "lvgl.h"
|
|
||||||
#include "panel.h"
|
|
||||||
#include "../../core/data_setup.h"
|
|
||||||
#include <HardwareSerial.h>
|
|
||||||
|
|
||||||
// False: Hotend, True: Bed
|
|
||||||
static bool hotend_or_bed = true;
|
|
||||||
static char hotend_buff[40];
|
|
||||||
static char bed_buff[40];
|
|
||||||
|
|
||||||
static void update_printer_data_hotend_temp(lv_event_t * e){
|
|
||||||
lv_obj_t * label = lv_event_get_target(e);
|
|
||||||
sprintf(hotend_buff, "Hotend: %.0f C\nTarget: %.0f C", printer.extruder_temp, printer.extruder_target_temp);
|
|
||||||
lv_label_set_text(label, hotend_buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void update_printer_data_bed_temp(lv_event_t * e){
|
|
||||||
lv_obj_t * label = lv_event_get_target(e);
|
|
||||||
sprintf(bed_buff, "Bed: %.0f C\nTarget: %.0f C", printer.bed_temp, printer.bed_target_temp);
|
|
||||||
lv_label_set_text(label, bed_buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void keyboard_callback(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 * text = lv_textarea_get_text(ta);
|
|
||||||
|
|
||||||
int temp = atoi(text);
|
|
||||||
if (temp < 0 || temp > 500){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.printf("%d %s %d\n", hotend_or_bed, text, temp);
|
|
||||||
char gcode[64];
|
|
||||||
const char* space = "%20";
|
|
||||||
|
|
||||||
if (hotend_or_bed){
|
|
||||||
sprintf(gcode, "M140%sS%d", space, temp);
|
|
||||||
} else {
|
|
||||||
sprintf(gcode, "M104%sS%d", space, temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
send_gcode(true, gcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(code == LV_EVENT_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY) {
|
|
||||||
lv_keyboard_set_textarea(kb, NULL);
|
|
||||||
lv_obj_del(kb);
|
|
||||||
lv_obj_del(ta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_keyboard(lv_event_t * e){
|
|
||||||
lv_obj_t * panel = (lv_obj_t *)lv_event_get_user_data(e);
|
|
||||||
lv_obj_t * keyboard = lv_keyboard_create(panel);
|
|
||||||
lv_obj_t * ta = lv_textarea_create(panel);
|
|
||||||
lv_obj_set_size(ta, 100, 30);
|
|
||||||
lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 40);
|
|
||||||
lv_textarea_set_max_length(ta, 3);
|
|
||||||
lv_textarea_set_one_line(ta, true);
|
|
||||||
lv_textarea_set_text(ta, "");
|
|
||||||
lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_ALL, keyboard);
|
|
||||||
|
|
||||||
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER);
|
|
||||||
lv_keyboard_set_textarea(keyboard, ta);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_keyboard_with_hotend(lv_event_t * e){
|
|
||||||
hotend_or_bed = false;
|
|
||||||
show_keyboard(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void show_keyboard_with_bed(lv_event_t * e){
|
|
||||||
hotend_or_bed = true;
|
|
||||||
show_keyboard(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cooldown_temp(lv_event_t * e){
|
|
||||||
if (printer.state == PRINTER_STATE_PRINTING){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_gcode(true, "M104%20S0");
|
|
||||||
send_gcode(true, "M140%20S0");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void btn_extrude(lv_event_t * e){
|
|
||||||
if (printer.state == PRINTER_STATE_PRINTING){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_gcode(true, "M83");
|
|
||||||
send_gcode(true, "G1%20E25%20F300");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void btn_retract(lv_event_t * e){
|
|
||||||
if (printer.state == PRINTER_STATE_PRINTING){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
send_gcode(true, "M83");
|
|
||||||
send_gcode(true, "G1%20E-25%20F300");
|
|
||||||
}
|
|
||||||
|
|
||||||
void temp_panel_init(lv_obj_t* panel){
|
|
||||||
auto panel_width = TFT_HEIGHT - 40;
|
|
||||||
lv_obj_t * label = lv_label_create(panel);
|
|
||||||
lv_label_set_text(label, "Hotend");
|
|
||||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10);
|
|
||||||
lv_obj_add_event_cb(label, update_printer_data_hotend_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
|
||||||
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
|
|
||||||
|
|
||||||
label = lv_label_create(panel);
|
|
||||||
lv_label_set_text(label, "Bed");
|
|
||||||
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 50);
|
|
||||||
lv_obj_add_event_cb(label, update_printer_data_bed_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
|
||||||
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
|
|
||||||
|
|
||||||
lv_obj_t * btn = lv_btn_create(panel);
|
|
||||||
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, 10);
|
|
||||||
lv_obj_add_event_cb(btn, show_keyboard_with_hotend, LV_EVENT_CLICKED, panel);
|
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
|
||||||
lv_label_set_text(label, "Set");
|
|
||||||
lv_obj_center(label);
|
|
||||||
|
|
||||||
btn = lv_btn_create(panel);
|
|
||||||
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, 50);
|
|
||||||
lv_obj_add_event_cb(btn, show_keyboard_with_bed, LV_EVENT_CLICKED, panel);
|
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
|
||||||
lv_label_set_text(label, "Set");
|
|
||||||
lv_obj_center(label);
|
|
||||||
|
|
||||||
btn = lv_btn_create(panel);
|
|
||||||
lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 90);
|
|
||||||
lv_obj_add_event_cb(btn, cooldown_temp, LV_EVENT_CLICKED, panel);
|
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
|
||||||
lv_label_set_text(label, "Cooldown");
|
|
||||||
lv_obj_center(label);
|
|
||||||
|
|
||||||
btn = lv_btn_create(panel);
|
|
||||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -5);
|
|
||||||
lv_obj_add_event_cb(btn, btn_extrude, LV_EVENT_CLICKED, NULL);
|
|
||||||
lv_obj_set_size(btn, panel_width / 2 - 15, 30);
|
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
|
||||||
lv_label_set_text(label, LV_SYMBOL_DOWN " Extrude");
|
|
||||||
lv_obj_center(label);
|
|
||||||
|
|
||||||
btn = lv_btn_create(panel);
|
|
||||||
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -5);
|
|
||||||
lv_obj_add_event_cb(btn, btn_retract, LV_EVENT_CLICKED, NULL);
|
|
||||||
lv_obj_set_size(btn, panel_width / 2 - 15, 30);
|
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
|
||||||
lv_label_set_text(label, LV_SYMBOL_UP " Retract");
|
|
||||||
lv_obj_center(label);
|
|
||||||
|
|
||||||
lv_msg_send(DATA_PRINTER_DATA, &printer);
|
|
||||||
}
|
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"unordered_set": "cpp",
|
"unordered_set": "cpp",
|
||||||
"vector": "cpp",
|
"vector": "cpp",
|
||||||
"string_view": "cpp",
|
"string_view": "cpp",
|
||||||
"initializer_list": "cpp"
|
"initializer_list": "cpp",
|
||||||
|
"algorithm": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
cmake_minimum_required(VERSION 3.16.0)
|
cmake_minimum_required(VERSION 3.16.0)
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(CYD-Klipper-Display)
|
project(CYD-Klipper)
|
||||||
@@ -41,6 +41,12 @@ void LoadGlobalConfig() {
|
|||||||
global_config.version = CONFIG_VERSION;
|
global_config.version = CONFIG_VERSION;
|
||||||
global_config.brightness = 255;
|
global_config.brightness = 255;
|
||||||
global_config.screenTimeout = 5;
|
global_config.screenTimeout = 5;
|
||||||
|
global_config.hotend_presets[0] = 0;
|
||||||
|
global_config.hotend_presets[1] = 200;
|
||||||
|
global_config.hotend_presets[2] = 240;
|
||||||
|
global_config.bed_presets[0] = 0;
|
||||||
|
global_config.bed_presets[1] = 60;
|
||||||
|
global_config.bed_presets[2] = 70;
|
||||||
VerifyVersion();
|
VerifyVersion();
|
||||||
Preferences preferences;
|
Preferences preferences;
|
||||||
preferences.begin("global_config", true);
|
preferences.begin("global_config", true);
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
|
|
||||||
#define CONFIG_VERSION 2
|
#define CONFIG_VERSION 3
|
||||||
|
|
||||||
typedef struct _GLOBAL_CONFIG {
|
typedef struct _GLOBAL_CONFIG {
|
||||||
unsigned char version;
|
unsigned char version;
|
||||||
@@ -33,6 +33,9 @@ typedef struct _GLOBAL_CONFIG {
|
|||||||
unsigned char color_scheme;
|
unsigned char color_scheme;
|
||||||
unsigned char brightness;
|
unsigned char brightness;
|
||||||
unsigned char screenTimeout;
|
unsigned char screenTimeout;
|
||||||
|
|
||||||
|
unsigned short hotend_presets[3];
|
||||||
|
unsigned short bed_presets[3];
|
||||||
} GLOBAL_CONFIG;
|
} GLOBAL_CONFIG;
|
||||||
|
|
||||||
typedef struct _COLOR_DEF {
|
typedef struct _COLOR_DEF {
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "../conf/global_config.h"
|
#include "../conf/global_config.h"
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
#include "macros_query.h"
|
||||||
|
|
||||||
const char *printer_state_messages[] = {
|
const char *printer_state_messages[] = {
|
||||||
"Error",
|
"Error",
|
||||||
@@ -97,15 +98,15 @@ void fetch_printer_data()
|
|||||||
|
|
||||||
if (status.containsKey("toolhead"))
|
if (status.containsKey("toolhead"))
|
||||||
{
|
{
|
||||||
printer.position[0] = status["toolhead"]["position"][0];
|
|
||||||
printer.position[1] = status["toolhead"]["position"][1];
|
|
||||||
printer.position[2] = status["toolhead"]["position"][2];
|
|
||||||
const char *homed_axis = status["toolhead"]["homed_axes"];
|
const char *homed_axis = status["toolhead"]["homed_axes"];
|
||||||
printer.homed_axis = strcmp(homed_axis, "xyz") == 0;
|
printer.homed_axis = strcmp(homed_axis, "xyz") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.containsKey("gcode_move"))
|
if (status.containsKey("gcode_move"))
|
||||||
{
|
{
|
||||||
|
printer.position[0] = status["gcode_move"]["gcode_position"][0];
|
||||||
|
printer.position[1] = status["gcode_move"]["gcode_position"][1];
|
||||||
|
printer.position[2] = status["gcode_move"]["gcode_position"][2];
|
||||||
bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
|
bool absolute_coords = status["gcode_move"]["absolute_coordinates"];
|
||||||
printer.absolute_coords = absolute_coords == true;
|
printer.absolute_coords = absolute_coords == true;
|
||||||
}
|
}
|
||||||
@@ -179,4 +180,5 @@ void data_setup()
|
|||||||
{
|
{
|
||||||
printer.print_filename = filename_buff;
|
printer.print_filename = filename_buff;
|
||||||
fetch_printer_data();
|
fetch_printer_data();
|
||||||
|
macros_query_setup();
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,7 @@ extern Printer printer;
|
|||||||
|
|
||||||
#define DATA_PRINTER_STATE 1
|
#define DATA_PRINTER_STATE 1
|
||||||
#define DATA_PRINTER_DATA 2
|
#define DATA_PRINTER_DATA 2
|
||||||
|
#define DATA_PRINTER_TEMP_PRESET 3
|
||||||
|
|
||||||
void data_loop();
|
void data_loop();
|
||||||
void data_setup();
|
void data_setup();
|
||||||
51
CYD-Klipper/src/core/macros_query.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "lvgl.h"
|
||||||
|
#include "macros_query.h"
|
||||||
|
#include "./data_setup.h"
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
#include "../conf/global_config.h"
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
static char* macros[64] = {0};
|
||||||
|
static int macros_count = 0;
|
||||||
|
|
||||||
|
static void on_state_change(void * s, lv_msg_t * m) {
|
||||||
|
if (printer.state == PRINTER_STATE_ERROR || printer.state == PRINTER_STATE_PAUSED){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/gcode/help";
|
||||||
|
HTTPClient client;
|
||||||
|
client.begin(url.c_str());
|
||||||
|
int httpCode = client.GET();
|
||||||
|
if (httpCode == 200){
|
||||||
|
String payload = client.getString();
|
||||||
|
DynamicJsonDocument doc(16384);
|
||||||
|
deserializeJson(doc, payload);
|
||||||
|
auto result = doc["result"].as<JsonObject>();
|
||||||
|
|
||||||
|
for (int i = 0; i < macros_count; i++){
|
||||||
|
free(macros[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
macros_count = 0;
|
||||||
|
|
||||||
|
for (JsonPair i : result){
|
||||||
|
const char *key = i.key().c_str();
|
||||||
|
const char *value = i.value().as<String>().c_str();
|
||||||
|
if (strcmp(value, "CYD_SCREEN_MACRO") == 0) {
|
||||||
|
char* macro = (char*)malloc(strlen(key) + 1);
|
||||||
|
strcpy(macro, key);
|
||||||
|
macros[macros_count++] = macro;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MACROSQUERY macros_query() {
|
||||||
|
return {(const char**)macros, macros_count};
|
||||||
|
}
|
||||||
|
|
||||||
|
void macros_query_setup(){
|
||||||
|
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL);
|
||||||
|
on_state_change(NULL, NULL);
|
||||||
|
}
|
||||||
9
CYD-Klipper/src/core/macros_query.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char** macros;
|
||||||
|
uint32_t count;
|
||||||
|
} MACROSQUERY;
|
||||||
|
|
||||||
|
MACROSQUERY macros_query();
|
||||||
|
void macros_query_setup();
|
||||||
@@ -100,12 +100,20 @@ void screen_timer_wake()
|
|||||||
lv_timer_reset(screenSleepTimer);
|
lv_timer_reset(screenSleepTimer);
|
||||||
isScreenInSleep = false;
|
isScreenInSleep = false;
|
||||||
set_screen_brightness();
|
set_screen_brightness();
|
||||||
|
|
||||||
|
// Reset cpu freq
|
||||||
|
setCpuFrequencyMhz(CPU_FREQ_HIGH);
|
||||||
|
Serial.printf("CPU Speed: %d MHz\n", ESP.getCpuFreqMHz());
|
||||||
}
|
}
|
||||||
|
|
||||||
void screen_timer_sleep(lv_timer_t *timer)
|
void screen_timer_sleep(lv_timer_t *timer)
|
||||||
{
|
{
|
||||||
screen_setBrightness(0);
|
screen_setBrightness(0);
|
||||||
isScreenInSleep = true;
|
isScreenInSleep = true;
|
||||||
|
|
||||||
|
// Screen is off, no need to make the cpu run fast, the user won't notice ;)
|
||||||
|
setCpuFrequencyMhz(CPU_FREQ_LOW);
|
||||||
|
Serial.printf("CPU Speed: %d MHz\n", ESP.getCpuFreqMHz());
|
||||||
}
|
}
|
||||||
|
|
||||||
void screen_timer_setup()
|
void screen_timer_setup()
|
||||||
@@ -4,6 +4,9 @@
|
|||||||
#ifndef _SCREEN_DRIVER_INIT
|
#ifndef _SCREEN_DRIVER_INIT
|
||||||
#define _SCREEN_DRIVER_INIT
|
#define _SCREEN_DRIVER_INIT
|
||||||
|
|
||||||
|
#define CPU_FREQ_HIGH 240
|
||||||
|
#define CPU_FREQ_LOW 80
|
||||||
|
|
||||||
#include <XPT2046_Touchscreen.h>
|
#include <XPT2046_Touchscreen.h>
|
||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
|
|
||||||
@@ -25,33 +25,11 @@ void setup() {
|
|||||||
Serial.println("Screen init done");
|
Serial.println("Screen init done");
|
||||||
|
|
||||||
wifi_init();
|
wifi_init();
|
||||||
ip_setup();
|
ip_init();
|
||||||
data_setup();
|
data_setup();
|
||||||
|
|
||||||
nav_style_setup();
|
nav_style_setup();
|
||||||
main_ui_setup();
|
main_ui_setup();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
lv_obj_clean(lv_scr_act());
|
|
||||||
|
|
||||||
lv_obj_t * label;
|
|
||||||
|
|
||||||
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
|
|
||||||
lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_CLICKED, NULL);
|
|
||||||
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);
|
|
||||||
|
|
||||||
label = lv_label_create(btn1);
|
|
||||||
lv_label_set_text(label, "Reset Configuration");
|
|
||||||
lv_obj_center(label);
|
|
||||||
|
|
||||||
lv_obj_t * slider = lv_slider_create(lv_scr_act());
|
|
||||||
lv_obj_set_width(slider, 200);
|
|
||||||
lv_obj_align(slider, LV_ALIGN_CENTER, 0, 40);
|
|
||||||
lv_slider_set_range(slider, 0, 100);
|
|
||||||
lv_slider_set_value(slider, 50, LV_ANIM_OFF);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(){
|
void loop(){
|
||||||
@@ -9,12 +9,15 @@ lv_obj_t * ipEntry;
|
|||||||
lv_obj_t * portEntry;
|
lv_obj_t * portEntry;
|
||||||
lv_obj_t * label = NULL;
|
lv_obj_t * label = NULL;
|
||||||
|
|
||||||
|
void ip_init_inner();
|
||||||
|
|
||||||
bool verify_ip(){
|
bool verify_ip(){
|
||||||
HTTPClient client;
|
HTTPClient client;
|
||||||
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
|
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
|
||||||
int httpCode;
|
int httpCode;
|
||||||
try {
|
try {
|
||||||
Serial.println(url);
|
Serial.println(url);
|
||||||
|
client.setTimeout(500);
|
||||||
client.begin(url.c_str());
|
client.begin(url.c_str());
|
||||||
httpCode = client.GET();
|
httpCode = client.GET();
|
||||||
return httpCode == 200;
|
return httpCode == 200;
|
||||||
@@ -42,8 +45,8 @@ static void ta_event_cb(lv_event_t * e) {
|
|||||||
{
|
{
|
||||||
strcpy(global_config.klipperHost, lv_textarea_get_text(ipEntry));
|
strcpy(global_config.klipperHost, lv_textarea_get_text(ipEntry));
|
||||||
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry));
|
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry));
|
||||||
bool result = verify_ip();
|
|
||||||
if (result)
|
if (verify_ip())
|
||||||
{
|
{
|
||||||
global_config.ipConfigured = true;
|
global_config.ipConfigured = true;
|
||||||
WriteGlobalConfig();
|
WriteGlobalConfig();
|
||||||
@@ -56,9 +59,33 @@ static void ta_event_cb(lv_event_t * e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip_setup_inner(){
|
static void reset_btn_event_handler(lv_event_t * e){
|
||||||
|
lv_event_code_t code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(code == LV_EVENT_CLICKED) {
|
||||||
|
global_config.ipConfigured = false;
|
||||||
|
ip_init_inner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip_init_inner(){
|
||||||
lv_obj_clean(lv_scr_act());
|
lv_obj_clean(lv_scr_act());
|
||||||
|
|
||||||
|
if (global_config.ipConfigured) {
|
||||||
|
label = lv_label_create(lv_scr_act());
|
||||||
|
lv_label_set_text(label, "Connecting to Klipper");
|
||||||
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
|
||||||
|
lv_obj_t * resetBtn = lv_btn_create(lv_scr_act());
|
||||||
|
lv_obj_add_event_cb(resetBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL);
|
||||||
|
lv_obj_align(resetBtn, LV_ALIGN_CENTER, 0, 40);
|
||||||
|
|
||||||
|
lv_obj_t * btnLabel = lv_label_create(resetBtn);
|
||||||
|
lv_label_set_text(btnLabel, "Reset");
|
||||||
|
lv_obj_center(btnLabel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
lv_obj_t * keyboard = lv_keyboard_create(lv_scr_act());
|
lv_obj_t * keyboard = lv_keyboard_create(lv_scr_act());
|
||||||
label = lv_label_create(lv_scr_act());
|
label = lv_label_create(lv_scr_act());
|
||||||
lv_label_set_text(label, "Enter Klipper IP and Port");
|
lv_label_set_text(label, "Enter Klipper IP and Port");
|
||||||
@@ -84,18 +111,26 @@ void ip_setup_inner(){
|
|||||||
lv_keyboard_set_textarea(keyboard, ipEntry);
|
lv_keyboard_set_textarea(keyboard, ipEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ip_setup(){
|
long last_data_update_ip = -10000;
|
||||||
|
const long data_update_interval_ip = 10000;
|
||||||
|
int retry_count = 0;
|
||||||
|
|
||||||
|
void ip_init(){
|
||||||
connect_ok = false;
|
connect_ok = false;
|
||||||
|
|
||||||
if (global_config.ipConfigured && verify_ip()){
|
ip_init_inner();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ip_setup_inner();
|
|
||||||
|
|
||||||
while (!connect_ok)
|
while (!connect_ok)
|
||||||
{
|
{
|
||||||
lv_timer_handler();
|
lv_timer_handler();
|
||||||
lv_task_handler();
|
lv_task_handler();
|
||||||
|
|
||||||
|
if (!connect_ok && global_config.ipConfigured && (millis() - last_data_update_ip) > data_update_interval_ip){
|
||||||
|
connect_ok = verify_ip();
|
||||||
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1
CYD-Klipper/src/ui/ip_setup.h
Normal file
@@ -0,0 +1 @@
|
|||||||
|
void ip_init();
|
||||||
@@ -71,6 +71,10 @@ static void btn_click_settings(lv_event_t * e){
|
|||||||
nav_buttons_setup(3);
|
nav_buttons_setup(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btn_click_macros(lv_event_t * e){
|
||||||
|
nav_buttons_setup(4);
|
||||||
|
}
|
||||||
|
|
||||||
void nav_buttons_setup(unsigned char active_panel){
|
void nav_buttons_setup(unsigned char active_panel){
|
||||||
lv_obj_clean(lv_scr_act());
|
lv_obj_clean(lv_scr_act());
|
||||||
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
|
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
|
||||||
@@ -140,14 +144,14 @@ void nav_buttons_setup(unsigned char active_panel){
|
|||||||
lv_obj_set_size(btn, button_width, button_height);
|
lv_obj_set_size(btn, button_width, button_height);
|
||||||
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 3);
|
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 3);
|
||||||
lv_obj_add_style(btn, &nav_button_style, 0);
|
lv_obj_add_style(btn, &nav_button_style, 0);
|
||||||
lv_obj_add_event_cb(btn, btn_click_settings, LV_EVENT_CLICKED, NULL);
|
lv_obj_add_event_cb(btn, btn_click_macros, LV_EVENT_CLICKED, NULL);
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
label = lv_label_create(btn);
|
||||||
lv_label_set_text(label, LV_SYMBOL_SETTINGS);
|
lv_label_set_text(label, LV_SYMBOL_GPS);
|
||||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
|
||||||
|
|
||||||
label = lv_label_create(btn);
|
label = lv_label_create(btn);
|
||||||
lv_label_set_text(label, "Screen");
|
lv_label_set_text(label, "Macro");
|
||||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
|
||||||
lv_obj_add_style(label, &nav_button_text_style, 0);
|
lv_obj_add_style(label, &nav_button_text_style, 0);
|
||||||
|
|
||||||
@@ -171,6 +175,9 @@ void nav_buttons_setup(unsigned char active_panel){
|
|||||||
case 3:
|
case 3:
|
||||||
settings_panel_init(panel);
|
settings_panel_init(panel);
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
macros_panel_init(panel);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
81
CYD-Klipper/src/ui/panels/macros_panel.cpp
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "lvgl.h"
|
||||||
|
#include "panel.h"
|
||||||
|
#include "../nav_buttons.h"
|
||||||
|
#include "../../core/data_setup.h"
|
||||||
|
#include "../../core/macros_query.h"
|
||||||
|
#include <HardwareSerial.h>
|
||||||
|
|
||||||
|
int y_offset_macros = 40;
|
||||||
|
const int y_element_size = 50;
|
||||||
|
const int y_seperator_size = 1;
|
||||||
|
const int y_seperator_x_padding = 50;
|
||||||
|
const int panel_width = TFT_HEIGHT - 40;
|
||||||
|
const int y_element_x_padding = 30;
|
||||||
|
const static lv_point_t line_points[] = { {0, 0}, {panel_width - y_seperator_x_padding, 0} };
|
||||||
|
|
||||||
|
static void btn_press(lv_event_t * e){
|
||||||
|
lv_obj_t * btn = lv_event_get_target(e);
|
||||||
|
const char* macro = (const char*)lv_event_get_user_data(e);
|
||||||
|
Serial.printf("Macro: %s\n", macro);
|
||||||
|
send_gcode(false, macro);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btn_goto_settings(lv_event_t * e){
|
||||||
|
nav_buttons_setup(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_macro_widget(const char* macro, lv_obj_t* root_panel){
|
||||||
|
lv_obj_t * panel = lv_obj_create(root_panel);
|
||||||
|
lv_obj_set_style_border_width(panel, 0, 0);
|
||||||
|
lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, 0);
|
||||||
|
lv_obj_set_style_pad_all(panel, 0, 0);
|
||||||
|
lv_obj_align(panel, LV_ALIGN_TOP_MID, 0, y_offset_macros);
|
||||||
|
lv_obj_set_size(panel, panel_width - y_element_x_padding, y_element_size);
|
||||||
|
|
||||||
|
lv_obj_t * line = lv_line_create(panel);
|
||||||
|
lv_line_set_points(line, line_points, 2);
|
||||||
|
lv_obj_set_style_line_width(line, y_seperator_size, 0);
|
||||||
|
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
|
||||||
|
lv_obj_align(line, LV_ALIGN_BOTTOM_MID, 0, 0);
|
||||||
|
|
||||||
|
lv_obj_t * label = lv_label_create(panel);
|
||||||
|
lv_label_set_text(label, macro);
|
||||||
|
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||||
|
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
|
||||||
|
lv_obj_set_width(label, (TFT_HEIGHT - 40) * 0.75f);
|
||||||
|
|
||||||
|
lv_obj_t * btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||||
|
lv_obj_add_event_cb(btn, btn_press, LV_EVENT_CLICKED, (void*)macro);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "Run");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
y_offset_macros += y_element_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void macros_panel_init(lv_obj_t* panel) {
|
||||||
|
y_offset_macros = 40;
|
||||||
|
|
||||||
|
lv_obj_t * btn = lv_btn_create(panel);
|
||||||
|
lv_obj_add_event_cb(btn, btn_goto_settings, LV_EVENT_CLICKED, NULL);
|
||||||
|
lv_obj_set_size(btn, TFT_HEIGHT - 40 - 20, 30);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 5);
|
||||||
|
|
||||||
|
lv_obj_t * label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, LV_SYMBOL_SETTINGS " Screen Settings");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
MACROSQUERY query = macros_query();
|
||||||
|
if (query.count == 0){
|
||||||
|
label = lv_label_create(panel);
|
||||||
|
lv_label_set_text(label, "No macros found.\nMacros with the description\n\"CYD_SCREEN_MACRO\"\nwill show up here.");
|
||||||
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < query.count; i++){
|
||||||
|
create_macro_widget(query.macros[i], panel);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,3 +7,4 @@ void temp_panel_init(lv_obj_t* panel);
|
|||||||
void print_panel_init(lv_obj_t* panel);
|
void print_panel_init(lv_obj_t* panel);
|
||||||
void move_panel_init(lv_obj_t* panel);
|
void move_panel_init(lv_obj_t* panel);
|
||||||
void progress_panel_init(lv_obj_t* panel);
|
void progress_panel_init(lv_obj_t* panel);
|
||||||
|
void macros_panel_init(lv_obj_t* panel);
|
||||||
@@ -12,8 +12,27 @@ static void btn_print_file(lv_event_t * e){
|
|||||||
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
|
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
|
||||||
lv_obj_del(panel);
|
lv_obj_del(panel);
|
||||||
|
|
||||||
char* buff = (char*)malloc(128 + strlen(selected_file->name));
|
char* buff = (char*)malloc(128 + (strlen(selected_file->name) * 3));
|
||||||
sprintf(buff, "http://%s:%d/printer/print/start?filename=%s", global_config.klipperHost, global_config.klipperPort, selected_file->name);
|
sprintf(buff, "http://%s:%d/printer/print/start?filename=", global_config.klipperHost, global_config.klipperPort);
|
||||||
|
|
||||||
|
char* ptr = buff + strlen(buff);
|
||||||
|
int filename_length = strlen(selected_file->name);
|
||||||
|
for (int i = 0; i < filename_length; i++){
|
||||||
|
char c = selected_file->name[i];
|
||||||
|
if (c == ' '){
|
||||||
|
*ptr = '%';
|
||||||
|
ptr++;
|
||||||
|
*ptr = '2';
|
||||||
|
ptr++;
|
||||||
|
*ptr = '0';
|
||||||
|
} else {
|
||||||
|
*ptr = c;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr = 0;
|
||||||
|
|
||||||
HTTPClient client;
|
HTTPClient client;
|
||||||
client.begin(buff);
|
client.begin(buff);
|
||||||
int httpCode = client.POST("");
|
int httpCode = client.POST("");
|
||||||
307
CYD-Klipper/src/ui/panels/temp_panel.cpp
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
#include "lvgl.h"
|
||||||
|
#include "../../core/data_setup.h"
|
||||||
|
#include "../../conf/global_config.h"
|
||||||
|
#include <HardwareSerial.h>
|
||||||
|
|
||||||
|
enum temp_target{
|
||||||
|
TARGET_HOTEND,
|
||||||
|
TARGET_BED,
|
||||||
|
TARGET_HOTEND_CONFIG_1,
|
||||||
|
TARGET_HOTEND_CONFIG_2,
|
||||||
|
TARGET_HOTEND_CONFIG_3,
|
||||||
|
TARGET_BED_CONFIG_1,
|
||||||
|
TARGET_BED_CONFIG_2,
|
||||||
|
TARGET_BED_CONFIG_3,
|
||||||
|
};
|
||||||
|
|
||||||
|
static temp_target keyboard_target;
|
||||||
|
static char hotend_buff[40];
|
||||||
|
static char bed_buff[40];
|
||||||
|
static bool edit_mode = false;
|
||||||
|
lv_obj_t* root_panel;
|
||||||
|
|
||||||
|
static void update_printer_data_hotend_temp(lv_event_t * e){
|
||||||
|
lv_obj_t * label = lv_event_get_target(e);
|
||||||
|
sprintf(hotend_buff, "Hotend: %.0f C (Target: %.0f C)", printer.extruder_temp, printer.extruder_target_temp);
|
||||||
|
lv_label_set_text(label, hotend_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_printer_data_bed_temp(lv_event_t * e){
|
||||||
|
lv_obj_t * label = lv_event_get_target(e);
|
||||||
|
sprintf(bed_buff, "Bed: %.0f C (Target: %.0f C)", printer.bed_temp, printer.bed_target_temp);
|
||||||
|
lv_label_set_text(label, bed_buff);
|
||||||
|
}
|
||||||
|
|
||||||
|
static short get_temp_preset(int target){
|
||||||
|
switch (target){
|
||||||
|
case TARGET_HOTEND_CONFIG_1:
|
||||||
|
return global_config.hotend_presets[0];
|
||||||
|
case TARGET_HOTEND_CONFIG_2:
|
||||||
|
return global_config.hotend_presets[1];
|
||||||
|
case TARGET_HOTEND_CONFIG_3:
|
||||||
|
return global_config.hotend_presets[2];
|
||||||
|
case TARGET_BED_CONFIG_1:
|
||||||
|
return global_config.bed_presets[0];
|
||||||
|
case TARGET_BED_CONFIG_2:
|
||||||
|
return global_config.bed_presets[1];
|
||||||
|
case TARGET_BED_CONFIG_3:
|
||||||
|
return global_config.bed_presets[2];
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_temp_preset_label(lv_event_t * e){
|
||||||
|
lv_obj_t * label = lv_event_get_target(e);
|
||||||
|
int target = static_cast<int>(reinterpret_cast<intptr_t>(lv_event_get_user_data(e)));
|
||||||
|
short value = get_temp_preset(target);
|
||||||
|
|
||||||
|
String text_label = String(value) + " C";
|
||||||
|
lv_label_set_text(label, text_label.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateConfig(){
|
||||||
|
WriteGlobalConfig();
|
||||||
|
lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keyboard_callback(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 * text = lv_textarea_get_text(ta);
|
||||||
|
|
||||||
|
int temp = atoi(text);
|
||||||
|
if (temp < 0 || temp > 500){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char gcode[64];
|
||||||
|
const char* space = "%20";
|
||||||
|
|
||||||
|
switch (keyboard_target){
|
||||||
|
case TARGET_HOTEND:
|
||||||
|
sprintf(gcode, "M104%sS%d", space, temp);
|
||||||
|
send_gcode(true, gcode);
|
||||||
|
break;
|
||||||
|
case TARGET_BED:
|
||||||
|
sprintf(gcode, "M140%sS%d", space, temp);
|
||||||
|
send_gcode(true, gcode);
|
||||||
|
break;
|
||||||
|
case TARGET_HOTEND_CONFIG_1:
|
||||||
|
global_config.hotend_presets[0] = temp;
|
||||||
|
UpdateConfig();
|
||||||
|
break;
|
||||||
|
case TARGET_HOTEND_CONFIG_2:
|
||||||
|
global_config.hotend_presets[1] = temp;
|
||||||
|
UpdateConfig();
|
||||||
|
break;
|
||||||
|
case TARGET_HOTEND_CONFIG_3:
|
||||||
|
global_config.hotend_presets[2] = temp;
|
||||||
|
UpdateConfig();
|
||||||
|
break;
|
||||||
|
case TARGET_BED_CONFIG_1:
|
||||||
|
global_config.bed_presets[0] = temp;
|
||||||
|
UpdateConfig();
|
||||||
|
break;
|
||||||
|
case TARGET_BED_CONFIG_2:
|
||||||
|
global_config.bed_presets[1] = temp;
|
||||||
|
UpdateConfig();
|
||||||
|
break;
|
||||||
|
case TARGET_BED_CONFIG_3:
|
||||||
|
global_config.bed_presets[2] = temp;
|
||||||
|
UpdateConfig();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(code == LV_EVENT_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY) {
|
||||||
|
lv_keyboard_set_textarea(kb, NULL);
|
||||||
|
lv_obj_del(kb);
|
||||||
|
lv_obj_del(ta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_keyboard(lv_event_t * e){
|
||||||
|
lv_obj_t * keyboard = lv_keyboard_create(root_panel);
|
||||||
|
lv_obj_t * ta = lv_textarea_create(root_panel);
|
||||||
|
lv_obj_set_size(ta, TFT_HEIGHT - 40, 120);
|
||||||
|
lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 0);
|
||||||
|
lv_textarea_set_max_length(ta, 3);
|
||||||
|
//lv_textarea_set_one_line(ta, true);
|
||||||
|
lv_textarea_set_text(ta, "");
|
||||||
|
lv_textarea_set_align(ta, LV_TEXT_ALIGN_CENTER);
|
||||||
|
lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_ALL, keyboard);
|
||||||
|
|
||||||
|
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER);
|
||||||
|
lv_keyboard_set_textarea(keyboard, ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_keyboard_with_hotend(lv_event_t * e){
|
||||||
|
keyboard_target = TARGET_HOTEND;
|
||||||
|
show_keyboard(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_keyboard_with_bed(lv_event_t * e){
|
||||||
|
keyboard_target = TARGET_BED;
|
||||||
|
show_keyboard(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cooldown_temp(lv_event_t * e){
|
||||||
|
if (printer.state == PRINTER_STATE_PRINTING){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_gcode(true, "M104%20S0");
|
||||||
|
send_gcode(true, "M140%20S0");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btn_extrude(lv_event_t * e){
|
||||||
|
if (printer.state == PRINTER_STATE_PRINTING){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_gcode(true, "M83");
|
||||||
|
send_gcode(true, "G1%20E25%20F300");
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
int value = get_temp_preset(target);
|
||||||
|
|
||||||
|
if (edit_mode) {
|
||||||
|
keyboard_target = (temp_target)target;
|
||||||
|
show_keyboard(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char gcode[64];
|
||||||
|
const char* space = "%20";
|
||||||
|
if (target <= TARGET_HOTEND_CONFIG_3)
|
||||||
|
sprintf(gcode, "M104%sS%d", space, value);
|
||||||
|
else
|
||||||
|
sprintf(gcode, "M140%sS%d", space, value);
|
||||||
|
|
||||||
|
send_gcode(true, gcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btn_toggleable_edit(lv_event_t * e){
|
||||||
|
lv_obj_t * btn = lv_event_get_target(e);
|
||||||
|
auto state = lv_obj_get_state(btn);
|
||||||
|
edit_mode = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btn_retract(lv_event_t * e){
|
||||||
|
if (printer.state == PRINTER_STATE_PRINTING){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_gcode(true, "M83");
|
||||||
|
send_gcode(true, "G1%20E-25%20F300");
|
||||||
|
}
|
||||||
|
|
||||||
|
void temp_panel_init(lv_obj_t* panel){
|
||||||
|
root_panel = panel;
|
||||||
|
edit_mode = false;
|
||||||
|
const int btn_row_y_one = 30;
|
||||||
|
const int btn_row_y_two = 100;
|
||||||
|
auto panel_width = TFT_HEIGHT - 40;
|
||||||
|
lv_obj_t * label = lv_label_create(panel);
|
||||||
|
lv_label_set_text(label, "???");
|
||||||
|
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10);
|
||||||
|
lv_obj_add_event_cb(label, update_printer_data_hotend_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
||||||
|
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||||
|
|
||||||
|
label = lv_label_create(panel);
|
||||||
|
lv_label_set_text(label, "???");
|
||||||
|
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 80);
|
||||||
|
lv_obj_add_event_cb(label, update_printer_data_bed_temp, LV_EVENT_MSG_RECEIVED, NULL);
|
||||||
|
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
|
||||||
|
|
||||||
|
lv_obj_t * btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, btn_row_y_one);
|
||||||
|
lv_obj_add_event_cb(btn, show_keyboard_with_hotend, LV_EVENT_CLICKED, panel);
|
||||||
|
lv_obj_set_width(btn, panel_width / 4 - 10);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "Set");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, btn_row_y_two);
|
||||||
|
lv_obj_add_event_cb(btn, show_keyboard_with_bed, LV_EVENT_CLICKED, panel);
|
||||||
|
lv_obj_set_width(btn, panel_width / 4 - 10);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "Set");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
// Presets
|
||||||
|
for (int i = 0; i < 3; i++){
|
||||||
|
int x_pos = 10 + (panel_width / 4) * i - (3 * i);
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_pos, btn_row_y_one);
|
||||||
|
lv_obj_add_event_cb(btn, set_temp_via_preset, LV_EVENT_CLICKED, reinterpret_cast<void*>(TARGET_HOTEND_CONFIG_1 + i));
|
||||||
|
lv_obj_set_width(btn, panel_width / 4 - 10);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "???");
|
||||||
|
lv_obj_center(label);
|
||||||
|
lv_obj_add_event_cb(label, update_temp_preset_label, LV_EVENT_MSG_RECEIVED, reinterpret_cast<void*>(TARGET_HOTEND_CONFIG_1 + i));
|
||||||
|
lv_msg_subscribe_obj(DATA_PRINTER_TEMP_PRESET, label, NULL);
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_pos, btn_row_y_two);
|
||||||
|
lv_obj_add_event_cb(btn, set_temp_via_preset, LV_EVENT_CLICKED, reinterpret_cast<void*>(TARGET_BED_CONFIG_1 + i));
|
||||||
|
lv_obj_set_width(btn, panel_width / 4 - 10);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "???");
|
||||||
|
lv_obj_center(label);
|
||||||
|
lv_obj_add_event_cb(label, update_temp_preset_label, LV_EVENT_MSG_RECEIVED, reinterpret_cast<void*>(TARGET_BED_CONFIG_1 + i));
|
||||||
|
lv_msg_subscribe_obj(DATA_PRINTER_TEMP_PRESET, label, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -50);
|
||||||
|
lv_obj_set_size(btn, panel_width / 2 - 15, 40);
|
||||||
|
lv_obj_add_event_cb(btn, cooldown_temp, LV_EVENT_CLICKED, panel);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "Cooldown");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -50);
|
||||||
|
lv_obj_add_event_cb(btn, btn_toggleable_edit, LV_EVENT_CLICKED, NULL);
|
||||||
|
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
|
||||||
|
lv_obj_set_size(btn, panel_width / 2 - 15, 40);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, "Edit Presets");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -5);
|
||||||
|
lv_obj_add_event_cb(btn, btn_extrude, LV_EVENT_CLICKED, NULL);
|
||||||
|
lv_obj_set_size(btn, panel_width / 2 - 15, 40);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, LV_SYMBOL_DOWN " Extrude");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
btn = lv_btn_create(panel);
|
||||||
|
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -5);
|
||||||
|
lv_obj_add_event_cb(btn, btn_retract, LV_EVENT_CLICKED, NULL);
|
||||||
|
lv_obj_set_size(btn, panel_width / 2 - 15, 40);
|
||||||
|
|
||||||
|
label = lv_label_create(btn);
|
||||||
|
lv_label_set_text(label, LV_SYMBOL_UP " Retract");
|
||||||
|
lv_obj_center(label);
|
||||||
|
|
||||||
|
lv_msg_send(DATA_PRINTER_DATA, &printer);
|
||||||
|
lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer);
|
||||||
|
}
|
||||||
@@ -77,12 +77,11 @@ static void wifi_btn_event_handler(lv_event_t * e){
|
|||||||
|
|
||||||
void wifi_init_inner(){
|
void wifi_init_inner(){
|
||||||
WiFi.disconnect();
|
WiFi.disconnect();
|
||||||
|
lv_obj_clean(lv_scr_act());
|
||||||
|
|
||||||
if (global_config.wifiConfigured){
|
if (global_config.wifiConfigured){
|
||||||
WiFi.begin(global_config.wifiSSID, global_config.wifiPassword);
|
WiFi.begin(global_config.wifiSSID, global_config.wifiPassword);
|
||||||
|
|
||||||
lv_obj_clean(lv_scr_act());
|
|
||||||
|
|
||||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||||
lv_label_set_text(label, "Connecting to WiFi");
|
lv_label_set_text(label, "Connecting to WiFi");
|
||||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||||
@@ -98,8 +97,6 @@ void wifi_init_inner(){
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_obj_clean(lv_scr_act());
|
|
||||||
|
|
||||||
lv_obj_t * label = lv_label_create(lv_scr_act());
|
lv_obj_t * label = lv_label_create(lv_scr_act());
|
||||||
lv_label_set_text(label, "Scanning for networks...");
|
lv_label_set_text(label, "Scanning for networks...");
|
||||||
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
|
||||||
@@ -108,8 +105,6 @@ void wifi_init_inner(){
|
|||||||
lv_task_handler();
|
lv_task_handler();
|
||||||
lv_refr_now(NULL);
|
lv_refr_now(NULL);
|
||||||
|
|
||||||
int n = WiFi.scanNetworks();
|
|
||||||
|
|
||||||
lv_obj_clean(lv_scr_act());
|
lv_obj_clean(lv_scr_act());
|
||||||
|
|
||||||
lv_obj_t * refreshBtn = lv_btn_create(lv_scr_act());
|
lv_obj_t * refreshBtn = lv_btn_create(lv_scr_act());
|
||||||
@@ -128,25 +123,50 @@ void wifi_init_inner(){
|
|||||||
lv_obj_align(list, LV_ALIGN_TOP_LEFT, 10, 40);
|
lv_obj_align(list, LV_ALIGN_TOP_LEFT, 10, 40);
|
||||||
lv_obj_set_size(list, TFT_HEIGHT - 20, TFT_WIDTH - 40 - 5);
|
lv_obj_set_size(list, TFT_HEIGHT - 20, TFT_WIDTH - 40 - 5);
|
||||||
|
|
||||||
|
int n = WiFi.scanNetworks();
|
||||||
|
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
const char* ssid = WiFi.SSID(i).c_str();
|
String ssid = WiFi.SSID(i);
|
||||||
int len = strlen(ssid);
|
char* ssid_copy = (char*)malloc(ssid.length() + 1);
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
if (len == 0)
|
for (; j < ssid.length(); ++j){
|
||||||
continue;
|
if (ssid[j] == '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ssid_copy[j] = ssid[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid_copy[j] = '\0';
|
||||||
|
|
||||||
const char* ssid_copy = (const char*)malloc(len + 1);
|
|
||||||
strcpy((char*)ssid_copy, ssid);
|
|
||||||
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_WIFI, ssid_copy);
|
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_WIFI, ssid_copy);
|
||||||
lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_ALL, (void*)ssid_copy);
|
lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_ALL, (void*)ssid_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* errs[] = {
|
||||||
|
"Idle",
|
||||||
|
"No SSID Available",
|
||||||
|
"Scan Completed",
|
||||||
|
"Connected",
|
||||||
|
"Connection Failed",
|
||||||
|
"Connection Lost",
|
||||||
|
"Disconnected"
|
||||||
|
};
|
||||||
|
|
||||||
|
const int print_freq = 1000;
|
||||||
|
int print_timer = 0;
|
||||||
|
|
||||||
void wifi_init(){
|
void wifi_init(){
|
||||||
WiFi.mode(WIFI_STA);
|
WiFi.mode(WIFI_STA);
|
||||||
wifi_init_inner();
|
wifi_init_inner();
|
||||||
|
|
||||||
while (!global_config.wifiConfigured || WiFi.status() != WL_CONNECTED){
|
while (!global_config.wifiConfigured || WiFi.status() != WL_CONNECTED){
|
||||||
|
if (millis() - print_timer > print_freq){
|
||||||
|
print_timer = millis();
|
||||||
|
Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]);
|
||||||
|
}
|
||||||
|
|
||||||
lv_timer_handler();
|
lv_timer_handler();
|
||||||
lv_task_handler();
|
lv_task_handler();
|
||||||
}
|
}
|
||||||
45
README.md
@@ -1,3 +1,44 @@
|
|||||||
# CYD-Klipper-Display
|

|
||||||
|
[](https://ko-fi.com/suchmememanyskill)
|
||||||
|
|
||||||
WIP!
|
# CYD-Klipper
|
||||||
|
An implementation of a wireless Klipper status display on an ESP32 + screen. Uses Moonraker to fetch data.
|
||||||
|
|
||||||
|
A simple and cheap solution to use a dedicated screen with Klipper, a 3d printing Firmware.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Required hardware
|
||||||
|
|
||||||
|
A ESP32-2432S028R is required to run this project. You can find out where to buy these on the ["ESP32 Cheap Yellow Display"](https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display#where-to-buy) repository.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- View printer status
|
||||||
|
- View print progress
|
||||||
|
- Start a print
|
||||||
|
- Move the printer
|
||||||
|
- Manage temperature
|
||||||
|
- Extrude/Retract filament
|
||||||
|
- Execute predefined gcode macros
|
||||||
|
|
||||||
|
### 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/)
|
||||||
|
|
||||||
|
On initial install, all data should be wiped. On updates, data should be able to be kept without issues.
|
||||||
|
|
||||||
|
There are no 'over the air' updates. Each update has to be applied manually.
|
||||||
|
|
||||||
|
### Screenshots
|
||||||
|
(Quite literally shots of the screen. I'm sorry)
|
||||||
|
|
||||||
|
-|-
|
||||||
|
:-:|:-:
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
### Credits
|
||||||
|
- [xtouch](https://github.com/xperiments-in/xtouch)
|
||||||
|
- [ESP32-Cheap-Yellow-Display](https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display)
|
||||||
32
_site/index.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
width: fit-content;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script type="module" src="https://unpkg.com/esp-web-tools@9/dist/web/install-button.js?module"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<section class="main">
|
||||||
|
<h2>CYD-Klipper</h2>
|
||||||
|
<p>An implementation of a Klipper status display on an ESP32 + screen.<br>Uses Moonraker to fetch data.</p>
|
||||||
|
<img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/suchmememanyskill/CYD-Klipper">
|
||||||
|
<a href="https://github.com/suchmememanyskill/CYD-Klipper"><img alt="GitHub repo" src="https://img.shields.io/badge/Source-Github-blue.svg"></a>
|
||||||
|
<section class="install">
|
||||||
|
<h3>Install</h3>
|
||||||
|
<p>Note: You may need to hold the 'BOOT' button on the device while pressing install</p>
|
||||||
|
<esp-web-install-button
|
||||||
|
manifest="https://suchmememanyskill.github.io/CYD-Klipper/manifest.json"></esp-web-install-button>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
27
_site/manifest.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "CYD-Klipper",
|
||||||
|
"new_install_prompt_erase": true,
|
||||||
|
"builds": [
|
||||||
|
{
|
||||||
|
"chipFamily": "ESP32",
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"path": "output/bootloader.bin",
|
||||||
|
"offset": 4096
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "output/partitions.bin",
|
||||||
|
"offset": 32768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "output/boot_app0.bin",
|
||||||
|
"offset": 57344
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "output/firmware.bin",
|
||||||
|
"offset": 65536
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
10
_site/manifest_wipe.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "CYD-Klipper",
|
||||||
|
"new_install_prompt_erase": false,
|
||||||
|
"builds": [
|
||||||
|
{
|
||||||
|
"path": "output/merged-firmware.bin",
|
||||||
|
"offset": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
readme/PXL_20231113_142717308.jpg
Normal file
|
After Width: | Height: | Size: 335 KiB |
BIN
readme/PXL_20231113_171629383.jpg
Normal file
|
After Width: | Height: | Size: 533 KiB |
BIN
readme/PXL_20231113_171701876.jpg
Normal file
|
After Width: | Height: | Size: 890 KiB |
BIN
readme/PXL_20231113_171715809.jpg
Normal file
|
After Width: | Height: | Size: 552 KiB |
BIN
readme/PXL_20231113_171724404.jpg
Normal file
|
After Width: | Height: | Size: 911 KiB |
BIN
readme/PXL_20231113_171751745.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
readme/PXL_20231113_171809315.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |