diff --git a/.diagrams/esp32.json b/.diagrams/esp32.json new file mode 100644 index 00000000..0ba6e942 --- /dev/null +++ b/.diagrams/esp32.json @@ -0,0 +1,205 @@ +{ + "version": 1, + "author": "Thomas Forntoh", + "editor": "wokwi", + "parts": [ + { + "type": "wokwi-breadboard-half", + "id": "bb2", + "top": 226.5, + "left": 80.1, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-breadboard-mini", + "id": "bb1", + "top": 440.2, + "left": 439.2, + "attrs": {} + }, + { + "type": "wokwi-lcd1602", + "id": "lcd1", + "top": 16, + "left": 140, + "attrs": { "pins": "i2c" } + }, + { + "type": "wokwi-ky-040", + "id": "encoder1", + "top": 41.4, + "left": 433.3, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-pushbutton", + "id": "btn1", + "top": 198.2, + "left": 489.6, + "attrs": { "color": "blue", "label": "Up" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn2", + "top": 332.6, + "left": 489.6, + "attrs": { "color": "blue", "label": "Down" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn3", + "top": 265.4, + "left": 489.6, + "attrs": { "color": "green", "label": "Enter" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn4", + "top": 332.6, + "left": 576, + "attrs": { "color": "red", "label": "Back" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn5", + "top": 265.4, + "left": 403.2, + "attrs": { "color": "blue", "label": "Left" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn6", + "top": 265.4, + "left": 576, + "attrs": { "color": "blue", "label": "Right" } + }, + { + "type": "board-ssd1306", + "id": "oled1", + "top": 22.34, + "left": -28.57, + "attrs": { "i2cAddress": "0x3c" } + }, + { + "type": "board-esp32-devkit-c-v4", + "id": "esp", + "top": 245.29, + "left": -53.03, + "attrs": {} + }, + { + "type": "wokwi-pushbutton", + "id": "btn7", + "top": 332.6, + "left": 403.2, + "attrs": { "color": "yellow", "label": "BKSP" } + } + ], + "connections": [ + ["esp:TX", "$serialMonitor:RX", "", []], + ["esp:RX", "$serialMonitor:TX", "", []], + ["bb2:2t.a", "encoder1:CLK", "purple", ["h67.2", "v-38.4", "h144"]], + ["bb2:3t.a", "encoder1:DT", "magenta", ["h76.8", "v-38.4", "h124.8"]], + ["bb2:4t.a", "encoder1:SW", "cyan", ["h86.4", "v-38.4", "h105.6"]], + ["bb2:tp.4", "encoder1:VCC", "red", ["h57.3", "v-36.8", "h86.4"]], + ["encoder1:GND", "bb2:tn.5", "black", ["v67.2", "h-77.6", "v36.8"]], + ["lcd1:GND", "bb2:bn.1", "black", ["h-9.6", "v153.6", "h17.9"]], + ["lcd1:VCC", "bb2:bp.2", "red", ["h-19.2", "v152.1"]], + ["lcd1:SDA", "bb2:21b.j", "violet", ["h-28.8", "v0.2"]], + ["lcd1:SCL", "bb2:22b.j", "blue", ["h-38.4", "v67.5"]], + [ + "oled1:SDA", + "bb2:21b.i", + "violet", + ["v-9.6", "h-76.73", "v96", "h134.4", "v278.4"] + ], + [ + "oled1:SCL", + "bb2:22b.i", + "blue", + ["v-19.2", "h-76.5", "v115.2", "h134.4", "v278.4"] + ], + [ + "oled1:VCC", + "bb2:bp.3", + "red", + ["v-28.8", "h-76.65", "v134.4", "h134.4", "v86.4"] + ], + [ + "oled1:GND", + "bb2:bn.4", + "black", + ["v-38.4", "h-76.8", "v153.6", "h134.4", "v86.4"] + ], + ["bb2:tn.25", "bb2:bn.25", "black", ["h0"]], + ["bb2:tp.24", "bb2:bp.24", "red", ["h0"]], + ["bb2:2t.e", "bb2:2b.f", "purple", ["h0"]], + ["bb2:3t.e", "bb2:3b.f", "magenta", ["h0"]], + ["bb2:4t.e", "bb2:4b.f", "cyan", ["h0"]], + ["bb2:3b.j", "esp:3", "green", ["h-259.2", "v9.6"]], + ["bb2:6b.j", "esp:6", "green", ["h-288", "v96"]], + ["bb2:7b.j", "esp:7", "green", ["h-297.6", "v96"]], + ["bb2:8b.j", "esp:8", "green", ["h-307.2", "v96"]], + ["bb2:9b.j", "esp:9", "green", ["h-316.8", "v115.2", "h174.35"]], + ["bb2:10b.j", "esp:10", "green", ["h-326.4", "v96"]], + ["bb2:11b.j", "esp:11", "green", ["h-336", "v96"]], + ["bb2:21b.h", "esp:20", "green", ["h-134.4", "v57.6"]], + ["esp:3V3", "bb2:bp.23", "red", ["h-9.6", "v201.6", "h172.8", "v-30.4"]], + [ + "bb2:bn.24", + "esp:GND.1", + "black", + ["h-37.1", "v30.4", "h-182.4", "v-90.71"] + ], + ["bb2:22b.h", "esp:22", "blue", ["h-134.4", "v-9.6"]], + ["bb2:21b.h", "esp:21", "violet", ["h-144", "v-57.6"]], + ["btn2:2.l", "bb1:2t.a", "green", ["h-9.6", "v67.4", "h-19.2"]], + ["btn3:2.l", "bb1:3t.a", "green", ["h-9.6", "v134.6", "h-9.6"]], + ["btn4:2.l", "bb1:4t.a", "green", ["h-9.6", "v67.4", "h-86.4"]], + ["btn5:2.l", "bb1:5t.a", "green", ["h-9.6", "v134.6", "h96"]], + ["btn6:2.r", "bb1:6t.a", "green", ["h9.8", "v134.6", "h-9.6"]], + ["btn7:2.l", "bb1:7t.a", "green", ["h-19.2", "v67.4", "h124.8"]], + ["btn1:2.l", "bb1:1t.a", "green", ["h-9.6", "v201.8", "h-28.8"]], + ["btn1:1.r", "bb1:17t.a", "black", ["v0", "h105.8", "v240"]], + ["btn6:1.r", "bb1:17t.b", "black", ["h19.4", "v182.4"]], + ["btn4:1.r", "bb1:17t.c", "black", ["h19.4", "v124.8"]], + ["btn2:1.r", "bb1:17t.d", "black", ["h9.8", "v-19.2", "h96", "v153.6"]], + ["btn3:1.r", "bb1:17t.e", "black", ["h9.8", "v-19.2", "h96", "v230.4"]], + [ + "btn5:1.r", + "bb1:17b.f", + "black", + ["h9.8", "v-19.2", "h76.8", "v-9.6", "h105.6", "v268.8"] + ], + ["bb1:17t.e", "bb1:17b.f", "black", ["v0"]], + [ + "btn7:1.r", + "bb1:17b.g", + "black", + ["v0", "h9.8", "v76.8", "h182.4", "v105.6"] + ], + ["bb1:1t.e", "bb1:1b.f", "green", ["v0"]], + ["bb1:2t.e", "bb1:2b.f", "green", ["v0"]], + ["bb1:3t.e", "bb1:3b.f", "green", ["v0"]], + ["bb1:4t.e", "bb1:4b.f", "green", ["v0"]], + ["bb1:5t.e", "bb1:5b.f", "green", ["v0"]], + ["bb1:6t.e", "bb1:6b.f", "green", ["v0"]], + ["bb1:7t.e", "bb1:7b.f", "green", ["v0"]], + ["bb1:17b.j", "bb2:tn.25", "black", ["v19.2", "h-278.4"]], + ["bb1:5b.j", "esp:16", "green", ["v0", "h-432", "v-172.8"]], + ["bb1:6b.j", "esp:17", "green", ["v0", "h-441.6", "v-192"]], + ["bb1:7b.j", "esp:5", "green", ["v0", "h-451.2", "v-201.6"]], + ["bb1:1b.j", "esp:15", "green", ["v0", "h-393.6", "v-134.4"]], + ["esp:2", "bb1:2b.j", "green", ["h9.87", "v148.31"]], + ["esp:0", "bb1:3b.j", "green", ["h9.87", "v157.91"]], + ["esp:4", "bb1:4b.j", "green", ["h9.87", "v167.51"]], + ["esp:CLK", "bb2:25b.j", "purple", ["h48.27", "v-5.29"]], + ["bb2:2t.d", "bb2:25t.d", "purple", ["h0"]], + ["bb2:25t.e", "bb2:25b.f", "purple", ["h0"]], + ["esp:18", "bb2:4b.h", "cyan", ["h0"]], + ["esp:19", "bb2:3b.i", "magenta", ["h0"]] + ], + "dependencies": {} +} diff --git a/.diagrams/uno.json b/.diagrams/uno.json new file mode 100644 index 00000000..bf6ce650 --- /dev/null +++ b/.diagrams/uno.json @@ -0,0 +1,192 @@ +{ + "version": 1, + "author": "Thomas Forntoh", + "editor": "wokwi", + "parts": [ + { + "type": "wokwi-breadboard-half", + "id": "bb2", + "top": 226.5, + "left": 80.1, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-breadboard-mini", + "id": "bb1", + "top": 440.2, + "left": 439.2, + "attrs": {} + }, + { + "type": "wokwi-lcd1602", + "id": "lcd1", + "top": 16, + "left": 140, + "attrs": { "pins": "i2c" } + }, + { + "type": "wokwi-ky-040", + "id": "encoder1", + "top": 41.4, + "left": 433.3, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-pushbutton", + "id": "btn1", + "top": 198.2, + "left": 489.6, + "attrs": { "color": "blue", "label": "Up" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn2", + "top": 332.6, + "left": 489.6, + "attrs": { "color": "blue", "label": "Down" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn3", + "top": 265.4, + "left": 489.6, + "attrs": { "color": "green", "label": "Enter" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn4", + "top": 332.6, + "left": 576, + "attrs": { "color": "red", "label": "Back" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn5", + "top": 265.4, + "left": 403.2, + "attrs": { "color": "blue", "label": "Left" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn6", + "top": 265.4, + "left": 576, + "attrs": { "color": "blue", "label": "Right" } + }, + { + "type": "board-ssd1306", + "id": "oled1", + "top": 22.34, + "left": -28.57, + "attrs": { "i2cAddress": "0x3c" } + }, + { + "type": "wokwi-pushbutton", + "id": "btn7", + "top": 332.6, + "left": 403.2, + "attrs": { "color": "yellow", "label": "BKSP" } + }, + { + "type": "wokwi-arduino-uno", + "id": "uno", + "top": 256.2, + "left": -200.2, + "rotate": 90, + "attrs": {} + } + ], + "connections": [ + ["bb2:2t.a", "encoder1:CLK", "purple", ["h67.2", "v-38.4", "h144"]], + ["bb2:3t.a", "encoder1:DT", "magenta", ["h76.8", "v-38.4", "h124.8"]], + ["bb2:4t.a", "encoder1:SW", "cyan", ["h86.4", "v-38.4", "h105.6"]], + ["bb2:tp.4", "encoder1:VCC", "red", ["h57.3", "v-36.8", "h86.4"]], + ["encoder1:GND", "bb2:tn.5", "black", ["v67.2", "h-77.6", "v36.8"]], + ["lcd1:GND", "bb2:bn.1", "black", ["h-9.6", "v153.6", "h17.9"]], + ["lcd1:VCC", "bb2:bp.2", "red", ["h-19.2", "v152.1"]], + ["lcd1:SDA", "bb2:21b.j", "violet", ["h-28.8", "v0.2"]], + ["lcd1:SCL", "bb2:22b.j", "blue", ["h-38.4", "v67.5"]], + [ + "oled1:SDA", + "bb2:21b.i", + "violet", + ["v-9.6", "h-76.73", "v96", "h134.4", "v278.4"] + ], + [ + "oled1:SCL", + "bb2:22b.i", + "blue", + ["v-19.2", "h-76.5", "v115.2", "h134.4", "v278.4"] + ], + [ + "oled1:VCC", + "bb2:bp.3", + "red", + ["v-28.8", "h-76.65", "v134.4", "h134.4", "v86.4"] + ], + [ + "oled1:GND", + "bb2:bn.4", + "black", + ["v-38.4", "h-76.8", "v153.6", "h134.4", "v86.4"] + ], + ["bb2:tn.25", "bb2:bn.25", "black", ["h0"]], + ["bb2:tp.24", "bb2:bp.24", "red", ["h0"]], + ["bb2:2t.e", "bb2:2b.f", "purple", ["h0"]], + ["bb2:3t.e", "bb2:3b.f", "magenta", ["h0"]], + ["bb2:4t.e", "bb2:4b.f", "cyan", ["h0"]], + ["btn2:2.l", "bb1:2t.a", "green", ["h-9.6", "v67.4", "h-19.2"]], + ["btn3:2.l", "bb1:3t.a", "green", ["h-9.6", "v134.6", "h-9.6"]], + ["btn4:2.l", "bb1:4t.a", "green", ["h-9.6", "v67.4", "h-86.4"]], + ["btn5:2.l", "bb1:5t.a", "green", ["h-9.6", "v134.6", "h96"]], + ["btn6:2.r", "bb1:6t.a", "green", ["h9.8", "v134.6", "h-9.6"]], + ["btn7:2.l", "bb1:7t.a", "green", ["h-19.2", "v67.4", "h124.8"]], + ["btn1:2.l", "bb1:1t.a", "green", ["h-9.6", "v201.8", "h-28.8"]], + ["btn1:1.r", "bb1:17t.a", "black", ["v0", "h105.8", "v240"]], + ["btn6:1.r", "bb1:17t.b", "black", ["h19.4", "v182.4"]], + ["btn4:1.r", "bb1:17t.c", "black", ["h19.4", "v124.8"]], + ["btn2:1.r", "bb1:17t.d", "black", ["h9.8", "v-19.2", "h96", "v153.6"]], + ["btn3:1.r", "bb1:17t.e", "black", ["h9.8", "v-19.2", "h96", "v230.4"]], + [ + "btn5:1.r", + "bb1:17b.f", + "black", + ["h9.8", "v-19.2", "h76.8", "v-9.6", "h105.6", "v268.8"] + ], + ["bb1:17t.e", "bb1:17b.f", "black", ["v0"]], + [ + "btn7:1.r", + "bb1:17b.g", + "black", + ["v0", "h9.8", "v76.8", "h182.4", "v105.6"] + ], + ["bb1:1t.e", "bb1:1b.f", "green", ["v0"]], + ["bb1:2t.e", "bb1:2b.f", "green", ["v0"]], + ["bb1:3t.e", "bb1:3b.f", "green", ["v0"]], + ["bb1:4t.e", "bb1:4b.f", "green", ["v0"]], + ["bb1:5t.e", "bb1:5b.f", "green", ["v0"]], + ["bb1:6t.e", "bb1:6b.f", "green", ["v0"]], + ["bb1:7t.e", "bb1:7b.f", "green", ["v0"]], + ["bb1:17b.j", "bb2:tn.25", "black", ["v19.2", "h-278.4"]], + ["bb2:2t.d", "bb2:25t.d", "purple", ["h0"]], + ["bb2:25t.e", "bb2:25b.f", "purple", ["h0"]], + ["bb2:25b.j", "uno:2", "purple", ["h-96", "v38.4"]], + ["bb2:3b.j", "uno:3", "magenta", ["h0", "v201.6", "h-105.6", "v48"]], + ["uno:4", "bb2:23b.g", "cyan", ["h192", "v-34.5"]], + ["bb2:4b.g", "bb2:23b.g", "cyan", ["h0"]], + ["uno:GND.3", "bb2:bn.25", "black", ["h-19.1", "v109.6", "h326.4", "v-40"]], + ["uno:3.3V", "bb2:bp.25", "red", ["h-28.7", "v148.2", "h470.4"]], + ["uno:A4", "bb2:21b.h", "violet", ["h-9.5", "v33", "h220.8", "v-115.2"]], + ["uno:A5", "bb2:22b.h", "blue", ["h0.1", "v13.9", "h220.8", "v-96"]], + ["bb1:1b.f", "uno:5", "green", ["v9.6", "h-403.2", "v-99.8"]], + ["uno:6", "bb1:2b.g", "green", ["h19.2", "v118.9", "h412.8"]], + ["bb1:3b.g", "uno:7", "green", ["v19.2", "h-422.4", "v-144"]], + ["bb1:4b.j", "uno:8", "green", ["v28.8", "h-432", "v-192.4"]], + ["uno:9", "bb1:5b.j", "green", ["h19.2", "v192.8", "h0", "v9.6", "h441.6"]], + ["bb1:6b.j", "uno:10", "green", ["v28.8", "h-451.2", "v-211.9"]], + ["uno:11", "bb1:7b.j", "green", ["h19.2", "v221.4", "h460.8"]] + ], + "dependencies": {} +} diff --git a/.github/workflows/compile-arduino.yml b/.github/workflows/compile-arduino.yml index 72c81393..6b6d893f 100644 --- a/.github/workflows/compile-arduino.yml +++ b/.github/workflows/compile-arduino.yml @@ -17,11 +17,85 @@ jobs: compile: runs-on: ubuntu-latest + env: + UNIVERSAL_LIBRARIES: | + - source-path: ./ + - name: Button + - name: SimpleRotary + - name: LiquidCrystal I2C + - name: SSD1803A_I2C + + UNIVERSAL_SKETCH_PATHS: | + - examples/Basic + - examples/ButtonAdapter + - examples/Callbacks + - examples/InputRotary + - examples/IntFloatValues + - examples/KeyboardAdapter + - examples/List + - examples/SimpleRotary + - examples/SSD1803A_I2C + + SKETCHES_REPORTS_PATH: sketches-reports + strategy: + fail-fast: false matrix: board: + - fqbn: esp32:esp32:esp32 + type: esp32 + artifact-name-suffix: esp32-esp32-esp32 - fqbn: arduino:avr:uno + type: avr artifact-name-suffix: arduino-avr-uno + - fqbn: esp8266:esp8266:huzzah + type: esp8266 + artifact-name-suffix: esp8266-esp8266-huzzah + - fqbn: arduino:samd:mkr1000 + type: mkr1000 + artifact-name-suffix: arduino-samd-mkr1000 + - fqbn: STMicroelectronics:stm32:GenF1 + type: stm32 + artifact-name-suffix: STM32-stm32-GenF1 + + include: + # AVR boards + - board: + type: avr + platforms: | + # Install AVR platform via Boards Manager + - name: arduino:avr + libraries: | + - name: FreeRTOS + sketch-paths: | + - examples/RTOS + # ESP32 boards + - board: + type: esp32 + platforms: | + # Install ESP32 platform via Boards Manager + - name: esp32:esp32 + source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + libraries: + sketch-paths: | + - examples/RTOS + # ESP8266 boards + - board: + type: esp8266 + platforms: | + # Install ESP8266 platform via Boards Manager + - name: esp8266:esp8266 + source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json + libraries: + sketch-paths: + # STM32 boards + - board: + type: stm32 + platforms: | + # Install STM32 platform via Boards Manager + - name: STMicroelectronics:stm32 + source-url: https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json + sketch-paths: steps: - name: Checkout @@ -31,19 +105,19 @@ jobs: uses: arduino/compile-sketches@v1 with: fqbn: ${{ matrix.board.fqbn }} + platforms: ${{ matrix.platforms }} + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + libraries: | + ${{ env.UNIVERSAL_LIBRARIES }} + ${{ matrix.libraries }} + sketch-paths: | + ${{ matrix.sketch-paths }} + ${{ env.UNIVERSAL_SKETCH_PATHS }} enable-deltas-report: true enable-warnings-report: true - sketches-report-path: sketches-reports - libraries: | - - source-path: ./ - - name: Button - - name: FreeRTOS - - name: SimpleRotary - - name: LiquidCrystal I2C - - name: SSD1803A_I2C - name: Upload sketches reports uses: actions/upload-artifact@v4 with: name: sketches-report-${{ matrix.board.artifact-name-suffix }} - path: sketches-reports + path: ${{ env.SKETCHES_REPORTS_PATH }} diff --git a/diagram.json b/diagram.json index f105716c..bf6ce650 100644 --- a/diagram.json +++ b/diagram.json @@ -3,13 +3,33 @@ "author": "Thomas Forntoh", "editor": "wokwi", "parts": [ - { "type": "wokwi-arduino-uno", "id": "uno", "top": 200, "left": 20, "attrs": {} }, - { "type": "wokwi-lcd1602", "id": "lcd1", "top": 16, "left": 15.2, "attrs": { "pins": "i2c" } }, + { + "type": "wokwi-breadboard-half", + "id": "bb2", + "top": 226.5, + "left": 80.1, + "rotate": 90, + "attrs": {} + }, + { + "type": "wokwi-breadboard-mini", + "id": "bb1", + "top": 440.2, + "left": 439.2, + "attrs": {} + }, + { + "type": "wokwi-lcd1602", + "id": "lcd1", + "top": 16, + "left": 140, + "attrs": { "pins": "i2c" } + }, { "type": "wokwi-ky-040", "id": "encoder1", "top": 41.4, - "left": 318.1, + "left": 433.3, "rotate": 90, "attrs": {} }, @@ -18,75 +38,155 @@ "id": "btn1", "top": 198.2, "left": 489.6, - "attrs": { "color": "blue" } + "attrs": { "color": "blue", "label": "Up" } }, { "type": "wokwi-pushbutton", "id": "btn2", - "top": 294.2, + "top": 332.6, "left": 489.6, - "attrs": { "color": "blue" } + "attrs": { "color": "blue", "label": "Down" } }, { "type": "wokwi-pushbutton", "id": "btn3", - "top": 246.2, + "top": 265.4, "left": 489.6, - "attrs": { "color": "green" } + "attrs": { "color": "green", "label": "Enter" } }, { "type": "wokwi-pushbutton", "id": "btn4", - "top": 380.6, - "left": 393.6, - "attrs": { "color": "red" } + "top": 332.6, + "left": 576, + "attrs": { "color": "red", "label": "Back" } }, { "type": "wokwi-pushbutton", "id": "btn5", - "top": 246.2, - "left": 422.4, - "attrs": { "color": "blue" } + "top": 265.4, + "left": 403.2, + "attrs": { "color": "blue", "label": "Left" } }, { "type": "wokwi-pushbutton", "id": "btn6", - "top": 246.2, - "left": 556.8, - "attrs": { "color": "blue" } + "top": 265.4, + "left": 576, + "attrs": { "color": "blue", "label": "Right" } + }, + { + "type": "board-ssd1306", + "id": "oled1", + "top": 22.34, + "left": -28.57, + "attrs": { "i2cAddress": "0x3c" } }, { - "type": "wokwi-pushbutton-6mm", + "type": "wokwi-pushbutton", "id": "btn7", - "top": 353, - "left": 412.8, - "attrs": { "color": "yellow" } + "top": 332.6, + "left": 403.2, + "attrs": { "color": "yellow", "label": "BKSP" } + }, + { + "type": "wokwi-arduino-uno", + "id": "uno", + "top": 256.2, + "left": -200.2, + "rotate": 90, + "attrs": {} } ], "connections": [ - [ "lcd1:SDA", "uno:A4", "blue", [ "h-30.42", "v369.27", "h273.31" ] ], - [ "lcd1:SCL", "uno:A5", "limegreen", [ "h-16.48", "v370.62", "h268.87" ] ], - [ "lcd1:VCC", "uno:5V", "red", [ "h-42.82", "v366.38", "h199.71" ] ], - [ "lcd1:GND", "uno:GND.1", "black", [ "h-24.23", "v175.22" ] ], - [ "encoder1:CLK", "uno:2", "blue", [ "v28.8", "h-146.7" ] ], - [ "encoder1:DT", "uno:3", "orange", [ "h-0.1", "v57.6", "h-146.6" ] ], - [ "encoder1:SW", "uno:4", "green", [ "h-0.1", "v48", "h-146.5" ] ], - [ "encoder1:GND", "uno:GND.1", "black", [ "h-0.8", "v38.4", "h-229.3" ] ], - [ "encoder1:VCC", "uno:5V", "red", [ "h-0.4", "v288", "h-194.4" ] ], - [ "btn1:1.l", "uno:5", "green", [ "h-163.2", "v-11.8" ] ], - [ "btn1:2.l", "uno:GND.1", "black", [ "h0" ] ], - [ "btn2:1.l", "uno:6", "green", [ "h0" ] ], - [ "btn3:1.l", "uno:7", "green", [ "v-28.8", "h-280.6" ] ], - [ "btn4:1.l", "uno:8", "green", [ "h0" ] ], - [ "btn2:2.l", "uno:GND.1", "black", [ "h0" ] ], - [ "btn3:2.l", "uno:GND.1", "black", [ "v29", "h-354.1" ] ], - [ "btn4:2.l", "uno:GND.1", "black", [ "h0" ] ], - [ "btn5:1.l", "uno:9", "green", [ "h0" ] ], - [ "btn6:1.l", "uno:10", "green", [ "v-19.2", "h-392.9" ] ], - [ "btn5:2.l", "uno:GND.1", "black", [ "h0" ] ], - [ "btn6:2.l", "uno:GND.1", "black", [ "v19.4", "h-430.9" ] ], - [ "btn7:1.l", "uno:11", "green", [ "h0" ] ], - [ "btn7:2.l", "uno:GND.2", "black", [ "h0" ] ] + ["bb2:2t.a", "encoder1:CLK", "purple", ["h67.2", "v-38.4", "h144"]], + ["bb2:3t.a", "encoder1:DT", "magenta", ["h76.8", "v-38.4", "h124.8"]], + ["bb2:4t.a", "encoder1:SW", "cyan", ["h86.4", "v-38.4", "h105.6"]], + ["bb2:tp.4", "encoder1:VCC", "red", ["h57.3", "v-36.8", "h86.4"]], + ["encoder1:GND", "bb2:tn.5", "black", ["v67.2", "h-77.6", "v36.8"]], + ["lcd1:GND", "bb2:bn.1", "black", ["h-9.6", "v153.6", "h17.9"]], + ["lcd1:VCC", "bb2:bp.2", "red", ["h-19.2", "v152.1"]], + ["lcd1:SDA", "bb2:21b.j", "violet", ["h-28.8", "v0.2"]], + ["lcd1:SCL", "bb2:22b.j", "blue", ["h-38.4", "v67.5"]], + [ + "oled1:SDA", + "bb2:21b.i", + "violet", + ["v-9.6", "h-76.73", "v96", "h134.4", "v278.4"] + ], + [ + "oled1:SCL", + "bb2:22b.i", + "blue", + ["v-19.2", "h-76.5", "v115.2", "h134.4", "v278.4"] + ], + [ + "oled1:VCC", + "bb2:bp.3", + "red", + ["v-28.8", "h-76.65", "v134.4", "h134.4", "v86.4"] + ], + [ + "oled1:GND", + "bb2:bn.4", + "black", + ["v-38.4", "h-76.8", "v153.6", "h134.4", "v86.4"] + ], + ["bb2:tn.25", "bb2:bn.25", "black", ["h0"]], + ["bb2:tp.24", "bb2:bp.24", "red", ["h0"]], + ["bb2:2t.e", "bb2:2b.f", "purple", ["h0"]], + ["bb2:3t.e", "bb2:3b.f", "magenta", ["h0"]], + ["bb2:4t.e", "bb2:4b.f", "cyan", ["h0"]], + ["btn2:2.l", "bb1:2t.a", "green", ["h-9.6", "v67.4", "h-19.2"]], + ["btn3:2.l", "bb1:3t.a", "green", ["h-9.6", "v134.6", "h-9.6"]], + ["btn4:2.l", "bb1:4t.a", "green", ["h-9.6", "v67.4", "h-86.4"]], + ["btn5:2.l", "bb1:5t.a", "green", ["h-9.6", "v134.6", "h96"]], + ["btn6:2.r", "bb1:6t.a", "green", ["h9.8", "v134.6", "h-9.6"]], + ["btn7:2.l", "bb1:7t.a", "green", ["h-19.2", "v67.4", "h124.8"]], + ["btn1:2.l", "bb1:1t.a", "green", ["h-9.6", "v201.8", "h-28.8"]], + ["btn1:1.r", "bb1:17t.a", "black", ["v0", "h105.8", "v240"]], + ["btn6:1.r", "bb1:17t.b", "black", ["h19.4", "v182.4"]], + ["btn4:1.r", "bb1:17t.c", "black", ["h19.4", "v124.8"]], + ["btn2:1.r", "bb1:17t.d", "black", ["h9.8", "v-19.2", "h96", "v153.6"]], + ["btn3:1.r", "bb1:17t.e", "black", ["h9.8", "v-19.2", "h96", "v230.4"]], + [ + "btn5:1.r", + "bb1:17b.f", + "black", + ["h9.8", "v-19.2", "h76.8", "v-9.6", "h105.6", "v268.8"] + ], + ["bb1:17t.e", "bb1:17b.f", "black", ["v0"]], + [ + "btn7:1.r", + "bb1:17b.g", + "black", + ["v0", "h9.8", "v76.8", "h182.4", "v105.6"] + ], + ["bb1:1t.e", "bb1:1b.f", "green", ["v0"]], + ["bb1:2t.e", "bb1:2b.f", "green", ["v0"]], + ["bb1:3t.e", "bb1:3b.f", "green", ["v0"]], + ["bb1:4t.e", "bb1:4b.f", "green", ["v0"]], + ["bb1:5t.e", "bb1:5b.f", "green", ["v0"]], + ["bb1:6t.e", "bb1:6b.f", "green", ["v0"]], + ["bb1:7t.e", "bb1:7b.f", "green", ["v0"]], + ["bb1:17b.j", "bb2:tn.25", "black", ["v19.2", "h-278.4"]], + ["bb2:2t.d", "bb2:25t.d", "purple", ["h0"]], + ["bb2:25t.e", "bb2:25b.f", "purple", ["h0"]], + ["bb2:25b.j", "uno:2", "purple", ["h-96", "v38.4"]], + ["bb2:3b.j", "uno:3", "magenta", ["h0", "v201.6", "h-105.6", "v48"]], + ["uno:4", "bb2:23b.g", "cyan", ["h192", "v-34.5"]], + ["bb2:4b.g", "bb2:23b.g", "cyan", ["h0"]], + ["uno:GND.3", "bb2:bn.25", "black", ["h-19.1", "v109.6", "h326.4", "v-40"]], + ["uno:3.3V", "bb2:bp.25", "red", ["h-28.7", "v148.2", "h470.4"]], + ["uno:A4", "bb2:21b.h", "violet", ["h-9.5", "v33", "h220.8", "v-115.2"]], + ["uno:A5", "bb2:22b.h", "blue", ["h0.1", "v13.9", "h220.8", "v-96"]], + ["bb1:1b.f", "uno:5", "green", ["v9.6", "h-403.2", "v-99.8"]], + ["uno:6", "bb1:2b.g", "green", ["h19.2", "v118.9", "h412.8"]], + ["bb1:3b.g", "uno:7", "green", ["v19.2", "h-422.4", "v-144"]], + ["bb1:4b.j", "uno:8", "green", ["v28.8", "h-432", "v-192.4"]], + ["uno:9", "bb1:5b.j", "green", ["h19.2", "v192.8", "h0", "v9.6", "h441.6"]], + ["bb1:6b.j", "uno:10", "green", ["v28.8", "h-451.2", "v-211.9"]], + ["uno:11", "bb1:7b.j", "green", ["h19.2", "v221.4", "h460.8"]] ], "dependencies": {} -} \ No newline at end of file +} diff --git a/examples/RTOS/RTOS.ino b/examples/RTOS/RTOS.ino index 5fa7fc2f..2dba39dd 100644 --- a/examples/RTOS/RTOS.ino +++ b/examples/RTOS/RTOS.ino @@ -1,5 +1,7 @@ // Libraries +#if defined(ARDUINO_ARCH_AVR) #include +#endif #include #include #include @@ -7,10 +9,11 @@ #include #include #include +#include // 2x20 LCD Display -#define LCD_ROWS 4 -#define LCD_COLS 20 +#define LCD_ROWS 2 +#define LCD_COLS 16 float temperature1; float temperature2; @@ -61,7 +64,6 @@ MENU_SCREEN(relayScreen, relayItems, // Sub Menu 2: Temperature Values // clang-format off MENU_SCREEN(tempScreen, tempItems, - ITEM_BASIC(""), ITEM_BASIC(""), ITEM_BASIC("")); // clang-format on @@ -73,32 +75,22 @@ static void tempMeas(void* pvParameters) { //-------------------BEGIN: TEST WITH RANDOM------------------// temperature1 = random(1, 1000) / 100.0; // Generate random float temperature2 = random(1, 2000) / 100.0; // Generate random float - temperature3 = random(1, 3000) / 100.0; // Generate random float //-------------------END: TEST WITH RANDOM--------------------// char buffer1[8]; - tempItems[0]->setText(dtostrf(temperature1, 5, 2, buffer1)); + snprintf(buffer1, sizeof(buffer1), "%.02f mA", temperature1); + tempItems[0]->setText(buffer1); - char buffer2[8]; - tempItems[1]->setText(dtostrf(temperature2, 5, 2, buffer2)); + vTaskDelay(500 / portTICK_PERIOD_MS); // wait for 200ms - char buffer3[8]; - tempItems[2]->setText(dtostrf(temperature3, 5, 2, buffer3)); + char buffer2[8]; + snprintf(buffer2, sizeof(buffer2), "%.02f V", temperature2); + tempItems[1]->setText(buffer2); if (menu.getScreen() == tempScreen) { menu.refresh(); } - vTaskDelay(5000 / portTICK_PERIOD_MS); // wait for five seconds - } -} - -// RTOS func to read serial input from keyboard -static void keyPad(void* pvParameters) { - (void)pvParameters; // Unused parameter - - for (;;) { - keyboard.observe(); - vTaskDelay(1); + vTaskDelay(3000 / portTICK_PERIOD_MS); // wait for three seconds } } @@ -108,7 +100,6 @@ void setup() { renderer.begin(); menu.setScreen(mainScreen); // Run RTOS func. - xTaskCreate(keyPad, "keyPad", 128, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate(tempMeas, "tempMeas", 128, NULL, tskIDLE_PRIORITY + 1, NULL); // Setup random seed pinMode(A0, INPUT); @@ -117,4 +108,5 @@ void setup() { void loop() { renderer.updateTimer(); + keyboard.observe(); } diff --git a/library.json b/library.json index 57fc637f..8457c733 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,8 @@ "diagram.json", "Gemfile", "*.toml", - "docs/" + "docs/", + ".diagrams/" ] } } diff --git a/library.properties b/library.properties index f2ac1124..acfc0a83 100644 --- a/library.properties +++ b/library.properties @@ -7,5 +7,5 @@ paragraph=LcdMenu is an Arduino library that enables you to create interactive m category=Display url=https://lcdmenu.forntoh.dev repository=https://github.com/forntoh/LcdMenu.git -architectures=avr +architectures=* includes=LcdMenu.h diff --git a/platformio.ini b/platformio.ini index aca9aa25..c520bd32 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,3 +21,16 @@ lib_deps = madleech/Button@^1.0.0 Wire sstaub/SSD1803A_I2C@^1.0.2 + +[env:esp32] +platform = espressif32 +board = esp32dev +framework = arduino +extra_scripts = pre:.scripts/pio_config.py +lib_deps = + marcoschwartz/LiquidCrystal_I2C@^1.1.4 + arduino-libraries/LiquidCrystal @ ^1.0.7 + mprograms/SimpleRotary@^1.1.3 + madleech/Button@^1.0.0 + Wire + sstaub/SSD1803A_I2C@^1.0.2 \ No newline at end of file diff --git a/src/ItemFloatRange.h b/src/ItemFloatRange.h index 027aa4d6..84f9cf63 100644 --- a/src/ItemFloatRange.h +++ b/src/ItemFloatRange.h @@ -2,7 +2,10 @@ #define ItemFloatRange_H #include "ItemRangeBase.h" -#include +#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) +#else +#include "utils/printf.h" +#endif /** * @brief Item that allows user to input float information within a range. diff --git a/src/MenuScreen.cpp b/src/MenuScreen.cpp index c55510de..a6345dab 100644 --- a/src/MenuScreen.cpp +++ b/src/MenuScreen.cpp @@ -71,7 +71,7 @@ bool MenuScreen::process(LcdMenu* menu, const unsigned char command) { printLog(F("MenuScreen::back")); return true; case RIGHT: - if (renderer->cursorCol >= renderer->getEffectiveCols()) { + if (renderer->cursorCol >= renderer->maxCols - 1) { renderer->viewShift++; draw(renderer); } diff --git a/src/renderer/CharacterDisplayRenderer.cpp b/src/renderer/CharacterDisplayRenderer.cpp index 43d2729a..00a56ac7 100644 --- a/src/renderer/CharacterDisplayRenderer.cpp +++ b/src/renderer/CharacterDisplayRenderer.cpp @@ -22,31 +22,65 @@ void CharacterDisplayRenderer::begin() { } void CharacterDisplayRenderer::drawItem(const char* text, const char* value) { - char* buf = new char[maxCols + viewShift + 1]; + uint8_t cursorCol = 0; + display->setCursor(cursorCol, cursorRow); + + // Draw cursor or empty space based on focus and edit mode + if (cursorIcon != 0 || editCursorIcon != 0) { + display->draw(hasFocus ? (inEditMode ? editCursorIcon : cursorIcon) : ' '); + cursorCol++; + } + + // Draw text + drawText(text, cursorCol, viewShift); + + // Draw colon separator if value is present and within bounds + if (value && cursorCol < availableColumns && (!hasFocus || viewShift < strlen(text) + 1)) { + display->draw(':'); + cursorCol++; + } + + // Draw value if present + if (value) { + uint8_t textLen = strlen(text); + uint8_t valueViewShift = (viewShift > textLen) ? viewShift - textLen - 1 : 0; + drawText(value, cursorCol, valueViewShift); + } - strcpy(buf, text); + uint8_t cursorColEnd = cursorCol; - if (value != NULL) { - strcat(buf, ":"); - strcat(buf, value); + // Fill remaining space with white spaces + for (; cursorCol < availableColumns; cursorCol++) { + display->draw(' '); } - if (hasFocus && viewShift > 0) { - memmove(buf, buf + viewShift, availableColumns); + // Draw up and down arrows if present + if (upArrow && downArrow) { + uint8_t indicator = hasHiddenItemsAbove ? 1 : (hasHiddenItemsBelow ? 2 : 0); + display->setCursor(maxCols - 1, cursorRow); + display->draw(indicator); } - appendCursorToText(buf); + // Move cursor to the end position if focused + if (hasFocus) moveCursor(cursorColEnd, cursorRow); +} - buf[availableColumns] = '\0'; - uint8_t cursorCol = strlen(buf); +void CharacterDisplayRenderer::drawText(const char* text, uint8_t& col, uint8_t shift) { + // Pointer to the current character in the text + const char* textPtr = text; - padText(buf); - appendIndicatorToText(buf); + // If the renderer has focus, adjust the text pointer based on the shift value + if (hasFocus) { + uint8_t textLen = strlen(text); + // Move the text pointer forward by 'shift' characters, if within bounds + textPtr = (shift < textLen) ? textPtr + shift : NULL; + } - display->setCursor(0, cursorRow); - display->draw(buf); - if (hasFocus) moveCursor(cursorCol, cursorRow); - delete[] buf; + // Draw characters from the text until we reach the end of the available columns or the end of the text + while (col < availableColumns && textPtr && *textPtr) { + display->draw(*textPtr++); // Draw the current character and move to the next + col++; // Move to the next column + } } void CharacterDisplayRenderer::draw(uint8_t byte) { @@ -66,39 +100,6 @@ void CharacterDisplayRenderer::moveCursor(uint8_t cursorCol, uint8_t cursorRow) display->setCursor(cursorCol, cursorRow); } -void CharacterDisplayRenderer::appendCursorToText(char* text) { - if (cursorIcon == 0 && editCursorIcon == 0) return; - - uint8_t cursor = hasFocus ? (inEditMode ? editCursorIcon : cursorIcon) : ' '; - uint8_t len = strlen(text); - - memmove(text + 1, text, len + 1); - text[0] = cursor; -} - -void CharacterDisplayRenderer::appendIndicatorToText(char* text) { - uint8_t indicator = (hasHiddenItemsAbove) ? 1 : ((hasHiddenItemsBelow) ? 2 : 0); - uint8_t len = strlen(text); - bool hasArrows = upArrow != NULL && downArrow != NULL; - - if (indicator != 0 && hasArrows) { - text[len] = indicator; - } else if (hasArrows) { - text[len] = ' '; - } else { - return; - } - text[len + 1] = '\0'; -} - -void CharacterDisplayRenderer::padText(char* text) { - uint8_t textLength = strlen(text); - uint8_t spaces = (textLength > availableColumns) ? 0 : availableColumns - textLength; - spaces = constrain(spaces, 0, maxCols); - memset(text + textLength, ' ', spaces); - text[textLength + spaces] = '\0'; -} - uint8_t CharacterDisplayRenderer::getEffectiveCols() const { return availableColumns - (cursorIcon != 0 || editCursorIcon != 0 ? 1 : 0); } \ No newline at end of file diff --git a/src/renderer/CharacterDisplayRenderer.h b/src/renderer/CharacterDisplayRenderer.h index 8b6322ad..5f368d21 100644 --- a/src/renderer/CharacterDisplayRenderer.h +++ b/src/renderer/CharacterDisplayRenderer.h @@ -26,32 +26,6 @@ class CharacterDisplayRenderer : public MenuRenderer { const uint8_t cursorIcon; const uint8_t editCursorIcon; const uint8_t availableColumns; - - /** - * @brief Appends a cursor icon to the given text if the specified screen row is active. - * - * @param text The original text to which the cursor icon will be appended. - */ - void appendCursorToText(char* text); - - /** - * @brief Appends an indicator to the provided text based on the item index and screen row. - * - * @param text The original text to which the indicator may be appended. - */ - void appendIndicatorToText(char* text); - - /** - * @brief Pads the given text with spaces to fit within the available length. - * - * This function takes a text string and pads it with spaces so that the total - * length of the text fits within the available length of the display. If the - * text is longer than the available length, no padding is added. - * - * @param text The input text to be padded. - */ - void padText(char* text); - /** * @brief Calculates the available horizontal space for displaying content. * @@ -63,6 +37,19 @@ class CharacterDisplayRenderer : public MenuRenderer { */ uint8_t getEffectiveCols() const override; + /** + * @brief Draws text on the display. + * + * This function draws text on the display, handling text truncation and shifting. + * It takes into account the viewShift parameter to shift the text by a specified + * number of columns. + * + * @param text The text to be drawn on the display. + * @param col The column position to start drawing the text. This parameter will be updated to the new column position after drawing the text. + * @param viewShift The number of columns to shift the text by. + */ + inline void drawText(const char* text, uint8_t& col, uint8_t viewShift); + public: /** * @brief Constructor for CharacterDisplayRenderer. diff --git a/test/ViewShifting.test.yml b/test/ViewShifting.test.yml index fe9a0a93..90bea845 100644 --- a/test/ViewShifting.test.yml +++ b/test/ViewShifting.test.yml @@ -46,13 +46,9 @@ steps: - simulate: rightButton-press - wait-serial: "#LOG# MenuScreen::right=5" - simulate: rightButton-press - - wait-serial: "#LOG# MenuScreen::right=6" - - simulate: rightButton-press - - wait-serial: "#LOG# MenuScreen::right=6" + - wait-serial: "#LOG# MenuScreen::right=5" - simulate: rightButton-press - - wait-serial: "#LOG# MenuScreen::right=6" - - simulate: leftButton-press - - wait-serial: "#LOG# MenuScreen::left=5" + - wait-serial: "#LOG# MenuScreen::right=5" - simulate: leftButton-press - wait-serial: "#LOG# MenuScreen::left=4" - simulate: leftButton-press diff --git a/wokwi.toml b/wokwi.toml index 0cab9755..4536f483 100644 --- a/wokwi.toml +++ b/wokwi.toml @@ -1,4 +1,10 @@ [wokwi] version=1 + +# UNO firmware='.pio/build/uno/firmware.hex' -elf='.pio/build/uno/firmware.elf' \ No newline at end of file +elf='.pio/build/uno/firmware.elf' + +# ESP32 +# firmware='.pio/build/esp32/firmware.bin' +# elf='.pio/build/esp32/firmware.elf' \ No newline at end of file