273 Commits

Author SHA1 Message Date
d2fb6b8411 adjustments for 3.0 pcb 2024-06-18 20:34:35 +02:00
4d92e0c2a6 more stack for json, more json for mqtt 2024-06-10 23:40:50 +02:00
b57eb2513c more json 2024-06-10 21:37:58 +02:00
3f98a321fc mqtt now uses more json to reduce message count 2024-06-10 21:10:46 +02:00
27858948e5 also disable warning light at start 2024-06-08 21:13:26 +02:00
e87012cc9c keep fault alive actually :) 2024-06-08 00:27:12 +02:00
214db0cc67 v3.0 first pcb 2024-06-04 03:01:13 +02:00
229f7cda10 v3 adjustments, sensor test project 2024-06-02 11:54:35 +02:00
b6abebd012 switch to oneshoot adc, as that seems to work 2024-05-14 21:57:11 +02:00
e2d00bc939 cleanup 2024-05-01 21:00:49 +02:00
dd91973f9b i2c adjust and pin downgrade 2024-05-01 18:06:20 +02:00
bfb19321fd stuff 2024-04-27 19:58:56 +02:00
1fc04a58a0 stuff 2024-04-26 18:52:53 +02:00
d8044b8e34 clippy adjustments 2024-04-25 20:26:58 +02:00
86c6bb5a73 fmt and mqtt workarounds 2024-04-22 13:04:25 +02:00
82bc9ed66d compiler adjustments for c6 2024-04-21 20:17:08 +02:00
a44aa86732 switch to esp32c6 2024-04-20 23:32:44 +02:00
e7e38e9fca add single pump test mode to config page 2024-04-06 21:14:56 +02:00
1f71b94238 changes 2024-03-27 21:10:37 +01:00
b4ad668620 fix palntstate not correctly calculated 2024-03-09 15:21:52 +01:00
869a581242 delay messages to reduce mqtt issues (sender to fast) improve mqtt debugging 2024-03-02 14:43:52 +01:00
e070c802d5 show build version in html 2024-03-02 14:01:48 +01:00
34066ee463 more stack slightly improved debugging 2024-03-02 13:21:12 +01:00
3110f25d80 Merge branch 'feature/12v' of https://git.mannheim.ccc.de/C3MA/PlantCtrl into feature/12v 2024-02-24 16:26:01 +01:00
5be6197f8c after pump fast restart cycle 2024-02-24 16:25:56 +01:00
27bde9cc87 fix tank calculation, update bq34 driver 2024-02-21 22:30:03 +01:00
3e31b4c041 Merge branch 'feature/12v' of ssh://git.mannheim.ccc.de:1337/C3MA/PlantCtrl into feature/12v 2024-02-21 20:00:40 +01:00
c6ef614221 doc erase-parts 2024-02-21 19:57:36 +01:00
bfee21796a fix rollback and windows build 2024-02-21 15:36:26 +01:00
57a0971c4b also print mode to mqtt 2024-02-17 18:43:36 +01:00
556e64740a allow build to run on windows as well 2024-02-17 18:40:11 +01:00
9d1a807805 allow to selectivly enable redundant sensors 2024-02-17 17:25:50 +01:00
680d1c3aaf fix rtc storage 2024-02-15 23:00:05 +01:00
060a1cc32d proceed with bq34z100 extraction 2024-02-02 21:35:04 +01:00
541f7e4471 Also ignore rust folder 2024-01-25 13:31:44 +01:00
7ea1486e2c made most battery code ready to work 2024-01-22 23:13:52 +01:00
b933516062 fix for bq34z100 led mode, added i2c header 2024-01-22 23:13:37 +01:00
b533739aa4 bq34z100 code improvements 2024-01-21 06:11:06 +01:00
12463c557b add i2c initial and pull configs 2024-01-17 21:25:01 +01:00
9473466feb set mppt output voltage to be less agressive 2024-01-10 19:49:57 +01:00
b5b5b25238 main pump handler 2024-01-09 00:16:13 +01:00
b9ec3247af clippy 2024-01-07 14:34:45 +01:00
a30dbe0759 go to stay alive 2024-01-07 14:33:02 +01:00
5724088780 remove boardaccess arc and replace with static lazy 2023-12-27 20:00:06 +01:00
4c02b99ea7 webserver improvements 2023-12-27 17:33:11 +01:00
1e40e2e3ba move to typescript, testmode, shiftregister revival 2023-12-23 01:59:00 +01:00
fd823217aa fix for reset of shift register 2023-12-23 01:56:07 +01:00
2541c83ebe more javascript shit 2023-12-22 17:26:00 +01:00
58801f870e initial config changes 2023-12-22 01:35:08 +01:00
066b3ec24f play with config page 2023-12-19 10:45:56 +01:00
303bdd131f fix reverse protection diodes 2023-12-19 10:45:22 +01:00
5d6871250e wifi config file handling added 2023-12-12 03:46:53 +01:00
e43538ec8a free size handling 2023-12-07 02:50:50 +01:00
fb0ad6b1dc file write test 2023-12-07 02:33:17 +01:00
f0f0e9f27e adjustments 2023-12-04 00:41:29 +01:00
4a8fffb3cc Merge branch 'feature/12v' of github.com:0110/PlantCtrl into feature/12v
# Conflicts:
#	rust/Cargo.toml
2023-11-30 19:26:03 +01:00
dd949a1be1 partition table 2023-11-29 18:28:09 +01:00
a9ab4ee99b fixes 2023-11-29 18:27:55 +01:00
8bfa27612d config start 2023-11-29 18:27:40 +01:00
55369e46a8 adjusted partitions 2023-11-29 18:27:23 +01:00
b2e5ccccee adjusted runner 2023-11-29 18:27:15 +01:00
031e8de99f use vergen 2023-11-27 01:07:07 +01:00
d35b814047 adjust compile stuff 2023-11-27 00:05:09 +01:00
0a0ac6babf added chrono-tz filter 2023-11-23 22:50:17 +01:00
b268466b89 adjustments 2023-11-21 23:45:15 +01:00
3c409ea339 proceeed further 2023-11-21 01:05:12 +01:00
825d389a8c design 2023-11-20 02:24:14 +01:00
17db1b8a45 adjust folder to be shorter 2023-11-20 01:46:19 +01:00
2092354bc9 ignore netlist 2023-11-20 00:14:29 +01:00
ae8ff86c1a rust init 2023-11-20 00:05:47 +01:00
ec67450a0a finalize layout for comparator 2023-11-01 22:44:32 +01:00
f72135a2b3 finalize 2023-10-26 23:08:03 +02:00
ba0fa2e732 added bettry manager 2023-10-26 07:49:56 +02:00
d3d6ad8ffb added batterymanagemt 2023-10-22 20:06:27 +02:00
ca74a716b7 updated layout 2023-10-22 01:20:17 +02:00
ba9fc2432b changes 2023-10-21 21:59:41 +02:00
fd08921bba layouted further 2023-10-16 01:10:03 +02:00
33082b7481 add charging circuit 2023-10-15 13:16:44 +02:00
8cc9b9d492 layouting continued 2023-10-11 00:01:17 +02:00
928dce949d Signed-off-by: Empire <empirephoenix@yahoo.de> 2023-10-10 20:20:48 +02:00
5f20ec17d0 12v layout tests 2023-09-27 00:55:39 +02:00
bdd9a17757 initial bus design 2023-09-26 01:20:07 +02:00
Empire
fbbbc5f5aa fix ota 2023-08-02 21:45:36 +02:00
Empire
5e16ca32e0 increase ota partition size for newer platform core 2023-08-02 21:44:54 +02:00
Empire
78193855a3 gpio 15 warnung 2023-08-02 21:44:17 +02:00
Empire
6d5f68fab5 Merge branch 'master' of github.com:0110/PlantCtrl 2023-07-20 20:11:58 +02:00
Ollo
9167da5a82 Refactoring 2023-06-20 18:06:29 +02:00
Ollo
f65132652c Optional features can be controlled via platformio.ini and are mentioned in firmware name on MQTT 2023-06-20 17:53:19 +02:00
Empire
703553beb4 Merge branch 'master' of github.com:0110/PlantCtrl 2023-06-15 21:44:00 +02:00
Ollo
2636e2defa Read more distances 2023-06-11 13:51:13 +02:00
Ollo
c6ddfea44b Handle unrealistic water values 2023-06-11 13:28:52 +02:00
Empire
85bcbd166c Fix remaining mqtt calculation 2023-06-04 19:21:53 +02:00
Ollo
6cb446735d Adapted default work time, as internal time is UTC 2023-05-28 10:53:43 +02:00
Ollo
ab17709435 More serial debuging (parsing 1WIRE Addresses failed) 2023-05-27 09:12:55 +02:00
Empire
e55b4abd49 added extension board 2023-05-18 11:06:12 +02:00
Empire
cf7ff9b0d1 added ota state debugging 2023-05-17 18:24:27 +02:00
Your Name
1cc46a360b fixed not watering when water is left 2023-04-26 08:33:12 +02:00
Ollo
9235e8a272 Changed to python3 2023-04-06 18:03:13 +02:00
Ollo
2a2a36b267 sleep at least several minutes, so the solar panel can charge the battery 2023-04-06 17:56:17 +02:00
Ollo
9f2e21d94c Sleep 3 times longer, if the battery voltage is low 2023-03-25 14:21:33 +01:00
Empire
a84344f978 Merge branch 'ollo-dev' 2023-03-24 19:55:14 +01:00
Ollo
5df69f20a8 Stop pumps due to water sensor 2023-03-24 18:40:57 +01:00
Ollo
704684d437 Fixed water distance and publish percentage 2023-03-24 18:06:21 +01:00
Ollo
90f2d821a7 Swapped water sensor pins 2023-03-22 22:04:49 +01:00
Empire
e8759435e7 frequency resistive sensor adjustment 2023-03-22 21:43:52 +01:00
Ollo
bd2e4d3da0 distance sensor is reset after powercycle 2023-03-22 21:06:14 +01:00
Ollo
9eb16637dc Reset as distance is > 8 meter 2023-03-22 21:01:24 +01:00
Ollo
66f61a69db Reset sensor on bad values 2023-03-22 20:50:25 +01:00
Ollo
939a5fe21a Print distance 2023-03-22 20:21:10 +01:00
Ollo
3a2ddb92e3 Set onewire bus 2023-03-22 20:06:35 +01:00
Ollo
1e79588e98 Merge branch 'ollo-dev' of github.com:0110/PlantCtrl into ollo-dev 2023-03-22 20:02:33 +01:00
Ollo
a0c657a418 VL53L0X test started 2023-03-22 20:02:23 +01:00
Ollo
ab480041b2 Removed timeout 2023-03-10 23:37:50 +01:00
Ollo
1fad63a84d Start I2C sensor after power was activated 2023-03-10 22:50:16 +01:00
Ollo
712ef73a30 Merged master into ollo-dev 2023-03-10 20:06:05 +01:00
Empire
63ed9afabc stuff changed 2023-03-03 19:58:55 +01:00
Empire
3835bd96a1 Revert "Revert "add resistive frequency sensor, updated dependencies""
This reverts commit 42ce4cdda2.
2023-02-12 12:51:52 +01:00
Empire
42ce4cdda2 Revert "add resistive frequency sensor, updated dependencies"
This reverts commit 17d16a6eef.
2023-02-12 12:40:38 +01:00
Empire
2b6d766492 fix water error code 2023-02-10 22:23:04 +01:00
Empire
68386ce02f Merge branch 'master' of github.com:0110/PlantCtrl 2023-02-10 22:12:57 +01:00
Empire
17d16a6eef add resistive frequency sensor, updated dependencies 2023-02-10 22:08:29 +01:00
Your Name
43e638a587 set more state retained 2022-12-20 00:07:25 +01:00
Your Name
0d15479268 remove leftover 2022-12-20 00:07:25 +01:00
Your Name
2914a0c7a1 slightly adjust range for better precision 2022-12-20 00:07:25 +01:00
37a08dede6 add frozen water mode 2022-12-20 00:04:57 +01:00
Ollo
195d3d3c1b Ignore voltages above 100V 2022-08-25 18:40:41 +02:00
Ollo
e820301490 Tweak state numbers 2022-08-23 20:26:11 +02:00
Ollo
29e3aa08cb Fixed unit description for cooldown 2022-08-22 18:08:19 +02:00
Ollo
791d6f04b0 Tweaked number 2022-08-21 12:12:07 +02:00
Ollo
79ffd8acff Version increased 2022-08-21 12:07:43 +02:00
Ollo
18b927bd59 Publish state as number and string 2022-08-21 12:05:43 +02:00
Ollo
c444117853 code refactoring: use the defined states of header file 2022-08-21 11:59:50 +02:00
Ollo
5d24a51bd9 Plant states defined in header 2022-08-21 11:52:15 +02:00
Ollo
71b9150279 Restore frequency boundaries (7a54065a5f) 2022-06-25 17:43:23 +02:00
Ollo
7eda866a91 Kept branch version of /esp32test/Esp32DeepSleepTest/src/main.cpp 2022-06-25 17:28:01 +02:00
Ollo
f18e4a7586 Show process in output (steps) 2022-06-25 17:20:11 +02:00
662d7bc853 add timer only mode, more sane default config 2022-05-20 01:00:04 +02:00
5dedc76727 formating only 2022-04-29 10:47:54 +02:00
15e96a4990 ensure compilation with bricking limits is not possible 2022-04-29 10:47:46 +02:00
0dd4553999 do not use pump for download indication anymore 2022-04-29 10:47:16 +02:00
7a841d423b use more sane default (pump always not only at night) 2022-04-29 10:45:59 +02:00
4a86d8c41c fixed analog probe being backwards, extended range for frequency one 2022-04-29 10:14:50 +02:00
Empire
c43da98245 Merge branch 'hydro'
# Conflicts:
#	esp32/PlantControl.code-workspace
#	esp32/include/ControllerConfiguration.h
#	esp32/platformio.ini
#	esp32/src/main.cpp
2022-04-27 19:19:26 +00:00
Ollo
f38cb6b564 Testsetup for frequency on GPIO17 2022-04-02 22:10:31 +02:00
Ollo
6c475a2ade Sensor types are defined in platformio.ini 2022-03-06 14:25:14 +01:00
Ollo
9a172c269e Swapped max and min for analog mapping 2022-03-06 14:05:54 +01:00
Ollo
868d3d912e Update the analog maximum according datasheet 2022-03-06 13:47:21 +01:00
Empire
defbcca8ae sht20 support 2022-03-05 09:31:43 +00:00
Empire
a9c4c32a22 Merge branch 'master' of github.com:0110/PlantCtrl 2022-02-19 17:47:00 +00:00
c3ma
1161c62a90 print into mqtt the sensor mode 2022-02-19 02:51:36 +01:00
c3ma
a0f8df7016 fix for capacitive sensors not working, enum introduction for sensormode 2022-02-19 02:24:19 +01:00
c3ma
d0320beaa7 allow sensor type selection per plant, changed calculations to use PCT values, due to different raw value meaning 2022-02-12 05:26:54 +01:00
Ollo
7a54065a5f Reduced frequrency boundery 2022-01-25 22:11:38 +01:00
Your Name
27cd6af02d cleanup power settings 2021-12-05 16:13:02 +01:00
Your Name
a745896643 added ulp-pwm logic for timedlight 2021-12-05 02:36:03 +01:00
Empire
80828eadd7 ulp tests 2021-12-04 16:04:18 +00:00
Empire
b9d8831dea Merge branch 'master' of github.com:0110/PlantCtrl
# Conflicts:
#	esp32/src/main.cpp
2021-12-03 18:42:37 +00:00
Empire
d69feb4143 basic pump ml calculation 2021-12-03 18:36:10 +00:00
Your Name
f131d9f39a hydro mode config and ignore low voltage light condition 2021-12-02 16:50:24 +01:00
Your Name
d7b854da75 allow disable light voltage range with -1 2021-12-02 14:40:06 +01:00
Ollo
16a722816c Use only Homie compliant datatypes: https://homieiot.github.io/specification/spec-core-v3_0_1/# 2021-11-29 17:25:08 +01:00
Ollo
9ff546b7b7 Remove Exception stuff 2021-11-28 16:02:08 +01:00
Empire
61fad8e14c Merge branch 'master' of https://github.com/0110/PlantCtrl 2021-11-19 18:58:26 +00:00
Empire
af618e73f3 pump refactor round 1 2021-11-19 18:48:14 +00:00
Ollo
c5bce25afe Added time into logs 2021-11-14 19:49:40 +01:00
Ollo
a457db4447 Fixed memory leak 2021-11-14 13:51:52 +01:00
c3ma
66d69eab6b Exceptions added 2021-11-13 17:26:39 +01:00
c3ma
f727971138 increased ota flash sizes 2021-10-27 22:04:44 +02:00
Your Name
d00517ec1e added epoxy form and sensor mod 2021-10-27 15:05:37 +02:00
Your Name
2ad351c41b remove selfTest causing sideeffects for pumploop trigger 2021-10-27 02:05:48 +02:00
Your Name
7d80d444cf use only seconds for time units, improve self test debug 2021-10-27 01:42:01 +02:00
Your Name
e70e467e9b properly set last run time, as it apparently was missing 2021-10-27 00:40:46 +02:00
Your Name
6a97215a04 fix for hydroponic not working at night 2021-10-27 00:40:26 +02:00
Your Name
2c8645121e added pump specific power level (requires controller that supports this or dc motor) 2021-10-26 21:50:55 +02:00
Your Name
dba39869d1 use shorter valid firmeware name 2021-10-26 21:12:00 +02:00
Your Name
9170a1fe05 some fixes for hydroponics mode 2021-10-26 20:46:40 +02:00
Empire
49664ba6f7 added initial support for hydroponic systems, changed cooldown to use minutes 2021-10-22 17:39:42 +00:00
Your Name
0bcef25528 Merge branch 'master' of https://github.com/0110/PlantCtrl 2021-10-22 15:53:58 +02:00
Your Name
f30a0a0c78 smooth battery sensor 2021-10-22 15:52:19 +02:00
Ollo
d819f7df4e Update documentation 2021-10-15 21:59:47 +02:00
c3ma
ecc03e9cb4 mqtt extraction 2021-10-06 22:00:17 +02:00
c3ma
2cd0a0f48b initial flowmeter logic and calculation 2021-10-06 21:24:34 +02:00
c3ma
b5569aa8ab Cleanup of last changes 2021-10-06 20:05:09 +02:00
Your Name
244dfb9b27 Merge branch 'master' of https://github.com/0110/PlantCtrl
# Conflicts:
#	esp32/src/main.cpp
2021-10-01 23:51:29 +02:00
Your Name
f4e13454e3 wip new pump system 2021-10-01 23:46:37 +02:00
Ollo
1619b93fa1 Updated ini.example 2021-10-01 23:00:24 +02:00
Ollo
58cb523e1b added determineTimeLightState in TIMED_LIGHT_PIN define 2021-10-01 22:53:40 +02:00
Ollo
e913ff462e Merge branch 'master' of github.com:0110/PlantCtrl 2021-10-01 21:40:41 +02:00
Your Name
f13a25b34d prevent light from being reenabled untill next day after low voltage trigger 2021-09-14 18:54:14 +02:00
Empire
88e4ceea8b fix for wrong validator 2021-08-30 08:02:12 +00:00
Your Name
f99f72b65a added timed light function 2021-08-29 20:45:50 +02:00
Your Name
e927fc8c70 add alarm if pumps did not change state to wet after X consecutive tries 2021-08-23 00:58:37 +02:00
Your Name
61098724b6 fixed wrong percent calculation, emit trigger value to mqtt 2021-08-17 16:55:57 +02:00
c3ma
2e052710e2 missing sensor error 2021-07-21 21:34:14 +02:00
c3ma
d043d873cc Reading sensors by frequency 2021-07-21 21:23:58 +02:00
Ollo
2d167c7393 adapted datatype 2021-07-14 21:43:03 +02:00
Ollo
f6c51f6d05 Updated example, more debug output in script 2021-07-14 21:33:47 +02:00
Ollo
02a882ebde Seperate setting itself into a local file 2021-07-14 21:21:49 +02:00
Ollo
697d470d29 Renamed file 2021-07-14 21:15:04 +02:00
Ollo
c448960415 Check values before publishing water stuff 2021-07-14 21:14:03 +02:00
c3ma
2d91f91290 react on switch from Mqtt 2021-07-09 22:51:50 +02:00
c3ma
df39c09c50 code cleanups 2021-07-09 21:50:51 +02:00
c3ma
99703e5ad1 Adjust moister sensor boundaries 2021-07-09 19:40:51 +02:00
Your Name
12d4c9950d fix cooldown memory without power, improved logging 2021-07-01 23:09:02 +02:00
Ollo
456f78042c Fixed concatination of strings in logging 2021-07-01 22:15:55 +02:00
Ollo
57d18af76d converted serial prints into MQTT status log messages 2021-07-01 22:06:50 +02:00
Your Name
f1d55ed603 extracte time stuff, started logger 2021-07-01 21:19:51 +02:00
Your Name
a1f2388c7f use mAlive instead of mqtt/homie varaibles 2021-07-01 20:50:47 +02:00
Your Name
d2010ddebb improved script reliability 2021-07-01 20:40:51 +02:00
Your Name
7c9a0bf6f1 clear averages for each run, ignore distances higher than tank depth 2021-07-01 20:39:51 +02:00
Your Name
11d29939f6 code stuff 2021-07-01 20:39:06 +02:00
Your Name
c32fd350c1 stuff 2021-06-29 23:50:41 +02:00
Your Name
a1de9ee2b9 config reduced, config json parser memory adjusted 2021-06-29 23:49:48 +02:00
Your Name
5568000d62 initial settings uploader added 2021-06-29 23:49:30 +02:00
Your Name
191e05b941 fixed config backup and restore 2021-06-29 22:09:30 +02:00
Your Name
c22c14a42b stop then script from sleeping the esp in case of an error 2021-06-29 20:14:36 +02:00
Your Name
54398b7bd6 adjust voltage divider to match 0.10 pcb layout 2021-06-29 20:14:19 +02:00
Your Name
0eeeb6dc60 set threshold for accumlator calculation 2021-06-29 20:14:03 +02:00
C3MA Werkstatt
e483b63400 Set 2k2 as pullup for I2C 2021-06-23 22:05:24 +02:00
Your Name
bc4d3ca271 0.10 rev final 2021-06-23 20:20:55 +02:00
Your Name
d08132c420 new extension header, improved labeling of connectors, optimized layout 2021-06-10 23:04:13 +02:00
Your Name
295673b6cb redesigned custom connector 2021-06-10 20:41:08 +02:00
Ollo
c400200e23 Merge branch 'master' of github.com:0110/PlantCtrl 2021-06-09 19:52:23 +02:00
Your Name
b5031124f4 Merge branch 'master' of https://github.com/0110/PlantCtrl
# Conflicts:
#	board/PlantCtrlESP32.kicad_pcb
2021-06-06 22:53:41 +02:00
3391dfb2c9 report raw distance for water sensor 2021-06-06 22:50:56 +02:00
c3ma
a8403a7c98 added distance sensor and adjusted pcb for it 2021-06-06 21:23:21 +02:00
c3ma
5fcf72602d fixed bootloader 2021-06-06 19:25:27 +02:00
c3ma
5980115298 added more correct pull down for download mode 2021-06-06 17:31:07 +02:00
e78f49b9da further reduced only once used parts 2021-06-04 12:52:11 +02:00
84690562b2 reduced odd resistors 2021-06-04 12:37:18 +02:00
7fcee1fb0d add high impendance pulldown to analog in 2021-06-04 12:31:00 +02:00
c3ma
2f21bd133e Signed-off-by: c3ma <c3ma@example.com> 2021-06-02 23:34:16 +02:00
Ollo
bb0eefa8bd Merge branch 'master' of github.com:0110/PlantCtrl 2021-06-02 22:20:26 +02:00
c3ma
89b982e59f Signed-off-by: c3ma <c3ma@example.com> 2021-06-02 22:20:05 +02:00
Ollo
8cbd96adda Merge branch 'master' of github.com:0110/PlantCtrl 2021-06-02 22:14:43 +02:00
c3ma
ac8e2bc4d4 use same pinout for moisture sensor as used on the sensor itself 2021-06-02 22:14:07 +02:00
Your Name
049246312e fixed labeling and spacing for sensors and pumps 2021-06-01 22:56:09 +02:00
Your Name
8c04bcbb7d fixed power on download mode, solar voltage sensor fixed 2021-06-01 22:44:31 +02:00
Your Name
dd58310fe9 make sensor address compare actually work 2021-05-29 22:07:47 +02:00
Your Name
ce1f75eae3 Merge branch 'master' of https://github.com/0110/PlantCtrl 2021-05-29 21:38:11 +02:00
Your Name
8e5a13d291 ensure DS18S20 are properly resolved via address 2021-05-29 21:37:27 +02:00
Your Name
200ff30f62 allow analog sensor some time to settle 2021-05-29 19:11:40 +02:00
c3ma
f275becb98 changed switches to cheaper alternative 2021-05-28 20:22:55 +02:00
Your Name
2c5d61a124 "improved" topic macro, added backup status and topic 2021-05-27 22:53:49 +02:00
Your Name
057e2b37c3 retry on crc error for onewire 2021-05-27 21:43:15 +02:00
Your Name
3d45a3fca3 config backup wip 2021-05-26 22:25:12 +02:00
Your Name
98799bd2d5 added testmode, fixed formating 2021-05-26 21:46:33 +02:00
Your Name
2c70ff1ed3 more capacitors, slight layout optimisation 2021-05-26 21:18:52 +02:00
Ollo
f0127921b1 Handle different start and end times to water plants 2021-05-26 20:19:27 +02:00
Your Name
cad836b070 fixed homie config fail mode 2021-05-24 20:35:41 +02:00
Your Name
72f8d36393 ignore bod while starting upstepper 2021-05-24 20:07:22 +02:00
Your Name
a90b59f69f use mqtt roundtrip to ensure all receiving messages are processed before ds 2021-05-24 19:37:27 +02:00
Your Name
50d07a3c02 fixed deepsleep procedure, homie shutdown, ensure pinhold is same as pin 2021-05-24 15:50:04 +02:00
Your Name
92005c1c33 control works again (fixed with wifi and fallback) 2021-05-24 14:58:35 +02:00
Ollo
5db0e2c82f Merged 2021-05-21 22:09:30 +02:00
Ollo
ad0ae88c3c More GPIO debug output added; checking GPIO15, too 2021-05-19 20:54:11 +02:00
c3ma
c7d98ef108 GPIO12 is evil 2021-05-16 22:24:14 +02:00
C3MA Werkstatt
3fffd41bcd Todos after building revision 2021-05-16 18:56:15 +02:00
C3MA Werkstatt
9af5a13e12 Nchannel is not Pchannel! 2021-05-16 18:18:11 +02:00
C3MA Werkstatt
758ae3ef57 Describe different buttons should be used 2021-05-16 17:49:12 +02:00
C3MA Werkstatt
04d7120adf Fix labels in pcb 2021-05-16 17:43:05 +02:00
Ollo
129b2b1478 Cleanup unused variables and code 2021-04-07 22:42:31 +02:00
Ollo
658bc7a389 Todos aufgerauemt 2021-04-07 22:21:58 +02:00
Ollo
0a1d755154 runtime optimization 2021-04-07 22:18:52 +02:00
Ollo
31229594fe One wire is initialized directly after start 2021-04-07 22:10:26 +02:00
Ollo
b8b8cf84d5 Reduce frequence of ESP32 to 80Mhz 2021-04-07 21:57:00 +02:00
Ollo
902c863873 Main logic introduced as seperate function. This is executed after MQTT is connected or a timeout occured 2021-04-07 21:54:53 +02:00
Ollo
47aba5387b Handle cooldown time for watering; add start and end time when pumping is allowed 2021-04-07 21:26:11 +02:00
Ollo
3932e82593 Address of tempsensors is published to MQTT 2021-04-07 20:27:42 +02:00
Ollo
dc5dc27ba5 Removed index to indentify temperatur sensors 2021-04-07 19:40:31 +02:00
Ollo
284fb4907d Renamed constants 2021-04-07 18:49:59 +02:00
Ollo
1eba578f20 Merge branch 'master' of github.com:0110/PlantCtrl 2020-11-11 22:16:30 +01:00
Ollo
060fa80efd read only once 2020-11-11 21:54:38 +01:00
113 changed files with 301601 additions and 21622 deletions

