127 Commits

Author SHA1 Message Date
Sims
4bfe149244 Merge pull request #66 from suchmememanyskill/dev
v1.5.0
2024-03-15 22:42:34 +01:00
suchmememanyskill
7aceb85621 Move error ui to panel 2024-03-14 19:00:57 +01:00
suchmememanyskill
9c958b42b3 Fix macro panel in error screen 2024-03-14 18:28:22 +01:00
suchmememanyskill
92d47d8c07 Move print preview image to the top left 2024-03-13 22:42:06 +01:00
suchmememanyskill
1a31ef0758 map error text in moonraker as error state 2024-03-13 22:26:10 +01:00
suchmememanyskill
a7bde99442 Fix inverted vertical 2024-03-13 20:20:57 +01:00
suchmememanyskill
be3b2ddb24 3248S035C Vertical 2024-03-13 19:50:20 +01:00
suchmememanyskill
36b37176d6 Fix macros tab controlling other printers 2024-03-13 18:46:13 +01:00
suchmememanyskill
d0d80e8980 Imrpove site 2024-03-12 22:06:52 +01:00
suchmememanyskill
65abe295c9 Fix button disable conditions 2024-03-12 21:30:23 +01:00
suchmememanyskill
a8c94fe207 Refactor + Power menu in printer menu 2024-03-12 21:08:48 +01:00
suchmememanyskill
a265301d97 Update smartdisplay driver to v2.0.7 2024-03-11 22:20:56 +01:00
suchmememanyskill
90dcf95cf6 Merge branch 'experimental-multi-printer' into dev 2024-03-11 21:55:44 +01:00
suchmememanyskill
8d6d22c38a Change status to 'In Control' when in control 2024-03-11 21:55:33 +01:00
suchmememanyskill
fb1e264df7 Display M117 message on screen 2024-03-10 01:08:47 +01:00
suchmememanyskill
e457114402 (Hopefully) fix touch on 2432S024C 2024-03-10 00:03:30 +01:00
suchmememanyskill
61f15ff6f3 Fix bugs 2024-03-09 21:43:46 +01:00
suchmememanyskill
451304b5df Add 2432S024C and 4827S043C to CI 2024-03-09 21:16:55 +01:00
suchmememanyskill
68ff78eb49 Add 2432S024C-smartdisplay 2024-03-09 21:16:40 +01:00
Andrey Melnikov
215439df2f adds esp32-4827s043C-smartdisplay (#63)
* +add esp32-4827s043C

* DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX 40 to 35
2024-03-09 21:10:39 +01:00
suchmememanyskill
397c835129 Add build instructions 2024-03-09 21:08:45 +01:00
suchmememanyskill
870d109c92 Implement printer switching in ip connect/error screen 2024-03-09 20:47:45 +01:00
suchmememanyskill
f98c2eff78 Small refactor 2024-03-09 19:22:24 +01:00
suchmememanyskill
67b5ce1948 Set max printer name limit to 24 chars 2024-03-09 01:56:35 +01:00
suchmememanyskill
e9b58e0a6f Implement printer panel fully 2024-03-09 01:55:31 +01:00
suchmememanyskill
3b7b49c62b Split configuration; start printer panel 2024-03-07 23:25:12 +01:00
suchmememanyskill
f0cc211e30 Unify http client creation 2024-03-06 22:32:49 +01:00
suchmememanyskill
9427381e05 Add other CYD 2.8R inch models for smartdisplay 2024-03-03 01:02:52 +01:00
suchmememanyskill
02e27e6d83 Set screen brightness in lvgl setup 2024-03-03 01:00:09 +01:00
suchmememanyskill
b65003e40b Better button sizes for esp32-3248S035C 2024-03-02 23:50:24 +01:00
suchmememanyskill
cb242240d3 Remove unneeded code 2024-03-02 22:11:39 +01:00
suchmememanyskill
c061164edf Fix compile on linux 2024-03-02 22:06:15 +01:00
suchmememanyskill
ea42bf775d Merge branch 'experimental_load_gcode_img-2' into dev 2024-03-02 22:03:14 +01:00
suchmememanyskill
4e6457c729 Misc fixes 2024-03-02 22:02:20 +01:00
themacboy
bc3ca3892f Some visual UI tweaks for ESP32-8048S043C (#57)
* Some visual UI tweaks

* more visual UI tweaks adjustements
2024-03-02 21:57:00 +01:00
suchmememanyskill
639eb50371 A 2024-03-02 21:16:31 +01:00
suchmememanyskill
1adb966ee1 Image load round 2 (slightly less unstable) 2024-03-02 21:05:16 +01:00
suchmememanyskill
64290afd89 Set size for settings dropdown 2024-03-02 14:18:37 +01:00
suchmememanyskill
3fbd14f154 Hopefully fix esp32-8048S043C 2024-03-02 10:38:34 +01:00
suchmememanyskill
ef3676faef Merge branch 'dev' into 4.3inch 2024-03-02 10:32:14 +01:00
suchmememanyskill
fc7cfbd85b Add esp32-2432S032C to CI 2024-03-02 10:22:18 +01:00
suchmememanyskill
49c27f2b01 Add esp32-2432S032C 2024-03-02 10:21:09 +01:00
suchmememanyskill
801432c3a6 Driver configuration improvements 2024-03-02 10:19:03 +01:00
suchmememanyskill
55e9ce3d81 Vertical UI, round 2 2024-03-01 22:28:35 +01:00
suchmememanyskill
f467e8a604 Add esp32-8048S043C 2024-02-27 21:32:00 +01:00
suchmememanyskill
45779b5a13 Make calibration work with smartdisplay driver 2024-02-24 14:27:03 +01:00
Sims
1c7d5ffacd Merge pull request #51 from suchmememanyskill/dev
v1.4.0
2024-02-21 23:33:13 +01:00
suchmememanyskill
1bc770a1cf Undo o2 optimalisations 2024-02-21 23:20:01 +01:00
suchmememanyskill
b5ac6d045a Retry slicer print time fetch 2024-02-20 23:20:33 +01:00
suchmememanyskill
c9f8935310 Don't send gcode requests twice 2024-02-20 22:40:00 +01:00
suchmememanyskill
ff1c13602c Add API key flow 2024-02-19 21:56:35 +01:00
Flaviu Tamas
5d3d32b116 Fix frequent null-pointer errors (#49)
I was frequently seeing the following and a reboot:

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x4008ae2d  PS      : 0x00060330  A0      : 0x800d3fd9  A1      : 0x3ffe15f0
A2      : 0x3ffc40e8  A3      : 0x00000000  A4      : 0x000000ff  A5      : 0x0000ff00
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x00000000  A9      : 0x3ffe15c0
A10     : 0x3ffc40e8  A11     : 0x3f40035d  A12     : 0x3ffe16a0  A13     : 0x000004b0
A14     : 0x7ff00000  A15     : 0x7ff2c000  SAR     : 0x0000001d  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x4008ae2d  LEND    : 0x4008ae41  LCOUNT  : 0xffffffff

Backtrace: 0x4008ae2a:0x3ffe15f0 0x400d3fd6:0x3ffe1600 0x400d42d3:0x3ffe18f0

decoded:

0x4008acbc: strcmp at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/strcmp.S:467
0x400d4145: fetch_printer_data() at /home/user/tmp/CYD-Klipper/CYD-Klipper/src/core/data_setup.cpp:180
0x400d42d3: data_loop_background(void*) at /home/user/tmp/CYD-Klipper/CYD-Klipper/src/core/data_setup.cpp:233 (discriminator 1)

Seems like the printer state was frequently ending up as null, so check
for that and return a reasonable response. After applying this patch,
things are stable for me.
2024-02-19 21:26:22 +01:00
suchmememanyskill
edec1724e6 Properly fix #45 2024-02-19 17:37:08 +01:00
suchmememanyskill
dd5e82d637 Reorder settings 2024-02-19 17:16:56 +01:00
suchmememanyskill
e5edabffa4 Add slicer time based estimates 2024-02-18 12:04:01 +01:00
suchmememanyskill
a1bb6a750f Improve Z Offset menu 2024-02-17 12:11:18 +01:00
suchmememanyskill
43cefaafd2 Make temp chart fit the lines 2024-02-16 23:39:35 +01:00
suchmememanyskill
dcf32d6685 Fix temp chart crashing 2024-02-16 23:09:32 +01:00
suchmememanyskill
12c4319173 Add graph to temp panel 2024-02-16 22:47:55 +01:00
suchmememanyskill
86be30034d Optimalisations 2024-02-16 22:15:15 +01:00
suchmememanyskill
4fc2316970 (Hack) Restart ESP when klipper calls start failing 2024-02-15 18:32:36 +01:00
suchmememanyskill
3dc241dbec Make stats panel accessible from move panel, improve Z offset menu 2024-02-15 18:29:13 +01:00
suchmememanyskill
cd58fcae4f Move touch calibration to lv_conf, implement invert colors in smartdisplay driver 2024-02-12 22:26:09 +01:00
suchmememanyskill
87a9257e19 Add ESP32-2432S022C using smartdisplay driver 2024-02-12 18:24:30 +01:00
suchmememanyskill
a436c6b5c7 Update readme 2024-02-11 10:33:22 +01:00
Sims
2b92b8daee Merge pull request #37 from suchmememanyskill/dev
v1.3.0
2024-02-11 00:23:56 +01:00
suchmememanyskill
c443bb74d7 increase 3.5" screens SPI freq to 80mhz 2024-02-10 23:24:24 +01:00
suchmememanyskill
2fb83df0cf Set default font in a better way 2024-02-10 13:11:11 +01:00
suchmememanyskill
1c10d46a5e Make temp manual entry ui responsive 2024-02-10 13:02:40 +01:00
suchmememanyskill
d3e7eec47a Reset config, fix screen calibration 2024-02-10 12:09:43 +01:00
suchmememanyskill
64266b1ff8 Implement OTA updates 2024-02-10 00:37:25 +01:00
suchmememanyskill
254d8453ad A 2024-02-09 22:12:51 +01:00
suchmememanyskill
f05246f8c7 Ignore tags during build 2024-02-09 22:11:54 +01:00
suchmememanyskill
5bbdc9e509 Fix version extractor 2024-02-09 21:51:24 +01:00
suchmememanyskill
4302c4492c More CI changes 2024-02-09 21:44:21 +01:00
suchmememanyskill
8ff2be168e Fetch entire git history so tag can be extracted 2024-02-09 21:28:17 +01:00
suchmememanyskill
4fe6f3e975 State device name in webinstall tool 2024-02-09 21:22:56 +01:00
Sims
b8cb7f7ad9 Merge pull request #34 from suchmememanyskill/dev
v1.2.0: More displays, improved ui, unified ui
2024-02-09 21:15:05 +01:00
suchmememanyskill
15209544d0 Add version to settings 2024-02-09 21:06:23 +01:00
suchmememanyskill
452dbefbdb Is this why linux CI broke? 2024-02-09 20:13:28 +01:00
suchmememanyskill
adea917a5d html changes 2024-02-09 19:19:20 +01:00
Matt Hawley
e5efe08fc3 Updating keyboard to match style / layout of original (#33) 2024-02-09 19:10:33 +01:00
suchmememanyskill
2c7aab7607 Shuffle around board defines 2024-02-09 19:05:16 +01:00
suchmememanyskill
4daa0aa549 Extract display timeout from driver 2024-02-09 18:53:17 +01:00
suchmememanyskill
134e7ad48d Remove reference to boards 2024-02-09 17:47:29 +01:00
suchmememanyskill
2d6c2e8d10 Fix up smartdisplay driver, update readme, update install page 2024-02-08 23:35:31 +01:00
suchmememanyskill
725d76d9c5 Modify CI further 2024-02-07 23:39:25 +01:00
suchmememanyskill
e669017949 I hate CI 2024-02-07 23:07:44 +01:00
suchmememanyskill
82b1d515d1 Edit CI 2024-02-07 23:02:28 +01:00
suchmememanyskill
f985813960 Update boards 2024-02-07 22:37:52 +01:00
suchmememanyskill
81aa08b732 Delete boards 2024-02-07 22:25:26 +01:00
suchmememanyskill
fb928d28db Fix broken auto sleep 2024-02-07 22:10:04 +01:00
suchmememanyskill
716f934b6c Fix scaling for 3.5inch, Fix text scaling in general 2024-02-07 21:58:23 +01:00
suchmememanyskill
26a0f35dd2 Merge branch 'setup-ports' of https://github.com/suchmememanyskill/CYD-Klipper-Display into setup-ports 2024-02-07 21:04:01 +01:00
suchmememanyskill
ab4688c6dd Initial port to ESP32_3248S035C 2024-02-07 21:03:26 +01:00
Matt Hawley
c18cd10c69 Adding support for hostname with dual keyboards for port (#29)
* Adding support for hostname with dual keyboards for port

* Updating to use a single keyboard

* Changing keyboard layout
2024-02-06 17:30:59 +01:00
suchmememanyskill
1f76012423 Make power devices also show on klipper connect screen if available 2024-02-03 23:45:28 +01:00
suchmememanyskill
a07d28293c Add power devices to macro menu 2024-02-03 22:41:31 +01:00
suchmememanyskill
e152868e0f Add macros to not ready screen 2024-02-03 17:22:09 +01:00
suchmememanyskill
77db3652f2 Add info to stat panel 2024-02-03 16:39:49 +01:00
suchmememanyskill
41be4b1a31 Add stats panel 2024-02-03 15:16:25 +01:00
suchmememanyskill
ba015bb2e8 Switch to fork of lvgl for keyboard mods 2024-02-01 18:18:36 +01:00
suchmememanyskill
1ff75d2aa5 Process feedback partially 2024-02-01 18:10:40 +01:00
suchmememanyskill
4e7bff92c9 Test CI 2 2024-01-30 20:50:35 +01:00
suchmememanyskill
9c12588187 CI pls 2024-01-30 20:47:56 +01:00
suchmememanyskill
a84c695a9f Kickstart workflow 2024-01-30 20:39:00 +01:00
suchmememanyskill
c077b6e617 Remove leftover defines 2024-01-30 20:32:45 +01:00
suchmememanyskill
899f89b57d Make ip setup responsive 2024-01-30 20:12:42 +01:00
suchmememanyskill
982c03b0f6 Make wifi-setup responsive 2024-01-30 19:02:59 +01:00
suchmememanyskill
0ba2abd6b1 Rename BIG_GAP to GAP 2024-01-29 20:56:03 +01:00
suchmememanyskill
de1833e219 Make klipper error screen responsive 2024-01-29 20:51:25 +01:00
suchmememanyskill
c5b6401c60 Remove unneeded code 2024-01-29 20:34:25 +01:00
suchmememanyskill
292f879780 Make move panel responsive 2024-01-29 20:32:38 +01:00
suchmememanyskill
c65cc08eb3 Don't break macros 2024-01-28 19:23:35 +01:00
suchmememanyskill
8f29978082 Make temp panel responsive 2024-01-28 17:54:47 +01:00
suchmememanyskill
6750c8f572 Make progress panel responsive 2024-01-28 12:54:18 +01:00
suchmememanyskill
b3c60e4442 Change styling of print panel 2024-01-28 12:14:12 +01:00
suchmememanyskill
4ff96e0278 Make file select responsive 2024-01-28 12:06:35 +01:00
suchmememanyskill
2d6fdb8e84 Set timeout for getting files 2024-01-28 12:06:20 +01:00
suchmememanyskill
66bb1137aa Make generic functions for creating flex parents 2024-01-28 11:40:25 +01:00
suchmememanyskill
db0c335049 Don't show each macro twice 2024-01-28 00:55:33 +01:00
suchmememanyskill
8198729ad3 Rename defines 2024-01-28 00:49:25 +01:00
suchmememanyskill
939a9f6547 Make sidebar ajustable 2024-01-28 00:48:06 +01:00
suchmememanyskill
1c50efa500 Make fonts ajustable 2024-01-28 00:24:33 +01:00
suchmememanyskill
ec75a3e289 Start of porting process 2024-01-28 00:18:52 +01:00
suchmememanyskill
2e252c1d18 Upgrade lvgl 2024-01-26 17:26:41 +01:00
suchmememanyskill
dd20c11d8b Slightly optimise file reader 2024-01-23 20:07:06 +01:00
83 changed files with 5420 additions and 1221 deletions

View File

@@ -4,7 +4,16 @@ permissions:
pages: write
id-token: write
on: [push, pull_request]
on:
push:
branches:
- '*'
tags-ignore:
- '*'
pull_request:
workflow_dispatch:
release:
types: [created]
jobs:
build:
@@ -12,12 +21,15 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/cache@v3
with:
path: |
~/.cache/pip
~/.platformio/.cache
key: ${{ runner.os }}-pio
key: ${{ runner.os }}-pio-cyd-klipper
- uses: actions/setup-python@v4
with:
@@ -28,27 +40,13 @@ jobs:
- name: Build PlatformIO Project
run: |
cd CYD-Klipper
pio run
- name: Make output dir
run: |
mkdir -p output
- name: Build Binary
run: |
cp ./CYD-Klipper/.pio/build/esp32dev/bootloader.bin output
cp ./CYD-Klipper/.pio/build/esp32dev/partitions.bin output
cp ./CYD-Klipper/.pio/build/esp32dev/firmware.bin output
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin output
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
python3 ci.py
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./output
path: ./out
- name: Upload GitHub Page Artifact
uses: actions/upload-pages-artifact@v2
@@ -59,7 +57,7 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
if: github.event_name == 'release' && github.event.action == 'created'
steps:
- name: Print GitHub event name
run: |

0
.gitmodules vendored Normal file
View File

37
Build.md Normal file
View File

@@ -0,0 +1,37 @@
# Building
## Running a developer build
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:
#### 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
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`
- Don't forget to hold down the boot button on the display
## Building via PlatformIO
0. Install [Visual Studio Code](https://code.visualstudio.com/) and install the PlatformIO IDE plugin.
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
3. Click on the Alien/Bug tab (PlatformIO) on the left
4. Expand the folder/tab for your specific screen
- Entries with the suffix '-SD' are using the smartdisplay driver. Entries without this suffix are using a custom driver
- Usually, a custom driver is preferred over the smartdisplay driver
5. Connect the display to your computer
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

View File

@@ -9,6 +9,11 @@
"vector": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"algorithm": "cpp"
}
"algorithm": "cpp",
"cstddef": "cpp",
"functional": "cpp",
"*.tcc": "cpp",
"cmath": "cpp"
},
"cmake.configureOnOpen": false
}

View File

@@ -0,0 +1,3 @@
# Boards
Contains specialised CYD definitions from [platformio-espressif32-sunton](https://github.com/rzeldent/platformio-espressif32-sunton)

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 GPIO_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=12000000'",
"'-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_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 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=I2C_NUM_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=true'",
"'-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,122 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S024C'",
"'-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 GPIO_BCKL=27'",
"'-D LCD_ILI9341_SPI'",
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ILI9341_SPI_BUS_FLAGS=0'",
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=NULL'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_CST816S_I2C'",
"'-D CST816S_I2C_HOST=I2C_NUM_0'",
"'-D CST816S_I2C_CONFIG_SDA_IO_NUM=33'",
"'-D CST816S_I2C_CONFIG_SCL_IO_NUM=32'",
"'-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=25'",
"'-D CST816S_TOUCH_CONFIG_INT_GPIO_NUM=21'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D CST816S_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=true'",
"'-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_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-2432S024C-SD",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005005865107357.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,63 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DUSER_SETUP_LOADED=1",
"-DILI9341_2_DRIVER=1",
"-DTFT_BACKLIGHT_ON=HIGH",
"-DTFT_BL=21",
"-DTFT_MISO=12",
"-DTFT_MOSI=13",
"-DTFT_SCLK=14",
"-DTFT_CS=15",
"-DTFT_DC=2",
"-DTFT_RST=-1",
"-DLOAD_GCLD=1",
"-DSPI_FREQUENCY=55000000",
"-DSPI_READ_FREQUENCY=20000000",
"-DSPI_TOUCH_FREQUENCY=2500000",
"-DTOUCH_CS=-1",
"-DCYD_SCREEN_HEIGHT_PX=240",
"-DCYD_SCREEN_WIDTH_PX=320",
"-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_2432S028R=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-2432S028R",
"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

@@ -0,0 +1,125 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S028R'",
"'-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 GPIO_BCKL=21'",
"'-D LCD_ILI9341_SPI'",
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ILI9341_SPI_BUS_FLAGS=0'",
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=NULL'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-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"
],
"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-2432S028Rv1-SD",
"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

@@ -0,0 +1,125 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S028Rv2'",
"'-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 GPIO_BCKL=21'",
"'-D LCD_ILI9341_SPI'",
"'-D ILI9341_SPI_HOST=SPI2_HOST'",
"'-D ILI9341_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ILI9341_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ILI9341_SPI_BUS_MISO_IO_NUM=12'",
"'-D ILI9341_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ILI9341_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ILI9341_SPI_BUS_FLAGS=0'",
"'-D ILI9341_SPI_BUS_INTR_FLAGS=0'",
"'-D ILI9341_SPI_CONFIG_CS_GPIO_NUM=15'",
"'-D ILI9341_SPI_CONFIG_DC_GPIO_NUM=2'",
"'-D ILI9341_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
"'-D ILI9341_SPI_CONFIG_PCLK_HZ=24000000'",
"'-D ILI9341_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
"'-D ILI9341_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ILI9341_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ILI9341_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ILI9341_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=\"(ili9341_vendor_config_t[]){{.init_cmds=(ili9341_lcd_init_cmd_t[]){{.cmd=0xCF,.data=(uint8_t[]){0x00,0xC1,0x30},.data_bytes=3},{.cmd=0xED,.data=(uint8_t[]){0x64,0x03,0x12,0x81},.data_bytes=4},{.cmd=0xE8,.data=(uint8_t[]){0x85,0x00,0x78},.data_bytes=3},{.cmd=0xCB,.data=(uint8_t[]){0x39,0x2C,0x00,0x34,0x02},.data_bytes=5},{.cmd=0xF7,.data=(uint8_t[]){0x20},.data_bytes=1},{.cmd=0xEA,.data=(uint8_t[]){0x00,0x00},.data_bytes=2},{.cmd=0xC0,.data=(uint8_t[]){0x10},.data_bytes=1},{.cmd=0xC1,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0xC5,.data=(uint8_t[]){0x30,0x30},.data_bytes=2,},{.cmd=0xC7,.data=(uint8_t[]){0xB7},.data_bytes=1},{.cmd=0x3A,.data=(uint8_t[]){0x55},.data_bytes=1},{.cmd=0x36,.data=(uint8_t[]){0x08},.data_bytes=1},{.cmd=0xB1,.data=(uint8_t[]){0x00,0x1A},.data_bytes=2},{.cmd=0xB6,.data=(uint8_t[]){0x08,0x82,0x27},.data_bytes=3},{.cmd=0xF2,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0x26,.data=(uint8_t[]){0x01},.data_bytes=1},{.cmd=0xE0,.data=(uint8_t[]){0x0F,0x2A,0x28,0x08,0x0E,0x08,0x54,0xA9,0x43,0x0A,0x0F,0x00,0x00,0x00,0x00},.data_bytes=15},{.cmd=0xE1,.data=(uint8_t[]){0x00,0x15,0x17,0x07,0x11,0x06,0x2B,0x56,0x3C,0x05,0x10,0x0F,0x3F,0x3F,0x0F},.data_bytes=15},{.cmd=0x2B,.data=(uint8_t[]){0x00,0x00,0x01,0x3F},.data_bytes=4},{.cmd=0x2A,.data=(uint8_t[]){0x00,0x00,0x00,0xEF},.data_bytes=4},{.cmd=0x21},{.cmd=0x11,.delay_ms=120},{.cmd=0x29,.delay_ms=1}},.init_cmds_size=23}}\"'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-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"
],
"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-2432S028Rv2-SD",
"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

@@ -0,0 +1,125 @@
{
"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 GPIO_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=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-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=24000000'",
"'-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"
],
"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-SD",
"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

@@ -0,0 +1,125 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_2432S032C'",
"'-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 GPIO_BCKL=27'",
"'-D LCD_IPS'",
"'-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=12'",
"'-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=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-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=24000000'",
"'-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_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=25'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=21'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=true'",
"'-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_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_HEIGHT_PX=240",
"-DCYD_SCREEN_WIDTH_PX=320",
"-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-2432S032C-SD",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005006224494145.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,122 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"'-D ARDUINO_ESP32_DEV'",
"'-D ESP32_3248S035C'",
"'-D LCD_WIDTH=320'",
"'-D LCD_HEIGHT=480'",
"'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
"'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
"'-D GPIO_BCKL=27'",
"'-D LCD_ST7796_SPI'",
"'-D ST7796_SPI_HOST=SPI2_HOST'",
"'-D ST7796_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
"'-D ST7796_SPI_BUS_MOSI_IO_NUM=13'",
"'-D ST7796_SPI_BUS_MISO_IO_NUM=12'",
"'-D ST7796_SPI_BUS_SCLK_IO_NUM=14'",
"'-D ST7796_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
"'-D ST7796_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
"'-D ST7796_SPI_BUS_MAX_TRANSFER_SZ=(LVGL_BUFFER_PIXELS*sizeof(lv_color16_t))'",
"'-D ST7796_SPI_BUS_FLAGS=0'",
"'-D ST7796_SPI_BUS_INTR_FLAGS=0'",
"'-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_TRANS_QUEUE_DEPTH=10'",
"'-D ST7796_SPI_CONFIG_LCD_CMD_BITS=8'",
"'-D ST7796_SPI_CONFIG_LCD_PARAM_BITS=8'",
"'-D ST7796_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
"'-D ST7796_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D ST7796_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
"'-D ST7796_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
"'-D ST7796_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
"'-D ST7796_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'",
"'-D ST7796_DEV_CONFIG_BITS_PER_PIXEL=16'",
"'-D ST7796_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
"'-D ST7796_DEV_CONFIG_VENDOR_CONFIG=NULL'",
"'-D LCD_SWAP_XY=false'",
"'-D LCD_MIRROR_X=true'",
"'-D LCD_MIRROR_Y=false'",
"'-D BOARD_HAS_TOUCH'",
"'-D TOUCH_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=33'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=32'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=25'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=21'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
"'-D TOUCH_SWAP_XY=true'",
"'-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_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=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-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"
],
"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-3248S035C",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004632953455.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,66 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DUSER_SETUP_LOADED=1",
"-DST7796_DRIVER=1",
"-DTFT_BL=27",
"-DTFT_BACKLIGHT_ON=HIGH",
"-DTFT_MISO=12",
"-DTFT_MOSI=13",
"-DTFT_SCLK=14",
"-DTFT_CS=15",
"-DTFT_DC=2",
"-DTFT_RST=-1",
"-DLOAD_GCLD=1",
"-DSPI_FREQUENCY=80000000",
"-DSPI_READ_FREQUENCY=20000000",
"-DSPI_TOUCH_FREQUENCY=2500000",
"-DTOUCH_CS=-1",
"-DCYD_SCREEN_HEIGHT_PX=480",
"-DCYD_SCREEN_WIDTH_PX=320",
"-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-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_3248S035C=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=1",
"-DCYD_SCREEN_VERTICAL=1",
"-DCYD_SCREEN_NO_TEMP_SCROLL=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-3248S035C-V",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004632953455.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,64 @@
{
"build": {
"arduino": {
"ldscript": "esp32_out.ld"
},
"core": "esp32",
"extra_flags": [
"-DUSER_SETUP_LOADED=1",
"-DST7796_DRIVER=1",
"-DTFT_BL=27",
"-DTFT_BACKLIGHT_ON=HIGH",
"-DTFT_MISO=12",
"-DTFT_MOSI=13",
"-DTFT_SCLK=14",
"-DTFT_CS=15",
"-DTFT_DC=2",
"-DTFT_RST=-1",
"-DLOAD_GCLD=1",
"-DSPI_FREQUENCY=80000000",
"-DSPI_READ_FREQUENCY=20000000",
"-DSPI_TOUCH_FREQUENCY=2500000",
"-DTOUCH_CS=-1",
"-DCYD_SCREEN_HEIGHT_PX=320",
"-DCYD_SCREEN_WIDTH_PX=480",
"-DCYD_SCREEN_GAP_PX=10",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=45",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=45",
"-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_3248S035C=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-3248S035C",
"upload": {
"flash_size": "4MB",
"maximum_ram_size": 327680,
"maximum_size": 4194304,
"require_upload_port": true,
"speed": 460800
},
"url": "https://www.aliexpress.com/item/1005004632953455.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,143 @@
{
"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_4827S043C'",
"'-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_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_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'",
"'-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=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-4827S043C-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

@@ -0,0 +1,143 @@
{
"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_8048S043C'",
"'-D LCD_WIDTH=800'",
"'-D LCD_HEIGHT=480'",
"'-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=(12.5*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=8'",
"'-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=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_VSYNC_FRONT_PORCH=8'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_HSYNC_IDLE_LOW=false'",
"'-D ST7262_PANEL_CONFIG_TIMINGS_FLAGS_VSYNC_IDLE_LOW=false'",
"'-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_GT911_I2C'",
"'-D GT911_I2C_HOST=I2C_NUM_0'",
"'-D GT911_I2C_CONFIG_SDA_IO_NUM=19'",
"'-D GT911_I2C_CONFIG_SCL_IO_NUM=20'",
"'-D GT911_I2C_CONFIG_SDA_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_SCL_PULLUP_EN=GPIO_PULLUP_DISABLE'",
"'-D GT911_I2C_CONFIG_MASTER_CLK_SPEED=400000'",
"'-D GT911_I2C_CONFIG_CLK_FLAGS=I2C_SCLK_SRC_FLAG_FOR_NOMAL'",
"'-D GT911_IO_I2C_CONFIG_DEV_ADDR=ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS'",
"'-D GT911_IO_I2C_CONFIG_CONTROL_PHASE_BYTES=1'",
"'-D GT911_IO_I2C_CONFIG_DC_BIT_OFFSET=0'",
"'-D GT911_IO_I2C_CONFIG_LCD_CMD_BITS=16'",
"'-D GT911_IO_I2C_CONFIG_LCD_PARAM_BITS=0'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
"'-D GT911_IO_I2C_CONFIG_FLAGS_DISABLE_CONTROL_PHASE=true'",
"'-D GT911_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
"'-D GT911_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
"'-D GT911_TOUCH_CONFIG_RST_GPIO_NUM=38'",
"'-D GT911_TOUCH_CONFIG_INT_GPIO_NUM=18'",
"'-D GT911_TOUCH_CONFIG_LEVELS_RESET=0'",
"'-D GT911_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=480",
"-DCYD_SCREEN_WIDTH_PX=800",
"-DROTATION_INVERTED=LV_DISP_ROT_180",
"-DROTATION_NORMAL=LV_DISP_ROT_NONE",
"-DCYD_SCREEN_GAP_PX=15",
"-DCYD_SCREEN_MIN_BUTTON_HEIGHT_PX=60",
"-DCYD_SCREEN_MIN_BUTTON_WIDTH_PX=60",
"-DCYD_SCREEN_FONT=lv_font_montserrat_22",
"-DCYD_SCREEN_FONT_SMALL=lv_font_montserrat_16",
"-DCYD_SCREEN_SIDEBAR_SIZE_PX=70",
"-DCYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY=1",
"-DCYD_SCREEN_DISABLE_TOUCH_CALIBRATION=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-8048S043C-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/1005006110360174.html",
"vendor": "Sunton"
}

View File

@@ -0,0 +1,31 @@
import subprocess
def extract_commit() -> str:
git_describe_output = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, text=True, check=True).stdout.strip()
split_output = git_describe_output.split("-")
if (len(split_output) >= 3):
return f"{split_output[0]}\\ ({split_output[2][1:]})"
else:
return split_output[0]
try:
version = extract_commit()
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=flags
)

View File

@@ -8,36 +8,75 @@
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32dev]
[env]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
SPI
lvgl/lvgl@^8.3.9
https://github.com/Bodmer/TFT_eSPI.git
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
https://github.com/suchmememanyskill/esp32-smartdisplay#9c1d737
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
monitor_filters = esp32_exception_decoder
build_flags =
-DLV_CONF_PATH="../../../../src/conf/lv_conf.h"
-DUSER_SETUP_LOADED=1
-DILI9341_2_DRIVER=1
-DTFT_WIDTH=240
-DTFT_HEIGHT=320
-DTFT_BL=21
-DTFT_BACKLIGHT_ON=HIGH
-DTFT_MISO=12
-DTFT_MOSI=13
-DTFT_SCLK=14
-DTFT_CS=15
-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
extra_scripts =
pre:extract_commit.py
[env:esp32-2432S028R]
board = esp32-2432S028R
lib_deps =
SPI
https://github.com/suchmememanyskill/lvgl
https://github.com/Bodmer/TFT_eSPI.git
https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-3248S035C]
board = esp32-3248S035C
lib_deps =
SPI
https://github.com/suchmememanyskill/lvgl
https://github.com/Bodmer/TFT_eSPI.git
https://github.com/OperatorB/gt911-arduino-fixed-reset.git
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-3248S035C-V]
board = esp32-3248S035C-vertical
lib_deps =
SPI
https://github.com/suchmememanyskill/lvgl
https://github.com/Bodmer/TFT_eSPI.git
https://github.com/OperatorB/gt911-arduino-fixed-reset.git
bblanchon/ArduinoJson@^7.0.0
plageoj/UrlEncode@^1.0.1
erriez/ErriezCRC32 @ ^1.0.1
[env:esp32-2432S024C-SD]
board = esp32-2432S024C-smartdisplay
[env:esp32-2432S028Rv1-SD]
board = esp32-2432S028RV1-smartdisplay
[env:esp32-2432S028Rv2-SD]
board = esp32-2432S028RV2-smartdisplay
[env:esp32-2432S028Rv3-SD]
board = esp32-2432S028RV3-smartdisplay
[env:esp32-2432S032C-SD]
board = esp32-2432S032C-smartdisplay
[env:esp32-3248S035C-SD]
board = esp32-3248S035C-smartdisplay
[env:esp32-4827S043C-SD]
board = esp32-4827S043C-smartdisplay
[env:esp32-8048S043C-SD]
board = esp32-8048S043C-smartdisplay

View File

@@ -14,14 +14,16 @@ COLOR_DEF color_defs[] = {
{LV_PALETTE_PURPLE, 0, LV_PALETTE_GREY},
};
void WriteGlobalConfig() {
void write_global_config()
{
Preferences preferences;
preferences.begin("global_config", false);
preferences.putBytes("global_config", &global_config, sizeof(global_config));
preferences.end();
}
void VerifyVersion(){
void verify_version()
{
Preferences preferences;
if (!preferences.begin("global_config", false))
return;
@@ -37,17 +39,76 @@ void VerifyVersion(){
preferences.end();
}
void LoadGlobalConfig() {
PRINTER_CONFIG* get_current_printer_config()
{
return &global_config.printer_config[global_config.printer_index];
}
int get_printer_config_count()
{
int count = 0;
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++) {
if (global_config.printer_config[i].ip_configured)
count++;
}
return count;
}
int get_printer_config_free_index()
{
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++) {
if (!global_config.printer_config[i].ip_configured)
return i;
}
return -1;
}
void set_printer_config_index(int index)
{
if (index < 0 || index >= PRINTER_CONFIG_COUNT)
return;
PRINTER_CONFIG* old_config = &global_config.printer_config[global_config.printer_index];
PRINTER_CONFIG* new_config = &global_config.printer_config[index];
global_config.printer_index = index;
if (!new_config->ip_configured){
new_config->raw = old_config->raw;
new_config->ip_configured = false;
new_config->auth_configured = false;
new_config->printer_name[0] = 0;
new_config->klipper_host[0] = 0;
new_config->klipper_auth[0] = 0;
new_config->klipper_port = 0;
new_config->color_scheme = old_config->color_scheme;
for (int i = 0; i < 3; i++){
new_config->hotend_presets[i] = old_config->hotend_presets[i];
new_config->bed_presets[i] = old_config->bed_presets[i];
}
write_global_config();
ESP.restart();
}
write_global_config();
}
void load_global_config()
{
global_config.version = CONFIG_VERSION;
global_config.brightness = 255;
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();
global_config.screen_timeout = 5;
global_config.printer_config[0].hotend_presets[0] = 0;
global_config.printer_config[0].hotend_presets[1] = 200;
global_config.printer_config[0].hotend_presets[2] = 240;
global_config.printer_config[0].bed_presets[0] = 0;
global_config.printer_config[0].bed_presets[1] = 60;
global_config.printer_config[0].bed_presets[2] = 70;
verify_version();
Preferences preferences;
preferences.begin("global_config", true);
preferences.getBytes("global_config", &global_config, sizeof(global_config));

View File

@@ -3,42 +3,71 @@
#include "lvgl.h"
#define CONFIG_VERSION 3
#define CONFIG_VERSION 5
#define PRINTER_CONFIG_COUNT 8
enum {
REMAINING_TIME_CALC_PERCENTAGE = 0,
REMAINING_TIME_CALC_INTERPOLATED = 1,
REMAINING_TIME_CALC_SLICER = 2,
};
typedef struct _PRINTER_CONFIG {
union {
unsigned int raw;
struct {
// Internal
bool ip_configured : 1;
bool auth_configured : 1;
// External
bool light_mode : 1;
bool invert_colors : 1;
unsigned char remaining_time_calc_mode : 2;
};
};
char printer_name[25];
char klipper_host[65];
char klipper_auth[33];
unsigned short klipper_port;
unsigned char color_scheme;
unsigned short hotend_presets[3];
unsigned short bed_presets[3];
} PRINTER_CONFIG;
typedef struct _GLOBAL_CONFIG {
unsigned char version;
union {
unsigned char raw;
unsigned int raw;
struct {
// Internal
bool screenCalibrated : 1;
bool wifiConfigured : 1;
bool ipConfigured : 1;
bool screen_calibrated : 1;
bool wifi_configured : 1;
// External
bool lightMode : 1;
bool invertColors : 1;
bool rotateScreen : 1;
bool onDuringPrint : 1;
bool rotate_screen : 1;
bool auto_ota_update : 1;
bool multi_printer_mode : 1;
bool on_during_print : 1;
};
};
float screenCalXOffset;
float screenCalXMult;
float screenCalYOffset;
float screenCalYMult;
char wifiSSID[32];
char wifiPassword[64];
PRINTER_CONFIG printer_config[PRINTER_CONFIG_COUNT];
char klipperHost[64];
unsigned short klipperPort;
float screen_cal_x_offset;
float screen_cal_x_mult;
float screen_cal_y_offset;
float screen_cal_y_mult;
char wifi_SSID[32];
char wifi_password[64];
unsigned char color_scheme;
unsigned char brightness;
unsigned char screenTimeout;
unsigned short hotend_presets[3];
unsigned short bed_presets[3];
unsigned char screen_timeout;
unsigned char printer_index;
} GLOBAL_CONFIG;
typedef struct _COLOR_DEF {
@@ -50,8 +79,13 @@ typedef struct _COLOR_DEF {
extern GLOBAL_CONFIG global_config;
extern COLOR_DEF color_defs[];
void WriteGlobalConfig();
void VerifyVersion();
void LoadGlobalConfig();
void write_global_config();
void verify_version();
void load_global_config();
PRINTER_CONFIG* get_current_printer_config();
int get_printer_config_count();
void set_printer_config_index(int index);
int get_printer_config_free_index();
#endif // !_GLOBAL_CONFIG_INIT

View File

@@ -49,7 +49,7 @@
#define LV_MEM_CUSTOM 0
#if LV_MEM_CUSTOM == 0
/*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
#define LV_MEM_SIZE (32U * 1024U) /*[bytes]*/
#define LV_MEM_SIZE (40U * 1024U) /*[bytes]*/
/*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
#define LV_MEM_ADR 0 /*0: unused*/
@@ -194,7 +194,7 @@
*-----------*/
/*Enable the log module*/
#define LV_USE_LOG 1
#define LV_USE_LOG 0
#if LV_USE_LOG
/*How important log should be added:
@@ -204,7 +204,7 @@
*LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
*LV_LOG_LEVEL_USER Only logs added by the user
*LV_LOG_LEVEL_NONE Do not log anything*/
#define LV_LOG_LEVEL LV_LOG_LEVEL_USER
#define LV_LOG_LEVEL LV_LOG_LEVEL_NONE
/*1: Print the log with 'printf';
*0: User need to register a callback with `lv_log_register_print_cb()`*/
@@ -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
@@ -327,12 +331,12 @@
*https://fonts.google.com/specimen/Montserrat*/
#define LV_FONT_MONTSERRAT_8 0
#define LV_FONT_MONTSERRAT_10 1
#define LV_FONT_MONTSERRAT_12 0
#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 0
#define LV_FONT_MONTSERRAT_16 1
#define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_20 0
#define LV_FONT_MONTSERRAT_22 0
#define LV_FONT_MONTSERRAT_22 1
#define LV_FONT_MONTSERRAT_24 0
#define LV_FONT_MONTSERRAT_26 0
#define LV_FONT_MONTSERRAT_28 1
@@ -363,7 +367,7 @@
#define LV_FONT_CUSTOM_DECLARE
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_montserrat_14
#define LV_FONT_DEFAULT &CYD_SCREEN_FONT
/*Enable handling large font and/or fonts with a lot of characters.
*The limit depends on the font size, font face and bpp.
@@ -497,7 +501,7 @@
#define LV_USE_MSG 1
#define LV_USE_CHART 0
#define LV_USE_CHART 1
#define LV_USE_COLORWHEEL 0
@@ -603,7 +607,7 @@
#endif
/*PNG decoder library*/
#define LV_USE_PNG 0
#define LV_USE_PNG 1
/*BMP decoder library*/
#define LV_USE_BMP 0
@@ -674,16 +678,16 @@
====================*/
/*Show some widget. It might be required to increase `LV_MEM_SIZE` */
#define LV_USE_DEMO_WIDGETS 1
#define LV_USE_DEMO_WIDGETS 0
#if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 1
#endif
/*Demonstrate the usage of encoder and keyboard*/
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 1
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
/*Benchmark your system*/
#define LV_USE_DEMO_BENCHMARK 1
#define LV_USE_DEMO_BENCHMARK 0
/*Stress test for LVGL*/
#define LV_USE_DEMO_STRESS 0

View File

@@ -2,10 +2,13 @@
#include "data_setup.h"
#include "lvgl.h"
#include "../conf/global_config.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <esp_task_wdt.h>
#include "macros_query.h"
#include <UrlEncode.h>
#include "http_client.h"
#include "../ui/ui_utils.h"
#include "macros_query.h"
const char *printer_state_messages[] = {
"Error",
@@ -13,6 +16,7 @@ const char *printer_state_messages[] = {
"Printing"};
Printer printer = {0};
PrinterMinimal *printer_minimal;
int klipper_request_consecutive_fail_count = 0;
char filename_buff[512] = {0};
SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore;
@@ -43,16 +47,9 @@ void unfreeze_render_thread(){
void send_gcode(bool wait, const char *gcode)
{
char buff[256] = {};
sprintf(buff, "http://%s:%d/printer/gcode/script?script=%s", global_config.klipperHost, global_config.klipperPort, gcode);
HTTPClient client;
client.begin(buff);
if (!wait)
{
client.setTimeout(1000);
}
Serial.printf("Sending gcode: %s\n", gcode);
SETUP_HTTP_CLIENT_FULL("/printer/gcode/script?script=" + urlEncode(gcode), false, wait ? 5000 : 750);
try
{
client.GET();
@@ -63,14 +60,62 @@ void send_gcode(bool wait, const char *gcode)
}
}
int get_slicer_time_estimate_s()
{
if (printer.state == PRINTER_STATE_IDLE)
return 0;
delay(10);
SETUP_HTTP_CLIENT("/server/files/metadata?filename=" + urlEncode(printer.print_filename));
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();
char buff[256] = {};
sprintf(buff, "http://%s:%d/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks", global_config.klipperHost, global_config.klipperPort);
HTTPClient client;
client.useHTTP10(true);
client.begin(buff);
PRINTER_CONFIG *config = get_current_printer_config();
SETUP_HTTP_CLIENT("/printer/objects/query?extruder&heater_bed&toolhead&gcode_move&virtual_sdcard&print_stats&webhooks&fan&display_status")
int httpCode = client.GET();
delay(10);
if (httpCode == 200)
@@ -94,7 +139,7 @@ void fetch_printer_data()
{
printer_state = PRINTER_STATE_IDLE;
}
else if (strcmp(state, "shutdown") == 0 && printer.state != PRINTER_STATE_ERROR)
else if ((strcmp(state, "shutdown") == 0 || strcmp(state, "error") == 0) && printer.state != PRINTER_STATE_ERROR)
{
printer_state = PRINTER_STATE_ERROR;
}
@@ -119,6 +164,8 @@ void fetch_printer_data()
printer.extruder_temp = status["extruder"]["temperature"];
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;
}
@@ -139,8 +186,20 @@ void fetch_printer_data()
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];
printer.gcode_offset[0] = status["gcode_move"]["homing_origin"][0];
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"];
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"];
printer.feedrate_mm_per_s /= 60; // convert mm/m to mm/s
}
if (status.containsKey("fan"))
{
printer.fan_speed = status["fan"]["speed"];
}
if (status.containsKey("virtual_sdcard"))
@@ -155,10 +214,16 @@ void fetch_printer_data()
printer.print_filename = filename_buff;
printer.elapsed_time_s = status["print_stats"]["print_duration"];
printer.filament_used_mm = status["print_stats"]["filament_used"];
printer.total_layers = status["print_stats"]["info"]["total_layer"];
printer.current_layer = status["print_stats"]["info"]["current_layer"];
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;
}
@@ -172,12 +237,44 @@ void fetch_printer_data()
}
}
// TODO: make a call to /server/files/metadata to get more accurate time estimates
// https://moonraker.readthedocs.io/en/latest/web_api/#server-administration
if (status.containsKey("display_status"))
{
const char* message = status["display_status"]["message"];
lv_create_popup_message(message, 10000);
}
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 || config->remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE)
{
printer.remaining_time_s = remaining_time_s_percentage;
}
else if (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 (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);
@@ -189,6 +286,13 @@ void fetch_printer_data()
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();
}
else
@@ -199,6 +303,94 @@ void fetch_printer_data()
}
}
void fetch_printer_data_minimal()
{
PrinterMinimal data[PRINTER_CONFIG_COUNT] = {0};
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG *config = &global_config.printer_config[i];
if (!config->ip_configured)
{
data[i].online = false;
continue;
}
delay(10);
HTTPClient client;
configure_http_client(client, get_full_url("/printer/objects/query?webhooks&print_stats&virtual_sdcard", config), true, 1000);
freeze_request_thread();
int httpCode = client.GET();
delay(10);
if (httpCode == 200)
{
data[i].online = true;
data[i].power_devices = 0;
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto status = doc["result"]["status"];
unfreeze_request_thread();
if (status.containsKey("webhooks"))
{
const char *state = status["webhooks"]["state"];
if (strcmp(state, "ready") == 0 && data[i].state == PRINTER_STATE_ERROR)
{
data[i].state = PRINTER_STATE_IDLE;
}
else if (strcmp(state, "shutdown") == 0 && data[i].state != PRINTER_STATE_ERROR)
{
data[i].state = PRINTER_STATE_ERROR;
}
}
if (data[i].state != PRINTER_STATE_ERROR)
{
if (status.containsKey("virtual_sdcard"))
{
data[i].print_progress = status["virtual_sdcard"]["progress"];
}
if (status.containsKey("print_stats"))
{
const char *state = status["print_stats"]["state"];
if (state == nullptr)
{
data[i].state = PRINTER_STATE_ERROR;
}
else if (strcmp(state, "printing") == 0)
{
data[i].state = PRINTER_STATE_PRINTING;
}
else if (strcmp(state, "paused") == 0)
{
data[i].state = PRINTER_STATE_PAUSED;
}
else if (strcmp(state, "complete") == 0 || strcmp(state, "cancelled") == 0 || strcmp(state, "standby") == 0)
{
data[i].state = PRINTER_STATE_IDLE;
}
}
}
}
else
{
data[i].online = false;
data[i].power_devices = power_devices_count(config);
unfreeze_request_thread();
}
}
freeze_render_thread();
memcpy(printer_minimal, data, sizeof(PrinterMinimal) * PRINTER_CONFIG_COUNT);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
unfreeze_render_thread();
}
void data_loop()
{
// Causes other threads that are trying to lock the thread to actually lock it
@@ -209,9 +401,16 @@ void data_loop()
void data_loop_background(void * param){
esp_task_wdt_init(10, true);
int loop_iter = 20;
while (true){
delay(data_update_interval);
fetch_printer_data();
if (global_config.multi_printer_mode) {
if (loop_iter++ > 20){
fetch_printer_data_minimal();
loop_iter = 0;
}
}
}
}
@@ -219,10 +418,11 @@ TaskHandle_t background_loop;
void data_setup()
{
printer_minimal = (PrinterMinimal *)calloc(sizeof(PrinterMinimal), PRINTER_CONFIG_COUNT);
semaphore_init();
printer.print_filename = filename_buff;
fetch_printer_data();
macros_query_setup();
freeze_render_thread();
xTaskCreatePinnedToCore(data_loop_background, "data_loop_background", 5000, NULL, 0, &background_loop, 0);
xTaskCreatePinnedToCore(data_loop_background, "data_loop_background", 5000, NULL, 2, &background_loop, 0);
}

View File

@@ -23,20 +23,40 @@ 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;
float extrude_mult;
int total_layers;
int current_layer;
float pressure_advance;
float smooth_time;
int feedrate_mm_per_s;
int slicer_estimated_print_time_s;
} Printer;
typedef struct _PrinterMinimal {
bool online;
unsigned char state;
float print_progress; // 0 -> 1
unsigned int power_devices;
} PrinterMinimal;
extern Printer printer;
extern PrinterMinimal *printer_minimal;
extern int klipper_request_consecutive_fail_count;
#define DATA_PRINTER_STATE 1
#define DATA_PRINTER_DATA 2
#define DATA_PRINTER_TEMP_PRESET 3
#define DATA_PRINTER_MINIMAL 4
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

@@ -0,0 +1,111 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R
#include "../screen_driver.h"
#ifdef CYD_SCREEN_VERTICAL
#error "Vertical screen not supported with the ESP32_2432S028R driver"
#endif
#include <SPI.h>
#include <TFT_eSPI.h>
#include "../../conf/global_config.h"
#include "lvgl.h"
#include <XPT2046_Touchscreen.h>
#include <TFT_eSPI.h>
#include "../lv_setup.h"
#define XPT2046_IRQ 36
#define XPT2046_MOSI 32
#define XPT2046_MISO 39
#define XPT2046_CLK 25
#define XPT2046_CS 33
#define CPU_FREQ_HIGH 240
#define CPU_FREQ_LOW 80
SPIClass touchscreen_spi = SPIClass(HSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
TFT_eSPI tft = TFT_eSPI();
void screen_setBrightness(byte brightness)
{
// calculate duty, 4095 from 2 ^ 12 - 1
uint32_t duty = (4095 / 255) * brightness;
// write duty to LEDC
ledcWrite(0, duty);
}
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp);
}
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
if (touchscreen.tirqTouched() && touchscreen.touched())
{
TS_Point p = touchscreen.getPoint();
data->state = LV_INDEV_STATE_PR;
data->point.x = p.x;
data->point.y = p.y;
}
else
{
data->state = LV_INDEV_STATE_REL;
}
}
void set_invert_display(){
tft.invertDisplay(get_current_printer_config()->invert_colors);
}
void screen_setup()
{
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);
touchscreen.setRotation(global_config.rotate_screen ? 3 : 1);
lv_init();
tft.init();
ledcSetup(0, 5000, 12);
ledcAttachPin(21, 0);
tft.setRotation(global_config.rotate_screen ? 3 : 1);
tft.fillScreen(TFT_BLACK);
set_invert_display();
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);
lv_disp_draw_buf_init(&draw_buf, buf, NULL, CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10);
/*Initialize the display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = CYD_SCREEN_WIDTH_PX;
disp_drv.ver_res = CYD_SCREEN_HEIGHT_PX;
disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = screen_lv_touchRead;
lv_indev_drv_register(&indev_drv);
}
#endif // CYD_SCREEN_DRIVER_ESP32_2432S028R

View File

@@ -0,0 +1,154 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_3248S035C
#include "../screen_driver.h"
#include "lvgl.h"
#include <TAMC_GT911.h>
#include <TFT_eSPI.h>
#include "../../conf/global_config.h"
#include "../lv_setup.h"
#define TOUCH_SDA 33
#define TOUCH_SCL 32
#define TOUCH_INT 21
#define TOUCH_RST 25
#define TOUCH_WIDTH 320
#define TOUCH_HEIGHT 480
#define LED_PIN_R 4
#define LED_PIN_G 16
#define LED_PIN_B 17
TAMC_GT911 tp = TAMC_GT911(TOUCH_SDA, TOUCH_SCL, TOUCH_INT, TOUCH_RST, TOUCH_WIDTH, TOUCH_HEIGHT);
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[CYD_SCREEN_HEIGHT_PX * CYD_SCREEN_WIDTH_PX / 10];
TFT_eSPI tft = TFT_eSPI();
void screen_setBrightness(byte brightness)
{
// calculate duty, 4095 from 2 ^ 12 - 1
uint32_t duty = (4095 / 255) * brightness;
// write duty to LEDC
ledcWrite(0, duty);
}
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp);
}
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
tp.read();
if (!tp.isTouched)
{
data->state = LV_INDEV_STATE_REL;
}
else
{
data->state = LV_INDEV_STATE_PR;
for (int i = 0; i < tp.touches; i++)
{
uint16_t magicX; // fix GT911 driver - orientation and handle rotation
uint16_t magicY;
if (!global_config.rotate_screen)
{
magicY = tp.points[i].x;
magicX = TOUCH_HEIGHT - tp.points[i].y;
}
else
{
#ifdef CYD_SCREEN_VERTICAL
// I don't even want to know why this works...
magicY = TOUCH_HEIGHT - tp.points[i].x;
magicX = tp.points[i].y - 160;
#else
magicY = TOUCH_WIDTH - tp.points[i].x;
magicX = tp.points[i].y;
#endif
}
data->point.x = magicX;
data->point.y = magicY;
}
}
}
void set_invert_display()
{
tft.invertDisplay(get_current_printer_config()->invert_colors);
}
void set_LED_color(uint8_t rgbVal[3])
{
analogWrite(LED_PIN_R, 255 - rgbVal[0]);
analogWrite(LED_PIN_G, 255 - rgbVal[1]);
analogWrite(LED_PIN_B, 255 - rgbVal[2]);
}
void LED_init()
{
pinMode(LED_PIN_R, OUTPUT);
pinMode(LED_PIN_G, OUTPUT);
pinMode(LED_PIN_B, OUTPUT);
uint8_t rgbVal[3] = {0, 0, 0};
set_LED_color(rgbVal);
}
void screen_setup()
{
// Initialize the touchscreen
tp.begin();
// Initialize LVGL
lv_init();
// Initialize the display
tft.init();
ledcSetup(0, 5000, 12);
ledcAttachPin(TFT_BL, 0);
tft.fillScreen(TFT_BLACK);
set_invert_display();
LED_init();
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
#ifdef CYD_SCREEN_VERTICAL
disp_drv.hor_res = TFT_WIDTH;
disp_drv.ver_res = TFT_HEIGHT;
tp.setRotation(2);
tft.setRotation(global_config.rotate_screen ? 2 : 0);
#else
disp_drv.hor_res = TFT_HEIGHT;
disp_drv.ver_res = TFT_WIDTH;
tft.setRotation(global_config.rotate_screen ? 3 : 1);
tp.setRotation(ROTATION_NORMAL);
#endif
disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
// Initialize the (dummy) input device driver
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = screen_lv_touchRead;
lv_indev_drv_register(&indev_drv);
}
#endif // CYD_SCREEN_DRIVER_ESP32_3248S035C

View File

@@ -0,0 +1,67 @@
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
#include "../screen_driver.h"
#include <esp32_smartdisplay.h>
#include "../../conf/global_config.h"
#include "lvgl.h"
#include "../lv_setup.h"
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)
{
smartdisplay_lcd_set_backlight(brightness / 255.0f);
}
void set_invert_display()
{
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 (get_current_printer_config()->invert_colors) {
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);
}
#ifndef ROTATION_INVERTED
#ifdef CYD_SCREEN_VERTICAL
#define ROTATION_INVERTED LV_DISP_ROT_180
#else
#define ROTATION_INVERTED LV_DISP_ROT_270
#endif
#endif
#ifndef ROTATION_NORMAL
#ifdef CYD_SCREEN_VERTICAL
#define ROTATION_NORMAL LV_DISP_ROT_NONE
#else
#define ROTATION_NORMAL LV_DISP_ROT_90
#endif
#endif
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.rotate_screen) ? ROTATION_INVERTED : ROTATION_NORMAL);
}
#endif // CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY

View File

@@ -2,9 +2,9 @@
#include "files_query.h"
#include "../conf/global_config.h"
#include "data_setup.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <HardwareSerial.h>
#include "http_client.h"
// Always has +1 entry with a null'd name
FILESYSTEM_FILE* last_query = NULL;
@@ -27,11 +27,8 @@ FILESYSTEM_FILE* get_files(int limit){
std::list<FILESYSTEM_FILE> files;
auto timer_request = millis();
char buff[256] = {};
sprintf(buff, "http://%s:%d/server/files/list", global_config.klipperHost, global_config.klipperPort);
HTTPClient client;
client.useHTTP10(true);
client.begin(buff);
SETUP_HTTP_CLIENT_FULL("/server/files/list", true, 5000);
int httpCode = client.GET();
auto timer_parse = millis();
@@ -54,7 +51,9 @@ FILESYSTEM_FILE* get_files(int limit){
file_iter++;
}
// Little inefficient as it always allocates a string, even if it doesn't have to
if (file_iter == files.end() && files.size() >= limit)
continue;
f.name = (char*)malloc(strlen(path) + 1);
if (f.name == NULL){
Serial.println("Failed to allocate memory");

View File

@@ -0,0 +1,29 @@
#include "http_client.h"
String get_full_url(String url_part, PRINTER_CONFIG * config)
{
return "http://" + String(config->klipper_host) + ":" + String(config->klipper_port) + url_part;
}
String get_full_url(String url_part)
{
return "http://" + String(get_current_printer_config()->klipper_host) + ":" + String(get_current_printer_config()->klipper_port) + url_part;
}
void configure_http_client(HTTPClient &client, String url, bool stream, int timeout)
{
if (stream){
client.useHTTP10(true);
}
if (timeout > 0){
client.setTimeout(timeout);
client.setConnectTimeout(timeout);
}
client.begin(url);
if (get_current_printer_config()->auth_configured) {
client.addHeader("X-Api-Key", get_current_printer_config()->klipper_auth);
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include <HTTPClient.h>
#include "../conf/global_config.h"
String get_full_url(String url_part);
String get_full_url(String url_part, PRINTER_CONFIG * config);
void configure_http_client(HTTPClient &client, String url, bool stream = true, int timeout = 1000);
#define SETUP_HTTP_CLIENT(url_part) HTTPClient client; configure_http_client(client, get_full_url(url_part));
#define SETUP_HTTP_CLIENT_FULL(url_part, stream, timeout) HTTPClient client; configure_http_client(client, get_full_url(url_part), stream, timeout);

View File

@@ -0,0 +1,282 @@
#include "lv_setup.h"
#include "screen_driver.h"
#include "../conf/global_config.h"
#include "lvgl.h"
#include "../ui/ui_utils.h"
#include <Esp.h>
#ifndef CPU_FREQ_HIGH
#define CPU_FREQ_HIGH 240
#endif
#ifndef CPU_FREQ_LOW
#define CPU_FREQ_LOW 80
#endif
typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
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){
lv_coord_t local_point[] = {data->point.x, data->point.y};
while (data->state == LV_INDEV_STATE_PR){
original_touch_driver(indev_driver, data);
delay(20);
}
point[0] = local_point[0];
point[1] = local_point[1];
}
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.screen_cal_x_mult) + global_config.screen_cal_x_offset);
data->point.y = round((data->point.y * global_config.screen_cal_y_mult) + global_config.screen_cal_y_offset);
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
}
}
void lv_do_calibration(){
if (global_config.screen_calibrated){
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_x = lv_line_create(lv_scr_act());
lv_obj_t * line_y = 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_x, line_points_x, 2);
lv_obj_set_style_line_width(line_x, 1, 0);
lv_line_set_points(line_y, line_points_y, 2);
lv_obj_set_style_line_width(line_y, 1, 0);
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
lv_obj_align(line_x, LV_ALIGN_TOP_RIGHT, 1, 0);
lv_obj_align(line_y, LV_ALIGN_TOP_RIGHT, -10, 0);
#else
lv_obj_align(line_x, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_align(line_y, LV_ALIGN_TOP_LEFT, 0, 0);
#endif
while (true){
lv_timer_handler();
lv_task_handler();
if (point[0] != 0 && point[1] != 0){
break;
}
}
delay(300);
lv_coord_t x1 = point[0];
lv_coord_t y1 = point[1];
point[0] = 0;
point[1] = 0;
lv_obj_del(line_x);
lv_obj_del(line_y);
line_x = lv_line_create(lv_scr_act());
line_y = lv_line_create(lv_scr_act());
lv_line_set_points(line_x, line_points_x, 2);
lv_line_set_points(line_y, line_points_y, 2);
lv_obj_set_style_line_width(line_x, 1, 0);
lv_obj_set_style_line_width(line_y, 1, 0);
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
lv_obj_align(line_x, LV_ALIGN_BOTTOM_LEFT, 0, -10);
lv_obj_align(line_y, LV_ALIGN_BOTTOM_LEFT, 0, 1);
#else
lv_obj_align(line_x, LV_ALIGN_BOTTOM_RIGHT, 1, -10);
lv_obj_align(line_y, LV_ALIGN_BOTTOM_RIGHT, -10, 1);
#endif
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];
#ifdef CYD_SCREEN_DRIVER_ESP32_SMARTDISPLAY
int16_t xDist = CYD_SCREEN_HEIGHT_PX - 20;
int16_t yDist = CYD_SCREEN_WIDTH_PX - 20;
#else
int16_t xDist = CYD_SCREEN_WIDTH_PX - 20;
int16_t yDist = CYD_SCREEN_HEIGHT_PX - 20;
#endif
global_config.screen_cal_x_mult = (float)xDist / (float)(x2 - x1);
global_config.screen_cal_x_offset = 10.0 - ((float)x1 * global_config.screen_cal_x_mult);
global_config.screen_cal_y_mult = (float)yDist / (float)(y2 - y1);
global_config.screen_cal_y_offset = 10.0 - ((float)y1 * global_config.screen_cal_y_mult);
if (global_config.screen_cal_x_mult == std::numeric_limits<float>::infinity() || global_config.screen_cal_y_mult == std::numeric_limits<float>::infinity()){
Serial.println("Calibration failed, please try again");
ESP.restart();
}
global_config.screen_calibrated = true;
write_global_config();
lv_obj_clean(lv_scr_act());
Serial.printf("Calibration done: X*%.2f + %.2f, Y*%.2f + %.2f\n", global_config.screen_cal_x_mult, global_config.screen_cal_x_offset, global_config.screen_cal_y_mult, global_config.screen_cal_y_offset);
}
void set_screen_brightness()
{
if (global_config.brightness < 32)
screen_setBrightness(255);
else
screen_setBrightness(global_config.brightness);
}
void screen_timer_wake()
{
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
lv_timer_reset(screen_sleep_timer);
if (!is_screen_in_sleep){
return;
}
is_screen_in_sleep = false;
set_screen_brightness();
// Reset cpu freq
setCpuFrequencyMhz(CPU_FREQ_HIGH);
Serial.printf("CPU Speed: %d MHz\n", ESP.getCpuFreqMHz());
#endif
}
void screen_timer_sleep(lv_timer_t *timer)
{
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
screen_setBrightness(0);
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);
Serial.printf("CPU Speed: %d MHz\n", ESP.getCpuFreqMHz());
#endif
}
void screen_timer_setup()
{
screen_sleep_timer = lv_timer_create(screen_timer_sleep, global_config.screen_timeout * 1000 * 60, NULL);
lv_timer_pause(screen_sleep_timer);
}
void screen_timer_start()
{
lv_timer_resume(screen_sleep_timer);
}
void screen_timer_stop()
{
lv_timer_pause(screen_sleep_timer);
}
void screen_timer_period(unsigned int period)
{
lv_timer_set_period(screen_sleep_timer, period);
}
void set_screen_timer_period()
{
screen_timer_period(global_config.screen_timeout * 1000 * 60);
}
void set_color_scheme()
{
PRINTER_CONFIG *config = get_current_printer_config();
lv_disp_t *dispp = lv_disp_get_default();
lv_color_t main_color = {0};
COLOR_DEF color_def = color_defs[config->color_scheme];
if (color_defs[config->color_scheme].primary_color_light > 0){
main_color = lv_palette_lighten(color_def.primary_color, color_def.primary_color_light);
}
else if (color_defs[config->color_scheme].primary_color_light < 0) {
main_color = lv_palette_darken(color_def.primary_color, color_def.primary_color_light * -1);
}
else {
main_color = lv_palette_main(color_defs[config->color_scheme].primary_color);
}
lv_theme_t *theme = lv_theme_default_init(dispp, main_color, lv_palette_main(color_def.secondary_color), !config->light_mode, &CYD_SCREEN_FONT);
lv_disp_set_theme(dispp, theme);
}
void lv_setup()
{
set_screen_brightness();
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();
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_do_calibration();
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
display_driver->driver->read_cb = lv_touch_intercept;
screen_timer_setup();
screen_timer_start();
lv_png_init();
}
bool is_screen_asleep()
{
return is_screen_in_sleep;
}

View File

@@ -0,0 +1,10 @@
#pragma once
void set_screen_brightness();
void set_screen_timer_period();
void screen_timer_wake();
void screen_timer_start();
void screen_timer_stop();
void set_color_scheme();
void lv_setup();
bool is_screen_asleep();

View File

@@ -1,23 +1,24 @@
#include "lvgl.h"
#include "macros_query.h"
#include "./data_setup.h"
#include <HTTPClient.h>
#include "../conf/global_config.h"
#include <ArduinoJson.h>
#include <UrlEncode.h>
#include "http_client.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;
}
static char* power_devices[16] = {0};
static bool power_device_states[16] = {0};
static unsigned int stored_power_devices_count = 0;
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/gcode/help";
MACROSQUERY macros_query(PRINTER_CONFIG * config)
{
HTTPClient client;
client.useHTTP10(true);
client.begin(url.c_str());
configure_http_client(client, get_full_url("/printer/gcode/help", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
@@ -38,14 +39,132 @@ static void on_state_change(void * s, lv_msg_t * m) {
macros[macros_count++] = macro;
}
}
return {(const char**)macros, (unsigned int)macros_count};
}
else {
return {NULL, 0};
}
}
MACROSQUERY macros_query() {
return {(const char**)macros, macros_count};
MACROSQUERY macros_query()
{
return macros_query(get_current_printer_config());
}
void macros_query_setup(){
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL);
on_state_change(NULL, NULL);
unsigned int macro_count(PRINTER_CONFIG * config)
{
HTTPClient client;
configure_http_client(client, get_full_url("/printer/gcode/help", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"].as<JsonObject>();
unsigned int count = 0;
for (JsonPair i : result){
const char *value = i.value().as<String>().c_str();
if (strcmp(value, "CYD_SCREEN_MACRO") == 0) {
count++;
}
}
return count;
}
else {
return 0;
}
}
unsigned int macro_count()
{
return macro_count(get_current_printer_config());
}
POWERQUERY power_devices_query(PRINTER_CONFIG * config)
{
HTTPClient client;
configure_http_client(client, get_full_url("/machine/device_power/devices", config), true, 1000);
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 < stored_power_devices_count; i++){
free(power_devices[i]);
}
stored_power_devices_count = 0;
for (auto i : result){
const char * device_name = i["device"];
const char * device_state = i["status"];
power_devices[stored_power_devices_count] = (char*)malloc(strlen(device_name) + 1);
strcpy(power_devices[stored_power_devices_count], device_name);
power_device_states[stored_power_devices_count] = strcmp(device_state, "on") == 0;
stored_power_devices_count++;
}
return {(const char**)power_devices, (const bool*)power_device_states, (unsigned int)stored_power_devices_count};
}
else {
return {NULL, NULL, 0};
}
}
POWERQUERY power_devices_query()
{
return power_devices_query(get_current_printer_config());
}
unsigned int power_devices_count(PRINTER_CONFIG * config)
{
HTTPClient client;
configure_http_client(client, get_full_url("/machine/device_power/devices", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200){
JsonDocument doc;
deserializeJson(doc, client.getStream());
auto result = doc["result"]["devices"].as<JsonArray>();
unsigned int count = 0;
for (auto i : result){
count++;
}
return count;
}
else {
return 0;
}
}
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;
configure_http_client(client, get_full_url("/machine/device_power/device?device=" + urlEncode(device_name) + "&action=" + (state ? "on" : "off"), config), true, 1000);
return client.POST("") == 200;
}
bool set_power_state(const char* device_name, bool state)
{
return set_power_state(device_name, state, get_current_printer_config());
}

View File

@@ -1,9 +1,25 @@
#pragma once
#include "../conf/global_config.h"
typedef struct {
const char** macros;
uint32_t count;
} MACROSQUERY;
typedef struct {
const char** power_devices;
const bool* power_states;
uint32_t count;
} POWERQUERY;
MACROSQUERY macros_query(PRINTER_CONFIG * config);
MACROSQUERY macros_query();
void macros_query_setup();
unsigned int macro_count(PRINTER_CONFIG * config);
unsigned int macro_count();
POWERQUERY power_devices_query(PRINTER_CONFIG * config);
POWERQUERY power_devices_query();
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);

View File

@@ -1,259 +0,0 @@
#include "screen_driver.h"
#include <SPI.h>
#include <TFT_eSPI.h>
#include "../conf/global_config.h"
#include "lvgl.h"
SPIClass touchscreen_spi = SPIClass(HSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
uint32_t LV_EVENT_GET_COMP_CHILD;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[TFT_WIDTH * TFT_HEIGHT / 10];
TFT_eSPI tft = TFT_eSPI();
bool isScreenInSleep = false;
lv_timer_t *screenSleepTimer;
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 - 40;
int16_t yDist = 240 - 40;
global_config.screenCalXMult = (float)xDist / (float)(x2 - x1);
global_config.screenCalXOffset = 20.0 - ((float)x1 * global_config.screenCalXMult);
global_config.screenCalYMult = (float)yDist / (float)(y2 - y1);
global_config.screenCalYOffset = 20.0 - ((float)y1 * global_config.screenCalYMult);
global_config.screenCalibrated = true;
WriteGlobalConfig();
}
void screen_setBrightness(byte brightness)
{
// calculate duty, 4095 from 2 ^ 12 - 1
uint32_t duty = (4095 / 255) * brightness;
// write duty to LEDC
ledcWrite(0, duty);
}
void set_screen_brightness()
{
if (global_config.brightness < 32)
screen_setBrightness(255);
else
screen_setBrightness(global_config.brightness);
}
void screen_timer_wake()
{
lv_timer_reset(screenSleepTimer);
isScreenInSleep = false;
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)
{
screen_setBrightness(0);
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()
{
screenSleepTimer = lv_timer_create(screen_timer_sleep, global_config.screenTimeout * 1000 * 60, NULL);
lv_timer_pause(screenSleepTimer);
}
void screen_timer_start()
{
lv_timer_resume(screenSleepTimer);
}
void screen_timer_stop()
{
lv_timer_pause(screenSleepTimer);
}
void screen_timer_period(uint32_t period)
{
lv_timer_set_period(screenSleepTimer, period);
}
void set_screen_timer_period()
{
screen_timer_period(global_config.screenTimeout * 1000 * 60);
}
void screen_lv_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp);
}
void screen_lv_touchRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
if (touchscreen.tirqTouched() && touchscreen.touched())
{
lv_timer_reset(screenSleepTimer);
// dont pass first touch after power on
if (isScreenInSleep)
{
screen_timer_wake();
while (touchscreen.touched())
;
return;
}
TS_Point p = touchscreen_point();
data->state = LV_INDEV_STATE_PR;
data->point.x = p.x;
data->point.y = p.y;
}
else
{
data->state = LV_INDEV_STATE_REL;
}
}
void set_color_scheme(){
lv_disp_t *dispp = lv_disp_get_default();
lv_color_t main_color = {0};
COLOR_DEF color_def = color_defs[global_config.color_scheme];
if (color_defs[global_config.color_scheme].primary_color_light > 0){
main_color = lv_palette_lighten(color_def.primary_color, color_def.primary_color_light);
}
else if (color_defs[global_config.color_scheme].primary_color_light < 0) {
main_color = lv_palette_darken(color_def.primary_color, color_def.primary_color_light * -1);
}
else {
main_color = lv_palette_main(color_defs[global_config.color_scheme].primary_color);
}
lv_theme_t *theme = lv_theme_default_init(dispp, main_color, lv_palette_main(color_def.secondary_color), !global_config.lightMode, LV_FONT_DEFAULT);
lv_disp_set_theme(dispp, theme);
}
void set_invert_display(){
tft.invertDisplay(global_config.invertColors);
}
void screen_setup()
{
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);
touchscreen.setRotation(global_config.rotateScreen ? 3 : 1);
lv_init();
tft.init();
ledcSetup(0, 5000, 12);
ledcAttachPin(21, 0);
tft.setRotation(global_config.rotateScreen ? 3 : 1);
tft.fillScreen(TFT_BLACK);
set_screen_brightness();
set_invert_display();
touchscreen_spi.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreen_spi);
touchscreen_calibrate();
lv_disp_draw_buf_init(&draw_buf, buf, NULL, TFT_WIDTH * TFT_HEIGHT / 10);
/*Initialize the display*/
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = TFT_HEIGHT;
disp_drv.ver_res = TFT_WIDTH;
disp_drv.flush_cb = screen_lv_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = screen_lv_touchRead;
lv_indev_drv_register(&indev_drv);
screen_timer_setup();
screen_timer_start();
/*Initialize the graphics library */
LV_EVENT_GET_COMP_CHILD = lv_event_register_id();
set_color_scheme();
}

View File

@@ -1,35 +1,6 @@
#pragma once
// Adapted from https://github.com/xperiments-in/xtouch/blob/main/src/devices/2.8/screen.h
#ifndef _SCREEN_DRIVER_INIT
#define _SCREEN_DRIVER_INIT
#define CPU_FREQ_HIGH 240
#define CPU_FREQ_LOW 80
#include <XPT2046_Touchscreen.h>
#include <TFT_eSPI.h>
#define XPT2046_IRQ 36
#define XPT2046_MOSI 32
#define XPT2046_MISO 39
#define XPT2046_CLK 25
#define XPT2046_CS 33
TS_Point touchscreen_point();
void touchscreen_calibrate(bool force = false);
void screen_setBrightness(byte brightness);
void screen_timer_setup();
void screen_timer_start();
void screen_timer_stop();
void screen_timer_period(uint32_t period);
void set_color_scheme();
void screen_setBrightness(unsigned char brightness);
void screen_setup();
void set_invert_display();
void screen_timer_wake();
void set_screen_timer_period();
void set_screen_brightness();
extern TFT_eSPI tft;
#endif // _SCREEN_DRIVER_INIT

View File

@@ -0,0 +1,230 @@
/*
ESP32-OTA-Pull - a library for doing "pull" based OTA ("Over The Air") firmware
updates, where the image updates are posted on the web.
MIT License
Copyright (c) 2022-3 Mikal Hart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Update.h>
#include <WiFi.h>
class ESP32OTAPull
{
public:
enum ActionType { DONT_DO_UPDATE, UPDATE_BUT_NO_BOOT, UPDATE_AND_BOOT };
// Return codes from CheckForOTAUpdate
enum ErrorCode { UPDATE_AVAILABLE = -3, NO_UPDATE_PROFILE_FOUND = -2, NO_UPDATE_AVAILABLE = -1, UPDATE_OK = 0, HTTP_FAILED = 1, WRITE_ERROR = 2, JSON_PROBLEM = 3, OTA_UPDATE_FAIL = 4 };
private:
void (*Callback)(int offset, int totallength) = NULL;
ActionType Action = UPDATE_AND_BOOT;
String Board = ARDUINO_BOARD;
String Device = "";
String Config = "";
String CVersion = "";
bool DowngradesAllowed = false;
int DownloadJson(const char* URL, String& payload)
{
HTTPClient http;
http.begin(URL);
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode == 200)
{
payload = http.getString();
}
// Free resources
http.end();
return httpResponseCode;
}
int DoOTAUpdate(const char* URL, ActionType Action)
{
HTTPClient http;
http.begin(URL);
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode == 200)
{
int totalLength = http.getSize();
// this is required to start firmware update process
if (!Update.begin(UPDATE_SIZE_UNKNOWN))
return OTA_UPDATE_FAIL;
// create buffer for read
uint8_t buff[1280] = { 0 };
// get tcp stream
WiFiClient* stream = http.getStreamPtr();
// read all data from server
int offset = 0;
while (http.connected() && offset < totalLength)
{
size_t sizeAvail = stream->available();
if (sizeAvail > 0)
{
size_t bytes_to_read = min(sizeAvail, sizeof(buff));
size_t bytes_read = stream->readBytes(buff, bytes_to_read);
size_t bytes_written = Update.write(buff, bytes_read);
if (bytes_read != bytes_written)
{
// Serial.printf("Unexpected error in OTA: %d %d %d\n", bytes_to_read, bytes_read, bytes_written);
break;
}
offset += bytes_written;
if (Callback != NULL)
Callback(offset, totalLength);
}
}
if (offset == totalLength)
{
Update.end(true);
delay(1000);
// Restart ESP32 to see changes
if (Action == UPDATE_BUT_NO_BOOT)
return UPDATE_OK;
ESP.restart();
}
return WRITE_ERROR;
}
http.end();
return httpResponseCode;
}
public:
/// @brief Return the version string of the binary, as reported by the JSON
/// @return The firmware version
String GetVersion()
{
return CVersion;
}
/// @brief Override the default "Device" id (MAC Address)
/// @param device A string identifying the particular device (instance) (typically e.g., a MAC address)
/// @return The current ESP32OTAPull object for chaining
ESP32OTAPull &OverrideDevice(const char *device)
{
Device = device;
return *this;
}
/// @brief Override the default "Board" value of ARDUINO_BOARD
/// @param board A string identifying the board (class) being targeted
/// @return The current ESP32OTAPull object for chaining
ESP32OTAPull &OverrideBoard(const char *board)
{
Board = board;
return *this;
}
/// @brief Specify a configuration string that must match any "Config" in JSON
/// @param config An arbitrary string showing the current configuration
/// @return The current ESP32OTAPull object for chaining
ESP32OTAPull &SetConfig(const char *config)
{
Config = config;
return *this;
}
/// @brief Specify whether downgrades (posted version is lower) are allowed
/// @param allow_downgrades true if downgrades are allowed
/// @return The current ESP32OTAPull object for chaining
ESP32OTAPull &AllowDowngrades(bool allow_downgrades)
{
DowngradesAllowed = allow_downgrades;
return *this;
}
/// @brief Specify a callback function to monitor update progress
/// @param callback Pointer to a function that is called repeatedly during update
/// @return The current ESP32OTAPull object for chaining
ESP32OTAPull &SetCallback(void (*callback)(int offset, int totallength))
{
Callback = callback;
return *this;
}
/// @brief The main entry point for OTA Update
/// @param JSON_URL The URL for the JSON filter file
/// @param CurrentVersion The version # of the current (i.e. to be replaced) sketch
/// @param ActionType The action to be performed. May be any of DONT_DO_UPDATE, UPDATE_BUT_NO_BOOT, UPDATE_AND_BOOT (default)
/// @return ErrorCode or HTTP failure code (see enum above)
int CheckForOTAUpdate(const char* JSON_URL, const char *CurrentVersion, ActionType Action = UPDATE_AND_BOOT)
{
CurrentVersion = CurrentVersion == NULL ? "" : CurrentVersion;
// Downloading OTA Json...
String Payload;
int httpResponseCode = DownloadJson(JSON_URL, Payload);
if (httpResponseCode != 200)
return httpResponseCode > 0 ? httpResponseCode : HTTP_FAILED;
// Deserialize the JSON file downloaded from user's site
JsonDocument doc;
DeserializationError deserialization = deserializeJson(doc, Payload.c_str());
if (deserialization != DeserializationError::Ok)
return JSON_PROBLEM;
String DeviceName = Device.isEmpty() ? WiFi.macAddress() : Device;
String BoardName = Board.isEmpty() ? ARDUINO_BOARD : Board;
String ConfigName = Config.isEmpty() ? "" : Config;
bool foundProfile = false;
// Step through the configurations looking for a match
for (auto config : doc["Configurations"].as<JsonArray>())
{
String CBoard = config["Board"].isNull() ? "" : (const char *)config["Board"];
String CDevice = config["Device"].isNull() ? "" : (const char *)config["Device"];
CVersion = config["Version"].isNull() ? "" : (const char *)config["Version"];
String CConfig = config["Config"].isNull() ? "" : (const char *)config["Config"];
//Serial.printf("Checking %s %s %s %s\n", CBoard.c_str(), CDevice.c_str(), CVersion.c_str(), CConfig.c_str());
//Serial.printf("Against %s %s %s %s\n", BoardName.c_str(), DeviceName.c_str(), CurrentVersion, ConfigName.c_str());
if ((CBoard.isEmpty() || CBoard == BoardName) &&
(CDevice.isEmpty() || CDevice == DeviceName) &&
(CConfig.isEmpty() || CConfig == ConfigName))
{
if (CVersion.isEmpty() || CVersion > String(CurrentVersion) ||
(DowngradesAllowed && CVersion != String(CurrentVersion)))
return Action == DONT_DO_UPDATE ? UPDATE_AVAILABLE : DoOTAUpdate(config["URL"], Action);
foundProfile = true;
}
}
return foundProfile ? NO_UPDATE_AVAILABLE : NO_UPDATE_PROFILE_FOUND;
}
};

View File

@@ -6,25 +6,20 @@
#include "core/data_setup.h"
#include "ui/main_ui.h"
#include "ui/nav_buttons.h"
static void event_handler(lv_event_t * e){
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
global_config.version = 0;
WriteGlobalConfig();
ESP.restart();
}
}
#include <Esp.h>
#include "core/lv_setup.h"
#include "ui/ota_setup.h"
void setup() {
Serial.begin(115200);
Serial.println("Hello World");
LoadGlobalConfig();
load_global_config();
screen_setup();
lv_setup();
Serial.println("Screen init done");
wifi_init();
ota_init();
ip_init();
data_setup();
@@ -38,4 +33,9 @@ void loop(){
data_loop();
lv_timer_handler();
lv_task_handler();
if (is_ready_for_ota_update())
{
ota_do_update();
}
}

View File

@@ -0,0 +1,138 @@
#include "gcode_img.h"
#include "lvgl.h"
#include "ui_utils.h"
#include <Esp.h>
#include <ArduinoJson.h>
#include "../conf/global_config.h"
#include "../core/http_client.h"
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)
{
if (filename == NULL){
Serial.println("No gcode filename");
return false;
}
SETUP_HTTP_CLIENT("/server/files/thumbnails?filename=" + String(filename));
int httpCode = 0;
try {
httpCode = client.GET();
}
catch (...){
Serial.println("Exception while fetching gcode img location");
return {0};
}
if (httpCode == 200)
{
String payload = client.getString();
JsonDocument doc;
deserializeJson(doc, payload);
auto result = doc["result"].as<JsonArray>();
const char* chosen_thumb = NULL;
for (auto file : result){
int width = file["width"];
int height = file["height"];
int size = file["size"];
const char* thumbnail = file["thumbnail_path"];
if (width != height || width != 32)
continue;
if (strcmp(thumbnail + strlen(thumbnail) - 4, ".png"))
continue;
chosen_thumb = thumbnail;
break;
}
if (chosen_thumb != NULL){
Serial.printf("Found 32x32 PNG gcode img at %s\n", filename);
strcpy(img_filename_path, chosen_thumb);
return true;
}
}
return false;
}
lv_obj_t* draw_gcode_img()
{
clear_img_mem();
if (img_filename_path[0] == 0){
Serial.println("No gcode img path");
return NULL;
}
SETUP_HTTP_CLIENT_FULL("/server/files/gcodes/" + String(img_filename_path), false, 2000);
int httpCode = 0;
try {
httpCode = client.GET();
}
catch (...){
Serial.println("Exception while fetching gcode img");
return NULL;
}
if (httpCode == 200)
{
size_t len = client.getSize();
if (len <= 0)
{
Serial.println("No gcode img data");
return NULL;
}
data_png = (unsigned char*)malloc(len + 1);
if (len != client.getStream().readBytes(data_png, len)){
Serial.println("Failed to read gcode img data");
clear_img_mem();
return NULL;
}
memset(&img_header, 0, sizeof(img_header));
img_header.header.w = 32;
img_header.header.h = 32;
img_header.data_size = len;
img_header.header.cf = LV_IMG_CF_RAW_ALPHA;
img_header.data = data_png;
lv_obj_t * img = lv_img_create(lv_scr_act());
lv_img_set_src(img, &img_header);
return img;
}
return NULL;
}
lv_obj_t* show_gcode_img(const char* filename)
{
if (filename == NULL){
Serial.println("No gcode filename");
return NULL;
}
if (!has_128_128_gcode(filename)){
Serial.println("No 32x32 gcode img found");
return NULL;
}
return draw_gcode_img();
}
void clear_img_mem()
{
if (data_png != NULL){
free(data_png);
data_png = NULL;
}
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include "lvgl.h"
lv_obj_t* show_gcode_img(const char* filename);
bool has_128_128_gcode(const char* filename);
void clear_img_mem();

View File

@@ -1,31 +1,59 @@
#include "ip_setup.h"
#include "../conf/global_config.h"
#include "lvgl.h"
#include <TFT_eSPI.h>
#include <HTTPClient.h>
#include "core/data_setup.h"
#include "ui_utils.h"
#include "../core/macros_query.h"
#include "panels/panel.h"
#include "../core/http_client.h"
#include "switch_printer.h"
#include "macros.h"
bool connect_ok = false;
lv_obj_t * ipEntry;
int prev_power_device_count = 0;
lv_obj_t * hostEntry;
lv_obj_t * portEntry;
lv_obj_t * label = NULL;
/* Create a custom keyboard to allow hostnames or ip addresses (a-z, 0 - 9, and -) */
static const char * kb_map[] = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n",
"a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_OK, "\n",
LV_SYMBOL_LEFT, "z", "x", "c", "v", "b", "n", "m", ".", "-", LV_SYMBOL_RIGHT, NULL
};
static const lv_btnmatrix_ctrl_t kb_ctrl[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 5,
LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6
};
void ip_init_inner();
bool verify_ip(){
HTTPClient client;
String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/info";
enum connection_status_t {
CONNECT_FAIL = 0,
CONNECT_OK = 1,
CONNECT_AUTH_REQUIRED = 2,
};
connection_status_t verify_ip(){
SETUP_HTTP_CLIENT_FULL("/printer/info", true, 1000);
int httpCode;
try {
Serial.println(url);
client.setTimeout(500);
client.begin(url.c_str());
httpCode = client.GET();
return httpCode == 200;
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;
}
}
@@ -44,72 +72,205 @@ static void ta_event_cb(lv_event_t * e) {
}
else if (code == LV_EVENT_READY)
{
strcpy(global_config.klipperHost, lv_textarea_get_text(ipEntry));
global_config.klipperPort = atoi(lv_textarea_get_text(portEntry));
strcpy(get_current_printer_config()->klipper_host, lv_textarea_get_text(hostEntry));
get_current_printer_config()->klipper_port = atoi(lv_textarea_get_text(portEntry));
if (verify_ip())
connection_status_t status = verify_ip();
if (status == CONNECT_OK)
{
global_config.ipConfigured = true;
WriteGlobalConfig();
get_current_printer_config()->ip_configured = true;
write_global_config();
connect_ok = true;
}
else if (status == CONNECT_AUTH_REQUIRED)
{
label = NULL;
get_current_printer_config()->ip_configured = true;
write_global_config();
}
else
{
lv_label_set_text(label, "Failed to connect");
}
}
else
{
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 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;
get_current_printer_config()->ip_configured = false;
ip_init_inner();
}
}
void ip_init_inner(){
static void power_devices_button(lv_event_t * e) {
macros_draw_power_fullscreen();
}
void redraw_connect_screen(){
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 * button_row = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(button_row, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(button_row, LV_FLEX_ALIGN_CENTER);
lv_obj_align(button_row, LV_ALIGN_CENTER, 0, CYD_SCREEN_GAP_PX + CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * btnLabel = lv_label_create(resetBtn);
lv_label_set_text(btnLabel, "Reset");
lv_obj_center(btnLabel);
lv_obj_t * reset_btn = lv_btn_create(button_row);
lv_obj_add_event_cb(reset_btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(reset_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * btn_label = lv_label_create(reset_btn);
lv_label_set_text(btn_label, "Reset");
lv_obj_center(btn_label);
if (prev_power_device_count >= 1){
lv_obj_t * power_devices_btn = lv_btn_create(button_row);
lv_obj_add_event_cb(power_devices_btn, power_devices_button, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(power_devices_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
btn_label = lv_label_create(power_devices_btn);
lv_label_set_text(btn_label, "Power Devices");
lv_obj_center(btn_label);
}
draw_switch_printer_button();
}
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)
{
get_current_printer_config()->auth_configured = true;
strcpy(get_current_printer_config()->klipper_auth, txt);
write_global_config();
auth_entry_done = true;
}
}
else if (code == LV_EVENT_CANCEL)
{
auth_entry_done = true;
}
}
void handle_auth_entry(){
auth_entry_done = false;
get_current_printer_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 (get_current_printer_config()->auth_configured)
lv_textarea_set_text(passEntry, get_current_printer_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 (get_current_printer_config()->ip_configured) {
redraw_connect_screen();
return;
}
lv_obj_t * keyboard = lv_keyboard_create(lv_scr_act());
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Enter Klipper IP and Port");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10 + 2);
lv_obj_clean(lv_scr_act());
ipEntry = lv_textarea_create(lv_scr_act());
lv_textarea_set_one_line(ipEntry, true);
lv_textarea_set_max_length(ipEntry, 63);
lv_textarea_set_text(ipEntry, "");
lv_obj_align(ipEntry, LV_ALIGN_TOP_LEFT, 10, 40);
lv_obj_add_event_cb(ipEntry, ta_event_cb, LV_EVENT_ALL, keyboard);
lv_obj_set_size(ipEntry, TFT_HEIGHT - 20 - 100, 60);
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);
portEntry = lv_textarea_create(lv_scr_act());
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);
label = lv_label_create(top_root);
lv_label_set_text(label, "Enter Klipper IP/Hostname and Port");
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_t * textbow_row = lv_create_empty_panel(top_root);
lv_obj_set_width(textbow_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_set_flex_grow(textbow_row, 1);
lv_layout_flex_row(textbow_row);
hostEntry = lv_textarea_create(textbow_row);
lv_textarea_set_one_line(hostEntry, true);
lv_obj_add_flag(hostEntry, LV_OBJ_FLAG_USER_1);
lv_textarea_set_max_length(hostEntry, 63);
lv_textarea_set_text(hostEntry, "");
lv_obj_set_flex_grow(hostEntry, 3);
portEntry = lv_textarea_create(textbow_row);
lv_textarea_set_one_line(portEntry, true);
lv_textarea_set_max_length(portEntry, 5);
lv_textarea_set_text(portEntry, "80");
lv_obj_align(portEntry, LV_ALIGN_TOP_LEFT, TFT_HEIGHT - 20 - 80, 40);
lv_obj_add_event_cb(portEntry, ta_event_cb, LV_EVENT_ALL, keyboard);
lv_obj_set_size(portEntry, 90, 60);
lv_obj_set_flex_grow(portEntry, 1);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER);
lv_keyboard_set_textarea(keyboard, ipEntry);
lv_obj_t * keyboard = lv_keyboard_create(root);
lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl);
lv_obj_add_event_cb(hostEntry, ta_event_cb, LV_EVENT_ALL, keyboard);
lv_obj_add_event_cb(portEntry, ta_event_cb, LV_EVENT_ALL, keyboard);
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1);
lv_keyboard_set_textarea(keyboard, hostEntry);
}
long last_data_update_ip = -10000;
@@ -119,6 +280,7 @@ int retry_count = 0;
void ip_init(){
connect_ok = false;
retry_count = 0;
prev_power_device_count = 0;
ip_init_inner();
@@ -127,13 +289,26 @@ void ip_init(){
lv_timer_handler();
lv_task_handler();
if (!connect_ok && global_config.ipConfigured && (millis() - last_data_update_ip) > data_update_interval_ip){
connect_ok = verify_ip();
if (!connect_ok && get_current_printer_config()->ip_configured && (millis() - last_data_update_ip) > data_update_interval_ip){
connection_status_t status = verify_ip();
connect_ok = status == CONNECT_OK;
last_data_update_ip = millis();
retry_count++;
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());
}
if (status == CONNECT_AUTH_REQUIRED)
handle_auth_entry();
unsigned int power_device_count = power_devices_count();
if (power_device_count != prev_power_device_count) {
prev_power_device_count = power_device_count;
redraw_connect_screen();
}
}
}
}

View File

@@ -0,0 +1,77 @@
#include "macros.h"
#include "ui_utils.h"
#include <Esp.h>
#include "../core/data_setup.h"
PRINTER_CONFIG * curernt_config = NULL;
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);
}
void macros_add_macros_to_panel(lv_obj_t * root_panel, MACROSQUERY query)
{
for (int i = 0; i < query.count; i++){
const char* macro = query.macros[i];
lv_create_custom_menu_button(macro, root_panel, btn_press, "Run", (void*)macro);
}
}
static void power_device_toggle(lv_event_t * e)
{
auto state = lv_obj_get_state(lv_event_get_target(e));
bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED);
const char* power_device_name = (const char*)lv_event_get_user_data(e);
Serial.printf("Power Device: %s, State: %d -> %d\n", power_device_name, !checked, checked);
if (curernt_config != NULL)
set_power_state(power_device_name, checked, curernt_config);
}
void macros_add_power_devices_to_panel(lv_obj_t * root_panel, POWERQUERY query)
{
for (int i = 0; i < query.count; i++){
const char* power_device_name = query.power_devices[i];
const bool power_device_state = query.power_states[i];
lv_create_custom_menu_switch(power_device_name, root_panel, power_device_toggle, power_device_state, (void*)power_device_name);
}
}
void macros_set_current_config(PRINTER_CONFIG * config)
{
curernt_config = config;
}
void macros_draw_power_fullscreen(PRINTER_CONFIG * config)
{
macros_set_current_config(config);
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(parent, LV_OPA_100, 0);
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(parent);
lv_obj_set_size(lv_create_empty_panel(parent), 0, 0);
auto width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * btn = lv_btn_create(parent);
lv_obj_set_size(btn, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, parent);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
lv_obj_center(label);
POWERQUERY power = power_devices_query(config);
macros_add_power_devices_to_panel(parent, power);
}
void macros_draw_power_fullscreen()
{
macros_draw_power_fullscreen(get_current_printer_config());
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "lvgl.h"
#include "../core/macros_query.h"
void macros_add_macros_to_panel(lv_obj_t * root_panel, MACROSQUERY query);
void macros_add_power_devices_to_panel(lv_obj_t * root_panel, POWERQUERY query);
void macros_set_current_config(PRINTER_CONFIG * config);
void macros_draw_power_fullscreen(PRINTER_CONFIG * config);
void macros_draw_power_fullscreen();

View File

@@ -4,55 +4,15 @@
#include "../core/screen_driver.h"
#include "lvgl.h"
#include "nav_buttons.h"
char extruder_temp_buff[20];
char bed_temp_buff[20];
char position_buff[20];
static void btn_click_restart(lv_event_t * e){
send_gcode(false, "RESTART");
}
static void btn_click_firmware_restart(lv_event_t * e){
send_gcode(false, "FIRMWARE_RESTART");
}
void error_ui(){
lv_obj_clean(lv_scr_act());
lv_obj_t * label;
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, LV_SYMBOL_WARNING " Printer is not ready");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10);
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, printer.state_message);
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 30);
lv_obj_set_size(label, TFT_HEIGHT - 20, TFT_WIDTH - 30);
lv_obj_clear_flag(label, LV_OBJ_FLAG_SCROLLABLE);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -10);
lv_obj_set_size(btn, TFT_HEIGHT / 2 - 15, 30);
lv_obj_add_event_cb(btn, btn_click_restart, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
btn = lv_btn_create(lv_scr_act());
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
lv_obj_set_size(btn, TFT_HEIGHT / 2 - 15, 30);
lv_obj_add_event_cb(btn, btn_click_firmware_restart, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, "Firmware Restart");
lv_obj_center(label);
}
#include "ui_utils.h"
#include "panels/panel.h"
#include "../core/macros_query.h"
#include "../core/lv_setup.h"
#include "switch_printer.h"
#include "macros.h"
void check_if_screen_needs_to_be_disabled(){
if (global_config.onDuringPrint && printer.state == PRINTER_STATE_PRINTING){
if (global_config.on_during_print && printer.state == PRINTER_STATE_PRINTING){
screen_timer_wake();
screen_timer_stop();
}
@@ -65,14 +25,13 @@ static void on_state_change(void * s, lv_msg_t * m){
check_if_screen_needs_to_be_disabled();
if (printer.state == PRINTER_STATE_ERROR){
error_ui();
nav_buttons_setup(PANEL_ERROR);
}
else {
nav_buttons_setup(0);
nav_buttons_setup(PANEL_PRINT);
}
}
void main_ui_setup(){
lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL);
on_state_change(NULL, NULL);

View File

@@ -2,7 +2,9 @@
#include "panels/panel.h"
#include "../core/data_setup.h"
#include "nav_buttons.h"
#include <HTTPClient.h>
#include "ui_utils.h"
#include <stdio.h>
#include "../conf/global_config.h"
static lv_style_t nav_button_style;
@@ -56,129 +58,132 @@ static void update_printer_data_time(lv_event_t * e){
}
static void btn_click_files(lv_event_t * e){
nav_buttons_setup(0);
nav_buttons_setup(PANEL_PRINT);
}
static void btn_click_move(lv_event_t * e){
nav_buttons_setup(1);
nav_buttons_setup(PANEL_MOVE);
}
static void btn_click_extrude(lv_event_t * e){
nav_buttons_setup(2);
nav_buttons_setup(PANEL_TEMP);
}
static void btn_click_settings(lv_event_t * e){
nav_buttons_setup(3);
nav_buttons_setup(PANEL_SETTINGS);
}
static void btn_click_macros(lv_event_t * e){
nav_buttons_setup(4);
nav_buttons_setup(PANEL_MACROS);
}
static void btn_click_printer(lv_event_t * e){
nav_buttons_setup(PANEL_PRINTER);
}
static void btn_click_err(lv_event_t * e){
nav_buttons_setup(PANEL_ERROR);
}
void create_button(const char* icon, const char* name, lv_event_cb_t button_click, lv_event_cb_t label_update, lv_obj_t * root){
lv_obj_t* btn = lv_btn_create(root);
lv_obj_set_flex_grow(btn, 1);
#ifdef CYD_SCREEN_VERTICAL
lv_obj_set_height(btn, CYD_SCREEN_SIDEBAR_SIZE_PX);
#else
lv_obj_set_width(btn, CYD_SCREEN_SIDEBAR_SIZE_PX);
#endif
lv_obj_add_style(btn, &nav_button_style, 0);
if (button_click != NULL)
lv_obj_add_event_cb(btn, button_click, LV_EVENT_CLICKED, NULL);
lv_obj_t* label = lv_label_create(btn);
lv_label_set_text(label, icon);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * CYD_SCREEN_GAP_PX);
label = lv_label_create(btn);
lv_label_set_text(label, name);
lv_obj_align(label, LV_ALIGN_CENTER, 0, CYD_SCREEN_GAP_PX);
lv_obj_add_event_cb(label, label_update, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
lv_obj_add_style(label, &nav_button_text_style, 0);
}
void nav_buttons_setup(unsigned char active_panel){
lv_obj_clean(lv_scr_act());
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
sprintf(temp_buffer, "%.0f/%.0f", printer.extruder_temp, printer.bed_temp);
sprintf(z_pos_buffer, "Z%.2f", printer.position[2]);
const int button_width = 40;
const int button_height = 60;
const int icon_text_spacing = 10;
lv_obj_t * root_panel = lv_create_empty_panel(lv_scr_act());
#ifdef CYD_SCREEN_VERTICAL
lv_obj_set_size(root_panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_SIDEBAR_SIZE_PX);
lv_obj_align(root_panel, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_layout_flex_row(root_panel, LV_FLEX_ALIGN_START, 0, 0);
#else
lv_obj_set_size(root_panel, CYD_SCREEN_SIDEBAR_SIZE_PX, CYD_SCREEN_HEIGHT_PX);
lv_obj_align(root_panel, LV_ALIGN_TOP_LEFT, 0, 0);
lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_START, 0, 0);
#endif
if (printer.state != PRINTER_STATE_ERROR){
// Files/Print
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, button_width, button_height);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_add_style(btn, &nav_button_style, 0);
lv_obj_add_event_cb(btn, btn_click_files, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_COPY);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
label = lv_label_create(btn);
lv_label_set_text(label, "Idle");
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
lv_obj_add_style(label, &nav_button_text_style, 0);
lv_obj_add_event_cb(label, update_printer_data_time, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel);
// Move
btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, button_width, button_height);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height);
lv_obj_add_style(btn, &nav_button_style, 0);
lv_obj_add_event_cb(btn, btn_click_move, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CHARGE);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
label = lv_label_create(btn);
lv_label_set_text(label, z_pos_buffer);
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
lv_obj_add_event_cb(label, update_printer_data_z_pos, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
lv_obj_add_style(label, &nav_button_text_style, 0);
create_button(printer.state == PRINTER_STATE_PRINTING ? LV_SYMBOL_EDIT : LV_SYMBOL_CHARGE, "Z?", btn_click_move, update_printer_data_z_pos, root_panel);
// Extrude/Temp
btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, button_width, button_height);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 2);
lv_obj_add_style(btn, &nav_button_style, 0);
lv_obj_add_event_cb(btn, btn_click_extrude, LV_EVENT_CLICKED, NULL);
create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel);
}
else {
// Error UI
create_button(LV_SYMBOL_WARNING, "Error", btn_click_err, NULL, root_panel);
}
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_WARNING);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
// Macros
create_button(LV_SYMBOL_GPS, "Macro", btn_click_macros, NULL, root_panel);
label = lv_label_create(btn);
lv_label_set_text(label, temp_buffer);
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
lv_obj_add_event_cb(label, update_printer_data_temp, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
lv_obj_add_style(label, &nav_button_text_style, 0);
if (global_config.multi_printer_mode)
{
// Printers
create_button(LV_SYMBOL_HOME, "Printer", btn_click_printer, NULL, root_panel);
}
// Settings
btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, button_width, button_height);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 3);
lv_obj_add_style(btn, &nav_button_style, 0);
lv_obj_add_event_cb(btn, btn_click_macros, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_GPS);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing);
label = lv_label_create(btn);
lv_label_set_text(label, "Macro");
lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing);
lv_obj_add_style(label, &nav_button_text_style, 0);
lv_obj_t * panel = lv_obj_create(lv_scr_act());
lv_obj_set_size(panel, TFT_HEIGHT - button_width, TFT_WIDTH);
lv_obj_t * panel = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, 0, 0);
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);
switch (active_panel){
case 0:
case PANEL_PRINT:
print_panel_init(panel);
break;
case 1:
case PANEL_MOVE:
move_panel_init(panel);
break;
case 2:
case PANEL_TEMP:
temp_panel_init(panel);
break;
case 3:
case PANEL_SETTINGS:
settings_panel_init(panel);
break;
case 4:
case PANEL_MACROS:
macros_panel_init(panel);
break;
case PANEL_STATS:
stats_panel_init(panel);
break;
case PANEL_PRINTER:
printer_panel_init(panel);
break;
case PANEL_ERROR:
error_panel_init(panel);
break;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);
}
void nav_style_setup(){
@@ -186,5 +191,5 @@ void nav_style_setup(){
lv_style_set_radius(&nav_button_style, 0);
lv_style_init(&nav_button_text_style);
lv_style_set_text_font(&nav_button_text_style, &lv_font_montserrat_10);
lv_style_set_text_font(&nav_button_text_style, &CYD_SCREEN_FONT_SMALL);
}

View File

@@ -1,2 +1,13 @@
#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
void nav_buttons_setup(unsigned char active_panel);
void nav_style_setup();

View File

@@ -0,0 +1,103 @@
#include "../lib/ESP32OTAPull.h"
#include "lvgl.h"
#include "ui_utils.h"
#include "../core/lv_setup.h"
#include "../core/data_setup.h"
#include "../conf/global_config.h"
#include "ota_setup.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
ESP32OTAPull ota_pull;
static bool update_available;
static bool ready_for_ota_update = false;
String ota_new_version_name()
{
return ota_pull.GetVersion();
}
bool ota_has_update()
{
return update_available;
}
static int last_callback_time = 0;
lv_obj_t *percentage_bar;
lv_obj_t *update_label;
void do_update_callback(int offset, int totallength)
{
int now = millis();
if (now - last_callback_time < 1000)
{
return;
}
last_callback_time = now;
float percentage = (float)offset / (float)totallength; // 0 -> 1
lv_bar_set_value(percentage_bar, percentage * 100, LV_ANIM_OFF);
lv_label_set_text_fmt(update_label, "%d/%d bytes", offset, totallength);
lv_refr_now(NULL);
lv_timer_handler();
lv_task_handler();
}
void ota_do_update(bool variant_automatic)
{
Serial.println("Starting OTA Update");
lv_obj_clean(lv_scr_act());
lv_obj_t *panel = lv_create_empty_panel(lv_scr_act());
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_obj_align(panel, LV_ALIGN_TOP_LEFT, 0, 0);
lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER);
lv_obj_t *label = lv_label_create(panel);
lv_label_set_text(label, "Updating OTA...");
percentage_bar = lv_bar_create(panel);
lv_obj_set_size(percentage_bar, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * 0.75f);
update_label = lv_label_create(panel);
lv_label_set_text(update_label, "0/0");
if (!variant_automatic) {
Serial.println("Freezing Background Tasks");
screen_timer_wake();
screen_timer_stop();
freeze_request_thread();
}
lv_refr_now(NULL);
lv_timer_handler();
lv_task_handler();
ota_pull.SetCallback(do_update_callback);
ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::UPDATE_AND_BOOT);
}
void ota_init()
{
//ota_pull.AllowDowngrades(true);
int result = ota_pull.CheckForOTAUpdate(ota_url, REPO_VERSION, ESP32OTAPull::ActionType::DONT_DO_UPDATE);
Serial.printf("OTA Update Result: %d\n", result);
update_available = result == ESP32OTAPull::UPDATE_AVAILABLE;
if (global_config.auto_ota_update && update_available)
{
ota_do_update(true);
}
}
void set_ready_for_ota_update()
{
ready_for_ota_update = true;
}
bool is_ready_for_ota_update()
{
return ready_for_ota_update;
}

View File

@@ -0,0 +1,8 @@
#pragma once
String ota_new_version_name();
bool ota_has_update();
void ota_do_update(bool variant_automatic = false);
void ota_init();
void set_ready_for_ota_update();
bool is_ready_for_ota_update();

View File

@@ -0,0 +1,53 @@
#include "panel.h"
#include "../../core/data_setup.h"
#include "../ui_utils.h"
static void btn_click_restart(lv_event_t * e){
send_gcode(false, "RESTART");
}
static void btn_click_firmware_restart(lv_event_t * e){
send_gcode(false, "FIRMWARE_RESTART");
}
void error_panel_init(lv_obj_t* panel)
{
lv_layout_flex_column(panel, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_obj_t * label;
label = lv_label_create(panel);
lv_label_set_text(label, LV_SYMBOL_WARNING " Printer is not ready");
lv_obj_t * panel_with_text = lv_create_empty_panel(panel);
lv_layout_flex_column(panel_with_text, LV_FLEX_ALIGN_START);
lv_obj_set_flex_grow(panel_with_text, 1);
lv_obj_set_width(panel_with_text, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
label = lv_label_create(panel_with_text);
lv_label_set_text(label, printer.state_message);
lv_obj_set_width(label, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_t * button_row = lv_create_empty_panel(panel);
lv_obj_set_size(button_row, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(button_row);
lv_obj_t * btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_click_restart, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
btn = lv_btn_create(button_row);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_click_firmware_restart, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, "FW Restart");
lv_obj_center(label);
}

View File

@@ -1,81 +1,42 @@
#include "lvgl.h"
#include "../macros.h"
#include "panel.h"
#include "../nav_buttons.h"
#include "../../core/data_setup.h"
#include "../../core/macros_query.h"
#include "../../conf/global_config.h"
#include "../ui_utils.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;
nav_buttons_setup(PANEL_SETTINGS);
}
void macros_panel_init(lv_obj_t* panel) {
y_offset_macros = 40;
macros_set_current_config(get_current_printer_config());
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_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_GAP_PX);
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){
POWERQUERY power = power_devices_query();
if (query.count == 0 && power.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);
}
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_PANEL_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);
macros_add_power_devices_to_panel(root_panel, power);
macros_add_macros_to_panel(root_panel, query);
}

View File

@@ -1,47 +1,28 @@
#include "lvgl.h"
#include "panel.h"
#include "../../core/data_setup.h"
#include <TFT_eSPI.h>
#include "../nav_buttons.h"
#include "../ui_utils.h"
#include <stdio.h>
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");
}
const char * space = "%20";
sprintf(gcode, "G1%s%s%s%.1f%sF6000", space, axis, extra, amount, space);
send_gcode(true, gcode);
if (absolute_coords) {
send_gcode(true, "G90");
}
}
static bool last_homing_state = false;
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];
@@ -72,7 +53,7 @@ lv_event_cb_t button_callbacks[] = {x_line_button_press, y_line_button_press, z_
lv_event_cb_t position_callbacks[] = {x_pos_update, y_pos_update, z_pos_update};
const float xy_offsets[] = {-100, -10, -1, 1, 10, 100};
const float z_offsets[] = {-25, -1, -0.1, 0.1, 1, 25};
const float z_offsets[] = {-10, -1, -0.1, 0.1, 1, 10};
const float* offsets[] = {
xy_offsets,
xy_offsets,
@@ -80,7 +61,7 @@ const float* offsets[] = {
};
const char* xy_offset_labels[] = {"-100", "-10", "-1", "+1", "+10", "+100"};
const char* z_offset_labels[] = {"-25", "-1", "-0.1", "+0.1", "+1", "+25"};
const char* z_offset_labels[] = {"-10", "-1", "-0.1", "+0.1", "+1", "+10"};
const char** offset_labels[] = {
xy_offset_labels,
@@ -102,108 +83,117 @@ static void disable_steppers_click(lv_event_t * e) {
send_gcode(true, "M18");
}
static void stepper_state_update(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
lv_label_set_text(label, printer.homed_axis ? LV_SYMBOL_HOME " Steppers locked" : LV_SYMBOL_EYE_CLOSE " Steppers unlocked");
static void switch_to_stat_panel(lv_event_t * e) {
lv_obj_t * panel = lv_event_get_target(e);
nav_buttons_setup(PANEL_STATS);
}
inline void root_panel_steppers_locked(lv_obj_t * root_panel){
const auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
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_SPACE_BETWEEN, 0, 0);
lv_obj_t * home_button_row = lv_create_empty_panel(panel);
lv_obj_set_size(home_button_row, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(home_button_row);
lv_obj_t * btn = lv_btn_create(home_button_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);
lv_obj_set_flex_grow(btn, 1);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_HOME "Home");
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, disable_steppers_click, LV_EVENT_CLICKED, NULL);
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
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++) {
label = lv_label_create(panel);
lv_label_set_text(label, "???");
lv_obj_set_width(label, width);
lv_obj_add_event_cb(label, position_callbacks[row], LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
lv_obj_t * row_panel = lv_create_empty_panel(panel);
lv_obj_set_size(row_panel, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_layout_flex_row(row_panel);
for (int col = 0; col < 6; col++)
{
btn = lv_btn_create(row_panel);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, button_callbacks[row], LV_EVENT_CLICKED, (void*)(offsets[row] + col));
lv_obj_set_flex_grow(btn, 1);
label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[row][col]);
lv_obj_center(label);
}
}
}
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_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);
}
static void root_panel_state_update(lv_event_t * e){
if (last_homing_state == printer.homed_axis)
return;
lv_obj_t * panel = lv_event_get_target(e);
last_homing_state = printer.homed_axis;
lv_obj_clean(panel);
if (printer.homed_axis)
root_panel_steppers_locked(panel);
else
root_panel_steppers_unlocked(panel);
}
void move_panel_init(lv_obj_t* panel){
lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLLABLE);
const int button_size = 40;
const int button_size_vertical = 40;
const int button_padding = 2;
const int x_offset = 15;
int y_pos = 75;
auto panel_width = TFT_HEIGHT - 40;
lv_obj_t * home_button = lv_btn_create(panel);
lv_obj_align(home_button, LV_ALIGN_TOP_LEFT, 10, 5);
lv_obj_add_event_cb(home_button, home_button_click, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(home_button, panel_width / 2 - 15, 30);
lv_obj_t * home_label = lv_label_create(home_button);
lv_label_set_text(home_label, LV_SYMBOL_HOME "Home Axis");
lv_obj_center(home_label);
lv_obj_t * disable_steppers_button = lv_btn_create(panel);
lv_obj_align(disable_steppers_button, LV_ALIGN_TOP_RIGHT, -10, 5);
lv_obj_add_event_cb(disable_steppers_button, disable_steppers_click, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(disable_steppers_button, panel_width / 2 - 15, 30);
lv_obj_t * disable_steppers_label = lv_label_create(disable_steppers_button);
lv_label_set_text(disable_steppers_label, LV_SYMBOL_EYE_CLOSE "Disable Step");
lv_obj_center(disable_steppers_label);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "???");
lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 40);
lv_obj_add_event_cb(label, stepper_state_update, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
for (int i = 0; i < 3; i++) {
lv_obj_t * btn = lv_btn_create(panel);
lv_obj_set_size(btn, button_size, button_size_vertical);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset, y_pos);
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i]));
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[i][0]);
lv_obj_center(label);
btn = lv_btn_create(panel);
lv_obj_set_size(btn, button_size, button_size_vertical);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 1, y_pos);
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 1));
label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[i][1]);
lv_obj_center(label);
btn = lv_btn_create(panel);
lv_obj_set_size(btn, button_size, button_size_vertical);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 2, y_pos);
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 2));
label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[i][2]);
lv_obj_center(label);
btn = lv_btn_create(panel);
lv_obj_set_size(btn, button_size, button_size_vertical);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 3, y_pos);
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 3));
label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[i][3]);
lv_obj_center(label);
btn = lv_btn_create(panel);
lv_obj_set_size(btn, button_size, button_size_vertical);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 4, y_pos);
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 4));
label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[i][4]);
lv_obj_center(label);
btn = lv_btn_create(panel);
lv_obj_set_size(btn, button_size, button_size_vertical);
lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_offset + (button_size + button_padding) * 5, y_pos);
lv_obj_add_event_cb(btn, button_callbacks[i], LV_EVENT_CLICKED, (void*)(offsets[i] + 5));
label = lv_label_create(btn);
lv_label_set_text(label, offset_labels[i][5]);
lv_obj_center(label);
label = lv_label_create(panel);
lv_label_set_text(label, "???");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, x_offset, y_pos - 15);\
lv_obj_add_event_cb(label, position_callbacks[i], LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
y_pos += 60;
if (printer.state == PRINTER_STATE_PRINTING){
stats_panel_init(panel);
return;
}
lv_msg_send(DATA_PRINTER_DATA, &printer);
last_homing_state = !printer.homed_axis;
lv_obj_add_event_cb(panel, root_panel_state_update, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, panel, NULL);
}

View File

@@ -1,4 +1,5 @@
#include "lvgl.h"
#include "../../core/macros_query.h"
#define SIZEOF(arr) (sizeof(arr) / sizeof(*arr))
@@ -8,3 +9,6 @@ void print_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);
void stats_panel_init(lv_obj_t* panel);
void printer_panel_init(lv_obj_t* panel);
void error_panel_init(lv_obj_t* panel);

View File

@@ -4,7 +4,11 @@
#include "../../core/files_query.h"
#include "../../conf/global_config.h"
#include <HardwareSerial.h>
#include <HTTPClient.h>
#include "../ui_utils.h"
#include "../../core/lv_setup.h"
#include "../gcode_img.h"
#include "../../core/http_client.h"
#include <UrlEncode.h>
FILESYSTEM_FILE* selected_file = NULL;
@@ -12,73 +16,64 @@ static void btn_print_file(lv_event_t * e){
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
lv_obj_del(panel);
char* buff = (char*)malloc(128 + (strlen(selected_file->name) * 3));
sprintf(buff, "http://%s:%d/printer/print/start?filename=", global_config.klipperHost, global_config.klipperPort);
SETUP_HTTP_CLIENT("/printer/print/start?filename=" + urlEncode(selected_file->name));
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;
client.begin(buff);
int httpCode = client.POST("");
Serial.printf("Print start: HTTP %d\n", httpCode);
}
static void btn_print_back(lv_event_t * e){
lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e);
lv_obj_del(panel);
}
static void btn_print_file_verify(lv_event_t * e){
const auto button_size_mult = 1.3f;
lv_obj_t * btn = lv_event_get_target(e);
selected_file = (FILESYSTEM_FILE*)lv_event_get_user_data(e);
lv_obj_t * panel = lv_obj_create(lv_scr_act());
lv_obj_set_size(panel, TFT_HEIGHT - 40, TFT_WIDTH - 30);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX * 2, 0);
lv_obj_set_size(panel, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 4, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 3);
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "Print File");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t * label_print_file = lv_label_create(panel);
lv_label_set_text(label_print_file, "Print File");
lv_obj_align(label_print_file, LV_ALIGN_TOP_LEFT, 0, 0);
label = lv_label_create(panel);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, selected_file->name);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -20);
lv_obj_set_width(label, TFT_HEIGHT - 90);
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 10);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
btn = lv_btn_create(panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -10);
lv_obj_set_size(btn, 40, 40);
lv_obj_add_event_cb(btn, btn_print_back, LV_EVENT_CLICKED, panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult);
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, panel);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE);
lv_obj_center(label);
btn = lv_btn_create(panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
lv_obj_set_size(btn, 40, 40);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult);
lv_obj_add_event_cb(btn, btn_print_file, LV_EVENT_CLICKED, panel);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_OK);
lv_obj_center(label);
lv_obj_t* img = show_gcode_img(selected_file->name);
if (img != NULL){
lv_obj_set_parent(img, panel);
lv_obj_align(img, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t * text_center_panel = lv_create_empty_panel(panel);
lv_obj_set_size(text_center_panel, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2, 32);
lv_obj_align(text_center_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX + 32, 0);
lv_obj_set_parent(label_print_file, text_center_panel);
lv_obj_align(label_print_file, LV_ALIGN_LEFT_MID, 0, 0);
}
}
void print_panel_init(lv_obj_t* panel){
@@ -87,18 +82,20 @@ void print_panel_init(lv_obj_t* panel){
return;
}
auto panel_width = TFT_HEIGHT - 40;
auto panel_height_margin = TFT_WIDTH - 10;
auto panel_width_margin = panel_width - 10;
clear_img_mem();
lv_obj_t * list = lv_list_create(panel);
lv_obj_set_size(list, panel_width_margin, panel_height_margin);
lv_obj_set_style_radius(list, 0, 0);
lv_obj_set_style_border_width(list, 0, 0);
lv_obj_set_style_bg_opa(list, LV_OPA_TRANSP, 0);
lv_obj_set_size(list, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_obj_align(list, LV_ALIGN_CENTER, 0, 0);
FILESYSTEM_FILE* files = get_files(25);
int count = 0;
while (files != NULL && files->name != NULL && count <= 20){
lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, files->name);
lv_obj_set_style_bg_opa(btn, LV_OPA_TRANSP, 0);
lv_obj_add_event_cb(btn, btn_print_file_verify, LV_EVENT_CLICKED, (void*)files);
files += 1;

View File

@@ -0,0 +1,299 @@
#include "panel.h"
#include "../../conf/global_config.h"
#include "../../core/data_setup.h"
#include "../ui_utils.h"
#include "../../core/lv_setup.h"
#include <stdio.h>
#include "../nav_buttons.h"
#include "../../core/macros_query.h"
#include "../switch_printer.h"
#include "../macros.h"
const char * printer_status[] = {
"Error",
"Idle",
"Printing",
"Paused"
};
const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} };
static void update_printer_name_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
lv_label_set_text(label, config->printer_name[0] == 0 ? config->klipper_host : config->printer_name);
}
static void update_printer_status_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (config == get_current_printer_config())
{
lv_label_set_text(label, "In Control");
return;
}
if (!printer->online)
{
lv_label_set_text(label, "Offline");
return;
}
lv_label_set_text(label, printer_status[printer->state]);
}
static void update_printer_percentage_bar(lv_event_t * e)
{
lv_obj_t * percentage = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (printer->online && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED)){
lv_bar_set_value(percentage, printer->print_progress * 100, LV_ANIM_OFF);
}
else {
lv_bar_set_value(percentage, 0, LV_ANIM_OFF);
}
}
static void update_printer_percentage_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (printer->online && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED))
{
char percentage_buffer[12];
sprintf(percentage_buffer, "%.2f%%", printer->print_progress * 100);
lv_label_set_text(label, percentage_buffer);
}
else
{
lv_label_set_text(label, "-%");
}
}
static void update_printer_control_button_text(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (!printer->online && printer->power_devices > 0)
{
lv_label_set_text(label, "Power");
}
else
{
lv_label_set_text(label, "Control");
}
}
static void btn_enable_delete(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
if (config == get_current_printer_config())
{
// Disable
lv_obj_add_state(btn, LV_STATE_DISABLED);
}
else
{
// Enable
lv_obj_clear_state(btn, LV_STATE_DISABLED);
}
}
static void btn_enable_control(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (config == get_current_printer_config() || (!printer->online && printer->power_devices <= 0))
{
// Disable
lv_obj_add_state(btn, LV_STATE_DISABLED);
}
else
{
// Enable
lv_obj_clear_state(btn, LV_STATE_DISABLED);
}
}
PRINTER_CONFIG * keyboard_config = NULL;
static void keyboard_callback(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);
const char * text = lv_textarea_get_text(ta);
strcpy(keyboard_config->printer_name, text);
write_global_config();
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
}
static void btn_printer_delete(lv_event_t * e)
{
lv_obj_t * btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
if (config == get_current_printer_config())
{
return;
}
config->ip_configured = false;
write_global_config();
nav_buttons_setup(PANEL_PRINTER);
}
// TODO: Extract this from temp/print panel and combine
static void btn_printer_rename(lv_event_t * e)
{
keyboard_config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
lv_create_keyboard_text_entry(keyboard_callback, LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 24, keyboard_config->printer_name, false);
}
static void btn_printer_activate(lv_event_t * e)
{
lv_obj_t * label = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
PrinterMinimal * printer = &printer_minimal[index];
if (!printer->online)
{
macros_draw_power_fullscreen(config);
return;
}
switch_printer(index);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
}
static void btn_printer_add(lv_event_t * e)
{
set_printer_config_index(get_printer_config_free_index());
}
void create_printer_ui(PRINTER_CONFIG * config, lv_obj_t * root)
{
int index = config - global_config.printer_config;
auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * data_row_name = lv_create_empty_panel(root);
lv_layout_flex_row(data_row_name, LV_FLEX_ALIGN_SPACE_BETWEEN);
lv_obj_set_size(data_row_name, width, LV_SIZE_CONTENT);
lv_obj_t * label = lv_label_create(data_row_name);
lv_obj_add_event_cb(label, update_printer_name_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
label = lv_label_create(data_row_name);
lv_obj_add_event_cb(label, update_printer_status_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
lv_obj_t * progress_row = lv_create_empty_panel(root);
lv_layout_flex_row(progress_row);
lv_obj_set_size(progress_row, width, LV_SIZE_CONTENT);
lv_obj_t * progress_bar = lv_bar_create(progress_row);
lv_obj_set_flex_grow(progress_bar, 1);
lv_obj_add_event_cb(progress_bar, update_printer_percentage_bar, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, progress_bar, config);
label = lv_label_create(progress_row);
lv_obj_set_style_text_font(label, &CYD_SCREEN_FONT_SMALL, 0);
lv_obj_add_event_cb(label, update_printer_percentage_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
lv_obj_t * button_row = lv_create_empty_panel(root);
lv_layout_flex_row(button_row);
lv_obj_set_size(button_row, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * btn = lv_btn_create(button_row);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_printer_delete, LV_EVENT_CLICKED, config);
lv_obj_add_event_cb(btn, btn_enable_delete, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, btn, config);
label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_TRASH);
lv_obj_center(label);
btn = lv_btn_create(button_row);
lv_obj_set_flex_grow(btn, 2);
lv_obj_add_event_cb(btn, btn_printer_rename, LV_EVENT_CLICKED, config);
label = lv_label_create(btn);
lv_label_set_text(label, "Rename");
lv_obj_center(label);
btn = lv_btn_create(button_row);
lv_obj_set_flex_grow(btn, 2);
lv_obj_add_event_cb(btn, btn_printer_activate, LV_EVENT_CLICKED, config);
lv_obj_add_event_cb(btn, btn_enable_control, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, btn, config);
label = lv_label_create(btn);
lv_obj_center(label);
lv_obj_add_event_cb(label, update_printer_control_button_text, LV_EVENT_MSG_RECEIVED, config);
lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config);
lv_obj_t * line = lv_line_create(root);
lv_line_set_points(line, line_points, 2);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
}
void printer_panel_init(lv_obj_t* panel)
{
lv_obj_t * inner_panel = lv_create_empty_panel(panel);
lv_obj_align(inner_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, 0);
lv_obj_set_size(inner_panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_PANEL_HEIGHT_PX);
lv_layout_flex_column(inner_panel);
lv_obj_set_scrollbar_mode(inner_panel, LV_SCROLLBAR_MODE_OFF);
lv_obj_set_size(lv_create_empty_panel(inner_panel), 0, 0);
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG * config = &global_config.printer_config[i];
if (config->ip_configured) {
create_printer_ui(&global_config.printer_config[i], inner_panel);
}
}
// Add Printer Button
if (get_printer_config_free_index() != -1){
lv_obj_t * btn = lv_btn_create(inner_panel);
lv_obj_set_size(btn, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, btn_printer_add, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Add Printer");
lv_obj_center(label);
}
lv_obj_set_size(lv_create_empty_panel(inner_panel), 0, 0);
lv_msg_send(DATA_PRINTER_MINIMAL, NULL);
}

View File

@@ -1,6 +1,7 @@
#include "panel.h"
#include "../../core/data_setup.h"
#include <stdio.h>
#include "../ui_utils.h"
char time_buffer[12];
@@ -47,48 +48,55 @@ static void btn_click_resume(lv_event_t * e){
}
void progress_panel_init(lv_obj_t* panel){
auto panel_width = TFT_HEIGHT - 40;
auto panel_width_margin = panel_width - 30;
auto panel_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3;
const auto button_size_mult = 1.3f;
lv_obj_t * center_panel = lv_create_empty_panel(panel);
lv_obj_align(center_panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(center_panel, panel_width, LV_SIZE_CONTENT);
lv_layout_flex_column(center_panel);
// Filename
lv_obj_t * label = lv_label_create(panel);
lv_obj_t * label = lv_label_create(center_panel);
lv_label_set_text(label, printer.print_filename);
lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_width(label, panel_width_margin);
lv_obj_set_width(label, panel_width);
// Progress Bar
lv_obj_t * bar = lv_bar_create(panel);
lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_size(bar, panel_width_margin, 20);
lv_obj_t * bar = lv_bar_create(center_panel);
lv_obj_set_size(bar, panel_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * 0.75f);
lv_obj_add_event_cb(bar, progress_bar_update, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, bar, NULL);
// Time
lv_obj_t * time_est_panel = lv_create_empty_panel(center_panel);
lv_obj_set_size(time_est_panel, panel_width, LV_SIZE_CONTENT);
// Elapsed Time
label = lv_label_create(panel);
label = lv_label_create(time_est_panel);
lv_label_set_text(label, "???");
lv_obj_align(label, LV_ALIGN_LEFT_MID, 10, 20);
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_add_event_cb(label, update_printer_data_elapsed_time, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
// Remaining Time
label = lv_label_create(panel);
label = lv_label_create(time_est_panel);
lv_label_set_text(label, "???");
lv_obj_align(label, LV_ALIGN_RIGHT_MID, -10, 20);
lv_obj_align(label, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(label, update_printer_data_remaining_time, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
// Percentage
label = lv_label_create(panel);
label = lv_label_create(time_est_panel);
lv_label_set_text(label, "???");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_event_cb(label, update_printer_data_percentage, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
// Stop Button
lv_obj_t * btn = lv_btn_create(panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
lv_obj_set_size(btn, 40, 40);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -1 * CYD_SCREEN_GAP_PX, -1 * CYD_SCREEN_GAP_PX);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult);
lv_obj_add_event_cb(btn, btn_click_stop, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
@@ -98,8 +106,6 @@ void progress_panel_init(lv_obj_t* panel){
// Resume Button
if (printer.state == PRINTER_STATE_PAUSED){
btn = lv_btn_create(panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -60, -10);
lv_obj_set_size(btn, 40, 40);
lv_obj_add_event_cb(btn, btn_click_resume, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
@@ -109,8 +115,6 @@ void progress_panel_init(lv_obj_t* panel){
// Pause Button
else {
btn = lv_btn_create(panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -60, -10);
lv_obj_set_size(btn, 40, 40);
lv_obj_add_event_cb(btn, btn_click_pause, LV_EVENT_CLICKED, NULL);
label = lv_label_create(btn);
@@ -118,5 +122,6 @@ void progress_panel_init(lv_obj_t* panel){
lv_obj_center(label);
}
lv_msg_send(DATA_PRINTER_DATA, &printer);
lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -2 * CYD_SCREEN_GAP_PX - CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, -1 * CYD_SCREEN_GAP_PX);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult);
}

View File

@@ -3,53 +3,68 @@
#include "../../core/screen_driver.h"
#include "../../conf/global_config.h"
#include "../main_ui.h"
#include "../ui_utils.h"
#include <Esp.h>
#include "../../core/lv_setup.h"
#include "../ota_setup.h"
#include "../nav_buttons.h"
#ifndef REPO_VERSION
#define REPO_VERSION "Unknown"
#endif // REPO_VERSION
static void invert_color_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.invertColors = checked;
WriteGlobalConfig();
get_current_printer_config()->invert_colors = checked;
write_global_config();
set_invert_display();
}
static void reset_calibration_click(lv_event_t * e){
global_config.screenCalibrated = false;
WriteGlobalConfig();
global_config.screen_calibrated = false;
write_global_config();
ESP.restart();
}
static void reset_wifi_click(lv_event_t * e){
global_config.wifiConfigured = false;
global_config.ipConfigured = false;
WriteGlobalConfig();
global_config.wifi_configured = false;
write_global_config();
ESP.restart();
}
static void reset_ip_click(lv_event_t * e){
get_current_printer_config()->ip_configured = false;
get_current_printer_config()->auth_configured = false;
write_global_config();
ESP.restart();
}
static void light_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);
global_config.lightMode = checked;
WriteGlobalConfig();
get_current_printer_config()->light_mode = checked;
write_global_config();
set_color_scheme();
}
static void theme_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown);
global_config.color_scheme = selected;
get_current_printer_config()->color_scheme = selected;
set_color_scheme();
WriteGlobalConfig();
write_global_config();
}
const char* brightness_options = "100%\n75%\n50%\n25%";
const char brightness_options_values[] = { 255, 192, 128, 64 };
const unsigned char brightness_options_values[] = { 255, 192, 128, 64 };
static void brightness_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown);
global_config.brightness = brightness_options_values[selected];
set_screen_brightness();
WriteGlobalConfig();
write_global_config();
}
const char* wake_timeout_options = "1m\n2m\n5m\n10m\n15m\n30m\n1h\n2h\n4h";
@@ -58,143 +73,130 @@ const char wake_timeout_options_values[] = { 1, 2, 5, 10, 15, 30, 60, 120, 240
static void wake_timeout_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
auto selected = lv_dropdown_get_selected(dropdown);
global_config.screenTimeout = wake_timeout_options_values[selected];
global_config.screen_timeout = wake_timeout_options_values[selected];
set_screen_timer_period();
WriteGlobalConfig();
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);
global_config.rotateScreen = checked;
global_config.screenCalibrated = false;
WriteGlobalConfig();
global_config.rotate_screen = checked;
global_config.screen_calibrated = false;
write_global_config();
ESP.restart();
}
static void on_during_print_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.onDuringPrint = checked;
global_config.on_during_print = checked;
check_if_screen_needs_to_be_disabled();
WriteGlobalConfig();
write_global_config();
}
int y_offset = 0;
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_ota_do_update(lv_event_t * e){
set_ready_for_ota_update();
}
void create_settings_widget(const char* label_text, lv_obj_t* object, 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);
lv_obj_set_size(panel, panel_width - y_element_x_padding, y_element_size);
static void auto_ota_update_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.auto_ota_update = checked;
write_global_config();
}
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);
static void multi_printer_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.multi_printer_mode = checked;
write_global_config();
nav_buttons_setup(PANEL_SETTINGS);
}
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, label_text);
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
const char* estimated_time_options = "Percentage\nInterpolated\nSlicer";
lv_obj_set_parent(object, panel);
lv_obj_align(object, LV_ALIGN_RIGHT_MID, 0, 0);
y_offset += y_element_size;
static void estimated_time_dropdown(lv_event_t * e){
lv_obj_t * dropdown = lv_event_get_target(e);
get_current_printer_config()->remaining_time_calc_mode = lv_dropdown_get_selected(dropdown);
write_global_config();
}
void settings_panel_init(lv_obj_t* panel){
y_offset = 0;
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);
lv_obj_add_event_cb(btn, reset_wifi_click, LV_EVENT_CLICKED, NULL);
if (global_config.multi_printer_mode)
{
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "Printer Specific Settings");
}
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
lv_create_custom_menu_dropdown("Estimated Time", panel, estimated_time_dropdown, estimated_time_options, get_current_printer_config()->remaining_time_calc_mode);
lv_create_custom_menu_dropdown("Theme", panel, theme_dropdown, "Blue\nGreen\nGrey\nYellow\nOrange\nRed\nPurple", get_current_printer_config()->color_scheme);
create_settings_widget("Configure WiFi", btn, panel);
#ifndef CYD_SCREEN_DISABLE_INVERT_COLORS
lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors);
#endif // CYD_SCREEN_DISABLE_INVERT_COLORS
btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, reset_calibration_click, LV_EVENT_CLICKED, NULL);
lv_create_custom_menu_switch("Light Mode", panel, light_mode_switch, get_current_printer_config()->light_mode);
lv_create_custom_menu_button("Configure IP", panel, reset_ip_click, "Restart");
label = lv_label_create(btn);
lv_label_set_text(label, "Restart");
lv_obj_center(label);
if (global_config.multi_printer_mode)
{
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, "\nGlobal Settings");
}
create_settings_widget("Calibrate Touch", btn, panel);
lv_obj_t * toggle = lv_switch_create(panel);
lv_obj_add_event_cb(toggle, invert_color_switch, LV_EVENT_VALUE_CHANGED, NULL);
if (global_config.invertColors)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Invert Colors", toggle, panel);
toggle = lv_switch_create(panel);
lv_obj_add_event_cb(toggle, light_mode_switch, LV_EVENT_VALUE_CHANGED, NULL);
if (global_config.lightMode)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
create_settings_widget("Light Mode", toggle, panel);
lv_obj_t * 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);
create_settings_widget("Theme", dropdown, panel);
dropdown = lv_dropdown_create(panel);
lv_dropdown_set_options(dropdown, brightness_options);
lv_obj_add_event_cb(dropdown, brightness_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
lv_create_custom_menu_switch("Screen On During Print", panel, on_during_print_switch, global_config.on_during_print);
#endif
int brightness_settings_index = 0;
for (int i = 0; i < SIZEOF(brightness_options_values); i++){
if (brightness_options_values[i] == global_config.brightness){
lv_dropdown_set_selected(dropdown, i);
brightness_settings_index = i;
break;
}
}
create_settings_widget("Brightness", dropdown, panel);
dropdown = lv_dropdown_create(panel);
lv_dropdown_set_options(dropdown, wake_timeout_options);
lv_obj_add_event_cb(dropdown, wake_timeout_dropdown, LV_EVENT_VALUE_CHANGED, NULL);
lv_create_custom_menu_dropdown("Brightness", panel, brightness_dropdown, brightness_options, brightness_settings_index);
#ifndef CYD_SCREEN_DISABLE_TIMEOUT
int wake_timeout_settings_index = 0;
for (int i = 0; i < SIZEOF(wake_timeout_options_values); i++){
if (wake_timeout_options_values[i] == global_config.screenTimeout){
lv_dropdown_set_selected(dropdown, i);
if (wake_timeout_options_values[i] == global_config.screen_timeout){
wake_timeout_settings_index = i;
break;
}
}
create_settings_widget("Wake Timeout", dropdown, panel);
lv_create_custom_menu_dropdown("Wake Timeout", panel, wake_timeout_dropdown, wake_timeout_options, wake_timeout_settings_index);
#endif
toggle = lv_switch_create(panel);
lv_obj_add_event_cb(toggle, rotate_screen_switch, LV_EVENT_VALUE_CHANGED, NULL);
lv_create_custom_menu_switch("Rotate Screen", panel, rotate_screen_switch, global_config.rotate_screen);
lv_create_custom_menu_switch("Multi Printer Mode", panel, multi_printer_switch, global_config.multi_printer_mode);
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 " ");
if (global_config.rotateScreen)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
if (ota_has_update()){
lv_obj_t *btn = lv_btn_create(panel);
lv_obj_add_event_cb(btn, btn_ota_do_update, LV_EVENT_CLICKED, NULL);
create_settings_widget("Rotate Screen", toggle, panel);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text_fmt(label, "Update to %s", ota_new_version_name().c_str());
lv_obj_center(label);
toggle = lv_switch_create(panel);
lv_obj_add_event_cb(toggle, on_during_print_switch, LV_EVENT_VALUE_CHANGED, NULL);
lv_create_custom_menu_entry("Device", btn, panel);
}
else {
lv_create_custom_menu_label("Device", panel, ARDUINO_BOARD " ");
}
if (global_config.onDuringPrint)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
lv_create_custom_menu_button("Calibrate Touch", panel, reset_calibration_click, "Restart");
#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION
create_settings_widget("Screen On During Print", toggle, panel);
lv_create_custom_menu_button("Configure WiFi", panel, reset_wifi_click, "Restart");
}

View File

@@ -0,0 +1,256 @@
#include "panel.h"
#include "../ui_utils.h"
#include "../../core/data_setup.h"
#include <stdio.h>
#include <Esp.h>
static void set_fan_speed_text(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e);
char data[64];
sprintf(data, "Fan: %.0f%%", printer.fan_speed * 100);
lv_label_set_text(label, data);
}
static void set_fan_speed(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
char gcode[64];
sprintf(gcode, "M106 S%d", speed);
send_gcode(true, gcode);
}
const char* fan_speeds[] = { "0%", "15%", "25%", "35%" };
const int fan_speeds_values[] = { 0, 38, 64, 90 };
const char* fan_speeds_2[] = { "50%", "75%", "100%"};
const int fan_speeds_values_2[] = { 128, 192, 255 };
lv_button_column_t fan_speed_columns[] = {
{ set_fan_speed, fan_speeds, (const void**)fan_speeds_values, 4},
{ set_fan_speed, fan_speeds_2, (const void**)fan_speeds_values_2, 3}
};
static void set_zoffset_text(lv_event_t * e) {
lv_obj_t * label = lv_event_get_target(e);
char data[64];
sprintf(data, "Z Offset: %.03f", printer.gcode_offset[2]);
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 MOVE=1", offset);
send_gcode(true, gcode);
}
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_z, zabs, (const void**)zabsvalues, 4}
};
static void set_speed_mult_text(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char data[64];
sprintf(data, "Speed: %.0f%%", printer.speed_mult * 100);
lv_label_set_text(label, data);
}
static void set_speed_mult(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
char gcode[64];
sprintf(gcode, "M220 S%d", speed);
send_gcode(true, gcode);
}
static void set_speed_mult_offset(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
float result = printer.speed_mult * 100 + speed;
printer.speed_mult = result / 100;
char gcode[64];
sprintf(gcode, "M220 S%.0f", result);
send_gcode(true, gcode);
}
const char* speed_presets[] = { "50%", "100%", "150%", "200%" };
const int speed_presets_values[] = { 50, 100, 150, 200 };
const char* speed_presets_minus[] = { "-1%", "-5%", "-10%", "-25%" };
const int speed_presets_minus_values[] = { -1, -5, -10, -25 };
const char* speed_presets_plus[] = { "+1%", "+5%", "+10%", "+25%" };
const int speed_presets_plus_values[] = { 1, 5, 10, 25 };
lv_button_column_t speed_mult_columns[] = {
{ set_speed_mult, speed_presets, (const void**)speed_presets_values, 4},
{ set_speed_mult_offset, speed_presets_minus, (const void**)speed_presets_minus_values, 4},
{ set_speed_mult_offset, speed_presets_plus, (const void**)speed_presets_plus_values, 4}
};
static void set_extrude_mult_text(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char data[64];
sprintf(data, "Flow: %.0f%%", printer.extrude_mult * 100);
lv_label_set_text(label, data);
}
static void set_extrude_mult(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
char gcode[64];
sprintf(gcode, "M221 S%d", speed);
send_gcode(true, gcode);
}
static void set_extrude_mult_offset(lv_event_t * e){
int speed = (int)lv_event_get_user_data(e);
float result = printer.extrude_mult * 100 + speed;
printer.extrude_mult = result / 100;
char gcode[64];
sprintf(gcode, "M221 S%.0f", result);
send_gcode(true, gcode);
}
const char* extrude_presets[] = { "95%", "100%", "105%", "110%" };
const int extrude_presets_values[] = { 95, 100, 105, 110 };
const char* extrude_offset[] = { "+5%", "+1%", "-1%", "-5%" };
const int extrude_offset_values[] = { 5, 1, -1, -5 };
lv_button_column_t extrude_mult_columns[] = {
{ set_extrude_mult, extrude_presets, (const void**)extrude_presets_values, 4},
{ set_extrude_mult_offset, extrude_offset, (const void**)extrude_offset_values, 4}
};
static void open_fan_speed_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_fan_speed_text, fan_speed_columns, 2);
lv_msg_send(DATA_PRINTER_DATA, &printer);
}
static void open_zoffset_panel(lv_event_t * e){
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);
}
static void open_speed_mult_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_speed_mult_text, speed_mult_columns, 3);
lv_msg_send(DATA_PRINTER_DATA, &printer);
}
static void open_extrude_mult_panel(lv_event_t * e){
lv_create_fullscreen_button_matrix_popup(lv_scr_act(), set_extrude_mult_text, extrude_mult_columns, 2);
lv_msg_send(DATA_PRINTER_DATA, &printer);
}
void create_state_button(lv_obj_t * root, lv_event_cb_t label, lv_event_cb_t button){
lv_obj_t * btn = lv_btn_create(root);
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, button, LV_EVENT_CLICKED, NULL);
lv_obj_t * label_obj = lv_label_create(btn);
lv_obj_add_event_cb(label_obj, label, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label_obj, NULL);
lv_obj_align(label_obj, LV_ALIGN_CENTER, 0, 0);
}
static void label_pos(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char x_pos_buff[32];
sprintf(x_pos_buff, "X%.2f Y%.2f", printer.position[0], printer.position[1]);
lv_label_set_text(label, x_pos_buff);
}
static void label_filament_used_m(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char filament_buff[32];
sprintf(filament_buff, "%.2f m", printer.filament_used_mm / 1000);
lv_label_set_text(label, filament_buff);
}
static void label_total_layers(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char layers_buff[32];
sprintf(layers_buff, "%d of %d", printer.current_layer, printer.total_layers);
lv_label_set_text(label, layers_buff);
}
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 (%.2fs)", printer.pressure_advance, printer.smooth_time);
lv_label_set_text(label, pressure_buff);
}
static void label_feedrate(lv_event_t * e){
lv_obj_t * label = lv_event_get_target(e);
char feedrate_buff[32];
sprintf(feedrate_buff, "%d mm/s", printer.feedrate_mm_per_s);
lv_label_set_text(label, feedrate_buff);
}
void create_stat_text_block(lv_obj_t * root, const char* label, lv_event_cb_t value){
lv_obj_t * panel = lv_create_empty_panel(root);
lv_obj_set_size(panel, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_layout_flex_column(panel , LV_FLEX_ALIGN_START, CYD_SCREEN_GAP_PX / 2, CYD_SCREEN_GAP_PX / 2);
lv_obj_set_flex_align(panel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_t * label_obj = lv_label_create(panel);
lv_label_set_text(label_obj, label);
lv_obj_set_style_text_font(label_obj, &CYD_SCREEN_FONT_SMALL, 0);
lv_obj_t * value_obj = lv_label_create(panel);
lv_obj_add_event_cb(value_obj, value, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subscribe_obj(DATA_PRINTER_DATA, value_obj, NULL);
}
void stats_panel_init(lv_obj_t* panel) {
auto panel_width = CYD_SCREEN_PANEL_WIDTH_PX / 2 - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * left_panel = lv_create_empty_panel(panel);
lv_obj_set_size(left_panel, panel_width, CYD_SCREEN_PANEL_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
lv_layout_flex_column(left_panel);
lv_obj_set_flex_align(left_panel, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
lv_obj_align(left_panel, LV_ALIGN_TOP_LEFT, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_clear_flag(left_panel, LV_OBJ_FLAG_SCROLLABLE);
create_stat_text_block(left_panel, "Position:", label_pos);
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);
lv_obj_t * right_panel = lv_create_empty_panel(panel);
lv_obj_set_size(right_panel, panel_width, CYD_SCREEN_PANEL_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2);
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);
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);
create_state_button(right_panel, set_extrude_mult_text, open_extrude_mult_panel);
}

View File

@@ -2,6 +2,7 @@
#include "../../core/data_setup.h"
#include "../../conf/global_config.h"
#include <HardwareSerial.h>
#include "../ui_utils.h"
enum temp_target{
TARGET_HOTEND,
@@ -35,17 +36,17 @@ static void update_printer_data_bed_temp(lv_event_t * e){
static short get_temp_preset(int target){
switch (target){
case TARGET_HOTEND_CONFIG_1:
return global_config.hotend_presets[0];
return get_current_printer_config()->hotend_presets[0];
case TARGET_HOTEND_CONFIG_2:
return global_config.hotend_presets[1];
return get_current_printer_config()->hotend_presets[1];
case TARGET_HOTEND_CONFIG_3:
return global_config.hotend_presets[2];
return get_current_printer_config()->hotend_presets[2];
case TARGET_BED_CONFIG_1:
return global_config.bed_presets[0];
return get_current_printer_config()->bed_presets[0];
case TARGET_BED_CONFIG_2:
return global_config.bed_presets[1];
return get_current_printer_config()->bed_presets[1];
case TARGET_BED_CONFIG_3:
return global_config.bed_presets[2];
return get_current_printer_config()->bed_presets[2];
default:
return -1;
}
@@ -61,16 +62,14 @@ static void update_temp_preset_label(lv_event_t * e){
}
void UpdateConfig(){
WriteGlobalConfig();
write_global_config();
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);
@@ -79,74 +78,51 @@ static void keyboard_callback(lv_event_t * e){
}
char gcode[64];
const char* space = "%20";
switch (keyboard_target){
case TARGET_HOTEND:
sprintf(gcode, "M104%sS%d", space, temp);
sprintf(gcode, "M104 S%d", temp);
send_gcode(true, gcode);
break;
case TARGET_BED:
sprintf(gcode, "M140%sS%d", space, temp);
sprintf(gcode, "M140 S%d", temp);
send_gcode(true, gcode);
break;
case TARGET_HOTEND_CONFIG_1:
global_config.hotend_presets[0] = temp;
get_current_printer_config()->hotend_presets[0] = temp;
UpdateConfig();
break;
case TARGET_HOTEND_CONFIG_2:
global_config.hotend_presets[1] = temp;
get_current_printer_config()->hotend_presets[1] = temp;
UpdateConfig();
break;
case TARGET_HOTEND_CONFIG_3:
global_config.hotend_presets[2] = temp;
get_current_printer_config()->hotend_presets[2] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_1:
global_config.bed_presets[0] = temp;
get_current_printer_config()->bed_presets[0] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_2:
global_config.bed_presets[1] = temp;
get_current_printer_config()->bed_presets[1] = temp;
UpdateConfig();
break;
case TARGET_BED_CONFIG_3:
global_config.bed_presets[2] = temp;
get_current_printer_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);
lv_create_keyboard_text_entry(keyboard_callback);
}
static void show_keyboard_with_bed(lv_event_t * e){
keyboard_target = TARGET_BED;
show_keyboard(e);
lv_create_keyboard_text_entry(keyboard_callback);
}
static void cooldown_temp(lv_event_t * e){
@@ -154,8 +130,8 @@ static void cooldown_temp(lv_event_t * e){
return;
}
send_gcode(true, "M104%20S0");
send_gcode(true, "M140%20S0");
send_gcode(true, "M104 S0");
send_gcode(true, "M140 S0");
}
static void btn_extrude(lv_event_t * e){
@@ -164,7 +140,7 @@ static void btn_extrude(lv_event_t * e){
}
send_gcode(true, "M83");
send_gcode(true, "G1%20E25%20F300");
send_gcode(true, "G1 E25 F300");
}
static void set_temp_via_preset(lv_event_t * e){
@@ -173,16 +149,15 @@ static void set_temp_via_preset(lv_event_t * e){
if (edit_mode) {
keyboard_target = (temp_target)target;
show_keyboard(e);
lv_create_keyboard_text_entry(keyboard_callback);
return;
}
char gcode[64];
const char* space = "%20";
if (target <= TARGET_HOTEND_CONFIG_3)
sprintf(gcode, "M104%sS%d", space, value);
sprintf(gcode, "M104 S%d", value);
else
sprintf(gcode, "M140%sS%d", space, value);
sprintf(gcode, "M140 S%d", value);
send_gcode(true, gcode);
}
@@ -199,109 +174,208 @@ static void btn_retract(lv_event_t * e){
}
send_gcode(true, "M83");
send_gcode(true, "G1%20E-25%20F300");
send_gcode(true, "G1 E-25 F300");
}
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);
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 create_charts(lv_obj_t * root)
{
const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * chart = lv_chart_create(root);
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);
}
void create_temp_buttons(lv_obj_t * root, lv_obj_t * panel)
{
const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
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);
lv_layout_flex_column(temp_rows[tempIter]);
lv_obj_set_size(temp_rows[tempIter], element_width, LV_SIZE_CONTENT);
lv_obj_t * label = lv_label_create(temp_rows[tempIter]);
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_obj_add_event_cb(label, (tempIter == 0) ? update_printer_data_hotend_temp : update_printer_data_bed_temp, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL);
lv_obj_set_width(label, element_width);
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);
button_temp_rows[tempIter] = lv_create_empty_panel(temp_rows[tempIter]);
lv_layout_flex_row(button_temp_rows[tempIter], LV_FLEX_ALIGN_SPACE_EVENLY);
lv_obj_set_size(button_temp_rows[tempIter], element_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
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);
for (int buttonIter = 0; buttonIter < 3; buttonIter++){
lv_obj_t * btn = lv_btn_create(button_temp_rows[tempIter]);
lv_obj_add_event_cb(btn, set_temp_via_preset, LV_EVENT_CLICKED, reinterpret_cast<void*>(TARGET_HOTEND_CONFIG_1 + buttonIter + tempIter * 3));
lv_obj_set_flex_grow(btn, 1);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
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_obj_add_event_cb(label, update_temp_preset_label, LV_EVENT_MSG_RECEIVED, reinterpret_cast<void*>(TARGET_HOTEND_CONFIG_1 + buttonIter + tempIter * 3));
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);
lv_obj_t * btn = lv_btn_create(button_temp_rows[tempIter]);
lv_obj_add_event_cb(btn, (tempIter == 0) ? show_keyboard_with_hotend : show_keyboard_with_bed, LV_EVENT_CLICKED, panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(btn);
lv_label_set_text(label, "Cooldown");
lv_label_set_text(label, "Set");
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);
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;
label = lv_label_create(btn);
lv_label_set_text(label, "Edit Presets");
lv_obj_center(label);
lv_obj_t * root_temp_panel = lv_create_empty_panel(panel);
lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_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);
btn = lv_btn_create(panel);
lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -5);
#ifndef CYD_SCREEN_NO_TEMP_SCROLL
create_charts(root_temp_panel);
lv_obj_t * single_screen_panel = lv_create_empty_panel(root_temp_panel);
lv_obj_set_size(single_screen_panel, element_width, CYD_SCREEN_PANEL_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2 - CYD_SCREEN_GAP_PX / 2);
lv_layout_flex_column(single_screen_panel);
#else
lv_obj_clear_flag(root_temp_panel, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_t * single_screen_panel = root_temp_panel;
#endif
create_temp_buttons(single_screen_panel, panel);
#ifdef CYD_SCREEN_NO_TEMP_SCROLL
create_charts(single_screen_panel);
#else
lv_obj_t * gap = lv_create_empty_panel(single_screen_panel);
lv_obj_set_flex_grow(gap, 1);
#endif
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_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);
lv_obj_set_size(btn, panel_width / 2 - 15, 40);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(btn);
lv_obj_t * 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);
btn = lv_btn_create(one_above_bottom_panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_retract, LV_EVENT_CLICKED, NULL);
lv_obj_set_size(btn, panel_width / 2 - 15, 40);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
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);
btn = lv_btn_create(bottom_panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, cooldown_temp, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(btn);
lv_label_set_text(label, "Cooldown");
lv_obj_center(label);
btn = lv_btn_create(one_above_bottom_panel);
lv_obj_set_flex_grow(btn, 1);
lv_obj_add_event_cb(btn, btn_toggleable_edit, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
label = lv_label_create(btn);
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);
}

View File

@@ -0,0 +1,93 @@
#include "switch_printer.h"
#include "lvgl.h"
#include "../conf/global_config.h"
#include "ui_utils.h"
#include "../core/http_client.h"
#include "../core/lv_setup.h"
#include "../core/macros_query.h"
#include "../core/screen_driver.h"
void switch_printer(int index)
{
set_printer_config_index(index);
set_color_scheme();
set_invert_display();
}
static void btn_switch_printer(lv_event_t *e){
lv_obj_t *btn = lv_event_get_target(e);
PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e);
int index = config - global_config.printer_config;
switch_printer(index);
lv_obj_del(lv_obj_get_parent(lv_obj_get_parent(btn)));
}
void switch_printer_init() {
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(parent, LV_OPA_100, 0);
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
lv_layout_flex_column(parent);
lv_obj_set_size(lv_create_empty_panel(parent), 0, 0);
auto width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2;
lv_obj_t * btn = lv_btn_create(parent);
lv_obj_set_size(btn, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, parent);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE " Close");
lv_obj_center(label);
for (int i = 0; i < PRINTER_CONFIG_COUNT; i++){
PRINTER_CONFIG * config = &global_config.printer_config[i];
const char* printer_name = (config->printer_name[0] == 0) ? config->klipper_host : config->printer_name;
if (config == get_current_printer_config())
{
lv_create_custom_menu_label(printer_name, parent, "Active");
continue;
}
if (config->ip_configured) {
HTTPClient client;
configure_http_client(client, get_full_url("/printer/objects/query?webhooks&print_stats&virtual_sdcard", config), true, 1000);
int httpCode = client.GET();
if (httpCode == 200)
{
lv_create_custom_menu_button(printer_name, parent, btn_switch_printer, "Switch", config);
}
else
{
lv_create_custom_menu_label(printer_name, parent, "Offline");
}
}
}
}
static void show_switch_printer_screen(lv_event_t * e){
switch_printer_init();
}
void draw_switch_printer_button()
{
if (!global_config.multi_printer_mode)
{
return;
}
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_add_event_cb(btn, show_switch_printer_screen, LV_EVENT_CLICKED, NULL);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_HOME);
lv_obj_center(label);
}

View File

@@ -0,0 +1,5 @@
#pragma once
void switch_printer(int index);
void switch_printer_init();
void draw_switch_printer_button();

View File

@@ -0,0 +1,250 @@
#include "lvgl.h"
#include "ui_utils.h"
#include "../core/data_setup.h"
#include "../core/lv_setup.h"
#include <ErriezCRC32.h>
lv_obj_t* lv_create_empty_panel(lv_obj_t* root) {
lv_obj_t* panel = lv_obj_create(root);
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);
return panel;
}
void lv_layout_flex_column(lv_obj_t* obj, lv_flex_align_t allign, lv_coord_t pad_column, lv_coord_t pad_row){
lv_obj_set_layout(obj, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN);
lv_obj_set_flex_align(obj, allign, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_column(obj, pad_column, 0);
lv_obj_set_style_pad_row(obj, pad_row, 0);
}
void lv_layout_flex_row(lv_obj_t* obj, lv_flex_align_t allign, lv_coord_t pad_column, lv_coord_t pad_row){
lv_obj_set_layout(obj, LV_LAYOUT_FLEX);
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(obj, allign, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_pad_column(obj, pad_column, 0);
lv_obj_set_style_pad_row(obj, pad_row, 0);
}
void destroy_event_user_data(lv_event_t * e){
lv_obj_t * obj = (lv_obj_t *)lv_event_get_user_data(e);
lv_obj_del(obj);
}
void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t title, lv_button_column_t* columns, int column_count){
const auto full_panel_width = CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 3;
const auto full_panel_inner_width = full_panel_width - CYD_SCREEN_GAP_PX * 2 - 4;
const auto full_panel_height = CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX;
const auto full_panel_inner_height = full_panel_height - CYD_SCREEN_GAP_PX * 2 - 4;
auto column_width = full_panel_inner_width / column_count - CYD_SCREEN_GAP_PX;
auto column_height = full_panel_inner_height - CYD_SCREEN_GAP_PX - CYD_SCREEN_MIN_BUTTON_HEIGHT_PX;
lv_obj_t * panel = lv_obj_create(root);
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0);
lv_obj_set_size(panel, full_panel_width, full_panel_height);
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_t * top_menu_row = lv_create_empty_panel(panel);
lv_obj_set_size(top_menu_row, full_panel_inner_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(top_menu_row, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_t * btn = lv_btn_create(top_menu_row);
lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(btn, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(btn, destroy_event_user_data, LV_EVENT_CLICKED, panel);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, LV_SYMBOL_CLOSE);
lv_obj_center(label);
label = lv_label_create(top_menu_row);
lv_label_set_text(label, "-");
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_add_event_cb(label, title, LV_EVENT_MSG_RECEIVED, NULL);
lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL);
lv_obj_t * rows = lv_create_empty_panel(panel);
lv_obj_set_size(rows, full_panel_inner_width, column_height);
lv_obj_align(rows, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_layout_flex_row(rows, LV_FLEX_ALIGN_SPACE_BETWEEN, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
for (int i = 0; i < column_count; i++){
lv_obj_t * column = lv_create_empty_panel(rows);
lv_obj_clear_flag(column, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(column, column_width, column_height);
lv_layout_flex_column(column, LV_FLEX_ALIGN_CENTER, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
for (int j = 0; j < columns[i].length; j++){
lv_obj_t * btn = lv_btn_create(column);
lv_obj_set_size(btn, column_width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_add_event_cb(btn, columns[i].event, LV_EVENT_CLICKED, (void*)columns[i].data[j]);
label = lv_label_create(btn);
lv_label_set_text(label, columns[i].labels[j]);
lv_obj_center(label);
}
}
}
void lv_keyboard_text_entry_close(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_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY)
{
lv_keyboard_set_textarea(kb, NULL);
lv_obj_del(lv_obj_get_parent(kb));
}
}
void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, lv_keyboard_mode_t keyboard_mode, lv_coord_t width, uint8_t max_length, const char* fill_text, bool contain_in_panel)
{
lv_obj_t * parent = lv_create_empty_panel(lv_scr_act());
lv_obj_set_style_bg_opa(parent, LV_OPA_50, 0);
lv_obj_align(parent, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_layout_flex_column(parent, LV_FLEX_ALIGN_SPACE_BETWEEN);
if (contain_in_panel)
{
lv_obj_set_size(parent, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX);
}
else
{
lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX);
}
lv_obj_t * empty_panel = lv_create_empty_panel(parent);
lv_obj_set_flex_grow(empty_panel, 1);
lv_obj_t * ta = lv_textarea_create(parent);
lv_obj_t * keyboard = lv_keyboard_create(parent);
lv_obj_set_width(ta, width);
lv_textarea_set_max_length(ta, max_length);
lv_textarea_set_one_line(ta, true);
lv_textarea_set_text(ta, fill_text);
lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_READY, keyboard);
lv_obj_add_event_cb(ta, lv_keyboard_text_entry_close, LV_EVENT_ALL, keyboard);
lv_keyboard_set_mode(keyboard, keyboard_mode);
lv_keyboard_set_textarea(keyboard, ta);
}
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 lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height)
{
lv_obj_t * panel = lv_create_empty_panel(root_panel);
lv_layout_flex_row(panel, LV_FLEX_ALIGN_END);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 3, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * label = lv_label_create(panel);
lv_label_set_text(label, label_text);
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_flex_grow(label, 1);
lv_obj_set_parent(object, panel);
if (set_height)
lv_obj_set_height(object, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_t * line = lv_line_create(root_panel);
lv_line_set_points(line, line_points, 2);
lv_obj_set_style_line_width(line, 1, 0);
lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0);
}
#define DROPDOWN_WIDTH CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 3.75
#define TOGGLE_WIDTH CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2
void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data)
{
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_add_event_cb(btn, on_click, LV_EVENT_CLICKED, user_data);
lv_obj_t * label = lv_label_create(btn);
lv_label_set_text(label, btn_text);
lv_obj_center(label);
lv_create_custom_menu_entry(label_text, btn, root_panel, true);
}
void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data)
{
lv_obj_t * toggle = lv_switch_create(lv_scr_act());
lv_obj_add_event_cb(toggle, on_toggle, LV_EVENT_VALUE_CHANGED, user_data);
lv_obj_set_width(toggle, TOGGLE_WIDTH);
if (state)
lv_obj_add_state(toggle, LV_STATE_CHECKED);
lv_create_custom_menu_entry(label_text, toggle, root_panel, true);
}
void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data)
{
lv_obj_t * dropdown = lv_dropdown_create(lv_scr_act());
lv_dropdown_set_options(dropdown, options);
lv_dropdown_set_selected(dropdown, index);
lv_obj_set_width(dropdown, DROPDOWN_WIDTH);
lv_obj_add_event_cb(dropdown, on_change, LV_EVENT_VALUE_CHANGED, user_data);
lv_create_custom_menu_entry(label_text, dropdown, root_panel, true);
}
void lv_create_custom_menu_label(const char *label_text, lv_obj_t* root_panel, const char *text)
{
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, text);
lv_create_custom_menu_entry(label_text, label, root_panel, false);
}
uint32_t message_hash = 0;
lv_timer_t* timer = NULL;
void on_timer_destroy(lv_event_t * e)
{
lv_timer_del(timer);
timer = NULL;
}
void timer_callback(lv_timer_t *timer)
{
lv_obj_t * panel = (lv_obj_t *)timer->user_data;
lv_obj_del(panel);
}
void lv_create_popup_message(const char* message, uint16_t timeout_ms)
{
if (message == nullptr || timer != NULL)
{
return;
}
uint32_t new_hash = crc32String(message);
if (new_hash == message_hash)
{
return;
}
message_hash = new_hash;
lv_obj_t* panel = lv_obj_create(lv_scr_act());
lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER);
lv_obj_align(panel, LV_ALIGN_TOP_RIGHT, -CYD_SCREEN_GAP_PX, CYD_SCREEN_GAP_PX);
lv_obj_add_event_cb(panel, on_timer_destroy, LV_EVENT_DELETE, NULL);
lv_obj_set_style_border_color(panel, lv_color_hex(0xFF0000), 0);
lv_obj_t* label = lv_label_create(panel);
lv_label_set_text_fmt(label, "%s", message);
lv_obj_set_size(label, CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 6, LV_SIZE_CONTENT);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
timer = lv_timer_create(timer_callback, timeout_ms, panel);
}

View File

@@ -0,0 +1,47 @@
#pragma once
#ifdef CYD_SCREEN_VERTICAL
#ifndef CYD_SCREEN_WIDTH_PX
#define CYD_SCREEN_WIDTH_PX LCD_WIDTH
#endif
#ifndef CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_HEIGHT_PX LCD_HEIGHT
#endif
#define CYD_SCREEN_PANEL_HEIGHT_PX \
(CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_SIDEBAR_SIZE_PX)
#define CYD_SCREEN_PANEL_WIDTH_PX CYD_SCREEN_WIDTH_PX
#else
#ifndef CYD_SCREEN_WIDTH_PX
#define CYD_SCREEN_WIDTH_PX LCD_HEIGHT
#endif
#ifndef CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_HEIGHT_PX LCD_WIDTH
#endif
#define CYD_SCREEN_PANEL_HEIGHT_PX CYD_SCREEN_HEIGHT_PX
#define CYD_SCREEN_PANEL_WIDTH_PX \
(CYD_SCREEN_WIDTH_PX - CYD_SCREEN_SIDEBAR_SIZE_PX)
#endif
typedef struct {
lv_event_cb_t event;
const char** labels;
const void** data;
int length;
} lv_button_column_t;
lv_obj_t* lv_create_empty_panel(lv_obj_t* root);
void lv_layout_flex_column(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN_START, lv_coord_t pad_column = CYD_SCREEN_GAP_PX, lv_coord_t pad_row = CYD_SCREEN_GAP_PX);
void lv_layout_flex_row(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN_START, lv_coord_t pad_column = CYD_SCREEN_GAP_PX, lv_coord_t pad_row = CYD_SCREEN_GAP_PX);
void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t title, lv_button_column_t* columns, int column_count);
void destroy_event_user_data(lv_event_t * e);
void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, lv_keyboard_mode_t keyboard_mode = LV_KEYBOARD_MODE_NUMBER, lv_coord_t width = CYD_SCREEN_PANEL_WIDTH_PX / 2, uint8_t max_length = 3, const char* fill_text = "", bool contain_in_panel= true);
void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true);
void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data = NULL);
void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data = NULL);
void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data = NULL);
void lv_create_custom_menu_label(const char *label_text, lv_obj_t* root_panel, const char *text);
void lv_create_popup_message(const char* message, uint16_t timeout_ms);

View File

@@ -1,15 +1,16 @@
#include "lvgl.h"
#include "wifi_setup.h"
#include "../conf/global_config.h"
#include "ui_utils.h"
#include "WiFi.h"
void wifi_init_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.wifiConfigured = false;
global_config.wifi_configured = false;
wifi_init_inner();
}
}
@@ -32,9 +33,9 @@ static void ta_event_cb(lv_event_t * e) {
int len = strlen(txt);
if (len > 0)
{
global_config.wifiConfigured = true;
strcpy(global_config.wifiPassword, txt);
WriteGlobalConfig();
global_config.wifi_configured = true;
strcpy(global_config.wifi_password, txt);
write_global_config();
wifi_init_inner();
}
}
@@ -47,18 +48,28 @@ static void ta_event_cb(lv_event_t * e) {
void wifi_pass_entry(const char* ssid){
lv_obj_clean(lv_scr_act());
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Enter WiFi Password");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10 + 2);
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 * passEntry = lv_textarea_create(lv_scr_act());
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 WiFi Password");
lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_t * passEntry = lv_textarea_create(top_root);
lv_textarea_set_one_line(passEntry, true);
lv_textarea_set_text(passEntry, "");
lv_obj_align(passEntry, LV_ALIGN_TOP_LEFT, 10, 40);
lv_obj_set_width(passEntry, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_add_event_cb(passEntry, ta_event_cb, LV_EVENT_ALL, NULL);
lv_obj_set_size(passEntry, TFT_HEIGHT - 20, 60);
lv_obj_set_flex_grow(passEntry, 1);
lv_obj_t * keyboard = lv_keyboard_create(lv_scr_act());
lv_obj_t * keyboard = lv_keyboard_create(root);
lv_keyboard_set_textarea(keyboard, passEntry);
}
@@ -68,27 +79,27 @@ static void wifi_btn_event_handler(lv_event_t * e){
if(code == LV_EVENT_CLICKED) {
delay(100);
char* ssid = (char*)e->user_data;
strcpy(global_config.wifiSSID, ssid);
strcpy(global_config.wifi_SSID, ssid);
Serial.println(ssid);
wifi_pass_entry(ssid);
}
}
void wifi_init_inner(){
WiFi.disconnect();
lv_obj_clean(lv_scr_act());
if (global_config.wifiConfigured){
WiFi.begin(global_config.wifiSSID, global_config.wifiPassword);
if (global_config.wifi_configured){
WiFi.begin(global_config.wifi_SSID, global_config.wifi_password);
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Connecting to WiFi");
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_add_event_cb(resetBtn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL);
lv_obj_set_height(resetBtn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
lv_obj_align(resetBtn, LV_ALIGN_CENTER, 0, CYD_SCREEN_GAP_PX + CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(resetBtn);
lv_label_set_text(label, "Reset");
@@ -107,21 +118,29 @@ void wifi_init_inner(){
lv_obj_clean(lv_scr_act());
lv_obj_t * refreshBtn = lv_btn_create(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_set_style_pad_all(root, CYD_SCREEN_GAP_PX, 0);
lv_obj_t * top_row = lv_create_empty_panel(root);
lv_obj_set_size(top_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT);
lv_layout_flex_row(top_row, LV_FLEX_ALIGN_SPACE_BETWEEN);
label = lv_label_create(top_row);
lv_label_set_text(label, "Select a network");
lv_obj_t * refreshBtn = lv_btn_create(top_row);
lv_obj_add_event_cb(refreshBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(refreshBtn, LV_ALIGN_TOP_RIGHT, -5, 5 - 1);
lv_obj_set_size(refreshBtn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX);
label = lv_label_create(refreshBtn);
lv_label_set_text(label, LV_SYMBOL_REFRESH);
lv_obj_center(label);
label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Select a network");
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10 + 2);
lv_obj_t * list = lv_list_create(lv_scr_act());
lv_obj_align(list, LV_ALIGN_TOP_LEFT, 10, 40);
lv_obj_set_size(list, TFT_HEIGHT - 20, TFT_WIDTH - 40 - 5);
lv_obj_t * list = lv_list_create(root);
lv_obj_set_width(list, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2);
lv_obj_set_flex_grow(list, 1);
int n = WiFi.scanNetworks();
@@ -161,7 +180,7 @@ void wifi_init(){
WiFi.mode(WIFI_STA);
wifi_init_inner();
while (!global_config.wifiConfigured || WiFi.status() != WL_CONNECTED){
while (!global_config.wifi_configured || WiFi.status() != WL_CONNECTED){
if (millis() - print_timer > print_freq){
print_timer = millis();
Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]);

View File

@@ -14,12 +14,15 @@ A ESP32-2432S028R is required to run this project. You can find out where to buy
### Features
- View printer status
- View print progress
- View print progress and print statistics
- Start a print
- Move the printer
- (When the printer is idle) move the printer
- (During a print) set fan speed, flow rate, speed and z offset
- Manage temperature
- Extrude/Retract filament
- Execute predefined gcode macros
- Toggle Moonraker power devices
- OTA updates
### Install
@@ -27,18 +30,28 @@ A ESP32-2432S028R is required to run this project. You can find out where to buy
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.
When there is an update available, a button in the settings will appear that can be pressed to update. If automatic updates are preferred, there is a toggle in the settings to automatically update. This will right after connecting to wifi update the screen.
### Donate
If you found this project helpful, please consider a donation [to my Ko-Fi](https://ko-fi.com/suchmememanyskill). It would help out a lot in the development of this project, due to the need to buy the screens.
Thank you!
### Screenshots
(Quite literally shots of the screen. I'm sorry)
-|-
:-:|:-:
![1](readme/PXL_20231113_142717308.jpg)|![2](readme/PXL_20231113_171701876.jpg)
![3](readme/PXL_20231113_171715809.jpg)|![4](readme/PXL_20231113_171724404.jpg)
![5](readme/PXL_20231113_171751745.jpg)|![6](readme/PXL_20231113_171809315.jpg)
![1](readme/1.jpg)|![2](readme/2.jpg)
![3](readme/3.jpg)|![4](readme/4.jpg)
![5](readme/5.jpg)|![6](readme/6.jpg)
![7](readme/7.jpg)|![8](readme/8.jpg)
![9](readme/9.jpg)|![10](readme/10.jpg)
### Credits
- [xtouch](https://github.com/xperiments-in/xtouch)
- [ESP32-Cheap-Yellow-Display](https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display)
- [OperatorB](https://github.com/OperatorB) for the ESP32-3248S035C display driver
- [esp32-smartdisplay](https://github.com/rzeldent/esp32-smartdisplay)

View File

@@ -8,26 +8,94 @@
font-family: 'Roboto', sans-serif;
}
body {
background-color: #181a1b;
color: white;
}
.main {
width: fit-content;
margin: auto;
max-width: 750px;
}
.main > section > :not(:first-child) {
margin-left: 20px;
}
.main a {
color: #F44;
}
.install {
margin-bottom: 300px;
}
.install .iconify {
color: green;
filter: drop-shadow(0 0 0.75rem lime);
}
#changelog-body {
white-space: break-spaces;
}
</style>
<script type="module" src="https://unpkg.com/esp-web-tools@9/dist/web/install-button.js?module"></script>
<script src="//code.iconify.design/1/1.0.6/iconify.min.js"></script>
<script>
async function fetchChangelog() {
const response = await fetch("https://api.github.com/repos/suchmememanyskill/CYD-Klipper/releases/latest");
const data = await response.json();
document.getElementById("changelog-body").innerText = data.body;
document.getElementById("changelog-header-version").innerText += data.tag_name;
}
function setInstallButton(esp){
document.getElementById("install-btn").innerHTML = `<esp-web-install-button manifest="https://suchmememanyskill.github.io/CYD-Klipper/${esp}.json"></esp-web-install-button>`;
}
function setInstallButtonDefault(){
setInstallButton("esp32-2432S028R")
}
fetchChangelog();
window.onload = setInstallButtonDefault;
</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>
<a href="https://ko-fi.com/suchmememanyskill"><img alt="Donate KoFi" src="https://img.shields.io/badge/Support%2FDonate%20On-Ko%20Fi-red"></a>
<h2>CYD-Klipper <span class="iconify" data-icon="mdi-printer-3d" style="color: #F44;"></span></h2>
<p>An implementation of a Klipper status display on an ESP32 + screen.<br>Uses Moonraker to fetch data.<br><a href="https://github.com/suchmememanyskill/CYD-Klipper">Source code is available on GitHub</a>.</p>
<section class="changelog">
<h3 id="changelog-header"><span class="iconify" data-icon="mdi-hammer-wrench" style="color: lightgray;"></span> Changelog <span id="changelog-header-version"></span></h3>
<p id="changelog-body"></p>
</section>
<section class="donate">
<h3><span class="iconify" data-icon="mdi-heart" style="color:orangered; filter: drop-shadow(0 0 0.75rem crimson);"></span> Donate</h3>
<p>If you found this project helpful, please consider a donation to <a href="https://ko-fi.com/suchmememanyskill">my Ko-Fi</a>.<br>It would help out a lot in the development of this project, due to the need to buy the screens.<br>Thank you!</p>
</section>
<section class="issues">
<h3><span class="iconify" data-icon="mdi-github" style="color: white; filter: drop-shadow(0 0 0.75rem gray);"></span> Report Issues</h3>
<p>If you experience any issues with this project, or any feature requests for the project, please report them on the <a href="https://github.com/suchmememanyskill/CYD-Klipper/issues">issues tab on Github</a>.</p>
</section>
<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>
<h3><span class="iconify" data-icon="mdi-download"></span> Install</h3>
<p>Select your device from the list below and click 'Connect'.<br>Note: You may need to hold the 'BOOT' button on the device while pressing install.<br>The 2.8" Resistive and 3.5" Capacitive models are best suited (in my opinion) for CYD-Klipper.</p>
<select id="select-install-btn" onchange="setInstallButton(getElementById('select-install-btn').value)">
<option value="esp32-2432S024C-SD">ESP32-2432S024 (2.4" Capacitive)</option>
<option selected value="esp32-2432S028R">ESP32-2432S028 (2.8" Resistive)</option>
<option value="esp32-2432S032C-SD">ESP32-2432S032 (3.2" Capacitive)</option>
<option value="esp32-3248S035C">ESP32-3248S035 (3.5" Capacitive)</option>
<option value="esp32-3248S035C-V">ESP32-3248S035 (3.5" Capacitive) Vertical Orientation</option>
<option value="esp32-4827S043C-SD">ESP32-4827S043 (4.3" 480x270 Capacitive)</option>
<option value="esp32-8048S043C-SD">ESP32-8048S043 (4.3" 800x480 Capacitive)</option>
</select>
<span id="install-btn"></span>
</section>
</section>
</body>

View File

@@ -1,27 +0,0 @@
{
"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
}
]
}
]
}

View File

@@ -1,10 +0,0 @@
{
"name": "CYD-Klipper",
"new_install_prompt_erase": false,
"builds": [
{
"path": "output/merged-firmware.bin",
"offset": 0
}
]
}

85
ci.py Normal file
View File

@@ -0,0 +1,85 @@
import subprocess, os, shutil, json
CYD_PORTS = [
"esp32-3248S035C",
"esp32-2432S028R",
"esp32-2432S032C-SD",
"esp32-8048S043C-SD",
"esp32-2432S024C-SD",
"esp32-4827S043C-SD",
"esp32-3248S035C-V"
]
BASE_DIR = os.getcwd()
def get_manifest(base_path : str, device_name : str):
return {
"name": f"to {device_name}",
"new_install_prompt_erase": True,
"builds": [
{
"chipFamily": "ESP32",
"parts": [
{
"path": f"{base_path}/bootloader.bin",
"offset": 4096
},
{
"path": f"{base_path}/partitions.bin",
"offset": 32768
},
{
"path": f"{base_path}/boot_app0.bin",
"offset": 57344
},
{
"path": f"{base_path}/firmware.bin",
"offset": 65536
}
]
}
]
}
def extract_commit() -> str:
git_describe_output = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, text=True, check=True).stdout.strip()
return git_describe_output.split("-")[0]
repo_version = extract_commit()
configurations = []
def add_configuration(board : str):
configurations.append({
"Board": board,
"Version": repo_version,
"URL": f"https://suchmememanyskill.github.io/CYD-Klipper/out/{board}/firmware.bin"
})
if os.path.exists("out"):
shutil.rmtree("out")
for port in CYD_PORTS:
port_path = f"out/{port}"
os.chdir(BASE_DIR)
os.makedirs(port_path, exist_ok=True)
os.chdir("CYD-Klipper")
subprocess.run(["pio", "run", "-e", port], check=True)
os.chdir(BASE_DIR)
for file in ["bootloader.bin", "partitions.bin", "firmware.bin"]:
shutil.copy(f"./CYD-Klipper/.pio/build/{port}/{file}", f"{port_path}/{file}")
shutil.copy(os.path.join(os.path.expanduser("~"), ".platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin"), f"{port_path}/boot_app0.bin")
os.chdir(port_path)
subprocess.run(["python3", "-m", "esptool", "--chip", "esp32", "merge_bin", "-o", "merged_firmware.bin", "--flash_mode", "dio", "--flash_freq", "40m", "--flash_size", "4MB", "0x1000", "bootloader.bin", "0x8000", "partitions.bin", "0xe000", "boot_app0.bin", "0x10000", "firmware.bin"], check=True)
os.chdir(BASE_DIR)
with open(f"./_site/{port}.json", "w") as f:
json.dump(get_manifest(port_path, port), f)
add_configuration(port)
os.chdir(BASE_DIR)
shutil.copytree("./out", "./_site/out")
with open("./_site/OTA.json", "w") as f:
json.dump({"Configurations": configurations}, f)

BIN
readme/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
readme/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
readme/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
readme/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 KiB

BIN
readme/5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 KiB

BIN
readme/6.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
readme/7.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
readme/8.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 890 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 911 KiB

BIN
readme/cmd.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB