From c1227e20c6df5fe33ab11ba251c652f7a179a903 Mon Sep 17 00:00:00 2001 From: Jannis Date: Wed, 23 Sep 2026 23:03:07 +0200 Subject: [PATCH] Homescreen Working --- .../KugelmühleSchaltplan.kicad_pro | 2 +- .../KugelmühleSchaltplan.kicad_sch | 1039 +++++++++++++++-- KugelmühleSchaltplan/KugelmühleSchaltplan.pdf | Bin 0 -> 62397 bytes .../~KugelmühleSchaltplan.kicad_pcb.lck | 1 + display_ui.cpp | 128 +- display_ui.h | 2 +- jentest.ino | 393 +++++++ main.ino | 28 +- types.h | 66 +- 9 files changed, 1491 insertions(+), 168 deletions(-) create mode 100644 KugelmühleSchaltplan/KugelmühleSchaltplan.pdf create mode 100644 KugelmühleSchaltplan/~KugelmühleSchaltplan.kicad_pcb.lck create mode 100644 jentest.ino diff --git a/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_pro b/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_pro index babcd68..4496911 100644 --- a/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_pro +++ b/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_pro @@ -429,7 +429,7 @@ "uuid": "08a39202-f0bc-425a-a79b-1d2766a907c0" } ], - "used_designators": "U1-2,SW1-3,J1", + "used_designators": "U1-2,SW1-3,Display1,J1", "variants": [] }, "sheets": [ diff --git a/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_sch b/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_sch index 4dd5889..5272aeb 100644 --- a/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_sch +++ b/KugelmühleSchaltplan/KugelmühleSchaltplan.kicad_sch @@ -5,6 +5,269 @@ (uuid "08a39202-f0bc-425a-a79b-1d2766a907c0") (paper "A4") (lib_symbols + (symbol "Conn_01x04_Pin_1" + (pin_names + (offset 1.016) + (hide yes) + ) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (duplicate_pin_numbers_are_jumpers no) + (property "Reference" "MotorTreiber" + (at 0.635 7.62 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "" + (at 0.635 5.08 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "Package_DFN_QFN:HVQFN-24-1EP_4x4mm_P0.5mm_EP2.1x2.1mm" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Generic connector, single row, 01x04, script generated" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_locked" "" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_keywords" "connector" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "ki_fp_filters" "Connector*:*_1x??_*" + (at 0 0 0) + (show_name no) + (do_not_autoplace no) + (hide yes) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (symbol "Conn_01x04_Pin_1_1_1" + (rectangle + (start 0.8636 2.667) + (end 0 2.413) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 0.127) + (end 0 -0.127) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -2.413) + (end 0 -2.667) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (rectangle + (start 0.8636 -4.953) + (end 0 -5.207) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type outline) + ) + ) + (polyline + (pts + (xy 1.27 2.54) (xy 0.8636 2.54) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 0) (xy 0.8636 0) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -2.54) (xy 0.8636 -2.54) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (polyline + (pts + (xy 1.27 -5.08) (xy 0.8636 -5.08) + ) + (stroke + (width 0.1524) + (type default) + ) + (fill + (type none) + ) + ) + (pin passive line + (at 5.08 0 180) + (length 3.81) + (name "<...>" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "CLK" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -2.54 180) + (length 3.81) + (name "<...>" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "DIR" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 -5.08 180) + (length 3.81) + (name "Pin_4" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "EN" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 2.54 180) + (length 3.81) + (name "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "GND" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + ) + (embedded_fonts no) + ) (symbol "Connector:Conn_01x04_Pin" (pin_names (offset 1.016) @@ -15,9 +278,9 @@ (on_board yes) (in_pos_files yes) (duplicate_pin_numbers_are_jumpers no) - (property "Reference" "J" - (at 0 5.08 0) - (show_name no) + (property "Reference" "J1" + (at 0.635 7.62 0) + (show_name yes) (do_not_autoplace no) (effects (font @@ -25,9 +288,9 @@ ) ) ) - (property "Value" "Conn_01x04_Pin" - (at 0 -7.62 0) - (show_name no) + (property "Value" "Diplay" + (at 0.635 5.08 0) + (show_name yes) (do_not_autoplace no) (effects (font @@ -35,7 +298,7 @@ ) ) ) - (property "Footprint" "" + (property "Footprint" "Package_DFN_QFN:HVQFN-24-1EP_4x4mm_P0.5mm_EP2.1x2.1mm" (at 0 0 0) (show_name no) (do_not_autoplace no) @@ -194,16 +457,16 @@ ) ) (pin passive line - (at 5.08 2.54 180) + (at 5.08 -5.08 180) (length 3.81) - (name "Pin_1" + (name "Pin_4" (effects (font (size 1.27 1.27) ) ) ) - (number "1" + (number "GND" (effects (font (size 1.27 1.27) @@ -214,14 +477,32 @@ (pin passive line (at 5.08 0 180) (length 3.81) - (name "Pin_2" + (name "<...>" (effects (font (size 1.27 1.27) ) ) ) - (number "2" + (number "SCL" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + ) + (pin passive line + (at 5.08 2.54 180) + (length 3.81) + (name "SDA" + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (number "SDA" (effects (font (size 1.27 1.27) @@ -232,32 +513,14 @@ (pin passive line (at 5.08 -2.54 180) (length 3.81) - (name "Pin_3" + (name "<...>" (effects (font (size 1.27 1.27) ) ) ) - (number "3" - (effects - (font - (size 1.27 1.27) - ) - ) - ) - ) - (pin passive line - (at 5.08 -5.08 180) - (length 3.81) - (name "Pin_4" - (effects - (font - (size 1.27 1.27) - ) - ) - ) - (number "4" + (number "VCC" (effects (font (size 1.27 1.27) @@ -1216,9 +1479,545 @@ (embedded_fonts no) ) ) + (junction + (at 121.92 144.78) + (diameter 0) + (color 0 0 0 0) + (uuid "3f4aad72-333a-41ac-8a33-004d56d05d4e") + ) + (junction + (at 73.66 72.39) + (diameter 0) + (color 0 0 0 0) + (uuid "454608f1-aeb8-4ae7-a648-85f48964cd3a") + ) + (junction + (at 163.83 80.01) + (diameter 0) + (color 0 0 0 0) + (uuid "47322e5d-43c6-404a-8084-1570b91d6298") + ) + (junction + (at 73.66 86.36) + (diameter 0) + (color 0 0 0 0) + (uuid "c2b3b985-a89c-47be-a6a2-e4e880afd361") + ) + (junction + (at 73.66 60.96) + (diameter 0) + (color 0 0 0 0) + (uuid "f010694d-3526-44fe-98ff-3b23815a6c3e") + ) + (junction + (at 167.64 80.01) + (diameter 0) + (color 0 0 0 0) + (uuid "f8707d1c-b191-405d-9129-e9c882e0e150") + ) + (wire + (pts + (xy 97.79 118.11) (xy 97.79 76.2) + ) + (stroke + (width 0) + (type default) + ) + (uuid "014ead51-9680-4dd6-86b5-00998759ff2f") + ) + (wire + (pts + (xy 121.92 144.78) (xy 162.56 144.78) + ) + (stroke + (width 0) + (type default) + ) + (uuid "040cf67e-4bd3-4bc1-8c3a-bcd9e5e4edc2") + ) + (wire + (pts + (xy 107.95 101.6) (xy 107.95 95.25) + ) + (stroke + (width 0) + (type default) + ) + (uuid "1d1bab62-99e8-4b52-b8ce-49ff1b7ff4d1") + ) + (wire + (pts + (xy 140.97 128.27) (xy 167.64 128.27) + ) + (stroke + (width 0) + (type default) + ) + (uuid "24a48fa0-5e80-4b86-a4b7-7dcf72769fd6") + ) + (wire + (pts + (xy 156.21 95.25) (xy 176.53 95.25) + ) + (stroke + (width 0) + (type default) + ) + (uuid "28a2cc89-28bf-4c95-816e-8bbee0fab722") + ) + (wire + (pts + (xy 78.74 72.39) (xy 73.66 72.39) + ) + (stroke + (width 0) + (type default) + ) + (uuid "31fe600a-d65f-4a14-bf08-7779d94ab58a") + ) + (wire + (pts + (xy 88.9 60.96) (xy 106.68 60.96) + ) + (stroke + (width 0) + (type default) + ) + (uuid "32c69609-b62c-423d-a683-bae687351e12") + ) + (wire + (pts + (xy 106.68 80.01) (xy 110.49 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "3f663840-7c10-4393-8eaa-774530e1aede") + ) + (wire + (pts + (xy 92.71 104.14) (xy 92.71 144.78) + ) + (stroke + (width 0) + (type default) + ) + (uuid "415aef43-4643-4f1f-a48e-f80f09c19e42") + ) + (wire + (pts + (xy 177.8 80.01) (xy 167.64 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "4f531d26-8f3e-48aa-9d4c-d67fece056bf") + ) + (wire + (pts + (xy 78.74 86.36) (xy 73.66 86.36) + ) + (stroke + (width 0) + (type default) + ) + (uuid "4fa3013a-fc10-4569-a20d-875260aef9f7") + ) + (wire + (pts + (xy 179.07 99.06) (xy 156.21 99.06) + ) + (stroke + (width 0) + (type default) + ) + (uuid "55957ce7-1d13-4c61-aeaf-b48d9b66829c") + ) + (wire + (pts + (xy 163.83 80.01) (xy 156.21 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "5ba5e3c9-74b2-4d66-8d08-35fe7557a711") + ) + (wire + (pts + (xy 107.95 95.25) (xy 110.49 95.25) + ) + (stroke + (width 0) + (type default) + ) + (uuid "5e998706-acea-4e65-80da-2813ff2fdf84") + ) + (wire + (pts + (xy 92.71 144.78) (xy 121.92 144.78) + ) + (stroke + (width 0) + (type default) + ) + (uuid "625324c2-1e3e-404c-955d-16deab625f8f") + ) + (wire + (pts + (xy 73.66 86.36) (xy 73.66 106.68) + ) + (stroke + (width 0) + (type default) + ) + (uuid "7804fabd-61ae-4deb-ae95-f271d35b4db0") + ) + (wire + (pts + (xy 167.64 80.01) (xy 163.83 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "78cb884a-659b-42b7-8d94-b643577883b8") + ) + (wire + (pts + (xy 73.66 72.39) (xy 73.66 60.96) + ) + (stroke + (width 0) + (type default) + ) + (uuid "78d4fd7d-9988-41ac-808b-f07dbb0569d0") + ) + (wire + (pts + (xy 102.87 99.06) (xy 102.87 91.44) + ) + (stroke + (width 0) + (type default) + ) + (uuid "84e2548a-a568-4ca8-9c47-ca8c80686d37") + ) + (wire + (pts + (xy 185.42 88.9) (xy 177.8 88.9) + ) + (stroke + (width 0) + (type default) + ) + (uuid "88e176da-3809-4d5f-88b3-4d4f8776672b") + ) + (wire + (pts + (xy 73.66 60.96) (xy 73.66 48.26) + ) + (stroke + (width 0) + (type default) + ) + (uuid "89f6893f-cda9-4ff9-b651-e0e4f8adbdd8") + ) + (wire + (pts + (xy 121.92 128.27) (xy 121.92 144.78) + ) + (stroke + (width 0) + (type default) + ) + (uuid "8b0e9533-820f-48aa-8513-aab047267bd8") + ) + (wire + (pts + (xy 177.8 88.9) (xy 177.8 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "8b21c44c-f273-4e35-a660-3d6b089d9a4d") + ) + (wire + (pts + (xy 109.22 87.63) (xy 110.49 87.63) + ) + (stroke + (width 0) + (type default) + ) + (uuid "9002a192-1085-43bf-ac13-fa029bc29100") + ) + (wire + (pts + (xy 102.87 91.44) (xy 110.49 91.44) + ) + (stroke + (width 0) + (type default) + ) + (uuid "91175461-9052-4727-b73f-626b7ab3c042") + ) + (wire + (pts + (xy 105.41 83.82) (xy 110.49 83.82) + ) + (stroke + (width 0) + (type default) + ) + (uuid "91a22082-1a30-4ad1-a759-9b2bd217047c") + ) + (wire + (pts + (xy 73.66 72.39) (xy 73.66 86.36) + ) + (stroke + (width 0) + (type default) + ) + (uuid "97b6368e-d3d4-4daf-b6e3-c9f857b20c2a") + ) + (wire + (pts + (xy 69.85 104.14) (xy 92.71 104.14) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ae9b1fb5-a310-4395-a413-4d909abed7ec") + ) + (wire + (pts + (xy 78.74 60.96) (xy 73.66 60.96) + ) + (stroke + (width 0) + (type default) + ) + (uuid "b22fbf97-1fd3-4635-a1ac-87ab25e4450a") + ) + (wire + (pts + (xy 88.9 86.36) (xy 109.22 86.36) + ) + (stroke + (width 0) + (type default) + ) + (uuid "b3716176-e0ca-4f8f-a7a1-24e828bc9e23") + ) + (wire + (pts + (xy 125.73 128.27) (xy 121.92 128.27) + ) + (stroke + (width 0) + (type default) + ) + (uuid "b9155000-a0bf-4fbc-a4bb-1dba9e619093") + ) + (wire + (pts + (xy 162.56 144.78) (xy 162.56 83.82) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c18e5549-78f7-4bef-b063-6a996bc0d92c") + ) + (wire + (pts + (xy 156.21 91.44) (xy 185.42 91.44) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c211721b-66ee-4219-ba57-72fe79d9acf7") + ) + (wire + (pts + (xy 163.83 48.26) (xy 163.83 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c46e1020-a514-4603-8925-761d5b34a1a6") + ) + (wire + (pts + (xy 176.53 93.98) (xy 185.42 93.98) + ) + (stroke + (width 0) + (type default) + ) + (uuid "c6108d17-5c8f-4ed0-a930-83c941d1bf7c") + ) + (wire + (pts + (xy 69.85 101.6) (xy 107.95 101.6) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ccded785-fe43-488a-97ca-55954c18a4a3") + ) + (wire + (pts + (xy 97.79 76.2) (xy 110.49 76.2) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ce19278b-58f9-4804-a47e-674691fd9cea") + ) + (wire + (pts + (xy 176.53 93.98) (xy 176.53 95.25) + ) + (stroke + (width 0) + (type default) + ) + (uuid "d3176749-d367-4ea0-835a-3947c461b024") + ) + (wire + (pts + (xy 106.68 60.96) (xy 106.68 80.01) + ) + (stroke + (width 0) + (type default) + ) + (uuid "d5ce48cc-a922-447e-85bd-dd74cfce28d0") + ) + (wire + (pts + (xy 179.07 96.52) (xy 179.07 99.06) + ) + (stroke + (width 0) + (type default) + ) + (uuid "d959dd47-3196-4a70-a752-b22cffdfd4b0") + ) + (wire + (pts + (xy 105.41 72.39) (xy 105.41 83.82) + ) + (stroke + (width 0) + (type default) + ) + (uuid "e20ea9fd-8af1-4631-8d4d-004dea03001e") + ) + (wire + (pts + (xy 185.42 96.52) (xy 179.07 96.52) + ) + (stroke + (width 0) + (type default) + ) + (uuid "e4103f9f-84d1-45c6-89a4-9ea907f6c015") + ) + (wire + (pts + (xy 162.56 83.82) (xy 156.21 83.82) + ) + (stroke + (width 0) + (type default) + ) + (uuid "e66e8d21-40ca-45a3-8fc7-757bbf36dc52") + ) + (wire + (pts + (xy 167.64 80.01) (xy 167.64 128.27) + ) + (stroke + (width 0) + (type default) + ) + (uuid "eb52d608-283e-4968-8745-f3e2c2844d33") + ) + (wire + (pts + (xy 69.85 106.68) (xy 73.66 106.68) + ) + (stroke + (width 0) + (type default) + ) + (uuid "eb60a395-4c73-4fd5-8f61-9e99bfeb0d28") + ) + (wire + (pts + (xy 109.22 86.36) (xy 109.22 87.63) + ) + (stroke + (width 0) + (type default) + ) + (uuid "ed4fa6ce-1c21-43ec-8893-99d6ba1d35e4") + ) + (wire + (pts + (xy 69.85 99.06) (xy 102.87 99.06) + ) + (stroke + (width 0) + (type default) + ) + (uuid "edc3368b-cb53-486f-9b5d-97c4d9c4de44") + ) + (wire + (pts + (xy 88.9 72.39) (xy 105.41 72.39) + ) + (stroke + (width 0) + (type default) + ) + (uuid "eede9df0-ad9c-484e-822b-5196002dc06f") + ) + (wire + (pts + (xy 133.35 118.11) (xy 97.79 118.11) + ) + (stroke + (width 0) + (type default) + ) + (uuid "f05fe509-0725-4c8e-ae89-6db03a745fd3") + ) + (wire + (pts + (xy 73.66 48.26) (xy 163.83 48.26) + ) + (stroke + (width 0) + (type default) + ) + (uuid "f2329298-1ffe-4fcb-b3de-52abdfaf19de") + ) (symbol (lib_id "Switch:SW_Push") - (at 207.01 114.3 0) + (at 83.82 86.36 0) (unit 1) (body_style 1) (exclude_from_sim no) @@ -1229,7 +2028,7 @@ (fields_autoplaced yes) (uuid "0ecb6888-f4b4-438a-88e8-a422ad205b84") (property "Reference" "buttonStop" - (at 207.01 106.68 0) + (at 83.82 78.74 0) (show_name no) (do_not_autoplace no) (effects @@ -1239,7 +2038,7 @@ ) ) (property "Value" "SW_Push" - (at 207.01 109.22 0) + (at 83.82 81.28 0) (show_name no) (do_not_autoplace no) (effects @@ -1249,7 +2048,7 @@ ) ) (property "Footprint" "Button_Switch_SMD:Nidec_Copal_SH-7040B" - (at 207.01 109.22 0) + (at 83.82 81.28 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1260,7 +2059,7 @@ ) ) (property "Datasheet" "" - (at 207.01 109.22 0) + (at 83.82 81.28 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1271,7 +2070,7 @@ ) ) (property "Description" "Push button switch, generic, two pins" - (at 207.01 114.3 0) + (at 83.82 86.36 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1298,7 +2097,7 @@ ) (symbol (lib_id "Connector:Conn_01x04_Pin") - (at 74.93 38.1 0) + (at 64.77 101.6 0) (unit 1) (body_style 1) (exclude_from_sim no) @@ -1308,8 +2107,8 @@ (dnp no) (fields_autoplaced yes) (uuid "27876009-53a2-4650-ba67-221ea18f35d0") - (property "Reference" "J1" - (at 75.565 30.48 0) + (property "Reference" "Display" + (at 65.405 93.98 0) (show_name no) (do_not_autoplace no) (effects @@ -1318,8 +2117,8 @@ ) ) ) - (property "Value" "Diplay" - (at 75.565 33.02 0) + (property "Value" "" + (at 65.405 96.52 0) (show_name no) (do_not_autoplace no) (effects @@ -1329,7 +2128,7 @@ ) ) (property "Footprint" "Package_DFN_QFN:HVQFN-24-1EP_4x4mm_P0.5mm_EP2.1x2.1mm" - (at 74.93 38.1 0) + (at 64.77 101.6 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1340,7 +2139,7 @@ ) ) (property "Datasheet" "" - (at 74.93 38.1 0) + (at 64.77 101.6 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1351,7 +2150,7 @@ ) ) (property "Description" "Generic connector, single row, 01x04, script generated" - (at 74.93 38.1 0) + (at 64.77 101.6 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1361,22 +2160,22 @@ ) ) ) - (pin "3" + (pin "SDA" (uuid "c9c57965-15d6-459c-bf6a-b318a5a98035") ) - (pin "1" + (pin "VCC" (uuid "1324a5c4-da82-4572-8475-aafd89d3754e") ) - (pin "2" + (pin "SCL" (uuid "518b75bc-1c6a-450a-ba80-f38270122c51") ) - (pin "4" + (pin "GND" (uuid "652ec2a9-9e81-408b-99ea-e509d9679231") ) (instances (project "KugelmühleSchaltplan" (path "/08a39202-f0bc-425a-a79b-1d2766a907c0" - (reference "J1") + (reference "Display") (unit 1) ) ) @@ -1407,6 +2206,7 @@ ) (property "Value" "XIAO-ESP32-C6-SMD" (at 136.7633 107.95 0) + (hide yes) (show_name no) (do_not_autoplace no) (effects @@ -1532,7 +2332,7 @@ ) (symbol (lib_id "Sensor_Temperature:LM35-LP") - (at 139.7 34.29 0) + (at 133.35 128.27 90) (unit 1) (body_style 1) (exclude_from_sim no) @@ -1543,29 +2343,27 @@ (fields_autoplaced yes) (uuid "ad1f4f7f-a9d9-4342-8775-68685cf988f6") (property "Reference" "U2" - (at 130.81 33.0199 0) + (at 133.35 138.43 90) (show_name no) (do_not_autoplace no) (effects (font (size 1.27 1.27) ) - (justify right) ) ) (property "Value" "LM35-LP" - (at 130.81 35.5599 0) + (at 133.35 140.97 90) (show_name no) (do_not_autoplace no) (effects (font (size 1.27 1.27) ) - (justify right) ) ) (property "Footprint" "Package_TO_SOT_THT:TO-92_Inline" - (at 140.97 40.64 0) + (at 139.7 127 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1577,7 +2375,7 @@ ) ) (property "Datasheet" "http://www.ti.com/lit/ds/symlink/lm35.pdf" - (at 139.7 34.29 0) + (at 133.35 128.27 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1588,7 +2386,7 @@ ) ) (property "Description" "Precision centigrade temperature sensor, TO-92" - (at 139.7 34.29 0) + (at 133.35 128.27 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1617,8 +2415,10 @@ ) ) (symbol - (lib_id "Switch:SW_Push") - (at 207.01 102.87 0) + (lib_name "Conn_01x04_Pin_1") + (lib_id "Connector:Conn_01x04_Pin") + (at 190.5 91.44 0) + (mirror y) (unit 1) (body_style 1) (exclude_from_sim no) @@ -1626,10 +2426,9 @@ (on_board yes) (in_pos_files yes) (dnp no) - (fields_autoplaced yes) - (uuid "e3d1ac0f-c92d-4cd0-ae2b-cad42e548773") - (property "Reference" "SWbuttonMinus" - (at 207.01 95.25 0) + (uuid "bdb44891-6bcc-44e0-a59b-b1bd1284b722") + (property "Reference" "MotorTreiber" + (at 189.865 83.82 0) (show_name no) (do_not_autoplace no) (effects @@ -1638,8 +2437,8 @@ ) ) ) - (property "Value" "SW_Push" - (at 207.01 97.79 0) + (property "Value" "" + (at 189.865 86.36 0) (show_name no) (do_not_autoplace no) (effects @@ -1648,8 +2447,8 @@ ) ) ) - (property "Footprint" "Button_Switch_SMD:Nidec_Copal_SH-7040B" - (at 207.01 97.79 0) + (property "Footprint" "Package_DFN_QFN:HVQFN-24-1EP_4x4mm_P0.5mm_EP2.1x2.1mm" + (at 190.5 91.44 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1660,7 +2459,93 @@ ) ) (property "Datasheet" "" - (at 207.01 97.79 0) + (at 190.5 91.44 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Description" "Generic connector, single row, 01x04, script generated" + (at 190.5 91.44 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (pin "EN" + (uuid "54893520-fde1-4fa3-abd3-72be719f3b98") + ) + (pin "CLK" + (uuid "347cd0a9-c832-4a8e-9180-8d57ce00bb8f") + ) + (pin "DIR" + (uuid "9603dc51-d52c-4c26-a80a-64a0b8f50fb1") + ) + (pin "GND" + (uuid "b335123a-b068-4e2e-ab91-6bdf29972de1") + ) + (instances + (project "KugelmühleSchaltplan" + (path "/08a39202-f0bc-425a-a79b-1d2766a907c0" + (reference "MotorTreiber") + (unit 1) + ) + ) + ) + ) + (symbol + (lib_id "Switch:SW_Push") + (at 83.82 72.39 0) + (unit 1) + (body_style 1) + (exclude_from_sim no) + (in_bom yes) + (on_board yes) + (in_pos_files yes) + (dnp no) + (fields_autoplaced yes) + (uuid "e3d1ac0f-c92d-4cd0-ae2b-cad42e548773") + (property "Reference" "SWbuttonMinus" + (at 83.82 64.77 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Value" "SW_Push" + (at 83.82 67.31 0) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Footprint" "Button_Switch_SMD:Nidec_Copal_SH-7040B" + (at 83.82 67.31 0) + (hide yes) + (show_name no) + (do_not_autoplace no) + (effects + (font + (size 1.27 1.27) + ) + ) + ) + (property "Datasheet" "" + (at 83.82 67.31 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1671,7 +2556,7 @@ ) ) (property "Description" "Push button switch, generic, two pins" - (at 207.01 102.87 0) + (at 83.82 72.39 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1698,7 +2583,7 @@ ) (symbol (lib_id "Switch:SW_Push") - (at 207.01 91.44 0) + (at 83.82 60.96 0) (unit 1) (body_style 1) (exclude_from_sim no) @@ -1709,7 +2594,7 @@ (fields_autoplaced yes) (uuid "ebc0ae61-3b52-4d66-bb5d-763303762925") (property "Reference" "buttonPlus" - (at 207.01 83.82 0) + (at 83.82 53.34 0) (show_name no) (do_not_autoplace no) (effects @@ -1719,7 +2604,7 @@ ) ) (property "Value" "SW_Push" - (at 207.01 86.36 0) + (at 83.82 55.88 0) (show_name no) (do_not_autoplace no) (effects @@ -1729,7 +2614,7 @@ ) ) (property "Footprint" "Button_Switch_SMD:Nidec_Copal_SH-7040B" - (at 207.01 86.36 0) + (at 83.82 55.88 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1740,7 +2625,7 @@ ) ) (property "Datasheet" "" - (at 207.01 86.36 0) + (at 83.82 55.88 0) (hide yes) (show_name no) (do_not_autoplace no) @@ -1751,7 +2636,7 @@ ) ) (property "Description" "Push button switch, generic, two pins" - (at 207.01 91.44 0) + (at 83.82 60.96 0) (hide yes) (show_name no) (do_not_autoplace no) diff --git a/KugelmühleSchaltplan/KugelmühleSchaltplan.pdf b/KugelmühleSchaltplan/KugelmühleSchaltplan.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3a248b3e61f3e01134d8421c1e549edc25194173 GIT binary patch literal 62397 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μ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 #include -// U8g2-Objekt bleibt gekapselt in dieser Datei +// Bitmaps & Animation-Dateien aus Lopaka +//#include "Clock.h" +//#include "Clock.h" +//#include "fire_flames.h" + +uint32_t lastDispTime = 0; + +// Statische Bitmap aus Lopaka +static const unsigned char image_paint_27_bits[] U8X8_PROGMEM = { + 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, + 0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x00,0x00,0x01,0x00 +}; + +// Animations-Zähler +//static uint8_t fire_flames_frame = 0; +//static uint8_t Clock_frame = 0; + +// U8g2-Display-Objekt static U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); void initDisplay() { @@ -11,10 +31,86 @@ void initDisplay() { u8g2.begin(); } +// ############################################################# +// ANIMATIONEN BERECHNEN & ZEICHNEN +// ############################################################# +static void updateAnimations() { + //fire_flames_frame = (millis() / 77) % 8; + //Clock_frame = (millis() / 200) % 143; +} + +static void drawAnimation_fire_flames() { + //u8g2.setDrawColor(1); + // u8g2.drawXBMP(80, 30, 21, 32, fire_flames_frames[fire_flames_frame]); +} + +static void drawAnimation_Clock() { + //u8g2.setDrawColor(1); + // u8g2.drawXBMP(104, 40, 21, 21, Clock_frames[Clock_frame]); +} + // ############################################################# // HAUPTANZEIGE // ############################################################# -static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid, bool timerActive) { +static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid, bool timerActive, SystemSettings settings, int curTemp) { + u8g2.setFontMode(1); + u8g2.setBitmapMode(1); + u8g2.setDrawColor(1); // 1 = Weiß (an) + + // 1. Feste Beschriftungen + u8g2.setFont(u8g2_font_5x7_tr); + u8g2.drawStr(7, 8, "Geschw"); + u8g2.drawStr(7, 19, "Zeituhr"); + u8g2.drawStr(7, 30, "Temp"); + + // 2. Dynamischer Wert: Geschwindigkeit + char speedBuf[10]; + snprintf(speedBuf, sizeof(speedBuf), "%d", currentSpeed); + u8g2.drawStr(51, 8, speedBuf); + + // 3. Dynamische Zeitschaltuhr: Start- und Endzeit + char startBuf[8]; + char endBuf[8]; + snprintf(startBuf, sizeof(startBuf), "%02d:%02d", settings.startHour, settings.startMin); + snprintf(endBuf, sizeof(endBuf), "%02d:%02d", settings.endHour, settings.endMin); + + u8g2.drawStr(51, 19, startBuf); + u8g2.drawLine(79, 16, 83, 16); // Bindestrich zwischen Zeiten + u8g2.drawStr(89, 19, endBuf); + + // 4. Dynamische Temperatur (Ist & Soll/Max) + // Hinweis: Hier kannst du später deine reale Sensortemperatur übergeben + char curTempBuf[10]; + snprintf(curTempBuf, sizeof(curTempBuf), "%d", curTemp); + u8g2.drawStr(52, 30, curTempBuf); + u8g2.drawLine(67, 24, 67, 29); // Trennstrich + + char maxTempBuf[8]; + snprintf(maxTempBuf, sizeof(maxTempBuf), "%d", settings.maxTemp); + u8g2.drawStr(74, 30, maxTempBuf); + + // 5. Große aktuelle Uhrzeit unten links + u8g2.setFont(u8g2_font_6x10_tr); + char timeBuf[10]; + if (timeValid) { + snprintf(timeBuf, sizeof(timeBuf), "%02d:%02d", curH, curM); + } else { + snprintf(timeBuf, sizeof(timeBuf), "--:--"); + } + u8g2.drawStr(4, 60, timeBuf); + + // 6. Lopaka Deko-Bitmap + u8g2.drawXBMP(28, 4, 16, 26, image_paint_27_bits); + + // 7. Lopaka Animationen abspielen + //drawAnimation_fire_flames(); + //drawAnimation_Clock(); +} + +// ############################################################# +// Zeitschaltuhr +// ############################################################# +static void drawTimerScreen(TimeEditStep timeEditStep, uint8_t settingIdx, const SystemSettings& settings){ } @@ -24,17 +120,10 @@ static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid, static void drawSettingsScreen(uint8_t settingIdx, TimeEditStep timeEditStep, const SystemSettings& s) { if(timeEditStep != EDIT_NONE){ - drawTimerScreen(TimeEditStep timeEditStep, uint8_t settingIdx, const SystemSettings& s); + drawTimerScreen(timeEditStep, settingIdx, s); } } -// ############################################################# -// Zeitschaltuhr -// ############################################################# -static void drawTimerScreen(TimeEditStep timeEditStep, uint8_t settingIdx, const SystemSettings& s){ - -} - // ############################################################# // Main Funktion // ############################################################# @@ -43,15 +132,18 @@ void updateDisplay(bool inSettings, TimeEditStep editStep, const SystemSettings& settings, int currentSpeed, - int curH, int curM, bool timeValid) { + int curH, int curM, bool timeValid, int curTemp) { + if (millis() - lastDispTime >= 50) { + lastDispTime = millis(); - u8g2.clearBuffer(); + u8g2.clearBuffer(); - if (inSettings) { - drawSettingsScreen(settingIdx, editStep, settings); - }else{ - drawHomeScreen(currentSpeed, curH, curM, timeValid, settings.timerEnabled); - } + if (inSettings) { + drawSettingsScreen(settingIdx, editStep, settings); + }else{ + drawHomeScreen(currentSpeed, curH, curM, timeValid, settings.timerEnabled, settings, curTemp); + } - u8g2.sendBuffer(); + u8g2.sendBuffer(); + } } \ No newline at end of file diff --git a/display_ui.h b/display_ui.h index 1ae8fb0..0751512 100644 --- a/display_ui.h +++ b/display_ui.h @@ -10,4 +10,4 @@ void updateDisplay(bool inSettings, TimeEditStep editStep, const SystemSettings& settings, int currentSpeed, - int curH, int curM, bool timeValid); \ No newline at end of file + int curH, int curM, bool timeValid, int curTemp); \ No newline at end of file diff --git a/jentest.ino b/jentest.ino new file mode 100644 index 0000000..34e0e96 --- /dev/null +++ b/jentest.ino @@ -0,0 +1,393 @@ +#include +#include +#include + + +const char* ssid = "Stockfeld"; +const char* password = "70691554384740972413"; + +// NTP-Server & Zeitzone für Deutschland +const char* ntpServer = "pool.ntp.org"; +const char* tzInfo = "CET-1CEST,M3.5.0,M10.5.0/3"; + +FastAccelStepperEngine engine = FastAccelStepperEngine(); +FastAccelStepper *stepper = NULL; + +// ################ Variabeln ################ +const uint32_t MAX_SPEED_HZ = 106000; +const int32_t COLDTEMP_C = 50; + +bool clickPlus = 0; +bool clickMinus = 0; +bool clickStop = 0; +bool holdPlus = 0; +bool holdMinus = 0; +bool holdStop = 0; + +bool shouldRun = true; +int lastSpeed = 0; + +int32_t lastControl = 0; +uint32_t lastPlotTime = 0; + +bool autoStop = false; +bool bSettings = false; +uint32_t curTemp = 0; + +struct tm timeinfo; + +TimeEditStep timeEditStep = EDIT_NONE; + +// fest in den Speicher schreiben +Preferences prefs; + +SystemSettings settings; + +//##################################### +//########### Hilfsfunktion ########### +//##################################### + +// Überladung des Präfix-Operators (++timeEditStep) +TimeEditStep& operator++(TimeEditStep& step) { + step = (step == EDIT_END_MIN) ? EDIT_NONE : static_cast(step + 1); + return step; +} + +// Werte aus dem Flash speicher laden +void loadSettings() { + // Namespace öffnen (Name max. 15 Zeichen, "true" = read-only) + prefs.begin("timer_cfg", true); + + // Werte auslesen + settings.startHour = prefs.getUChar("s_hour", 0); + settings.startMin = prefs.getUChar("s_min", 0); + settings.endHour = prefs.getUChar("e_hour", 0); + settings.endMin = prefs.getUChar("e_min", 0); + settings.timerEnabled = prefs.getBool("t_on", false); + settings.maxTemp = prefs.getShort("max_temp", 70); + settings.accelRate = prefs.getInt("accel_rate", 2000); + + prefs.end(); + Serial.println("[NVS] Einstellungen erfolgreich geladen."); +} + +// Save Settings in Flash Speichern +void saveSettings() { + prefs.begin("timer_cfg", false); // "false" = Read/Write + + prefs.putUChar("s_hour", settings.startHour); + prefs.putUChar("s_min", settings.startMin); + prefs.putUChar("e_hour", settings.endHour); + prefs.putUChar("e_min", settings.endMin); + prefs.putBool("t_on", settings.timerEnabled); + prefs.putShort("max_temp", settings.maxTemp); + prefs.putInt("accel_rate", settings.accelRate); + + prefs.end(); + Serial.println("[NVS] Einstellungen im Flash gespeichert."); +} + +void initWiFiAndTime() { + WiFi.begin(ssid, password); + + // Zeitzone und NTP-Server setzen + configTzTime(tzInfo, ntpServer); + + // Warten auf Verbindung (optional mit Timeout) + int retries = 0; + while (WiFi.status() != WL_CONNECTED && retries < 20) { + delay(500); + retries++; + } +} + +//####################################################### +//####################### Setup ######################### +//####################################################### +void setup() { + Serial.begin(115200); + delay(1000); // Zeit für USB-CDC-Verbindung geben + + // Daten aus Flash speicher laden + loadSettings(); + + engine.init(); + stepper = engine.stepperConnectToPin(stepPinStepper); + + if (stepper) { + stepper->setDirectionPin(dirPinStepper); + stepper->setEnablePin(enablePinStepper, true); + stepper->setAutoEnable(true); + stepper->setSpeedInHz(MAX_SPEED_HZ); + } + + // Pin Config + pinMode(buttonPlus, INPUT_PULLUP); + pinMode(buttonMinus, INPUT_PULLUP); + pinMode(buttonStop, INPUT_PULLUP); + + initWiFiAndTime(); + + initDisplay(); + + // Start Animation +} + +bool getCurrentTime(int &hour, int &minute, int &second) { + if (!getLocalTime(&timeinfo, 50)) { // 50ms Timeout + return false; // Noch keine NTP-Zeit synchronisiert + } + hour = timeinfo.tm_hour; + minute = timeinfo.tm_min; + second = timeinfo.tm_sec; + return true; +} + +// Rückgabe von Flanken (Klick) und Pegel (Halten) +void getInputs(bool &clickPlus, bool &clickMinus, bool &clickStop, + bool &holdPlus, bool &holdMinus, bool &holdStop) { + + // Physische Pegel einlesen (Active-Low) + bool curPlus = (digitalRead(buttonPlus) == LOW); + bool curMinus = (digitalRead(buttonMinus) == LOW); + bool curStop = (digitalRead(buttonStop) == LOW); + + // Speicher für vorherigen Durchlauf + static bool lastPlus = false; + static bool lastMinus = false; + static bool lastStop = false; + + // Nur bei Veränderung true (Sperre) + clickPlus = (curPlus && !lastPlus); + clickMinus = (curMinus && !lastMinus); + clickStop = (curStop && !lastStop); + + // Dauerzustand (für Stepper-Handbetrieb) + holdPlus = curPlus; + holdMinus = curMinus; + holdStop = curStop; + + // Zustand für nächsten Durchlauf merken + lastPlus = curPlus; + lastMinus = curMinus; + lastStop = curStop; +} + +// Liefert die Aktuelle Temperatur in °C +int getTempInC(uint8_t senTemp){ + int milliVolt = analogReadMilliVolts(senTemp); + return ((milliVolt - 500)/10); +} + +// Liefert true wenn der Timer aktuell Active ist und false wenn nicht aktiv +bool isTimerActiveNow(int curH, int curM, int startH, int startM, int endH, int endM) { + int current = curH * 60 + curM; + int start = startH * 60 + startM; + int end = endH * 60 + endM; + + // Fall A: Zeitfenster am selben Tag (z. B. 08:00 bis 16:00) + if (start <= end) { + return (current >= start && current < end); + } + // Fall B: Zeitfenster über Mitternacht (z. B. 22:00 bis 04:00) + else { + return (current >= start || current < end); + } +} + +// Die Funktion behandelt das gesammte Einstellungs menu +void setting(){ + //######### Timer Edit ######### + if (timeEditStep != EDIT_NONE) { + //PLUS GEDRÜCKT: Wert erhöhen + if (clickPlus || holdPlus) { + switch (timeEditStep) { + case EDIT_START_HOUR: + settings.startHour = (settings.startHour + 1) % 24; + break; + case EDIT_START_MIN: + settings.startMin = (settings.startMin + 5) % 60; + break; + case EDIT_END_HOUR: + settings.endHour = (settings.endHour + 1) % 24; + break; + case EDIT_END_MIN: + settings.endMin = (settings.endMin + 5) % 60; + break; + default: break; + } + } + + // MINUS GEDRÜCKT: Wert verringern + if (clickMinus) { + switch (timeEditStep) { + case EDIT_START_HOUR: + settings.startHour = (settings.startHour == 0) ? 23 : settings.startHour - 1; + break; + case EDIT_START_MIN: + settings.startMin = (settings.startMin == 0) ? 59 : settings.startMin -5; + break; + case EDIT_END_HOUR: + settings.endHour = (settings.endHour == 0) ? 23 : settings.endHour - 1; + break; + case EDIT_END_MIN: + settings.endMin = (settings.endMin == 0) ? 59 : settings.endMin - 5; + break; + default: break; + } + } + + // STOP GEDRÜCKT: Zum nächsten Wert springen + if (clickStop) { + ++timeEditStep; + } + + return; // Wichtig: Rest der Funktion überspringen, solange editiert wird! + } + + //######### Max Temp Edit ######### + if(settings.editMaxTemp){ + if(clickPlus){ + settings.maxTemp = (settings.maxTemp + 5) % 140; + } + if(clickPlus){ + settings.maxTemp = (settings.maxTemp == 0) ? -20 : settings.maxTemp - 5; + } + if(clickStop){ + settings.editMaxTemp = false; + } + return; // Wichtig: Rest der Funktion überspringen, solange editiert wird! + } + + //######### Beschleunigung Edit ######### + if(settings.editAcc){ + if(clickPlus){ + settings.accelRate = (settings.accelRate + 1000) % 20000; + } + if(clickPlus){ + settings.accelRate = (settings.accelRate == 0) ? 0 : settings.accelRate - 1000; + } + if(clickStop){ + settings.editAcc = false; + } + return; // Wichtig: Rest der Funktion überspringen, solange editiert wird! + } + + + //######### Menü ######### + // Menü bewegen + if(clickPlus){ + if(settings.settingIdx <= 2){ + settings.settingIdx++; + } + } + if(clickMinus){ + if(settings.settingIdx >=1){ + settings.settingIdx--; + } + } + + // Stop zum bestätigen + if (clickStop) { + if (settings.settingIdx == 0) { + // Zeitschaltuhr-Einstellung starten + timeEditStep = EDIT_START_HOUR; + } + else if (settings.settingIdx == 1) { + // Zeitschaltuhr ON/OFF + settings.timerEnabled = !settings.timerEnabled; + }else if (settings.settingIdx == 2) { + // Temperatur Grenze einstellen + settings.editMaxTemp = true; + }else if (settings.settingIdx == 3) { + // Beschleunigung + settings.editAcc = true; + }else if (settings.settingIdx == 4) { + // Menü verlassen + bSettings = false; + // Einstellungen Speichern + saveSettings(); + } + } +} + +void printStatus(FastAccelStepper *stepper, int speed, int clickPlus, int clickMinus){ + // Plotter-Ausgabe alle 50 ms (überflutet den Bus nicht) + if (millis() - lastPlotTime >= 50) { + lastPlotTime = millis(); + + int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs()); + + // Format kompatibel für den Arduino Serial Plotter + Serial.print("Current_Speed_U/Min:"); + Serial.print((60*currentSpeed)/3200); + Serial.print(" Accel_Control:"); + Serial.print(speed); + Serial.print(" Btn_Up:"); + Serial.print(clickPlus ? 5000 : 0); + Serial.print(" Btn_Down:"); + Serial.print(clickMinus ? -5000 : 0); + Serial.println(); + } +} + +//############################################################# +//#################### MAIN ################################### +//############################################################# +void loop() { + int32_t speed = 0; + + if (!stepper) { + Serial.println("[HALT] Kein Stepper-Objekt aktiv."); + delay(1000); + return; + } + + // Inputs + getInputs(clickPlus, clickMinus, clickStop, holdPlus, holdMinus, holdStop); + curTemp = getTempInC(senTemp); + + // zeitschaltuhr prüfen + int curH, curM, curS; + if (settings.timerEnabled && getCurrentTime(curH, curM, curS)) { + shouldRun = isTimerActiveNow(curH, curM, settings.startHour, settings.startMin, settings.endHour, settings.endMin); + } + + if(curTemp >= settings.maxTemp || !shouldRun){ + autoStop = true; + }else if(curTemp <= COLDTEMP_C){ + autoStop = false; + } + + // Main Control + if(bSettings){ + setting(); + }else if(clickStop || autoStop){ + stepper->stopMove(); + speed = 0; + if(clickStop && clickPlus){ + bSettings = true; + } + }else if(holdPlus){ + speed = settings.accelRate; + }else if(holdMinus){ + speed = -settings.accelRate; + }else{ + speed = 0; + } + + // Action + if (speed != lastSpeed) { + stepper->moveByAcceleration(speed, true); + lastSpeed = speed; + } + + int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs()); + + bool timeIsValid = getCurrentTime(curH, curM, curS); + updateDisplay(bSettings, settings.settingIdx, timeEditStep, settings, currentSpeed, curH, curM, timeIsValid, curTemp); + + // Status ausgabe auf Terminal + printStatus(stepper, speed, clickPlus, clickMinus); + +} \ No newline at end of file diff --git a/main.ino b/main.ino index cd7bebd..a9d6271 100644 --- a/main.ino +++ b/main.ino @@ -265,27 +265,6 @@ void setting(){ } } -void updateDisplay(){ - if (millis() - lastDispTime >= 50) { - lastDispTime = millis(); - int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs()); - - // einstellungs fenster - if(bSettings){ - // Mein Menu - - // Uhrzeit - - // Cursor mit settingIdx - //EDIT_START_HOUR - //EDIT_START_MIN - //EDIT_END_HOUR - //EDIT_END_MIN - - } - } -} - void printStatus(FastAccelStepper *stepper, int speed, int clickPlus, int clickMinus){ // Plotter-Ausgabe alle 50 ms (überflutet den Bus nicht) if (millis() - lastPlotTime >= 50) { @@ -339,7 +318,7 @@ void loop() { // Main Control if(bSettings){ - settings() + setting() }else if(clickStop || autoStop){ stepper->stopMove(); speed = 0; @@ -360,7 +339,10 @@ void loop() { lastSpeed = speed; } - updateDisplay() + int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs()); + + bool timeIsValid = getCurrentTime(curH, curM); + updateDisplay(bSettings, settings.settingIdx, timeEditStep, &settings, currentSpeed, timeIsValid, curTemp); // Status ausgabe auf Terminal printStatus(stepper, speed, clickPlus, clickMinus); diff --git a/types.h b/types.h index 9adf501..87e59ca 100644 --- a/types.h +++ b/types.h @@ -1,53 +1,23 @@ #pragma once #include #include +#include #include #include -const char* ssid = "DEIN_WLAN_NAME"; -const char* password = "DEIN_PASSWORT"; - -// NTP-Server & Zeitzone für Deutschland -const char* ntpServer = "pool.ntp.org"; -const char* tzInfo = "CET-1CEST,M3.5.0,M10.5.0/3"; - -FastAccelStepperEngine engine = FastAccelStepperEngine(); -FastAccelStepper *stepper = NULL; - // Pins -#define dirPinStepper D1 -#define enablePinStepper D2 -#define stepPinStepper D3 +#define dirPinStepper D8 +#define enablePinStepper D7 +#define stepPinStepper D9 -#define buttonPlus D7 -#define buttonMinus D8 -#define buttonStop D9 +#define buttonPlus D1 +#define buttonMinus D2 +#define buttonStop D3 #define senTemp D0 #define I2C_SDA D4 #define I2C_SCL D5 -// ################ Variabeln ################ -const uint32_t MAX_SPEED_HZ = 106000; -const int32_t COLDTEMP_C = 50; - -bool clickPlus = 0; -bool clickMinus = 0; -bool clickStop = 0; -bool holdPlus = 0; -bool holdMinus = 0; -bool holdStop = 0; - -int32_t lastControl = 0; -uint32_t lastPlotTime = 0; - -uint32_t lastDispTime = 0; -bool autoStop = false; -bool bSettings = false; -uint32_t curTemp = 0; - -struct tm timeinfo; - struct settings{ int settingIdx = 0; int startHour = 0; @@ -59,7 +29,7 @@ struct settings{ int16_t maxTemp = 70; //in °C bool editAcc = false; int32_t accelRate = 2000; -} +}; enum TimeEditStep { EDIT_NONE = 0, // Normales Menü (Navigation) @@ -69,20 +39,20 @@ enum TimeEditStep { EDIT_END_MIN // 4. End-Minute einstellen (0-59) }; -TimeEditStep timeEditStep = EDIT_NONE; -// fest in den Speicher schreiben -Preferences prefs; // Dein Einstellungs-Struct struct SystemSettings { - uint8_t startHour = 0; - uint8_t startMin = 0; - uint8_t endHour = 0; - uint8_t endMin = 0; + int settingIdx = 0; + int startHour = 0; + int startMin = 0; + int endHour = 0; + int endMin = 0; bool timerEnabled = false; - int16_t maxTemp = 70; - int32_t accelRate = 2000; + bool editMaxTemp = false; + int16_t maxTemp = 70; //in °C + bool editAcc = false; + int32_t accelRate = 2000; }; -SystemSettings settings; +