11
.gitignore vendored
View File

@@ -1 +1,12 @@
*.sch-bak
PlantCtrlESP32-backups/
board/production/PlantCtrlESP32_2023-11-08_00-45-35/PlantCtrlESP32.zip
board/production/PlantCtrlESP32_2023-11-08_00-45-35/netlist.ipc
.vscode
.embuild/
target
Cargo.lock
node_modules/
rust/src/webserver/bundle.js
rust/build/
rust/image.bin

View File

@@ -12,15 +12,15 @@ Open hardware design (powered by KiCAD).
The complete PCB is stored in the ***board*** sub directory.
There the following components are connected:
* ESP32 NodeMCU Module (the one of A-Z Delivery was used)
* Lipo
* ESP32 **16MB flash required**
* Lipo monitoring (DS2438)
* 7 moist sensors
* 7 pump
* DC-DC convert (generating voltage from Lipo for pumps)
* DS18B20 temperature sensors
* water tank ultrasonic sensor (via JSN-SR04T-2.0)
* water level via laser distance sensor (VL53L0X)
* DS2438 battery monitor
* general purpose expansion pin
* general purpose expansion pins
# Software
The firmware for the controller is stored in ***esp32*** sub directory.

46
board/4435.kicad_mod Normal file
View File

@@ -0,0 +1,46 @@
(footprint "4435" (version 20221018) (generator pcbnew)
(layer "F.Cu")
(attr smd)
(fp_text reference "REF**" (at -3.705 0 90) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 888d4749-ec8d-48e0-b622-265ef152540e)
)
(fp_text value "4435" (at 0 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 92782e22-8381-4ed1-a11f-ef69c9601af0)
)
(fp_line (start -2.705 -1.9) (end 2.705 -1.9)
(stroke (width 0.12) (type default)) (layer "F.SilkS") (tstamp 3128977c-e0a0-4ca7-8f5b-79eab6c86d44))
(fp_line (start -2.705 1.1) (end -2.705 -1.9)
(stroke (width 0.12) (type default)) (layer "F.SilkS") (tstamp b5339e6e-bef0-40f8-ac0d-5ffe68b262f3))
(fp_line (start -1.905 1.9) (end -2.705 1.1)
(stroke (width 0.12) (type default)) (layer "F.SilkS") (tstamp 267dcc87-49da-46db-86da-4ce81b7d2468))
(fp_line (start 2.705 -1.9) (end 2.705 1.9)
(stroke (width 0.12) (type default)) (layer "F.SilkS") (tstamp 14aaa409-1cdb-4bf6-a811-f0da4dffe73a))
(fp_line (start 2.705 1.9) (end -1.905 1.9)
(stroke (width 0.12) (type default)) (layer "F.SilkS") (tstamp 1789de97-d192-4375-b67e-3ad05848eee2))
(fp_line (start -2.46 -4.85) (end 2.46 -4.85)
(stroke (width 0.05) (type default)) (layer "F.CrtYd") (tstamp f4d6fc79-0700-4ee7-b411-e8f033ff66d3))
(fp_line (start -2.46 4.85) (end -2.46 -4.85)
(stroke (width 0.05) (type default)) (layer "F.CrtYd") (tstamp 3cfe9046-c22e-44b7-8f86-5e90bf2c83b0))
(fp_line (start 2.46 -4.85) (end 2.46 4.85)
(stroke (width 0.05) (type default)) (layer "F.CrtYd") (tstamp 41eb9d06-d36a-4d1d-a098-b2c48b580c65))
(fp_line (start 2.46 4.85) (end -2.46 4.85)
(stroke (width 0.05) (type default)) (layer "F.CrtYd") (tstamp 05ce4f60-8c60-4fe2-86da-df65172ffb03))
(pad "1" smd rect (at -1.905 -3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp 239f0d43-7a93-43bf-abef-be78a7aed604))
(pad "1" smd rect (at -0.635 -3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp a9c370b9-178b-48cd-94a4-ca368fb8484d))
(pad "1" smd rect (at 0.635 -3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp 8d506357-8b26-4d9b-b778-52fd40f96071))
(pad "1" smd rect (at 1.905 -3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp 4f4e03c6-0964-4327-a6cb-2e71085bfef0))
(pad "2" smd rect (at 1.905 3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp 3f6b4cbd-12fd-4380-92b9-d204178e6014))
(pad "3" smd rect (at -1.905 3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp bb893791-93a0-4766-9b0e-f175da5df5f4))
(pad "3" smd rect (at -0.635 3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp 8487832e-80f2-4019-9519-9da7cbe24a96))
(pad "3" smd rect (at 0.635 3.5) (size 0.6 2.2) (layers "F.Cu" "F.Paste" "F.Mask")
(thermal_bridge_angle 45) (tstamp 4ecffbef-d0f1-4d07-af9a-0fb6030dccea))
)

82
board/CN3306.kicad_sym Normal file
View File

@@ -0,0 +1,82 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "CN3306" (in_bom yes) (on_board yes)
(property "Reference" "U" (at 5.08 -5.08 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "CN3306_1_1"
(rectangle (start -2.54 7.62) (end 12.7 -16.51)
(stroke (width 0) (type default))
(fill (type background))
)
(pin input line (at 15.24 -8.89 180) (length 2.54)
(name "FB" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin input line (at 5.08 10.16 270) (length 2.54)
(name "COME" (effects (font (size 1.27 1.27))))
(number "10" (effects (font (size 1.27 1.27))))
)
(pin input line (at 15.24 -13.97 180) (length 2.54)
(name "VCC" (effects (font (size 1.27 1.27))))
(number "11" (effects (font (size 1.27 1.27))))
)
(pin input line (at 15.24 -11.43 180) (length 2.54)
(name "VCC" (effects (font (size 1.27 1.27))))
(number "12" (effects (font (size 1.27 1.27))))
)
(pin input line (at 15.24 5.08 180) (length 2.54)
(name "DRV" (effects (font (size 1.27 1.27))))
(number "13" (effects (font (size 1.27 1.27))))
)
(pin input line (at 3.81 -19.05 90) (length 2.54)
(name "GND" (effects (font (size 1.27 1.27))))
(number "14" (effects (font (size 1.27 1.27))))
)
(pin input line (at 6.35 -19.05 90) (length 2.54)
(name "GND" (effects (font (size 1.27 1.27))))
(number "15" (effects (font (size 1.27 1.27))))
)
(pin input line (at 15.24 2.54 180) (length 2.54)
(name "ISW" (effects (font (size 1.27 1.27))))
(number "16" (effects (font (size 1.27 1.27))))
)
(pin input line (at -5.08 -10.16 0) (length 2.54)
(name "COMP" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin input line (at -5.08 -1.27 0) (length 2.54)
(name "MPPT" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin input line (at -5.08 -7.62 0) (length 2.54)
(name "SHDN" (effects (font (size 1.27 1.27))))
(number "5" (effects (font (size 1.27 1.27))))
)
(pin input line (at -5.08 3.81 0) (length 2.54)
(name "CHRG" (effects (font (size 1.27 1.27))))
(number "6" (effects (font (size 1.27 1.27))))
)
(pin input line (at -5.08 1.27 0) (length 2.54)
(name "DONE" (effects (font (size 1.27 1.27))))
(number "7" (effects (font (size 1.27 1.27))))
)
(pin input line (at 15.24 -3.81 180) (length 2.54)
(name "CSP" (effects (font (size 1.27 1.27))))
(number "8" (effects (font (size 1.27 1.27))))
)
(pin input line (at 15.24 -6.35 180) (length 2.54)
(name "ONE" (effects (font (size 1.27 1.27))))
(number "9" (effects (font (size 1.27 1.27))))
)
)
)
)

123
board/CN3795.kicad_sym Normal file
View File

@@ -0,0 +1,123 @@
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
(symbol "CN3795" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (id 0) (at 5.08 18.542 0)
(effects (font (size 1.27 1.27)) (justify bottom left))
)
(property "Value" "CN3795" (id 1) (at 5.08 -20.32 0)
(effects (font (size 1.27 1.27)) (justify bottom left))
)
(property "Footprint" "CN3795:SSOP10" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MF" "Consonance" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Description" "\n4A, Multi-Chemistry Battery Charger\nWith Photovoltaic Cell MPPT Function\n" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Package" "Package" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Price" "None" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "SnapEDA_Link" "https://www.snapeda.com/parts/CN3795/Consonance/view-part/?ref=snap" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MP" "CN3795" (id 9) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Availability" "Not in stock" (id 10) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Check_prices" "https://www.snapeda.com/parts/CN3795/Consonance/view-part/?ref=eda" (id 11) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(symbol "CN3795_0_0"
(rectangle (start -12.7 -17.78) (end 12.7 17.78)
(stroke (width 0.254)) (fill (type background))
)
(pin bidirectional line (at -15.24 7.62 0) (length 2.54)
(name "VCC"
(effects (font (size 1.016 1.016)))
)
(number "9"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -15.24 -2.54 0) (length 2.54)
(name "~{CHRG}"
(effects (font (size 1.016 1.016)))
)
(number "3"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -15.24 -7.62 0) (length 2.54)
(name "MPPT"
(effects (font (size 1.016 1.016)))
)
(number "4"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -2.54 20.32 270.0) (length 2.54)
(name "VG"
(effects (font (size 1.016 1.016)))
)
(number "1"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 2.54 20.32 270.0) (length 2.54)
(name "DRV"
(effects (font (size 1.016 1.016)))
)
(number "10"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 15.24 7.62 180.0) (length 2.54)
(name "CSP"
(effects (font (size 1.016 1.016)))
)
(number "8"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 15.24 2.54 180.0) (length 2.54)
(name "BAT"
(effects (font (size 1.016 1.016)))
)
(number "7"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 15.24 -2.54 180.0) (length 2.54)
(name "FB"
(effects (font (size 1.016 1.016)))
)
(number "6"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 15.24 -7.62 180.0) (length 2.54)
(name "COM"
(effects (font (size 1.016 1.016)))
)
(number "5"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 0.0 -20.32 90.0) (length 2.54)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "2"
(effects (font (size 1.016 1.016)))
)
)
)
)
)

View File

@@ -0,0 +1,3 @@
EESchema-DOCLIB Version 2.0
#
#End Doc Library

11
board/PlantCtrlESP32.erc Normal file
View File

@@ -0,0 +1,11 @@
ERC report (Thu 10 Jun 2021 11:02:23 PM CEST, Encoding UTF8 )
***** Sheet /
ErrType(3): Pin connected to other pins, but not driven by any pin
@(476.25 mm, 236.22 mm): Pin 3 (Power input) of component U6 is not driven (Net 13).
ErrType(3): Pin connected to other pins, but not driven by any pin
@(71.12 mm, 154.94 mm): Pin 4 (Power input) of component U3 is not driven (Net 25).
ErrType(3): Pin connected to other pins, but not driven by any pin
@(558.80 mm, 274.32 mm): Pin 5 (Power input) of component U2 is not driven (Net 28).
** ERC messages: 3 Errors 0 Warnings 3

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

56377
board/PlantCtrlESP32.kicad_sch Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,286 +0,0 @@
update=Fri 27 Nov 2020 08:17:47 PM CET
version=1
last_client=kicad
[general]
version=1
RootSch=
BoardNm=
[cvpcb]
version=1
NetIExt=net
[eeschema]
version=1
LibDir=
[eeschema/libraries]
[schematic_editor]
version=1
PageLayoutDescrFile=
PlotDirectoryName=/tmp/
SubpartIdSeparator=0
SubpartFirstId=65
NetFmtName=Pcbnew
SpiceAjustPassiveValues=0
LabSize=50
ERC_TestSimilarLabels=1
[pcbnew]
version=1
PageLayoutDescrFile=
LastNetListRead=PlantCtrlESP32.net
CopperLayerCount=2
BoardThickness=1.6
AllowMicroVias=0
AllowBlindVias=0
RequireCourtyardDefinitions=0
ProhibitOverlappingCourtyards=1
MinTrackWidth=0.2
MinViaDiameter=0.4
MinViaDrill=0.3
MinMicroViaDiameter=0.2
MinMicroViaDrill=0.09999999999999999
MinHoleToHole=0.25
TrackWidth1=1.2
TrackWidth2=0.2
TrackWidth3=0.5
TrackWidth4=1
ViaDiameter1=0.8
ViaDrill1=0.4
ViaDiameter2=4
ViaDrill2=3
dPairWidth1=0.2
dPairGap1=0.25
dPairViaGap1=0.25
SilkLineWidth=0.12
SilkTextSizeV=1
SilkTextSizeH=1
SilkTextSizeThickness=0.15
SilkTextItalic=0
SilkTextUpright=1
CopperLineWidth=0.2
CopperTextSizeV=1.5
CopperTextSizeH=1.5
CopperTextThickness=0.3
CopperTextItalic=0
CopperTextUpright=1
EdgeCutLineWidth=0.05
CourtyardLineWidth=0.05
OthersLineWidth=0.15
OthersTextSizeV=1
OthersTextSizeH=1
OthersTextSizeThickness=0.15
OthersTextItalic=0
OthersTextUpright=1
SolderMaskClearance=0.051
SolderMaskMinWidth=0.25
SolderPasteClearance=0
SolderPasteRatio=-0
[pcbnew/Layer.F.Cu]
Name=F.Cu
Type=0
Enabled=1
[pcbnew/Layer.In1.Cu]
Name=In1.Cu
Type=0
Enabled=0
[pcbnew/Layer.In2.Cu]
Name=In2.Cu
Type=0
Enabled=0
[pcbnew/Layer.In3.Cu]
Name=In3.Cu
Type=0
Enabled=0
[pcbnew/Layer.In4.Cu]
Name=In4.Cu
Type=0
Enabled=0
[pcbnew/Layer.In5.Cu]
Name=In5.Cu
Type=0
Enabled=0
[pcbnew/Layer.In6.Cu]
Name=In6.Cu
Type=0
Enabled=0
[pcbnew/Layer.In7.Cu]
Name=In7.Cu
Type=0
Enabled=0
[pcbnew/Layer.In8.Cu]
Name=In8.Cu
Type=0
Enabled=0
[pcbnew/Layer.In9.Cu]
Name=In9.Cu
Type=0
Enabled=0
[pcbnew/Layer.In10.Cu]
Name=In10.Cu
Type=0
Enabled=0
[pcbnew/Layer.In11.Cu]
Name=In11.Cu
Type=0
Enabled=0
[pcbnew/Layer.In12.Cu]
Name=In12.Cu
Type=0
Enabled=0
[pcbnew/Layer.In13.Cu]
Name=In13.Cu
Type=0
Enabled=0
[pcbnew/Layer.In14.Cu]
Name=In14.Cu
Type=0
Enabled=0
[pcbnew/Layer.In15.Cu]
Name=In15.Cu
Type=0
Enabled=0
[pcbnew/Layer.In16.Cu]
Name=In16.Cu
Type=0
Enabled=0
[pcbnew/Layer.In17.Cu]
Name=In17.Cu
Type=0
Enabled=0
[pcbnew/Layer.In18.Cu]
Name=In18.Cu
Type=0
Enabled=0
[pcbnew/Layer.In19.Cu]
Name=In19.Cu
Type=0
Enabled=0
[pcbnew/Layer.In20.Cu]
Name=In20.Cu
Type=0
Enabled=0
[pcbnew/Layer.In21.Cu]
Name=In21.Cu
Type=0
Enabled=0
[pcbnew/Layer.In22.Cu]
Name=In22.Cu
Type=0
Enabled=0
[pcbnew/Layer.In23.Cu]
Name=In23.Cu
Type=0
Enabled=0
[pcbnew/Layer.In24.Cu]
Name=In24.Cu
Type=0
Enabled=0
[pcbnew/Layer.In25.Cu]
Name=In25.Cu
Type=0
Enabled=0
[pcbnew/Layer.In26.Cu]
Name=In26.Cu
Type=0
Enabled=0
[pcbnew/Layer.In27.Cu]
Name=In27.Cu
Type=0
Enabled=0
[pcbnew/Layer.In28.Cu]
Name=In28.Cu
Type=0
Enabled=0
[pcbnew/Layer.In29.Cu]
Name=In29.Cu
Type=0
Enabled=0
[pcbnew/Layer.In30.Cu]
Name=In30.Cu
Type=0
Enabled=0
[pcbnew/Layer.B.Cu]
Name=B.Cu
Type=0
Enabled=1
[pcbnew/Layer.B.Adhes]
Enabled=1
[pcbnew/Layer.F.Adhes]
Enabled=1
[pcbnew/Layer.B.Paste]
Enabled=1
[pcbnew/Layer.F.Paste]
Enabled=1
[pcbnew/Layer.B.SilkS]
Enabled=1
[pcbnew/Layer.F.SilkS]
Enabled=1
[pcbnew/Layer.B.Mask]
Enabled=1
[pcbnew/Layer.F.Mask]
Enabled=1
[pcbnew/Layer.Dwgs.User]
Enabled=1
[pcbnew/Layer.Cmts.User]
Enabled=1
[pcbnew/Layer.Eco1.User]
Enabled=1
[pcbnew/Layer.Eco2.User]
Enabled=1
[pcbnew/Layer.Edge.Cuts]
Enabled=1
[pcbnew/Layer.Margin]
Enabled=1
[pcbnew/Layer.B.CrtYd]
Enabled=1
[pcbnew/Layer.F.CrtYd]
Enabled=1
[pcbnew/Layer.B.Fab]
Enabled=1
[pcbnew/Layer.F.Fab]
Enabled=1
[pcbnew/Layer.Rescue]
Enabled=0
[pcbnew/Netclasses]
[pcbnew/Netclasses/Default]
Name=Default
Clearance=0.2
TrackWidth=1.2
ViaDiameter=0.8
ViaDrill=0.4
uViaDiameter=0.3
uViaDrill=0.1
dPairWidth=0.2
dPairGap=0.25
dPairViaGap=0.25
[pcbnew/Netclasses/1]
Name=5V
Clearance=0.2
TrackWidth=1.4
ViaDiameter=0.8
ViaDrill=0.4
uViaDiameter=0.3
uViaDrill=0.1
dPairWidth=0.2
dPairGap=0.25
dPairViaGap=0.25
[pcbnew/Netclasses/2]
Name=Mini
Clearance=0.2
TrackWidth=1
ViaDiameter=0.8
ViaDrill=0.4
uViaDiameter=0.3
uViaDrill=0.1
dPairWidth=0.2
dPairGap=0.25
dPairViaGap=0.25
[pcbnew/Netclasses/3]
Name=Power
Clearance=0.2
TrackWidth=1.7
ViaDiameter=0.8
ViaDrill=0.4
uViaDiameter=0.3
uViaDrill=0.1
dPairWidth=0.2
dPairGap=0.25
dPairViaGap=0.25

View File

@@ -0,0 +1,7 @@
Default False 2.0 3
12V True 2.0 3
3V True 2.0 3
BAT+ True 2.0 3
BAT- True 2.0 3
GND True 2.0 3
False True False

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
(footprint "R_Shunt_Vishay_WSK2512_6332Metric_T1.19mm" (version 20221018) (generator pcbnew)
(layer "F.Cu")
(descr "Shunt Resistor SMD 2512 (6332 Metric), 2.6mm thick, Vishay WKS2512, Terminal length (T) 1.19mm, 5 to 200 milli Ohm (http://http://www.vishay.com/docs/30108/wsk.pdf)")
(tags "resistor shunt WSK2512")
(attr smd)
(fp_text reference "REF**" (at 0 -2.65) (layer "F.SilkS")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp e64357ee-67ea-437d-842c-edd4e9b0e817)
)
(fp_text value "R_Shunt_Vishay_WSK2512_6332Metric_T1.19mm" (at 0 2.65) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 6d43eee8-d677-4710-a5b6-ed0a393d7e86)
)
(fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab")
(effects (font (size 1 1) (thickness 0.15)))
(tstamp 7af73258-6848-4c90-ada6-9916b21e0d54)
)
(fp_line (start -2.5 1.7) (end 1.67 1.7)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 686b0a9f-f303-4b9c-97bc-13b268071b2a))
(fp_line (start -1.67 -1.7) (end 2.53 -1.7)
(stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 8ff3cd0c-2e69-49a7-948e-62e2af1cdeaf))
(fp_line (start -4.38 -1.9) (end 4.38 -1.9)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 97453d6f-90a6-4d0b-9533-4b9de0e70d67))
(fp_line (start -4.38 1.9) (end -4.38 -1.9)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8d751a64-d963-4d3e-b652-c6367d221a4c))
(fp_line (start 4.38 -1.9) (end 4.38 1.9)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 5fc8cbbe-390d-45f2-b9e2-001b3b36ad53))
(fp_line (start 4.38 1.9) (end -4.38 1.9)
(stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 85ea9322-734e-4f57-b7f4-e08d8559c109))
(fp_line (start -3.175 -1.59) (end 3.175 -1.59)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp a616017c-8c30-4c24-8988-6ebc65a5a14c))
(fp_line (start -3.175 0.32) (end -3.175 -1.59)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 007035a4-df14-4627-b9dd-16c0816e9fc4))
(fp_line (start -3.175 0.32) (end -2.795 0.32)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7a92ebc4-86fb-494b-8925-1512bf4598dd))
(fp_line (start -3.175 0.94) (end -3.175 1.59)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 8d1ed9db-8b9e-4c9a-b026-a147d8ba5a89))
(fp_line (start -3.175 0.94) (end -2.795 0.94)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3238b0a3-1bbc-4ecd-9eca-d39a4563f46a))
(fp_line (start -2.795 0.94) (end -2.795 0.32)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 56e7214e-7e65-4896-9919-6dfa6ad242a1))
(fp_line (start 2.79 -0.94) (end 3.17 -0.94)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bf2fd8b5-dc07-4d36-93f4-c05d760e4ae8))
(fp_line (start 2.79 -0.32) (end 2.79 -0.94)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2732ea3b-0a68-4014-9f1f-147b192cb827))
(fp_line (start 2.79 -0.32) (end 3.17 -0.32)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7597632e-0fab-4537-9ef5-3d955ee8fe04))
(fp_line (start 3.175 -0.94) (end 3.175 -1.59)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp be78e59b-9296-4843-849b-9aeaddf3ec90))
(fp_line (start 3.175 -0.32) (end 3.175 1.59)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f0529fdf-6a96-4afa-ae66-3987676f8cc1))
(fp_line (start 3.175 1.59) (end -3.175 1.59)
(stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 5494f1f1-9934-4901-ae11-4f45356840a6))
(pad "1" smd roundrect (at -2.985 0.635) (size 2.29 2.03) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.12) (tstamp 7d665233-6376-4fd3-9d23-184556b0630c))
(pad "2" smd roundrect (at -3.43 -1.27) (size 1.4 0.76) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.12) (tstamp a060266a-0c38-4364-b2df-6f7cf4c69f0d))
(pad "3" smd roundrect (at 3.43 -1.27) (size 1.4 0.76) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp a1e31646-49e8-4836-bd67-1b6bed652414))
(pad "4" smd roundrect (at 2.985 0.635) (size 2.29 2.03) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.12) (tstamp 3f532dd2-fd5a-4fe7-9636-aa84f769e3b2))
(model "${KICAD6_3DMODEL_DIR}/Resistor_SMD.3dshapes/R_Shunt_Vishay_WSK2512_6332Metric_T1.19mm.wrl"
(offset (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

4562
board/bom/ibom.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,354 @@
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
(symbol "ESP32-C6-WROOM-1-N8" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (id 0) (at -15.24 23.622 0)
(effects (font (size 1.27 1.27)) (justify bottom left))
)
(property "Value" "ESP32-C6-WROOM-1-N8" (id 1) (at -15.24 -25.4 0)
(effects (font (size 1.27 1.27)) (justify bottom left))
)
(property "Footprint" "ESP32-C6-WROOM-1-N8:XCVR_ESP32-C6-WROOM-1-N8" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MF" "Espressif Systems" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MAXIMUM_PACKAGE_HEIGHT" "3.25mm" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Package" "None" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Price" "None" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Check_prices" "https://www.snapeda.com/parts/ESP32-C6-WROOM-1-N8/Espressif+Systems/view-part/?ref=eda" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "STANDARD" "Manufacturer Recommendations" (id 9) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "PARTREV" "1.0" (id 10) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "SnapEDA_Link" "https://www.snapeda.com/parts/ESP32-C6-WROOM-1-N8/Espressif+Systems/view-part/?ref=snap" (id 11) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MP" "ESP32-C6-WROOM-1-N8" (id 12) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Purchase-URL" "https://www.snapeda.com/api/url_track_click_mouser/?unipart_id=12616380&manufacturer=Espressif Systems&part_name=ESP32-C6-WROOM-1-N8&search_term=None" (id 13) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Description" "\nMultiprotocol Modules ESP32-C6 module, Wi-Fi 6 in 2.4 GHz band, Bluetooth 5, Zigbee 3.0 and Thread. ESP34-WROOM Compatible - ENGINEERING SAMPLE\n" (id 14) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Availability" "In Stock" (id 15) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MANUFACTURER" "Espressif Systems" (id 16) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(symbol "ESP32-C6-WROOM-1-N8_0_0"
(rectangle (start -15.24 -22.86) (end 15.24 22.86)
(stroke (width 0.254)) (fill (type background))
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "1"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "28"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_1"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_2"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_3"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_4"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_5"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_6"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_7"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_8"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 -20.32 180.0) (length 5.08)
(name "GND"
(effects (font (size 1.016 1.016)))
)
(number "29_9"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 20.32 20.32 180.0) (length 5.08)
(name "3V3"
(effects (font (size 1.016 1.016)))
)
(number "2"
(effects (font (size 1.016 1.016)))
)
)
(pin input line (at -20.32 15.24 0) (length 5.08)
(name "EN"
(effects (font (size 1.016 1.016)))
)
(number "3"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 0.0 0) (length 5.08)
(name "IO4"
(effects (font (size 1.016 1.016)))
)
(number "4"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 -2.54 0) (length 5.08)
(name "IO5"
(effects (font (size 1.016 1.016)))
)
(number "5"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 -5.08 0) (length 5.08)
(name "IO6"
(effects (font (size 1.016 1.016)))
)
(number "6"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 -7.62 0) (length 5.08)
(name "IO7"
(effects (font (size 1.016 1.016)))
)
(number "7"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 10.16 0) (length 5.08)
(name "IO0"
(effects (font (size 1.016 1.016)))
)
(number "8"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 7.62 0) (length 5.08)
(name "IO1"
(effects (font (size 1.016 1.016)))
)
(number "9"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 -10.16 0) (length 5.08)
(name "IO8"
(effects (font (size 1.016 1.016)))
)
(number "10"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 15.24 180.0) (length 5.08)
(name "IO10"
(effects (font (size 1.016 1.016)))
)
(number "11"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 12.7 180.0) (length 5.08)
(name "IO11"
(effects (font (size 1.016 1.016)))
)
(number "12"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 10.16 180.0) (length 5.08)
(name "IO12"
(effects (font (size 1.016 1.016)))
)
(number "13"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 7.62 180.0) (length 5.08)
(name "IO13"
(effects (font (size 1.016 1.016)))
)
(number "14"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 5.08 0) (length 5.08)
(name "IO2"
(effects (font (size 1.016 1.016)))
)
(number "27"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 2.54 0) (length 5.08)
(name "IO3"
(effects (font (size 1.016 1.016)))
)
(number "26"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 2.54 180.0) (length 5.08)
(name "TXD0/GPIO16"
(effects (font (size 1.016 1.016)))
)
(number "25"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 0.0 180.0) (length 5.08)
(name "RXD0/GPIO17"
(effects (font (size 1.016 1.016)))
)
(number "24"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 5.08 180.0) (length 5.08)
(name "IO15"
(effects (font (size 1.016 1.016)))
)
(number "23"
(effects (font (size 1.016 1.016)))
)
)
(pin no_connect line (at -20.32 -17.78 0) (length 5.08)
(name "NC"
(effects (font (size 1.016 1.016)))
)
(number "22"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 -15.24 180.0) (length 5.08)
(name "IO23"
(effects (font (size 1.016 1.016)))
)
(number "21"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 -12.7 180.0) (length 5.08)
(name "IO22"
(effects (font (size 1.016 1.016)))
)
(number "20"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 -10.16 180.0) (length 5.08)
(name "IO21"
(effects (font (size 1.016 1.016)))
)
(number "19"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 -7.62 180.0) (length 5.08)
(name "IO20"
(effects (font (size 1.016 1.016)))
)
(number "18"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 -5.08 180.0) (length 5.08)
(name "IO19"
(effects (font (size 1.016 1.016)))
)
(number "17"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 20.32 -2.54 180.0) (length 5.08)
(name "IO18"
(effects (font (size 1.016 1.016)))
)
(number "16"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -20.32 -12.7 0) (length 5.08)
(name "IO9"
(effects (font (size 1.016 1.016)))
)
(number "15"
(effects (font (size 1.016 1.016)))
)
)
)
)
)

