From 060a1cc32dea86584472821cac78d45aa4cdea5d Mon Sep 17 00:00:00 2001 From: Empire Date: Fri, 2 Feb 2024 21:35:04 +0100 Subject: [PATCH] proceed with bq34z100 extraction --- board/PlantCtrlESP32.kicad_pcb | 197 +++- board/PlantCtrlESP32.kicad_prl | 2 +- board/PlantCtrlESP32.kicad_sch | 164 ++- rust/.cargo/config.toml | 1 + rust/Cargo.toml | 2 + rust/src/bq34z100.rs | 1835 ++++++++++++-------------------- rust/src/config.rs | 8 +- rust/src/main.rs | 283 +++-- rust/src/plant_hal.rs | 290 +++-- rust/src/webserver/config.html | 8 +- rust/src_webpack/src/form.ts | 20 +- 11 files changed, 1371 insertions(+), 1439 deletions(-) diff --git a/board/PlantCtrlESP32.kicad_pcb b/board/PlantCtrlESP32.kicad_pcb index 14e677d..4bf2943 100644 --- a/board/PlantCtrlESP32.kicad_pcb +++ b/board/PlantCtrlESP32.kicad_pcb @@ -11113,7 +11113,7 @@ (property "ki_keywords" "HCMOS SR 3State") (path "/66a7ed92-e7d3-43dc-9320-c0d3557a8e25") (attr smd) - (fp_text reference "U1" (at 0 5.9 90) (layer "B.SilkS") + (fp_text reference "U1" (at 0 5.9 90) (layer "B.SilkS") hide (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) (tstamp aaafd671-664e-452e-9cb5-f767f0c5e818) ) @@ -14421,8 +14421,8 @@ (property "ki_keywords" "R res resistor") (path "/00000000-0000-0000-0000-000060bfab84") (attr smd) - (fp_text reference "R15" (at 0 -1.5) (layer "B.SilkS") - (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (fp_text reference "R15" (at -0.9 -1.2) (layer "B.SilkS") + (effects (font (size 1 0.7) (thickness 0.125)) (justify mirror)) (tstamp b8dca75e-7694-4664-a68f-a25b99c6e816) ) (fp_text value "1k" (at 0 -1.43) (layer "B.Fab") @@ -14821,6 +14821,61 @@ ) ) + (footprint "Resistor_SMD:R_0603_1608Metric" (layer "B.Cu") + (tstamp 47d606a6-b542-4eed-9691-d24fe13156a4) + (at 175.48 81.095 90) + (descr "Resistor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf), generated with kicad-footprint-generator") + (tags "resistor") + (property "LCSC_PART_NUMBER" "C212284") + (property "Sheetfile" "PlantCtrlESP32.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/b4ff286f-51e3-425f-8430-14c7e2113349") + (attr smd) + (fp_text reference "R46" (at 0 1.43 90) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 8940bf89-2e2e-4b1c-9b36-6e3e9e66912c) + ) + (fp_text value "10k" (at 0 -1.43 90) (layer "B.Fab") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp ffcdfcc9-1614-40b8-b345-4feaa8f0d896) + ) + (fp_text user "${REFERENCE}" (at 0 0 90) (layer "B.Fab") + (effects (font (size 0.4 0.4) (thickness 0.06)) (justify mirror)) + (tstamp 630a0503-d861-48d9-8d6e-ae2cd61d9218) + ) + (fp_line (start -0.237258 -0.5225) (end 0.237258 -0.5225) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp f5b433c5-1c83-46d4-9424-a1e255a4eeb1)) + (fp_line (start -0.237258 0.5225) (end 0.237258 0.5225) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 202cf467-adf0-4dc7-8ed8-e4e83a204fc1)) + (fp_line (start -1.48 -0.73) (end -1.48 0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp e325c82f-6158-42d3-b128-7b2b010dfa55)) + (fp_line (start -1.48 0.73) (end 1.48 0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp cc07117c-e071-4ab4-a68d-497020924749)) + (fp_line (start 1.48 -0.73) (end -1.48 -0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 72b9a2cc-bab1-4aa2-bc65-f9b3a39810f5)) + (fp_line (start 1.48 0.73) (end 1.48 -0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 797d2bb1-8ee8-4f2c-88f8-5b0d2547f4c5)) + (fp_line (start -0.8 -0.4125) (end -0.8 0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 601f924a-b1be-4291-94f6-d87569520e35)) + (fp_line (start -0.8 0.4125) (end 0.8 0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 8a14dea6-3e84-4b2e-9e60-2ec889f353e8)) + (fp_line (start 0.8 -0.4125) (end -0.8 -0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 50b07823-5420-4299-af85-b352a84e244b)) + (fp_line (start 0.8 0.4125) (end 0.8 -0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 7f8d523d-763b-4fff-b4de-3acdfd47f9a7)) + (pad "1" smd roundrect (at -0.825 0 90) (size 0.8 0.95) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) + (net 4 "GND") (pintype "passive") (tstamp f40837e4-35aa-4f5d-a250-5ddb00c287db)) + (pad "2" smd roundrect (at 0.825 0 90) (size 0.8 0.95) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) + (net 82 "SerialIn") (pintype "passive") (tstamp b28e3237-9e25-4e58-8a12-9d59ecfad216)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_SMD.3dshapes/R_0603_1608Metric.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + (footprint "Package_TO_SOT_SMD:SOT-23" (layer "B.Cu") (tstamp 481bba05-fb9d-4de3-aa52-66cb9c8f522d) (at 242.33 129.9825 -90) @@ -22552,6 +22607,61 @@ ) ) + (footprint "Resistor_SMD:R_0603_1608Metric" (layer "B.Cu") + (tstamp ae19be9b-13ee-4672-9eb6-fbb7cd3787ba) + (at 177.68 78.27) + (descr "Resistor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf), generated with kicad-footprint-generator") + (tags "resistor") + (property "LCSC_PART_NUMBER" "C212284") + (property "Sheetfile" "PlantCtrlESP32.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/ee167434-7247-432a-8a61-3f2f465cfc2a") + (attr smd) + (fp_text reference "R48" (at -2.4 0.8 180) (layer "B.SilkS") + (effects (font (size 1 0.7) (thickness 0.15)) (justify mirror)) + (tstamp 882a78fb-26f3-4c90-84d1-fde95b459b77) + ) + (fp_text value "10k" (at 0 -1.43) (layer "B.Fab") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 8b65b92d-4e0e-4246-8a01-c731512f8a26) + ) + (fp_text user "${REFERENCE}" (at 0 0) (layer "B.Fab") + (effects (font (size 0.4 0.4) (thickness 0.06)) (justify mirror)) + (tstamp 4d5539a5-1f58-4302-b78a-9b7b0e7596f4) + ) + (fp_line (start -0.237258 -0.5225) (end 0.237258 -0.5225) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp ea5d2922-2df8-45eb-a143-cccc4250fbda)) + (fp_line (start -0.237258 0.5225) (end 0.237258 0.5225) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 5f75bf84-fa2c-43ad-bbde-e6e4dafcddeb)) + (fp_line (start -1.48 -0.73) (end -1.48 0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 3d77616e-6deb-4999-9c1c-1ab64562db7e)) + (fp_line (start -1.48 0.73) (end 1.48 0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 90448eea-5b46-445a-a01e-1c6c70b5ccbe)) + (fp_line (start 1.48 -0.73) (end -1.48 -0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp f2ebd7fe-d528-4cb4-bc65-d6bfd8941531)) + (fp_line (start 1.48 0.73) (end 1.48 -0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp e89a0182-9707-4234-90b9-3b22aa2c8051)) + (fp_line (start -0.8 -0.4125) (end -0.8 0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 9c7e54e4-3203-4afd-af41-ae6c51469d16)) + (fp_line (start -0.8 0.4125) (end 0.8 0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 2d0eb338-7c07-46b0-9441-5227c5b60f76)) + (fp_line (start 0.8 -0.4125) (end -0.8 -0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 49378f51-9db8-4146-bc6f-e6aa6181ee13)) + (fp_line (start 0.8 0.4125) (end 0.8 -0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 4f543b8d-6ea2-419c-9b28-04b68a213f18)) + (pad "1" smd roundrect (at -0.825 0) (size 0.8 0.95) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) + (net 4 "GND") (pintype "passive") (tstamp f44c437f-c486-414e-8121-8a2da34766a0)) + (pad "2" smd roundrect (at 0.825 0) (size 0.8 0.95) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) + (net 28 "Latch") (pintype "passive") (tstamp d3b70f4f-26d1-4a8f-9bb3-2c2b35b67cad)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_SMD.3dshapes/R_0603_1608Metric.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + (footprint "Package_TO_SOT_SMD:SOT-23" (layer "B.Cu") (tstamp ae66a751-eade-4a70-9441-f0672cba6e29) (at 221.58 95.17 -90) @@ -23461,6 +23571,61 @@ ) ) + (footprint "Resistor_SMD:R_0603_1608Metric" (layer "B.Cu") + (tstamp b8f3f81e-a9af-47b3-b04f-39c6fa40c26f) + (at 177.68 76.47) + (descr "Resistor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf), generated with kicad-footprint-generator") + (tags "resistor") + (property "LCSC_PART_NUMBER" "C212284") + (property "Sheetfile" "PlantCtrlESP32.kicad_sch") + (property "Sheetname" "") + (property "ki_description" "Resistor") + (property "ki_keywords" "R res resistor") + (path "/bb4afad3-b745-45d5-a7ce-b8763b1bdea0") + (attr smd) + (fp_text reference "R51" (at -1.1 -1.1) (layer "B.SilkS") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp 13332d5e-c617-4483-b4f0-c7e15f20aaa1) + ) + (fp_text value "10k" (at 0 -1.43) (layer "B.Fab") + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + (tstamp b10fc1bd-be29-4b67-abc3-0f0d64d65a9a) + ) + (fp_text user "${REFERENCE}" (at 0 0) (layer "B.Fab") + (effects (font (size 0.4 0.4) (thickness 0.06)) (justify mirror)) + (tstamp 2d6f580f-76d6-481c-a8fc-0175a6b54367) + ) + (fp_line (start -0.237258 -0.5225) (end 0.237258 -0.5225) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 4e5e566b-8ad5-4ec3-b975-f6b1f1888def)) + (fp_line (start -0.237258 0.5225) (end 0.237258 0.5225) + (stroke (width 0.12) (type solid)) (layer "B.SilkS") (tstamp 657859c1-24e3-48af-8067-8906faa44c92)) + (fp_line (start -1.48 -0.73) (end -1.48 0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp c817aaee-9e1c-4a3b-a82d-c4394309dbeb)) + (fp_line (start -1.48 0.73) (end 1.48 0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 5a896cec-48ab-441f-b619-170df73e1564)) + (fp_line (start 1.48 -0.73) (end -1.48 -0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp 859402eb-e79e-41f7-b981-1b90ce949075)) + (fp_line (start 1.48 0.73) (end 1.48 -0.73) + (stroke (width 0.05) (type solid)) (layer "B.CrtYd") (tstamp bce1041d-6388-41f5-82f2-0741acfe61d6)) + (fp_line (start -0.8 -0.4125) (end -0.8 0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 1d49510e-55c1-4f67-9f79-25e5eece35ce)) + (fp_line (start -0.8 0.4125) (end 0.8 0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp 2d1b3292-c856-4f5c-84c0-9a3137f5d329)) + (fp_line (start 0.8 -0.4125) (end -0.8 -0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp c7d50401-c5ba-4169-b83b-0108ad23776a)) + (fp_line (start 0.8 0.4125) (end 0.8 -0.4125) + (stroke (width 0.1) (type solid)) (layer "B.Fab") (tstamp bad48cbf-bf89-4b11-a7c0-37481914c36b)) + (pad "1" smd roundrect (at -0.825 0) (size 0.8 0.95) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) + (net 4 "GND") (pintype "passive") (tstamp 2f25ffaf-400e-4221-a2fd-8a63e67d02cb)) + (pad "2" smd roundrect (at 0.825 0) (size 0.8 0.95) (layers "B.Cu" "B.Paste" "B.Mask") (roundrect_rratio 0.25) + (net 27 "Clock") (pintype "passive") (tstamp 12adee31-ed2b-4b77-a099-e5899bb37440)) + (model "${KICAD6_3DMODEL_DIR}/Resistor_SMD.3dshapes/R_0603_1608Metric.wrl" + (offset (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + (footprint "Resistor_SMD:R_0603_1608Metric" (layer "B.Cu") (tstamp ba4e6fc4-2749-4e12-b7ee-316c44ae524f) (at 242.33 119.17 180) @@ -28898,6 +29063,7 @@ (segment (start 210.83 115.2325) (end 211.8675 114.195) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0da79d79-ff4f-4f81-bdc1-2474b5add81f)) (segment (start 249.43 101.745) (end 248.985 101.745) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0db36108-d612-4e21-a43d-a04d23fe312b)) (segment (start 248.98 57.045) (end 247.73 57.045) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0dcd1a2a-fe93-4af2-96f2-8f21f738ef6a)) + (segment (start 176.705 76.47) (end 173.605 73.37) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0e4da3df-21c8-4428-b0e0-974f861cdc31)) (segment (start 175.6425 100.62) (end 180.2425 100.62) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0ee97dd0-b02b-46d5-9fed-de183d8add14)) (segment (start 245.855 94.17) (end 246.58 93.445) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0efc0c65-3dbe-4fae-94d6-bba0626b5dd4)) (segment (start 248.735 122.745) (end 249.6795 121.8005) (width 0.2) (layer "B.Cu") (net 4) (tstamp 0f28bde6-faad-4175-a9c3-fc2f2e843ad9)) @@ -29452,6 +29618,7 @@ (segment (start 243.83 80.892792) (end 243.83 65.645) (width 1) (layer "B.Cu") (net 4) (tstamp db6ed76a-3b45-4186-9c2d-6d9271a84a4c)) (segment (start 231.655 113.995) (end 230.63 112.97) (width 0.2) (layer "B.Cu") (net 4) (tstamp db993f52-365f-4798-9eba-5c3009a77f81)) (segment (start 251.8675 103.745) (end 255.155 103.745) (width 0.2) (layer "B.Cu") (net 4) (tstamp dc1ab6ee-acce-4fe4-ba99-5977483f0dc3)) + (segment (start 176.855 76.47) (end 176.855 78.27) (width 0.2) (layer "B.Cu") (net 4) (tstamp dc3cac55-c959-47b9-9ae3-7fab21b6b2d7)) (segment (start 223.005 103.62) (end 221.73 103.62) (width 0.2) (layer "B.Cu") (net 4) (tstamp dc92f7e1-ac86-49ea-9123-a9178abdf35a)) (segment (start 189.275 74.92) (end 191.775 72.42) (width 0.2) (layer "B.Cu") (net 4) (tstamp dcaf377a-4b07-4f38-b805-c095469376ba)) (segment (start 261.455 119.87) (end 262.08 119.87) (width 0.5) (layer "B.Cu") (net 4) (tstamp dd03f112-5e18-4199-8111-85e2ac73cadd)) @@ -29530,6 +29697,7 @@ (segment (start 231.985 79.92) (end 231.985 81.575) (width 0.2) (layer "B.Cu") (net 4) (tstamp fc0aa60a-1c83-44ff-9e30-ec236347dc46)) (segment (start 245.13 51.22) (end 247.28 49.07) (width 0.2) (layer "B.Cu") (net 4) (tstamp fc79b0dd-b7aa-409c-9d7e-3ac9a9bac1ea)) (segment (start 239.93 99.2825) (end 239.93 94.32) (width 0.2) (layer "B.Cu") (net 4) (tstamp fca5a196-7fae-47b3-a589-fbd4afd8d18f)) + (segment (start 176.855 76.47) (end 176.705 76.47) (width 0.2) (layer "B.Cu") (net 4) (tstamp fd157e30-0682-416c-a47f-c7bfcc509dce)) (segment (start 220.255 114.92) (end 220.63 115.295) (width 0.2) (layer "B.Cu") (net 4) (tstamp fd6f6c67-a3af-40eb-b436-5ea1d2457efc)) (segment (start 179.48 106.145) (end 180.63 104.995) (width 0.2) (layer "B.Cu") (net 4) (tstamp fd70e3ba-b9ba-4ff2-9481-ac05227e27cc)) (segment (start 180.63 94.295) (end 180.38 94.545) (width 0.2) (layer "B.Cu") (net 4) (tstamp fd8b6866-f37d-4849-9569-c6b5e31a6057)) @@ -29742,7 +29910,6 @@ (segment (start 180.805 42.845) (end 181.38 42.27) (width 0.2) (layer "B.Cu") (net 10) (tstamp 0162aa97-9415-4324-888b-5a40e22218ad)) (segment (start 175.6425 98.72) (end 175.6425 96.9825) (width 0.2) (layer "B.Cu") (net 10) (tstamp 01a0dcdf-8683-486b-8d5c-c1412da6c5f1)) (segment (start 257.58 45.47) (end 258.98 44.07) (width 0.2) (layer "B.Cu") (net 10) (tstamp 0315daee-ad93-471d-adcb-5a6912728148)) - (segment (start 177.055 73.87) (end 177.055 78.645) (width 0.2) (layer "B.Cu") (net 10) (tstamp 03f36878-df6e-4f8f-800a-30da66b5b845)) (segment (start 205.58 55.295) (end 202.58 55.295) (width 0.2) (layer "B.Cu") (net 10) (tstamp 0429863c-dfd0-484e-b0a0-552a30382d62)) (segment (start 220.58 119.356396) (end 220.58 117.37) (width 0.2) (layer "B.Cu") (net 10) (tstamp 06fef1e9-43af-4ea0-8b8d-904abbe17624)) (segment (start 171.68 120.77) (end 171.58 120.67) (width 0.2) (layer "B.Cu") (net 10) (tstamp 07323ed0-7f67-4dc0-9869-f13335da8bcb)) @@ -29788,6 +29955,7 @@ (segment (start 212.355 120.27) (end 212.78 120.695) (width 0.2) (layer "B.Cu") (net 10) (tstamp 3b0c11eb-00c6-4e50-9a17-b7b5718f8d80)) (segment (start 250.78 98.07) (end 250.78 96.07) (width 0.2) (layer "B.Cu") (net 10) (tstamp 3c2c1322-73e7-469c-a552-b992f340bfec)) (segment (start 260.3175 128.0825) (end 260.3175 126.6075) (width 0.5) (layer "B.Cu") (net 10) (tstamp 3c3eed0c-b782-46b5-a200-d2462e9a318c)) + (segment (start 177.055 73.87) (end 177.055 75.245) (width 0.2) (layer "B.Cu") (net 10) (tstamp 3cde8e6c-084f-4274-91d2-a573efd997d3)) (segment (start 202.58 115.17) (end 202.33 115.42) (width 0.2) (layer "B.Cu") (net 10) (tstamp 3d5777e3-eff0-4d53-9193-5cb3db2d1d75)) (segment (start 242.58 94.17) (end 242.58 100.0325) (width 0.2) (layer "B.Cu") (net 10) (tstamp 3daed90a-e2f0-4c10-9ff0-74b77c8818ce)) (segment (start 231.33 119.92) (end 230.33 118.92) (width 0.2) (layer "B.Cu") (net 10) (tstamp 3f4903ff-bb38-4b85-93a7-d7b26a974610)) @@ -29818,6 +29986,7 @@ (segment (start 232.53 100.17) (end 230.58 98.22) (width 0.2) (layer "B.Cu") (net 10) (tstamp 579d666c-16df-4ee8-8094-33c77621d47b)) (segment (start 230.33 118.92) (end 230.33 117.42) (width 0.2) (layer "B.Cu") (net 10) (tstamp 57d33c77-aaf5-4764-827c-b166fe7b8882)) (segment (start 221.118604 119.895) (end 220.58 119.356396) (width 0.2) (layer "B.Cu") (net 10) (tstamp 585f5d35-1af0-4462-8f78-189a98e33382)) + (segment (start 177.68 79.27) (end 180.33 81.92) (width 0.2) (layer "B.Cu") (net 10) (tstamp 5b8f0869-9b61-4292-8f41-5b52e01a79e2)) (segment (start 251.305 109.395) (end 250.83 108.92) (width 0.2) (layer "B.Cu") (net 10) (tstamp 5cdf11c1-6877-4303-8938-53abe63cd641)) (segment (start 265.58 117.25) (end 262.175 117.25) (width 0.5) (layer "B.Cu") (net 10) (tstamp 5e2d2eff-44d4-4884-80d0-e73e364780d3)) (segment (start 232.53 115.2325) (end 232.53 121.12) (width 0.2) (layer "B.Cu") (net 10) (tstamp 5e884bb1-cb2d-4912-abdb-714ae01ba223)) @@ -29853,6 +30022,7 @@ (segment (start 225.005001 82.07) (end 228.33 82.07) (width 0.2) (layer "B.Cu") (net 10) (tstamp 79a94bde-9daa-4fc3-9482-9375ac9f1a9c)) (segment (start 222.214369 118.999235) (end 222.214369 120.535631) (width 0.2) (layer "B.Cu") (net 10) (tstamp 7bd1f3b3-d98e-4975-90ac-a00561c7c5e8)) (segment (start 182.38 100.0825) (end 182.38 94.445) (width 0.2) (layer "B.Cu") (net 10) (tstamp 7c5db391-6bcb-4769-a943-6b39bc21e7d7)) + (segment (start 177.055 75.245) (end 177.68 75.87) (width 0.2) (layer "B.Cu") (net 10) (tstamp 83c17464-32d0-4b15-927b-3ce71baeebce)) (segment (start 192.255 99.17) (end 191.143604 99.17) (width 0.2) (layer "B.Cu") (net 10) (tstamp 843913e5-d744-497e-80fd-e6358f1f37ab)) (segment (start 240.58 98.17) (end 240.58 96.17) (width 0.2) (layer "B.Cu") (net 10) (tstamp 85b8b77f-9373-4a78-9202-ba464a70e5f8)) (segment (start 195.9675 62.62) (end 195.9675 61.07) (width 1) (layer "B.Cu") (net 10) (tstamp 8617004e-79c3-4c93-a319-5d101d1cc659)) @@ -29896,6 +30066,7 @@ (segment (start 181.105 109.495) (end 180.1805 108.5705) (width 0.2) (layer "B.Cu") (net 10) (tstamp b3348cb6-b34f-47a6-bf89-77eb969b9730)) (segment (start 211.499239 98.92) (end 211.393604 98.92) (width 0.2) (layer "B.Cu") (net 10) (tstamp b4f6e4e0-6739-4002-be0e-e462f76dab40)) (segment (start 180.33 81.92) (end 180.385 81.365) (width 0.2) (layer "B.Cu") (net 10) (tstamp b6394c72-ab63-451b-a6d8-311d9fa9b6d6)) + (segment (start 177.68 75.87) (end 177.68 79.27) (width 0.2) (layer "B.Cu") (net 10) (tstamp b69555f7-c5b2-4f39-8b73-88200c0069d6)) (segment (start 222.53 110.42) (end 221.53 109.42) (width 0.2) (layer "B.Cu") (net 10) (tstamp b6d00cf6-09ed-494c-bd78-f22c7e366bb4)) (segment (start 212.73 115.2325) (end 212.505 115.4575) (width 0.2) (layer "B.Cu") (net 10) (tstamp b8694d50-5139-4ab7-839d-df7b54b5fac3)) (segment (start 255.925001 45.07) (end 257.18 45.07) (width 0.2) (layer "B.Cu") (net 10) (tstamp b9ea2691-7b23-442c-b7bf-21c8f2bd073b)) @@ -29935,7 +30106,6 @@ (segment (start 212.505 120.895) (end 212.78 121.17) (width 0.2) (layer "B.Cu") (net 10) (tstamp e9bbbaee-cf1b-46b9-9429-d3d4659f7c71)) (segment (start 260.3175 120.5825) (end 260.3175 119.1075) (width 0.5) (layer "B.Cu") (net 10) (tstamp ea3902ff-af19-44b9-bca9-6efea460f77e)) (segment (start 257.58 46.5) (end 257.88 46.5) (width 0.2) (layer "B.Cu") (net 10) (tstamp ea515d4d-91cb-4ca2-b1e0-0645e56f563b)) - (segment (start 177.055 78.645) (end 180.33 81.92) (width 0.2) (layer "B.Cu") (net 10) (tstamp eb038917-0c65-41d4-a036-3738023fe791)) (segment (start 221.08 109.42) (end 220.58 108.92) (width 0.2) (layer "B.Cu") (net 10) (tstamp eb2a7ac5-f9b6-4773-a4b0-aae4ebf6bbf7)) (segment (start 221.53 109.42) (end 221.08 109.42) (width 0.2) (layer "B.Cu") (net 10) (tstamp eb54f7c2-7d09-4201-859c-da3c86a66a19)) (segment (start 257.23 46.5) (end 257.58 46.5) (width 0.2) (layer "B.Cu") (net 10) (tstamp ebb1e33b-7e1a-45e9-81d4-fc83ff770bdd)) @@ -30243,6 +30413,7 @@ (segment (start 258.210025 109.300025) (end 258.13 109.38005) (width 0.2) (layer "In2.Cu") (net 27) (tstamp c3caffaa-ef78-4415-844b-c7128b6cb371)) (segment (start 258.13 109.22) (end 258.210025 109.300025) (width 0.2) (layer "In2.Cu") (net 27) (tstamp da598899-bb2b-4be8-b0ec-b41887aa9891)) (segment (start 258.13 109.38005) (end 258.13 117.42) (width 0.2) (layer "In2.Cu") (net 27) (tstamp e7224add-e40e-4efc-964c-2ceb71874244)) + (segment (start 181.38 77.67) (end 180.18 76.47) (width 0.2) (layer "B.Cu") (net 27) (tstamp 066c33bb-afee-4264-a44e-9fe193004e92)) (segment (start 222.585 79.553604) (end 221.251396 78.22) (width 0.2) (layer "B.Cu") (net 27) (tstamp 0f3c47c4-1c93-49fa-bc1f-d8d7b11b4f2d)) (segment (start 186.735 78.025) (end 186.38 77.67) (width 0.2) (layer "B.Cu") (net 27) (tstamp 10ca370c-e6cc-4a76-bc39-1e962cdedf21)) (segment (start 178.115 67.575) (end 178.115 66.205) (width 0.2) (layer "B.Cu") (net 27) (tstamp 11fb2acf-15c5-45ce-ac9d-c38cd3ed093d)) @@ -30264,6 +30435,7 @@ (segment (start 198.605 79.553604) (end 197.271396 78.22) (width 0.2) (layer "B.Cu") (net 27) (tstamp e4b4348a-5296-4722-a0cc-ad7fadf7f9cc)) (segment (start 209.141396 78.22) (end 199.53 78.22) (width 0.2) (layer "B.Cu") (net 27) (tstamp e66c26cc-3833-4da4-8792-a55fb15a9136)) (segment (start 265.58 124.87) (end 264.03 126.42) (width 0.2) (layer "B.Cu") (net 27) (tstamp e71c9b50-c9ee-4d76-878c-f8ac19b1f7fa)) + (segment (start 180.18 76.47) (end 178.505 76.47) (width 0.2) (layer "B.Cu") (net 27) (tstamp f99d7cdb-73b1-4199-8486-e76d2f57a30d)) (segment (start 174.28 68.97) (end 180.38 75.07) (width 0.2) (layer "F.Cu") (net 28) (tstamp 51803ded-0bb0-4499-a89f-ca01ca859a29)) (segment (start 174.28 66.27) (end 174.28 68.97) (width 0.2) (layer "F.Cu") (net 28) (tstamp b6d026fe-466c-4db1-a022-f449f677b658)) (segment (start 180.38 75.07) (end 180.38 77.67) (width 0.2) (layer "F.Cu") (net 28) (tstamp fe3593c4-7a9d-4742-85fe-9a5c03546a15)) @@ -30292,6 +30464,7 @@ (segment (start 185.465 79.92) (end 185.465 78.555) (width 0.2) (layer "B.Cu") (net 28) (tstamp 3e9db227-fd2e-4ab9-b578-3ccef9ae3204)) (segment (start 174.305 66.295) (end 174.28 66.27) (width 0.2) (layer "B.Cu") (net 28) (tstamp 403adb90-4a4f-4108-9466-bb1250d51b19)) (segment (start 233.255 81.48495) (end 232.11995 82.62) (width 0.2) (layer "B.Cu") (net 28) (tstamp 454352b9-3bf5-4f48-8a85-e7006645fd83)) + (segment (start 179.78 78.27) (end 178.505 78.27) (width 0.2) (layer "B.Cu") (net 28) (tstamp 49b8290f-73aa-4719-9635-9b91dbb16bea)) (segment (start 196.36995 82.12) (end 197.335 81.15495) (width 0.2) (layer "B.Cu") (net 28) (tstamp 4e908e86-7f27-4d94-a80c-e4b3c1859dd7)) (segment (start 201.360761 81.17) (end 200.060761 82.47) (width 0.2) (layer "B.Cu") (net 28) (tstamp 54aaa6cf-28b3-4d33-b5c8-ad421ad33d25)) (segment (start 232.11995 82.62) (end 231.33 82.62) (width 0.2) (layer "B.Cu") (net 28) (tstamp 55441ca0-e77e-4488-ac92-207c8e1f3958)) @@ -30305,6 +30478,7 @@ (segment (start 263.33 129.66) (end 263.33 130.17) (width 0.2) (layer "B.Cu") (net 28) (tstamp 8e22ff07-8e90-4109-a250-e20c78bcb1ea)) (segment (start 174.305 67.575) (end 174.305 66.295) (width 0.2) (layer "B.Cu") (net 28) (tstamp 8f3f9d7f-34ce-4148-b85f-6e1fa6922d45)) (segment (start 226.58 83.02) (end 230.38 83.02) (width 0.2) (layer "B.Cu") (net 28) (tstamp 9506178d-aa10-46fa-a1b8-c721385f847d)) + (segment (start 180.38 77.67) (end 179.78 78.27) (width 0.2) (layer "B.Cu") (net 28) (tstamp 98aac04d-b728-4c58-8e05-9d31ea9c9a3d)) (segment (start 220.58 83.47) (end 219.18 83.47) (width 0.2) (layer "B.Cu") (net 28) (tstamp 9efaa25b-cccd-4963-9ac2-784ab74528b6)) (segment (start 226.18 82.62) (end 226.58 83.02) (width 0.2) (layer "B.Cu") (net 28) (tstamp 9fe8ebd7-b3bd-480a-8b25-cc1a4243b82e)) (segment (start 233.255 79.92) (end 233.255 81.48495) (width 0.2) (layer "B.Cu") (net 28) (tstamp a7611a1c-f96b-4979-b5fd-f9c6b69e1825)) @@ -30728,11 +30902,11 @@ (segment (start 254.362122 85.300378) (end 254.13 85.5325) (width 0.2) (layer "B.Cu") (net 81) (tstamp 37a47831-68a8-43d3-b142-1b196353ea40)) (segment (start 241.58 85.5325) (end 245.38 85.5325) (width 0.2) (layer "B.Cu") (net 81) (tstamp 3b7b8e73-1054-4aba-88d1-737ea500cb6c)) (segment (start 205.33 85.4825) (end 211.58 85.4825) (width 0.2) (layer "B.Cu") (net 81) (tstamp 3db0f412-c89b-4541-a08e-8fd922a4eeb2)) - (segment (start 181.33 85.545) (end 175.38 79.595) (width 0.2) (layer "B.Cu") (net 81) (tstamp 4d90bba8-8ae6-451b-8c21-920240905003)) + (segment (start 178.88 81.17) (end 178.88 83.095) (width 0.2) (layer "B.Cu") (net 81) (tstamp 4f9f947e-241f-42ba-949f-79f16c420cb1)) (segment (start 250.33 85.5325) (end 254.13 85.5325) (width 0.2) (layer "B.Cu") (net 81) (tstamp 51dcda47-ac8a-4978-9723-887fde653b2f)) + (segment (start 175.38 78.47) (end 176.18 79.27) (width 0.2) (layer "B.Cu") (net 81) (tstamp 54400117-5966-4a4f-a1a8-aeb9a85adc24)) (segment (start 181.925 67.575) (end 181.925 66.225) (width 0.2) (layer "B.Cu") (net 81) (tstamp 564772a8-522b-46e7-84b1-f1e834869824)) (segment (start 231.58 89.7325) (end 231.58 85.47) (width 0.2) (layer "B.Cu") (net 81) (tstamp 5a5a2224-07e6-450a-a608-e83bd0dcc297)) - (segment (start 175.38 79.595) (end 175.38 76.47) (width 0.2) (layer "B.Cu") (net 81) (tstamp 65e7c203-df7f-4f7f-937d-f889e4aba362)) (segment (start 221.58 85.4825) (end 221.58 89.7325) (width 0.2) (layer "B.Cu") (net 81) (tstamp 73fda6b0-1cb6-4217-8981-72ab07a08344)) (segment (start 191.58 85.4825) (end 195.33 85.4825) (width 0.2) (layer "B.Cu") (net 81) (tstamp 7bcb0394-246b-41f5-b1dc-0b3ddc13f8bd)) (segment (start 195.33 85.4825) (end 195.8175 85.97) (width 0.2) (layer "B.Cu") (net 81) (tstamp 8d2d6d82-c526-4abe-a4f7-c6b1edb00ec3)) @@ -30747,20 +30921,29 @@ (segment (start 181.33 89.6075) (end 181.33 85.545) (width 0.2) (layer "B.Cu") (net 81) (tstamp c2449367-f26e-4b00-a028-3929b0ee1ac7)) (segment (start 235.33 85.47) (end 241.5175 85.47) (width 0.2) (layer "B.Cu") (net 81) (tstamp c7fe3dd5-0195-45f8-84ef-30d510fa32f3)) (segment (start 200.08 86.07) (end 199.98 85.97) (width 0.2) (layer "B.Cu") (net 81) (tstamp c99f1c9c-9525-4711-8908-42e6975c7275)) + (segment (start 176.98 79.27) (end 178.88 81.17) (width 0.2) (layer "B.Cu") (net 81) (tstamp ce40f7f3-a64b-406b-b89c-8e5867392bb0)) (segment (start 199.98 85.97) (end 201.0925 85.97) (width 0.2) (layer "B.Cu") (net 81) (tstamp d434102b-025c-48e5-aa3c-0c81e47ed824)) (segment (start 245.38 85.5325) (end 250.33 85.5325) (width 0.2) (layer "B.Cu") (net 81) (tstamp ea756cc5-2100-4192-85e4-22aab9e58802)) (segment (start 211.58 89.7325) (end 211.58 85.4825) (width 0.2) (layer "B.Cu") (net 81) (tstamp ee4243f2-9128-41f2-b5f9-e7e9ffaa8a07)) + (segment (start 178.88 83.095) (end 181.33 85.545) (width 0.2) (layer "B.Cu") (net 81) (tstamp ef806edf-a568-4c38-bfd0-a67e82d5e3bc)) + (segment (start 175.38 76.47) (end 175.38 78.47) (width 0.2) (layer "B.Cu") (net 81) (tstamp f2675980-f062-4a65-bbb2-fa68a230ca8c)) + (segment (start 176.18 79.27) (end 176.98 79.27) (width 0.2) (layer "B.Cu") (net 81) (tstamp f9de0ca0-f9a7-40d0-9bf9-d3b9d65a0a2d)) (segment (start 200.08 88.2325) (end 200.08 86.07) (width 0.2) (layer "B.Cu") (net 81) (tstamp fb3e93ba-a66b-4f48-95c2-6879c62b1800)) (segment (start 231.58 85.47) (end 235.33 85.47) (width 0.2) (layer "B.Cu") (net 81) (tstamp fe0cbe1c-a2f4-4515-86c1-9c2bc11f9568)) (segment (start 183.08 81.67) (end 183.035025 81.625025) (width 0.2) (layer "F.Cu") (net 82) (tstamp 296d1bb1-3842-434b-a0d7-51395d2ecea3)) (segment (start 180.68 66.17) (end 180.68 73.25995) (width 0.2) (layer "F.Cu") (net 82) (tstamp 575340bd-cc4f-4940-bcee-88e8aba5ed2c)) (segment (start 183.035025 81.625025) (end 183.035025 75.614975) (width 0.2) (layer "F.Cu") (net 82) (tstamp 6137de4a-d76a-46f8-ab61-6fbf5d461ed5)) (segment (start 180.68 73.25995) (end 183.035025 75.614975) (width 0.2) (layer "F.Cu") (net 82) (tstamp 6f86c6f2-e6c9-49cd-9662-7e713f1934c9)) + (via (at 176.58 80.17) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 82) (tstamp 54cc5474-820b-469b-8e61-299a64d26409)) (via (at 183.08 81.67) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 82) (tstamp 6f660475-62b3-4ad2-badd-5f7c2ab85393)) (via (at 180.68 66.17) (size 0.8) (drill 0.4) (layers "F.Cu" "B.Cu") (net 82) (tstamp d269c222-ae01-478b-b9f4-1da215028865)) + (segment (start 181.58 80.17) (end 176.58 80.17) (width 0.2) (layer "In2.Cu") (net 82) (tstamp bc709376-91ea-4524-83c4-012e36a5d27b)) + (segment (start 183.08 81.67) (end 181.58 80.17) (width 0.2) (layer "In2.Cu") (net 82) (tstamp bfe21857-1363-414e-8011-8556ce7683b7)) (segment (start 180.655 67.575) (end 180.655 66.195) (width 0.2) (layer "B.Cu") (net 82) (tstamp 0029788b-0478-4045-a30b-5164ccc31e42)) (segment (start 182.925 81.515) (end 183.08 81.67) (width 0.2) (layer "B.Cu") (net 82) (tstamp 02e87b5e-83e2-4ef5-a375-ff1fbfaa0d1a)) + (segment (start 176.58 80.17) (end 175.58 80.17) (width 0.2) (layer "B.Cu") (net 82) (tstamp 3a530405-f71c-4205-9933-ed0995a336d2)) (segment (start 180.655 66.195) (end 180.68 66.17) (width 0.2) (layer "B.Cu") (net 82) (tstamp 7a898056-471a-432d-a742-4405e25cc29e)) + (segment (start 175.58 80.17) (end 175.48 80.27) (width 0.2) (layer "B.Cu") (net 82) (tstamp 98b2f137-2d86-4347-8128-09d7caeb5f07)) (segment (start 182.925 79.92) (end 182.925 81.515) (width 0.2) (layer "B.Cu") (net 82) (tstamp b8925caa-7726-4143-8810-22c025d4969f)) (segment (start 218.83 89.095) (end 218.005 89.095) (width 0.2) (layer "F.Cu") (net 84) (tstamp 3326281f-f5dd-4a33-ba36-bc322548e694)) (segment (start 218.005 89.095) (end 217.58 88.67) (width 0.2) (layer "F.Cu") (net 84) (tstamp b3cae221-0c4c-4c3c-824b-6718c6928560)) diff --git a/board/PlantCtrlESP32.kicad_prl b/board/PlantCtrlESP32.kicad_prl index 21f6e4b..572196b 100644 --- a/board/PlantCtrlESP32.kicad_prl +++ b/board/PlantCtrlESP32.kicad_prl @@ -1,6 +1,6 @@ { "board": { - "active_layer": 0, + "active_layer": 31, "active_layer_preset": "", "auto_track_width": false, "hidden_netclasses": [], diff --git a/board/PlantCtrlESP32.kicad_sch b/board/PlantCtrlESP32.kicad_sch index 08a4515..6043a26 100644 --- a/board/PlantCtrlESP32.kicad_sch +++ b/board/PlantCtrlESP32.kicad_sch @@ -2679,6 +2679,9 @@ (junction (at 360.172 380.746) (diameter 0) (color 0 0 0 0) (uuid 2125b107-250d-44b9-ae2a-63555b15b96b) ) + (junction (at 212.09 331.978) (diameter 0) (color 0 0 0 0) + (uuid 21c9489c-b7e7-411e-8242-06cb982ccdfb) + ) (junction (at 505.206 51.054) (diameter 0) (color 0 0 0 0) (uuid 2229d344-cb60-4539-b02a-c72401d1ef40) ) @@ -2814,6 +2817,9 @@ (junction (at 360.172 409.448) (diameter 0) (color 0 0 0 0) (uuid 547e0024-8ca5-4fd9-9ed0-6e6fa4efe2d1) ) + (junction (at 217.678 314.198) (diameter 0) (color 0 0 0 0) + (uuid 54c228c6-a419-4461-b51c-f4689ab11c16) + ) (junction (at 437.388 182.118) (diameter 0) (color 0 0 0 0) (uuid 54e7dc2f-bc56-4792-9ac4-117d8dbca40c) ) @@ -3348,6 +3354,9 @@ (junction (at 220.98 410.21) (diameter 0) (color 0 0 0 0) (uuid ea81a12e-80a8-4055-a8fc-17c9562b0042) ) + (junction (at 219.71 327.914) (diameter 0) (color 0 0 0 0) + (uuid eb134ef6-0e32-46e8-9263-d8797dfe432d) + ) (junction (at 592.074 296.291) (diameter 0) (color 0 0 0 0) (uuid ebf87918-a615-4d30-a04f-fc903a46a5a2) ) @@ -3902,6 +3911,10 @@ (stroke (width 0) (type default)) (uuid 1ac57f67-5331-4ab5-8e31-a0bea0b41fcb) ) + (wire (pts (xy 215.9 314.198) (xy 217.678 314.198)) + (stroke (width 0) (type default)) + (uuid 1af34761-dc49-4d18-bbf4-1492f4cc1d8d) + ) (wire (pts (xy 58.166 74.295) (xy 58.293 74.295)) (stroke (width 0) (type default)) (uuid 1afcf8f1-7ff8-4810-8e5d-9e8796e6dfba) @@ -4042,6 +4055,10 @@ (stroke (width 0) (type default)) (uuid 23de727b-6639-4447-893f-880e5b289536) ) + (wire (pts (xy 212.09 331.978) (xy 212.09 332.994)) + (stroke (width 0) (type default)) + (uuid 23e8c9c3-93be-44ca-8fad-c83dd18ac0c8) + ) (wire (pts (xy 544.576 63.754) (xy 544.576 77.724)) (stroke (width 0) (type default)) (uuid 23f0aa50-d487-4575-a843-de67ca60c727) @@ -4474,7 +4491,7 @@ (stroke (width 0) (type default)) (uuid 3ac512fc-03e0-45ef-bcfc-91cd31a5d08a) ) - (wire (pts (xy 212.598 327.914) (xy 230.378 327.914)) + (wire (pts (xy 212.598 327.914) (xy 219.71 327.914)) (stroke (width 0) (type default)) (uuid 3b182ec3-13b7-44b7-bac1-25041955a3fa) ) @@ -5334,6 +5351,10 @@ (stroke (width 0) (type default)) (uuid 73a51a53-a55b-473b-ad2a-375e6364ea43) ) + (wire (pts (xy 222.758 332.994) (xy 222.758 325.374)) + (stroke (width 0) (type default)) + (uuid 73aa0f01-ebf0-43dc-996d-3ff58256e648) + ) (wire (pts (xy 345.948 165.608) (xy 345.948 171.958)) (stroke (width 0) (type default)) (uuid 73c811c0-180d-4343-833c-a4531fc8ea4b) @@ -5390,6 +5411,10 @@ (stroke (width 0) (type default)) (uuid 7787bad0-9d3f-4609-aabe-4e315b1f104a) ) + (wire (pts (xy 219.71 332.994) (xy 222.758 332.994)) + (stroke (width 0) (type default)) + (uuid 779102a9-05bb-4278-bb3e-42b19f67fb92) + ) (wire (pts (xy 728.218 169.418) (xy 728.218 183.388)) (stroke (width 0) (type default)) (uuid 77a545d4-c2cc-4b63-bbb8-e17a2fec39e3) @@ -5690,6 +5715,10 @@ (stroke (width 0) (type default)) (uuid 8de7403f-6049-43f8-95bf-e7674bbb8126) ) + (wire (pts (xy 217.678 314.198) (xy 217.678 314.706)) + (stroke (width 0) (type default)) + (uuid 8e3947c4-be9e-457a-bc90-0a239e779748) + ) (wire (pts (xy 218.948 164.338) (xy 218.948 169.418)) (stroke (width 0) (type default)) (uuid 8e556e8d-3ee1-4358-b136-37db57b41c2d) @@ -5778,6 +5807,10 @@ (stroke (width 0) (type default)) (uuid 934f0394-ae0e-47f4-91b3-2ec651bd0e40) ) + (wire (pts (xy 207.518 314.198) (xy 208.28 314.198)) + (stroke (width 0) (type default)) + (uuid 93527407-e64a-464a-a822-23f894dba242) + ) (wire (pts (xy 382.778 313.944) (xy 382.778 327.914)) (stroke (width 0) (type default)) (uuid 93562069-8e07-48ad-b56e-a5f0da6e07c4) @@ -5798,6 +5831,10 @@ (stroke (width 0) (type default)) (uuid 943d1afc-7f5d-4875-8168-a29bc8d11059) ) + (wire (pts (xy 217.678 313.944) (xy 217.678 314.198)) + (stroke (width 0) (type default)) + (uuid 953a7cd9-fffb-4ca4-93ce-542d5be8c086) + ) (wire (pts (xy 727.456 63.754) (xy 727.456 77.724)) (stroke (width 0) (type default)) (uuid 957af009-c4d1-4703-a2b0-2895638aac41) @@ -6050,6 +6087,10 @@ (stroke (width 0) (type default)) (uuid a3e55282-f56d-4ba7-a844-9b0da0a714e4) ) + (wire (pts (xy 212.09 330.454) (xy 212.09 331.978)) + (stroke (width 0) (type default)) + (uuid a3f9aa8c-6e37-42a4-a5ea-bdb5c1293da3) + ) (wire (pts (xy 738.378 210.058) (xy 738.378 211.328)) (stroke (width 0) (type default)) (uuid a4d6f58e-d74f-4990-8ab2-709c04b5738d) @@ -6302,6 +6343,10 @@ (stroke (width 0) (type default)) (uuid b51314ec-4cdc-48a3-a408-417d07cad7c9) ) + (wire (pts (xy 211.074 331.978) (xy 212.09 331.978)) + (stroke (width 0) (type default)) + (uuid b556332f-cf07-4913-afad-9a147244daf9) + ) (wire (pts (xy 161.925 598.805) (xy 161.925 602.615)) (stroke (width 0) (type default)) (uuid b56b2139-5a37-484a-90d8-a5f9ef1e143a) @@ -6718,10 +6763,18 @@ (stroke (width 0) (type default)) (uuid ceb39d43-c3f5-4ba0-8409-156fc44404bd) ) + (wire (pts (xy 219.71 327.914) (xy 230.378 327.914)) + (stroke (width 0) (type default)) + (uuid cef05c58-cf41-42bf-ac69-07a5193ba078) + ) (wire (pts (xy 152.146 92.202) (xy 107.696 92.202)) (stroke (width 0) (type default)) (uuid cf535f02-1104-433d-b44e-1468f9b7d04c) ) + (wire (pts (xy 219.71 327.914) (xy 219.71 330.454)) + (stroke (width 0) (type default)) + (uuid cf5ad6aa-78f5-40ce-8d6b-96f71942f001) + ) (wire (pts (xy 445.262 419.608) (xy 445.262 422.148)) (stroke (width 0) (type default)) (uuid cfd7eed5-0d5e-4137-a194-4dc8b31a899b) @@ -7541,6 +7594,10 @@ (effects (font (size 1.27 1.27)) (justify left bottom)) (uuid 7d8bf144-571c-4332-bd3c-87c0906480f4) ) + (text "Very bright\n" (at 651.51 280.67 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + (uuid 832b3340-c75e-433e-b9da-dd5c76103ba0) + ) (text "Input only" (at 108.966 131.572 0) (effects (font (size 1.27 1.27)) (justify left bottom)) (uuid 89047526-255e-471a-8d38-0782d129a865) @@ -9266,6 +9323,13 @@ (effects (font (size 1.27 1.27)) (justify left) hide) ) ) + (global_label "GND" (shape input) (at 211.074 331.978 180) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid 78288350-16cd-4d62-a692-e0cb8d89fb85) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 204.8725 331.978 0) + (effects (font (size 1.27 1.27)) (justify right) hide) + ) + ) (global_label "1K_GND" (shape input) (at 236.728 210.058 0) (fields_autoplaced) (effects (font (size 1.27 1.27)) (justify left)) (uuid 78a43fe2-1a2b-4ecb-b5a3-8196eada2a7b) @@ -10127,6 +10191,13 @@ (effects (font (size 1.27 1.27)) (justify right) hide) ) ) + (global_label "GND" (shape input) (at 207.518 314.198 180) (fields_autoplaced) + (effects (font (size 1.27 1.27)) (justify right)) + (uuid b53f4dbf-44b8-4097-b5a3-e8b67f5ca368) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 201.3165 314.198 0) + (effects (font (size 1.27 1.27)) (justify right) hide) + ) + ) (global_label "SENSOR3_PUMP_END" (shape input) (at 507.746 105.664 270) (fields_autoplaced) (effects (font (size 1.27 1.27)) (justify right)) (uuid b5896234-9844-4a7c-b385-3ed74755ab79) @@ -10666,10 +10737,10 @@ (effects (font (size 1.27 1.27)) (justify left) hide) ) ) - (global_label "SerialIn" (shape input) (at 217.678 313.944 270) (fields_autoplaced) + (global_label "SerialIn" (shape input) (at 217.678 314.706 270) (fields_autoplaced) (effects (font (size 1.27 1.27)) (justify right)) (uuid dca7b472-c7e0-4e05-b5ef-1499c1695b27) - (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 217.678 324.1069 90) + (property "Intersheetrefs" "${INTERSHEET_REFS}" (at 217.678 324.8689 90) (effects (font (size 1.27 1.27)) (justify right) hide) ) ) @@ -20561,6 +20632,35 @@ ) ) + (symbol (lib_id "Device:R") (at 212.09 314.198 90) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid b4ff286f-51e3-425f-8430-14c7e2113349) + (property "Reference" "R46" (at 210.9216 312.42 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "10k" (at 213.233 312.42 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_SMD:R_0603_1608Metric" (at 212.09 315.976 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 212.09 314.198 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "LCSC_PART_NUMBER" "C212284" (at 212.09 314.198 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 4f49bea2-8256-45de-9483-b0b617806a07)) + (pin "2" (uuid cacf7d54-0201-4e58-91b5-78b976778c6d)) + (instances + (project "PlantCtrlESP32" + (path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c" + (reference "R46") (unit 1) + ) + ) + ) + ) + (symbol (lib_id "Device:C") (at 110.49 734.06 0) (unit 1) (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) (uuid b51bde50-3d7a-4a3c-9970-527322e8f4a4) @@ -20783,6 +20883,35 @@ ) ) + (symbol (lib_id "Device:R") (at 215.9 332.994 90) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid bb4afad3-b745-45d5-a7ce-b8763b1bdea0) + (property "Reference" "R51" (at 214.7316 331.216 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "10k" (at 217.043 331.216 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_SMD:R_0603_1608Metric" (at 215.9 334.772 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 215.9 332.994 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "LCSC_PART_NUMBER" "C212284" (at 215.9 332.994 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 5b451fb6-7b85-4d13-aaad-da9a7f63856b)) + (pin "2" (uuid ac816894-a69a-4fbf-9fbe-e1301d8a6d94)) + (instances + (project "PlantCtrlESP32" + (path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c" + (reference "R51") (unit 1) + ) + ) + ) + ) + (symbol (lib_id "Device:LED") (at 263.652 405.638 90) (unit 1) (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) (uuid bb8dd331-89fa-4efd-b804-823bb21d1395) @@ -23618,6 +23747,35 @@ ) ) + (symbol (lib_id "Device:R") (at 215.9 330.454 90) (unit 1) + (in_bom yes) (on_board yes) (dnp no) + (uuid ee167434-7247-432a-8a61-3f2f465cfc2a) + (property "Reference" "R48" (at 214.7316 328.676 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "10k" (at 217.043 328.676 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "Resistor_SMD:R_0603_1608Metric" (at 215.9 332.232 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (at 215.9 330.454 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "LCSC_PART_NUMBER" "C212284" (at 215.9 330.454 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid a8ce9c84-3042-4d2e-aefc-0a6dcd754e22)) + (pin "2" (uuid ec839d03-e002-45c2-8b4f-8962d298176c)) + (instances + (project "PlantCtrlESP32" + (path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c" + (reference "R48") (unit 1) + ) + ) + ) + ) + (symbol (lib_id "Device:C") (at 226.314 383.032 90) (unit 1) (in_bom yes) (on_board yes) (dnp no) (fields_autoplaced) (uuid ee6c797b-3de3-4642-9429-536ccc47bb9f) diff --git a/rust/.cargo/config.toml b/rust/.cargo/config.toml index bfe791a..29aa76a 100644 --- a/rust/.cargo/config.toml +++ b/rust/.cargo/config.toml @@ -3,6 +3,7 @@ target = "xtensa-esp32-espidf" [target.xtensa-esp32-espidf] linker = "ldproxy" +#runner = "espflash flash --monitor --partition-table partitions.csv" # Select this runner for espflash v2.x.x runner = "espflash flash --monitor --baud 921600 --partition-table partitions.csv" # Select this runner for espflash v2.x.x #runner = "cargo runner" rustflags = [ "--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110 diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 80620bb..cb0248a 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -78,6 +78,8 @@ serde_json = "1.0.108" strum = { version = "0.25.0", features = ["derive"] } once_cell = "1.19.0" measurements = "0.11.0" +medians = "3.0.6" +median-accumulator = "0.2.0" #?bq34z100 required [build-dependencies] diff --git a/rust/src/bq34z100.rs b/rust/src/bq34z100.rs index 7e99649..e04b4c5 100644 --- a/rust/src/bq34z100.rs +++ b/rust/src/bq34z100.rs @@ -1,30 +1,31 @@ -use anyhow::bail; use bit_field::BitField; -use embedded_hal::blocking::{i2c::{WriteRead, Write, Read}, delay::DelayMs}; -use esp_idf_sys::vTaskDelay; +use embedded_hal::blocking::{ + delay::DelayMs, + i2c::{Read, Write, WriteRead}, +}; -const BQ34Z100_G1_ADDRESS:u8 = 0x55; +const BQ34Z100_G1_ADDRESS: u8 = 0x55; // // bq34z100g1.cpp // SMC // // Created by Empire-Phoenix, -// directly ported from +// directly ported from // https://github.com/xkam1x/BQ34Z100G1/blob/master/bq34z100g1.cpp by Kamran Ahmad on 08/05/2019. // Xemics conversion from https://github.com/Ralim/BQ34Z100/blob/master/bq34z100.cpp -fn xemics_to_double(x:u32) -> f32 { +fn xemics_to_double(x: u32) -> f32 { let mut b_is_positive = false; - let f_exponent :f32; - let mut f_result :f32; - let v_msbyte :u8 = (x >> 24) as u8; - let mut v_mid_hi_byte :u8 = (x >> 16) as u8; - let v_mid_lo_byte :u8 = (x >> 8) as u8; + let f_exponent: f32; + let mut f_result: f32; + let v_msbyte: u8 = (x >> 24) as u8; + let mut v_mid_hi_byte: u8 = (x >> 16) as u8; + let v_mid_lo_byte: u8 = (x >> 8) as u8; let v_lsbyte: u8 = x as u8; // Get the sign, its in the 0x00 80 00 00 bit - if (v_mid_hi_byte & 128) == 0 { - b_is_positive = true; + if (v_mid_hi_byte & 128) == 0 { + b_is_positive = true; } // Get the exponent, it's 2^(MSbyte - 0x80) @@ -48,41 +49,8 @@ fn xemics_to_double(x:u32) -> f32 { } else { return -f_result; } - - - - // bool bIsPositive = false; - // float fExponent, fResult; - // byte vMSByte = (byte)(X >> 24); - // byte vMidHiByte = (byte)(X >> 16); - // byte vMidLoByte = (byte)(X >> 8); - // byte vLSByte = (byte)X; - // // Get the sign, its in the 0x00 80 00 00 bit - // if ((vMidHiByte & 128) == 0) - // { bIsPositive = true; } - - // // Get the exponent, it's 2^(MSbyte - 0x80) - // fExponent = pow(2, (vMSByte - 128)); - // // Or in 0x80 to the MidHiByte - // vMidHiByte = (byte)(vMidHiByte | 128); - // // get value out of midhi byte - // fResult = (vMidHiByte) * 65536; - // // add in midlow byte - // fResult = fResult + (vMidLoByte * 256); - // // add in LS byte - // fResult = fResult + vLSByte; - // // multiply by 2^-24 to get the actual fraction - // fResult = fResult * pow(2, -24); - // // multiply fraction by the ‘exponent’ part - // fResult = fResult * fExponent; - // // Make negative if necessary - // if (bIsPositive) - // return fResult; - // else - // return -fResult; } - fn float_to_xemics(mut x: f32) -> u32 { let mut b_negative = false; @@ -118,1052 +86,689 @@ fn float_to_xemics(mut x: f32) -> u32 { let i_byte2 = if !b_negative { i_byte2 & 0x7F } else { i_byte2 }; // Zusammenbau des Ergebnisses - return (i_byte1 << 24) | (i_byte2 << 16) | (i_byte3 << 8) | i_byte4 - - - // int iByte1, iByte2, iByte3, iByte4, iExp; - // bool bNegative = false; - // float fMantissa; - // // Don't blow up with logs of zero - // if (X == 0) X = 0.00001F; - // if (X < 0) - // { - // bNegative = true; - // X = -X; - // } - // // find the correct exponent - // iExp = (int)((log(X) / log(2)) + 1);// remember - log of any base is ln(x)/ln(base) - - // // MS byte is the exponent + 0x80 - // iByte1 = iExp + 128; - - // // Divide input by this exponent to get mantissa - // fMantissa = X / (pow(2, iExp)); - - // // Scale it up - // fMantissa = fMantissa / (pow(2, -24)); - - // // Split the mantissa into 3 bytes - // iByte2 = (int)(fMantissa / (pow(2, 16))); - - // iByte3 = (int)((fMantissa - (iByte2 * (pow(2, 16)))) / (pow(2, 8))); - - // iByte4 = (int)(fMantissa - (iByte2 * (pow(2, 16))) - (iByte3 * (pow(2, 8)))); - - // // subtract the sign bit if number is positive - // if (bNegative == false) - // { - // iByte2 = iByte2 & 0x7F; - // } - // return (uint32_t)((uint32_t)iByte1 << 24 | (uint32_t)iByte2 << 16 | (uint32_t)iByte3 << 8 | (uint32_t)iByte4); - + return (i_byte1 << 24) | (i_byte2 << 16) | (i_byte3 << 8) | i_byte4; } +#[derive(Debug)] +pub enum Bq34Z100Error { + NotStored, + I2C { error: E }, +} +impl From for Bq34Z100Error { + fn from(value: E) -> Self { + Bq34Z100Error::I2C { error: value } + } +} -impl Bq34z100g1 for Bq34z100g1Driver where I2C: WriteRead + Write + Read, DELAY: DelayMs { - fn read_2_register_as_u16(&mut self, address:u8) -> u16 { -// println!("Reading register block {:#04x} with length {}", address, 2); +impl Bq34z100g1 for Bq34z100g1Driver +where + I2C: WriteRead + Write + Read, + DELAY: DelayMs, +{ + fn read_2_register_as_u16(&mut self, address: u8) -> Result> { let data: [u8; 1] = [address]; let mut buffer: [u8; 2] = [0; 2]; - self.i2c.write_read(BQ34Z100_G1_ADDRESS, &data, &mut buffer).unwrap(); - u16::from_le_bytes([buffer[0], buffer[1]]) + self.i2c + .write_read(BQ34Z100_G1_ADDRESS, &data, &mut buffer)?; + Ok(u16::from_le_bytes([buffer[0], buffer[1]])) } - fn read_1_register_as_u8(&mut self, address:u8) -> u8 { -// println!("Reading register block {:#04x} with length {}", address, 1); + fn read_1_register_as_u8(&mut self, address: u8) -> Result> { let data: [u8; 1] = [address]; let mut buffer: [u8; 1] = [0; 1]; - self.i2c.write_read(BQ34Z100_G1_ADDRESS, &data, &mut buffer).unwrap(); - buffer[0] + self.i2c + .write_read(BQ34Z100_G1_ADDRESS, &data, &mut buffer)?; + Ok(buffer[0]) } - fn read_control(&mut self,address_lsb:u8, address_msb: u8) -> u16 { -// println!("Reading controll {} {}", address_lsb, address_msb); - let data: [u8;3] = [0x00_u8, address_lsb, address_msb]; - self.i2c.write(BQ34Z100_G1_ADDRESS, &data).unwrap(); + fn read_control(&mut self, address_lsb: u8, address_msb: u8) -> Result> { + let data: [u8; 3] = [0x00_u8, address_lsb, address_msb]; + self.i2c.write(BQ34Z100_G1_ADDRESS, &data)?; return self.read_2_register_as_u16(0x00); - // Wire.beginTransmission(BQ34Z100_G1_ADDRESS); - // Wire.write(0x00); - // Wire.write(address_lsb); - // Wire.write(address_msb); - // Wire.endTransmission(true); - // return read_register(0x00, 2); } - fn internal_temperature(&mut self) -> u16 { + fn internal_temperature(&mut self) -> Result> { return self.read_2_register_as_u16(0x2a); } - fn read_flash_block(&mut self, sub_class:u8, offset:u8) { + fn read_flash_block(&mut self, sub_class: u8, offset: u8) -> Result<(), Bq34Z100Error> { println!("Prepare reading block {}", sub_class); - self.write_reg(0x61, 0x00); // Block control - self.write_reg(0x3e, sub_class); // Flash class - self.write_reg(0x3f, offset / 32); // Flash block - - let data: [u8;1] = [0x40]; - self.i2c.write(BQ34Z100_G1_ADDRESS, &data).unwrap(); + self.write_reg(0x61, 0x00)?; // Block control + self.write_reg(0x3e, sub_class)?; // Flash class + self.write_reg(0x3f, offset / 32)?; // Flash block + + let data: [u8; 1] = [0x40]; + self.i2c.write(BQ34Z100_G1_ADDRESS, &data)?; println!("Reading block {} now", sub_class); - self.i2c.read(BQ34Z100_G1_ADDRESS, &mut self.flash_block_data).unwrap(); - - // write_reg(0x61, 0x00); // Block control - // write_reg(0x3e, sub_class); // Flash class - // write_reg(0x3f, offset / 32); // Flash block - - // Wire.beginTransmission(BQ34Z100_G1_ADDRESS); - // Wire.write(0x40); // Block data - // for (uint8_t i = 0; i < 32; i++) { - // Wire.write(flash_block_data[i]); // Data - // } - // Wire.endTransmission(true); + self.i2c + .read(BQ34Z100_G1_ADDRESS, &mut self.flash_block_data)?; + return Ok(()); } - fn write_reg(&mut self, address:u8, value:u8 ) { - let data: [u8;2] = [address, value]; - self.i2c.write(BQ34Z100_G1_ADDRESS, &data).unwrap(); + fn write_reg(&mut self, address: u8, value: u8) -> Result<(), Bq34Z100Error> { + let data: [u8; 2] = [address, value]; + self.i2c.write(BQ34Z100_G1_ADDRESS, &data)?; - println!("Writing register block {:#04x} with value {}", address, value); - // Wire.beginTransmission(BQ34Z100_G1_ADDRESS); - // Wire.write(addr); - // Wire.write(val); - // Wire.endTransmission(true); + println!( + "Writing register block {:#04x} with value {}", + address, value + ); + return Ok(()); } - fn write_flash_block(&mut self, sub_class:u8 , offset:u8) { - self.write_reg(0x61, 0x00); // Block control - self.write_reg(0x3e, sub_class); // Flash class - self.write_reg(0x3f, offset / 32); // Flash block - - self.i2c.write(BQ34Z100_G1_ADDRESS, &self.flash_block_data).unwrap(); - // write_reg(0x61, 0x00); // Block control - // write_reg(0x3e, sub_class); // Flash class - // write_reg(0x3f, offset / 32); // Flash block - - // Wire.beginTransmission(BQ34Z100_G1_ADDRESS); - // Wire.write(0x40); // Block data - // for (uint8_t i = 0; i < 32; i++) { - // Wire.write(flash_block_data[i]); // Data - // } - // Wire.endTransmission(true); + fn write_flash_block(&mut self, sub_class: u8, offset: u8) -> Result<(), Bq34Z100Error> { + self.write_reg(0x61, 0x00)?; // Block control + self.write_reg(0x3e, sub_class)?; // Flash class + self.write_reg(0x3f, offset / 32)?; // Flash block + + self.i2c + .write(BQ34Z100_G1_ADDRESS, &self.flash_block_data)?; + return Ok(()); } - fn flash_block_checksum(&mut self) -> u8 { + fn flash_block_checksum(&mut self) -> Result> { let mut temp: u8 = 0; - for i in self.flash_block_data.iter(){ + for i in self.flash_block_data.iter() { temp = u8::wrapping_add(temp, *i); } - return u8::wrapping_sub(255,temp); - // uint8_t temp = 0; - // for (uint8_t i = 0; i < 32; i++) { - // temp += flash_block_data[i]; - // } - // return 255 - temp; + return Ok(u8::wrapping_sub(255, temp)); } - fn unsealed(&mut self) { + fn unsealed(&mut self) -> Result<(), Bq34Z100Error> { println!("Unsealing"); - let data : [u8;3] = [0x00, 0x14, 0x04]; - self.i2c.write(BQ34Z100_G1_ADDRESS, &data).unwrap(); + let data: [u8; 3] = [0x00, 0x14, 0x04]; + self.i2c.write(BQ34Z100_G1_ADDRESS, &data)?; - let data2 : [u8;3] = [0x00, 0x72, 0x36]; - self.i2c.write(BQ34Z100_G1_ADDRESS, &data2).unwrap(); - // Wire.beginTransmission(BQ34Z100_G1_ADDRESS); - // Wire.write(0x00); // Control - // Wire.write(0x14); - // Wire.write(0x04); - // Wire.endTransmission(); - - // Wire.beginTransmission(BQ34Z100_G1_ADDRESS); - // Wire.write(0x00); // Control - // Wire.write(0x72); - // Wire.write(0x36); - // Wire.endTransmission(); + let data2: [u8; 3] = [0x00, 0x72, 0x36]; + self.i2c.write(BQ34Z100_G1_ADDRESS, &data2)?; + return Ok(()); } - fn enter_calibration(&mut self) { + fn enter_calibration(&mut self) -> Result<(), Bq34Z100Error> { println!("enter_calibration"); - self.unsealed(); + self.unsealed()?; loop { - self.cal_enable(); + self.cal_enable()?; println!("Enable cal"); - self.enter_cal(); + self.enter_cal()?; self.delay.delay_ms(1000); - if (self.control_status() & 0x1000 > 0) { + if self.control_status()? & 0x1000 > 0 { break; } - }; // CALEN - // unsealed(); - // do { - // cal_enable(); - // enter_cal(); - // delay(1000); - // } while (!(control_status() & 0x1000)); // CALEN + } // CALEN + return Ok(()); } - fn exit_calibration(&mut self) { - loop{ - self.exit_cal(); + fn exit_calibration(&mut self) -> Result<(), Bq34Z100Error> { + loop { + self.exit_cal()?; self.delay.delay_ms(1000); - if self.control_status() & 0x1000 == 0 { + if self.control_status()? & 0x1000 == 0 { break; } } // CALEN self.delay.delay_ms(150); - self.reset(); + self.reset()?; self.delay.delay_ms(150); - // do { - // exit_cal(); - // delay(1000); - // } while (!(control_status() &~ 0x1000)); // CALEN - - // delay(150); - // reset(); - // delay(150); + return Ok(()); } - fn update_design_capacity(&mut self, capacity:u16) -> bool { - self.unsealed(); - self.read_flash_block(48, 0); + /** + * If you are using a lipo li-ion battery this should be the only one you use. Since you cannot change the chemid with this driver, + * and need to use the BatteryManager desktop application anyway, I strongly recommend to set all other config there as well. + */ + fn update_design_capacity(&mut self, capacity: u16) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(48, 0)?; self.flash_block_data[6] = 0; // Cycle Count self.flash_block_data[7] = 0; - + self.flash_block_data[8] = (capacity >> 8) as u8; // CC Threshold self.flash_block_data[9] = (capacity & 0xff) as u8; - + self.flash_block_data[11] = (capacity >> 8) as u8; // Design Capacity self.flash_block_data[12] = (capacity & 0xff) as u8; - println!("Block 11 {} block 12 {}", self.flash_block_data[11], self.flash_block_data[12]); + println!( + "Block 11 {} block 12 {}", + self.flash_block_data[11], self.flash_block_data[12] + ); - for i in 6..=9 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + for i in 6..=9 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } - - for i in 11..=12 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + + for i in 11..=12 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - - + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + println!("Checksum {}", checksum); self.delay.delay_ms(150); - self.reset(); + self.reset()?; self.delay.delay_ms(150); - self.unsealed(); - - self.read_flash_block(48, 0); - let mut updated_cc_threshold : i16 = (self.flash_block_data[8] as i16) << 8_i16; + self.unsealed()?; + + self.read_flash_block(48, 0)?; + let mut updated_cc_threshold: i16 = (self.flash_block_data[8] as i16) << 8_i16; updated_cc_threshold |= self.flash_block_data[9] as i16; - + let mut updated_capacity: i16 = (self.flash_block_data[11] as i16) << 8; updated_capacity |= self.flash_block_data[12] as i16; - - if (self.flash_block_data[6] != 0 || self.flash_block_data[7] != 0) { + + if self.flash_block_data[6] != 0 || self.flash_block_data[7] != 0 { println!("Block 6 or 7 wrong"); - return false; + return Err(Bq34Z100Error::NotStored); } - println!("Expected capacity {} updated threshold {}" , capacity, updated_capacity); - if (capacity as i32 != updated_cc_threshold as i32) { + println!( + "Expected capacity {} updated threshold {}", + capacity, updated_capacity + ); + if capacity as i32 != updated_cc_threshold as i32 { println!("cc threshold wrong"); - return false; + return Err(Bq34Z100Error::NotStored); } - if (capacity as i32 != updated_capacity as i32) { + if capacity as i32 != updated_capacity as i32 { println!("capacity wrong"); - return false; + return Err(Bq34Z100Error::NotStored); } - return true; - // unsealed(); - // read_flash_block(48, 0); - - // flash_block_data[6] = 0; // Cycle Count - // flash_block_data[7] = 0; - - // flash_block_data[8] = capacity >> 8; // CC Threshold - // flash_block_data[9] = capacity & 0xff; - - // flash_block_data[11] = capacity >> 8; // Design Capacity - // flash_block_data[12] = capacity & 0xff; - - // for (uint8_t i = 6; i <= 9; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // for (uint8_t i = 11; i <= 12; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(48, 0); - // int16_t updated_cc_threshold = flash_block_data[8] << 8; - // updated_cc_threshold |= flash_block_data[9]; - - // int16_t updated_capacity = flash_block_data[11] << 8; - // updated_capacity |= flash_block_data[12]; - - // if (flash_block_data[6] != 0 || flash_block_data[7] != 0) { - // return false; - // } - // if (capacity != updated_cc_threshold) { - // return false; - // } - // if (capacity != updated_capacity) { - // return false; - // } - // return true; + return Ok(()); } - fn update_q_max(&mut self, capacity:i16) -> bool { - self.unsealed(); - self.read_flash_block(82, 0); + fn update_q_max(&mut self, capacity: i16) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(82, 0)?; self.flash_block_data[0] = (capacity >> 8) as u8; // Q Max self.flash_block_data[1] = (capacity & 0xff) as u8; - + self.flash_block_data[2] = 0; // Cycle Count self.flash_block_data[3] = 0; - - for i in 0_u8 .. 3_u8 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + + for i in 0_u8..3_u8 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + self.delay.delay_ms(150); - self.reset(); + self.reset()?; self.delay.delay_ms(150); - - self.unsealed(); - self.read_flash_block(82, 0); + + self.unsealed()?; + self.read_flash_block(82, 0)?; let mut updated_q_max: i16 = (self.flash_block_data[0] as i16) << 8; updated_q_max |= self.flash_block_data[1] as i16; - - if (capacity != updated_q_max) { - return false; - } - return true; - // unsealed(); - // read_flash_block(82, 0); - // flash_block_data[0] = capacity >> 8; // Q Max - // flash_block_data[1] = capacity & 0xff; - - // flash_block_data[2] = 0; // Cycle Count - // flash_block_data[3] = 0; - - // for (uint8_t i = 0; i <= 3; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(82, 0); - // int16_t updated_q_max = flash_block_data[0] << 8; - // updated_q_max |= flash_block_data[1]; - - // if (capacity != updated_q_max) { - // return false; - // } - // return true; + if capacity != updated_q_max { + return Err(Bq34Z100Error::NotStored); + } + return Ok(()); } - fn update_design_energy(&mut self, energy:i16, energy_scale:u8) -> bool { - self.unsealed(); - self.read_flash_block(48, 0); + /** + * If you are using a lipo li-ion battery this should be the only one you use. Since you cannot change the chemid with this driver, + * and need to use the BatteryManager desktop application anyway, I strongly recommend to set all other config there as well. + */ + fn update_design_energy( + &mut self, + energy: i16, + energy_scale: u8, + ) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(48, 0)?; self.flash_block_data[13] = (energy >> 8) as u8; // Design Energy self.flash_block_data[14] = (energy & 0xff) as u8; self.flash_block_data[30] = energy_scale; - - for i in 13..=14 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); - } - self.write_reg(0x40 + 30, self.flash_block_data[30]); - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - - self.delay.delay_ms(150); - self.reset(); - self.delay.delay_ms(150); - - self.unsealed(); - self.read_flash_block(48, 0); - let mut updated_energy :i16 = (self.flash_block_data[13] as i16) << 8; - updated_energy |= self.flash_block_data[14] as i16; - - if (energy != updated_energy) { - return false; - } + for i in 13..=14 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; + } + self.write_reg(0x40 + 30, self.flash_block_data[30])?; + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + + self.delay.delay_ms(150); + self.reset()?; + self.delay.delay_ms(150); + + self.unsealed()?; + self.read_flash_block(48, 0)?; + let mut updated_energy: i16 = (self.flash_block_data[13] as i16) << 8; + updated_energy |= self.flash_block_data[14] as i16; + + if energy != updated_energy { + return Err(Bq34Z100Error::NotStored); + } let updated_energy_scale: u8 = self.flash_block_data[30]; if updated_energy_scale != energy_scale { - return false; + return Err(Bq34Z100Error::NotStored); } - return true; - - // unsealed(); - // read_flash_block(48, 0); - // flash_block_data[13] = energy >> 8; // Design Energy - // flash_block_data[14] = energy & 0xff; - - // for (uint8_t i = 13; i <= 14; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(48, 0); - // int16_t updated_energy = flash_block_data[13] << 8; - // updated_energy |= flash_block_data[14]; - - // if (energy != updated_energy) { - // return false; - // } - // return true; + return Ok(()); } - fn update_cell_charge_voltage_range(&mut self, t1_t2:u16, t2_t3:u16, t3_t4:u16)-> bool { - self.unsealed(); - self.read_flash_block(48, 0); - + fn update_cell_charge_voltage_range( + &mut self, + t1_t2: u16, + t2_t3: u16, + t3_t4: u16, + ) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(48, 0)?; + self.flash_block_data[17] = (t1_t2 >> 8) as u8; // Cell Charge Voltage T1-T2 self.flash_block_data[18] = (t1_t2 & 0xff) as u8; - + self.flash_block_data[19] = (t2_t3 >> 8) as u8; // Cell Charge Voltage T2-T3 self.flash_block_data[20] = (t2_t3 & 0xff) as u8; - + self.flash_block_data[21] = (t3_t4 >> 8) as u8; // Cell Charge Voltage T3-T4 self.flash_block_data[22] = (t3_t4 & 0xff) as u8; - - for i in 17..=22 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); - } - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - - self.delay.delay_ms(150); - self.reset(); - self.delay.delay_ms(150); - - self.unsealed(); - self.read_flash_block(48, 0); - let mut updated_t1_t2 : u16 = (self.flash_block_data[17] as u16) << 8; - updated_t1_t2 |= self.flash_block_data[18] as u16; - - let mut updated_t2_t3 : u16 = (self.flash_block_data[19] as u16 )<< 8; - updated_t2_t3 |= self.flash_block_data[20] as u16; - - let mut updated_t3_t4 : u16 = (self.flash_block_data[21] as u16) << 8; - updated_t3_t4 |= self.flash_block_data[22] as u16; - - if (t1_t2 as u16 != updated_t1_t2 || t2_t3 as u16 != updated_t2_t3 || t3_t4 as u16 != updated_t3_t4) { - return false; - } - return true; - // unsealed(); - // read_flash_block(48, 0); - - // flash_block_data[17] = t1_t2 >> 8; // Cell Charge Voltage T1-T2 - // flash_block_data[18] = t1_t2 & 0xff; - - // flash_block_data[19] = t2_t3 >> 8; // Cell Charge Voltage T2-T3 - // flash_block_data[20] = t2_t3 & 0xff; - - // flash_block_data[21] = t3_t4 >> 8; // Cell Charge Voltage T3-T4 - // flash_block_data[22] = t3_t4 & 0xff; - - // for (uint8_t i = 17; i <= 22; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(48, 0); - // uint16_t updated_t1_t2 = flash_block_data[17] << 8; - // updated_t1_t2 |= flash_block_data[18]; - - // uint16_t updated_t2_t3 = flash_block_data[19] << 8; - // updated_t2_t3 |= flash_block_data[20]; - - // uint16_t updated_t3_t4 = flash_block_data[21] << 8; - // updated_t3_t4 |= flash_block_data[22]; - - // if (t1_t2 != updated_t1_t2 || t2_t3 != updated_t2_t3 || t3_t4 != updated_t3_t4) { - // return false; - // } - // return true; - } - fn set_led_mode(&mut self, led_config:u8) { - self.unsealed(); - self.read_flash_block(64, 0); - self.flash_block_data[4] = led_config; - self.write_reg(0x40 + 4, self.flash_block_data[4]); - - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - - self.delay.delay_ms(150); - self.reset(); - self.delay.delay_ms(150); - - self.unsealed(); - self.read_flash_block(64, 0); - - if (self.flash_block_data[4] != led_config){ - println!("Failed to set led config!"); + for i in 17..=22 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + + self.delay.delay_ms(150); + self.reset()?; + self.delay.delay_ms(150); + + self.unsealed()?; + self.read_flash_block(48, 0)?; + let mut updated_t1_t2: u16 = (self.flash_block_data[17] as u16) << 8; + updated_t1_t2 |= self.flash_block_data[18] as u16; + + let mut updated_t2_t3: u16 = (self.flash_block_data[19] as u16) << 8; + updated_t2_t3 |= self.flash_block_data[20] as u16; + + let mut updated_t3_t4: u16 = (self.flash_block_data[21] as u16) << 8; + updated_t3_t4 |= self.flash_block_data[22] as u16; + + if t1_t2 as u16 != updated_t1_t2 + || t2_t3 as u16 != updated_t2_t3 + || t3_t4 as u16 != updated_t3_t4 + { + return Err(Bq34Z100Error::NotStored); + } + return Ok(()); } - fn update_number_of_series_cells(&mut self, cells:u8)-> bool { - self.unsealed(); - self.read_flash_block(64, 0); - - self.flash_block_data[7] = cells; // Number of Series Cell - self.write_reg(0x40 + 7, self.flash_block_data[7]); - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - + fn set_led_mode(&mut self, led_config: u8) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(64, 0)?; + self.flash_block_data[4] = led_config; + self.write_reg(0x40 + 4, self.flash_block_data[4])?; + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + self.delay.delay_ms(150); - self.reset(); + self.reset()?; self.delay.delay_ms(150); - - self.unsealed(); - self.read_flash_block(64, 0); - - if (cells != self.flash_block_data[7]) { - return false; - } - return true; - // unsealed(); - // read_flash_block(64, 0); - - // flash_block_data[7] = cells; // Number of Series Cell - - // write_reg(0x40 + 7, flash_block_data[7]); - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(64, 0); - - // if (cells != flash_block_data[7]) { - // return false; - // } - // return true; + + self.unsealed()?; + self.read_flash_block(64, 0)?; + + if self.flash_block_data[4] != led_config { + println!("Failed to set led config!"); + return Err(Bq34Z100Error::NotStored); + } + return Ok(()); } - fn update_pack_configuration(&mut self, config:u16) -> bool { - self.unsealed(); - self.read_flash_block(64, 0); - + /** + * If you are using a lipo li-ion battery this should be the only one you use. Since you cannot change the chemid with this driver, + * and need to use the BatteryManager desktop application anyway, I strongly recommend to set all other config there as well. + */ + fn update_number_of_series_cells(&mut self, cells: u8) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(64, 0)?; + + self.flash_block_data[7] = cells; // Number of Series Cell + self.write_reg(0x40 + 7, self.flash_block_data[7])?; + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + + self.delay.delay_ms(150); + self.reset()?; + self.delay.delay_ms(150); + + self.unsealed()?; + self.read_flash_block(64, 0)?; + + if cells != self.flash_block_data[7] { + return Err(Bq34Z100Error::NotStored); + } + return Ok(()); + } + + /** + * If you are using a lipo li-ion battery this should be the only one you use. Since you cannot change the chemid with this driver, + * and need to use the BatteryManager desktop application anyway, I strongly recommend to set all other config there as well. + */ + fn update_pack_configuration(&mut self, config: u16) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(64, 0)?; + self.flash_block_data[0] = (config >> 8) as u8; // Pack Configuration self.flash_block_data[1] = (config & 0xff) as u8; - + for i in 0..=1 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + self.delay.delay_ms(150); - self.reset(); + self.reset()?; self.delay.delay_ms(1000); - - self.unsealed(); - self.read_flash_block(64, 0); + + self.unsealed()?; + self.read_flash_block(64, 0)?; let mut updated_config = (self.flash_block_data[0] as u16) << 8; updated_config |= self.flash_block_data[1] as u16; - if (config != updated_config) { - return false; + if config != updated_config { + return Err(Bq34Z100Error::NotStored); } - return true; - // unsealed(); - // read_flash_block(64, 0); - - // flash_block_data[0] = config >> 8; // Pack Configuration - // flash_block_data[1] = config & 0xff; - - // for (uint8_t i = 0; i <= 1; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(64, 0); - // uint16_t updated_config = flash_block_data[0] << 8; - // updated_config |= flash_block_data[1]; - // if (config != updated_config) { - // return false; - // } - // return true; + return Ok(()); } - fn update_charge_termination_parameters(&mut self, taper_current:i16, min_taper_capacity:i16, cell_taper_voltage:i16, - taper_window:u8, tca_set:i8, tca_clear:i8, fc_set:i8, fc_clear:i8) -> bool { - self.unsealed(); - self.read_flash_block(36, 0); - - self.flash_block_data[0] = (taper_current >> 8) as u8; // Taper Current - self.flash_block_data[1] = (taper_current & 0xff) as u8; - - self.flash_block_data[2] = (min_taper_capacity >> 8) as u8; // Min Taper Capacity - self.flash_block_data[3] = (min_taper_capacity & 0xff) as u8; - - self.flash_block_data[4] = (cell_taper_voltage >> 8) as u8; // Cell Taper Voltage - self.flash_block_data[5] = (cell_taper_voltage & 0xff) as u8; - - self.flash_block_data[6] = taper_window; // Current Taper Window - - self.flash_block_data[7] = (tca_set as u8) & 0xff; // TCA Set % - - self.flash_block_data[8] = (tca_clear as u8) & 0xff; // TCA Clear % - - self.flash_block_data[9] = (fc_set as u8) & 0xff; // FC Set % - - self.flash_block_data[10] = (fc_clear as u8) & 0xff; // FC Clear % - - for i in 0..=10 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); - } - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); - - self.delay.delay_ms(150); - self.reset(); - self.delay.delay_ms(150); - - self.unsealed(); - self.read_flash_block(36, 0); - let mut updated_taper_current :i16; - let mut updated_min_taper_capacity: i16; - let mut updated_cell_taper_voltage: i16; - let updated_taper_window: u8; - let updated_tca_set: i8; - let updated_tca_clear: i8; - let updated_fc_set: i8; - let updated_fc_clear: i8; - - updated_taper_current = (self.flash_block_data[0] as i16) << 8; - updated_taper_current |= self.flash_block_data[1] as i16; - - updated_min_taper_capacity = (self.flash_block_data[2] as i16) << 8; - updated_min_taper_capacity |= self.flash_block_data[3] as i16; - - updated_cell_taper_voltage = (self.flash_block_data[4] as i16) << 8; - updated_cell_taper_voltage |= self.flash_block_data[5] as i16; - - updated_taper_window = self.flash_block_data[6]; - - updated_tca_set = (self.flash_block_data[7] & 0xff) as i8; - - updated_tca_clear = (self.flash_block_data[8] & 0xff) as i8; - - updated_fc_set = (self.flash_block_data[9] & 0xff) as i8; - - updated_fc_clear = (self.flash_block_data[10] & 0xff) as i8; - - if (taper_current != updated_taper_current) { - println!("Could not update taper current expected {} actual {}", taper_current, updated_taper_current); - return false; - } - if (min_taper_capacity != updated_min_taper_capacity) { - println!("Could not update min_taper_capacity expected {} actual {}", min_taper_capacity, updated_min_taper_capacity); - return false; - } - if (cell_taper_voltage != updated_cell_taper_voltage) { - println!("Could not update cell_taper_voltage expected {} actual {}", cell_taper_voltage, updated_cell_taper_voltage); - return false; - } - if (taper_window != updated_taper_window) { - println!("Could not update taper_window expected {} actual {}", taper_window, updated_taper_window); - return false; - } - if (tca_set != updated_tca_set) { - println!("Could not update tca_set expected {} actual {}", tca_set, updated_tca_set); - return false; - } - if (tca_clear != updated_tca_clear) { - println!("Could not update tca_clear expected {} actual {}", tca_clear, updated_tca_clear); - return false; - } - if (fc_set != updated_fc_set) { - println!("Could not update fc_set expected {} actual {}", fc_set, updated_fc_set); - return false; - } - if (fc_clear != updated_fc_clear) { - println!("Could not update fc_clear expected {} actual {}", fc_clear, updated_fc_clear); - return false; - } - return true; + //Not recommended to use this + fn update_charge_termination_parameters( + &mut self, + taper_current: i16, + min_taper_capacity: i16, + cell_taper_voltage: i16, + taper_window: u8, + tca_set: i8, + tca_clear: i8, + fc_set: i8, + fc_clear: i8, + ) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.read_flash_block(36, 0)?; - // unsealed(); - // read_flash_block(36, 0); - - // flash_block_data[0] = taper_current >> 8; // Taper Current - // flash_block_data[1] = taper_current & 0xff; - - // flash_block_data[2] = min_taper_capacity >> 8; // Min Taper Capacity - // flash_block_data[3] = min_taper_capacity & 0xff; - - // flash_block_data[4] = cell_taper_voltage >> 8; // Cell Taper Voltage - // flash_block_data[5] = cell_taper_voltage & 0xff; - - // flash_block_data[6] = taper_window; // Current Taper Window - - // flash_block_data[7] = tca_set & 0xff; // TCA Set % - - // flash_block_data[8] = tca_clear & 0xff; // TCA Clear % - - // flash_block_data[9] = fc_set & 0xff; // FC Set % - - // flash_block_data[10] = fc_clear & 0xff; // FC Clear % - - // for (uint8_t i = 0; i <= 10; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); - - // unsealed(); - // read_flash_block(36, 0); - // int16_t updated_taper_current, updated_min_taper_capacity, updated_cell_taper_voltage; - // uint8_t updated_taper_window; - // int8_t updated_tca_set, updated_tca_clear, updated_fc_set, updated_fc_clear; - - // updated_taper_current = flash_block_data[0] << 8; - // updated_taper_current |= flash_block_data[1]; - - // updated_min_taper_capacity = flash_block_data[2] << 8; - // updated_min_taper_capacity |= flash_block_data[3]; - - // updated_cell_taper_voltage = flash_block_data[4] << 8; - // updated_cell_taper_voltage |= flash_block_data[5]; - - // updated_taper_window = flash_block_data[6]; - - // updated_tca_set = flash_block_data[7] & 0xff; - - // updated_tca_clear = flash_block_data[8] & 0xff; - - // updated_fc_set = flash_block_data[9] & 0xff; - - // updated_fc_clear = flash_block_data[10] & 0xff; - - // if (taper_current != updated_taper_current) { - // return false; - // } - // if (min_taper_capacity != updated_min_taper_capacity) { - // return false; - // } - // if (cell_taper_voltage != updated_cell_taper_voltage) { - // return false; - // } - // if (taper_window != updated_taper_window) { - // return false; - // } - // if (tca_set != updated_tca_set) { - // return false; - // } - // if (tca_clear != updated_tca_clear) { - // return false; - // } - // if (fc_set != updated_fc_set) { - // return false; - // } - // if (fc_clear != updated_fc_clear) { - // return false; - // } - // return true; + self.flash_block_data[0] = (taper_current >> 8) as u8; // Taper Current + self.flash_block_data[1] = (taper_current & 0xff) as u8; + + self.flash_block_data[2] = (min_taper_capacity >> 8) as u8; // Min Taper Capacity + self.flash_block_data[3] = (min_taper_capacity & 0xff) as u8; + + self.flash_block_data[4] = (cell_taper_voltage >> 8) as u8; // Cell Taper Voltage + self.flash_block_data[5] = (cell_taper_voltage & 0xff) as u8; + + self.flash_block_data[6] = taper_window; // Current Taper Window + + self.flash_block_data[7] = (tca_set as u8) & 0xff; // TCA Set % + + self.flash_block_data[8] = (tca_clear as u8) & 0xff; // TCA Clear % + + self.flash_block_data[9] = (fc_set as u8) & 0xff; // FC Set % + + self.flash_block_data[10] = (fc_clear as u8) & 0xff; // FC Clear % + + for i in 0..=10 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; + } + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; + + self.delay.delay_ms(150); + self.reset()?; + self.delay.delay_ms(150); + + self.unsealed()?; + self.read_flash_block(36, 0)?; + let mut updated_taper_current: i16; + let mut updated_min_taper_capacity: i16; + let mut updated_cell_taper_voltage: i16; + let updated_taper_window: u8; + let updated_tca_set: i8; + let updated_tca_clear: i8; + let updated_fc_set: i8; + let updated_fc_clear: i8; + + updated_taper_current = (self.flash_block_data[0] as i16) << 8; + updated_taper_current |= self.flash_block_data[1] as i16; + + updated_min_taper_capacity = (self.flash_block_data[2] as i16) << 8; + updated_min_taper_capacity |= self.flash_block_data[3] as i16; + + updated_cell_taper_voltage = (self.flash_block_data[4] as i16) << 8; + updated_cell_taper_voltage |= self.flash_block_data[5] as i16; + + updated_taper_window = self.flash_block_data[6]; + + updated_tca_set = (self.flash_block_data[7] & 0xff) as i8; + + updated_tca_clear = (self.flash_block_data[8] & 0xff) as i8; + + updated_fc_set = (self.flash_block_data[9] & 0xff) as i8; + + updated_fc_clear = (self.flash_block_data[10] & 0xff) as i8; + + if taper_current != updated_taper_current { + println!( + "Could not update taper current expected {} actual {}", + taper_current, updated_taper_current + ); + return Err(Bq34Z100Error::NotStored); + } + if min_taper_capacity != updated_min_taper_capacity { + println!( + "Could not update min_taper_capacity expected {} actual {}", + min_taper_capacity, updated_min_taper_capacity + ); + return Err(Bq34Z100Error::NotStored); + } + if cell_taper_voltage != updated_cell_taper_voltage { + println!( + "Could not update cell_taper_voltage expected {} actual {}", + cell_taper_voltage, updated_cell_taper_voltage + ); + return Err(Bq34Z100Error::NotStored); + } + if taper_window != updated_taper_window { + println!( + "Could not update taper_window expected {} actual {}", + taper_window, updated_taper_window + ); + return Err(Bq34Z100Error::NotStored); + } + if tca_set != updated_tca_set { + println!( + "Could not update tca_set expected {} actual {}", + tca_set, updated_tca_set + ); + return Err(Bq34Z100Error::NotStored); + } + if tca_clear != updated_tca_clear { + println!( + "Could not update tca_clear expected {} actual {}", + tca_clear, updated_tca_clear + ); + return Err(Bq34Z100Error::NotStored); + } + if fc_set != updated_fc_set { + println!( + "Could not update fc_set expected {} actual {}", + fc_set, updated_fc_set + ); + return Err(Bq34Z100Error::NotStored); + } + if fc_clear != updated_fc_clear { + println!( + "Could not update fc_clear expected {} actual {}", + fc_clear, updated_fc_clear + ); + return Err(Bq34Z100Error::NotStored); + } + return Ok(()); } - fn calibrate_cc_offset(&mut self) { - self.enter_calibration(); - + fn calibrate_cc_offset(&mut self) -> Result<(), Bq34Z100Error> { + self.enter_calibration()?; + loop { println!("Loop cc offset"); - self.cc_offset(); + self.cc_offset()?; self.delay.delay_ms(1000); - if(self.control_status() & 0x0800 > 0){ + if self.control_status()? & 0x0800 > 0 { break; } } // CCA - + loop { self.delay.delay_ms(1000); - if(self.control_status() & 0x0800 == 0){ + if self.control_status()? & 0x0800 == 0 { break; - } + } } // CCA - - self.cc_offset_save(); - self.exit_calibration(); - // enter_calibration(); - // do { - // cc_offset(); - // delay(1000); - // } while (!(control_status() & 0x0800)); // CCA - - // do { - // delay(1000); - // } while (!(control_status() &~ 0x0800)); // CCA - - // cc_offset_save(); - // exit_calibration(); + + self.cc_offset_save()?; + self.exit_calibration()?; + return Ok(()); } - fn calibrate_board_offset(&mut self) { - self.enter_calibration(); + fn calibrate_board_offset(&mut self) -> Result<(), Bq34Z100Error> { + self.enter_calibration()?; loop { - self.board_offset(); + self.board_offset()?; self.delay.delay_ms(1000); - if self.control_status() & 0x0c00 > 0{ + if self.control_status()? & 0x0c00 > 0 { break; } - }// CCA + BCA - - loop { - self.delay.delay_ms(1000); - if self.control_status() & 0x0c00 == 0{ - break; - } } // CCA + BCA - - self.cc_offset_save(); - self.exit_calibration(); - // enter_calibration(); - // do { - // board_offset(); - // delay(1000); - // } while (!(control_status() & 0x0c00)); // CCA + BCA - - // do { - // delay(1000); - // } while (!(control_status() &~ 0x0c00)); // CCA + BCA - - // cc_offset_save(); - // exit_calibration(); + loop { + self.delay.delay_ms(1000); + if self.control_status()? & 0x0c00 == 0 { + break; + } + } // CCA + BCA + + self.cc_offset_save()?; + self.exit_calibration()?; + return Ok(()); } - fn calibrate_voltage_divider(&mut self, applied_voltage:f32, cells_count:u8) { - let mut volt_array : [f32;50] = [0.0; 50]; - for i in 0 .. 50 { - - volt_array[i] = self.voltage() as f32; + fn calibrate_voltage_divider(&mut self, applied_voltage: f32) -> Result<(), Bq34Z100Error> { + let mut volt_array: [f32; 50] = [0.0; 50]; + for i in 0..50 { + volt_array[i] = self.voltage()? as f32; self.delay.delay_ms(150); println!("Reading voltage {} as {}", i, volt_array[i]); } - let mut volt_mean : f32 = 0.0; - for i in 0..50 { + let mut volt_mean: f32 = 0.0; + for i in 0..50 { volt_mean += volt_array[i]; } volt_mean /= 50.0; - + let mut volt_sd: f32 = 0.0; for i in 0..50 { - volt_sd += (volt_array[i] - volt_mean).powf(2.0); + volt_sd += (volt_array[i] - volt_mean).powf(2.0); } volt_sd /= 50.0; volt_sd = volt_sd.sqrt(); - - if (volt_sd > 100.0) { - return; + + if volt_sd > 100.0 { + return Ok(()); } - - self.unsealed(); - - self.read_flash_block(104, 0); - - - let mut current_voltage_divider : u16 = (self.flash_block_data[14] as u16) << 8; + + self.unsealed()?; + + self.read_flash_block(104, 0)?; + + let mut current_voltage_divider: u16 = (self.flash_block_data[14] as u16) << 8; current_voltage_divider |= self.flash_block_data[15] as u16; - - let new_voltage_divider: u16 = ((applied_voltage as f32/ volt_mean as f32) * current_voltage_divider as f32) as u16; - + + let new_voltage_divider: u16 = + ((applied_voltage as f32 / volt_mean as f32) * current_voltage_divider as f32) as u16; + println!("Setting new voltage divider to {}", new_voltage_divider); self.flash_block_data[14] = (new_voltage_divider >> 8) as u8; self.flash_block_data[15] = (new_voltage_divider & 0xff) as u8; - + for i in 14..=15 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } - - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); + + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; self.delay.delay_ms(150); - - // self.unsealed(); - // self.read_flash_block(68, 0); - - // let flash_update_of_cell_voltage:i16 = ((2800.0 * cells_count as f32 * 5000.0) / new_voltage_divider as f32) as i16; - - // self.flash_block_data[0] = (flash_update_of_cell_voltage << 8) as u8; - // self.flash_block_data[1] = (flash_update_of_cell_voltage & 0xff) as u8; - - // for i in 0..=1 { - // self.write_reg(0x40 + i, self.flash_block_data[i as usize]); - // } - // println!("Wrote cell voltage {}", flash_update_of_cell_voltage); - - // let checksum = self.flash_block_checksum(); - // self.write_reg(0x60, checksum); - - // self.delay.delay_ms(150); - // self.reset(); - // self.delay.delay_ms(150); - - // double volt_array[50]; - // for (uint8_t i = 0; i < 50; i++) { - // volt_array[i] = voltage(); - // delay(150); - // } - // double volt_mean = 0; - // for (uint8_t i = 0; i < 50; i++) { - // volt_mean += volt_array[i]; - // } - // volt_mean /= 50.0; - - // double volt_sd = 0; - // for (uint8_t i = 0; i < 50; i++) { - // volt_sd += pow(volt_array[i] - volt_mean, 2); - // } - // volt_sd /= 50.0; - // volt_sd = sqrt(volt_sd); - - // if (volt_sd > 100) { - // return; - // } - - // unsealed(); - // read_flash_block(104, 0); - - // uint16_t current_voltage_divider = flash_block_data[14] << 8; - // current_voltage_divider |= flash_block_data[15]; - - // uint16_t new_voltage_divider = ((double)applied_voltage / volt_mean) * (double)current_voltage_divider; - - // flash_block_data[14] = new_voltage_divider >> 8; - // flash_block_data[15] = new_voltage_divider & 0xff; - - // for (uint8_t i = 14; i <= 15; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - // delay(150); - - // unsealed(); - // read_flash_block(68, 0); - - // int16_t flash_update_of_cell_voltage = (double)(2800 * cells_count * 5000) / (double)new_voltage_divider; - - // flash_block_data[0] = flash_update_of_cell_voltage << 8; - // flash_block_data[1] = flash_update_of_cell_voltage & 0xff; - - // for (uint8_t i = 0; i <= 1; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - - // delay(150); - // reset(); - // delay(150); + return Ok(()); } - fn calibrate_sense_resistor(&mut self, applied_current:i16) { - let mut current_array: [f32;50] = [0.0;50]; - for i in 0 .. 50 { - current_array[i] = self.current() as f32; + fn calibrate_sense_resistor(&mut self, applied_current: i16) -> Result<(), Bq34Z100Error> { + let mut current_array: [f32; 50] = [0.0; 50]; + for i in 0..50 { + current_array[i] = self.current()? as f32; println!("Reading current {} @ {}", current_array[i], i); self.delay.delay_ms(150); } let mut current_mean: f32 = 0.0; - for i in 0 .. 50 { + for i in 0..50 { current_mean += current_array[i]; } current_mean /= 50.0; let mut current_sd: f32 = 0.0; - for i in 0 .. 50 { + for i in 0..50 { current_sd += (current_array[i] - current_mean).powf(2.0); } current_sd /= 50.0; current_sd = current_sd.sqrt(); - if (current_sd > 100.0) { - return; + if current_sd > 100.0 { + //actually this might not be ok? + return Ok(()); } - self.unsealed(); - self.read_flash_block(104, 0); + self.unsealed()?; + self.read_flash_block(104, 0)?; let mut cc_gain: u32 = (self.flash_block_data[0] as u32) << 24; cc_gain |= (self.flash_block_data[1] as u32) << 16; cc_gain |= (self.flash_block_data[2] as u32) << 8; cc_gain |= self.flash_block_data[3] as u32; - + let float_cc_gain = xemics_to_double(cc_gain); let xemics_cc_gain = float_to_xemics(float_cc_gain); let float_cc_gain2 = xemics_to_double(xemics_cc_gain); - if (float_cc_gain-float_cc_gain2).abs() > 0.01 { + if (float_cc_gain - float_cc_gain2).abs() > 0.01 { println!("Error converting old gain!!"); } - let mut gain_resistence: f32 = 4.768 / float_cc_gain; - println!("Current gain R is {} xemics is {}", gain_resistence, cc_gain); - - let mut temp: f32 = (current_mean * gain_resistence) / applied_current as f32; - println!("Current is {} , applied current ist {}, new gain is {}", current_mean, applied_current, temp); + let gain_resistence: f32 = 4.768 / float_cc_gain; + println!( + "Current gain R is {} xemics is {}", + gain_resistence, cc_gain + ); - let mut new_cc_gain : u32 = float_to_xemics(4.768 / temp); + let temp: f32 = (current_mean * gain_resistence) / applied_current as f32; + println!( + "Current is {} , applied current ist {}, new gain is {}", + current_mean, applied_current, temp + ); + + let mut new_cc_gain: u32 = float_to_xemics(4.768 / temp); self.flash_block_data[0] = (new_cc_gain >> 24) as u8; self.flash_block_data[1] = (new_cc_gain >> 16) as u8; self.flash_block_data[2] = (new_cc_gain >> 8) as u8; @@ -1174,436 +779,390 @@ impl Bq34z100g1 for Bq34z100g1Driver self.flash_block_data[5] = (new_cc_gain >> 16) as u8; self.flash_block_data[6] = (new_cc_gain >> 8) as u8; self.flash_block_data[7] = (new_cc_gain & 0xff) as u8; - - for i in 0..=3 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + for i in 0..=3 { + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } for i in 4..=7 { - self.write_reg(0x40 + i, self.flash_block_data[i as usize]); + self.write_reg(0x40 + i, self.flash_block_data[i as usize])?; } - let checksum = self.flash_block_checksum(); - self.write_reg(0x60, checksum); + let checksum = self.flash_block_checksum()?; + self.write_reg(0x60, checksum)?; self.delay.delay_ms(150); - self.reset(); + self.reset()?; self.delay.delay_ms(150); - - // double current_array[50]; - // for (uint8_t i = 0; i < 50; i++) { - // current_array[i] = current(); - // delay(150); - // } - // double current_mean = 0; - // for (uint8_t i = 0; i < 50; i++) { - // current_mean += current_array[i]; - // } - // current_mean /= 50.0; - - // double current_sd = 0; - // for (uint8_t i = 0; i < 50; i++) { - // current_sd += pow(current_array[i] - current_mean, 2); - // } - // current_sd /= 50.0; - // current_sd = sqrt(current_sd); - - // if (current_sd > 100) { - // return; - // } - - // unsealed(); - // read_flash_block(104, 0); - - // uint32_t cc_gain = flash_block_data[0] << 24; - // cc_gain |= flash_block_data[1] << 16; - // cc_gain |= flash_block_data[2] << 8; - // cc_gain |= flash_block_data[3]; - - // double gain_resistence = 4.768 / xemics_to_double(cc_gain); - - // double temp = (current_mean * gain_resistence) / (double)applied_current; - - // uint32_t new_cc_gain = double_to_xemics(4.768 / temp); - // flash_block_data[0] = new_cc_gain >> 24; - // flash_block_data[1] = new_cc_gain >> 16; - // flash_block_data[2] = new_cc_gain >> 8; - // flash_block_data[3] = new_cc_gain & 0xff; - - // new_cc_gain = double_to_xemics(5677445.6 / temp); - // flash_block_data[4] = new_cc_gain >> 24; - // flash_block_data[5] = new_cc_gain >> 16; - // flash_block_data[6] = new_cc_gain >> 8; - // flash_block_data[7] = new_cc_gain & 0xff; - - - // for (uint8_t i = 0; i <= 3; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // for (uint8_t i = 4; i <= 7; i++) { - // write_reg(0x40 + i, flash_block_data[i]); - // } - - // write_reg(0x60, flash_block_checksum()); - // delay(150); - // reset(); - // delay(150); + return Ok(()); } - fn set_current_deadband(&mut self, deadband:u8) { + fn set_current_deadband(&mut self, deadband: u8) -> Result<(), Bq34Z100Error> { + let _ = deadband; todo!() } - fn ready(&mut self) { - self.unsealed(); - self.it_enable(); + fn ready(&mut self) -> Result<(), Bq34Z100Error> { + self.unsealed()?; + self.it_enable()?; + return Ok(()); } - fn control_status(&mut self) -> u16 { + fn control_status(&mut self) -> Result> { return self.read_control(0x00, 0x00); } - fn device_type(&mut self) ->u16 { + fn device_type(&mut self) -> Result> { return self.read_control(0x01, 0x00); } - fn fw_version(&mut self)->u16 { + fn fw_version(&mut self) -> Result> { return self.read_control(0x02, 0x00); } - fn hw_version(&mut self)->u16 { + fn hw_version(&mut self) -> Result> { return self.read_control(0x03, 0x00); } - fn reset_data(&mut self) -> u16 { + fn reset_data(&mut self) -> Result> { return self.read_control(0x05, 0x00); } - fn prev_macwrite(&mut self) -> u16 { + fn prev_macwrite(&mut self) -> Result> { return self.read_control(0x07, 0x00); } - fn chem_id(&mut self) -> u16 { + fn chem_id(&mut self) -> Result> { return self.read_control(0x08, 0x00); } - fn board_offset(&mut self) -> u16 { + fn board_offset(&mut self) -> Result> { return self.read_control(0x09, 0x00); } - fn cc_offset(&mut self) -> u16 { + fn cc_offset(&mut self) -> Result> { return self.read_control(0x0a, 0x00); } - fn cc_offset_save(&mut self) -> u16 { + fn cc_offset_save(&mut self) -> Result> { return self.read_control(0x0b, 0x00); } - fn df_version(&mut self) -> u16 { + fn df_version(&mut self) -> Result> { return self.read_control(0x0c, 0x00); } - fn set_fullsleep(&mut self) -> u16 { + fn set_fullsleep(&mut self) -> Result> { return self.read_control(0x10, 0x00); } - fn static_chem_chksum(&mut self) -> u16 { + fn static_chem_chksum(&mut self) -> Result> { return self.read_control(0x17, 0x00); } - fn sealed(&mut self) -> u16 { + fn sealed(&mut self) -> Result> { + //why do we want to ever seal a hobby diy project tho? anyway pull requests welcome ;) todo!() } - fn it_enable(&mut self) -> u16 { + fn it_enable(&mut self) -> Result> { return self.read_control(0x21, 0x00); } - fn cal_enable(&mut self) -> u16 { + fn cal_enable(&mut self) -> Result> { return self.read_control(0x2d, 0x00); } - fn reset(&mut self) -> u16 { + fn reset(&mut self) -> Result> { return self.read_control(0x41, 0x00); } - fn exit_cal(&mut self) -> u16 { + fn exit_cal(&mut self) -> Result> { return self.read_control(0x80, 0x00); } - fn enter_cal(&mut self) -> u16 { + fn enter_cal(&mut self) -> Result> { return self.read_control(0x81, 0x00); } - fn offset_cal(&mut self) -> u16 { + fn offset_cal(&mut self) -> Result> { return self.read_control(0x82, 0x00); } - fn state_of_charge(&mut self) -> u8 { + fn state_of_charge(&mut self) -> Result> { return self.read_1_register_as_u8(0x02); } - fn state_of_charge_max_error(&mut self) -> u8 { + fn state_of_charge_max_error(&mut self) -> Result> { return self.read_1_register_as_u8(0x03); } - fn remaining_capacity(&mut self) -> u16 { + fn remaining_capacity(&mut self) -> Result> { return self.read_2_register_as_u16(0x04); } - fn full_charge_capacity(&mut self) -> u16 { + fn full_charge_capacity(&mut self) -> Result> { return self.read_2_register_as_u16(0x06); } - fn voltage(&mut self) -> u16 { + fn voltage(&mut self) -> Result> { return self.read_2_register_as_u16(0x08); } - fn average_current(&mut self) -> i16 { - return self.read_2_register_as_u16(0x0a) as i16; + fn average_current(&mut self) -> Result> { + return Ok(self.read_2_register_as_u16(0x0a)? as i16); } - fn temperature(&mut self) -> u16 { + fn temperature(&mut self) -> Result> { return self.read_2_register_as_u16(0x0c); } - fn flags(&mut self) -> u16 { + fn flags(&mut self) -> Result> { return self.read_2_register_as_u16(0x0e); } - fn flags_b(&mut self) -> u16 { + fn flags_b(&mut self) -> Result> { return self.read_2_register_as_u16(0x12); } - fn current(&mut self) -> i16 { - return self.read_2_register_as_u16(0x10) as i16; + fn current(&mut self) -> Result> { + return Ok(self.read_2_register_as_u16(0x10)? as i16); } - fn average_time_to_empty(&mut self) -> u16 { + fn average_time_to_empty(&mut self) -> Result> { return self.read_2_register_as_u16(0x18); } - fn average_time_to_full(&mut self) -> u16 { + fn average_time_to_full(&mut self) -> Result> { return self.read_2_register_as_u16(0x1a); } - fn passed_charge(&mut self) -> u16 { + fn passed_charge(&mut self) -> Result> { return self.read_2_register_as_u16(0x1c); } - fn do_d0_time(&mut self) -> u16 { + fn do_d0_time(&mut self) -> Result> { return self.read_2_register_as_u16(0x1e); } - fn available_energy(&mut self) -> u16 { + fn available_energy(&mut self) -> Result> { return self.read_2_register_as_u16(0x24); } - fn average_power(&mut self) -> u16 { + fn average_power(&mut self) -> Result> { return self.read_2_register_as_u16(0x26); } - fn serial_number(&mut self) -> u16 { + fn serial_number(&mut self) -> Result> { return self.read_2_register_as_u16(0x28); } - fn cycle_count(&mut self) -> u16 { + fn cycle_count(&mut self) -> Result> { return self.read_2_register_as_u16(0x2c); } - fn state_of_health(&mut self) -> u16 { + fn state_of_health(&mut self) -> Result> { return self.read_2_register_as_u16(0x2e); } - fn charge_voltage(&mut self) -> u16 { + fn charge_voltage(&mut self) -> Result> { return self.read_2_register_as_u16(0x30); } - fn charge_current(&mut self) -> u16 { + fn charge_current(&mut self) -> Result> { return self.read_2_register_as_u16(0x32); } - fn pack_configuration(&mut self) -> u16 { + fn pack_configuration(&mut self) -> Result> { return self.read_2_register_as_u16(0x3a); } - fn design_capacity(&mut self) -> u16 { + fn design_capacity(&mut self) -> Result> { return self.read_2_register_as_u16(0x3c); } - fn grid_number(&mut self) -> u8 { + fn grid_number(&mut self) -> Result> { return self.read_1_register_as_u8(0x62); } - fn learned_status(&mut self) -> u8 { + fn learned_status(&mut self) -> Result> { return self.read_1_register_as_u8(0x63); } - fn dod_at_eoc(&mut self) -> u16 { + fn dod_at_eoc(&mut self) -> Result> { return self.read_2_register_as_u16(0x64); } - fn q_start(&mut self) -> u16 { + fn q_start(&mut self) -> Result> { return self.read_2_register_as_u16(0x66); } - fn true_fcc(&mut self) -> u16 { + fn true_fcc(&mut self) -> Result> { return self.read_2_register_as_u16(0x6a); } - fn state_time(&mut self) -> u16 { + fn state_time(&mut self) -> Result> { return self.read_2_register_as_u16(0x6c); } - fn q_max_passed_q(&mut self) -> u16 { + fn q_max_passed_q(&mut self) -> Result> { return self.read_2_register_as_u16(0x6e); } - fn dod_0(&mut self) -> u16 { + fn dod_0(&mut self) -> Result> { return self.read_2_register_as_u16(0x70); } - fn q_max_dod_0(&mut self) -> u16 { + fn q_max_dod_0(&mut self) -> Result> { return self.read_2_register_as_u16(0x72); } - fn q_max_time(&mut self) -> u16 { + fn q_max_time(&mut self) -> Result> { return self.read_2_register_as_u16(0x74); } - fn get_flags_decoded(&mut self) -> Flags { - let flags = self.flags().to_le_bytes(); + fn get_flags_decoded(&mut self) -> Result> { + let flags = self.flags()?.to_le_bytes(); - return Flags { + return Ok(Flags { fast_charge_allowed: flags[0].get_bit(0), full_chage: flags[0].get_bit(1), charging_not_allowed: flags[0].get_bit(2), - charge_inhibit: flags[0].get_bit(3), - bat_low: flags[0].get_bit(4), - bat_high: flags[0].get_bit(5), - over_temp_discharge: flags[0].get_bit(6), - over_temp_charge: flags[0].get_bit(7), + charge_inhibit: flags[0].get_bit(3), + bat_low: flags[0].get_bit(4), + bat_high: flags[0].get_bit(5), + over_temp_discharge: flags[0].get_bit(6), + over_temp_charge: flags[0].get_bit(7), - discharge: flags[1].get_bit(0), - state_of_charge_f: flags[1].get_bit(1), - state_of_charge_1: flags[1].get_bit(2), - cf: flags[1].get_bit(4), - ocv_taken: flags[1].get_bit(7) - } + discharge: flags[1].get_bit(0), + state_of_charge_f: flags[1].get_bit(1), + state_of_charge_1: flags[1].get_bit(2), + cf: flags[1].get_bit(4), + ocv_taken: flags[1].get_bit(7), + }); } - - - } -pub struct Bq34z100g1Driver{ +pub struct Bq34z100g1Driver { pub i2c: I2C, pub delay: Delay, - pub flash_block_data: [u8;32], + pub flash_block_data: [u8; 32], } -pub trait Bq34z100g1 { - fn read_2_register_as_u16(&mut self, address:u8) -> u16; - fn read_1_register_as_u8(&mut self, address:u8) -> u8; - fn read_control(&mut self, address_lsb:u8, address_msb: u8) -> u16; - fn read_flash_block(&mut self, sub_class:u8, offset:u8); - fn write_reg(&mut self, address:u8, value:u8 ); - fn write_flash_block(&mut self, sub_class:u8 , offset:u8); - - fn flash_block_checksum(&mut self) -> u8; - - fn unsealed(&mut self); - fn enter_calibration(&mut self); - fn exit_calibration(&mut self); +pub trait Bq34z100g1 { + fn read_2_register_as_u16(&mut self, address: u8) -> Result>; + fn read_1_register_as_u8(&mut self, address: u8) -> Result>; + fn read_control(&mut self, address_lsb: u8, address_msb: u8) -> Result>; + fn read_flash_block(&mut self, sub_class: u8, offset: u8) -> Result<(), Bq34Z100Error>; + fn write_reg(&mut self, address: u8, value: u8) -> Result<(), Bq34Z100Error>; + fn write_flash_block(&mut self, sub_class: u8, offset: u8) -> Result<(), Bq34Z100Error>; - fn update_design_capacity(&mut self, capacity:u16) -> bool; - fn update_q_max(&mut self, capacity:i16) -> bool ; - fn update_design_energy(&mut self, energy:i16, scale:u8) -> bool ; - fn update_cell_charge_voltage_range(&mut self, t1_t2:u16, t2_t3:u16, t3_t4:u16)-> bool ; - fn update_number_of_series_cells(&mut self, cells:u8)-> bool ; - fn update_pack_configuration(&mut self, config:u16) -> bool ; - fn update_charge_termination_parameters(&mut self, taper_current:i16, min_taper_capacity:i16, cell_taper_voltage:i16, - taper_window:u8, tca_set:i8, tca_clear:i8, fc_set:i8, fc_clear:i8) -> bool ; - fn calibrate_cc_offset(&mut self); - fn calibrate_board_offset(&mut self); - fn calibrate_voltage_divider(&mut self, applied_voltage:f32, cells_count:u8); - fn calibrate_sense_resistor(&mut self, applied_current:i16); - fn set_current_deadband(&mut self, deadband:u8); - fn ready(&mut self); - - fn control_status(&mut self) -> u16; - fn device_type(&mut self) ->u16; - fn fw_version(&mut self)->u16; - fn hw_version(&mut self)->u16; - fn reset_data(&mut self) -> u16 ; - fn prev_macwrite(&mut self) -> u16 ; - fn chem_id(&mut self) -> u16 ; - fn board_offset(&mut self) -> u16 ; - fn cc_offset(&mut self) -> u16 ; - fn cc_offset_save(&mut self) -> u16 ; - fn df_version(&mut self) -> u16 ; - fn set_fullsleep(&mut self) -> u16 ; - fn static_chem_chksum(&mut self) -> u16 ; - fn sealed(&mut self) -> u16 ; - fn it_enable(&mut self) -> u16 ; - fn cal_enable(&mut self) -> u16 ; - fn reset(&mut self) -> u16 ; - fn exit_cal(&mut self) -> u16 ; - fn enter_cal(&mut self) -> u16 ; - fn offset_cal(&mut self) -> u16 ; - - fn state_of_charge(&mut self) -> u8 ; // 0 to 100% - fn state_of_charge_max_error(&mut self) -> u8 ; // 1 to 100% - fn remaining_capacity(&mut self) -> u16 ; // mAh - fn full_charge_capacity(&mut self) -> u16 ; // mAh - fn voltage(&mut self) -> u16 ; // mV - fn average_current(&mut self) -> i16; // mA - fn temperature(&mut self) -> u16 ; // Unit of x10 K - fn flags(&mut self) -> u16 ; - fn flags_b(&mut self) -> u16 ; - fn current(&mut self) -> i16; // mA - - fn average_time_to_empty(&mut self) -> u16; // Minutes - fn average_time_to_full(&mut self) -> u16; // Minutes - fn passed_charge(&mut self) -> u16; // mAh - fn do_d0_time(&mut self) -> u16 ; // Minutes - fn available_energy(&mut self) -> u16 ; // 10 mWh - fn average_power(&mut self) -> u16 ; // 10 mW - fn serial_number(&mut self) -> u16 ; - fn internal_temperature(&mut self) -> u16 ; // Unit of x10 K - fn cycle_count(&mut self) -> u16 ; // Counts - fn state_of_health(&mut self) -> u16 ; // 0 to 100% - fn charge_voltage(&mut self) -> u16 ; // mV - fn charge_current(&mut self) -> u16; // mA - fn pack_configuration(&mut self) -> u16 ; - fn design_capacity(&mut self) -> u16 ; // mAh - fn grid_number(&mut self) -> u8 ; - fn learned_status(&mut self) -> u8 ; - fn dod_at_eoc(&mut self) -> u16 ; - fn q_start(&mut self) -> u16; // mAh - fn true_fcc(&mut self) -> u16; // mAh - fn state_time(&mut self) -> u16 ; // s - fn q_max_passed_q(&mut self) -> u16; // mAh - fn dod_0(&mut self) -> u16; - fn q_max_dod_0(&mut self) -> u16; - fn q_max_time(&mut self) -> u16; - fn set_led_mode(&mut self, led_config:u8); - fn get_flags_decoded(&mut self) -> Flags; + fn flash_block_checksum(&mut self) -> Result>; + + fn unsealed(&mut self) -> Result<(), Bq34Z100Error>; + fn enter_calibration(&mut self) -> Result<(), Bq34Z100Error>; + fn exit_calibration(&mut self) -> Result<(), Bq34Z100Error>; + + fn update_design_capacity(&mut self, capacity: u16) -> Result<(), Bq34Z100Error>; + fn update_q_max(&mut self, capacity: i16) -> Result<(), Bq34Z100Error>; + fn update_design_energy(&mut self, energy: i16, scale: u8) -> Result<(), Bq34Z100Error>; + fn update_cell_charge_voltage_range( + &mut self, + t1_t2: u16, + t2_t3: u16, + t3_t4: u16, + ) -> Result<(), Bq34Z100Error>; + fn update_number_of_series_cells(&mut self, cells: u8) -> Result<(), Bq34Z100Error>; + fn update_pack_configuration(&mut self, config: u16) -> Result<(), Bq34Z100Error>; + fn update_charge_termination_parameters( + &mut self, + taper_current: i16, + min_taper_capacity: i16, + cell_taper_voltage: i16, + taper_window: u8, + tca_set: i8, + tca_clear: i8, + fc_set: i8, + fc_clear: i8, + ) -> Result<(), Bq34Z100Error>; + fn calibrate_cc_offset(&mut self) -> Result<(), Bq34Z100Error>; + fn calibrate_board_offset(&mut self) -> Result<(), Bq34Z100Error>; + fn calibrate_voltage_divider(&mut self, applied_voltage: f32) -> Result<(), Bq34Z100Error>; + fn calibrate_sense_resistor(&mut self, applied_current: i16) -> Result<(), Bq34Z100Error>; + fn set_current_deadband(&mut self, deadband: u8) -> Result<(), Bq34Z100Error>; + fn ready(&mut self) -> Result<(), Bq34Z100Error>; + + fn control_status(&mut self) -> Result>; + fn device_type(&mut self) -> Result>; + fn fw_version(&mut self) -> Result>; + fn hw_version(&mut self) -> Result>; + fn reset_data(&mut self) -> Result>; + fn prev_macwrite(&mut self) -> Result>; + fn chem_id(&mut self) -> Result>; + fn board_offset(&mut self) -> Result>; + fn cc_offset(&mut self) -> Result>; + fn cc_offset_save(&mut self) -> Result>; + fn df_version(&mut self) -> Result>; + fn set_fullsleep(&mut self) -> Result>; + fn static_chem_chksum(&mut self) -> Result>; + fn sealed(&mut self) -> Result>; + fn it_enable(&mut self) -> Result>; + fn cal_enable(&mut self) -> Result>; + fn reset(&mut self) -> Result>; + fn exit_cal(&mut self) -> Result>; + fn enter_cal(&mut self) -> Result>; + fn offset_cal(&mut self) -> Result>; + + fn state_of_charge(&mut self) -> Result>; // 0 to 100% + fn state_of_charge_max_error(&mut self) -> Result>; // 1 to 100% + fn remaining_capacity(&mut self) -> Result>; // mAh + fn full_charge_capacity(&mut self) -> Result>; // mAh + fn voltage(&mut self) -> Result>; // mV + fn average_current(&mut self) -> Result>; // mA + fn temperature(&mut self) -> Result>; // Unit of x10 K + fn flags(&mut self) -> Result>; + fn flags_b(&mut self) -> Result>; + fn current(&mut self) -> Result>; // mA + + fn average_time_to_empty(&mut self) -> Result>; // Minutes + fn average_time_to_full(&mut self) -> Result>; // Minutes + fn passed_charge(&mut self) -> Result>; // mAh + fn do_d0_time(&mut self) -> Result>; // Minutes + fn available_energy(&mut self) -> Result>; // 10 mWh + fn average_power(&mut self) -> Result>; // 10 mW + fn serial_number(&mut self) -> Result>; + fn internal_temperature(&mut self) -> Result>; // Unit of x10 K + fn cycle_count(&mut self) -> Result>; // Counts + fn state_of_health(&mut self) -> Result>; // 0 to 100% + fn charge_voltage(&mut self) -> Result>; // mV + fn charge_current(&mut self) -> Result>; // mA + fn pack_configuration(&mut self) -> Result>; + fn design_capacity(&mut self) -> Result>; // mAh + fn grid_number(&mut self) -> Result>; + fn learned_status(&mut self) -> Result>; + fn dod_at_eoc(&mut self) -> Result>; + fn q_start(&mut self) -> Result>; // mAh + fn true_fcc(&mut self) -> Result>; // mAh + fn state_time(&mut self) -> Result>; // s + fn q_max_passed_q(&mut self) -> Result>; // mAh + fn dod_0(&mut self) -> Result>; + fn q_max_dod_0(&mut self) -> Result>; + fn q_max_time(&mut self) -> Result>; + fn set_led_mode(&mut self, led_config: u8) -> Result<(), Bq34Z100Error>; + fn get_flags_decoded(&mut self) -> Result>; } #[derive(Debug)] -pub struct Flags{ - fast_charge_allowed:bool, - full_chage:bool, - charging_not_allowed:bool, - charge_inhibit:bool, - bat_low: bool, - bat_high: bool, - over_temp_discharge: bool, - over_temp_charge: bool, - discharge:bool, - state_of_charge_f: bool, - state_of_charge_1: bool, - cf: bool, - ocv_taken: bool -} \ No newline at end of file +pub struct Flags { + pub fast_charge_allowed: bool, + pub full_chage: bool, + pub charging_not_allowed: bool, + pub charge_inhibit: bool, + pub bat_low: bool, + pub bat_high: bool, + pub over_temp_discharge: bool, + pub over_temp_charge: bool, + pub discharge: bool, + pub state_of_charge_f: bool, + pub state_of_charge_1: bool, + pub cf: bool, + pub ocv_taken: bool, +} diff --git a/rust/src/config.rs b/rust/src/config.rs index d2fdb84..ca4e58d 100644 --- a/rust/src/config.rs +++ b/rust/src/config.rs @@ -14,8 +14,8 @@ pub struct Config { pub tank_sensor_enabled: bool, pub tank_useable_ml: u32, pub tank_warn_percent: u8, - pub tank_empty_mv: u16, - pub tank_full_mv: u16, + pub tank_empty_percent: u16, + pub tank_full_percent: u16, pub night_lamp_hour_start: u8, pub night_lamp_hour_end: u8, @@ -38,8 +38,8 @@ impl Default for Config { plants: [Plant::default(); PLANT_COUNT], max_consecutive_pump_count: 15, tank_useable_ml: 5000, - tank_empty_mv: 0100_u16, - tank_full_mv: 3300_u16, + tank_empty_percent: 0_u16, + tank_full_percent: 100_u16, } } } diff --git a/rust/src/main.rs b/rust/src/main.rs index 3d81367..3b3fba7 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -3,11 +3,13 @@ use std::{ sync::{atomic::AtomicBool, Arc, Mutex}, }; -use anyhow::{Result, bail}; -use chrono::{Datelike, Duration, NaiveDateTime, Timelike, DateTime}; +use anyhow::{bail, Result}; +use chrono::{DateTime, Datelike, Duration, NaiveDateTime, Timelike}; use chrono_tz::{Europe::Berlin, Tz}; use esp_idf_hal::delay::Delay; -use esp_idf_sys::{esp_restart, vTaskDelay, CONFIG_FREERTOS_HZ, esp_deep_sleep}; +use esp_idf_sys::{ + esp_deep_sleep, esp_restart, gpio_deep_sleep_hold_dis, gpio_deep_sleep_hold_en, vTaskDelay, CONFIG_FREERTOS_HZ +}; use esp_ota::rollback_and_reboot; use log::error; use once_cell::sync::Lazy; @@ -51,11 +53,11 @@ enum WaitType { } #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)] -struct LightState{ +struct LightState { active: bool, out_of_work_hour: bool, battery_low: bool, - is_day: bool + is_day: bool, } #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)] @@ -75,7 +77,7 @@ struct PlantState { sensor_error_a: bool, sensor_error_b: bool, sensor_error_p: bool, - out_of_work_hour: bool + out_of_work_hour: bool, } fn wait_infinity(wait_type: WaitType, reboot_now: Arc) -> ! { @@ -122,10 +124,18 @@ pub static STAY_ALIVE: Lazy = Lazy::new(|| AtomicBool::new(false)); fn map_range(from_range: (f32, f32), s: f32) -> Result { if s < from_range.0 { - bail!("Value out of range, min {} but current is {}", from_range.0, s); + bail!( + "Value out of range, min {} but current is {}", + from_range.0, + s + ); } if s > from_range.1 { - bail!("Value out of range, max {} but current is {}", from_range.1, s); + bail!( + "Value out of range, max {} but current is {}", + from_range.1, + s + ); } return Ok(TO.0 + (s - from_range.0) * (TO.1 - TO.0) / (from_range.1 - from_range.0)); } @@ -141,7 +151,7 @@ fn map_range_moisture(s: f32) -> Result { return Ok(tmp as u8); } -fn in_time_range(cur: DateTime, start:u8, end:u8) -> bool{ +fn in_time_range(cur: DateTime, start: u8, end: u8) -> bool { let curhour = cur.hour() as u8; //eg 10-14 if start < end { @@ -152,40 +162,60 @@ fn in_time_range(cur: DateTime, start:u8, end:u8) -> bool{ } } -fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime, enough_water: bool, water_frozen: bool, tank_sensor_error: bool, config: &Config, board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>) -> Option { +fn determine_next_plant( + plantstate: &mut [PlantState; PLANT_COUNT], + cur: DateTime, + enough_water: bool, + water_frozen: bool, + tank_sensor_error: bool, + config: &Config, + board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>, +) -> Option { for plant in 0..PLANT_COUNT { let state = &mut plantstate[plant]; let plant_config = config.plants[plant]; match plant_config.mode { - config::Mode::OFF => { - - }, + config::Mode::OFF => {} config::Mode::TargetMoisture => { - match board.measure_moisture_hz(plant, plant_hal::Sensor::A).and_then (|moist| map_range_moisture(moist as f32)) { + match board + .measure_moisture_hz(plant, plant_hal::Sensor::A) + .and_then(|moist| map_range_moisture(moist as f32)) + { Ok(a) => state.a = Some(a), Err(err) => { board.fault(plant, true); - println!("Could not determine Moisture A for plant {} due to {}", plant, err); - state.a = None; + println!( + "Could not determine Moisture A for plant {} due to {}", + plant, err + ); + state.a = None; state.sensor_error_a = true; } } - match board.measure_moisture_hz(plant, plant_hal::Sensor::B).and_then (|moist| map_range_moisture(moist as f32)) { + match board + .measure_moisture_hz(plant, plant_hal::Sensor::B) + .and_then(|moist| map_range_moisture(moist as f32)) + { Ok(b) => state.b = Some(b), Err(err) => { board.fault(plant, true); - println!("Could not determine Moisture B for plant {} due to {}", plant, err); - state.b = None; + println!( + "Could not determine Moisture B for plant {} due to {}", + plant, err + ); + state.b = None; state.sensor_error_b = true; } } - //FIXME how to average analyze whatever? + //FIXME how to average analyze whatever? let a_low = state.a.is_some() && state.a.unwrap() < plant_config.target_moisture; let b_low = state.b.is_some() && state.b.unwrap() < plant_config.target_moisture; - + if a_low || b_low { state.dry = true; - if tank_sensor_error && !config.tank_allow_pumping_if_sensor_error || !enough_water { + if tank_sensor_error && !config.tank_allow_pumping_if_sensor_error + || !enough_water + { state.no_water = true; } } @@ -194,20 +224,24 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime< if next_pump > cur { state.cooldown = true; } - if !in_time_range(cur, plant_config.pump_hour_start, plant_config.pump_hour_end) { + if !in_time_range( + cur, + plant_config.pump_hour_start, + plant_config.pump_hour_end, + ) { state.out_of_work_hour = true; } if water_frozen { state.frozen = true; } - if state.dry && !state.no_water && !state.cooldown && !state.out_of_work_hour{ + if state.dry && !state.no_water && !state.cooldown && !state.out_of_work_hour { if water_frozen { state.frozen = true; } else { state.do_water = true; } } - }, + } config::Mode::TimerOnly => { let duration = Duration::minutes((60 * plant_config.pump_cooldown_min).into()); let next_pump = board.last_pump_time(plant) + duration; @@ -220,14 +254,18 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime< state.do_water = true; } } - }, + } config::Mode::TimerAndDeadzone => { let duration = Duration::minutes((60 * plant_config.pump_cooldown_min).into()); let next_pump = board.last_pump_time(plant) + duration; if next_pump > cur { state.cooldown = true; - } - if !in_time_range(cur, plant_config.pump_hour_start, plant_config.pump_hour_end) { + } + if !in_time_range( + cur, + plant_config.pump_hour_start, + plant_config.pump_hour_end, + ) { state.out_of_work_hour = true; } if !state.cooldown && !state.out_of_work_hour { @@ -237,10 +275,10 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime< state.do_water = true; } } - }, + } } //FIXME publish state here! - if state.do_water{ + if state.do_water { if board.consecutive_pump_count(plant) > config.max_consecutive_pump_count.into() { state.not_effective = true; board.fault(plant, true); @@ -252,13 +290,16 @@ fn determine_next_plant(plantstate: &mut [PlantState;PLANT_COUNT],cur: DateTime< } for plant in 0..PLANT_COUNT { let state = &plantstate[plant]; - println!("Checking for water plant {} with state {}", plant, state.do_water); + println!( + "Checking for water plant {} with state {}", + plant, state.do_water + ); if state.do_water { return Some(plant); } } println!("No plant needs water"); - return None + return None; } fn safe_main() -> Result<()> { @@ -284,23 +325,23 @@ fn safe_main() -> Result<()> { let partition_state: embedded_svc::ota::SlotState = embedded_svc::ota::SlotState::Unknown; match esp_idf_svc::ota::EspOta::new() { - Ok(ota) => { - //match ota.get_running_slot(){ - // Ok(slot) => { - // partition_state = slot.state; - // println!( - // "Booting from {} with state {:?}", - // slot.label, partition_state - // ); - //}, - // Err(err) => { - // println!("Error getting running slot {}", err); - // }, - //} - }, - Err(err) => { - println!("Error obtaining ota info {}", err); - }, + Ok(ota) => { + //match ota.get_running_slot(){ + // Ok(slot) => { + // partition_state = slot.state; + // println!( + // "Booting from {} with state {:?}", + // slot.label, partition_state + // ); + //}, + // Err(err) => { + // println!("Error getting running slot {}", err); + // }, + //} + } + Err(err) => { + println!("Error obtaining ota info {}", err); + } } println!("Board hal init"); @@ -402,7 +443,7 @@ fn safe_main() -> Result<()> { } if online_mode == OnlineMode::Wifi { - match board.sntp(1000 * 120) { + match board.sntp(1000 * 5) { Ok(new_time) => { cur = new_time; online_mode = OnlineMode::SnTp; @@ -458,37 +499,43 @@ fn safe_main() -> Result<()> { if config.tank_sensor_enabled { let mut tank_value_r = 0; - let success = board.tank_sensor_mv().and_then(|raw| { - tank_value_r = raw; - return map_range( - (config.tank_empty_mv as f32, config.tank_full_mv as f32), - raw as f32, - ); - }).and_then(|percent| { - let left_ml = ((percent / 100_f32) * config.tank_useable_ml as f32) as u32; - println!( - "Tank sensor returned mv {} as {}% leaving {} ml useable", - tank_value_r, percent as u8, left_ml - ); - if config.tank_warn_percent > percent as u8 { - board.general_fault(true); - println!( - "Low water, current percent is {}, minimum warn level is {}", - percent as u8, config.tank_warn_percent + let success = board + .tank_sensor_percent() + .and_then(|raw| { + tank_value_r = raw; + return map_range( + ( + config.tank_empty_percent as f32, + config.tank_full_percent as f32, + ), + raw as f32, ); - } - if config.tank_warn_percent <= 0 { - enough_water = false; - } - return Ok(()); - }); + }) + .and_then(|percent| { + let left_ml = (percent * config.tank_useable_ml as f32) as u32; + println!( + "Tank sensor returned mv {} as {}% leaving {} ml useable", + tank_value_r, percent as u8, left_ml + ); + if config.tank_warn_percent > percent as u8 { + board.general_fault(true); + println!( + "Low water, current percent is {}, minimum warn level is {}", + percent as u8, config.tank_warn_percent + ); + } + if config.tank_warn_percent <= 0 { + enough_water = false; + } + return Ok(()); + }); match success { Err(err) => { println!("Could not determine tank value due to {}", err); board.general_fault(true); tank_sensor_error = true; } - Ok(_) => {}, + Ok(_) => {} } } @@ -503,17 +550,25 @@ fn safe_main() -> Result<()> { water_frozen = true; } break; - }, + } Err(err) => { println!("Could not get water temp {}", err) - }, + } } } - + let mut plantstate = [PlantState { ..Default::default() }; PLANT_COUNT]; - let plant_to_pump = determine_next_plant(&mut plantstate, europe_time, enough_water, water_frozen, tank_sensor_error, &config, &mut board); + let plant_to_pump = determine_next_plant( + &mut plantstate, + europe_time, + enough_water, + water_frozen, + tank_sensor_error, + &config, + &mut board, + ); if STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed) { drop(board); @@ -521,72 +576,94 @@ fn safe_main() -> Result<()> { let _webserver = httpd(reboot_now.clone()); wait_infinity(WaitType::StayAlive, reboot_now.clone()); } - + match plant_to_pump { Some(plant) => { let mut state = plantstate[plant]; let consecutive_pump_count = board.consecutive_pump_count(plant) + 1; board.store_consecutive_pump_count(plant, consecutive_pump_count); let plant_config = config.plants[plant]; - println!("Trying to pump for {}s with pump {} now", plant_config.pump_time_s,plant); - + println!( + "Trying to pump for {}s with pump {} now", + plant_config.pump_time_s, plant + ); + board.any_pump(true)?; board.store_last_pump_time(plant, cur); board.pump(plant, true)?; board.last_pump_time(plant); state.active = true; //FIXME do periodic pump test here and state update - unsafe { vTaskDelay(plant_config.pump_time_s as u32*CONFIG_FREERTOS_HZ) }; - match map_range_moisture(board.measure_moisture_hz(plant, plant_hal::Sensor::PUMP)? as f32) { + unsafe { vTaskDelay(plant_config.pump_time_s as u32 * CONFIG_FREERTOS_HZ) }; + board.pump(plant, false)?; + match map_range_moisture( + board.measure_moisture_hz(plant, plant_hal::Sensor::PUMP)? as f32 + ) { Ok(p) => state.after_p = Some(p), Err(err) => { board.fault(plant, true); - println!("Could not determine Moisture P after for plant {} due to {}", plant, err); - state.after_p = None; + println!( + "Could not determine Moisture P after for plant {} due to {}", + plant, err + ); + state.after_p = None; state.sensor_error_p = true; } } - if state.after_p.is_none() || state.p.is_none() || state.after_p.unwrap() < state.p.unwrap() + 5 { + if state.after_p.is_none() + || state.p.is_none() + || state.after_p.unwrap() < state.p.unwrap() + 5 + { state.pump_error = true; board.fault(plant, true); } - }, + } None => { println!("Nothing to do"); } - , } - let mut light_state = LightState{ ..Default::default() }; + let mut light_state = LightState { + ..Default::default() + }; light_state.is_day = board.is_day(); - light_state.out_of_work_hour = !in_time_range(europe_time, config.night_lamp_hour_start, config.night_lamp_hour_end); + light_state.out_of_work_hour = !in_time_range( + europe_time, + config.night_lamp_hour_start, + config.night_lamp_hour_end, + ); if !light_state.out_of_work_hour { if config.night_lamp_only_when_dark { if !light_state.is_day { + light_state.active = true; board.light(true).unwrap(); } - }else { + } else { + light_state.active = true; board.light(true).unwrap(); } } else { + light_state.active = false; board.light(false).unwrap(); } println!("Lightstate is {:?}", light_state); - - //check if during light time - //lightstate += out of worktime - //check battery level - //lightstate += battery empty - //check solar level if config requires - //lightstate += stillday - //if no preventing lightstate, enable light - //lightstate = active - //deepsleep here? - unsafe { esp_deep_sleep(1000*1000*10) }; + //check if during light time + //lightstate += out of worktime + //check battery level + //lightstate += battery empty + //check solar level if config requires + //lightstate += stillday + //if no preventing lightstate, enable light + //lightstate = active + + //relatch + unsafe{gpio_deep_sleep_hold_dis()}; + unsafe { gpio_deep_sleep_hold_en() }; + unsafe { esp_deep_sleep(1000 * 1000 * 20) }; } -fn main(){ +fn main() { let result = safe_main(); result.unwrap(); } diff --git a/rust/src/plant_hal.rs b/rust/src/plant_hal.rs index a98c5cb..78e6830 100644 --- a/rust/src/plant_hal.rs +++ b/rust/src/plant_hal.rs @@ -1,12 +1,9 @@ //mod config; - -use bit_field::BitField; -use embedded_hal::blocking::i2c::Operation; use embedded_svc::wifi::{ AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration, }; -use esp_idf_hal::i2c::{I2cConfig, I2cDriver, APBTickType}; +use esp_idf_hal::i2c::{I2cConfig, I2cDriver, I2cError}; use esp_idf_hal::units::FromValueType; use esp_idf_svc::eventloop::EspSystemEventLoop; use esp_idf_svc::mqtt::client::QoS::ExactlyOnce; @@ -14,7 +11,7 @@ use esp_idf_svc::mqtt::client::{EspMqttClient, MqttClientConfiguration}; use esp_idf_svc::nvs::EspDefaultNvsPartition; use esp_idf_svc::wifi::config::{ScanConfig, ScanType}; use esp_idf_svc::wifi::EspWifi; -use measurements::{Measurement, Temperature}; +use measurements::Temperature; use plant_ctrl2::sipo::ShiftRegister40; use anyhow::anyhow; @@ -34,7 +31,7 @@ use ds18b20::Ds18b20; use embedded_hal::digital::v2::OutputPin; use esp_idf_hal::adc::{attenuation, AdcChannelDriver, AdcDriver}; use esp_idf_hal::delay::Delay; -use esp_idf_hal::gpio::{AnyInputPin, Gpio39, Gpio4, Level, PinDriver, Pull, InputOutput}; +use esp_idf_hal::gpio::{AnyInputPin, Gpio39, Gpio4, InputOutput, Level, PinDriver, Pull}; use esp_idf_hal::pcnt::{ PcntChannel, PcntChannelConfig, PcntControlMode, PcntCountMode, PcntDriver, PinIndex, }; @@ -42,12 +39,12 @@ use esp_idf_hal::prelude::Peripherals; use esp_idf_hal::reset::ResetReason; use esp_idf_svc::sntp::{self, SyncStatus}; use esp_idf_svc::systime::EspSystemTime; -use esp_idf_sys::{vTaskDelay, EspError, esp}; +use esp_idf_sys::{gpio_hold_dis, gpio_hold_en, vTaskDelay, EspError}; use one_wire_bus::OneWire; +use crate::bq34z100::{Bq34Z100Error, Bq34z100g1, Bq34z100g1Driver}; use crate::config::{self, Config, WifiConfig}; use crate::STAY_ALIVE; -use crate::bq34z100::{Bq34z100g1Driver, Bq34z100g1}; pub const PLANT_COUNT: usize = 8; const PINS_PER_PLANT: usize = 5; @@ -61,6 +58,8 @@ const SPIFFS_PARTITION_NAME: &str = "storage"; const WIFI_CONFIG_FILE: &str = "/spiffs/wifi.cfg"; const CONFIG_FILE: &str = "/spiffs/config.cfg"; +const TANK_MULTI_SAMPLE: usize = 11; + #[link_section = ".rtc.data"] static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT]; #[link_section = ".rtc.data"] @@ -137,7 +136,7 @@ pub trait PlantCtrlBoardInteraction { fn is_day(&self) -> bool; fn water_temperature_c(&mut self) -> Result; - fn tank_sensor_mv(&mut self) -> Result; + fn tank_sensor_percent(&mut self) -> Result; fn set_low_voltage_in_cycle(&mut self); fn clear_low_voltage_in_cycle(&mut self); @@ -202,7 +201,11 @@ pub struct PlantCtrlBoard<'a> { impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { fn battery_state(&mut self) -> Result { - Ok(BatteryState::default()) + let state = BatteryState { + ..Default::default() + }; + + Ok(state) } fn is_day(&self) -> bool { @@ -236,17 +239,45 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { if sensor_data.temperature == 85_f32 { bail!("Ds18b20 dummy temperature returned"); } - Ok(sensor_data.temperature/10_f32) + Ok(sensor_data.temperature / 10_f32) } - fn tank_sensor_mv(&mut self) -> Result { + fn tank_sensor_percent(&mut self) -> Result { let delay = Delay::new_default(); self.tank_power.set_high()?; //let stabilize delay.delay_ms(100); - let value = self.tank_driver.read(&mut self.tank_channel)?; - self.tank_power.set_low()?; - Ok(value) + unsafe { + vTaskDelay(100); + } + + let mut store = [0_u16; TANK_MULTI_SAMPLE]; + for multisample in 0..TANK_MULTI_SAMPLE { + let value = self.tank_driver.read(&mut self.tank_channel)?; + store[multisample] = value; + } + store.sort(); + let median = store[6] as f32 / 1000_f32; + let config_open_voltage_mv = 3.0; + if config_open_voltage_mv < median { + self.tank_power.set_low()?; + bail!( + "Tank sensor missing, open loop voltage {} on tank sensor input {}", + config_open_voltage_mv, + median + ); + } + + let r2 = median * 50.0 / (3.3 - median); + let mut percent = r2 / 190_f32 * 100_f32; + percent = percent.clamp(0.0, 100.0); + + let quantizised = quantize_to_next_5_percent(percent as f64) as u16; + println!( + "Tank sensor raw {} percent {} quantized {}", + median, percent, quantizised + ); + return Ok(quantizised); } fn set_low_voltage_in_cycle(&mut self) { @@ -258,7 +289,9 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { } fn light(&mut self, enable: bool) -> Result<()> { + unsafe { gpio_hold_dis(self.light.pin()) }; self.light.set_state(enable.into())?; + unsafe { gpio_hold_en(self.light.pin()) }; Ok(()) } @@ -667,40 +700,69 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> { } } +fn print_battery( + battery_driver: &mut Bq34z100g1Driver, +) -> Result<(), Bq34Z100Error> { + let fwversion = battery_driver.fw_version()?; + println!("fw version is {}", fwversion); + + let design_capacity = battery_driver.design_capacity()?; + println!("Design Capacity {}", design_capacity); + if design_capacity == 1000 { + println!("Still stock configuring battery, readouts are likely to be wrong!"); + } + + let flags = battery_driver.get_flags_decoded()?; + println!("Flags {:?}", flags); + + let chem_id = battery_driver.chem_id()?; + let bat_temp = battery_driver.internal_temperature()?; + let temp_c = Temperature::from_kelvin(bat_temp as f64 / 10_f64).as_celsius(); + let voltage = battery_driver.voltage()?; + let current = battery_driver.current()?; + let state = battery_driver.state_of_charge()?; + let charge_voltage = battery_driver.charge_voltage()?; + let charge_current = battery_driver.charge_current()?; + println!("ChemId: {} Current voltage {} and current {} with charge {}% and temp {} CVolt: {} CCur {}", chem_id, voltage, current, state, temp_c, charge_voltage, charge_current); + return Result::Ok(()); +} + impl CreatePlantHal<'_> for PlantHal { fn create() -> Result>> { let peripherals = Peripherals::take()?; - + let i2c = peripherals.i2c1; let config = I2cConfig::new() - .scl_enable_pullup(false) - .sda_enable_pullup(false) - .baudrate(10_u32.kHz().into()); + .scl_enable_pullup(false) + .sda_enable_pullup(false) + .baudrate(10_u32.kHz().into()); let scl = peripherals.pins.gpio16; let sda = peripherals.pins.gpio17; - let driver = I2cDriver::new(i2c, sda, scl, &config).unwrap(); - let i2c_port = driver.port(); - let mut battery_driver :Bq34z100g1Driver = Bq34z100g1Driver{ - i2c :driver, + + //let i2c_port = driver.port(); + //esp!(unsafe { esp_idf_sys::i2c_set_timeout(i2c_port, 1048000) }).unwrap(); + + let mut battery_driver: Bq34z100g1Driver = Bq34z100g1Driver { + i2c: driver, delay: Delay::new_default(), - flash_block_data : [0;32], - }; + flash_block_data: [0; 32], + }; let mut clock = PinDriver::input_output(peripherals.pins.gpio21)?; - clock.set_pull(Pull::Floating); + clock.set_pull(Pull::Floating).unwrap(); let mut latch = PinDriver::input_output(peripherals.pins.gpio22)?; - latch.set_pull(Pull::Floating); + latch.set_pull(Pull::Floating).unwrap(); let mut data = PinDriver::input_output(peripherals.pins.gpio19)?; - data.set_pull(Pull::Floating); + data.set_pull(Pull::Floating).unwrap(); let shift_register = ShiftRegister40::new(clock.into(), latch.into(), data.into()); for mut pin in shift_register.decompose() { pin.set_low().unwrap(); } let mut one_wire_pin = PinDriver::input_output_od(peripherals.pins.gpio4)?; - one_wire_pin.set_pull(Pull::Floating); + one_wire_pin.set_pull(Pull::Floating).unwrap(); //TODO make to none if not possible to init //init,reset rtc memory depending on cause @@ -765,12 +827,15 @@ impl CreatePlantHal<'_> for PlantHal { let nvs = EspDefaultNvsPartition::take()?; let wifi_driver = EspWifi::new(peripherals.modem, sys_loop, Some(nvs))?; - let last_watering_timestamp = Mutex::new(unsafe { LAST_WATERING_TIMESTAMP }); let consecutive_watering_plant = Mutex::new(unsafe { CONSECUTIVE_WATERING_PLANT }); let low_voltage_detected = Mutex::new(unsafe { LOW_VOLTAGE_DETECTED }); - let tank_driver = - AdcDriver::new(peripherals.adc1, &esp_idf_hal::adc::config::Config::new())?; + + let adc_config = esp_idf_hal::adc::config::Config { + resolution: esp_idf_hal::adc::config::Resolution::Resolution12Bit, + calibration: true, + }; + let tank_driver = AdcDriver::new(peripherals.adc1, &adc_config)?; let tank_channel: AdcChannelDriver<'_, { attenuation::DB_11 }, Gpio39> = AdcChannelDriver::new(peripherals.pins.gpio39)?; @@ -779,8 +844,10 @@ impl CreatePlantHal<'_> for PlantHal { let mut boot_button = PinDriver::input(peripherals.pins.gpio0)?; boot_button.set_pull(Pull::Floating)?; + let mut light = PinDriver::input_output(peripherals.pins.gpio26)?; - light.set_pull(Pull::Floating)?; + light.set_pull(Pull::Floating).unwrap(); + let mut main_pump = PinDriver::input_output(peripherals.pins.gpio23)?; main_pump.set_pull(Pull::Floating)?; main_pump.set_low()?; @@ -794,143 +861,10 @@ impl CreatePlantHal<'_> for PlantHal { println!("After stuff"); - esp!(unsafe { esp_idf_sys::i2c_set_timeout(i2c_port, 1048000) }).unwrap(); - - let fwversion = battery_driver.fw_version(); - println!("fw version is {}", fwversion); - - let design_capacity = battery_driver.design_capacity(); - println!("Design Capacity {}", design_capacity); - if(design_capacity == 1000){ - println!("Still stock configuring battery"); + let status = print_battery(&mut battery_driver); + if status.is_err() { + println!("Error communicating with battery!! {:?}", status.err()); } - - //battery_driver.update_design_capacity(5999); - - - //let mut success = battery_driver.update_design_capacity(6000); - //if (!success){ - // bail!("Error updating capacity"); - //} - - //success = battery_driver.update_q_max(6000); - //if (!success){ - // bail!("Error updating max q"); - //} - - //let energy = 25600; - //success = battery_driver.update_design_energy(energy, 3); - //if (!success){ - // bail!("Error updating design energy"); - //} - - //success = battery_driver.update_cell_charge_voltage_range(3650,3650,3650); - //if (!success){ - // bail!("Error updating cell charge voltage"); - //} - - //success = battery_driver.update_number_of_series_cells(4); - //if (!success){ - // bail!("Error updating number of series"); - //} - - //charge termination here - - - - // //RESCAP CAL_EN SCALED RSVD VOLTSEL IWAKE RSNS1 RSNS0 - // //RFACTSTEP SLEEP RMFCC NiDT NiDV QPCCLEAR GNDSEL TEMPS - // let mut conf: u16 = 0; - // //RESCAP - // conf.set_bit(15, true); - // //CAL_EN - // conf.set_bit(14, true); - // //SCALED - // conf.set_bit(13, false); - // //RSVD - // conf.set_bit(12, false); - // //VOLTSEL - // conf.set_bit(11, true); - // //IWAKE - // conf.set_bit(10, false); - // //RSNS1 - // conf.set_bit(9, false); - // //RSNS0 - // conf.set_bit(8, true); - - // //RFACTSTEP - // conf.set_bit(7, true); - // //SLEEP - // conf.set_bit(6, true); - // //RMFCC - // conf.set_bit(5, true); - // //NiDT - // conf.set_bit(4, false); - // //NiDV - // conf.set_bit(3, false); - // //QPCCLEAR - // conf.set_bit(2, false); - // //GNDSEL - // conf.set_bit(1, true); - // //TEMPS - // conf.set_bit(0, false); - - - - // let mut success = battery_driver.update_pack_configuration(conf); - // if (!success){ - // bail!("Error updating pack config"); - // } - -// let mut success = battery_driver.update_charge_termination_parameters(100, 25, 100, 40, 99, 95, 100, 96); -// if (!success){ -// bail!("Error updating pack config"); -// } - -//calibration here - - //println!("Cc offset"); - //battery_driver.calibrate_cc_offset(); - //println!("board offset"); - //battery_driver.calibrate_board_offset(); - //println!("voltage divider"); - //battery_driver.calibrate_voltage_divider(15000.0, 4); - - //battery_driver.calibrate_sense_resistor(1530); - //let mut data = 0_u8; - //data.set_bit(0, true); //led mode - //data.set_bit(1, false); // led mode - //data.set_bit(2, false); //led mode - - //data.set_bit(3, true); //led always on - - - //battery_driver.set_led_mode(data); - //battery_driver.unsealed(); - battery_driver.it_enable(); - - loop { - - let flags = battery_driver.get_flags_decoded(); - println!("Flags {:?}", flags); - - let chem_id = battery_driver.chem_id(); - let bat_temp = battery_driver.internal_temperature(); - let temp_c = Temperature::from_kelvin(bat_temp as f64/10_f64).as_celsius(); - let voltage = battery_driver.voltage(); - let current = battery_driver.current(); - let state = battery_driver.state_of_charge(); - let charge_voltage = battery_driver.charge_voltage(); - let charge_current = battery_driver.charge_current(); - println!("ChemId: {} Current voltage {} and current {} with charge {}% and temp {} CVolt: {} CCur {}", chem_id, voltage, current, state, temp_c, charge_voltage, charge_current); - - unsafe{ - vTaskDelay(1000); - } - - } - - let rv = Mutex::new(PlantCtrlBoard { shift_register, last_watering_timestamp, @@ -952,3 +886,21 @@ impl CreatePlantHal<'_> for PlantHal { Ok(rv) } } + +fn quantize_to_next_5_percent(value: f64) -> i32 { + // Multiply by 100 to work with integer values + let multiplied_value = (value * 100.0).round() as i32; + + // Calculate the remainder when divided by 5 + let remainder = multiplied_value % 5; + + // If the remainder is greater than or equal to half of 5, round up to the next 5% + let rounded_value = if remainder >= 2 { + multiplied_value + (5 - remainder) + } else { + multiplied_value - remainder + }; + + // Divide by 100 to get back to a float + rounded_value / 100 +} diff --git a/rust/src/webserver/config.html b/rust/src/webserver/config.html index fd6af1d..0156e59 100644 --- a/rust/src/webserver/config.html +++ b/rust/src/webserver/config.html @@ -43,12 +43,12 @@ Tank Warn below mL
- - Tank Empty Voltage (mv) + + Tank Empty Percent (% max move)
- - Tank Full Voltage (mv) + + Tank Full Percent (% max move)

Light:

diff --git a/rust/src_webpack/src/form.ts b/rust/src_webpack/src/form.ts index 90ffa4c..6c0890f 100644 --- a/rust/src_webpack/src/form.ts +++ b/rust/src_webpack/src/form.ts @@ -5,8 +5,8 @@ interface PlantConfig { tank_allow_pumping_if_sensor_error: boolean, tank_useable_ml: number, tank_warn_percent: number, - tank_empty_mv: number, - tank_full_mv: number, + tank_empty_percent: number, + tank_full_percent: number, night_lamp_hour_start: number, night_lamp_hour_end: number, night_lamp_only_when_dark: boolean, @@ -46,10 +46,10 @@ let fromWrapper = (() => { let tank_useable_ml = document.getElementById("tank_useable_ml") as HTMLInputElement; tank_useable_ml.onchange = updateJson - let tank_empty_mv = document.getElementById("tank_empty_mv") as HTMLInputElement; - tank_empty_mv.onchange = updateJson - let tank_full_mv = document.getElementById("tank_full_mv") as HTMLInputElement; - tank_full_mv.onchange = updateJson + let tank_empty_percent = document.getElementById("tank_empty_percent") as HTMLInputElement; + tank_empty_percent.onchange = updateJson + let tank_full_percent = document.getElementById("tank_full_percent") as HTMLInputElement; + tank_full_percent.onchange = updateJson let tank_warn_percent = document.getElementById("tank_warn_percent") as HTMLInputElement; tank_warn_percent.onchange = updateJson let tank_sensor_enabled = document.getElementById("tank_sensor_enabled") as HTMLInputElement; @@ -189,8 +189,8 @@ let fromWrapper = (() => { tank_allow_pumping_if_sensor_error.checked = current.tank_allow_pumping_if_sensor_error; tank_useable_ml.value = current.tank_useable_ml.toString(); tank_warn_percent.value = current.tank_warn_percent.toString(); - tank_empty_mv.value = current.tank_empty_mv.toString(); - tank_full_mv.value = current.tank_full_mv.toString(); + tank_empty_percent.value = current.tank_empty_percent.toString(); + tank_full_percent.value = current.tank_full_percent.toString(); night_lamp_time_start.value = current.night_lamp_hour_start.toString(); night_lamp_time_end.value = current.night_lamp_hour_end.toString(); @@ -220,8 +220,8 @@ let fromWrapper = (() => { tank_sensor_enabled: tank_sensor_enabled.checked, tank_useable_ml: +tank_useable_ml.value, tank_warn_percent: +tank_warn_percent.value, - tank_empty_mv: +tank_empty_mv.value, - tank_full_mv: +tank_full_mv.value, + tank_empty_percent: +tank_empty_percent.value, + tank_full_percent: +tank_full_percent.value, night_lamp_hour_start: +night_lamp_time_start.value, night_lamp_hour_end: +night_lamp_time_end.value, night_lamp_only_when_dark: night_lamp_only_when_dark.checked,