8 Commits

48 changed files with 108485 additions and 260 deletions

View File

@ -74,7 +74,7 @@
"ssh_key": "" "ssh_key": ""
}, },
"meta": { "meta": {
"filename": "0004-DenshaBekutoru.kicad_prl", "filename": "0004-DenshaBekutoru_v0.1.kicad_prl",
"version": 3 "version": 3
}, },
"project": { "project": {

View File

@ -239,7 +239,7 @@
"pinned_symbol_libs": [] "pinned_symbol_libs": []
}, },
"meta": { "meta": {
"filename": "0004-DenshaBekutoru.kicad_pro", "filename": "0004-DenshaBekutoru_v0.1.kicad_pro",
"version": 1 "version": 1
}, },
"net_settings": { "net_settings": {
@ -372,7 +372,7 @@
}, },
"net_format_name": "Spice Model", "net_format_name": "Spice Model",
"page_layout_descr_file": "", "page_layout_descr_file": "",
"plot_directory": "/home/tgohle/Desktop/git/ToGo-Lab/0004-DenshaBekutoru/KiCad/0004-DenshaBekutoru/", "plot_directory": "/home/tgohle/Desktop/git/ToGo-Lab/0004-DenshaBekutoru/KiCad/0004-DenshaBekutoru_v0.1/",
"spice_current_sheet_as_root": false, "spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"", "spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true, "spice_model_current_sheet_as_root": true,

View File