View File

@@ -0,0 +1,104 @@
(footprint XCVR_ESP32-C6-WROOM-1-N8 (layer F.Cu) (tedit 66216AE3)
(descr "")
(attr smd)
(fp_text reference REF** (at -5.825 -13.885 0) (layer F.SilkS)
(effects (font (size 1.0 1.0) (thickness 0.15)))
)
(fp_text value XCVR_ESP32-C6-WROOM-1-N8 (at 6.24 13.865 0) (layer F.Fab)
(effects (font (size 1.0 1.0) (thickness 0.15)))
)
(pad 1 smd rect (at -8.75 -5.26) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 2 smd rect (at -8.75 -3.99) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 3 smd rect (at -8.75 -2.72) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 4 smd rect (at -8.75 -1.45) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 5 smd rect (at -8.75 -0.18) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 6 smd rect (at -8.75 1.09) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 7 smd rect (at -8.75 2.36) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 8 smd rect (at -8.75 3.63) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 9 smd rect (at -8.75 4.9) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 10 smd rect (at -8.75 6.17) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 11 smd rect (at -8.75 7.44) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 12 smd rect (at -8.75 8.71) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 13 smd rect (at -8.75 9.98) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 14 smd rect (at -8.75 11.25) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 15 smd rect (at 8.75 11.25) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 16 smd rect (at 8.75 9.98) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 17 smd rect (at 8.75 8.71) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 18 smd rect (at 8.75 7.44) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 19 smd rect (at 8.75 6.17) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 20 smd rect (at 8.75 4.9) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 21 smd rect (at 8.75 3.63) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 22 smd rect (at 8.75 2.36) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 23 smd rect (at 8.75 1.09) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 24 smd rect (at 8.75 -0.18) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 25 smd rect (at 8.75 -1.45) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 26 smd rect (at 8.75 -2.72) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 27 smd rect (at 8.75 -3.99) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 28 smd rect (at 8.75 -5.26) (size 1.5 0.9) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_5 smd rect (at -1.505 0.46) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_1 smd rect (at -2.755 -0.79) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_2 smd rect (at -1.505 -0.79) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_3 smd rect (at -0.255 -0.79) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_4 smd rect (at -2.755 0.46) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_6 smd rect (at -0.255 0.46) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_7 smd rect (at -2.755 1.71) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_8 smd rect (at -1.505 1.71) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 29_9 smd rect (at -0.255 1.71) (size 0.8 0.8) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 30_1 thru_hole circle (at -2.13 -0.79) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_2 thru_hole circle (at -0.88 -0.79) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_3 thru_hole circle (at -2.755 -0.165) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_4 thru_hole circle (at -1.505 -0.165) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_5 thru_hole circle (at -0.255 -0.165) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_6 thru_hole circle (at -2.13 0.46) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_7 thru_hole circle (at -0.88 0.46) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_8 thru_hole circle (at -2.755 1.085) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_9 thru_hole circle (at -1.505 1.085) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_10 thru_hole circle (at -0.255 1.085) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_11 thru_hole circle (at -2.13 1.71) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(pad 30_12 thru_hole circle (at -0.88 1.71) (size 0.35 0.35) (drill 0.25) (layers *.Cu))
(fp_line (start -9.0 12.75) (end 9.0 12.75) (layer F.Fab) (width 0.127))
(fp_line (start -9.0 -12.75) (end 9.0 -12.75) (layer F.Fab) (width 0.127))
(fp_line (start 9.0 -12.75) (end 9.0 12.75) (layer F.Fab) (width 0.127))
(fp_line (start -9.0 12.75) (end 9.0 12.75) (layer F.SilkS) (width 0.127))
(fp_line (start -9.0 12.75) (end -9.0 12.02) (layer F.SilkS) (width 0.127))
(fp_line (start 9.0 12.02) (end 9.0 12.75) (layer F.SilkS) (width 0.127))
(fp_line (start -9.0 -6.03) (end -9.0 -12.75) (layer F.SilkS) (width 0.127))
(fp_line (start -9.0 -12.75) (end 9.0 -12.75) (layer F.SilkS) (width 0.127))
(fp_line (start 9.0 -12.75) (end 9.0 -6.03) (layer F.SilkS) (width 0.127))
(zone (net 0) (net_name "") (layers *.Cu) (hatch full 0.508)
(connect_pads (clearance 0))
(min_thickness 0.01)
(keepout (tracks allowed) (vias not_allowed) (pads allowed ) (copperpour allowed) (footprints allowed))
(fill (thermal_gap 0.508) (thermal_bridge_width 0.508))
(polygon
(pts
(xy -9.0 -12.75)
(xy 9.0 -12.75)
(xy 9.0 -6.75)
(xy -9.0 -6.75)
)
)
)
(zone (net 0) (net_name "") (layer F.Cu) (hatch full 0.508)
(connect_pads (clearance 0))
(min_thickness 0.01)
(keepout (tracks not_allowed) (vias not_allowed) (pads not_allowed ) (copperpour not_allowed) (footprints allowed))
(fill (thermal_gap 0.508) (thermal_bridge_width 0.508))
(polygon
(pts
(xy -9.0 -12.75)
(xy 9.0 -12.75)
(xy 9.0 -6.75)
(xy -9.0 -6.75)
)
)
)
(fp_line (start -9.75 -13.0) (end -9.75 13.0) (layer F.CrtYd) (width 0.05))
(fp_line (start -9.75 13.0) (end 9.75 13.0) (layer F.CrtYd) (width 0.05))
(fp_line (start 9.75 13.0) (end 9.75 -13.0) (layer F.CrtYd) (width 0.05))
(fp_line (start 9.75 -13.0) (end -9.75 -13.0) (layer F.CrtYd) (width 0.05))
(fp_line (start -9.0 12.75) (end -9.0 -12.75) (layer F.Fab) (width 0.127))
(fp_circle (center -10.0 -5.25) (end -9.9 -5.25) (layer F.SilkS) (width 0.2))
(fp_circle (center -10.0 -5.25) (end -9.9 -5.25) (layer F.Fab) (width 0.2))
)

View File

@@ -0,0 +1 @@
{"EXTRA_LAYERS": "", "EXTEND_EDGE_CUT": false, "AUTO TRANSLATE": true, "AUTO FILL": true, "EXCLUDE DNP": true}

View File

@@ -1,4 +1,8 @@
(fp_lib_table
(lib (name misc_footprints)(type KiCad)(uri ${KIPRJMOD}/kicad-stuff/misc_footprints-master/misc_footprints.pretty)(options "")(descr ""))
(lib (name ESP32)(type KiCad)(uri ${KIPRJMOD}/kicad-stuff/ESP32)(options "")(descr ""))
(version 7)
(lib (name "misc_footprints")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/misc_footprints-master/misc_footprints.pretty")(options "")(descr ""))
(lib (name "ESP32")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/ESP32")(options "")(descr ""))
(lib (name "kicad-stuff")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff")(options "")(descr ""))
(lib (name "board")(type "KiCad")(uri "${KIPRJMOD}/")(options "")(descr ""))
(lib (name "esp32c6")(type "KiCad")(uri "${KIPRJMOD}/esp32c6")(options "")(descr ""))
)

View File

@@ -0,0 +1,158 @@
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
(symbol "BQ34Z100PWR-G1" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (id 0) (at -12.7 26.4 0.0)
(effects (font (size 1.27 1.27)) (justify bottom left))
)
(property "Value" "BQ34Z100PWR-G1" (id 1) (at -12.7 -29.4 0.0)
(effects (font (size 1.27 1.27)) (justify bottom left))
)
(property "Footprint" "BQ34Z100PWR-G1:SOP65P640X120-14N" (id 2) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MF" "Texas Instruments" (id 4) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Description" "\nMulti-chemistry Impedance Track™ standalone fuel gauge | battery gas gauge\n" (id 5) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Package" "TSSOP-14 Texas Instruments" (id 6) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Price" "None" (id 7) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "SnapEDA_Link" "https://www.snapeda.com/parts/BQ34Z100PWR-G1/Texas+Instruments/view-part/?ref=snap" (id 8) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "MP" "BQ34Z100PWR-G1" (id 9) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Purchase-URL" "https://www.snapeda.com/api/url_track_click_mouser/?unipart_id=327977&manufacturer=Texas Instruments&part_name=BQ34Z100PWR-G1&search_term=None" (id 10) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Availability" "In Stock" (id 11) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(property "Check_prices" "https://www.snapeda.com/parts/BQ34Z100PWR-G1/Texas+Instruments/view-part/?ref=eda" (id 12) (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify bottom) hide)
)
(symbol "BQ34Z100PWR-G1_0_0"
(rectangle (start -12.7 -25.4) (end 12.7 25.4)
(stroke (width 0.41)) (fill (type background))
)
(pin input line (at -17.78 22.86 0) (length 5.08)
(name "REGIN"
(effects (font (size 1.016 1.016)))
)
(number "6"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 17.78 0) (length 5.08)
(name "BAT"
(effects (font (size 1.016 1.016)))
)
(number "4"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 12.7 0) (length 5.08)
(name "CE"
(effects (font (size 1.016 1.016)))
)
(number "5"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 7.62 0) (length 5.08)
(name "P1"
(effects (font (size 1.016 1.016)))
)
(number "3"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 5.08 0) (length 5.08)
(name "P2"
(effects (font (size 1.016 1.016)))
)
(number "1"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 2.54 0) (length 5.08)
(name "P3/SDA"
(effects (font (size 1.016 1.016)))
)
(number "14"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 -2.54 0) (length 5.08)
(name "REG25"
(effects (font (size 1.016 1.016)))
)
(number "7"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 -7.62 0) (length 5.08)
(name "SRN"
(effects (font (size 1.016 1.016)))
)
(number "10"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 -12.7 0) (length 5.08)
(name "SRP"
(effects (font (size 1.016 1.016)))
)
(number "9"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at -17.78 -17.78 0) (length 5.08)
(name "VEN"
(effects (font (size 1.016 1.016)))
)
(number "2"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 17.78 5.08 180.0) (length 5.08)
(name "P4/SCL"
(effects (font (size 1.016 1.016)))
)
(number "13"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 17.78 2.54 180.0) (length 5.08)
(name "P5/HDQ"
(effects (font (size 1.016 1.016)))
)
(number "12"
(effects (font (size 1.016 1.016)))
)
)
(pin bidirectional line (at 17.78 1.77636e-15 180.0) (length 5.08)
(name "P6/TS"
(effects (font (size 1.016 1.016)))
)
(number "11"
(effects (font (size 1.016 1.016)))
)
)
(pin power_in line (at 17.78 -20.32 180.0) (length 5.08)
(name "VSS"
(effects (font (size 1.016 1.016)))
)
(number "8"
(effects (font (size 1.016 1.016)))
)
)
)
)
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,186 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "CN61CN33" (in_bom yes) (on_board yes)
(property "Reference" "U" (at 2.54 12.7 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "CN61CN33" (at 5.08 10.16 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "Package_TO_SOT_SMD:SOT-23" (at 7.62 2.54 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "http://www.ti.com/lit/ds/symlink/lm809.pdf" (at 7.62 2.54 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "reset supervisor" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Microprocessor Reset (active-low) Circuit, SOT-23" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "SOT?23*" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "CN61CN33_0_1"
(rectangle (start 5.08 7.62) (end -5.08 -7.62)
(stroke (width 0.254) (type solid))
(fill (type background))
)
)
(symbol "CN61CN33_1_1"
(pin output line (at 0 -10.16 90) (length 2.54)
(name "RESET" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin power_in line (at 7.62 0 180) (length 2.54)
(name "GND" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin power_in line (at 0 10.16 270) (length 2.54)
(name "VCC" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "DS2438" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "DS2438" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "DS2438_0_1"
(rectangle (start -11.43 -2.54) (end 12.7 -30.48)
(stroke (width 0) (type solid))
(fill (type background))
)
)
(symbol "DS2438_1_1"
(pin power_in line (at -13.97 -6.35 0) (length 2.54)
(name "GND" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin unspecified line (at -13.97 -12.7 0) (length 2.54)
(name "Vsens+" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin unspecified line (at -13.97 -19.05 0) (length 2.54)
(name "Vsense-" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin input line (at -13.97 -25.4 0) (length 2.54)
(name "Vad" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
(pin power_in line (at 15.24 -25.4 180) (length 2.54)
(name "Vdd" (effects (font (size 1.27 1.27))))
(number "5" (effects (font (size 1.27 1.27))))
)
(pin unspecified line (at 15.24 -19.05 180) (length 2.54)
(name "NC" (effects (font (size 1.27 1.27))))
(number "6" (effects (font (size 1.27 1.27))))
)
(pin unspecified line (at 15.24 -12.7 180) (length 2.54)
(name "NC" (effects (font (size 1.27 1.27))))
(number "7" (effects (font (size 1.27 1.27))))
)
(pin bidirectional line (at 15.24 -6.35 180) (length 2.54)
(name "DQ" (effects (font (size 1.27 1.27))))
(number "8" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "DW01" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "IC" (at 21.59 7.62 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Value" "DW01" (at 21.59 5.08 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Footprint" "SOT95P280X135-6N" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "HEIGHT" "1.35mm" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "DESCRIPTION" "ic" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "MANUFACTURER_PART_NUMBER" "DW01" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "MANUFACTURER_NAME" "Slkor" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "ki_locked" "" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(symbol "DW01_0_0"
(polyline
(pts
(xy 5.08 2.54)
(xy 5.08 -7.62)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 5.08 2.54)
(xy 20.32 2.54)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 20.32 -7.62)
(xy 5.08 -7.62)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 20.32 -7.62)
(xy 20.32 2.54)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(pin bidirectional line (at 0 0 0) (length 5.08)
(name "OD" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 0 -2.54 0) (length 5.08)
(name "CSI" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 0 -5.08 0) (length 5.08)
(name "OC" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 25.4 -5.08 180) (length 5.08)
(name "TD" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 25.4 -2.54 180) (length 5.08)
(name "VDD" (effects (font (size 1.016 1.016))))
(number "5" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 25.4 0 180) (length 5.08)
(name "VSS" (effects (font (size 1.016 1.016))))
(number "6" (effects (font (size 1.016 1.016))))
)
)
)
)

View File

@@ -0,0 +1,454 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "ESP32-DEVKITC-32D" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (at -15.2654 26.0604 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Value" "ESP32-DEVKITC-32D" (at -15.2654 -27.9654 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Footprint" "MODULE_ESP32-DEVKITC-32D" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "4" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Field4" "Espressif Systems" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "ki_locked" "" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(symbol "ESP32-DEVKITC-32D_0_0"
(polyline
(pts
(xy -15.24 -25.4)
(xy -15.24 25.4)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -15.24 25.4)
(xy 15.24 25.4)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 15.24 -25.4)
(xy -15.24 -25.4)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 15.24 25.4)
(xy 15.24 -25.4)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(pin power_in line (at -20.32 22.86 0) (length 5.08)
(name "3V3" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 0 0) (length 5.08)
(name "IO26" (effects (font (size 1.016 1.016))))
(number "10" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -2.54 0) (length 5.08)
(name "IO27" (effects (font (size 1.016 1.016))))
(number "11" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -5.08 0) (length 5.08)
(name "IO14" (effects (font (size 1.016 1.016))))
(number "12" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -7.62 0) (length 5.08)
(name "IO12" (effects (font (size 1.016 1.016))))
(number "13" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at -20.32 -10.16 0) (length 5.08)
(name "GND1" (effects (font (size 1.016 1.016))))
(number "14" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -12.7 0) (length 5.08)
(name "IO13" (effects (font (size 1.016 1.016))))
(number "15" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -15.24 0) (length 5.08)
(name "SD2" (effects (font (size 1.016 1.016))))
(number "16" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -17.78 0) (length 5.08)
(name "SD3" (effects (font (size 1.016 1.016))))
(number "17" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 -20.32 0) (length 5.08)
(name "CMD" (effects (font (size 1.016 1.016))))
(number "18" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at -20.32 -22.86 0) (length 5.08)
(name "EXT_5V" (effects (font (size 1.016 1.016))))
(number "19" (effects (font (size 1.016 1.016))))
)
(pin input line (at -20.32 20.32 0) (length 5.08)
(name "EN" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 20.32 22.86 180) (length 5.08)
(name "GND3" (effects (font (size 1.016 1.016))))
(number "20" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 20.32 180) (length 5.08)
(name "IO23" (effects (font (size 1.016 1.016))))
(number "21" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 17.78 180) (length 5.08)
(name "IO22" (effects (font (size 1.016 1.016))))
(number "22" (effects (font (size 1.016 1.016))))
)
(pin output line (at 20.32 15.24 180) (length 5.08)
(name "TXD0" (effects (font (size 1.016 1.016))))
(number "23" (effects (font (size 1.016 1.016))))
)
(pin input line (at 20.32 12.7 180) (length 5.08)
(name "RXD0" (effects (font (size 1.016 1.016))))
(number "24" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 10.16 180) (length 5.08)
(name "IO21" (effects (font (size 1.016 1.016))))
(number "25" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 20.32 7.62 180) (length 5.08)
(name "GND2" (effects (font (size 1.016 1.016))))
(number "26" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 5.08 180) (length 5.08)
(name "IO19" (effects (font (size 1.016 1.016))))
(number "27" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 2.54 180) (length 5.08)
(name "IO18" (effects (font (size 1.016 1.016))))
(number "28" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 0 180) (length 5.08)
(name "IO5" (effects (font (size 1.016 1.016))))
(number "29" (effects (font (size 1.016 1.016))))
)
(pin input line (at -20.32 17.78 0) (length 5.08)
(name "SENSOR_VP" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -2.54 180) (length 5.08)
(name "IO17" (effects (font (size 1.016 1.016))))
(number "30" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -5.08 180) (length 5.08)
(name "IO16" (effects (font (size 1.016 1.016))))
(number "31" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -7.62 180) (length 5.08)
(name "IO4" (effects (font (size 1.016 1.016))))
(number "32" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -10.16 180) (length 5.08)
(name "IO0" (effects (font (size 1.016 1.016))))
(number "33" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -12.7 180) (length 5.08)
(name "IO2" (effects (font (size 1.016 1.016))))
(number "34" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -15.24 180) (length 5.08)
(name "IO15" (effects (font (size 1.016 1.016))))
(number "35" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -17.78 180) (length 5.08)
(name "SD1" (effects (font (size 1.016 1.016))))
(number "36" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 20.32 -20.32 180) (length 5.08)
(name "SD0" (effects (font (size 1.016 1.016))))
(number "37" (effects (font (size 1.016 1.016))))
)
(pin input clock (at 20.32 -22.86 180) (length 5.08)
(name "CLK" (effects (font (size 1.016 1.016))))
(number "38" (effects (font (size 1.016 1.016))))
)
(pin input line (at -20.32 15.24 0) (length 5.08)
(name "SENSOR_VN" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 12.7 0) (length 5.08)
(name "IO34" (effects (font (size 1.016 1.016))))
(number "5" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 10.16 0) (length 5.08)
(name "IO35" (effects (font (size 1.016 1.016))))
(number "6" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 7.62 0) (length 5.08)
(name "IO32" (effects (font (size 1.016 1.016))))
(number "7" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 5.08 0) (length 5.08)
(name "IO33" (effects (font (size 1.016 1.016))))
(number "8" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -20.32 2.54 0) (length 5.08)
(name "IO25" (effects (font (size 1.016 1.016))))
(number "9" (effects (font (size 1.016 1.016))))
)
)
)
(symbol "SL2300" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "Q" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "SL2300" (at 7.62 0 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "SL2300_1_1"
(polyline
(pts
(xy -1.016 0)
(xy -3.81 0)
)
(stroke (width 0) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -1.016 1.905)
(xy -1.016 -1.905)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -0.508 -1.27)
(xy -0.508 -2.286)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -0.508 0.508)
(xy -0.508 -0.508)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -0.508 2.286)
(xy -0.508 1.27)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 1.27 2.54)
(xy 1.27 1.778)
)
(stroke (width 0) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 1.27 -2.54)
(xy 1.27 0)
(xy -0.508 0)
)
(stroke (width 0) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -0.508 -1.778)
(xy 2.032 -1.778)
(xy 2.032 1.778)
(xy -0.508 1.778)
)
(stroke (width 0) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -0.254 0)
(xy 0.762 0.381)
(xy 0.762 -0.381)
(xy -0.254 0)
)
(stroke (width 0) (type solid))
(fill (type outline))
)
(polyline
(pts
(xy 1.524 0.508)
(xy 1.651 0.381)
(xy 2.413 0.381)
(xy 2.54 0.254)
)
(stroke (width 0) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 2.032 0.381)
(xy 1.651 -0.254)
(xy 2.413 -0.254)
(xy 2.032 0.381)
)
(stroke (width 0) (type solid))
(fill (type none))
)
(circle (center 0.381 0) (radius 2.794)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(circle (center 1.27 -1.778) (radius 0.254)
(stroke (width 0) (type solid))
(fill (type outline))
)
(circle (center 1.27 1.778) (radius 0.254)
(stroke (width 0) (type solid))
(fill (type outline))
)
(pin input line (at -6.35 0 0) (length 2.54)
(name "G" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 1.27 -5.08 90) (length 2.54)
(name "S" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin passive line (at 1.27 5.08 270) (length 2.54)
(name "D" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
)
)
(symbol "SR04M-2" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "H" (at 6.35 27.94 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "SR04M-2" (at 7.62 -21.59 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "SR04M-2_0_1"
(rectangle (start -22.86 26.67) (end 41.91 -20.32)
(stroke (width 0.254) (type solid))
(fill (type none))
)
)
)
(symbol "SR04M-2-HeaderConn_01x04_Female" (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes)
(property "Reference" "J" (at 0 5.08 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "SR04M-2-HeaderConn_01x04_Female" (at 0 -7.62 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "ESP32:SR04M-2PinHeader_1x04_P2.54mm_Vertical" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "Datasheet" "~" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_keywords" "connector" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_description" "Generic connector, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(property "ki_fp_filters" "Connector*:*_1x??_*" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "SR04M-2-HeaderConn_01x04_Female_1_1"
(arc (start 0 -4.572) (mid -0.5058 -5.08) (end 0 -5.588)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(arc (start 0 -2.032) (mid -0.5058 -2.54) (end 0 -3.048)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -5.08)
(xy -0.508 -5.08)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -1.27 -2.54)
(xy -0.508 -2.54)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -1.27 0)
(xy -0.508 0)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -1.27 2.54)
(xy -0.508 2.54)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(arc (start 0 0.508) (mid -0.5058 0) (end 0 -0.508)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(arc (start 0 3.048) (mid -0.5058 2.54) (end 0 2.032)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(pin power_in line (at -5.08 2.54 0) (length 3.81)
(name "VCC" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin input line (at -5.08 0 0) (length 3.81)
(name "RX" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
(pin output line (at -5.08 -2.54 0) (length 3.81)
(name "TX" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin power_in line (at -5.08 -5.08 0) (length 3.81)
(name "GND" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
)
)
)

View File

@@ -0,0 +1,74 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "LP38690DT-3.3" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (at -10.16 5.08 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Value" "LP38690DT-3.3" (at -10.16 -7.62 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Footprint" "DPAK457P991X255-3N" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "IPC-7351B" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Field4" "Texas Instruments" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Field5" "M" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Field6" "2.55mm" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "ki_locked" "" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(symbol "LP38690DT-3.3_0_0"
(polyline
(pts
(xy -10.16 -5.08)
(xy 10.16 -5.08)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -10.16 5.08)
(xy -10.16 -5.08)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 10.16 -5.08)
(xy 10.16 5.08)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 10.16 5.08)
(xy -10.16 5.08)
)
(stroke (width 0.1524) (type solid))
(fill (type none))
)
(pin output line (at 15.24 2.54 180) (length 5.08)
(name "OUT" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin input line (at -15.24 2.54 0) (length 5.08)
(name "IN" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin power_in line (at 15.24 -2.54 180) (length 5.08)
(name "GND" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
)
)
)

View File

@@ -0,0 +1,37 @@
(footprint SOP65P640X120-14N (layer F.Cu) (tedit 65346025)
(descr "")
(attr smd)
(fp_text reference REF** (at -0.595 -3.435 0) (layer F.SilkS)
(effects (font (size 1.0 1.0) (thickness 0.15)))
)
(fp_text value SOP65P640X120-14N (at 7.025 3.435 0) (layer F.Fab)
(effects (font (size 1.0 1.0) (thickness 0.15)))
)
(pad 1 smd roundrect (roundrect_rratio 0.05) (at -2.87 -1.95) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 2 smd roundrect (roundrect_rratio 0.05) (at -2.87 -1.3) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 3 smd roundrect (roundrect_rratio 0.05) (at -2.87 -0.65) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 4 smd roundrect (roundrect_rratio 0.05) (at -2.87 0.0) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 5 smd roundrect (roundrect_rratio 0.05) (at -2.87 0.65) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 6 smd roundrect (roundrect_rratio 0.05) (at -2.87 1.3) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 7 smd roundrect (roundrect_rratio 0.05) (at -2.87 1.95) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 8 smd roundrect (roundrect_rratio 0.05) (at 2.87 1.95) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 9 smd roundrect (roundrect_rratio 0.05) (at 2.87 1.3) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 10 smd roundrect (roundrect_rratio 0.05) (at 2.87 0.65) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 11 smd roundrect (roundrect_rratio 0.05) (at 2.87 0.0) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 12 smd roundrect (roundrect_rratio 0.05) (at 2.87 -0.65) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 13 smd roundrect (roundrect_rratio 0.05) (at 2.87 -1.3) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 14 smd roundrect (roundrect_rratio 0.05) (at 2.87 -1.95) (size 1.57 0.41) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(fp_circle (center -4.24 -2.26) (end -4.14 -2.26) (layer F.SilkS) (width 0.2))
(fp_circle (center -4.24 -2.26) (end -4.14 -2.26) (layer F.Fab) (width 0.2))
(fp_line (start -2.2 -2.5) (end 2.2 -2.5) (layer F.Fab) (width 0.127))
(fp_line (start -2.2 2.5) (end 2.2 2.5) (layer F.Fab) (width 0.127))
(fp_line (start -2.2 -2.5) (end 2.2 -2.5) (layer F.SilkS) (width 0.127))
(fp_line (start -2.2 2.5) (end 2.2 2.5) (layer F.SilkS) (width 0.127))
(fp_line (start -2.2 -2.5) (end -2.2 2.5) (layer F.Fab) (width 0.127))
(fp_line (start 2.2 -2.5) (end 2.2 2.5) (layer F.Fab) (width 0.127))
(fp_line (start -3.905 -2.75) (end 3.905 -2.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.905 2.75) (end 3.905 2.75) (layer F.CrtYd) (width 0.05))
(fp_line (start -3.905 -2.75) (end -3.905 2.75) (layer F.CrtYd) (width 0.05))
(fp_line (start 3.905 -2.75) (end 3.905 2.75) (layer F.CrtYd) (width 0.05))
)

View File

@@ -0,0 +1,29 @@
(footprint SSOP10 (layer F.Cu) (tedit 652971AF)
(descr "")
(attr smd)
(fp_text reference REF** (at -3.2004 0.0 900) (layer F.SilkS)
(effects (font (size 0.64 0.64) (thickness 0.15)))
)
(fp_text value SSOP10 (at 3.1496 -0.4064 900) (layer F.Fab)
(effects (font (size 0.64 0.64) (thickness 0.15)))
)
(pad 2 smd rect (at -1.0 2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 9 smd rect (at -1.0 -2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 1 smd rect (at -2.0 2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 3 smd rect (at 0.0 2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 4 smd rect (at 1.0 2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 10 smd rect (at -2.0 -2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 8 smd rect (at 0.0 -2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 7 smd rect (at 1.0 -2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 5 smd rect (at 2.0 2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(pad 6 smd rect (at 2.0 -2.8) (size 0.6 1.75) (layers F.Cu F.Mask F.Paste) (solder_mask_margin 0.102))
(fp_line (start 2.527 -1.9) (end 2.527 1.4) (layer F.Fab) (width 0.2032))
(fp_line (start 2.527 1.4) (end 2.527 1.9) (layer F.Fab) (width 0.2032))
(fp_line (start 2.527 1.9) (end -2.527 1.9) (layer F.Fab) (width 0.2032))
(fp_line (start -2.527 1.9) (end -2.527 1.4) (layer F.Fab) (width 0.2032))
(fp_line (start -2.527 1.4) (end -2.527 -1.9) (layer F.Fab) (width 0.2032))
(fp_line (start -2.527 -1.9) (end 2.527 -1.9) (layer F.Fab) (width 0.2032))
(fp_line (start 2.527 1.4) (end -2.527 1.4) (layer F.Fab) (width 0.2032))
(fp_line (start -1.905 1.016) (end -1.905 -1.016) (layer F.SilkS) (width 0.3048))
)

View File

@@ -0,0 +1,104 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "SX1308" (pin_names (offset 1.016)) (in_bom yes) (on_board yes)
(property "Reference" "U" (at -17.78 20.32 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Value" "SX1308" (at -17.8054 17.8054 0)
(effects (font (size 1.27 1.27)) (justify left bottom))
)
(property "Footprint" "SOT-23-6" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.27 1.27)) (justify left bottom) hide)
)
(property "ki_locked" "" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(symbol "SX1308_0_0"
(polyline
(pts
(xy -17.78 -7.62)
(xy -17.78 15.24)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -17.78 15.24)
(xy 0 15.24)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -13.7922 0.1778)
(xy -11.2522 0.1778)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -11.303 1.6764)
(xy -8.763 1.6764)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy -11.2522 0.1778)
(xy -11.303 1.6764)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 0 -7.62)
(xy -17.78 -7.62)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 0 15.24)
(xy 0 -7.62)
)
(stroke (width 0.254) (type solid))
(fill (type none))
)
(text "ON/OFF" (at -10.8712 -0.0508 0)
(effects (font (size 0.8128 0.8128)) (justify left bottom))
)
(pin bidirectional line (at 5.08 12.7 180) (length 5.08)
(name "SW" (effects (font (size 1.016 1.016))))
(number "1" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -22.86 -5.08 0) (length 5.08)
(name "GND" (effects (font (size 1.016 1.016))))
(number "2" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 5.08 -2.54 180) (length 5.08)
(name "FB" (effects (font (size 1.016 1.016))))
(number "3" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -22.86 2.54 0) (length 5.08)
(name "EN" (effects (font (size 1.016 1.016))))
(number "4" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at -22.86 12.7 0) (length 5.08)
(name "IN" (effects (font (size 1.016 1.016))))
(number "5" (effects (font (size 1.016 1.016))))
)
(pin bidirectional line (at 5.08 5.08 180) (length 5.08)
(name "N/C" (effects (font (size 1.016 1.016))))
(number "6" (effects (font (size 1.016 1.016))))
)
)
)
)

View File

@@ -0,0 +1,168 @@
(kicad_symbol_lib (version 20220914) (generator kicad_symbol_editor)
(symbol "ds2438az+" (pin_names (offset 0.254)) (in_bom yes) (on_board yes)
(property "Reference" "U" (at 30.48 10.16 0)
(effects (font (size 1.524 1.524)))
)
(property "Value" "ds2438az+" (at 30.48 7.62 0)
(effects (font (size 1.524 1.524)))
)
(property "Footprint" "21-0041B_8_MXM" (at 30.48 6.096 0)
(effects (font (size 1.524 1.524)) hide)
)
(property "Datasheet" "" (at 0 0 0)
(effects (font (size 1.524 1.524)))
)
(property "ki_locked" "" (at 0 0 0)
(effects (font (size 1.27 1.27)))
)
(property "ki_fp_filters" "21-0041B_8_MXM 21-0041B_8_MXM-M 21-0041B_8_MXM-L" (at 0 0 0)
(effects (font (size 1.27 1.27)) hide)
)
(symbol "ds2438az+_1_1"
(polyline
(pts
(xy 7.112 -7.62)
(xy 6.0452 -8.128)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.112 -7.62)
(xy 6.0452 -7.112)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.112 -5.08)
(xy 6.0452 -5.588)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.112 -5.08)
(xy 6.0452 -4.572)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.112 -2.54)
(xy 6.0452 -3.048)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.112 -2.54)
(xy 6.0452 -2.032)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.62 -12.7)
(xy 53.34 -12.7)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 7.62 5.08)
(xy 7.62 -12.7)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 53.34 -12.7)
(xy 53.34 5.08)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 53.34 5.08)
(xy 7.62 5.08)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 53.848 0)
(xy 54.9148 -0.508)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 53.848 0)
(xy 54.9148 0.508)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 55.4228 -0.508)
(xy 56.4642 0)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(polyline
(pts
(xy 55.4228 0.508)
(xy 56.4642 0)
)
(stroke (width 0.127) (type solid))
(fill (type none))
)
(pin power_in line (at 0 0 0) (length 7.62)
(name "GND" (effects (font (size 1.4986 1.4986))))
(number "1" (effects (font (size 1.4986 1.4986))))
)
(pin input line (at 0 -2.54 0) (length 7.62)
(name "VSENS+" (effects (font (size 1.4986 1.4986))))
(number "2" (effects (font (size 1.4986 1.4986))))
)
(pin input line (at 0 -5.08 0) (length 7.62)
(name "VSENS-" (effects (font (size 1.4986 1.4986))))
(number "3" (effects (font (size 1.4986 1.4986))))
)
(pin input line (at 0 -7.62 0) (length 7.62)
(name "VAD" (effects (font (size 1.4986 1.4986))))
(number "4" (effects (font (size 1.4986 1.4986))))
)
(pin power_in line (at 60.96 -7.62 180) (length 7.62)
(name "VDD" (effects (font (size 1.4986 1.4986))))
(number "5" (effects (font (size 1.4986 1.4986))))
)
(pin no_connect line (at 60.96 -5.08 180) (length 7.62)
(name "NC" (effects (font (size 1.4986 1.4986))))
(number "6" (effects (font (size 1.4986 1.4986))))
)
(pin no_connect line (at 60.96 -2.54 180) (length 7.62)
(name "NC" (effects (font (size 1.4986 1.4986))))
(number "7" (effects (font (size 1.4986 1.4986))))
)
(pin bidirectional line (at 60.96 0 180) (length 7.62)
(name "DQ" (effects (font (size 1.4986 1.4986))))
(number "8" (effects (font (size 1.4986 1.4986))))
)
)
)
)

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,12 @@
(sym_lib_table
(lib (name LP38690DT-3.3)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/LP38690DT-3.3.lib)(options "")(descr ""))
(lib (name ESP32-DEVKITC-32D)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/ESP32/ESP32-DEVKITC-32D.lib)(options "")(descr ""))
(lib (name DW01)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/DW01.lib)(options "")(descr ""))
(lib (name SX1308)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/SX1308.lib)(options "")(descr ""))
(lib (name ds2438)(type Legacy)(uri ${KIPRJMOD}/kicad-stuff/ds2438.lib)(options "")(descr ""))
(version 7)
(lib (name "LP38690DT-3.3")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/LP38690DT-3.3.kicad_sym")(options "")(descr ""))
(lib (name "ESP32-DEVKITC-32D")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/ESP32/ESP32-DEVKITC-32D.kicad_sym")(options "")(descr ""))
(lib (name "DW01")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/DW01.kicad_sym")(options "")(descr ""))
(lib (name "SX1308")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/SX1308.kicad_sym")(options "")(descr ""))
(lib (name "ds2438")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/ds2438.kicad_sym")(options "")(descr ""))
(lib (name "CN3306")(type "KiCad")(uri "${KIPRJMOD}/CN3306.kicad_sym")(options "")(descr ""))
(lib (name "CN3795")(type "KiCad")(uri "${KIPRJMOD}/CN3795.kicad_sym")(options "")(descr ""))
(lib (name "BQ34Z100PWR-G1")(type "KiCad")(uri "${KIPRJMOD}/kicad-stuff/BQ34Z100PWR-G1.kicad_sym")(options "")(descr ""))
(lib (name "ESP32-C6-WROOM-1-N8")(type "KiCad")(uri "${KIPRJMOD}/esp32c6/ESP32-C6-WROOM-1-N8.kicad_sym")(options "")(descr ""))
)

9
esp32/.gitignore vendored
View File

@@ -1,9 +0,0 @@
*.swp
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
doc/
custom_platformio.ini
cppcheck-build-dir

View File

@@ -1,7 +0,0 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"functional": "cpp",
"*.tcc": "cpp",
"map": "cpp",
"*.cps": "javascript",
"bitset": "cpp",
"algorithm": "cpp",
"istream": "cpp",
"limits": "cpp",
"streambuf": "cpp",
"string": "cpp",
"typeinfo": "cpp",
"cmath": "cpp",
"iterator": "cpp"
}
}
}

View File

@@ -1,76 +0,0 @@
# PlantControl
## Hardware
Uses ESP32MiniKit
### Used Pins:
* See '''include/ControllerConfiguration.h'''
## Software
* MQTT topics
# Hardware
## Features
* Support for up to
* 7 Moister sensors
* 7 Pumps
* Sensors
* Solar powered (voltage)
* Lipo-Powered (voltage)
* Temperature
* Distance sensor [JSN-SR04T-2.0] (for waterlevel)
* Custom GPIO
## Documentation of Power-Modes
https://lastminuteengineers.com/esp32-sleep-modes-power-consumption/#esp32-deep-sleep
gpio 17 only out no hold
gpio 16 only out no hold
## Additional hardware
solar charger 2A?
https://www.aliexpress.com/item/4000238259949.html?spm=a2g0o.productlist.0.0.7e50231cCWGu0Z&algo_pvid=9ab7b0d3-5026-438b-972b-1d4a81d4dc56&algo_expid=9ab7b0d3-5026-438b-972b-1d4a81d4dc56-11&btsid=0b0a0ac215999246489888249e72a9&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_
MT3608 boost für pumpe
https://www.aliexpress.com/item/32925951391.html?spm=a2g0o.productlist.0.0.39e21087nAzH9q&algo_pvid=7db0a849-62f7-4403-88e3-615ee4d99339&algo_expid=7db0a849-62f7-4403-88e3-615ee4d99339-0&btsid=0b0a0ac215999252934777876e7253&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_
DS18B20 one wire temp sensor
# Features
## Empires Wunschliste
* Pflanze
* Pumpe
* Zeitspann (wann laufen darf)
* Helligkeitstrigger (Um den Morgen zum pumpen zu erkennen)
* Maximal Dauer zum Pumpen (als Zeit oder Milliliter)
* Zeitspanne zwischen zwei Pumpvorgängen
* Moister sensor
* Oberen
* Unteren Wert
* Tank
* Füllstand Anzeige (in Liter)
* Minimum Wasserstand (in cm damit Pumpen nicht leer laufen; enspricht 0 nutzbaren Liter)
* Trigger-Erinnerungen um Wasser nachzufüllen
* Maximaler Wasserstand des Tanks (in cm & Liter)
* System
* Tiefentladungsschutz vom LIPO (fest im Controller die Spannung festlegen)
* 3.5V unterschritten, dann nur noch Deepsleep
* MQTT Topic, wenn Spannung unterschritten wurde
* Lipo innerhalb 24h nicht geladen -> MQTT Topic
* Deep-Sleep
* Mode1:
* Nur Sensor werte einsameln
* Wird verlassen bei Aktionen
* Pumpe schalten
* MQTT Nachrichten
* nach x Minuten nur in Mode1
* Mode2:
* WLAN aktivieren und Werte über MQTT raus hauen
* aktuelle Werte raushauen
* MQTT lesen
* Mode3:
* Deepsleep verboten (MQTT topic, retained)
* alle Pumpen & Sensoren deaktiviert

View File

@@ -1,17 +0,0 @@
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
board_build.partitions = defaultWithSmallerSpiffs.csv
extra_configs = custom_platformio.ini
; the latest development brankitchen-lightch (convention V3.0.x)
lib_deps = ArduinoJson@6.16.1
https://github.com/homieiot/homie-esp8266.git#v3.0
OneWire
DallasTemperature
; add additional parameter, like the upload port
upload_port=/dev/ttyUSB1

View File

@@ -1 +0,0 @@
config.json

View File

@@ -1,12 +0,0 @@
# Filesystem
## Configuration
Use the config-example.json from the host folder and create here a config.json file.
## HowTo upload
Start Platform.io
Open a new Atom-Terminal and generate the filesystem with the following command :
```pio run -t buildfs```
Upload this new generated filesystem with:
```pio run -t uploadfs```
## Command pio
Can be found at ```~/.platformio/penv/bin/pio```

Binary file not shown.

View File

@@ -1,6 +0,0 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x150000,
app1, app, ota_1, 0x160000,0x150000,
spiffs, data, spiffs, 0x300000,0x17000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x150000
5 app1 app ota_1 0x160000 0x150000
6 spiffs data spiffs 0x300000 0x17000

View File

@@ -1,90 +0,0 @@
# Configuration
## File
Generate a file as, described in
https://homieiot.github.io/homie-esp8266/docs/3.0.0/configuration/json-configuration-file/
For further details have a look at the Readme.md one level above.
## Upload
* Start ESP
* Login to Wifi, opened by the ESP
* Use the script to upload the configuration file
* restart the ESP
# Remote Upload
This script will allow you to send an OTA update to your device.
## Installation
Requirements are:
* paho-mqtt
## Usage
See ***upload-via-mqtt.sh***
# Remote Upload - Backend
## Usage
```text
usage: ota_updater.py [-h] -l BROKER_HOST -p BROKER_PORT [-u BROKER_USERNAME]
[-d BROKER_PASSWORD] [-t BASE_TOPIC] -i DEVICE_ID
firmware
ota firmware update scirpt for ESP8226 implemenation of the Homie mqtt IoT
convention.
positional arguments:
firmware path to the firmware to be sent to the device
arguments:
-h, --help show this help message and exit
-l BROKER_HOST, --broker-host BROKER_HOST
host name or ip address of the mqtt broker
-p BROKER_PORT, --broker-port BROKER_PORT
port of the mqtt broker
-u BROKER_USERNAME, --broker-username BROKER_USERNAME
username used to authenticate with the mqtt broker
-d BROKER_PASSWORD, --broker-password BROKER_PASSWORD
password used to authenticate with the mqtt broker
-t BASE_TOPIC, --base-topic BASE_TOPIC
base topic of the homie devices on the broker
-i DEVICE_ID, --device-id DEVICE_ID
homie device id
```
* `BROKER_HOST` and `BROKER_PORT` defaults to 127.0.0.1 and 1883 respectively if not set.
* `BROKER_USERNAME` and `BROKER_PASSWORD` are optional.
* `BASE_TOPIC` has to end with a slash, defaults to `homie/` if not set.
### Example:
```bash
python ota_updater.py -l localhost -u admin -d secure -t "homie/" -i "device-id" /path/to/firmware.bin
```
The Parameter can be extracted from the serial console
```serial
{} Stored configuration
• Hardware device ID: 12345abcd
• Device ID: MyDeviceId
• Name: MyDeviceName
• Device Stats Interval: 60 sec
• Wi-Fi:
◦ SSID: MyWifi
◦ Password not shown
• MQTT:
◦ Host: 192.168.0.2
◦ Port: 1883
◦ Base topic: /test/
◦ Auth? no
```
will result in the following command (when executed in this folder):
```bash
python ota_updater.py -l 192.168.0.2 -t "/test/" -i "MyDeviceId" ../.pio/build/esp32doit-devkit-v1/firmware.bin
```
### Source
https://github.com/homieiot/homie-esp8266/blob/develop/scripts/ota_updater

View File

@@ -1,49 +0,0 @@
{
"name": "PlantControl",
"device_id": "PlantCtrl1",
"device_stats_interval": 60,
"wifi": {
"ssid": "SSID",
"bssid" : "BSSID",
"password": "mysecretPassword",
"channel": 1
},
"mqtt": {
"host": "[0-255].[0-255].[0-255].[0-255]",
"port": 1883,
"base_topic": "mqtt/topic/",
"auth": false
},
"ota": {
"enabled": true
},
"settings": {
"deepsleep" : 60000,
"nightsleep" : 60000,
"pumpdeepsleep": 1000,
"watermaxlevel": 50,
"watermin" : 5,
"plants" : 3,
"moist0" : 2000,
"moist1" : 2000,
"moist2" : 2000,
"moist3" : 2000,
"moist4" : 2000,
"moist5" : 2000,
"moist6" : 2000,
"plant0MaxPumpTime": 1000,
"plant1MaxPumpTime": 1000,
"plant2MaxPumpTime": 1000,
"plant3MaxPumpTime": 1000,
"plant4MaxPumpTime": 1000,
"plant5MaxPumpTime": 1000,
"plant6MaxPumpTime": 1000,
"plant0MinPumpIdle": 10000,
"plant1MinPumpIdle": 10000,
"plant2MinPumpIdle": 10000,
"plant3MinPumpIdle": 10000,
"plant4MinPumpIdle": 10000,
"plant5MinPumpIdle": 10000,
"plant6MinPumpIdle": 10000
}
}

View File

@@ -1,174 +0,0 @@
#!/usr/bin/env python
from __future__ import division, print_function
import paho.mqtt.client as mqtt
import base64, sys, math
from hashlib import md5
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
if rc != 0:
print("Connection Failed with result code {}".format(rc))
client.disconnect()
else:
print("Connected with result code {}".format(rc))
client.subscribe("{base_topic}{device_id}/$state".format(**userdata)) # v3 / v4 devices
client.subscribe("{base_topic}{device_id}/$online".format(**userdata)) # v2 devices
print("Waiting for device to come online...")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
# decode string for python2/3 compatiblity
msg.payload = msg.payload.decode()
if msg.topic.endswith('$implementation/ota/status'):
status = int(msg.payload.split()[0])
if userdata.get("published"):
if status == 206: # in progress
# state in progress, print progress bar
progress, total = [int(x) for x in msg.payload.split()[1].split('/')]
bar_width = 30
bar = int(bar_width*(progress/total))
print("\r[", '+'*bar, ' '*(bar_width-bar), "] ", msg.payload.split()[1], end='', sep='')
if (progress == total):
print()
sys.stdout.flush()
elif status == 304: # not modified
print("Device firmware already up to date with md5 checksum: {}".format(userdata.get('md5')))
client.disconnect()
elif status == 403: # forbidden
print("Device ota disabled, aborting...")
client.disconnect()
elif msg.topic.endswith('$fw/checksum'):
checksum = msg.payload
if userdata.get("published"):
if checksum == userdata.get('md5'):
print("Device back online. Update Successful!")
else:
print("Expecting checksum {}, got {}, update failed!".format(userdata.get('md5'), checksum))
client.disconnect()
else:
if checksum != userdata.get('md5'): # save old md5 for comparison with new firmware
userdata.update({'old_md5': checksum})
else:
print("Device firmware already up to date with md5 checksum: {}".format(checksum))
client.disconnect()
elif msg.topic.endswith('ota/enabled'):
if msg.payload == 'true':
userdata.update({'ota_enabled': True})
else:
print("Device ota disabled, aborting...")
client.disconnect()
elif msg.topic.endswith('$state') or msg.topic.endswith('$online'):
if (msg.topic.endswith('$state') and msg.payload != 'ready') or (msg.topic.endswith('$online') and msg.payload == 'false'):
return
# calcluate firmware md5
firmware_md5 = md5(userdata['firmware']).hexdigest()
userdata.update({'md5': firmware_md5})
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("{base_topic}{device_id}/$implementation/ota/status".format(**userdata))
client.subscribe("{base_topic}{device_id}/$implementation/ota/enabled".format(**userdata))
client.subscribe("{base_topic}{device_id}/$fw/#".format(**userdata))
# Wait for device info to come in and invoke the on_message callback where update will continue
print("Waiting for device info...")
if ( not userdata.get("published") ) and ( userdata.get('ota_enabled') ) and \
( 'old_md5' in userdata.keys() ) and ( userdata.get('md5') != userdata.get('old_md5') ):
# push the firmware binary
userdata.update({"published": True})
topic = "{base_topic}{device_id}/$implementation/ota/firmware/{md5}".format(**userdata)
print("Publishing new firmware with checksum {}".format(userdata.get('md5')))
client.publish(topic, userdata['firmware'])
def main(broker_host, broker_port, broker_username, broker_password, broker_ca_cert, base_topic, device_id, firmware):
# initialise mqtt client and register callbacks
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
# set username and password if given
if broker_username and broker_password:
client.username_pw_set(broker_username, broker_password)
if broker_ca_cert is not None:
client.tls_set(
ca_certs=broker_ca_cert
)
# save data to be used in the callbacks
client.user_data_set({
"base_topic": base_topic,
"device_id": device_id,
"firmware": firmware
})
# start connection
print("Connecting to mqtt broker {} on port {}".format(broker_host, broker_port))
client.connect(broker_host, broker_port, 60)
# Blocking call that processes network traffic, dispatches callbacks and handles reconnecting.
client.loop_forever()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
description='ota firmware update scirpt for ESP8226 implemenation of the Homie mqtt IoT convention.')
# ensure base topic always ends with a '/'
def base_topic_arg(s):
s = str(s)
if not s.endswith('/'):
s = s + '/'
return s
# specify arguments
parser.add_argument('-l', '--broker-host', type=str, required=False,
help='host name or ip address of the mqtt broker', default="127.0.0.1")
parser.add_argument('-p', '--broker-port', type=int, required=False,
help='port of the mqtt broker', default=1883)
parser.add_argument('-u', '--broker-username', type=str, required=False,
help='username used to authenticate with the mqtt broker')
parser.add_argument('-d', '--broker-password', type=str, required=False,
help='password used to authenticate with the mqtt broker')
parser.add_argument('-t', '--base-topic', type=base_topic_arg, required=False,
help='base topic of the homie devices on the broker', default="homie/")
parser.add_argument('-i', '--device-id', type=str, required=True,
help='homie device id')
parser.add_argument('firmware', type=argparse.FileType('rb'),
help='path to the firmware to be sent to the device')
parser.add_argument("--broker-tls-cacert", default=None, required=False,
help="CA certificate bundle used to validate TLS connections. If set, TLS will be enabled on the broker conncetion"
)
# workaround for http://bugs.python.org/issue9694
parser._optionals.title = "arguments"
# get and validate arguments
args = parser.parse_args()
# read the contents of firmware into buffer
fw_buffer = args.firmware.read()
args.firmware.close()
firmware = bytearray()
firmware.extend(fw_buffer)
# Invoke the business logic
main(args.broker_host, args.broker_port, args.broker_username,
args.broker_password, args.broker_tls_cacert, args.base_topic, args.device_id, firmware)

View File

@@ -1,27 +0,0 @@
#!//bin/bash
if [ $# -ne 3 ]; then
echo "Homie prefex and device index must be specified:"
echo "$0 <mqtt host> <prefix> <device index>"
echo "e.g."
echo "$0 192.168.0.2 test/ MyDeviceId"
exit 1
fi
mqttHost=$1
mqttPrefix=$2
homieId=$3
firmwareFile=../.pio/build/esp32doit-devkit-v1/firmware.bin
if [ ! -f $firmwareFile ]; then
echo "the script $0 must be started in host/ sub directory"
exit 2
fi
mosquitto_pub -h $mqttHost -t "${mqttPrefix}${homieId}/stay/alive/set" -m "1" -r
echo "Waiting ..."
mosquitto_sub -h $mqttHost -t "${mqttPrefix}${homieId}/#" -R -C 1
python ota_updater.py -l $mqttHost -t "$mqttPrefix" -i "$homieId" $firmwareFile
mosquitto_pub -h $mqttHost -t "${mqttPrefix}${homieId}/stay/alive/set" -m "0" -r
exit 0

View File

@@ -1,13 +0,0 @@
#!/bin/bash
echo "Homie device is in AP mode, then the configuration can be uploaded"
if [ ! -f config.json ]; then
echo "Create config file according to :"
echo "https://homieiot.github.io/homie-esp8266/docs/3.0.0/configuration/json-configuration-file/"
exit 2
fi
echo "Check connection to Plug in AP-mode"
ping -c 4 192.168.123.1
curl -X PUT http://192.168.123.1/config --header "Content-Type: application/json" -d @config.json

View File

@@ -1,108 +0,0 @@
/**
* @file ControllerConfiguration.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-05-30
*
* @copyright Copyright (c) 2020
*
* \mainpage Configuration of the controller
* @{
* Describe the used PINs of the controller
*
* @subpage Controller
*
* @subpage Homie
*
* @subpage Configuration
*
* There are several modes in the controller
* \dot
* digraph Operationmode {
* ranksep=.75;
* poweroff [ label="off" ];
* mode1 [ label="Mode 1 - Sensor only", shape=box, width=2 ];
* mode2 [ label="Mode 2 - Wifi enabled", shape=box ];
* mode3 [ label="Mode 3 - Stay alive", shape=box ];
* mode1 -> mode2 [ label="wakeup reason", fontsize=10 ];
* mode1 -> mode2 [ label="Time duration", fontsize=10 ];
* mode2 -> mode3 [ label="Over the Air Update", fontsize=10 ];
* mode3 -> mode2 [ label="Over the Air Finished", fontsize=10 ];
* mode3 -> mode2 [ label="Mqtt Command", fontsize=10 ];
* mode2 -> mode3 [ label="Mqtt Command", fontsize=10 ];
* poweroff -> mode1 [ label="deep sleep wakeup", fontsize=10 ];
* mode1 -> poweroff [ label="enter deep sleep", fontsize=10 ];
* mode2 -> poweroff [ label="Mqtt queue empty", fontsize=10 ];
* }
* \enddot
*
* Before entering Deep sleep the controller is configured with an wakeup time.
*
* @}
*/
#ifndef CONTROLLER_CONFIG_H
#define CONTROLLER_CONFIG_H
/** \addtogroup Configuration
* @{
*/
#define FIRMWARE_VERSION "1.1.0"
#define ADC_TO_VOLT(adc) ((adc) * 3.3 ) / 4095)
#define ADC_TO_VOLT_WITH_MULTI(adc, multi) (((adc)*3.3 * (multi)) / 4095)
#define MOIST_SENSOR_MAX_ADC (85 * 4095 / 100)
#define MOIST_SENSOR_MIN_ADC (25 * 4095 / 100)
#define SOLAR_VOLT_FACTOR 2
#define BATTSENSOR_INDEX_SOLAR 0
#define BATTSENSOR_INDEX_BATTERY 1
#define MS_TO_S 1000
#define SENSOR_PLANT0 32 /**< GPIO 32 (ADC1) */
#define SENSOR_PLANT1 33 /**< GPIO 33 (ADC1) */
#define SENSOR_PLANT2 25 /**< GPIO 25 (ADC2) */
#define SENSOR_PLANT3 26 /**< GPIO 26 (ADC2) */
#define SENSOR_PLANT4 27 /**< GPIO 27 (ADC2) */
#define SENSOR_PLANT5 39 /**< SENSOR_VIN */
#define SENSOR_PLANT6 36 /**< SENSOR_VP */
#define OUTPUT_PUMP0 17 /**< GPIO 17 */
#define OUTPUT_PUMP1 5 /**< GPIO 5 */
#define OUTPUT_PUMP2 18 /**< GPIO 18 */
#define OUTPUT_PUMP3 19 /**< GPIO 19 */
#define OUTPUT_PUMP4 21 /**< GPIO 21 */
#define OUTPUT_PUMP5 22 /**< GPIO 22 */
#define OUTPUT_PUMP6 23 /**< GPIO 23 */
#define OUTPUT_SENSOR 16 /**< GPIO 16 - Enable Sensors */
#define OUTPUT_PUMP 13 /**< GPIO 13 - Enable Pumps */
#define SENSOR_DS18B20 2 /**< GPIO 2 - Temperatur sensor */
#define BUTTON 0 /**< GPIO 0 - Fix button of NodeMCU */
#define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */
#define MAX_PLANTS 7
#define MINIMUM_LIPO_VOLT 3.2f /**< Minimum voltage of the Lipo, that must be present */
#define NO_LIPO_VOLT 2.0f /**< No Lipo connected */
#define MINIMUM_SOLAR_VOLT 4.0f /**< Minimum voltage of the sun, to detect daylight */
#define SOLAR_CHARGE_MIN_VOLTAGE 7 /**< Sun is rising (morning detected) */
#define SOLAR_CHARGE_MAX_VOLTAGE 9 /**< Sun is shining (noon) */
#define VOLT_MAX_BATT 4.2f
#define MAX_CONFIG_SETTING_ITEMS 50 /**< Parameter, that can be configured in Homie */
#define PANIK_MODE_DEEPSLEEP (60 * 60 * 5U) /**< 5 hours in usecond */
#define PANIK_MODE_DEEPSLEEP_US (PANIK_MODE_DEEPSLEEP * 1000 * 1000)
#define LIPO_MAX_TEMPERATUR 85
#define LIPO_MAX_TEMPERATUR_DIFF 10
#define TEMPERATURE_DELTA_TRIGGER_IN_C 1.0f
#define MOIST_DELTA_TRIGGER_ADC 10
#define SOLAR_DELTA_VOLT_ADC 3
#define LIPO_DELTA_VOLT_ADC 0.2 /**< trigger for lipo voltage */
#define TEMPERATUR_TIMEOUT 3000 /**< 3 Seconds timeout for the temperatur sensors */
#define TEMP_SENSOR_MEASURE_SERIES 5
/* @} */
#endif

View File

@@ -1,119 +0,0 @@
/*
* DS2438.h
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#ifndef DS2438_h
#define DS2438_h
#include <Arduino.h>
#include <OneWire.h>
#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4
#define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4e
#define DS2438_COPY_SCRATCHPAD_COMMAND 0x48
#define DS2438_READ_SCRATCHPAD_COMMAND 0xbe
#define DS2438_RECALL_MEMORY_COMMAND 0xb8
#define PAGE_MIN 0
#define PAGE_MAX 7
#define DS2438_CHA 0
#define DS2438_CHB 1
#define DS2438_MODE_CHA 0x01
#define DS2438_MODE_CHB 0x02
#define DS2438_MODE_TEMPERATURE 0x04
#define DS2438_TEMPERATURE_DELAY 10
#define DS2438_VOLTAGE_CONVERSION_DELAY 8
#define DEFAULT_PAGE0(var) uint8_t var[8] { \
0b00001011 /* X, ADB=0, NVB=0, TB=0, AD=1, EE=0, CA=1, IAD=1 */, \
0, /* Temperatur */ \
0, /* Temperatur */ \
0, /* Voltage */ \
0, /* Voltage */ \
0, /* Current */ \
0, /* Current */ \
0 /* Threashold */ \
}
typedef struct PageOne {
uint8_t eleapsedTimerByte0; /**< LSB of timestamp */
uint8_t eleapsedTimerByte1;
uint8_t eleapsedTimerByte2;
uint8_t eleapsedTimerByte3; /**< MSB of timestamp */
uint8_t ICA; /**< Integrated Current Accumulator (current flowing into and out of the battery) */
uint8_t offsetRegisterByte0; /**< Offset for ADC calibdation */
uint8_t offsetRegisterByte1; /**< Offset for ADC calibdation */
uint8_t reserved;
} PageOne_t;
typedef struct PageSeven {
uint8_t userByte0;
uint8_t userByte1;
uint8_t userByte2;
uint8_t userByte3;
uint8_t CCA0; /**< Charging Current Accumulator (CCA) */
uint8_t CCA1; /**< Charging Current Accumulator (CCA) */
uint8_t DCA0; /**< Discharge Current Accumulator (DCA) */
uint8_t DCA1; /**< Discharge Current Accumulator (DCA) */
} PageSeven_t;
typedef uint8_t DeviceAddress[8];
class DS2438 {
public:
DS2438(OneWire *ow, float currentShunt);
DS2438(OneWire *ow, uint8_t *address);
void begin();
void update();
double getTemperature();
float getVoltage(int channel=DS2438_CHA);
float getCurrent();
long getICA();
long getCCA();
long getDCA();
float getAh();
boolean isError();
boolean isFound();
private:
bool validAddress(const uint8_t*);
bool validFamily(const uint8_t* deviceAddress);
bool deviceFound = false;
OneWire *_ow;
DeviceAddress _address;
uint8_t _mode;
double _temperature;
float _voltageA;
float _voltageB;
float _current;
float _currentShunt;
long _CCA;
long _DCA;
long _ICA;
boolean _error;
boolean startConversion(int channel, boolean doTemperature);
boolean selectChannel(int channel);
void writePage(int page, uint8_t *data);
boolean readPage(int page, uint8_t *data);
};
#endif

View File

@@ -1,104 +0,0 @@
/** \addtogroup Homie
* @{
*
* @file HomieConfiguration.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-10-16
*
* @copyright Copyright (c) 2020
* All Settings, configurable in Homie
*
*/
#ifndef HOMIE_PLANT_CONFIG_H
#define HOMIE_PLANT_CONFIG_H
#include "HomieTypes.h"
#define MAX_PLANTS 7
/**
* @name Attributes
* generated Information
* @{
**/
#define NUMBER_TYPE "number"
#define TEMPERATUR_SENSOR_LIPO "lipo"
#define TEMPERATUR_SENSOR_WATER "water"
#define TEMPERATUR_SENSOR_OUTSIDE "temp"
#define TEMPERATUR_SENSOR_CHIP "chip"
#define TEMPERATURE_NAME "Temperature"
#define TEMPERATURE_UNIT "°C"
HomieNode plant0("plant0", "Plant 0", "Plant"); /**< dynamic Homie information for first plant */
HomieNode plant1("plant1", "Plant 1", "Plant"); /**< dynamic Homie information for second plant */
HomieNode plant2("plant2", "Plant 2", "Plant"); /**< dynamic Homie information for first plant */
HomieNode plant3("plant3", "Plant 3", "Plant"); /**< dynamic Homie information for first plant */
HomieNode plant4("plant4", "Plant 4", "Plant"); /**< dynamic Homie information for first plant */
HomieNode plant5("plant5", "Plant 5", "Plant"); /**< dynamic Homie information for first plant */
HomieNode plant6("plant6", "Plant 6", "Plant"); /**< dynamic Homie information for first plant */
HomieNode sensorLipo("lipo", "Battery Status", "Lipo");
HomieNode sensorSolar("solar", "Solar Status", "Solarpanel");
HomieNode sensorWater("water", "WaterSensor", "Water");
HomieNode sensorTemp("temperature", "Temperature", "temperature");
HomieNode startupReason("startupReason", "startupReason", "startupReason");
HomieNode stayAlive("stay", "alive", "alive"); /**< Necessary for Mqtt Active Command */
/* @} */
/**
* @name Settings
* General settings for the controller
* @{
*/
HomieSetting<long> maxTimeBetweenMQTTUpdates("mqttSleep", "time in seconds to start into mode2");
HomieSetting<long> deepSleepTime("deepsleep", "time in seconds to sleep (0 deactivats it)");
HomieSetting<long> deepSleepNightTime("nightsleep", "time in seconds to sleep (0 uses same setting: deepsleep at night, too)");
HomieSetting<long> wateringDeepSleep("pumpdeepsleep", "time seconds to sleep, while a pump is running");
HomieSetting<long> waterLevelMax("watermaxlevel", "distance (mm) at maximum water level");
HomieSetting<long> waterLevelMin("waterminlevel", "distance (mm) at minimum water level (pumps still covered)");
HomieSetting<long> waterLevelWarn("waterlevelwarn", "warn (mm) if below this water level %");
HomieSetting<long> waterLevelVol("waterVolume", "(ml) between minimum and maximum");
HomieSetting<long> lipoSensorIndex("lipoTempIndex", "index onwire bus for lipo temperature sensor");
HomieSetting<long> waterSensorIndex("waterTempIndex", "index onwire bus for water temperature sensor");
HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as default)");
/**
*@}
*/
/**
* @name Plant specific ones
* Setting for one plant
* @{
**/
#define GENERATE_PLANT(plant, strplant) \
HomieSetting<long> mSensorDry##plant = HomieSetting<long>("moistdry" strplant, "Plant " strplant "- Moist sensor dry threshold"); \
HomieSetting<long> mPumpAllowedHourRangeStart##plant = HomieSetting<long>("rangehourstart" strplant, "Plant" strplant " - Range pump allowed hour start (0-23)"); \
HomieSetting<long> mPumpAllowedHourRangeEnd##plant = HomieSetting<long>("rangehourend" strplant, "Plant" strplant " - Range pump allowed hour end (0-23)"); \
HomieSetting<bool> mPumpOnlyWhenLowLight##plant = HomieSetting<bool>("onlyWhenLowLightZ" strplant, "Plant" strplant " - Enable the Pump only, when there is light but not enought to charge battery"); \
HomieSetting<long> mPumpCooldownInHours##plant = HomieSetting<long>("cooldownpump" strplant, "Plant" strplant " - How long to wait until the pump is activated again (minutes)"); \
PlantSettings_t mSetting##plant = {&mSensorDry##plant, &mPumpAllowedHourRangeStart##plant, &mPumpAllowedHourRangeEnd##plant, &mPumpOnlyWhenLowLight##plant, &mPumpCooldownInHours##plant}; \
/**< Generate all settings for one plant \
* \
* Feature to start pumping only at morning: @link{SOLAR_CHARGE_MIN_VOLTAGE} and @link{SOLAR_CHARGE_MAX_VOLTAGE} \
*/
/**
* @}
*/
GENERATE_PLANT(0, "0"); /**< Homie settings for first plant */
GENERATE_PLANT(1, "1"); /**< Homie settings for second Plant */
GENERATE_PLANT(2, "2"); /**< Homie settings for third plant */
GENERATE_PLANT(3, "3"); /**< Homie settings for fourth plant */
GENERATE_PLANT(4, "4"); /**< Homie settings for fifth plant */
GENERATE_PLANT(5, "5"); /**< Homie settings for sixth plant */
GENERATE_PLANT(6, "6"); /**< Homie settings for seventh plant */
#endif /* HOMIE_PLANT_CONFIG_H @} */

View File

@@ -1,28 +0,0 @@
/**
* @file HomieTypes.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-10-16
*
* @copyright Copyright (c) 2020
* All Settings, configurable in Homie
*/
#ifndef HOMIE_PLANT_CFG_CONFIG_H
#define HOMIE_PLANT_CFG_CONFIG_H
#include <Homie.h>
#define DEACTIVATED_PLANT 5000
#define MISSING_SENSOR 5001
typedef struct PlantSettings_t
{
HomieSetting<long> *pSensorDry;
HomieSetting<long> *pPumpAllowedHourRangeStart;
HomieSetting<long> *pPumpAllowedHourRangeEnd;
HomieSetting<bool> *pPumpOnlyWhenLowLight;
HomieSetting<long> *pPumpCooldownInHours;
} PlantSettings_t;
#endif

View File

@@ -1,126 +0,0 @@
/**
* @file PlantCtrl.h
* @author your name (you@domain.com)
* @brief Abstraction to handle the Sensors
* @version 0.1
* @date 2020-05-27
*
* @copyright Copyright (c) 2020
*
*/
#ifndef PLANT_CTRL_H
#define PLANT_CTRL_H
#include "HomieTypes.h"
#include "RunningMedian.h"
class Plant
{
private:
RunningMedian moistureRaw = RunningMedian(5);
HomieNode *mPlant = NULL;
int mPinSensor = 0; /**< Pin of the moist sensor */
int mPinPump = 0; /**< Pin of the pump */
bool mConnected = false;
int mPlantId = -1;
public:
PlantSettings_t *mSetting;
/**
* @brief Construct a new Plant object
*
* @param pinSensor Pin of the Sensor to use to measure moist
* @param pinPump Pin of the Pump to use
*/
Plant(int pinSensor, int pinPump,
int plantId,
HomieNode *plant,
PlantSettings_t *setting);
void postMQTTconnection(void);
void advertise(void);
/**
* @brief Measure a new analog moister value
*
*/
void addSenseValue(void);
void deactivatePump(void);
void activatePump(void);
/**
* @brief Check if a plant is too dry and needs some water.
*
* @return true
* @return false
*/
bool isPumpRequired()
{
bool isDry = getCurrentMoisture() > getSettingsMoisture();
bool isActive = isPumpTriggerActive();
return isDry && isActive;
}
bool isPumpTriggerActive()
{
return this->mSetting->pSensorDry->get() != DEACTIVATED_PLANT;
}
float getCurrentMoisture()
{
if(moistureRaw.getCount()==0){
return MISSING_SENSOR;
}
return this->moistureRaw.getMedian();
}
long getSettingsMoisture()
{
if (this->mSetting->pSensorDry != NULL)
{
return this->mSetting->pSensorDry->get();
}
else
{
return DEACTIVATED_PLANT;
}
}
HomieInternals::SendingPromise &setProperty(const String &property) const
{
return mPlant->setProperty(property);
}
bool switchHandler(const HomieRange &range, const String &value);
void init(void);
/** @fn bool isInCooldown(long sinceLastActivation)
* @brief determine, if the plant was recently casted
* @param sinceLastActivation timestamp of last time
*/
bool isInCooldown(long sinceLastActivation)
{
/* if the time difference is greater than one month, we know these are initial values */
if (sinceLastActivation > (60 * 60 * 24 * 30))
{
return false;
}
return (getCooldownInSeconds() > sinceLastActivation);
}
long getCooldownInSeconds(){
return this->mSetting->pPumpCooldownInHours->get()*60*60;
}
bool isAllowedOnlyAtLowLight(void)
{
return this->mSetting->pPumpOnlyWhenLowLight->get();
}
};
#endif

View File

@@ -1,39 +0,0 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -1,75 +0,0 @@
#pragma once
//
// FILE: RunningMedian.h
// AUTHOR: Rob dot Tillaart at gmail dot com
// PURPOSE: RunningMedian library for Arduino
// VERSION: 0.2.1
// URL: https://github.com/RobTillaart/RunningMedian
// URL: http://arduino.cc/playground/Main/RunningMedian
// HISTORY: See RunningMedian.cpp
//
#include "Arduino.h"
#define RUNNING_MEDIAN_VERSION "0.2.1"
// prepare for dynamic version
// not tested ==> use at own risk :)
// #define RUNNING_MEDIAN_USE_MALLOC
// should at least be 5 to be practical,
// odd sizes results in a 'real' middle element and will be a bit faster.
// even sizes takes the average of the two middle elements as median
#define MEDIAN_MIN_SIZE 5
#define MEDIAN_MAX_SIZE 19
class RunningMedian
{
public:
// # elements in the internal buffer
explicit RunningMedian(const uint8_t size);
~RunningMedian();
// resets internal buffer and var
void clear();
// adds a new value to internal buffer, optionally replacing the oldest element.
void add(const float value);
// returns the median == middle element
float getMedian();
// returns average of the values in the internal buffer
float getAverage();
// returns average of the middle nMedian values, removes noise from outliers
float getAverage(uint8_t nMedian);
float getHighest() { return getSortedElement(_cnt - 1); };
float getLowest() { return getSortedElement(0); };
// get n'th element from the values in time order
float getElement(const uint8_t n);
// get n'th element from the values in size order
float getSortedElement(const uint8_t n);
// predict the max change of median after n additions
float predict(const uint8_t n);
uint8_t getSize() { return _size; };
// returns current used elements, getCount() <= getSize()
uint8_t getCount() { return _cnt; };
protected:
boolean _sorted;
uint8_t _size;
uint8_t _cnt;
uint8_t _idx;
#ifdef RUNNING_MEDIAN_USE_MALLOC
float *_ar;
uint8_t *_p;
#else
float _ar[MEDIAN_MAX_SIZE];
uint8_t _p[MEDIAN_MAX_SIZE];
#endif
void sort();
};
// END OF FILE

View File

@@ -1,27 +0,0 @@
/**
* @file WakeReason.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-11-28
*
* @copyright Copyright (c) 2020
*
*/
#ifndef WAKEUP_REASON_H
#define WAKEUP_REASON_H
#define WAKEUP_REASON_UNDEFINED 0
#define WAKEUP_REASON_TEMP1_CHANGE 2
#define WAKEUP_REASON_TEMP2_CHANGE 3
#define WAKEUP_REASON_BATTERY_CHANGE 4
#define WAKEUP_REASON_SOLAR_CHANGE 5
#define WAKEUP_REASON_RTC_MISSING 6
#define WAKEUP_REASON_TIME_UNSET 7
#define WAKEUP_REASON_MODE2_WAKEUP_TIMER 8
#define WAKEUP_REASON_MOIST_CHANGE 20 /**< <code>20-26</code> for plant0 to plant9 */
#define WAKEUP_REASON_PLANT_DRY 30 /**< <code>30-36</code> for plant0 to plant9 */
#endif

View File

@@ -1,46 +0,0 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@@ -1,26 +0,0 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
board_build.partitions = defaultWithSmallerSpiffs.csv
; the latest development brankitchen-lightch (convention V3.0.x)
lib_deps = ArduinoJson@6.16.1
https://github.com/homieiot/homie-esp8266.git#v3.0
OneWire
DallasTemperature
[platformio]
extra_configs = custom_platformio.ini

View File

@@ -1,255 +0,0 @@
/*
* DS2438.cpp
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#include "DS2438.h"
// DSROM FIELDS
#define DSROM_FAMILY 0
#define DSROM_CRC 7
#define DS2438MODEL 0x26
DS2438::DS2438(OneWire *ow, float currentShunt = 1.0f) {
_ow = ow;
_currentShunt = currentShunt;
};
void DS2438::begin(){
DeviceAddress searchDeviceAddress;
_ow->reset_search();
memset(searchDeviceAddress,0, 8);
_temperature = 0;
_voltageA = 0.0;
_voltageB = 0.0;
_error = true;
_mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE);
deviceFound = false; // Reset the number of devices when we enumerate wire devices
while (_ow->search(searchDeviceAddress)) {
if (validAddress(searchDeviceAddress)) {
if (validFamily(searchDeviceAddress)) {
memcpy(_address,searchDeviceAddress,8);
DEFAULT_PAGE0(defaultConfig);
writePage(0, defaultConfig);
deviceFound = true;
}
}
}
}
bool DS2438::isFound(){
return deviceFound;
}
bool DS2438::validAddress(const uint8_t* deviceAddress) {
return (_ow->crc8(deviceAddress, 7) == deviceAddress[DSROM_CRC]);
}
bool DS2438::validFamily(const uint8_t* deviceAddress) {
switch (deviceAddress[DSROM_FAMILY]) {
case DS2438MODEL:
return true;
default:
return false;
}
}
void DS2438::update() {
uint8_t data[9];
_error = true;
if(!isFound()){
return;
}
if (_mode & DS2438_MODE_CHA || _mode == DS2438_MODE_TEMPERATURE) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE;
if (!startConversion(DS2438_CHA, doTemperature)) {
Serial.println("Error starting temp conversion ds2438 channel a");
return;
}
if (!readPage(0, data)){
Serial.println("Error reading zero page ds2438 channel a");
return;
}
if (doTemperature) {
_temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125;
}
if (_mode & DS2438_MODE_CHA) {
_voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
}
if (_mode & DS2438_MODE_CHB) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE && !(_mode & DS2438_MODE_CHA);
if (!startConversion(DS2438_CHB, doTemperature)) {
Serial.println("Error starting temp conversion channel b ds2438");
return;
}
if (!readPage(0, data)){
Serial.println("Error reading zero page ds2438 channel b");
return;
}
if (doTemperature) {
int16_t upperByte = ((int16_t)data[2]) << 8;
int16_t lowerByte = data[1] >> 3;
int16_t fullByte = (upperByte | lowerByte);
_temperature = ((double)fullByte) * 0.03125;
}
_voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
int16_t upperByte = ((int16_t)data[6]) << 8;
int16_t lowerByte = data[5];
int16_t fullByte = (int16_t)(upperByte | lowerByte);
float fullByteb = fullByte;
_current = (fullByteb) / ((4096.0f * _currentShunt));
_error = false;
if (readPage(1, data)){
PageOne_t *pOne = (PageOne_t *) data;
_ICA = pOne->ICA;
}
if (readPage(7, data)){
PageSeven_t *pSeven = (PageSeven_t *) data;
_CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8;
_DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8;
}
}
double DS2438::getTemperature() {
return _temperature;
}
float DS2438::getAh(){
return _ICA / (2048.0f * _currentShunt);
}
long DS2438::getICA(){
return _ICA;
}
long DS2438::getDCA(){
return _DCA;
}
long DS2438::getCCA(){
return _CCA;
}
float DS2438::getVoltage(int channel) {
if (channel == DS2438_CHA) {
return _voltageA;
} else if (channel == DS2438_CHB) {
return _voltageB;
} else {
return 0.0;
}
}
float DS2438::getCurrent() {
return _current;
}
boolean DS2438::isError() {
return _error;
}
boolean DS2438::startConversion(int channel, boolean doTemperature) {
if(!isFound()){
return false;
}
if (!selectChannel(channel)){
return false;
}
_ow->reset();
_ow->select(_address);
if (doTemperature) {
_ow->write(DS2438_TEMPERATURE_CONVERSION_COMMAND, 0);
delay(DS2438_TEMPERATURE_DELAY);
_ow->reset();
_ow->select(_address);
}
_ow->write(DS2438_VOLTAGE_CONVERSION_COMMAND, 0);
delay(DS2438_VOLTAGE_CONVERSION_DELAY);
return true;
}
boolean DS2438::selectChannel(int channel) {
if(!isFound()){
return false;
}
uint8_t data[9];
if (readPage(0, data)) {
if (channel == DS2438_CHB){
data[0] = data[0] | 0x08;
}
else {
data[0] = data[0] & 0xf7;
}
writePage(0, data);
return true;
}
Serial.println("Could not read page zero data");
return false;
}
void DS2438::writePage(int page, uint8_t *data) {
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return;
}
for (int i = 0; i < 8; i++){
_ow->write(data[i], 0);
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
}
boolean DS2438::readPage(int page, uint8_t *data) {
//TODO if all data is 0 0 is a valid crc, but most likly not as intended
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_RECALL_MEMORY_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return false;
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
for (int i = 0; i < 9; i++){
data[i] = _ow->read();
}
return _ow->crc8(data, 8) == data[8];
}

View File

@@ -1,115 +0,0 @@
/**
* @file PlantCtrl.cpp
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-05-27
*
* @copyright Copyright (c) 2020
*
*/
#include "PlantCtrl.h"
#include "ControllerConfiguration.h"
Plant::Plant(int pinSensor, int pinPump, int plantId, HomieNode *plant, PlantSettings_t *setting)
{
this->mPinSensor = pinSensor;
this->mPinPump = pinPump;
this->mPlant = plant;
this->mSetting = setting;
this->mPlantId = plantId;
}
void Plant::init(void)
{
/* Initialize Home Settings validator */
this->mSetting->pSensorDry->setDefaultValue(DEACTIVATED_PLANT);
this->mSetting->pSensorDry->setValidator([](long candidate) {
return (((candidate >= 0) && (candidate <= 4095)) || candidate == DEACTIVATED_PLANT);
});
this->mSetting->pPumpAllowedHourRangeStart->setDefaultValue(8); // start at 8:00
this->mSetting->pPumpAllowedHourRangeStart->setValidator([](long candidate) {
return ((candidate >= 0) && (candidate <= 23));
});
this->mSetting->pPumpAllowedHourRangeEnd->setDefaultValue(20); // stop pumps at 20:00
this->mSetting->pPumpAllowedHourRangeEnd->setValidator([](long candidate) {
return ((candidate >= 0) && (candidate <= 23));
});
this->mSetting->pPumpOnlyWhenLowLight->setDefaultValue(true);
this->mSetting->pPumpCooldownInHours->setDefaultValue(20); // minutes
this->mSetting->pPumpCooldownInHours->setValidator([](long candidate) {
return ((candidate >= 0) && (candidate <= 1024));
});
/* Initialize Hardware */
pinMode(this->mPinPump, OUTPUT);
pinMode(this->mPinSensor, ANALOG);
digitalWrite(this->mPinPump, LOW);
}
void Plant::addSenseValue(void)
{
int raw = analogRead(this->mPinSensor);
if(raw < MOIST_SENSOR_MAX_ADC && raw > MOIST_SENSOR_MIN_ADC){
this->moistureRaw.add(raw);
} else {
int plantId = this->mPlantId;
Serial << "ignoring sensor " << plantId << " value due to being strange " << raw << endl;
}
}
void Plant::postMQTTconnection(void)
{
const String OFF = String("OFF");
this->mConnected = true;
this->mPlant->setProperty("switch").send(OFF);
}
void Plant::deactivatePump(void)
{
digitalWrite(this->mPinPump, LOW);
if (this->mConnected)
{
const String OFF = String("OFF");
this->mPlant->setProperty("switch").send(OFF);
}
}
void Plant::activatePump(void)
{
digitalWrite(this->mPinPump, HIGH);
if (this->mConnected)
{
const String OFF = String("ON");
this->mPlant->setProperty("switch").send(OFF);
}
}
void Plant::advertise(void)
{
// Advertise topics
this->mPlant->advertise("switch").setName("Pump 1").setDatatype("boolean");
//FIXME add .settable(this->switchHandler)
this->mPlant->advertise("moist").setName("Percent").setDatatype("number").setUnit("%");
this->mPlant->advertise("moistraw").setName("adc").setDatatype("number").setUnit("3.3/4096V");
}
/* FIXME
bool Plant::switchHandler(const HomieRange& range, const String& value) {
if (range.isRange) return false; // only one switch is present
if ((value.equals("ON")) || (value.equals("On")) || (value.equals("on")) || (value.equals("true"))) {
this->activatePump();
return true;
} else if ((value.equals("OFF")) || (value.equals("Off")) || (value.equals("off")) || (value.equals("false")) ) {
this->deactivatePump();
return true;
} else {
return false;
}
}
}
*/

View File

@@ -1,183 +0,0 @@
//
// FILE: RunningMedian.cpp
// AUTHOR: Rob.Tillaart at gmail.com
// VERSION: 0.2.1
// PURPOSE: RunningMedian library for Arduino
//
// HISTORY:
// 0.1.00 - 2011-02-16 initial version
// 0.1.01 - 2011-02-22 added remarks from CodingBadly
// 0.1.02 - 2012-03-15 added
// 0.1.03 - 2013-09-30 added _sorted flag, minor refactor
// 0.1.04 - 2013-10-17 added getAverage(uint8_t) - kudo's to Sembazuru
// 0.1.05 - 2013-10-18 fixed bug in sort; removes default constructor; dynamic memory
// 0.1.06 - 2013-10-19 faster sort, dynamic arrays, replaced sorted float array with indirection array
// 0.1.07 - 2013-10-19 add correct median if _cnt is even.
// 0.1.08 - 2013-10-20 add getElement(), add getSottedElement() add predict()
// 0.1.09 - 2014-11-25 float to double (support ARM)
// 0.1.10 - 2015-03-07 fix clear
// 0.1.11 - 2015-03-29 undo 0.1.10 fix clear
// 0.1.12 - 2015-07-12 refactor constructor + const
// 0.1.13 - 2015-10-30 fix getElement(n) - kudos to Gdunge
// 0.1.14 - 2017-07-26 revert double to float - issue #33
// 0.1.15 - 2018-08-24 make runningMedian Configurable #110
// 0.2.0 2020-04-16 refactor.
// 0.2.1 2020-06-19 fix library.json
#include "RunningMedian.h"
RunningMedian::RunningMedian(const uint8_t size)
{
_size = constrain(size, MEDIAN_MIN_SIZE, MEDIAN_MAX_SIZE);
#ifdef RUNNING_MEDIAN_USE_MALLOC
_ar = (float *)malloc(_size * sizeof(float));
_p = (uint8_t *)malloc(_size * sizeof(uint8_t));
#endif
clear();
}
RunningMedian::~RunningMedian()
{
#ifdef RUNNING_MEDIAN_USE_MALLOC
free(_ar);
free(_p);
#endif
}
// resets all counters
void RunningMedian::clear()
{
_cnt = 0;
_idx = 0;
_sorted = false;
for (uint8_t i = 0; i < _size; i++)
{
_p[i] = i;
}
}
// adds a new value to the data-set
// or overwrites the oldest if full.
void RunningMedian::add(float value)
{
_ar[_idx++] = value;
if (_idx >= _size)
_idx = 0; // wrap around
if (_cnt < _size)
_cnt++;
_sorted = false;
}
float RunningMedian::getMedian()
{
if (_cnt == 0)
return NAN;
if (_sorted == false)
sort();
if (_cnt & 0x01) // is it odd sized?
{
return _ar[_p[_cnt / 2]];
}
return (_ar[_p[_cnt / 2]] + _ar[_p[_cnt / 2 - 1]]) / 2;
}
float RunningMedian::getAverage()
{
if (_cnt == 0)
return NAN;
float sum = 0;
for (uint8_t i = 0; i < _cnt; i++)
{
sum += _ar[i];
}
return sum / _cnt;
}
float RunningMedian::getAverage(uint8_t nMedians)
{
if ((_cnt == 0) || (nMedians == 0))
return NAN;
if (_cnt < nMedians)
nMedians = _cnt; // when filling the array for first time
uint8_t start = ((_cnt - nMedians) / 2);
uint8_t stop = start + nMedians;
if (_sorted == false)
sort();
float sum = 0;
for (uint8_t i = start; i < stop; i++)
{
sum += _ar[_p[i]];
}
return sum / nMedians;
}
float RunningMedian::getElement(const uint8_t n)
{
if ((_cnt == 0) || (n >= _cnt))
return NAN;
uint8_t pos = _idx + n;
if (pos >= _cnt) // faster than %
{
pos -= _cnt;
}
return _ar[pos];
}
float RunningMedian::getSortedElement(const uint8_t n)
{
if ((_cnt == 0) || (n >= _cnt))
return NAN;
if (_sorted == false)
sort();
return _ar[_p[n]];
}
// n can be max <= half the (filled) size
float RunningMedian::predict(const uint8_t n)
{
if ((_cnt == 0) || (n >= _cnt / 2))
return NAN;
float med = getMedian(); // takes care of sorting !
if (_cnt & 0x01)
{
return max(med - _ar[_p[_cnt / 2 - n]], _ar[_p[_cnt / 2 + n]] - med);
}
float f1 = (_ar[_p[_cnt / 2 - n]] + _ar[_p[_cnt / 2 - n - 1]]) / 2;
float f2 = (_ar[_p[_cnt / 2 + n]] + _ar[_p[_cnt / 2 + n - 1]]) / 2;
return max(med - f1, f2 - med) / 2;
}
void RunningMedian::sort()
{
// bubble sort with flag
for (uint8_t i = 0; i < _cnt - 1; i++)
{
bool flag = true;
for (uint8_t j = 1; j < _cnt - i; j++)
{
if (_ar[_p[j - 1]] > _ar[_p[j]])
{
uint8_t t = _p[j - 1];
_p[j - 1] = _p[j];
_p[j] = t;
flag = false;
}
}
if (flag)
break;
}
_sorted = true;
}
// -- END OF FILE --

View File

@@ -1,630 +0,0 @@
/** \addtogroup Controller
* @{
*
* @file main.cpp
* @author Ollo
* @brief PlantControl
* @version 0.1
* @date 2020-05-01
*
* @copyright Copyright (c) 2020
*/
/******************************************************************************
* INCLUDES
******************************************************************************/
#include "PlantCtrl.h"
#include "ControllerConfiguration.h"
#include "HomieConfiguration.h"
#include "DallasTemperature.h"
#include <Homie.h>
#include "time.h"
#include "esp_sleep.h"
#include "RunningMedian.h"
#include "WakeReason.h"
#include <stdint.h>
#include <math.h>
#include <OneWire.h>
#include "DS2438.h"
/******************************************************************************
* DEFINES
******************************************************************************/
#define AMOUNT_SENOR_QUERYS 8
#define MAX_TANK_DEPTH 1000
/******************************************************************************
* FUNCTION PROTOTYPES
******************************************************************************/
int determineNextPump();
//void setLastActivationForPump(int pumpId, long time);
int readTemp();
/******************************************************************************
* NON VOLATILE VARIABLES in DEEP SLEEP
******************************************************************************/
//only relevant if mode2 did start pumping before
RTC_DATA_ATTR int lastPumpRunning = 0;
RTC_DATA_ATTR long lastWaterValue = 0;
RTC_DATA_ATTR int gBootCount = 0;
//FIXME use -1 and configure properly
RTC_DATA_ATTR int rtcLipoTempIndex = 0;
RTC_DATA_ATTR int rtcWaterTempIndex = -1;
/******************************************************************************
* LOCAL VARIABLES
******************************************************************************/
bool volatile mode3Active = false; /**< Controller must not sleep */
bool volatile mDeepsleep = false;
int readCounter = 0;
bool mConfigured = false;
long nextBlink = 0; /**< Time needed in main loop to support expected blink code */
RunningMedian waterRawSensor = RunningMedian(5);
float mTempLipo = 0.0f;
float mTempWater = 0.0f;
float mBatteryVoltage = 0.0f;
float mSolarVoltage = 0.0f;
float mChipTemp = 0.0f;
/*************************** Hardware abstraction *****************************/
OneWire oneWire(SENSOR_DS18B20);
DallasTemperature sensors(&oneWire);
DS2438 battery(&oneWire, 0.1f);
Plant mPlants[MAX_PLANTS] = {
Plant(SENSOR_PLANT0, OUTPUT_PUMP0, 0, &plant0, &mSetting0),
Plant(SENSOR_PLANT1, OUTPUT_PUMP1, 1, &plant1, &mSetting1),
Plant(SENSOR_PLANT2, OUTPUT_PUMP2, 2, &plant2, &mSetting2),
Plant(SENSOR_PLANT3, OUTPUT_PUMP3, 3, &plant3, &mSetting3),
Plant(SENSOR_PLANT4, OUTPUT_PUMP4, 4, &plant4, &mSetting4),
Plant(SENSOR_PLANT5, OUTPUT_PUMP5, 5, &plant5, &mSetting5),
Plant(SENSOR_PLANT6, OUTPUT_PUMP6, 6, &plant6, &mSetting6)};
/******************************************************************************
* LOCAL FUNCTIONS
******************************************************************************/
long getCurrentTime()
{
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
return tv_now.tv_sec;
}
void espDeepSleepFor(long seconds, bool activatePump = false)
{
if (mode3Active)
{
Serial << "abort deepsleep, mode3Active" << endl;
return;
}
for (int i = 0; i < 10; i++)
{
long cTime = getCurrentTime();
if (cTime < 100000)
{
Serial << "Wait for ntp" << endl;
delay(100);
}
else
{
break;
}
}
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_ON);
if (activatePump)
{
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
gpio_deep_sleep_hold_en();
gpio_hold_en(GPIO_NUM_13); //pump pwr
}
else
{
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
gpio_hold_dis(GPIO_NUM_13); //pump pwr
gpio_deep_sleep_hold_dis();
digitalWrite(OUTPUT_PUMP, LOW);
digitalWrite(OUTPUT_SENSOR, LOW);
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].deactivatePump();
}
}
//gpio_hold_en(GPIO_NUM_23); //p0
//FIXME fix for outher outputs
Serial.print("Trying to sleep for ");
Serial.print(seconds);
Serial.println(" seconds");
esp_sleep_enable_timer_wakeup((seconds * 1000U * 1000U));
mDeepsleep = true;
}
void mode2MQTT()
{
digitalWrite(OUTPUT_PUMP, LOW);
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].deactivatePump();
}
if (lastPumpRunning != -1)
{
//long waterDiff = waterRawSensor.getAverage() - lastWaterValue;
//TODO attribute used water in ml to plantid
}
for (int i = 0; i < MAX_PLANTS; i++)
{
long raw = mPlants[i].getCurrentMoisture();
long pct = 100 - map(raw, MOIST_SENSOR_MIN_ADC, MOIST_SENSOR_MAX_ADC, 0, 100);
if (raw == MISSING_SENSOR)
{
pct = 0;
}
if (pct < 0)
{
pct = 0;
}
if (pct > 100)
{
pct = 100;
}
mPlants[i].setProperty("moist").send(String(pct));
mPlants[i].setProperty("moistraw").send(String(raw));
}
sensorWater.setProperty("remaining").send(String(waterLevelMax.get() - waterRawSensor.getAverage()));
Serial << "W : " << waterRawSensor.getAverage() << " cm (" << String(waterLevelMax.get() - waterRawSensor.getAverage()) << "%)" << endl;
lastWaterValue = waterRawSensor.getAverage();
sensorLipo.setProperty("percent").send(String(100 * mBatteryVoltage / VOLT_MAX_BATT));
sensorLipo.setProperty("volt").send(String(mBatteryVoltage));
sensorLipo.setProperty("current").send(String(battery.getCurrent()));
sensorLipo.setProperty("Ah").send(String(battery.getAh()));
sensorLipo.setProperty("ICA").send(String(battery.getICA()));
sensorLipo.setProperty("DCA").send(String(battery.getDCA()));
sensorLipo.setProperty("CCA").send(String(battery.getCCA()));
sensorSolar.setProperty("volt").send(String(mSolarVoltage));
rtcLipoTempIndex = lipoSensorIndex.get();
rtcWaterTempIndex = waterSensorIndex.get();
sensorTemp.setProperty(TEMPERATUR_SENSOR_LIPO).send(String(mTempLipo));
Serial << "Lipo Temperatur " << mTempLipo << " °C " << endl;
sensorTemp.setProperty(TEMPERATUR_SENSOR_WATER).send(String(mTempWater));
Serial << "Water Temperatur " << mTempWater << " °C " << endl;
sensorTemp.setProperty(TEMPERATUR_SENSOR_CHIP).send(String(mChipTemp));
Serial << "Chip Temperatur " << mChipTemp << " °C " << endl;
bool hasWater = true; //FIXMEmWaterGone > waterLevelMin.get();
//FIXME no water warning message
lastPumpRunning = determineNextPump();
if (lastPumpRunning != -1 && !hasWater)
{
Serial.println("Want to pump but no water");
}
if (lastPumpRunning != -1 && hasWater)
{
if (mode3Active)
{
Serial.println("Mode 3 active, ignoring pump request");
}
else
{
digitalWrite(OUTPUT_PUMP, HIGH);
//TODO setLastActivationForPump(lastPumpRunning, getCurrentTime());
mPlants[lastPumpRunning].activatePump();
}
}
if (lastPumpRunning == -1 || !hasWater)
{
if (mSolarVoltage < SOLAR_CHARGE_MIN_VOLTAGE)
{
Serial.print(mSolarVoltage);
Serial.println("V! No pumps to activate and low light, deepSleepNight");
espDeepSleepFor(deepSleepNightTime.get());
}
else
{
Serial.println("No pumps to activate, deepSleep");
espDeepSleepFor(deepSleepTime.get());
}
}
else
{
Serial.println("Running pump, watering deepsleep");
espDeepSleepFor(wateringDeepSleep.get(), true);
}
}
/**
* @brief Read ultra sensor JSN-SR04T-2.0
* Read the distance of the water level.
*/
void readDistance()
{
for (int i = 0; i < AMOUNT_SENOR_QUERYS; i++)
{
unsigned long duration = 0;
digitalWrite(triggerPin, HIGH);
delayMicroseconds(20);
cli();
digitalWrite(triggerPin, LOW);
duration = pulseIn(echoPin, HIGH);
sei();
int mmDis = duration * 0.3432 / 2;
if(mmDis > MAX_TANK_DEPTH){
waterRawSensor.add(0);
} else {
waterRawSensor.add(mmDis);
}
}
}
/**
* @brief Sensors, that are connected to GPIOs, mandatory for WIFI.
* These sensors (ADC2) can only be read when no Wifi is used.
*/
void readSensors()
{
Serial << "Read Sensors" << endl;
/* activate all sensors */
digitalWrite(OUTPUT_SENSOR, HIGH);
/* wait before reading something */
delay(20);
int timeoutTemp = millis() + TEMPERATUR_TIMEOUT;
int sensorCount = 0;
/* Required to read the temperature at least once */
while ((sensorCount == 0 || !battery.isFound()) && millis() < timeoutTemp)
{
sensors.begin();
battery.begin();
sensorCount = sensors.getDS18Count();
delay(50);
}
Serial << "One wire count: " << sensorCount << " found in " << (millis() - timeoutTemp) << "ms" << endl;
/* Measure temperature */
if (sensorCount > 0)
{
sensors.requestTemperatures();
}
for (int i = 0; i < sensorCount; i++) {
float temp = sensors.getTempCByIndex(i);
Serial << "OneWire sensor " << i << " has value " << temp << endl;
if (rtcWaterTempIndex != -1 && rtcWaterTempIndex == i) {
mTempWater = temp;
}
if (rtcLipoTempIndex != -1 && rtcLipoTempIndex == i) {
mTempLipo = temp;
}
}
// Update battery chip data
battery.update();
mSolarVoltage = battery.getVoltage(BATTSENSOR_INDEX_SOLAR) * SOLAR_VOLT_FACTOR;
mBatteryVoltage = battery.getVoltage(BATTSENSOR_INDEX_BATTERY);
mChipTemp = battery.getTemperature();
// if(mBatteryVoltage < MINIMUM_LIPO_VOLT){
// Serial.println("Low lipo voltage, abort high level processing");
// }
for (int readCnt = 0; readCnt < AMOUNT_SENOR_QUERYS; readCnt++)
{
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].addSenseValue();
}
delay(10);
}
/* Read the distance and give the temperature sensors some time */
readDistance();
Serial << "Distance sensor " << waterRawSensor.getAverage() << " cm" << endl;
/* deactivate the sensors */
digitalWrite(OUTPUT_SENSOR, LOW);
}
void onHomieEvent(const HomieEvent &event)
{
switch (event.type)
{
case HomieEventType::SENDING_STATISTICS:
Homie.getLogger() << "My statistics" << endl;
break;
case HomieEventType::MQTT_READY:
Serial.printf("NTP Setup with server %s\r\n", ntpServer.get());
configTime(0, 0, ntpServer.get());
Serial << "Setup plants" << endl;
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].postMQTTconnection();
}
mode2MQTT();
break;
case HomieEventType::OTA_STARTED:
Homie.getLogger() << "OTA started" << endl;
digitalWrite(OUTPUT_SENSOR, HIGH);
digitalWrite(OUTPUT_PUMP, HIGH);
gpio_hold_dis(GPIO_NUM_13); //pump pwr
gpio_deep_sleep_hold_dis();
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].deactivatePump();
}
mode3Active = true;
break;
case HomieEventType::OTA_SUCCESSFUL:
Homie.getLogger() << "OTA successfull" << endl;
digitalWrite(OUTPUT_SENSOR, LOW);
digitalWrite(OUTPUT_PUMP, LOW);
ESP.restart();
break;
default:
break;
}
}
int determineNextPump()
{
bool isLowLight = (mSolarVoltage > SOLAR_CHARGE_MIN_VOLTAGE || mSolarVoltage < SOLAR_CHARGE_MAX_VOLTAGE);
//FIXME instead of for, use sorted by last activation index to ensure equal runtime?
int pumpToUse = -1;
for (int i = 0; i < MAX_PLANTS; i++)
{
Plant plant = mPlants[i];
//TODO skip pump last used here!
//if (plant.isInCooldown(sinceLastActivation))
//{
// Serial.printf("%d Skipping due to cooldown %ld / %ld \r\n", i, sinceLastActivation, plant.getCooldownInSeconds());
//continue;
//}
//skip as it is not low light
if (!isLowLight && plant.isAllowedOnlyAtLowLight())
{
Serial.printf("%d No pump required: due to light\r\n", i);
continue;
}
if (plant.getCurrentMoisture() == MISSING_SENSOR && plant.isPumpTriggerActive())
{
Serial.printf("%d No pump possible: missing sensor \r\n", i);
continue;
}
if (plant.isPumpRequired())
{
Serial.printf("%d Requested pumping\r\n", i);
pumpToUse = i;
}
else if (plant.isPumpTriggerActive())
{
Serial.printf("%d No pump required: moisture acceptable %f / %ld\r\n", i, plant.getCurrentMoisture(), plant.getSettingsMoisture());
}
else
{
Serial.printf("%d No pump required: disabled pump trigger \r\n", i);
}
}
return pumpToUse;
}
/**
* @brief Handle Mqtt commands to keep controller alive
*
* @param range multiple transmitted values (not used for this function)
* @param value single value
* @return true when the command was parsed and executed succuessfully
* @return false on errors when parsing the request
*/
bool aliveHandler(const HomieRange &range, const String &value)
{
if (range.isRange)
return false; // only one controller is present
if (value.equals("ON") || value.equals("On") || value.equals("1"))
{
mode3Active = true;
}
else
{
mode3Active = false;
}
return true;
}
void homieLoop()
{
}
void systemInit()
{
WiFi.mode(WIFI_STA);
Homie_setFirmware("PlantControl", FIRMWARE_VERSION);
// Set default values
//in seconds
maxTimeBetweenMQTTUpdates.setDefaultValue(700);
deepSleepTime.setDefaultValue(600);
deepSleepNightTime.setDefaultValue(600);
wateringDeepSleep.setDefaultValue(5);
ntpServer.setDefaultValue("pool.ntp.org");
/* waterLevelMax 1000 */ /* 100cm in mm */
waterLevelMin.setDefaultValue(50); /* 5cm in mm */
waterLevelWarn.setDefaultValue(500); /* 50cm in mm */
waterLevelVol.setDefaultValue(5000); /* 5l in ml */
lipoSensorIndex.setDefaultValue(0);
waterSensorIndex.setDefaultValue(-1);
Homie.setLoopFunction(homieLoop);
Homie.onEvent(onHomieEvent);
//Homie.disableLogging();
Homie.setup();
mConfigured = Homie.isConfigured();
if (mConfigured)
{
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].advertise();
}
sensorTemp.advertise(TEMPERATUR_SENSOR_LIPO)
.setName(TEMPERATURE_NAME)
.setDatatype(NUMBER_TYPE)
.setUnit(TEMPERATURE_UNIT);
sensorTemp.advertise(TEMPERATUR_SENSOR_WATER)
.setName(TEMPERATURE_NAME)
.setDatatype(NUMBER_TYPE)
.setUnit(TEMPERATURE_UNIT);
sensorTemp.advertise(TEMPERATUR_SENSOR_CHIP)
.setName(TEMPERATURE_NAME)
.setDatatype(NUMBER_TYPE)
.setUnit(TEMPERATURE_UNIT);
sensorLipo.advertise("percent")
.setName("Percent")
.setDatatype(NUMBER_TYPE)
.setUnit("%");
sensorLipo.advertise("volt")
.setName("Volt")
.setDatatype(NUMBER_TYPE)
.setUnit("V");
sensorSolar.advertise("percent")
.setName("Percent")
.setDatatype(NUMBER_TYPE)
.setUnit("%");
sensorSolar.advertise("volt")
.setName("Volt")
.setDatatype(NUMBER_TYPE)
.setUnit("V");
sensorWater.advertise("remaining").setDatatype(NUMBER_TYPE).setUnit("%");
startupReason.advertise("startupReason").setDatatype(NUMBER_TYPE).setUnit("Enum");
}
stayAlive.advertise("alive").setName("Alive").setDatatype(NUMBER_TYPE).settable(aliveHandler);
}
void mode2()
{
Serial.println("==== Mode 2 ====");
systemInit();
/* Jump into Mode 3, if not configured */
if (!mConfigured)
{
Serial.println("==== Mode 3 ====");
mode3Active = true;
}
}
/**
* @brief Startup function
* Is called once, the controller is started
*/
void setup()
{
Serial.begin(115200);
Serial << endl
<< endl;
/* Intialize Plant */
for (int i = 0; i < MAX_PLANTS; i++)
{
mPlants[i].init();
}
// read button
pinMode(BUTTON, INPUT);
// Power pins
pinMode(OUTPUT_PUMP, OUTPUT);
pinMode(OUTPUT_SENSOR, OUTPUT);
// Individual Pump pins
/* Disable Wifi and bluetooth */
WiFi.mode(WIFI_OFF);
if (HomieInternals::MAX_CONFIG_SETTING_SIZE < MAX_CONFIG_SETTING_ITEMS)
{
//increase the config settings to 50 and the json to 3000
Serial << "Limits.hpp" << endl;
}
readSensors();
// Big TODO use here the settings in RTC_Memory
//Panik mode, the Lipo is empty, sleep a long long time:
// if ((mBatteryVoltage < MINIMUM_LIPO_VOLT) &&
// (mBatteryVoltage > NO_LIPO_VOLT))
// {
// Serial << PANIK_MODE_DEEPSLEEP << " s lipo " << mBatteryVoltage << "V" << endl;
// esp_sleep_enable_timer_wakeup(PANIK_MODE_DEEPSLEEP_US);
// esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
// esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
// esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
// esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF);
// esp_deep_sleep_start();
// }
mode2();
}
/**
* @brief Cyclic call
* Executs the Homie base functionallity or triggers sleeping, if requested.
*/
void loop()
{
/* Toggel Senor LED to visualize mode 3 */
if (mode3Active)
{
if (nextBlink < millis())
{
nextBlink = millis() + 500;
digitalWrite(OUTPUT_SENSOR, !digitalRead(OUTPUT_SENSOR));
}
}
else if (!mDeepsleep)
{
Homie.loop();
}
else
{
Serial << "Bye" << endl;
Serial.flush();
esp_deep_sleep_start();
}
if (millis() > 30000 && !mode3Active)
{
Serial << (millis() / 1000) << "not terminated watchdog reset" << endl;
Serial.flush();
esp_restart();
}
}
/** @}*/

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="1">
<builddir>cppcheck-build-dir</builddir>
<platform>arm32-wchar_t4.xml</platform>
<analyze-all-vs-configs>false</analyze-all-vs-configs>
<check-headers>true</check-headers>
<check-unused-templates>false</check-unused-templates>
<max-ctu-depth>10</max-ctu-depth>
<paths>
<dir name="src"/>
<dir name="include"/>
</paths>
<libraries>
<library>cppcheck-lib</library>
</libraries>
</project>

View File

@@ -1,11 +0,0 @@
This directory is intended for PIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

View File

@@ -1,5 +0,0 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@@ -1,7 +0,0 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

View File

@@ -1,21 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"*.tcc": "cpp",
"bitset": "cpp",
"algorithm": "cpp",
"istream": "cpp",
"limits": "cpp",
"streambuf": "cpp",
"functional": "cpp",
"string": "cpp",
"typeinfo": "cpp",
"cmath": "cpp"
}
}
}

View File

@@ -1,112 +0,0 @@
/*
* DS2438.h
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#ifndef DS2438_h
#define DS2438_h
#include <Arduino.h>
#include <OneWire.h>
#define DS2438_TEMPERATURE_CONVERSION_COMMAND 0x44
#define DS2438_VOLTAGE_CONVERSION_COMMAND 0xb4
#define DS2438_WRITE_SCRATCHPAD_COMMAND 0x4e
#define DS2438_COPY_SCRATCHPAD_COMMAND 0x48
#define DS2438_READ_SCRATCHPAD_COMMAND 0xbe
#define DS2438_RECALL_MEMORY_COMMAND 0xb8
#define PAGE_MIN 0
#define PAGE_MAX 7
#define DS2438_CHA 0
#define DS2438_CHB 1
#define DS2438_MODE_CHA 0x01
#define DS2438_MODE_CHB 0x02
#define DS2438_MODE_TEMPERATURE 0x04
#define DS2438_TEMPERATURE_DELAY 10
#define DS2438_VOLTAGE_CONVERSION_DELAY 8
#define DEFAULT_PAGE0(var) uint8_t var[8] { \
0b00001011 /* X, ADB=0, NVB=0, TB=0, AD=1, EE=0, CA=1, IAD=1 */, \
0, /* Temperatur */ \
0, /* Temperatur */ \
0, /* Voltage */ \
0, /* Voltage */ \
0, /* Current */ \
0, /* Current */ \
0 /* Threashold */ \
}
typedef struct PageOne {
uint8_t eleapsedTimerByte0; /**< LSB of timestamp */
uint8_t eleapsedTimerByte1;
uint8_t eleapsedTimerByte2;
uint8_t eleapsedTimerByte3; /**< MSB of timestamp */
uint8_t ICA; /**< Integrated Current Accumulator (current flowing into and out of the battery) */
uint8_t offsetRegisterByte0; /**< Offset for ADC calibdation */
uint8_t offsetRegisterByte1; /**< Offset for ADC calibdation */
uint8_t reserved;
} PageOne_t;
typedef struct PageSeven {
uint8_t userByte0;
uint8_t userByte1;
uint8_t userByte2;
uint8_t userByte3;
uint8_t CCA0; /**< Charging Current Accumulator (CCA) */
uint8_t CCA1; /**< Charging Current Accumulator (CCA) */
uint8_t DCA0; /**< Discharge Current Accumulator (DCA) */
uint8_t DCA1; /**< Discharge Current Accumulator (DCA) */
} PageSeven_t;
typedef uint8_t DeviceAddress[8];
class DS2438 {
public:
DS2438(OneWire *ow, float currentShunt);
DS2438(OneWire *ow, uint8_t *address);
void begin();
void update();
double getTemperature();
float getVoltage(int channel=DS2438_CHA);
float getCurrent();
boolean isError();
boolean isFound();
private:
bool validAddress(const uint8_t*);
bool validFamily(const uint8_t* deviceAddress);
bool deviceFound = false;
OneWire *_ow;
DeviceAddress _address;
uint8_t _mode;
double _temperature;
float _voltageA;
float _voltageB;
float _current;
float _currentShunt;
boolean _error;
boolean startConversion(int channel, boolean doTemperature);
boolean selectChannel(int channel);
void writePage(int page, uint8_t *data);
boolean readPage(int page, uint8_t *data);
};
#endif