@ -6,7 +6,7 @@
(paper "A4") (paper "A4")
(title_block (title_block
(title "DenshaBekutoru 電車ベクトル (Train Vector)") (title "DenshaBekutoru 電車ベクトル (Train Vector)")
(date "2025-11-02") (date "2025-11-10")
(rev "#001") (rev "#001")
(company "ToGo-Lab") (company "ToGo-Lab")
(comment 1 "- https://togo-lab.io/") (comment 1 "- https://togo-lab.io/")
@ -2299,12 +2299,6 @@
(color 0 0 0 0) (color 0 0 0 0)
(uuid "18d14335-de9f-45f2-a4cc-180a2d8dc852") (uuid "18d14335-de9f-45f2-a4cc-180a2d8dc852")
) )
(junction
(at 182.88 106.68)
(diameter 0)
(color 0 0 0 0)
(uuid "1f239e7b-1e06-4b14-af20-034b4b4ffd89")
)
(junction (junction
(at 53.34 82.55) (at 53.34 82.55)
(diameter 0) (diameter 0)
@ -2324,10 +2318,10 @@
(uuid "30b28ed0-5697-4199-8822-158e2b1a60c8") (uuid "30b28ed0-5697-4199-8822-158e2b1a60c8")
) )
(junction (junction
(at 182.88 101.6) (at 208.28 111.76)
(diameter 0) (diameter 0)
(color 0 0 0 0) (color 0 0 0 0)
(uuid "3801c894-ae42-4eda-8d02-a60c9af73401") (uuid "3946b4d0-1318-4fdb-84c2-f810f95c281b")
) )
(junction (junction
(at 63.5 49.53) (at 63.5 49.53)
@ -2347,12 +2341,6 @@
(color 0 0 0 0) (color 0 0 0 0)
(uuid "62c162a4-02aa-4d73-a877-dd43b712ff83") (uuid "62c162a4-02aa-4d73-a877-dd43b712ff83")
) )
(junction
(at 233.68 104.14)
(diameter 0)
(color 0 0 0 0)
(uuid "69403b42-500c-4703-8b4b-71225e9752fd")
)
(junction (junction
(at 254 49.53) (at 254 49.53)
(diameter 0) (diameter 0)
@ -2371,24 +2359,30 @@
(color 0 0 0 0) (color 0 0 0 0)
(uuid "755fdb91-31e6-4c85-9a85-356faed56e78") (uuid "755fdb91-31e6-4c85-9a85-356faed56e78")
) )
(junction
(at 182.88 113.03)
(diameter 0)
(color 0 0 0 0)
(uuid "7584aefd-e768-4fad-9ef8-29c598224de3")
)
(junction (junction
(at 165.1 77.47) (at 165.1 77.47)
(diameter 0) (diameter 0)
(color 0 0 0 0) (color 0 0 0 0)
(uuid "7661277d-70d8-4690-ba7d-cd49253bbdbb") (uuid "7661277d-70d8-4690-ba7d-cd49253bbdbb")
) )
(junction
(at 208.28 111.76)
(diameter 0)
(color 0 0 0 0)
(uuid "7720ca20-9bd5-4382-86b1-332ffca59368")
)
(junction (junction
(at 127 58.42) (at 127 58.42)
(diameter 0) (diameter 0)
(color 0 0 0 0) (color 0 0 0 0)
(uuid "82ef0e26-c162-4d21-a930-310df31322ae") (uuid "82ef0e26-c162-4d21-a930-310df31322ae")
) )
(junction
(at 214.63 142.24)
(diameter 0)
(color 0 0 0 0)
(uuid "88077938-aa1d-4441-a812-b1bea64d7459")
)
(junction (junction
(at 76.2 58.42) (at 76.2 58.42)
(diameter 0) (diameter 0)
@ -2396,10 +2390,16 @@
(uuid "93826f1f-32d3-46b1-8387-53e4a96a8d03") (uuid "93826f1f-32d3-46b1-8387-53e4a96a8d03")
) )
(junction (junction
(at 208.28 99.06) (at 233.68 110.49)
(diameter 0) (diameter 0)
(color 0 0 0 0) (color 0 0 0 0)
(uuid "9d05bd90-8bfe-4b81-b321-b8273bc65092") (uuid "9a844833-2e1e-4ee4-b470-2fb0d234712e")
)
(junction
(at 227.33 139.7)
(diameter 0)
(color 0 0 0 0)
(uuid "9f28060d-90ac-4c8f-9507-b3471e0ddcd1")
) )
(junction (junction
(at 114.3 49.53) (at 114.3 49.53)
@ -2438,10 +2438,10 @@
(uuid "ce2f90af-1659-40af-b731-f02d61bb1e3a") (uuid "ce2f90af-1659-40af-b731-f02d61bb1e3a")
) )
(junction (junction
(at 233.68 109.22) (at 240.03 140.97)
(diameter 0) (diameter 0)
(color 0 0 0 0) (color 0 0 0 0)
(uuid "e579b160-1f59-44ec-a035-ed2c06c25011") (uuid "dc5976c8-65a3-4be8-90d6-fe61922b0432")
) )
(junction (junction
(at 222.25 92.71) (at 222.25 92.71)
@ -2483,16 +2483,6 @@
) )
(uuid "03871aea-97d7-4df5-a644-61febfe36353") (uuid "03871aea-97d7-4df5-a644-61febfe36353")
) )
(wire
(pts
(xy 208.28 69.85) (xy 208.28 99.06)
)
(stroke
(width 0)
(type default)
)
(uuid "03f9927e-2206-4a73-bbea-f6e782a37f7b")
)
(wire (wire
(pts (pts
(xy 76.2 55.88) (xy 76.2 58.42) (xy 76.2 55.88) (xy 76.2 58.42)
@ -2513,16 +2503,6 @@
) )
(uuid "077acef7-8d2f-4939-8819-d10bbdfd6345") (uuid "077acef7-8d2f-4939-8819-d10bbdfd6345")
) )
(wire
(pts
(xy 208.28 111.76) (xy 250.19 111.76)
)
(stroke
(width 0)
(type default)
)
(uuid "082f72d9-2fc8-4469-94c6-6cb9280f9977")
)
(wire (wire
(pts (pts
(xy 50.8 49.53) (xy 63.5 49.53) (xy 50.8 49.53) (xy 63.5 49.53)
@ -2535,23 +2515,23 @@
) )
(wire (wire
(pts (pts
(xy 233.68 109.22) (xy 252.73 109.22) (xy 189.23 137.16) (xy 189.23 142.24)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "0c898650-b37b-4cae-a9d8-27195bbb4396") (uuid "0c13ccac-cce8-42a0-820d-d03a8790adb7")
) )
(wire (wire
(pts (pts
(xy 208.28 99.06) (xy 208.28 111.76) (xy 254 113.03) (xy 254 139.7)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "0ca3aab4-c892-49b3-b42a-01f0ffe5d91e") (uuid "0d57923f-8ff5-40b0-9a64-e0ca56564ab2")
) )
(wire (wire
(pts (pts
@ -2573,6 +2553,16 @@
) )
(uuid "127e5934-d799-4acc-8376-348ea723e5b5") (uuid "127e5934-d799-4acc-8376-348ea723e5b5")
) )
(wire
(pts
(xy 255.27 111.76) (xy 255.27 140.97)
)
(stroke
(width 0)
(type default)
)
(uuid "162b7e51-8fc5-4fc9-800a-3dbb1710f5f3")
)
(wire (wire
(pts (pts
(xy 238.76 67.31) (xy 182.88 67.31) (xy 238.76 67.31) (xy 182.88 67.31)
@ -2605,33 +2595,23 @@
) )
(wire (wire
(pts (pts
(xy 257.81 147.32) (xy 257.81 104.14) (xy 208.28 111.76) (xy 208.28 114.3)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "1d364f04-23dd-4336-937c-2d6cb4cd5b37") (uuid "1e594437-c747-4142-bf93-d5c60d13cb81")
) )
(wire (wire
(pts (pts
(xy 240.03 152.4) (xy 264.16 152.4) (xy 240.03 140.97) (xy 176.53 140.97)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "225616c9-9869-456f-b62e-298c58f38ac5") (uuid "21b7c7bb-11d7-4208-a894-1ed9b6dc71fe")
)
(wire
(pts
(xy 252.73 139.7) (xy 252.73 109.22)
)
(stroke
(width 0)
(type default)
)
(uuid "231bec29-1fac-4e77-b372-a999d1d60763")
) )
(wire (wire
(pts (pts
@ -2645,7 +2625,7 @@
) )
(wire (wire
(pts (pts
(xy 233.68 104.14) (xy 233.68 109.22) (xy 233.68 72.39) (xy 233.68 110.49)
) )
(stroke (stroke
(width 0) (width 0)
@ -2685,13 +2665,13 @@
) )
(wire (wire
(pts (pts
(xy 233.68 72.39) (xy 233.68 104.14) (xy 233.68 110.49) (xy 233.68 114.3)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "2f2c9529-9c06-4377-a6eb-d622abac99bd") (uuid "34512f54-666e-4e4a-8cda-739c8897a60c")
) )
(wire (wire
(pts (pts
@ -2743,16 +2723,6 @@
) )
(uuid "3b785ac1-70c9-42d9-91b0-d1b7a300d3a4") (uuid "3b785ac1-70c9-42d9-91b0-d1b7a300d3a4")
) )
(wire
(pts
(xy 264.16 152.4) (xy 264.16 99.06)
)
(stroke
(width 0)
(type default)
)
(uuid "3b7c71ab-0d10-48fe-873f-2e76fa938cf6")
)
(wire (wire
(pts (pts
(xy 165.1 77.47) (xy 238.76 77.47) (xy 165.1 77.47) (xy 238.76 77.47)
@ -2813,6 +2783,16 @@
) )
(uuid "478627e1-22f0-4aa5-8f76-3cf20da43807") (uuid "478627e1-22f0-4aa5-8f76-3cf20da43807")
) )
(wire
(pts
(xy 201.93 137.16) (xy 201.93 139.7)
)
(stroke
(width 0)
(type default)
)
(uuid "49f1c1df-364e-4786-90aa-5c8ab3f3d486")
)
(wire (wire
(pts (pts
(xy 222.25 92.71) (xy 254 92.71) (xy 222.25 92.71) (xy 254 92.71)
@ -2833,6 +2813,16 @@
) )
(uuid "4d6622c3-b033-45ec-be29-398c0802ecf2") (uuid "4d6622c3-b033-45ec-be29-398c0802ecf2")
) )
(wire
(pts
(xy 208.28 111.76) (xy 255.27 111.76)
)
(stroke
(width 0)
(type default)
)
(uuid "4ea12a6b-db60-41f9-8806-fb74763d3b64")
)
(wire (wire
(pts (pts
(xy 114.3 46.99) (xy 114.3 49.53) (xy 114.3 46.99) (xy 114.3 49.53)
@ -2845,7 +2835,7 @@
) )
(wire (wire
(pts (pts
(xy 182.88 67.31) (xy 182.88 101.6) (xy 182.88 67.31) (xy 182.88 113.03)
) )
(stroke (stroke
(width 0) (width 0)
@ -2873,16 +2863,6 @@
) )
(uuid "5190df3c-09f0-4ac2-86fd-fdd45881d197") (uuid "5190df3c-09f0-4ac2-86fd-fdd45881d197")
) )
(wire
(pts
(xy 233.68 104.14) (xy 257.81 104.14)
)
(stroke
(width 0)
(type default)
)
(uuid "52439f80-4fb4-4838-ada4-cbfeaeee8fc4")
)
(wire (wire
(pts (pts
(xy 127 46.99) (xy 127 49.53) (xy 127 46.99) (xy 127 49.53)
@ -2913,16 +2893,6 @@
) )
(uuid "53fc23ba-ea79-488d-9c39-9ce730bd5817") (uuid "53fc23ba-ea79-488d-9c39-9ce730bd5817")
) )
(wire
(pts
(xy 176.53 142.24) (xy 250.19 142.24)
)
(stroke
(width 0)
(type default)
)
(uuid "548f29cf-4665-44c0-84b7-fa4b211ceb6b")
)
(wire (wire
(pts (pts
(xy 189.23 123.19) (xy 189.23 129.54) (xy 189.23 123.19) (xy 189.23 129.54)
@ -2943,16 +2913,6 @@
) )
(uuid "5adcb769-63e8-4dc6-9022-8c3dced2fc1a") (uuid "5adcb769-63e8-4dc6-9022-8c3dced2fc1a")
) )
(wire
(pts
(xy 201.93 137.16) (xy 201.93 144.78)
)
(stroke
(width 0)
(type default)
)
(uuid "5b378fd8-d1f7-4c32-900b-24f6a5bcafce")
)
(wire (wire
(pts (pts
(xy 69.85 91.44) (xy 69.85 92.71) (xy 69.85 91.44) (xy 69.85 92.71)
@ -3063,16 +3023,6 @@
) )
(uuid "695bb26e-eca8-4e2b-beed-eb2eeaa25e7e") (uuid "695bb26e-eca8-4e2b-beed-eb2eeaa25e7e")
) )
(wire
(pts
(xy 264.16 99.06) (xy 208.28 99.06)
)
(stroke
(width 0)
(type default)
)
(uuid "69d37a24-2f55-4eb8-9314-4776f03c3ffe")
)
(wire (wire
(pts (pts
(xy 254 45.72) (xy 254 49.53) (xy 254 45.72) (xy 254 49.53)
@ -3085,13 +3035,13 @@
) )
(wire (wire
(pts (pts
(xy 201.93 144.78) (xy 255.27 144.78) (xy 182.88 113.03) (xy 182.88 114.3)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "727d6958-57dc-4380-b73a-5026418021ce") (uuid "729f75d0-a040-43ca-a20a-ad6a7746aa99")
) )
(wire (wire
(pts (pts
@ -3113,26 +3063,6 @@
) )
(uuid "7ab0e3a2-d291-4644-91a2-310e3f3779b8") (uuid "7ab0e3a2-d291-4644-91a2-310e3f3779b8")
) )
(wire
(pts
(xy 250.19 142.24) (xy 250.19 111.76)
)
(stroke
(width 0)
(type default)
)
(uuid "7c3beac1-0ae4-4e05-91f3-88718ad266e5")
)
(wire
(pts
(xy 227.33 149.86) (xy 261.62 149.86)
)
(stroke
(width 0)
(type default)
)
(uuid "7fb6d153-f9f5-443a-a000-36bca9d349f1")
)
(wire (wire
(pts (pts
(xy 50.8 102.87) (xy 50.8 104.14) (xy 50.8 102.87) (xy 50.8 104.14)
@ -3155,13 +3085,23 @@
) )
(wire (wire
(pts (pts
(xy 176.53 137.16) (xy 176.53 142.24) (xy 256.54 110.49) (xy 256.54 142.24)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "84f2bdbb-ad23-4a30-9f6b-147501d2e6e1") (uuid "893bba9d-6d8d-439b-a8ee-0f8e4d85ae3b")
)
(wire
(pts
(xy 227.33 137.16) (xy 227.33 139.7)
)
(stroke
(width 0)
(type default)
)
(uuid "8a6c82dd-5ee1-4bac-a9b2-6fd9cf6f5643")
) )
(wire (wire
(pts (pts
@ -3183,16 +3123,6 @@
) )
(uuid "8f36358c-8110-4d1a-8d48-c37408cf3aef") (uuid "8f36358c-8110-4d1a-8d48-c37408cf3aef")
) )
(wire
(pts
(xy 233.68 109.22) (xy 233.68 114.3)
)
(stroke
(width 0)
(type default)
)
(uuid "913bc1ed-25d5-4ea2-b600-6bc559eb3168")
)
(wire (wire
(pts (pts
(xy 208.28 123.19) (xy 214.63 123.19) (xy 208.28 123.19) (xy 214.63 123.19)
@ -3223,6 +3153,16 @@
) )
(uuid "92b04ca6-d759-43f8-bbdc-5638b2d51062") (uuid "92b04ca6-d759-43f8-bbdc-5638b2d51062")
) )
(wire
(pts
(xy 255.27 140.97) (xy 240.03 140.97)
)
(stroke
(width 0)
(type default)
)
(uuid "9447f0b4-0b0d-4fe5-9775-1809a23b5005")
)
(wire (wire
(pts (pts
(xy 158.75 49.53) (xy 165.1 49.53) (xy 158.75 49.53) (xy 165.1 49.53)
@ -3245,33 +3185,13 @@
) )
(wire (wire
(pts (pts
(xy 182.88 101.6) (xy 182.88 106.68) (xy 233.68 110.49) (xy 256.54 110.49)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "982763b3-f7f1-4b51-8a97-cd1857910902") (uuid "9a300a0e-b692-474e-9f90-3fa69a7adbdb")
)
(wire
(pts
(xy 214.63 147.32) (xy 257.81 147.32)
)
(stroke
(width 0)
(type default)
)
(uuid "99b58e1e-63fe-4385-9ad3-78377caa2c6b")
)
(wire
(pts
(xy 189.23 139.7) (xy 252.73 139.7)
)
(stroke
(width 0)
(type default)
)
(uuid "9bb930c1-35a8-492d-8864-c4cec609cfe6")
) )
(wire (wire
(pts (pts
@ -3303,6 +3223,16 @@
) )
(uuid "a0bc0158-aef3-48a6-97f3-b4245e2346f1") (uuid "a0bc0158-aef3-48a6-97f3-b4245e2346f1")
) )
(wire
(pts
(xy 182.88 113.03) (xy 254 113.03)
)
(stroke
(width 0)
(type default)
)
(uuid "a103d7d7-dd85-439b-b914-5436d9cb9aa1")
)
(wire (wire
(pts (pts
(xy 54.61 85.09) (xy 55.88 85.09) (xy 54.61 85.09) (xy 55.88 85.09)
@ -3323,6 +3253,16 @@
) )
(uuid "a3bc624e-8b24-475a-9ae9-f857eac9aa4d") (uuid "a3bc624e-8b24-475a-9ae9-f857eac9aa4d")
) )
(wire
(pts
(xy 214.63 137.16) (xy 214.63 142.24)
)
(stroke
(width 0)
(type default)
)
(uuid "a4caf5f6-0faa-452d-8714-391f8ed973cf")
)
(wire (wire
(pts (pts
(xy 165.1 68.58) (xy 165.1 77.47) (xy 165.1 68.58) (xy 165.1 77.47)
@ -3345,23 +3285,13 @@
) )
(wire (wire
(pts (pts
(xy 227.33 137.16) (xy 227.33 149.86) (xy 214.63 142.24) (xy 189.23 142.24)
) )
(stroke (stroke
(width 0) (width 0)
(type default) (type default)
) )
(uuid "ac37cdac-25ad-434a-a1a1-c78237111ca4") (uuid "af6d0fe2-87fc-480d-a7cc-6cde78fc3fb1")
)
(wire
(pts
(xy 240.03 137.16) (xy 240.03 152.4)
)
(stroke
(width 0)
(type default)
)
(uuid "adaa6318-4f12-489e-b59e-ba90c8a1554d")
) )
(wire (wire
(pts (pts
@ -3373,16 +3303,6 @@
) )
(uuid "b1374777-4398-4187-b6a0-9465281b84b4") (uuid "b1374777-4398-4187-b6a0-9465281b84b4")
) )
(wire
(pts
(xy 261.62 149.86) (xy 261.62 101.6)
)
(stroke
(width 0)
(type default)
)
(uuid "b40b58ff-6914-4e05-a619-c465b4ba2209")
)
(wire (wire
(pts (pts
(xy 182.88 123.19) (xy 176.53 123.19) (xy 182.88 123.19) (xy 176.53 123.19)
@ -3393,16 +3313,6 @@
) )
(uuid "b76cabdd-3a68-4a5e-8430-138e00a5350b") (uuid "b76cabdd-3a68-4a5e-8430-138e00a5350b")
) )
(wire
(pts
(xy 214.63 137.16) (xy 214.63 147.32)
)
(stroke
(width 0)
(type default)
)
(uuid "b7ec96c4-d805-462d-99db-3a3020463c33")
)
(wire (wire
(pts (pts
(xy 53.34 73.66) (xy 55.88 73.66) (xy 53.34 73.66) (xy 55.88 73.66)
@ -3413,6 +3323,16 @@
) )
(uuid "bc7b09cc-b7d0-4e90-b681-6467ec5be6f6") (uuid "bc7b09cc-b7d0-4e90-b681-6467ec5be6f6")
) )
(wire
(pts
(xy 176.53 137.16) (xy 176.53 140.97)
)
(stroke
(width 0)
(type default)
)
(uuid "bf13604a-6704-43bc-846d-a2bbdc2d5aab")
)
(wire (wire
(pts (pts
(xy 63.5 58.42) (xy 76.2 58.42) (xy 63.5 58.42) (xy 76.2 58.42)
@ -3433,16 +3353,6 @@
) )
(uuid "c2082274-0c44-4e62-8322-b503953a2385") (uuid "c2082274-0c44-4e62-8322-b503953a2385")
) )
(wire
(pts
(xy 182.88 106.68) (xy 182.88 114.3)
)
(stroke
(width 0)
(type default)
)
(uuid "c35f91ae-df6b-4d61-8c0b-b70966a657e2")
)
(wire (wire
(pts (pts
(xy 238.76 69.85) (xy 208.28 69.85) (xy 238.76 69.85) (xy 208.28 69.85)
@ -3453,16 +3363,6 @@
) )
(uuid "c63d628a-8795-4c40-8732-347a0b08719f") (uuid "c63d628a-8795-4c40-8732-347a0b08719f")
) )
(wire
(pts
(xy 189.23 137.16) (xy 189.23 139.7)
)
(stroke
(width 0)
(type default)
)
(uuid "c8927b09-9613-4eac-a0a8-e7b049965fde")
)
(wire (wire
(pts (pts
(xy 152.4 74.93) (xy 238.76 74.93) (xy 152.4 74.93) (xy 238.76 74.93)
@ -3475,7 +3375,7 @@
) )
(wire (wire
(pts (pts
(xy 208.28 111.76) (xy 208.28 114.3) (xy 208.28 69.85) (xy 208.28 111.76)
) )
(stroke (stroke
(width 0) (width 0)
@ -3503,6 +3403,16 @@
) )
(uuid "cc015d09-efe0-4b4a-add3-2e0b8cc3cd77") (uuid "cc015d09-efe0-4b4a-add3-2e0b8cc3cd77")
) )
(wire
(pts
(xy 240.03 137.16) (xy 240.03 140.97)
)
(stroke
(width 0)
(type default)
)
(uuid "cc2d6793-b280-422c-b80d-02d4a29cfae9")
)
(wire (wire
(pts (pts
(xy 152.4 58.42) (xy 152.4 60.96) (xy 152.4 58.42) (xy 152.4 60.96)
@ -3523,16 +3433,6 @@
) )
(uuid "cdae4557-6272-4c5d-bf2f-f8b07dcc8dae") (uuid "cdae4557-6272-4c5d-bf2f-f8b07dcc8dae")
) )
(wire
(pts
(xy 182.88 101.6) (xy 261.62 101.6)
)
(stroke
(width 0)
(type default)
)
(uuid "cf1700ae-fd5a-4ab4-9f23-6ee0a5c8a3ce")
)
(wire (wire
(pts (pts
(xy 233.68 121.92) (xy 233.68 123.19) (xy 233.68 121.92) (xy 233.68 123.19)
@ -3613,6 +3513,16 @@
) )
(uuid "ed2d1d23-9c73-4f7a-8b96-87e2c7f148da") (uuid "ed2d1d23-9c73-4f7a-8b96-87e2c7f148da")
) )
(wire
(pts
(xy 227.33 139.7) (xy 201.93 139.7)
)
(stroke
(width 0)
(type default)
)
(uuid "ede25ee6-a01c-4891-9a5e-b55925e1a54b")
)
(wire (wire
(pts (pts
(xy 227.33 123.19) (xy 227.33 129.54) (xy 227.33 123.19) (xy 227.33 129.54)
@ -3633,6 +3543,16 @@
) )
(uuid "ef9f7809-5e6b-45c8-9644-679f84743bb9") (uuid "ef9f7809-5e6b-45c8-9644-679f84743bb9")
) )
(wire
(pts
(xy 256.54 142.24) (xy 214.63 142.24)
)
(stroke
(width 0)
(type default)
)
(uuid "f01911e7-a9d8-4ec0-8343-a969bb4a16f3")
)
(wire (wire
(pts (pts
(xy 127 49.53) (xy 127 50.8) (xy 127 49.53) (xy 127 50.8)
@ -3653,16 +3573,6 @@
) )
(uuid "f581af55-ffa5-4c77-b299-395ef0284bd8") (uuid "f581af55-ffa5-4c77-b299-395ef0284bd8")
) )
(wire
(pts
(xy 255.27 144.78) (xy 255.27 106.68)
)
(stroke
(width 0)
(type default)
)
(uuid "f5ab323b-6e45-4ffd-9d9e-29aabec80515")
)
(wire (wire
(pts (pts
(xy 69.85 80.01) (xy 69.85 81.28) (xy 69.85 80.01) (xy 69.85 81.28)
@ -3703,16 +3613,6 @@
) )
(uuid "f8ccf3eb-3caf-45a2-a97e-16395719fc9f") (uuid "f8ccf3eb-3caf-45a2-a97e-16395719fc9f")
) )
(wire
(pts
(xy 182.88 106.68) (xy 255.27 106.68)
)
(stroke
(width 0)
(type default)
)
(uuid "f8e744d1-4573-4a01-bb7d-ec640cd63dd4")
)
(wire (wire
(pts (pts
(xy 127 58.42) (xy 127 60.96) (xy 127 58.42) (xy 127 60.96)
@ -3733,9 +3633,19 @@
) )
(uuid "fac1ca40-1662-4c8b-ab11-b61ce411fd2b") (uuid "fac1ca40-1662-4c8b-ab11-b61ce411fd2b")
) )
(wire
(pts
(xy 254 139.7) (xy 227.33 139.7)
)
(stroke
(width 0)
(type default)
)
(uuid "fdca9757-291a-4a60-bd80-a3d5b956a35f")
)
(text "Idea:\nPWM and Charlieplexing for max. flexibility\nLater Layout: for each LED one Connector." (text "Idea:\nPWM and Charlieplexing for max. flexibility\nLater Layout: for each LED one Connector."
(exclude_from_sim no) (exclude_from_sim no)
(at 177.038 151.384 0) (at 177.038 149.352 0)
(effects (effects
(font (font
(size 1.27 1.27) (size 1.27 1.27)

View File

@ -0,0 +1 @@
/home/tgohle/Desktop/git/ToGo-Lab/0004-DenshaBekutoru/KiCad/0004-DenshaBekutoru_v0.2/_autosave-0004-DenshaBekutoru_v0.2.kicad_sch

View File

@ -0,0 +1,39 @@
*
.subckt 0004-DenshaBekutoru
.model __D2 D
.model __D1 D
R3 Net-_D10-A_ VCC 220
D10 __D10
C5 VCC GND 100n
U4 __U4
C4 VCC GND 4.7u
U3 __U3
R4 Net-_D11-A_ VCC 220
D11 __D11
R5 Net-_U3-_RESET/PB5_ VCC 10k
R6 Net-_D4-A_ Net-_D6-K_ 220
D6 __D6
D5 __D5
R7 Net-_D6-A_ Net-_D4-K_ 220
D4 __D4
C3 Net-_D3-K_ GND 100n
U1 __U1
C2 Net-_D3-K_ GND 47u
D3 __D3
U2 __U2
D2 Net-_D2-A_ Net-_D2-K_ __D2
C1 Net-_U3-_RESET/PB5_ GND 100n
SW1 __SW1
R8 Net-_D8-A_ Net-_D5-K_ 220
D7 __D7
D8 __D8
D9 __D9
R1 Net-_D2-A_ Net-_D1-K_ 1.8k
R2 Net-_D1-A_ Net-_D2-K_ 1.8k
D1 Net-_D1-A_ Net-_D1-K_ __D1
J1 __J1
.ends

View File

@ -0,0 +1,32 @@
ERC report (2026-01-25T14:36:13+0100, Encoding UTF8)
***** Sheet /
[pin_not_connected]: Pin not connected
; error (excluded)
@(10000.00 mils, 3950.00 mils): Symbol D7 Pin 1 [K, Passive, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(10000.00 mils, 3650.00 mils): Symbol D7 Pin 2 [A, Passive, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(9500.00 mils, 3950.00 mils): Symbol D6 Pin 1 [K, Passive, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(9500.00 mils, 3650.00 mils): Symbol D6 Pin 2 [A, Passive, Line]
[power_pin_not_driven]: Input Power pin not driven by any Output Power pins
; error (excluded)
@(5650.00 mils, 3350.00 mils): Symbol A1 Pin Vcc1 [Vcc, Power input, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(8500.00 mils, 3950.00 mils): Symbol D4 Pin 1 [K, Passive, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(8500.00 mils, 3650.00 mils): Symbol D4 Pin 2 [A, Passive, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(9000.00 mils, 3950.00 mils): Symbol D5 Pin 1 [K, Passive, Line]
[pin_not_connected]: Pin not connected
; error (excluded)
@(9000.00 mils, 3650.00 mils): Symbol D5 Pin 2 [A, Passive, Line]
** ERC messages: 9 Errors 9 Warnings 0

View File

@ -0,0 +1,83 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.6,
"pads": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.6
},
"selection_filter": {
"dimensions": true,
"footprints": true,
"graphics": true,
"keepouts": true,
"lockedItems": false,
"otherItems": true,
"pads": true,
"text": true,
"tracks": true,
"vias": true,
"zones": true
},
"visible_items": [
0,
1,
2,
3,
4,
5,
8,
9,
10,
11,
12,
13,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
32,
33,
34,
35,
36,
39,
40
],
"visible_layers": "fffffff_ffffffff",
"zone_display_mode": 0
},
"git": {
"repo_password": "",
"repo_type": "",
"repo_username": "",
"ssh_key": ""
},
"meta": {
"filename": "0004-DenshaBekutoru_v0.2.kicad_prl",
"version": 3
},
"project": {
"files": []
}
}

View File

@ -0,0 +1,402 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"rules": {},
"track_widths": [],
"via_dimensions": []
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_presets": [],
"viewports": []
},
"boards": [],
"cvpcb": {
"equivalence_files": []
},
"erc": {
"erc_exclusions": [
"pin_not_connected|2159000|1003300|75d7e973-8e06-4017-adef-8a7540fd15a0|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2159000|927100|b8d4dc81-b5c9-4b93-9376-0a9b9fc45175|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2286000|1003300|708ddeaa-1814-44d3-ae53-df03e7136210|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2286000|927100|e0f17062-911b-4fb8-9627-be8ce017775c|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2413000|1003300|c87497e0-f1a5-4cac-8154-452d26879be6|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2413000|927100|8209804a-7539-4743-bfca-aff943649ca9|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2540000|1003300|6d0ce029-b541-49e3-83e1-74431b2de240|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"pin_not_connected|2540000|927100|252bd632-84ad-409c-ab54-696d48f55782|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|",
"power_pin_not_driven|1435100|850900|c21116e5-546b-4c55-ac12-ee16de044258|00000000-0000-0000-0000-000000000000|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|/f227a2cd-5cbd-41a5-87f8-a5c1515170aa|"
],
"meta": {
"version": 0
},
"pin_map": [
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
1,
0,
1,
2
],
[
0,
1,
0,
0,
0,
0,
1,
1,
2,
1,
1,
2
],
[
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
2
],
[
1,
1,
1,
1,
1,
0,
1,
1,
1,
1,
1,
2
],
[
0,
0,
0,
1,
0,
0,
1,
0,
0,
0,
0,
2
],
[
0,
2,
1,
2,
0,
0,
1,
0,
2,
2,
2,
2
],
[
0,
2,
0,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
0,
2,
1,
1,
0,
0,
1,
0,
2,
0,
0,
2
],
[
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2,
2
]
],
"rule_severities": {
"bus_definition_conflict": "error",
"bus_entry_needed": "error",
"bus_to_bus_conflict": "error",
"bus_to_net_conflict": "error",
"conflicting_netclasses": "error",
"different_unit_footprint": "error",
"different_unit_net": "error",
"duplicate_reference": "error",
"duplicate_sheet_names": "error",
"endpoint_off_grid": "warning",
"extra_units": "error",
"global_label_dangling": "warning",
"hier_label_mismatch": "error",
"label_dangling": "error",
"lib_symbol_issues": "warning",
"missing_bidi_pin": "warning",
"missing_input_pin": "warning",
"missing_power_pin": "error",
"missing_unit": "warning",
"multiple_net_names": "warning",
"net_not_bus_member": "warning",
"no_connect_connected": "warning",
"no_connect_dangling": "warning",
"pin_not_connected": "error",
"pin_not_driven": "error",
"pin_to_pin": "error",
"power_pin_not_driven": "error",
"similar_labels": "warning",
"simulation_model_issue": "ignore",
"unannotated": "error",
"unit_value_mismatch": "error",
"unresolved_variable": "error",
"wire_dangling": "error"
}
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "0004-DenshaBekutoru_v0.2.kicad_pro",
"version": 1
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
}
],
"meta": {
"version": 3
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"gencad": "",
"idf": "",
"netlist": "",
"plot": "",
"pos_files": "",
"specctra_dsn": "",
"step": "",
"svg": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"annotate_start_num": 0,
"bom_export_filename": "",
"bom_fmt_presets": [],
"bom_fmt_settings": {
"field_delimiter": ",",
"keep_line_breaks": false,
"keep_tabs": false,
"name": "CSV",
"ref_delimiter": ",",
"ref_range_delimiter": "",
"string_delimiter": "\""
},
"bom_presets": [],
"bom_settings": {
"exclude_dnp": false,
"fields_ordered": [
{
"group_by": false,
"label": "Reference",
"name": "Reference",
"show": true
},
{
"group_by": true,
"label": "Value",
"name": "Value",
"show": true
},
{
"group_by": false,
"label": "Datasheet",
"name": "Datasheet",
"show": true
},
{
"group_by": false,
"label": "Footprint",
"name": "Footprint",
"show": true
},
{
"group_by": false,
"label": "Qty",
"name": "${QUANTITY}",
"show": true
},
{
"group_by": true,
"label": "DNP",
"name": "${DNP}",
"show": true
}
],
"filter_string": "",
"group_symbols": true,
"name": "Grouped By Value",
"sort_asc": true,
"sort_field": "Reference"
},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
"dashed_lines_gap_length_ratio": 3.0,
"default_line_thickness": 6.0,
"default_text_size": 50.0,
"field_names": [],
"intersheets_ref_own_page": false,
"intersheets_ref_prefix": "",
"intersheets_ref_short": false,
"intersheets_ref_show": false,
"intersheets_ref_suffix": "",
"junction_size_choice": 3,
"label_size_ratio": 0.375,
"operating_point_overlay_i_precision": 3,
"operating_point_overlay_i_range": "~A",
"operating_point_overlay_v_precision": 3,
"operating_point_overlay_v_range": "~V",
"overbar_offset_ratio": 1.23,
"pin_symbol_size": 25.0,
"text_offset_ratio": 0.15
},
"legacy_lib_dir": "",
"legacy_lib_list": [],
"meta": {
"version": 1
},
"net_format_name": "Spice Model",
"page_layout_descr_file": "",
"plot_directory": "/home/tgohle/Desktop/git/ToGo-Lab/0004-DenshaBekutoru/KiCad/0004-DenshaBekutoru_v0.2/",
"spice_current_sheet_as_root": false,
"spice_external_command": "spice \"%I\"",
"spice_model_current_sheet_as_root": true,
"spice_save_all_currents": false,
"spice_save_all_dissipations": false,
"spice_save_all_voltages": false,
"subpart_first_id": 65,
"subpart_id_separator": 0
},
"sheets": [
[
"f227a2cd-5cbd-41a5-87f8-a5c1515170aa",
"Root"
]
],
"text_variables": {}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"hostname":"NUC2","username":"tgohle"}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@ -0,0 +1,217 @@
/*
0004_DenshaBekutoru Optocoupler Averaging Test
Target dev board (later): Arduino Pro Mini 5V / 16 MHz (ATmega328P)
Measures average voltage on:
- A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
- A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
Boot calibration:
- assumes "no movement" at startup
- measures V1/V2 AverageRepeat times
- computes di = |V1 - V2| each time
- VdiffBaseline = median(di)
- VdiffThreshold = max(VdiffBaseline * VdiffThresholdMargin, VdiffThresholdMinVolts)
*/
const unsigned long SAMPLE_WINDOW_MS = 100; // averaging window per measurement
const unsigned long SAMPLE_DELAY_US = 500; // delay between ADC samples (~2 kHz)
const uint8_t ADC_PIN_1 = A2; // Pro Mini A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
const uint8_t ADC_PIN_2 = A3; // Pro Mini A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
// LEDs for direction indication (avoid D0/D1)
const uint8_t LED_DIR1_PIN = 2; // D2
const uint8_t LED_DIR2_PIN = 3; // D3
// Serial output control (0 = no output, 1 = output)
bool SerialOutputAllow = true;
// ---- Calibration parameters ----
const uint16_t AverageRepeat = 100; // number of init measurements
const float VdiffThresholdMargin = 1.50f; // multiplier (e.g., 1.5 = +50% margin)
const float VdiffThresholdMinVolts = 0.03f; // floor in volts (optional but practical)
// Globals: latest measured averaged voltages
float v1 = 0.0f;
float v2 = 0.0f;
// Calibration globals
float VdiffBaseline = 0.0f; // median(|V1-V2|) measured at boot (no movement)
float VdiffThreshold = 0.0f; // final threshold used for direction decision
// Direction encoding requirement:
// 0 = no direction
// 2 = direction 1 (maps to LED pin D2)
// 3 = direction 2 (maps to LED pin D3)
byte direction = 0;
static inline float absf(float x) { return (x >= 0.0f) ? x : -x; }
static inline float maxf(float a, float b) { return (a > b) ? a : b; }
static void applyDirectionOutputs()
{
digitalWrite(LED_DIR1_PIN, LOW);
digitalWrite(LED_DIR2_PIN, LOW);
if (direction == LED_DIR1_PIN) {
digitalWrite(LED_DIR1_PIN, HIGH);
} else if (direction == LED_DIR2_PIN) {
digitalWrite(LED_DIR2_PIN, HIGH);
}
}
// Measure averaged voltages (updates globals v1/v2)
static void measureAveragedVoltages()
{
unsigned long startTime = millis();
unsigned long sum1 = 0;
unsigned long sum2 = 0;
unsigned long samples = 0;
while (millis() - startTime < SAMPLE_WINDOW_MS) {
sum1 += analogRead(ADC_PIN_1);
sum2 += analogRead(ADC_PIN_2);
samples++;
delayMicroseconds(SAMPLE_DELAY_US);
}
float avg1 = (float)sum1 / samples;
float avg2 = (float)sum2 / samples;
// Convert ADC value to voltage (default analog reference = Vcc ~ 5V)
v1 = avg1 * (5.0f / 1023.0f);
v2 = avg2 * (5.0f / 1023.0f);
}
static void sortFloatArray(float *a, uint16_t n)
{
// Insertion sort (n=100 is small, OK)
for (uint16_t i = 1; i < n; i++) {
float key = a[i];
int16_t j = (int16_t)i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}
static float medianOfSortedFloatArray(const float *a, uint16_t n)
{
if (n == 0) return 0.0f;
if (n & 1) {
return a[n / 2];
} else {
return (a[(n / 2) - 1] + a[n / 2]) * 0.5f;
}
}
// Calibrate baseline + threshold once at boot/reset
// Parameter must be only AverageRepeat (per your requirement).
static void calibrateVdiffThreshold(uint16_t averageRepeat)
{
if (averageRepeat < 1) averageRepeat = 1;
if (averageRepeat > 200) averageRepeat = 200; // RAM safety cap
float diffs[200];
for (uint16_t i = 0; i < averageRepeat; i++) {
measureAveragedVoltages();
diffs[i] = absf(v1 - v2); // baseline mismatch sample
}
sortFloatArray(diffs, averageRepeat);
VdiffBaseline = medianOfSortedFloatArray(diffs, averageRepeat);
// Final threshold with margin + floor
VdiffThreshold = maxf(VdiffBaseline * VdiffThresholdMargin, VdiffThresholdMinVolts);
}
static void updateDirectionFromVoltages()
{
float diff = v1 - v2;
float absDiff = absf(diff);
if (absDiff <= VdiffThreshold) {
direction = 0;
} else {
// Mapping choice:
// v1 lower than v2 -> direction 1 (D2)
// v2 lower than v1 -> direction 2 (D3)
direction = (diff < 0.0f) ? LED_DIR1_PIN : LED_DIR2_PIN;
}
}
static void serialPrintAll()
{
if (!SerialOutputAllow) return;
Serial.print("A2 for PB3 XTAL1, Pin2: ");
Serial.print(v1, 3);
Serial.print(" V | ");
Serial.print("A3 for PB4 XTAL2, Pin3: ");
Serial.print(v2, 3);
Serial.print(" V | ");
Serial.print("|V1-V2|: ");
Serial.print(absf(v1 - v2), 3);
Serial.print(" V | ");
Serial.print("VdiffBaseline: ");
Serial.print(VdiffBaseline, 3);
Serial.print(" V | ");
Serial.print("VdiffThresholdMargin: ");
Serial.print(VdiffThresholdMargin, 2);
Serial.print(" x | ");
Serial.print("VdiffThresholdMinVolts: ");
Serial.print(VdiffThresholdMinVolts, 3);
Serial.print(" V | ");
Serial.print("VdiffThreshold: ");
Serial.print(VdiffThreshold, 3);
Serial.print(" V | ");
Serial.print("direction: ");
Serial.println(direction);
}
void setup() {
Serial.begin(115200);
pinMode(ADC_PIN_1, INPUT);
pinMode(ADC_PIN_2, INPUT);
pinMode(LED_DIR1_PIN, OUTPUT);
pinMode(LED_DIR2_PIN, OUTPUT);
calibrateVdiffThreshold(AverageRepeat);
// One measurement for initial output + outputs
measureAveragedVoltages();
updateDirectionFromVoltages();
applyDirectionOutputs();
if (SerialOutputAllow) {
Serial.println("=== DenshaBekutoru Optocoupler Average Test (Arduino Pro Mini 5V/16MHz) ===");
Serial.print("AverageRepeat: ");
Serial.println(AverageRepeat);
}
serialPrintAll();
}
void loop() {
measureAveragedVoltages();
updateDirectionFromVoltages();
applyDirectionOutputs();
serialPrintAll();
delay(300);
}

View File

@ -0,0 +1,58 @@
/*
0004_DenshaBekutoru ? Optocoupler Averaging Test (UNO)
Measures average voltage on:
- A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
- A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
Integration window is configurable via SAMPLE_WINDOW_MS.
by tgohle, last edit 20260111
*/
const unsigned long SAMPLE_WINDOW_MS = 100; // change here
const unsigned long SAMPLE_DELAY_US = 500; // delay between ADC samples
const uint8_t ADC_PIN_1 = A2; // UNO A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
const uint8_t ADC_PIN_2 = A3; // UNO A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
void setup() {
Serial.begin(115200);
pinMode(ADC_PIN_1, INPUT);
pinMode(ADC_PIN_2, INPUT);
Serial.println("=== DenshaBekutoru Optocoupler Average Test ===");
}
void loop() {
unsigned long startTime = millis();
unsigned long sum1 = 0;
unsigned long sum2 = 0;
unsigned long samples = 0;
while (millis() - startTime < SAMPLE_WINDOW_MS) {
sum1 += analogRead(ADC_PIN_1);
sum2 += analogRead(ADC_PIN_2);
samples++;
delayMicroseconds(SAMPLE_DELAY_US);
}
float avg1 = (float)sum1 / samples;
float avg2 = (float)sum2 / samples;
float v1 = avg1 * (5.0 / 1023.0);
float v2 = avg2 * (5.0 / 1023.0);
Serial.print("A2 for PB3 XTAL1, Pin2: ");
Serial.print(v1, 3);
Serial.print(" V | ");
Serial.print("A3 for PB4 XTAL2, Pin3: ");
Serial.print(v2, 3);
Serial.println(" V");
delay(300);
}

View File

@ -0,0 +1,292 @@
/*
0004_DenshaBekutoru Version 0.1 Test
Target dev board (later): Arduino Pro Mini 5V / 16 MHz (ATmega328P)
----------------------------------------------------------------------------
State machine (direction memory)
----------------------------------------------------------------------------
Inputs derived from v1, v2, VdiffThreshold:
N (Neutral): |v1 - v2| <= VdiffThreshold
D1 (v1>>v2): (v1 - v2) > VdiffThreshold
D2 (v2>>v1): (v2 - v1) > VdiffThreshold
State encoding:
0 = NONE
2 = DIR1
3 = DIR2
Transition table:
Current \ Input | N (neutral) | D1 (v1>>v2) | D2 (v2>>v1)
-----------------------------------------------------------------
0 (NONE) | 0 | 2 | 3
2 (DIR1) | 2 | 2 | 3
3 (DIR2) | 3 | 2 | 3
Mermaid (documentation)
-----------------------
stateDiagram-v2
[*] --> NONE
state "0 : NONE" as NONE
state "2 : DIR1 (v1>>v2)" as DIR1
state "3 : DIR2 (v2>>v1)" as DIR2
NONE --> NONE : |v1 - v2| <= T
NONE --> DIR1 : v1 - v2 > T
NONE --> DIR2 : v2 - v1 > T
DIR1 --> DIR1 : |v1 - v2| <= T
DIR1 --> DIR1 : v1 - v2 > T
DIR1 --> DIR2 : v2 - v1 > T
DIR2 --> DIR2 : |v1 - v2| <= T
DIR2 --> DIR2 : v2 - v1 > T
DIR2 --> DIR1 : v1 - v2 > T
*/
const unsigned long SAMPLE_WINDOW_MS = 100; // averaging window per measurement
const unsigned long SAMPLE_DELAY_US = 500; // delay between ADC samples (~2 kHz)
const uint8_t ADC_PIN_1 = A2; // Pro Mini A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
const uint8_t ADC_PIN_2 = A3; // Pro Mini A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
// Direction LEDs (avoid D0/D1 because you may want RX/TX later)
const uint8_t LED_DIR1_PIN = 2; // D2
const uint8_t LED_DIR2_PIN = 3; // D3
const unsigned int LED_BLINK_ON_MS = 150;
const unsigned int LED_BLINK_OFF_MS = 150;
// Serial output control (0 = no output, 1 = output)
bool SerialOutputAllow = true;
// ---- Calibration parameters ----
const uint16_t AverageRepeat = 100; // number of init measurements
const float VdiffThresholdMargin = 1.50f; // multiplier (e.g., 1.5 = +50% margin)
const float VdiffThresholdMinVolts = 0.03f; // floor in volts
// Globals: latest measured averaged voltages
float v1 = 0.0f;
float v2 = 0.0f;
// Calibration globals
float VdiffBaseline = 0.0f; // median(|V1-V2|) measured at boot (no movement)
float VdiffThreshold = 0.0f; // final threshold used for direction decision
// Direction encoding:
// 0 = NONE, 2 = DIR1, 3 = DIR2
byte direction = 0;
static inline float absf(float x) { return (x >= 0.0f) ? x : -x; }
static inline float maxf(float a, float b) { return (a > b) ? a : b; }
// -----------------------------------------------------------------------------
// LED helpers
// -----------------------------------------------------------------------------
static void blinkLED(uint8_t pin, uint8_t times)
{
for (uint8_t i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(LED_BLINK_ON_MS);
digitalWrite(pin, LOW);
delay(LED_BLINK_OFF_MS);
}
}
static void initBlinkSequence()
{
// LED at Output 2 blinks 2 times
blinkLED(LED_DIR1_PIN, 2);
// LED at Output 3 blinks 3 times
blinkLED(LED_DIR2_PIN, 3);
}
static void applyDirectionOutputs()
{
digitalWrite(LED_DIR1_PIN, LOW);
digitalWrite(LED_DIR2_PIN, LOW);
if (direction == 2) {
digitalWrite(LED_DIR1_PIN, HIGH);
} else if (direction == 3) {
digitalWrite(LED_DIR2_PIN, HIGH);
}
}
// -----------------------------------------------------------------------------
// Measurement
// -----------------------------------------------------------------------------
static void measureAveragedVoltages()
{
unsigned long startTime = millis();
unsigned long sum1 = 0;
unsigned long sum2 = 0;
unsigned long samples = 0;
while (millis() - startTime < SAMPLE_WINDOW_MS) {
sum1 += analogRead(ADC_PIN_1);
sum2 += analogRead(ADC_PIN_2);
samples++;
delayMicroseconds(SAMPLE_DELAY_US);
}
float avg1 = (float)sum1 / samples;
float avg2 = (float)sum2 / samples;
// Convert ADC value to voltage (default analog reference = Vcc ~ 5V)
v1 = avg1 * (5.0f / 1023.0f);
v2 = avg2 * (5.0f / 1023.0f);
}
// -----------------------------------------------------------------------------
// Median helpers (for calibration)
// -----------------------------------------------------------------------------
static void sortFloatArray(float *a, uint16_t n)
{
// Insertion sort (n=100 is small, OK)
for (uint16_t i = 1; i < n; i++) {
float key = a[i];
int16_t j = (int16_t)i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}
static float medianOfSortedFloatArray(const float *a, uint16_t n)
{
if (n == 0) return 0.0f;
if (n & 1) {
return a[n / 2];
} else {
return (a[(n / 2) - 1] + a[n / 2]) * 0.5f;
}
}
// Calibrate baseline + threshold once at boot/reset
// Parameter must be only AverageRepeat.
static void calibrateVdiffThreshold(uint16_t averageRepeat)
{
if (averageRepeat < 1) averageRepeat = 1;
if (averageRepeat > 200) averageRepeat = 200; // RAM safety cap
float diffs[200];
for (uint16_t i = 0; i < averageRepeat; i++) {
measureAveragedVoltages();
diffs[i] = absf(v1 - v2); // baseline mismatch sample
}
sortFloatArray(diffs, averageRepeat);
VdiffBaseline = medianOfSortedFloatArray(diffs, averageRepeat);
// Final threshold with margin + floor
VdiffThreshold = maxf(VdiffBaseline * VdiffThresholdMargin, VdiffThresholdMinVolts);
}
// -----------------------------------------------------------------------------
// State machine
// -----------------------------------------------------------------------------
static void updateDirectionFromVoltages()
{
const float diff = v1 - v2;
const float absDiff = absf(diff);
// Neutral region: hold direction
if (absDiff <= VdiffThreshold) {
return;
}
// Clear dominance: set direction deterministically
// diff > 0 => v1 >> v2 => DIR1 (2)
// diff < 0 => v2 >> v1 => DIR2 (3)
direction = (diff > 0.0f) ? (byte)2 : (byte)3;
}
// -----------------------------------------------------------------------------
// Serial output
// -----------------------------------------------------------------------------
static void serialPrintAll()
{
if (!SerialOutputAllow) return;
Serial.print("A2 for PB3 XTAL1, Pin2: ");
Serial.print(v1, 3);
Serial.print(" V | ");
Serial.print("A3 for PB4 XTAL2, Pin3: ");
Serial.print(v2, 3);
Serial.print(" V | ");
Serial.print("|V1-V2|: ");
Serial.print(absf(v1 - v2), 3);
Serial.print(" V | ");
Serial.print("VdiffBaseline: ");
Serial.print(VdiffBaseline, 3);
Serial.print(" V | ");
Serial.print("VdiffThresholdMargin: ");
Serial.print(VdiffThresholdMargin, 2);
Serial.print(" x | ");
Serial.print("VdiffThresholdMinVolts: ");
Serial.print(VdiffThresholdMinVolts, 3);
Serial.print(" V | ");
Serial.print("VdiffThreshold: ");
Serial.print(VdiffThreshold, 3);
Serial.print(" V | ");
Serial.print("direction: ");
Serial.println(direction);
}
// -----------------------------------------------------------------------------
// Arduino entry points
// -----------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(ADC_PIN_1, INPUT);
pinMode(ADC_PIN_2, INPUT);
pinMode(LED_DIR1_PIN, OUTPUT);
pinMode(LED_DIR2_PIN, OUTPUT);
// Initial calibration (assumes no movement)
calibrateVdiffThreshold(AverageRepeat);
// Init blink sequence: 2x on D2, 3x on D3
initBlinkSequence();
// One measurement for initial display + initial direction
measureAveragedVoltages();
updateDirectionFromVoltages();
applyDirectionOutputs();
if (SerialOutputAllow) {
Serial.println("=== DenshaBekutoru 0004 Version 0.1 Test (Arduino Uno Test) ===");
Serial.println(" ~~~ InitStart ~~~");
Serial.print(" AverageRepeat: ");
Serial.println(AverageRepeat);
Serial.println(" ~~~ InitEnd ~~~");
}
serialPrintAll();
}
void loop() {
measureAveragedVoltages();
updateDirectionFromVoltages();
applyDirectionOutputs();
serialPrintAll();
delay(300);
}

View File

@ -0,0 +1,286 @@
/*
0004_DenshaBekutoru 1st working Example
Target dev board: Arduino Pro Mini 5V / 16 MHz (ATmega328P)
----------------------------------------------------------------------------
State machine (direction memory) + Hysteresis (Version A)
----------------------------------------------------------------------------
We use two thresholds:
T_hold (smaller): below -> treat as neutral and HOLD state
T_enter (larger): above -> allow direction change (set by sign)
Behavior:
If |diff| <= T_hold : hold direction
If |diff| >= T_enter: set direction by sign
Else (between) : hold direction
Presets (implemented as multipliers of the calibrated VdiffThreshold):
T_hold = 1.0 * VdiffThreshold
T_enter = 2.0 * VdiffThreshold
Inputs derived from v1, v2:
diff = v1 - v2
*/
const unsigned long SAMPLE_WINDOW_MS = 100; // averaging window per measurement
const unsigned long SAMPLE_DELAY_US = 500; // delay between ADC samples (~2 kHz)
const uint8_t ADC_PIN_1 = A2; // Pro Mini A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
const uint8_t ADC_PIN_2 = A3; // Pro Mini A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
// Direction LEDs (avoid D0/D1 because you may want RX/TX later)
const uint8_t LED_DIR1_PIN = 2; // D2
const uint8_t LED_DIR2_PIN = 3; // D3
const unsigned int LED_BLINK_ON_MS = 150;
const unsigned int LED_BLINK_OFF_MS = 150;
// Serial output control (0 = no output, 1 = output)
bool SerialOutputAllow = true;
// ---- Calibration parameters ----
const uint16_t AverageRepeat = 100; // number of init measurements
const float VdiffThresholdMargin = 1.50f; // multiplier (e.g., 1.5 = +50% margin)
const float VdiffThresholdMinVolts = 0.03f; // floor in volts
// ---- Hysteresis presets (multipliers of VdiffThreshold) ----
const float THOLD_MULT = 1.0f; // T_hold = THOLD_MULT * VdiffThreshold
const float TENTER_MULT = 2.0f; // T_enter = TENTER_MULT * VdiffThreshold
// Globals: latest measured averaged voltages
float v1 = 0.0f;
float v2 = 0.0f;
// Calibration globals
float VdiffBaseline = 0.0f; // median(|V1-V2|) measured at boot (no movement)
float VdiffThreshold = 0.0f; // calibrated base threshold (used to derive T_hold/T_enter)
// Hysteresis thresholds (derived once after calibration)
float T_hold = 0.0f;
float T_enter = 0.0f;
// Direction encoding:
// 0 = NONE, 2 = DIR1, 3 = DIR2
byte direction = 0;
static inline float absf(float x) { return (x >= 0.0f) ? x : -x; }
static inline float maxf(float a, float b) { return (a > b) ? a : b; }
// -----------------------------------------------------------------------------
// LED helpers
// -----------------------------------------------------------------------------
static void blinkLED(uint8_t pin, uint8_t times)
{
for (uint8_t i = 0; i < times; i++) {
digitalWrite(pin, HIGH);
delay(LED_BLINK_ON_MS);
digitalWrite(pin, LOW);
delay(LED_BLINK_OFF_MS);
}
}
static void initBlinkSequence()
{
// LED at Output 2 blinks 2 times
blinkLED(LED_DIR1_PIN, 2);
// LED at Output 3 blinks 3 times
blinkLED(LED_DIR2_PIN, 3);
}
static void applyDirectionOutputs()
{
digitalWrite(LED_DIR1_PIN, LOW);
digitalWrite(LED_DIR2_PIN, LOW);
if (direction == 2) {
digitalWrite(LED_DIR1_PIN, HIGH);
} else if (direction == 3) {
digitalWrite(LED_DIR2_PIN, HIGH);
}
}
// -----------------------------------------------------------------------------
// Measurement
// -----------------------------------------------------------------------------
static void measureAveragedVoltages()
{
unsigned long startTime = millis();
unsigned long sum1 = 0;
unsigned long sum2 = 0;
unsigned long samples = 0;
while (millis() - startTime < SAMPLE_WINDOW_MS) {
sum1 += analogRead(ADC_PIN_1);
sum2 += analogRead(ADC_PIN_2);
samples++;
delayMicroseconds(SAMPLE_DELAY_US);
}
float avg1 = (float)sum1 / samples;
float avg2 = (float)sum2 / samples;
// Convert ADC value to voltage (default analog reference = Vcc ~ 5V)
v1 = avg1 * (5.0f / 1023.0f);
v2 = avg2 * (5.0f / 1023.0f);
}
// -----------------------------------------------------------------------------
// Median helpers (for calibration)
// -----------------------------------------------------------------------------
static void sortFloatArray(float *a, uint16_t n)
{
// Insertion sort (n=100 is small, OK)
for (uint16_t i = 1; i < n; i++) {
float key = a[i];
int16_t j = (int16_t)i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}
static float medianOfSortedFloatArray(const float *a, uint16_t n)
{
if (n == 0) return 0.0f;
if (n & 1) {
return a[n / 2];
} else {
return (a[(n / 2) - 1] + a[n / 2]) * 0.5f;
}
}
// Calibrate baseline + VdiffThreshold once at boot/reset
static void calibrateVdiffThreshold(uint16_t averageRepeat)
{
if (averageRepeat < 1) averageRepeat = 1;
if (averageRepeat > 200) averageRepeat = 200; // RAM safety cap
float diffs[200];
for (uint16_t i = 0; i < averageRepeat; i++) {
measureAveragedVoltages();
diffs[i] = absf(v1 - v2); // baseline mismatch sample
}
sortFloatArray(diffs, averageRepeat);
VdiffBaseline = medianOfSortedFloatArray(diffs, averageRepeat);
// Calibrated base threshold with margin + floor
VdiffThreshold = maxf(VdiffBaseline * VdiffThresholdMargin, VdiffThresholdMinVolts);
// Derive hysteresis thresholds (Version A)
T_hold = THOLD_MULT * VdiffThreshold;
T_enter = TENTER_MULT * VdiffThreshold;
}
// -----------------------------------------------------------------------------
// State machine with hysteresis (Version A)
// -----------------------------------------------------------------------------
static void updateDirectionFromVoltages()
{
const float diff = v1 - v2;
const float absDiff = absf(diff);
// 1) Neutral region: HOLD
if (absDiff <= T_hold) {
return;
}
// 2) Strong region: allow direction change
if (absDiff >= T_enter) {
direction = (diff > 0.0f) ? (byte)2 : (byte)3;
return;
}
// 3) Deadband between T_hold and T_enter: HOLD
return;
}
// -----------------------------------------------------------------------------
// Serial output
// -----------------------------------------------------------------------------
static void serialPrintAll()
{
if (!SerialOutputAllow) return;
Serial.print("A2 for PB3 XTAL1, Pin2: ");
Serial.print(v1, 3);
Serial.print(" V | ");
Serial.print("A3 for PB4 XTAL2, Pin3: ");
Serial.print(v2, 3);
Serial.print(" V | ");
Serial.print("|V1-V2|: ");
Serial.print(absf(v1 - v2), 3);
Serial.print(" V | ");
Serial.print("VdiffBaseline: ");
Serial.print(VdiffBaseline, 3);
Serial.print(" V | ");
Serial.print("VdiffThreshold: ");
Serial.print(VdiffThreshold, 3);
Serial.print(" V | ");
Serial.print("T_hold: ");
Serial.print(T_hold, 3);
Serial.print(" V | ");
Serial.print("T_enter: ");
Serial.print(T_enter, 3);
Serial.print(" V | ");
Serial.print("direction: ");
Serial.println(direction);
}
// -----------------------------------------------------------------------------
// Arduino entry points
// -----------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(ADC_PIN_1, INPUT);
pinMode(ADC_PIN_2, INPUT);
pinMode(LED_DIR1_PIN, OUTPUT);
pinMode(LED_DIR2_PIN, OUTPUT);
// Initial calibration (assumes no movement)
calibrateVdiffThreshold(AverageRepeat);
// Init blink sequence: 2x on D2, 3x on D3
initBlinkSequence();
// One measurement for initial display + initial direction
measureAveragedVoltages();
updateDirectionFromVoltages();
applyDirectionOutputs();
if (SerialOutputAllow) {
Serial.println("=== DenshaBekutoru Optocoupler Average Test (Arduino Pro Mini 5V/16MHz) ===");
Serial.print("AverageRepeat: ");
Serial.println(AverageRepeat);
Serial.print("THOLD_MULT: ");
Serial.print(THOLD_MULT, 2);
Serial.print(" TENTER_MULT: ");
Serial.println(TENTER_MULT, 2);
}
serialPrintAll();
}
void loop() {
measureAveragedVoltages();
updateDirectionFromVoltages();
applyDirectionOutputs();
serialPrintAll();
delay(300);
}

View File

@ -0,0 +1,231 @@
/*
0004_DenshaBekutoru State Machine implemented
Target dev board (later): Arduino Pro Mini 5V / 16 MHz (ATmega328P)
----------------------------------------------------------------------------
State machine (direction memory)
----------------------------------------------------------------------------
Inputs derived from v1, v2, VdiffThreshold:
N (Neutral): |v1 - v2| <= VdiffThreshold
D1 (v1>>v2): (v1 - v2) > VdiffThreshold
D2 (v2>>v1): (v2 - v1) > VdiffThreshold
State encoding (kept transfer-friendly, and compatible with earlier pin-mapping):
0 = NONE
2 = DIR1
3 = DIR2
Transition table:
Current \ Input | N (neutral) | D1 (v1>>v2) | D2 (v2>>v1)
-----------------------------------------------------------------
0 (NONE) | 0 | 2 | 3
2 (DIR1) | 2 | 2 | 3
3 (DIR2) | 3 | 2 | 3
Mermaid (documentation)
-----------------------
stateDiagram-v2
[*] --> NONE
state "0 : NONE" as NONE
state "2 : DIR1 (v1>>v2)" as DIR1
state "3 : DIR2 (v2>>v1)" as DIR2
NONE --> NONE : |v1 - v2| <= T
NONE --> DIR1 : v1 - v2 > T
NONE --> DIR2 : v2 - v1 > T
DIR1 --> DIR1 : |v1 - v2| <= T
DIR1 --> DIR1 : v1 - v2 > T
DIR1 --> DIR2 : v2 - v1 > T
DIR2 --> DIR2 : |v1 - v2| <= T
DIR2 --> DIR2 : v2 - v1 > T
DIR2 --> DIR1 : v1 - v2 > T
*/
const unsigned long SAMPLE_WINDOW_MS = 100; // averaging window per measurement
const unsigned long SAMPLE_DELAY_US = 500; // delay between ADC samples (~2 kHz)
const uint8_t ADC_PIN_1 = A2; // Pro Mini A2 -> later ATtiny85 PB3 (XTAL1, Pin 2)
const uint8_t ADC_PIN_2 = A3; // Pro Mini A3 -> later ATtiny85 PB4 (XTAL2, Pin 3)
// Serial output control (0 = no output, 1 = output)
bool SerialOutputAllow = true;
// ---- Calibration parameters ----
const uint16_t AverageRepeat = 100; // number of init measurements
const float VdiffThresholdMargin = 1.50f; // multiplier (e.g., 1.5 = +50% margin)
const float VdiffThresholdMinVolts = 0.03f; // floor in volts (optional but practical)
// Globals: latest measured averaged voltages
float v1 = 0.0f;
float v2 = 0.0f;
// Calibration globals
float VdiffBaseline = 0.0f; // median(|V1-V2|) measured at boot (no movement)
float VdiffThreshold = 0.0f; // final threshold used for direction decision
// Direction encoding:
// 0 = NONE, 2 = DIR1, 3 = DIR2
byte direction = 0;
static inline float absf(float x) { return (x >= 0.0f) ? x : -x; }
static inline float maxf(float a, float b) { return (a > b) ? a : b; }
// Measure averaged voltages (updates globals v1/v2)
static void measureAveragedVoltages()
{
unsigned long startTime = millis();
unsigned long sum1 = 0;
unsigned long sum2 = 0;
unsigned long samples = 0;
while (millis() - startTime < SAMPLE_WINDOW_MS) {
sum1 += analogRead(ADC_PIN_1);
sum2 += analogRead(ADC_PIN_2);
samples++;
delayMicroseconds(SAMPLE_DELAY_US);
}
float avg1 = (float)sum1 / samples;
float avg2 = (float)sum2 / samples;
// Convert ADC value to voltage (default analog reference = Vcc ~ 5V)
v1 = avg1 * (5.0f / 1023.0f);
v2 = avg2 * (5.0f / 1023.0f);
}
static void sortFloatArray(float *a, uint16_t n)
{
// Insertion sort (n=100 is small, OK)
for (uint16_t i = 1; i < n; i++) {
float key = a[i];
int16_t j = (int16_t)i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = key;
}
}
static float medianOfSortedFloatArray(const float *a, uint16_t n)
{
if (n == 0) return 0.0f;
if (n & 1) {
return a[n / 2];
} else {
return (a[(n / 2) - 1] + a[n / 2]) * 0.5f;
}
}
// Calibrate baseline + threshold once at boot/reset
// Parameter must be only AverageRepeat (per your requirement).
static void calibrateVdiffThreshold(uint16_t averageRepeat)
{
if (averageRepeat < 1) averageRepeat = 1;
if (averageRepeat > 200) averageRepeat = 200; // RAM safety cap
float diffs[200];
for (uint16_t i = 0; i < averageRepeat; i++) {
measureAveragedVoltages();
diffs[i] = absf(v1 - v2); // baseline mismatch sample
}
sortFloatArray(diffs, averageRepeat);
VdiffBaseline = medianOfSortedFloatArray(diffs, averageRepeat);
// Final threshold with margin + floor
VdiffThreshold = maxf(VdiffBaseline * VdiffThresholdMargin, VdiffThresholdMinVolts);
}
// Implements the state machine table above
static void updateDirectionFromVoltages()
{
const float diff = v1 - v2;
const float absDiff = absf(diff);
// Neutral region: hold direction (only NONE stays NONE)
if (absDiff <= VdiffThreshold) {
// direction remains unchanged (0 stays 0; 2 stays 2; 3 stays 3)
return;
}
// Clear dominance: set direction deterministically
// diff > 0 => v1 >> v2 => DIR1 (2)
// diff < 0 => v2 >> v1 => DIR2 (3)
direction = (diff > 0.0f) ? (byte)2 : (byte)3;
}
static void serialPrintAll()
{
if (!SerialOutputAllow) return;
Serial.print("A2 for PB3 XTAL1, Pin2: ");
Serial.print(v1, 3);
Serial.print(" V | ");
Serial.print("A3 for PB4 XTAL2, Pin3: ");
Serial.print(v2, 3);
Serial.print(" V | ");
Serial.print("|V1-V2|: ");
Serial.print(absf(v1 - v2), 3);
Serial.print(" V | ");
Serial.print("VdiffBaseline: ");
Serial.print(VdiffBaseline, 3);
Serial.print(" V | ");
Serial.print("VdiffThresholdMargin: ");
Serial.print(VdiffThresholdMargin, 2);
Serial.print(" x | ");
Serial.print("VdiffThresholdMinVolts: ");
Serial.print(VdiffThresholdMinVolts, 3);
Serial.print(" V | ");
Serial.print("VdiffThreshold: ");
Serial.print(VdiffThreshold, 3);
Serial.print(" V | ");
Serial.print("direction: ");
Serial.println(direction);
}
void setup() {
Serial.begin(115200);
pinMode(ADC_PIN_1, INPUT);
pinMode(ADC_PIN_2, INPUT);
// Initial calibration: compute VdiffThreshold once after boot/reset
calibrateVdiffThreshold(AverageRepeat);
// One measurement for initial display
measureAveragedVoltages();
updateDirectionFromVoltages();
if (SerialOutputAllow) {
Serial.println("=== DenshaBekutoru State Machine and Variable Output (Arduino Pro Mini 5V/16MHz) ===");
Serial.println("~~~ Init ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Serial.print("AverageRepeat: ");
Serial.println(AverageRepeat);
Serial.println("~~~ Init ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
serialPrintAll();
}
void loop() {
measureAveragedVoltages();
updateDirectionFromVoltages();
serialPrintAll();
delay(300);
}