View File

@@ -1,39 +0,0 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@@ -1,46 +0,0 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@@ -1,17 +0,0 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
lib_deps = OneWire
DallasTemperature

View File

@@ -1,286 +0,0 @@
/*
* DS2438.cpp
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#include "DS2438.h"
// DSROM FIELDS
#define DSROM_FAMILY 0
#define DSROM_CRC 7
#define DS2438MODEL 0x26
DS2438::DS2438(OneWire *ow, float currentShunt = 1.0f) {
_ow = ow;
_currentShunt = currentShunt;
};
void DS2438::begin(){
DeviceAddress searchDeviceAddress;
_ow->reset_search();
memset(searchDeviceAddress,0, 8);
_temperature = 0;
_voltageA = 0.0;
_voltageB = 0.0;
_error = true;
_mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE);
deviceFound = false; // Reset the number of devices when we enumerate wire devices
while (_ow->search(searchDeviceAddress)) {
if (validAddress(searchDeviceAddress)) {
if (validFamily(searchDeviceAddress)) {
memcpy(_address,searchDeviceAddress,8);
DEFAULT_PAGE0(defaultConfig);
writePage(0, defaultConfig);
deviceFound = true;
}
}
}
}
bool DS2438::isFound(){
return deviceFound;
}
bool DS2438::validAddress(const uint8_t* deviceAddress) {
return (_ow->crc8(deviceAddress, 7) == deviceAddress[DSROM_CRC]);
}
bool DS2438::validFamily(const uint8_t* deviceAddress) {
switch (deviceAddress[DSROM_FAMILY]) {
case DS2438MODEL:
return true;
default:
return false;
}
}
void DS2438::update() {
uint8_t data[9];
_error = true;
if(!isFound()){
return;
}
if (_mode & DS2438_MODE_CHA || _mode == DS2438_MODE_TEMPERATURE) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE;
if (!startConversion(DS2438_CHA, doTemperature)) {
Serial.println("Error starting temp conversion ds2438 channel a");
return;
}
if (!readPage(0, data)){
Serial.println("Error reading zero page ds2438 channel a");
return;
}
Serial.print(data[0],16);
Serial.print(" ");
Serial.print(data[1],16);
Serial.print(" ");
Serial.print(data[2],16);
Serial.print(" ");
Serial.print(data[3],16);
Serial.print(" ");
Serial.print(data[4],16);
Serial.print(" ");
Serial.print(data[5],16);
Serial.print(" ");
Serial.print(data[6],16);
Serial.print(" ");
Serial.println(data[7],16);
if (doTemperature) {
_temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125;
}
if (_mode & DS2438_MODE_CHA) {
_voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
}
if (_mode & DS2438_MODE_CHB) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE && !(_mode & DS2438_MODE_CHA);
if (!startConversion(DS2438_CHB, doTemperature)) {
Serial.println("Error starting temp conversion channel b ds2438");
return;
}
if (!readPage(0, data)){
Serial.println("Error reading zero page ds2438 channel b");
return;
}
if (doTemperature) {
int16_t upperByte = ((int16_t)data[2]) << 8;
int16_t lowerByte = data[1] >> 3;
int16_t fullByte = (upperByte | lowerByte);
_temperature = ((double)fullByte) * 0.03125;
}
_voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
int16_t upperByte = ((int16_t)data[6]) << 8;
int16_t lowerByte = data[5];
int16_t fullByte = (int16_t)(upperByte | lowerByte);
float fullByteb = fullByte;
_current = (fullByteb) / ((4096.0f * _currentShunt));
_error = false;
Serial.print(data[0],16);
Serial.print(" ");
Serial.print(data[1],16);
Serial.print(" ");
Serial.print(data[2],16);
Serial.print(" ");
Serial.print(data[3],16);
Serial.print(" ");
Serial.print(data[4],16);
Serial.print(" ");
Serial.print(data[5],16);
Serial.print(" ");
Serial.print(data[6],16);
Serial.print(" ");
Serial.println(data[7],16);
Serial.println("-");
uint16_t ICA = 0;
if (readPage(1, data)){
PageOne_t *pOne = (PageOne_t *) data;
Serial.println(pOne->ICA);
float Ah = pOne->ICA / (2048.0f * _currentShunt);
Serial.print("Ah=");
Serial.println(Ah);
ICA = pOne->ICA;
}
if (readPage(7, data)){
PageSeven_t *pSeven = (PageSeven_t *) data;
int16_t CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8;
int16_t DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8;
Serial.println("ICA, DCA, CCA");
Serial.print(ICA);
Serial.print(", ");
Serial.print(DCA);
Serial.print(", ");
Serial.println(CCA);
}
}
double DS2438::getTemperature() {
return _temperature;
}
float DS2438::getVoltage(int channel) {
if (channel == DS2438_CHA) {
return _voltageA;
} else if (channel == DS2438_CHB) {
return _voltageB;
} else {
return 0.0;
}
}
float DS2438::getCurrent() {
return _current;
}
boolean DS2438::isError() {
return _error;
}
boolean DS2438::startConversion(int channel, boolean doTemperature) {
if(!isFound()){
return false;
}
if (!selectChannel(channel)){
return false;
}
_ow->reset();
_ow->select(_address);
if (doTemperature) {
_ow->write(DS2438_TEMPERATURE_CONVERSION_COMMAND, 0);
delay(DS2438_TEMPERATURE_DELAY);
_ow->reset();
_ow->select(_address);
}
_ow->write(DS2438_VOLTAGE_CONVERSION_COMMAND, 0);
delay(DS2438_VOLTAGE_CONVERSION_DELAY);
return true;
}
boolean DS2438::selectChannel(int channel) {
if(!isFound()){
return false;
}
uint8_t data[9];
if (readPage(0, data)) {
if (channel == DS2438_CHB){
data[0] = data[0] | 0x08;
}
else {
data[0] = data[0] & 0xf7;
}
writePage(0, data);
return true;
}
Serial.println("Could not read page zero data");
return false;
}
void DS2438::writePage(int page, uint8_t *data) {
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return;
}
for (int i = 0; i < 8; i++){
_ow->write(data[i], 0);
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
}
boolean DS2438::readPage(int page, uint8_t *data) {
//TODO if all data is 0 0 is a valid crc, but most likly not as intended
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_RECALL_MEMORY_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return false;
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
for (int i = 0; i < 9; i++){
data[i] = _ow->read();
}
return _ow->crc8(data, 8) == data[8];
}

View File

@@ -1,141 +0,0 @@
#include <Arduino.h>
#include "esp_sleep.h"
#include "DallasTemperature.h"
#include "DS2438.h"
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */
#define SENSOR_DS18B20 2 /**< GPIO 2 */
#define OUTPUT_PUMP0 17 /**< GPIO 23 */
#define OUTPUT_PUMP1 05 /**< GPIO 22 */
#define OUTPUT_PUMP2 18 /**< GPIO 21 */
#define OUTPUT_PUMP3 19 /**< GPIO 19 */
#define OUTPUT_PUMP4 21 /**< GPIO 18 */
#define OUTPUT_PUMP5 22 /**< GPIO 5 */
#define OUTPUT_PUMP6 23 /**< GPIO 15 */
#define OUTPUT_SENSOR 16 /**< GPIO 16 - Enable Sensors */
#define OUTPUT_PUMP 13 /**< GPIO 13 - Enable Pumps */
#define SENSOR_PLANT0 32 /**< GPIO 32 (ADC1) */
#define ADC_TO_VOLT(adc) ((adc) * 3.3 ) / 4095)
#define ADC_TO_VOLT_WITH_MULTI(adc, multi) (((adc) * 3.3 * (multi)) / 4095)
#define SOLAR_VOLT(adc) ADC_TO_VOLT_WITH_MULTI(adc, 4.0306) /**< 100k and 33k voltage dividor */
#define ADC_5V_TO_3V3(adc) ADC_TO_VOLT_WITH_MULTI(adc, 1.7) /**< 33k and 47k8 voltage dividor */
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int pumpActive = 0;
int secondBootCount = 0;
OneWire oneWire(SENSOR_DS18B20);
DallasTemperature temp(&oneWire);
DS2438 battery(&oneWire,0.1f);
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason){
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
}
}
bool whatever = true;
void setAll2Off() {
digitalWrite(OUTPUT_PUMP0, LOW);
digitalWrite(OUTPUT_PUMP1, LOW);
digitalWrite(OUTPUT_PUMP2, LOW);
digitalWrite(OUTPUT_PUMP3, LOW);
digitalWrite(OUTPUT_PUMP4, LOW);
digitalWrite(OUTPUT_PUMP5, LOW);
digitalWrite(OUTPUT_PUMP6, LOW);
digitalWrite(OUTPUT_SENSOR, LOW);
digitalWrite(OUTPUT_PUMP, LOW);
}
void setup() {
pinMode(OUTPUT_PUMP0, OUTPUT);
pinMode(OUTPUT_PUMP1, OUTPUT);
pinMode(OUTPUT_PUMP2, OUTPUT);
pinMode(OUTPUT_PUMP3, OUTPUT);
pinMode(OUTPUT_PUMP4, OUTPUT);
pinMode(OUTPUT_PUMP5, OUTPUT);
pinMode(OUTPUT_PUMP6, OUTPUT);
pinMode(OUTPUT_SENSOR, OUTPUT);
pinMode(OUTPUT_PUMP, OUTPUT);
pinMode(SENSOR_PLANT0, ANALOG);
setAll2Off();
Serial.begin(9600);
//Increment boot number and print it every reboot
++bootCount;
++secondBootCount;
Serial.println("Boot number: " + String(bootCount) + " " + String(secondBootCount));
//Print the wakeup reason for ESP32
print_wakeup_reason();
/* activate power pump and pump 0 */
digitalWrite(OUTPUT_SENSOR, HIGH);
delay(1);
temp.begin();
battery.begin();
Serial.print("Battery");
Serial.print("\t");
Serial.print("Solar");
Serial.print("\t");
Serial.print("Bat I");
Serial.print("\t");
Serial.println("Temp/10");
}
void loop() {
whatever = !whatever;
digitalWrite(OUTPUT_PUMP, HIGH);
delay(500);
digitalWrite(OUTPUT_PUMP6, HIGH);
for(int j=0; j < 5 && temp.getDeviceCount() == 0; j++) {
delay(10);
// Serial.println("Reset 1wire temp");
temp.begin();
}
for(int j=0; j < 5 && (0 == battery.isFound()); j++) {
delay(10);
Serial.println("Reset 1wire bat");
battery.begin();
battery.update();
}
battery.update();
Serial.print(battery.getVoltage(0)); //use define here, solar
Serial.print("\t");
Serial.print(battery.getVoltage(1)); //use define here, battery
Serial.print("\t");
Serial.print(battery.getCurrent());
Serial.print("\t");
Serial.println(battery.getTemperature()/10);
}

View File

@@ -1,11 +0,0 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

23
rust/.cargo/config.toml Normal file
View File

@@ -0,0 +1,23 @@
[build]
#target = "xtensa-esp32-espidf"
target = "riscv32imac-esp-espidf"
[target.riscv32imac-esp-espidf]
linker = "ldproxy"
# runner = "espflash flash --monitor --partition-table partitions.csv -b no-reset" # Select this runner for espflash v2.x.x
# runner = "espflash flash --monitor --baud 921600 --partition-table partitions.csv -b no-reset" # Select this runner for espflash v2.x.x
# runner = espflash erase-parts otadata
runner = "cargo runner"
rustflags = [ "--cfg", "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110
[unstable]
build-std = ["std", "panic_abort"]
[env]
MCU="esp32c6"
# Note: this variable is not used by the pio builder (`cargo build --features pio`)
ESP_IDF_VERSION = "v5.2.1"
CHRONO_TZ_TIMEZONE_FILTER="UTC|Europe/Berlin"
CARGO_WORKSPACE_DIR = { value = "", relative = true }
RUST_BACKTRACE = "full"

8
rust/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

8
rust/.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/plant-ctrl2.iml" filepath="$PROJECT_DIR$/.idea/plant-ctrl2.iml" />
</modules>
</component>
</project>

11
rust/.idea/plant-ctrl2.iml generated Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
rust/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

82
rust/Cargo.toml Normal file
View File

@@ -0,0 +1,82 @@
[package]
name = "plant-ctrl2"
version = "0.1.0"
authors = ["Empire Phoenix"]
edition = "2021"
resolver = "2"
rust-version = "1.71"
[profile.dev]
# Explicitly disable LTO which the Xtensa codegen backend has issues
lto = false
strip = false
debug = true
overflow-checks = true
panic = "abort"
incremental = true
opt-level = "s"
[profile.dev.build-override]
opt-level = 1
incremental = true
[package.metadata.cargo_runner]
# The string `$TARGET_FILE` will be replaced with the path from cargo.
command = [
"cargo",
"espflash",
"save-image",
"--chip",
"esp32c6",
"image.bin"
]
[package.metadata.espflash]
partition_table = "partitions.csv"
[features]
default = ["std", "embassy", "esp-idf-svc/native"]
pio = ["esp-idf-svc/pio"]
std = ["alloc", "esp-idf-svc/binstart", "esp-idf-svc/std"]
alloc = ["esp-idf-svc/alloc"]
nightly = ["esp-idf-svc/nightly"]
experimental = ["esp-idf-svc/experimental"]
embassy = ["esp-idf-svc/embassy-sync", "esp-idf-svc/critical-section", "esp-idf-svc/embassy-time-driver"]
[dependencies]
log = { version = "0.4", default-features = false }
serde = { version = "1.0.192", features = ["derive"] }
average = { version = "0.14.1" , features = ["std"] }
#esp32 = "0.28.0"
bit_field = "0.10.2"
ds18b20 = "0.1.1"
embedded-svc = { version = "0.27.0", features = ["experimental"] }
esp-idf-hal = "0.43.0"
esp-idf-sys = { version = "0.34.0", features = ["binstart", "native"] }
esp-idf-svc = { version = "0.48.0", default-features = false }
esp_idf_build = "0.1.3"
chrono = { version = "0.4.23", default-features = false , features = ["iana-time-zone" , "alloc"] }
chrono-tz = {version="0.8.0", default-features = false , features = [ "filter-by-regex" ]}
embedded-hal = "1.0.0"
one-wire-bus = "0.1.1"
anyhow = { version = "1.0.75", features = ["std", "backtrace"] }
schemars = "0.8.16"
heapless = { version = "0.8", features = ["serde"] }
serde_json = "1.0.108"
strum = { version = "0.26.1", features = ["derive"] }
once_cell = "1.19.0"
measurements = "0.11.0"
bq34z100 = "0.2.1"
[patch.crates-io]
#esp-idf-hal = { git = "https://github.com/esp-rs/esp-idf-hal.git" }
esp-idf-hal = { git = "https://github.com/empirephoenix/esp-idf-hal.git" }
#esp-idf-sys = { git = "https://github.com/empirephoenix/esp-idf-sys.git" }
#esp-idf-sys = { git = "https://github.com/esp-rs/esp-idf-sys.git" }
#esp-idf-svc = { git = "https://github.com/esp-rs/esp-idf-svc.git" }
[build-dependencies]
embuild = "0.31.3"
vergen = { version = "8.2.6", features = ["build", "git", "gitcl"] }

42
rust/build.rs Normal file
View File

@@ -0,0 +1,42 @@
use std::process::Command;
use vergen::EmitBuilder;
fn main() {
println!("cargo:rerun-if-changed=./src/src_webpack");
Command::new("rm")
.arg("./src/webserver/bundle.js")
.output()
.unwrap();
match Command::new("cmd").spawn() {
Ok(_) => {
println!("Assuming build on windows");
let output = Command::new("cmd")
.arg("/K")
.arg("npx")
.arg("webpack")
.current_dir("./src_webpack")
.output()
.unwrap();
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
Err(_) => {
println!("Assuming build on linux");
let output = Command::new("npx")
.arg("webpack")
.current_dir("./src_webpack")
.output()
.unwrap();
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
}
embuild::espidf::sysenv::output();
let _ = EmitBuilder::builder().all_git().all_build().emit();
}

Binary file not shown.

6
rust/partitions.csv Normal file
View File

@@ -0,0 +1,6 @@
nvs, data, nvs, , 16k,
otadata, data, ota, , 8k,
phy_init, data, phy, , 4k,
ota_0, app, ota_0, , 1792K,
ota_1, app, ota_1, , 1792K,
storage, data, spiffs, , 400K,
1 nvs data nvs 16k
2 otadata data ota 8k
3 phy_init data phy 4k
4 ota_0 app ota_0 1792K
5 ota_1 app ota_1 1792K
6 storage data spiffs 400K

3
rust/rust-toolchain.toml Normal file
View File

@@ -0,0 +1,3 @@
[toolchain]
channel = "nightly"
toolchain = "esp"

10
rust/sdkconfig.defaults Normal file
View File

@@ -0,0 +1,10 @@
# Rust often needs a bit of an extra main task stack size compared to C (the default is 3K)
CONFIG_ESP_MAIN_TASK_STACK_SIZE=50000
# Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default).
# This allows to use 1 ms granuality for thread sleeps (10 ms by default).
CONFIG_FREERTOS_HZ=1000
CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y
CONFIG_I2C_ENABLE_DEBUG_LOG=y
DEBUG_LEVEL=5

18
rust/setup.txt Normal file
View File

@@ -0,0 +1,18 @@
cargo install cargo-generate
cargo install ldproxy
cargo install espup
cargo install espflash
cargo install cargo-espflash
cargo generate esp-rs/esp-idf-template cargo
export PATH="$PATH:$HOME/.cargo/bin"
espup install
rustup toolchain link esp ~/.rustup/toolchains/esp/
cargo install ldproxy
cargo espflash save-image --chip esp32 image.bin
esptool.py --chip ESP32-C3 elf2image --output my-app.bin target/release/my-app
$ espflash save-image ESP32-C3 target/release/my-app my-app.bin

88
rust/src/config.rs Normal file
View File

@@ -0,0 +1,88 @@
use std::{fmt, str::FromStr};
use serde::{Deserialize, Serialize};
use crate::PLANT_COUNT;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct Config {
pub mqtt_url: heapless::String<128>,
pub base_topic: heapless::String<64>,
pub max_consecutive_pump_count: u8,
pub tank_allow_pumping_if_sensor_error: bool,
pub tank_sensor_enabled: bool,
pub tank_useable_ml: u32,
pub tank_warn_percent: u8,
pub tank_empty_percent: u8,
pub tank_full_percent: u8,
pub night_lamp_hour_start: u8,
pub night_lamp_hour_end: u8,
pub night_lamp_only_when_dark: bool,
pub plants: [Plant; PLANT_COUNT],
}
impl Default for Config {
fn default() -> Self {
Self {
base_topic: heapless::String::from_str("plant/one").unwrap(),
mqtt_url: heapless::String::from_str("mqtt://192.168.1.1:1883").unwrap(),
tank_allow_pumping_if_sensor_error: true,
tank_sensor_enabled: true,
tank_warn_percent: 50,
night_lamp_hour_start: 21,
night_lamp_hour_end: 2,
night_lamp_only_when_dark: true,
plants: [Plant::default(); PLANT_COUNT],
max_consecutive_pump_count: 15,
tank_useable_ml: 5000,
tank_empty_percent: 0_u8,
tank_full_percent: 100_u8,
}
}
}
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
pub enum Mode {
OFF,
TargetMoisture,
TimerOnly,
TimerAndDeadzone,
}
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq)]
pub struct Plant {
pub mode: Mode,
pub target_moisture: u8,
pub pump_time_s: u16,
pub pump_cooldown_min: u16,
pub pump_hour_start: u8,
pub pump_hour_end: u8,
pub sensor_b: bool,
}
impl Default for Plant {
fn default() -> Self {
Self {
target_moisture: 40,
pump_time_s: 60,
pump_cooldown_min: 60,
pump_hour_start: 8,
pump_hour_end: 20,
mode: Mode::OFF,
sensor_b: false
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct WifiConfig {
pub ssid: heapless::String<32>,
pub password: Option<heapless::String<64>>,
}
impl fmt::Display for WifiConfig {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, ****)", self.ssid)
}
}

266
rust/src/espota.rs Normal file
View File

@@ -0,0 +1,266 @@
use core::fmt;
use core::mem;
use core::ptr;
use esp_idf_sys::{
esp_ota_abort, esp_ota_begin, esp_ota_end, esp_ota_get_next_update_partition, esp_ota_handle_t,
esp_ota_mark_app_invalid_rollback_and_reboot, esp_ota_mark_app_valid_cancel_rollback,
esp_ota_set_boot_partition, esp_ota_write, esp_partition_t, esp_restart, ESP_ERR_FLASH_OP_FAIL,
ESP_ERR_FLASH_OP_TIMEOUT, ESP_ERR_INVALID_ARG, ESP_ERR_INVALID_SIZE, ESP_ERR_INVALID_STATE,
ESP_ERR_NOT_FOUND, ESP_ERR_NO_MEM, ESP_ERR_OTA_PARTITION_CONFLICT, ESP_ERR_OTA_ROLLBACK_FAILED,
ESP_ERR_OTA_ROLLBACK_INVALID_STATE, ESP_ERR_OTA_SELECT_INFO_INVALID,
ESP_ERR_OTA_VALIDATE_FAILED, ESP_FAIL, ESP_OK, OTA_SIZE_UNKNOWN,
};
pub type Result<T> = core::result::Result<T, Error>;
/// An error that can happen during ESP OTA operations.
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl Error {
pub(crate) fn from_kind(kind: ErrorKind) -> Self {
Self { kind }
}
/// Returns the kind of error as an enum, that can be matched on.
pub fn kind(&self) -> ErrorKind {
self.kind
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.kind.fmt(f)
}
}
impl std::error::Error for Error {}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum ErrorKind {
/// No suitable partition for writing OTA update to found.
NoOtaPartition,
/// Cannot allocate memory for OTA operation.
AllocFailed,
/// Rollback enabled, but the currently running application is still pending. The currently
/// running application must confirm itself before downloading and flashing a new app.
InvalidRollbackState,
/// First byte of image contains invalid app image magic byte.
InvalidMagicByte,
/// Flash write operation timed out.
FlashTimeout,
/// Flash write operation failed.
FlashFailed,
/// OTA data partition has invalid contents.
InvalidOtaPartitionData,
/// The [`OtaUpdate`] handle was finalized before any app image was written to it.
NothingWritten,
/// OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.)
InvalidImage,
/// If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash.
WritingEncryptedFailed,
/// The rollback failed.
RollbackFailed,
/// The rollback is not possible due to flash does not have any apps.
RollbackFailedNoApps,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ErrorKind::*;
match self {
NoOtaPartition => "No suitable partition for writing OTA update to found",
AllocFailed => "Cannot allocate memory for OTA operation",
InvalidRollbackState => {
"Rollback enabled, but the currently running application is still pending"
}
InvalidMagicByte => "First byte of image contains invalid app image magic byte",
FlashTimeout => "Flash write operation timed out",
FlashFailed => "Flash write operation failed",
InvalidOtaPartitionData => "OTA data partition has invalid contents",
NothingWritten => "OtaUpdate was never written to",
InvalidImage => "OTA image is invalid",
WritingEncryptedFailed => "Internal error writing the final encrypted bytes to flash",
RollbackFailed => "The rollback failed",
RollbackFailedNoApps => {
"The rollback is not possible due to flash does not have any apps"
}
}
.fmt(f)
}
}
/// Represents an ongoing OTA update.
///
/// Dropping this object before calling [`finalize`](OtaUpdate::finalize) will abort the update.
#[derive(Debug)]
pub struct OtaUpdate {
partition: *const esp_partition_t,
ota_handle: esp_ota_handle_t,
}
impl OtaUpdate {
/// Starts an OTA update to the next OTA compatible partition.
///
/// Finds next partition round-robin, starting from the current running partition.
/// The entire partition is erased.
pub fn begin() -> Result<Self> {
let partition = unsafe { esp_ota_get_next_update_partition(ptr::null()) };
if partition.is_null() {
return Err(Error::from_kind(ErrorKind::NoOtaPartition));
}
let mut ota_handle = 0;
match unsafe { esp_ota_begin(partition, OTA_SIZE_UNKNOWN as usize, &mut ota_handle) } {
ESP_OK => Ok(()),
ESP_ERR_INVALID_ARG => panic!("Invalid partition or out_handle"),
ESP_ERR_NO_MEM => Err(Error::from_kind(ErrorKind::AllocFailed)),
ESP_ERR_OTA_PARTITION_CONFLICT => Err(Error::from_kind(ErrorKind::NoOtaPartition)),
ESP_ERR_NOT_FOUND => panic!("Partition argument not found in partition table"),
ESP_ERR_OTA_SELECT_INFO_INVALID => {
Err(Error::from_kind(ErrorKind::InvalidOtaPartitionData))
}
ESP_ERR_INVALID_SIZE => panic!("Partition doesnt fit in configured flash size"),
ESP_ERR_FLASH_OP_TIMEOUT => Err(Error::from_kind(ErrorKind::FlashTimeout)),
ESP_ERR_FLASH_OP_FAIL => Err(Error::from_kind(ErrorKind::FlashFailed)),
ESP_ERR_OTA_ROLLBACK_INVALID_STATE => {
Err(Error::from_kind(ErrorKind::InvalidRollbackState))
}
code => panic!("Unexpected esp_ota_begin return code: {}", code),
}?;
Ok(Self {
partition,
ota_handle,
})
}
/// Write app image data to partition.
///
/// This method can be called multiple times as data is received during the OTA operation.
/// Data is written sequentially to the partition.
///
/// The format of the app image can be read about in the main README and crate documentation.
pub fn write(&mut self, app_image_chunk: &[u8]) -> Result<()> {
let chunk_ptr = app_image_chunk.as_ptr() as *const _;
let chunk_len = app_image_chunk.len();
match unsafe { esp_ota_write(self.ota_handle, chunk_ptr, chunk_len) } {
ESP_OK => Ok(()),
ESP_ERR_INVALID_ARG => panic!("Invalid OTA handle"),
ESP_ERR_OTA_VALIDATE_FAILED => Err(Error::from_kind(ErrorKind::InvalidMagicByte)),
ESP_ERR_FLASH_OP_TIMEOUT => Err(Error::from_kind(ErrorKind::FlashTimeout)),
ESP_ERR_FLASH_OP_FAIL => Err(Error::from_kind(ErrorKind::FlashFailed)),
ESP_ERR_OTA_SELECT_INFO_INVALID => {
Err(Error::from_kind(ErrorKind::InvalidOtaPartitionData))
}
code => panic!("Unexpected esp_ota_write return code: {code}"),
}
}
/// Finish OTA update and validate newly written app image.
///
/// Unless you also call [`set_as_boot_partition`](CompletedOtaUpdate::set_as_boot_partition) the new app will not
/// start.
pub fn finalize(self) -> Result<CompletedOtaUpdate> {
match unsafe { esp_ota_end(self.ota_handle) } {
ESP_OK => Ok(()),
ESP_ERR_NOT_FOUND => panic!("Invalid OTA handle"),
ESP_ERR_INVALID_ARG => Err(Error::from_kind(ErrorKind::NothingWritten)),
ESP_ERR_OTA_VALIDATE_FAILED => Err(Error::from_kind(ErrorKind::InvalidImage)),
ESP_ERR_INVALID_STATE => Err(Error::from_kind(ErrorKind::WritingEncryptedFailed)),
code => panic!("Unexpected esp_ota_end return code: {code}"),
}?;
let partition = self.partition;
mem::forget(self);
Ok(CompletedOtaUpdate { partition })
}
/// Returns a raw pointer to the partition that the new app is/will be written to.
pub fn raw_partition(&self) -> *const esp_partition_t {
self.partition
}
}
impl Drop for OtaUpdate {
fn drop(&mut self) {
#[cfg(feature = "log")]
log::debug!("Aborting OTA update");
let abort_result_code = unsafe { esp_ota_abort(self.ota_handle) };
if abort_result_code != ESP_OK {
#[cfg(feature = "log")]
log::error!(
"Aborting the OTA update returned an unexpected code: {}",
abort_result_code
)
}
}
}
pub struct CompletedOtaUpdate {
partition: *const esp_partition_t,
}
impl CompletedOtaUpdate {
/// Sets the boot partition to the newly flashed OTA partition.
pub fn set_as_boot_partition(&mut self) -> Result<()> {
match unsafe { esp_ota_set_boot_partition(self.partition) } {
ESP_OK => Ok(()),
ESP_ERR_INVALID_ARG => panic!("Invalid partition sent to esp_ota_set_boot_partition"),
ESP_ERR_OTA_VALIDATE_FAILED => Err(Error::from_kind(ErrorKind::InvalidImage)),
ESP_ERR_NOT_FOUND => panic!("OTA data partition not found"),
ESP_ERR_FLASH_OP_TIMEOUT => Err(Error::from_kind(ErrorKind::FlashTimeout)),
ESP_ERR_FLASH_OP_FAIL => Err(Error::from_kind(ErrorKind::FlashFailed)),
code => panic!("Unexpected esp_ota_set_boot_partition code: {}", code),
}
}
/// Restarts the CPU. If [`set_as_boot_partition`](CompletedOtaUpdate::set_as_boot_partition) was
/// called and completed successfully, the CPU will boot into the newly written app.
///
/// After successful restart, CPU reset reason will be SW_CPU_RESET. Peripherals
/// (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset.
pub fn restart(self) -> ! {
unsafe { esp_restart() }
}
/// Returns a raw pointer to the partition that the new app was written to.
pub fn raw_partition(&self) -> *const esp_partition_t {
self.partition
}
}
/// Call this function to indicate that the running app is working well.
///
/// Should be called (at least) the first time a new app starts up after
/// being flashed.
pub fn mark_app_valid() {
match unsafe { esp_ota_mark_app_valid_cancel_rollback() } {
ESP_OK => (),
code => panic!(
"Unexpected esp_ota_mark_app_valid_cancel_rollback code: {}",
code
),
}
}
/// Call this function to roll back to the previously workable app with reboot.
///
/// If rolling back failed, it returns an error, otherwise this function never returns,
/// as the CPU is rebooting.
pub fn rollback_and_reboot() -> Result<core::convert::Infallible> {
match unsafe { esp_ota_mark_app_invalid_rollback_and_reboot() } {
ESP_FAIL => Err(Error::from_kind(ErrorKind::RollbackFailed)),
ESP_ERR_OTA_ROLLBACK_FAILED => Err(Error::from_kind(ErrorKind::RollbackFailedNoApps)),
code => panic!(
"Unexpected esp_ota_mark_app_invalid_rollback_and_reboot code: {}",
code
),
}
}

4
rust/src/lib.rs Normal file
View File

@@ -0,0 +1,4 @@
#![allow(dead_code)]
extern crate embedded_hal as hal;
pub mod sipo;

1052
rust/src/main.rs Normal file

File diff suppressed because it is too large Load Diff

1254
rust/src/plant_hal.rs Normal file

File diff suppressed because it is too large Load Diff

153
rust/src/sipo.rs Normal file
View File

@@ -0,0 +1,153 @@
//! Serial-in parallel-out shift register
use core::cell::RefCell;
use core::mem::{self, MaybeUninit};
use std::convert::Infallible;
use hal::digital::OutputPin;
trait ShiftRegisterInternal {
fn update(&self, index: usize, command: bool) -> Result<(), ()>;
}
/// Output pin of the shift register
pub struct ShiftRegisterPin<'a> {
shift_register: &'a dyn ShiftRegisterInternal,
index: usize,
}
impl<'a> ShiftRegisterPin<'a> {
fn new(shift_register: &'a dyn ShiftRegisterInternal, index: usize) -> Self {
ShiftRegisterPin {
shift_register,
index,
}
}
}
impl embedded_hal::digital::ErrorType for ShiftRegisterPin<'_> {
type Error = Infallible;
}
impl OutputPin for ShiftRegisterPin<'_> {
fn set_low(&mut self) -> Result<(), Infallible> {
self.shift_register.update(self.index, false).unwrap();
Ok(())
}
fn set_high(&mut self) -> Result<(), Infallible> {
self.shift_register.update(self.index, true).unwrap();
Ok(())
}
}
macro_rules! ShiftRegisterBuilder {
($name: ident, $size: expr) => {
/// Serial-in parallel-out shift register
pub struct $name<Pin1, Pin2, Pin3>
where
Pin1: OutputPin,
Pin2: OutputPin,
Pin3: OutputPin,
{
clock: RefCell<Pin1>,
latch: RefCell<Pin2>,
data: RefCell<Pin3>,
output_state: RefCell<[bool; $size]>,
}
impl<Pin1, Pin2, Pin3> ShiftRegisterInternal for $name<Pin1, Pin2, Pin3>
where
Pin1: OutputPin,
Pin2: OutputPin,
Pin3: OutputPin,
{
/// Sets the value of the shift register output at `index` to value `command`
fn update(&self, index: usize, command: bool) -> Result<(), ()> {
self.output_state.borrow_mut()[index] = command;
let output_state = self.output_state.borrow();
self.latch.borrow_mut().set_low().map_err(|_e| ())?;
for i in 1..=output_state.len() {
if output_state[output_state.len() - i] {
self.data.borrow_mut().set_high().map_err(|_e| ())?;
} else {
self.data.borrow_mut().set_low().map_err(|_e| ())?;
}
self.clock.borrow_mut().set_high().map_err(|_e| ())?;
self.clock.borrow_mut().set_low().map_err(|_e| ())?;
}
self.latch.borrow_mut().set_high().map_err(|_e| ())?;
Ok(())
}
}
impl<Pin1, Pin2, Pin3> $name<Pin1, Pin2, Pin3>
where
Pin1: OutputPin,
Pin2: OutputPin,
Pin3: OutputPin,
{
/// Creates a new SIPO shift register from clock, latch, and data output pins
pub fn new(clock: Pin1, latch: Pin2, data: Pin3) -> Self {
$name {
clock: RefCell::new(clock),
latch: RefCell::new(latch),
data: RefCell::new(data),
output_state: RefCell::new([false; $size]),
}
}
/// Get embedded-hal output pins to control the shift register outputs
pub fn decompose(&self) -> [ShiftRegisterPin; $size] {
// Create an uninitialized array of `MaybeUninit`. The `assume_init` is
// safe because the type we are claiming to have initialized here is a
// bunch of `MaybeUninit`s, which do not require initialization.
let mut pins: [MaybeUninit<ShiftRegisterPin>; $size] =
unsafe { MaybeUninit::uninit().assume_init() };
// Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
// we have a memory leak, but there is no memory safety issue.
for (index, elem) in pins.iter_mut().enumerate() {
elem.write(ShiftRegisterPin::new(self, index));
}
// Everything is initialized. Transmute the array to the
// initialized type.
unsafe { mem::transmute::<_, [ShiftRegisterPin; $size]>(pins) }
}
/// Consume the shift register and return the original clock, latch, and data output pins
pub fn release(self) -> (Pin1, Pin2, Pin3) {
let Self {
clock,
latch,
data,
output_state: _,
} = self;
(clock.into_inner(), latch.into_inner(), data.into_inner())
}
}
};
}
ShiftRegisterBuilder!(ShiftRegister8, 8);
ShiftRegisterBuilder!(ShiftRegister16, 16);
ShiftRegisterBuilder!(ShiftRegister24, 24);
ShiftRegisterBuilder!(ShiftRegister32, 32);
ShiftRegisterBuilder!(ShiftRegister40, 40);
ShiftRegisterBuilder!(ShiftRegister48, 48);
ShiftRegisterBuilder!(ShiftRegister56, 56);
ShiftRegisterBuilder!(ShiftRegister64, 64);
ShiftRegisterBuilder!(ShiftRegister72, 72);
ShiftRegisterBuilder!(ShiftRegister80, 80);
ShiftRegisterBuilder!(ShiftRegister88, 88);
ShiftRegisterBuilder!(ShiftRegister96, 96);
ShiftRegisterBuilder!(ShiftRegister104, 104);
ShiftRegisterBuilder!(ShiftRegister112, 112);
ShiftRegisterBuilder!(ShiftRegister120, 120);
ShiftRegisterBuilder!(ShiftRegister128, 128);
/// 8 output serial-in parallel-out shift register
pub type ShiftRegister<Pin1, Pin2, Pin3> = ShiftRegister8<Pin1, Pin2, Pin3>;

View File

@@ -0,0 +1,95 @@
<html>
<body>
<input type="button" id="test" value="Test">
<h2>Current Firmware</h2>
<div>
<div id="firmware_buildtime">Buildtime loading</div>
<div id="firmware_githash">Build githash loading</div>
</div>
<h2>firmeware OTA v3</h2>
<form id="upload_form" method="post">
<input type="file" name="file1" id="file1"><br>
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
<h3 id="status"></h3>
<h3 id="answer"></h3>
<p id="loaded_n_total"></p>
</form>
<h2>config</h2>
<div id="configform">
<h3>Mqtt:</h3>
<div>
<input type="text" id="mqtt_url">
MQTT Url
</div>
<div>
<input type="text" id="base_topic">
Base Topic
</div>
<h3>Tank:</h3>
<div>
<input type="checkbox" id="tank_sensor_enabled">
Enable Tank Sensor
</div>
<div>
<input type="checkbox" id="tank_allow_pumping_if_sensor_error">
Allow Pumping if Sensor Error
</div>
<div>
<input type="number" min="2" max="500000" id="tank_useable_ml">
Tank Size mL
</div>
<div>
<input type="number" min="1" max="500000" id="tank_warn_percent">
Tank Warn Percent (mapped in relation to empty and full)
</div>
<div>
<input type="number" min="0" max="100" id="tank_empty_percent">
Tank Empty Percent (% max move)
</div>
<div>
<input type="number" min="0" max="100" id="tank_full_percent">
Tank Full Percent (% max move)
</div>
<h3>Light:</h3>
<div>
Start
<select type="time" id="night_lamp_time_start">
</select>
Stop
<select type="time" id="night_lamp_time_end">
</select>
</div>
<div>
<input type="checkbox" id="night_lamp_only_when_dark">
Light only when dark
</div>
<h3>Plants:</h3>
<div>
<input type="number" min="2" max="100" id="max_consecutive_pump_count">
Max consecutive pump count:
</div>
<div id="plants"></div>
</div>
<button id="submit">Submit</button>
<div id="submit_status"></div>
<br>
<textarea id="json" cols=50 rows=10></textarea>
<script src="bundle.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,37 @@
<html>
<body>
<input type="button" id="test" value="Test">
<h2>Current Firmware</h2>
<div>
<div id="firmware_buildtime">Buildtime loading</div>
<div id="firmware_githash">Build githash loading</div>
</div>
<div>
<h2>firmeware OTA v3</h2>
<form id="upload_form" method="post">
<input type="file" name="file1" id="file1"><br>
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
<h3 id="status"></h3>
<h3 id="answer"></h3>
<p id="loaded_n_total"></p>
</form>
</div>
<div>
<h2>WIFI</h2>
<input type="button" id="scan" value="Scan">
<br>
<label for="ssid">SSID:</label>
<input type="text" id="ssid" list="ssidlist">
<datalist id="ssidlist">
<option value="Not scanned yet">
</datalist>
<label for="ssid">Password:</label>
<input type="text" id="password">
<input type="button" id="save" value="Save & Restart">
<div id="wifistatus"></div>
<br>
</div>
<script src="bundle.js"></script>
</body>
</html>

View File

@@ -0,0 +1,292 @@
//offer ota and config mode
use std::{
str::from_utf8,
sync::{atomic::AtomicBool, Arc},
};
use crate::{espota::OtaUpdate, BOARD_ACCESS};
use core::result::Result::Ok;
use embedded_svc::http::Method;
use esp_idf_svc::http::server::{Configuration, EspHttpServer};
use heapless::String;
use serde::{Deserialize, Serialize};
use crate::{
config::{Config, WifiConfig},
plant_hal::PlantCtrlBoardInteraction,
};
#[derive(Serialize, Debug)]
struct SSIDList<'a> {
ssids: Vec<&'a String<32>>,
}
#[derive(Serialize, Debug)]
struct VersionInfo<'a> {
git_hash: &'a str,
build_time: &'a str,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct TestPump {
pump: usize,
}
pub fn httpd_initial(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
let mut server = shared();
server
.fn_handler("/", Method::Get, move |request| {
let mut response = request.into_ok_response()?;
response.write(include_bytes!("initial_config.html"))?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/wifiscan", Method::Post, move |request| {
let mut response = request.into_ok_response()?;
let mut board = BOARD_ACCESS.lock().unwrap();
match board.wifi_scan() {
Err(error) => {
response.write(format!("Error scanning wifi: {}", error).as_bytes())?;
}
Ok(scan_result) => {
let mut ssids: Vec<&String<32>> = Vec::new();
scan_result.iter().for_each(|s| ssids.push(&s.ssid));
let ssid_json = serde_json::to_string(&SSIDList { ssids })?;
println!("Sending ssid list {}", &ssid_json);
response.write(ssid_json.as_bytes())?;
}
}
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/wifisave", Method::Post, move |mut request| {
let mut buf = [0_u8; 2048];
let read = request.read(&mut buf);
if read.is_err() {
let error_text = read.unwrap_err().to_string();
println!("Could not parse wificonfig {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return anyhow::Ok(());
}
let actual_data = &buf[0..read.unwrap()];
println!("raw {:?}", actual_data);
println!("Raw data {}", from_utf8(actual_data).unwrap());
let wifi_config: Result<WifiConfig, serde_json::Error> =
serde_json::from_slice(actual_data);
if wifi_config.is_err() {
let error_text = wifi_config.unwrap_err().to_string();
println!("Could not parse wificonfig {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return anyhow::Ok(());
}
let mut board = BOARD_ACCESS.lock().unwrap();
board.set_wifi(&wifi_config.unwrap())?;
let mut response = request.into_status_response(202)?;
response.write("saved".as_bytes())?;
reboot_now.store(true, std::sync::atomic::Ordering::Relaxed);
anyhow::Ok(())
})
.unwrap();
server
}
pub fn httpd(reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
let mut server = shared();
server
.fn_handler("/", Method::Get, move |request| {
let mut response = request.into_ok_response()?;
response.write(include_bytes!("config.html"))?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/get_config", Method::Get, move |request| {
let mut response = request.into_ok_response()?;
let mut board = BOARD_ACCESS.lock().unwrap();
match board.get_config() {
Ok(config) => {
let config_json = serde_json::to_string(&config)?;
response.write(config_json.as_bytes())?;
}
Err(_) => {
let config_json = serde_json::to_string(&Config::default())?;
response.write(config_json.as_bytes())?;
}
}
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/set_config", Method::Post, move |mut request| {
let mut buf = [0_u8; 3072];
let read = request.read(&mut buf);
if read.is_err() {
let error_text = read.unwrap_err().to_string();
println!("Could not parse config {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return anyhow::Ok(());
}
let actual_data = &buf[0..read.unwrap()];
println!("Raw data {}", from_utf8(actual_data).unwrap());
let config: Result<Config, serde_json::Error> = serde_json::from_slice(actual_data);
if config.is_err() {
let error_text = config.unwrap_err().to_string();
println!("Could not parse config {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return Ok(());
}
let mut board = BOARD_ACCESS.lock().unwrap();
board.set_config(&config.unwrap())?;
let mut response = request.into_status_response(202)?;
response.write("saved".as_bytes())?;
reboot_now.store(true, std::sync::atomic::Ordering::Relaxed);
Ok(())
})
.unwrap();
server
}
pub fn shared() -> Box<EspHttpServer<'static>> {
let server_config = Configuration {
stack_size: 8192,
..Default::default()
};
let mut server: Box<EspHttpServer<'static>> =
Box::new(EspHttpServer::new(&server_config).unwrap());
server
.fn_handler("/version", Method::Get, |request| {
let mut response = request.into_ok_response()?;
let git_hash = env!("VERGEN_GIT_DESCRIBE");
let build_time = env!("VERGEN_BUILD_TIMESTAMP");
let version_info = VersionInfo {
git_hash,
build_time,
};
let version_info_json = serde_json::to_string(&version_info)?;
response.write(version_info_json.as_bytes())?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/bundle.js", Method::Get, |request| {
let mut response = request.into_ok_response()?;
response.write(include_bytes!("bundle.js"))?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/favicon.ico", Method::Get, |request| {
let mut response = request.into_ok_response()?;
response.write(include_bytes!("favicon.ico"))?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/ota", Method::Post, |mut request| {
let ota = OtaUpdate::begin();
if ota.is_err() {
let error_text = ota.unwrap_err().to_string();
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return anyhow::Ok(());
}
let mut ota = ota.unwrap();
println!("start ota");
//having a larger buffer is not really faster, requires more stack and prevents the progress bar from working ;)
const BUFFER_SIZE: usize = 512;
let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
let mut total_read: usize = 0;
loop {
let read = request.read(&mut buffer).unwrap();
total_read += read;
println!("received {read} bytes ota {total_read}");
let to_write = &buffer[0..read];
let write_result = ota.write(to_write);
if write_result.is_err() {
let error_text = write_result.unwrap_err().to_string();
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return Ok(());
}
println!("wrote {read} bytes ota {total_read}");
if read == 0 {
break;
}
}
println!("finish ota");
let partition = ota.raw_partition();
println!("finalizing and changing boot partition to {partition:?}");
let finalizer = ota.finalize();
if finalizer.is_err() {
let error_text = finalizer.err().unwrap().to_string();
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return Ok(());
}
let mut finalizer = finalizer.unwrap();
println!("changing boot partition");
finalizer.set_as_boot_partition().unwrap();
finalizer.restart();
})
.unwrap();
server
.fn_handler("/boardtest", Method::Post, move |_| {
let mut board = BOARD_ACCESS.lock().unwrap();
board.test()?;
anyhow::Ok(())
})
.unwrap();
server
.fn_handler("/pumptest", Method::Post, |mut request| {
let mut buf = [0_u8; 3072];
let read = request.read(&mut buf);
if read.is_err() {
let error_text = read.unwrap_err().to_string();
println!("Could not parse testrequest {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return anyhow::Ok(());
}
let actual_data = &buf[0..read.unwrap()];
println!("Raw data {}", from_utf8(actual_data).unwrap());
let pump_test: Result<TestPump, serde_json::Error> =
serde_json::from_slice(actual_data);
if pump_test.is_err() {
let error_text = pump_test.unwrap_err().to_string();
println!("Could not parse TestPump {}", error_text);
request
.into_status_response(500)?
.write(error_text.as_bytes())?;
return Ok(());
}
let mut board = BOARD_ACCESS.lock().unwrap();
board.test_pump(pump_test.unwrap().pump)?;
anyhow::Ok(())
})
.unwrap();
server
}

1540
rust/src_webpack/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More