This commit is contained in:
Ollo 2021-05-21 22:09:30 +02:00
commit 5db0e2c82f
49 changed files with 16727 additions and 12704 deletions

View File

@ -18,7 +18,8 @@ There the following components are connected:
* 7 pump
* DC-DC convert (generating voltage from Lipo for pumps)
* DS18B20 temperature sensors
* water tank ultrasonic sensor (via HC_SR04)
* water tank ultrasonic sensor (via JSN-SR04T-2.0)
* DS2438 battery monitor
* general purpose expansion pin
# Software

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
update=Thu 29 Oct 2020 22:18:09 CET
update=Fri 27 Nov 2020 08:17:47 PM CET
version=1
last_client=kicad
[general]
@ -39,8 +39,9 @@ MinMicroViaDiameter=0.2
MinMicroViaDrill=0.09999999999999999
MinHoleToHole=0.25
TrackWidth1=1.2
TrackWidth2=0.25
TrackWidth2=0.2
TrackWidth3=0.5
TrackWidth4=1
ViaDiameter1=0.8
ViaDrill1=0.4
ViaDiameter2=4
@ -71,7 +72,7 @@ OthersTextUpright=1
SolderMaskClearance=0.051
SolderMaskMinWidth=0.25
SolderPasteClearance=0
SolderPasteRatio=0
SolderPasteRatio=-0
[pcbnew/Layer.F.Cu]
Name=F.Cu
Type=0

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,9 @@
EESchema-DOCLIB Version 2.0
#
$CMP CN61CN33
D Microprocessor Reset (active-low) Circuit, SOT-23
K reset supervisor
F http://www.ti.com/lit/ds/symlink/lm809.pdf
$ENDCMP
#
#End Doc Library

View File

@ -0,0 +1,67 @@
EESchema-LIBRARY Version 2.4
#encoding utf-8
#
# CN61CN33
#
DEF CN61CN33 U 0 20 Y Y 1 F N
F0 "U" 100 500 50 H V C CNN
F1 "CN61CN33" 200 400 50 H V C CNN
F2 "Package_TO_SOT_SMD:SOT-23" 300 100 50 H I C CNN
F3 "" 300 100 50 H I C CNN
$FPLIST
SOT?23*
$ENDFPLIST
DRAW
S 200 300 -200 -300 0 1 10 f
X RESET 1 0 -400 100 U 50 50 1 1 O
X GND 2 300 0 100 L 50 50 1 1 W
X VCC 3 0 400 100 D 50 50 1 1 W
ENDDRAW
ENDDEF
#
# DS2438
#
DEF DS2438 U 0 40 Y Y 1 F N
F0 "U" 0 0 50 H V C CNN
F1 "DS2438" 0 0 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
S -450 -100 500 -1200 0 1 0 f
X GND 1 -550 -250 100 R 50 50 1 1 W
X Vsens+ 2 -550 -500 100 R 50 50 1 1 U
X Vsense- 3 -550 -750 100 R 50 50 1 1 U
X Vad 4 -550 -1000 100 R 50 50 1 1 I
X Vdd 5 600 -1000 100 L 50 50 1 1 W
X NC 6 600 -750 100 L 50 50 1 1 U
X NC 7 600 -500 100 L 50 50 1 1 U
X DQ 8 600 -250 100 L 50 50 1 1 B
ENDDRAW
ENDDEF
#
# DW01
#
DEF DW01 IC 0 40 Y Y 1 L N
F0 "IC" 850 300 50 H V L BNN
F1 "DW01" 850 200 50 H V L BNN
F2 "SOT95P280X135-6N" 0 0 50 H I L BNN
F3 "" 0 0 50 H I L BNN
F4 "1.35mm" 0 0 50 H I L BNN "HEIGHT"
F5 "ic" 0 0 50 H I L BNN "DESCRIPTION"
F6 "DW01" 0 0 50 H I L BNN "MANUFACTURER_PART_NUMBER"
F7 "Slkor" 0 0 50 H I L BNN "MANUFACTURER_NAME"
DRAW
P 2 0 0 10 200 100 200 -300 N
P 2 0 0 10 200 100 800 100 N
P 2 0 0 10 800 -300 200 -300 N
P 2 0 0 10 800 -300 800 100 N
X OD 1 0 0 200 R 40 40 0 0 B
X CSI 2 0 -100 200 R 40 40 0 0 B
X OC 3 0 -200 200 R 40 40 0 0 B
X TD 4 1000 -200 200 L 40 40 0 0 B
X VDD 5 1000 -100 200 L 40 40 0 0 B
X VSS 6 1000 0 200 L 40 40 0 0 B
ENDDRAW
ENDDEF
#
#End Library

View File

@ -1,3 +1,9 @@
EESchema-DOCLIB Version 2.0
#
$CMP SR04M-2-HeaderConn_01x04_Female
D Generic connector, single row, 01x04, script generated (kicad-library-utils/schlib/autogen/connector/)
K connector
F ~
$ENDCMP
#
#End Doc Library

View File

@ -83,4 +83,42 @@ X D 3 50 200 100 D 50 50 1 1 P
ENDDRAW
ENDDEF
#
# SR04M-2
#
DEF SR04M-2 H 0 40 Y Y 1 F N
F0 "H" 250 1100 50 H V C CNN
F1 "SR04M-2" 300 -850 50 H V C CNN
F2 "" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
DRAW
S -900 1050 1650 -800 0 1 10 N
ENDDRAW
ENDDEF
#
# SR04M-2-HeaderConn_01x04_Female
#
DEF SR04M-2-HeaderConn_01x04_Female J 0 40 Y N 1 F N
F0 "J" 0 200 50 H V C CNN
F1 "SR04M-2-HeaderConn_01x04_Female" 0 -300 50 H V C CNN
F2 "ESP32:SR04M-2PinHeader_1x04_P2.54mm_Vertical" 0 0 50 H I C CNN
F3 "" 0 0 50 H I C CNN
$FPLIST
Connector*:*_1x??_*
$ENDFPLIST
DRAW
A 0 -200 20 901 -901 1 1 6 N 0 -180 0 -220
A 0 -100 20 901 -901 1 1 6 N 0 -80 0 -120
A 0 0 20 901 -901 1 1 6 N 0 20 0 -20
A 0 100 20 901 -901 1 1 6 N 0 120 0 80
P 2 1 1 6 -50 -200 -20 -200 N
P 2 1 1 6 -50 -100 -20 -100 N
P 2 1 1 6 -50 0 -20 0 N
P 2 1 1 6 -50 100 -20 100 N
X VCC 1 -200 100 150 R 50 50 1 1 W
X RX 2 -200 0 150 R 50 50 1 1 I
X TX 3 -200 -100 150 R 50 50 1 1 O
X GND 4 -200 -200 150 R 50 50 1 1 W
ENDDRAW
ENDDEF
#
#End Library

View File

@ -0,0 +1,43 @@
(module SR04M-2PinHeader_1x04_P2.54mm_Vertical (layer F.Cu) (tedit 5FC1448F)
(descr "Through hole straight pin header, 1x04, 2.54mm pitch, single row")
(tags "Through hole pin header THT 1x04 2.54mm single row")
(fp_text reference REF** (at 0 -2.33) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value SR04M-2PinHeader_1x04_P2.54mm_Vertical (at 0 9.95) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 1.8 -1.8) (end -1.8 -1.8) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.8 9.4) (end 1.8 -1.8) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.8 9.4) (end 1.8 9.4) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.8 -1.8) (end -1.8 9.4) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.33 -1.33) (end 0 -1.33) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 0) (end -1.33 -1.33) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 1.27) (end 1.33 1.27) (layer F.SilkS) (width 0.12))
(fp_line (start 1.33 1.27) (end 1.33 8.95) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 1.27) (end -1.33 8.95) (layer F.SilkS) (width 0.12))
(fp_line (start -1.33 8.95) (end 1.33 8.95) (layer F.SilkS) (width 0.12))
(fp_line (start -1.27 -0.635) (end -0.635 -1.27) (layer F.Fab) (width 0.1))
(fp_line (start -1.27 8.89) (end -1.27 -0.635) (layer F.Fab) (width 0.1))
(fp_line (start 1.27 8.89) (end -1.27 8.89) (layer F.Fab) (width 0.1))
(fp_line (start 1.27 -1.27) (end 1.27 8.89) (layer F.Fab) (width 0.1))
(fp_line (start -0.635 -1.27) (end 1.27 -1.27) (layer F.Fab) (width 0.1))
(fp_line (start 0 -17.5) (end 10 -17.5) (layer F.SilkS) (width 0.12))
(fp_line (start 10 -17.5) (end 10 23.5) (layer F.SilkS) (width 0.12))
(fp_line (start 10 23.5) (end -10 23.5) (layer F.SilkS) (width 0.12))
(fp_line (start -10 23.5) (end -10 -17.5) (layer F.SilkS) (width 0.12))
(fp_line (start -10 -17.5) (end 0.5 -17.5) (layer F.SilkS) (width 0.12))
(fp_poly (pts (xy 8.81 6.27) (xy 3.81 6.27) (xy 3.81 1.27) (xy 8.81 1.27)) (layer F.Fab) (width 0.1))
(fp_text user %R (at 0 3.81 90) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(pad 1 thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
(pad 2 thru_hole oval (at 0 2.54) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
(pad 3 thru_hole oval (at 0 5.08) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
(pad 4 thru_hole oval (at 0 7.62) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask))
(model ${KISYS3DMOD}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x04_P2.54mm_Vertical.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)

View File

@ -0,0 +1,31 @@
EESchema-LIBRARY Version 2.3
#encoding utf-8
#(c) SnapEDA 2016 (snapeda.com)
#This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA) with Design Exception 1.0
#
# SX1308
#
DEF SX1308 U 0 40 Y Y 1 L N
F0 "U" -700 800 50 H V L BNN
F1 "SX1308" -701 701 50 H V L BNN
F2 "SOT-23-6" 0 0 50 H I L BNN
F3 "" 0 0 50 H I L BNN
DRAW
P 2 0 0 10 -700 600 0 600 N
P 2 0 0 10 0 600 0 -300 N
P 2 0 0 10 0 -300 -700 -300 N
P 2 0 0 10 -700 -300 -700 600 N
P 2 0 0 10 -543 7 -443 7 N
P 2 0 0 10 -443 7 -445 66 N
P 2 0 0 10 -445 66 -345 66 N
T 0 -428 -2 32 0 0 0 ON/OFF Normal 0 L B
X SW 1 200 500 200 L 40 40 0 0 B
X FB 3 200 -100 200 L 40 40 0 0 B
X IN 5 -900 500 200 R 40 40 0 0 B
X EN 4 -900 100 200 R 40 40 0 0 B
X GND 2 -900 -200 200 R 40 40 0 0 B
X N/C 6 200 200 200 L 40 40 0 0 B
ENDDRAW
ENDDEF
#
# End Library

View File

@ -0,0 +1,42 @@
EESchema-LIBRARY Version 2.3 Date: 21-02-2013 11:13:20
#encoding utf-8
#
# ds2438az+
#
DEF ds2438az+ U 0 10 Y Y 1 L N
F0 "U" 1200 400 60 H V C CNN
F1 "ds2438az+" 1200 300 60 H V C CNN
F2 "21-0041B_8_MXM" 1200 240 60 H I C CNN
F3 "~" 0 0 60 H V C CNN
$FPLIST
21-0041B_8_MXM
21-0041B_8_MXM-M
21-0041B_8_MXM-L
$ENDFPLIST
DRAW
X GND 1 0 0 300 R 59 59 1 1 W
X VSENS+ 2 0 -100 300 R 59 59 1 1 I
X VSENS- 3 0 -200 300 R 59 59 1 1 I
X VAD 4 0 -300 300 R 59 59 1 1 I
X VDD 5 2400 -300 300 L 59 59 1 1 W
X NC 6 2400 -200 300 L 59 59 1 1 N
X NC 7 2400 -100 300 L 59 59 1 1 N
X DQ 8 2400 0 300 L 59 59 1 1 B
P 2 1 1 5 280 -100 238 -80 N
P 2 1 1 5 280 -100 238 -120 N
P 2 1 1 5 280 -200 238 -180 N
P 2 1 1 5 280 -200 238 -220 N
P 2 1 1 5 280 -300 238 -280 N
P 2 1 1 5 280 -300 238 -320 N
P 2 1 1 5 2120 0 2162 20 N
P 2 1 1 5 2120 0 2162 -20 N
P 2 1 1 5 2182 20 2223 0 N
P 2 1 1 5 2182 -20 2223 0 N
P 2 1 1 5 300 200 300 -500 N
P 2 1 1 5 300 -500 2100 -500 N
P 2 1 1 5 2100 -500 2100 200 N
P 2 1 1 5 2100 200 300 200 N
ENDDRAW
ENDDEF
#
#End Library

View File

@ -0,0 +1,21 @@
(module SOT-23-6 (layer F.Cu) (tedit 5FBEB024)
(descr "")
(fp_text reference REF** (at 0.0762369 -0.0794385 900) (layer F.SilkS)
(effects (font (size 0.600290551181 0.600290551181) (thickness 0.015)))
)
(fp_text value SOT-23-6 (at 0 0) (layer F.Fab)
(effects (font (size 0.787401574803 0.787401574803) (thickness 0.015)))
)
(fp_line (start 0.7 -1.5) (end 0.7 1.5) (layer F.SilkS) (width 0.1524))
(fp_line (start 0.7 1.5) (end -0.7 1.5) (layer F.SilkS) (width 0.1524))
(fp_line (start -0.7 1.5) (end -0.7 -1.5) (layer F.SilkS) (width 0.1524))
(fp_line (start -0.7 -1.5) (end 0.7 -1.5) (layer F.SilkS) (width 0.1524))
(fp_circle (center -1.2 -1.7) (end -0.9764 -1.7) (layer F.SilkS) (width 0.1524))
(pad 2 smd rect (at -1.35 0.0) (size 1.0 0.55) (layers F.Cu F.Mask F.Paste))
(pad 1 smd rect (at -1.35 -0.95) (size 1.0 0.55) (layers F.Cu F.Mask F.Paste))
(pad 3 smd rect (at -1.35 0.95) (size 1.0 0.55) (layers F.Cu F.Mask F.Paste))
(pad 4 smd rect (at 1.35 0.95) (size 1.0 0.55) (layers F.Cu F.Mask F.Paste))
(pad 6 smd rect (at 1.35 -0.95) (size 1.0 0.55) (layers F.Cu F.Mask F.Paste))
(pad 5 smd rect (at 1.35 0.0) (size 1.0 0.55) (layers F.Cu F.Mask F.Paste))
)

View File

@ -0,0 +1,30 @@
(module SOT95P280X135-6N (layer F.Cu) (tedit 5FAC25EE)
(descr "<b>SOT2-23-6</b><br>")
(fp_text reference REF** (at 0.0 0.0 0) (layer F.SilkS)
(effects (font (size 1.0 1.0) (thickness 0.015)))
)
(fp_text value SOT95P280X135-6N (at 0.0 0.0 0) (layer F.Fab)
(effects (font (size 1.0 1.0) (thickness 0.015)))
)
(fp_line (start -2.125 -1.835) (end 2.125 -1.835) (layer F.Fab) (width 0.05))
(fp_line (start 2.125 -1.835) (end 2.125 1.835) (layer F.Fab) (width 0.05))
(fp_line (start 2.125 1.835) (end -2.125 1.835) (layer F.Fab) (width 0.05))
(fp_line (start -2.125 1.835) (end -2.125 -1.835) (layer F.Fab) (width 0.05))
(fp_line (start -0.8 -1.46) (end 0.8 -1.46) (layer F.Fab) (width 0.1))
(fp_line (start 0.8 -1.46) (end 0.8 1.46) (layer F.Fab) (width 0.1))
(fp_line (start 0.8 1.46) (end -0.8 1.46) (layer F.Fab) (width 0.1))
(fp_line (start -0.8 1.46) (end -0.8 -1.46) (layer F.Fab) (width 0.1))
(fp_line (start -0.8 -0.51) (end 0.15 -1.46) (layer F.Fab) (width 0.1))
(fp_line (start -0.275 -1.46) (end 0.275 -1.46) (layer F.SilkS) (width 0.2))
(fp_line (start 0.275 -1.46) (end 0.275 1.46) (layer F.SilkS) (width 0.2))
(fp_line (start 0.275 1.46) (end -0.275 1.46) (layer F.SilkS) (width 0.2))
(fp_line (start -0.275 1.46) (end -0.275 -1.46) (layer F.SilkS) (width 0.2))
(fp_line (start -1.875 -1.6) (end -0.625 -1.6) (layer F.SilkS) (width 0.2))
(pad 1 smd rect (at -1.25 -0.95) (size 1.25 0.6) (layers F.Cu F.Mask F.Paste))
(pad 2 smd rect (at -1.25 0.0) (size 1.25 0.6) (layers F.Cu F.Mask F.Paste))
(pad 3 smd rect (at -1.25 0.95) (size 1.25 0.6) (layers F.Cu F.Mask F.Paste))
(pad 4 smd rect (at 1.25 0.95) (size 1.25 0.6) (layers F.Cu F.Mask F.Paste))
(pad 5 smd rect (at 1.25 0.0) (size 1.25 0.6) (layers F.Cu F.Mask F.Paste))
(pad 6 smd rect (at 1.25 -0.95) (size 1.25 0.6) (layers F.Cu F.Mask F.Paste))
)

View File

@ -0,0 +1,94 @@
(module 21-0041B_8_MXM (layer F.Cu)
(fp_text reference REF** (at 0 0) (layer F.SilkS)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text value 21-0041B_8_MXM (at 0 0) (layer F.SilkS)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "Copyright 2016 Accelerated Designs. All rights reserved." (at 0 0) (layer Cmts.User)
(effects (font (size .127 .127) (thickness .002)))
)
(fp_text user "*" (at -2.97815 -3.5814) (layer F.SilkS)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "*" (at -1.6129 -2.4257) (layer F.Fab)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "0.05in/1.27mm" (at -5.77215 -1.27) (layer Dwgs.User)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "0.021in/0.533mm" (at 5.77215 -1.905) (layer Dwgs.User)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "0.214in/5.448mm" (at 0 -4.9149) (layer Dwgs.User)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "0.058in/1.46mm" (at -2.72415 4.9149) (layer Dwgs.User)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "*" (at -2.97815 -3.5814) (layer F.SilkS)
(effects (font (size 1 1) (thickness .15)))
)
(fp_text user "*" (at -1.6129 -2.4257) (layer F.Fab)
(effects (font (size 1 1) (thickness .15)))
)
(fp_line (start -1.9939 -1.6637) (end -1.9939 -2.1463) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 -2.1463) (end -3.0988 -2.1463) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 -2.1463) (end -3.0988 -1.6637) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 -1.6637) (end -1.9939 -1.6637) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 -.3937) (end -1.9939 -.8763) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 -.8763) (end -3.0988 -.8763) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 -.8763) (end -3.0988 -.3937) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 -.3937) (end -1.9939 -.3937) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 .8763) (end -1.9939 .3937) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 .3937) (end -3.0988 .3937) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 .3937) (end -3.0988 .8763) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 .8763) (end -1.9939 .8763) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 2.1463) (end -1.9939 1.6637) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 1.6637) (end -3.0988 1.6637) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 1.6637) (end -3.0988 2.1463) (layer F.Fab) (width .1524))
(fp_line (start -3.0988 2.1463) (end -1.9939 2.1463) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 1.6637) (end 1.9939 2.1463) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 2.1463) (end 3.0988 2.1463) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 2.1463) (end 3.0988 1.6637) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 1.6637) (end 1.9939 1.6637) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 .3937) (end 1.9939 .8763) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 .8763) (end 3.0988 .8763) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 .8763) (end 3.0988 .3937) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 .3937) (end 1.9939 .3937) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 -.8763) (end 1.9939 -.3937) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 -.3937) (end 3.0988 -.3937) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 -.3937) (end 3.0988 -.8763) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 -.8763) (end 1.9939 -.8763) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 -2.1463) (end 1.9939 -1.6637) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 -1.6637) (end 3.0988 -1.6637) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 -1.6637) (end 3.0988 -2.1463) (layer F.Fab) (width .1524))
(fp_line (start 3.0988 -2.1463) (end 1.9939 -2.1463) (layer F.Fab) (width .1524))
(fp_line (start -2.1209 2.6289) (end 2.1209 2.6289) (layer F.SilkS) (width .1524))
(fp_line (start 2.1209 -2.6289) (end -2.1209 -2.6289) (layer F.SilkS) (width .1524))
(fp_line (start -1.9939 2.5019) (end 1.9939 2.5019) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 2.5019) (end 1.9939 -2.5019) (layer F.Fab) (width .1524))
(fp_line (start 1.9939 -2.5019) (end -1.9939 -2.5019) (layer F.Fab) (width .1524))
(fp_line (start -1.9939 -2.5019) (end -1.9939 2.5019) (layer F.Fab) (width .1524))
(fp_line (start -3.7084 2.4257) (end -3.7084 -2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start -3.7084 -2.4257) (end -2.2479 -2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start -2.2479 -2.4257) (end -2.2479 -2.7559) (layer F.CrtYd) (width .1524))
(fp_line (start -2.2479 -2.7559) (end 2.2479 -2.7559) (layer F.CrtYd) (width .1524))
(fp_line (start 2.2479 -2.7559) (end 2.2479 -2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start 2.2479 -2.4257) (end 3.7084 -2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start 3.7084 -2.4257) (end 3.7084 2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start 3.7084 2.4257) (end 2.2479 2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start 2.2479 2.4257) (end 2.2479 2.7559) (layer F.CrtYd) (width .1524))
(fp_line (start 2.2479 2.7559) (end -2.2479 2.7559) (layer F.CrtYd) (width .1524))
(fp_line (start -2.2479 2.7559) (end -2.2479 2.4257) (layer F.CrtYd) (width .1524))
(fp_line (start -2.2479 2.4257) (end -3.7084 2.4257) (layer F.CrtYd) (width .1524))
(fp_arc (start 0 -2.5019) (end .3048 -2.5019) (angle 180)(layer F.Fab) (width .1524))
(pad 1 smd rect (at -2.72415 -1.905) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 2 smd rect (at -2.72415 -.635) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 3 smd rect (at -2.72415 .635) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 4 smd rect (at -2.72415 1.905) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 5 smd rect (at 2.72415 1.905) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 6 smd rect (at 2.72415 .635) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 7 smd rect (at 2.72415 -.635) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
(pad 8 smd rect (at 2.72415 -1.905) (size 1.4605 .5334) (layers F.Cu F.Paste F.Mask))
)

View File

@ -1,6 +1,7 @@
(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 PlantCtrlESP32-rescue)(type Legacy)(uri ${KIPRJMOD}/PlantCtrlESP32-rescue.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 ""))
)

3
esp32/.gitignore vendored
View File

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

7
esp32/.vscode/extensions.json vendored Normal file
View File

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

View File

@ -6,15 +6,19 @@
],
"settings": {
"files.associations": {
"functional": "cpp",
"*.tcc": "cpp",
"map": "cpp",
"*.cps": "javascript",
"bitset": "cpp",
"algorithm": "cpp",
"istream": "cpp",
"limits": "cpp",
"streambuf": "cpp",
"functional": "cpp",
"string": "cpp",
"typeinfo": "cpp"
"typeinfo": "cpp",
"cmath": "cpp",
"iterator": "cpp"
}
}
}

View File

@ -18,6 +18,7 @@ Uses ESP32MiniKit
* Solar powered (voltage)
* Lipo-Powered (voltage)
* Temperature
* Distance sensor [JSN-SR04T-2.0] (for waterlevel)
* Custom GPIO
## Documentation of Power-Modes
@ -41,35 +42,18 @@ DS18B20 one wire temp sensor
## 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
* [x] Zeitspann (wann laufen darf)
* [x] Helligkeitstrigger (Um den Morgen zum pumpen zu erkennen)
* [-] Maximal Dauer zum Pumpen (als Zeit oder Milliliter)
* [x] Zeitspanne zwischen zwei Pumpvorgängen
* Moister sensor
* Oberen
* Unteren Wert
* [x] Schwellwert für Pumpe
* 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
* [x] Maximaler Wasserstand des Tanks (in cm & Liter)
## Masterplan 2.0
* Partitionslayout

View File

@ -0,0 +1,17 @@
[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

@ -7,3 +7,6 @@ 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```

View File

@ -43,65 +43,62 @@
*/
#ifndef CONTROLLER_CONFIG_H
#define CONTROLLER_CONFIG_H
/** \addtogroup Configuration
/** \addtogroup GPIO Settings
* @{
*/
#define FIRMWARE_VERSION "1.0.9"
#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(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.69) /**< 33k and 47k8 voltage dividor */
#define MS_TO_S 1000
#define SENSOR_LIPO 34 /**< GPIO 34 (ADC1) */
#define SENSOR_SOLAR 35 /**< GPIO 35 (ADC1) */
#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 14 /**< GPIO 14 (ADC2) */
#define SENSOR_PLANT6 12 /**< GPIO 12 (ADC2) */
#define SENSOR_PLANT5 39 /**< SENSOR_VIN */
#define SENSOR_PLANT6 36 /**< SENSOR_VP */
#define OUTPUT_PUMP0 23 /**< GPIO 23 */
#define OUTPUT_PUMP1 22 /**< GPIO 22 */
#define OUTPUT_PUMP2 21 /**< GPIO 21 */
#define OUTPUT_PUMP0 15 /**< GPIO 15 */
#define OUTPUT_PUMP1 5 /**< GPIO 5 */
#define OUTPUT_PUMP2 18 /**< GPIO 18 */
#define OUTPUT_PUMP3 19 /**< GPIO 19 */
#define OUTPUT_PUMP4 18 /**< GPIO 18 */
#define OUTPUT_PUMP5 5 /**< GPIO 5 */
#define OUTPUT_PUMP6 15 /**< GPIO 15 */
#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 OUTPUT_ENABLE_SENSOR 14 /**< GPIO 14 - Enable Sensors */
#define OUTPUT_ENABLE_PUMP 13 /**< GPIO 13 - Enable Pumps */
#define SENSOR_DS18B20 2 /**< GPIO 2 - Temperatur sensor */
#define SENSOR_ONEWIRE 4 /**< GPIO 12 - Temperatur sensor, Battery and other cool onewire stuff */
#define SENSOR_TANK_ECHO 16 /**< GPIO 16 - echo feedback of water sensor */
#define SENSOR_TANK_TRG 17 /**< GPIO 17 - trigger for water sensor */
#define BUTTON 0 /**< GPIO 0 - Fix button of NodeMCU */
#define CUSTOM1_PIN3 2 /**< GPIO 2 - Custom GPIO controlling a MOSFET, connected to GND */
#define CUSTOM1_PIN2 12 /**< GPIO 4 - custom GPIO directly connected to GPIO header */
#define I2C1_PIN2 34 /**< GPIO 34 - I2C */
#define I2C1_PIN3 35 /**< GPIO 35 - I2C */
/* @} */
/** \addtogroup Configuration
* @{
*/
#define FIRMWARE_VERSION "1.1.0"
#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 MQTT_TIMEOUT (1000 * 10) /**< After 10 seconds, MQTT is expected to be connected */
#define MIN_TIME_RUNNING 5UL /**< Amount of seconds the controller must stay awoken */
#define MAX_PLANTS 7
#define MINIMUM_LIPO_VOLT 3.6f /**< 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 HC_SR04 /**< Ultrasonic distance sensor to measure water level */
#define SENSOR_SR04_ECHO 17 /**< GPIO 17 - Echo */
#define SENSOR_SR04_TRIG 23 /**< GPIO 23 - Trigger */
#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 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 DS18B20_RESOLUTION 9 /**< 9bit temperature resolution -> 0.5°C steps */
/* @} */
#endif

View File

@ -1,56 +0,0 @@
/**
* @file DS18B20.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-06-09
*
* @copyright Copyright (c) 2020
* Based on the LUA code from the ESP8266
* --------------------------------------------------------------------------------
* -- DS18B20 one wire module for NODEMCU
* -- NODEMCU TEAM
* -- LICENCE: http://opensource.org/licenses/MIT
* -- Vowstar <vowstar@nodemcu.com>
* -- 2015/02/14 sza2 <sza2trash@gmail.com> Fix for negative values
* --------------------------------------------------------------------------------
*/
#ifndef DS18B20_H
#define DS18B20_H
#include <OneWire.h>
class Ds18B20
{
private:
OneWire *mDs;
int foundDevices;
public:
Ds18B20(int pin)
{
this->mDs = new OneWire(pin);
}
~Ds18B20()
{
delete this->mDs;
}
/**
* @brief read amount sensots
* check for available of DS18B20 sensors
* @return amount of sensors
*/
int readDevices(void);
/**
* @brief Read all temperatures in celsius
*
* @param pTemperatures array of float valuies
* @param maxTemperatures size of the given array
* @return int amount of read temperature values
*/
int readAllTemperatures(float *pTemperatures, int maxTemperatures);
};
#endif

107
esp32/include/DS2438.h Normal file
View File

@ -0,0 +1,107 @@
/**
* @file DS2438.h
*
*
*/
#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

@ -19,18 +19,36 @@
#define MAX_PLANTS 7
/**
* @name Attributes
* @name Homie Attributes
* generated Information
* @{
**/
#define NUMBER_TYPE "number" /**< numberic information, published or read in Homie */
/**
* @name Temperatur Node
* @{
**/
#define TEMPERATURE_NAME "Temperature"
#define TEMPERATURE_UNIT "°C"
#define TEMPERATUR_SENSOR_LIPO "lipo" /**< Homie node: temperatur, setting: lipo temperatur (or close to it) */
#define TEMPERATUR_SENSOR_CHIP "chip" /**< Homie node: temperatur, setting: battery chip */
#define TEMPERATUR_SENSOR_WATER "water" /**< Homie node: temperatur, setting: water temperatur */
/** @}
*
* @name Plant Nodes
* @{
*/
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 plant2("plant2", "Plant 2", "Plant"); /**< dynamic Homie information for third plant */
HomieNode plant3("plant3", "Plant 3", "Plant"); /**< dynamic Homie information for fourth plant */
HomieNode plant4("plant4", "Plant 4", "Plant"); /**< dynamic Homie information for fivth plant */
HomieNode plant5("plant5", "Plant 5", "Plant"); /**< dynamic Homie information for sixth plant */
HomieNode plant6("plant6", "Plant 6", "Plant"); /**< dynamic Homie information for seventh plant */
HomieNode sensorLipo("lipo", "Battery Status", "Lipo");
HomieNode sensorSolar("solar", "Solar Status", "Solarpanel");
@ -38,15 +56,16 @@ HomieNode sensorWater("water", "WaterSensor", "Water");
HomieNode sensorTemp("temperature", "Temperature", "temperature");
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> deepSleepTime("deepsleep", "time in seconds to sleep");
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");
@ -54,6 +73,8 @@ HomieSetting<long> waterLevelMax("watermaxlevel", "distance (mm) at maximum wate
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<const char *> lipoSensorAddr("lipoTempAddr", "1wire address for lipo temperature sensor");
HomieSetting<const char *> waterSensorAddr("waterTempIndex", "1wire address for water temperature sensor");
HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as default)");
/**
@ -70,12 +91,12 @@ HomieSetting<const char *> ntpServer("ntpServer", "NTP server (pool.ntp.org as d
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<bool> mPumpOnlyWhenLowLight##plant = HomieSetting<bool>("onlyWhenLowLightZ" strplant, "Plant" strplant " - Enable the Pump only, when there is no sunlight"); \
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 all settings for one plant \
* \
* Feature to start pumping only at morning: @link{SOLAR_CHARGE_MIN_VOLTAGE} and @link{SOLAR_CHARGE_MAX_VOLTAGE} \
*/
/**

View File

@ -24,6 +24,7 @@ private:
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;
@ -97,25 +98,28 @@ public:
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;
}
/**
* @brief Get the Hours when pumping should start
*
* @return hour
*/
int getHoursStart() {
return this->mSetting->pPumpAllowedHourRangeStart->get();
}
/**
* @brief Get the Hours when pumping should end
*
* @return hour
*/
int getHoursEnd() {
return this->mSetting->pPumpAllowedHourRangeEnd->get();
}
bool isAllowedOnlyAtLowLight(void)
{
return this->mSetting->pPumpOnlyWhenLowLight->get();

View File

@ -0,0 +1,27 @@
/**
* @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

@ -15,10 +15,12 @@ framework = arduino
build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
board_build.partitions = defaultWithSmallerSpiffs.csv
upload_port=/dev/ttyUSB0
; 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,103 +0,0 @@
/**
* @file DS18B20.cpp
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-06-09
*
* @copyright Copyright (c) 2020
*
*/
#include "DS18B20.h"
#define STARTCONV 0x44
#define READSCRATCH 0xBE // Read EEPROM
#define TEMP_LSB 0
#define TEMP_MSB 1
#define SCRATCHPADSIZE 9
#define OFFSET_CRC8 8 /**< 9th byte has the CRC of the complete data */
//Printf debugging
//#define DS_DEBUG
int Ds18B20::readDevices()
{
byte addr[8];
int amount = -1;
while (this->mDs->search(addr))
{
amount++;
}
this->mDs->reset_search();
return amount;
}
int Ds18B20::readAllTemperatures(float *pTemperatures, int maxTemperatures)
{
byte addr[8];
uint8_t scratchPad[SCRATCHPADSIZE];
int currentTemp = 0;
while (this->mDs->search(addr))
{
this->mDs->reset();
this->mDs->select(addr);
this->mDs->write(STARTCONV);
}
delay(750);
while (this->mDs->search(addr))
{
this->mDs->reset();
this->mDs->select(addr);
this->mDs->write(READSCRATCH);
// Read all registers in a simple loop
// byte 0: temperature LSB
// byte 1: temperature MSB
// byte 2: high alarm temp
// byte 3: low alarm temp
// byte 4: DS18S20: store for crc
// DS18B20 & DS1822: configuration register
// byte 5: internal use & crc
// byte 6: DS18S20: COUNT_REMAIN
// DS18B20 & DS1822: store for crc
// byte 7: DS18S20: COUNT_PER_C
// DS18B20 & DS1822: store for crc
// byte 8: SCRATCHPAD_CRC
for (uint8_t i = 0; i < 9; i++)
{
scratchPad[i] = this->mDs->read();
}
uint8_t crc8 = this->mDs->crc8(scratchPad, 8);
/* Only work an valid data */
if (crc8 == scratchPad[OFFSET_CRC8])
{
int16_t fpTemperature = (((int16_t)scratchPad[TEMP_MSB]) << 11) | (((int16_t)scratchPad[TEMP_LSB]) << 3);
float celsius = (float)fpTemperature * 0.0078125;
#ifdef DS_DEBUG
Serial.printf("\r\nTemp%d %f °C (Raw: %d, %x =? %x)\r\n", (currentTemp + 1), celsius, fpTemperature, crc8, scratchPad[8]);
#endif
/* check, if the buffer as some space for our data */
if (currentTemp < maxTemperatures)
{
pTemperatures[currentTemp] = celsius;
}
else
{
return -1;
}
}
currentTemp++;
}
this->mDs->reset();
#ifdef DS_DEBUG
Serial.println(" No more addresses.");
Serial.println();
#endif
return currentTemp;
}

255
esp32/src/DS2438.cpp Normal file
View File

@ -0,0 +1,255 @@
/*
* 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

@ -19,6 +19,7 @@ Plant::Plant(int pinSensor, int pinPump, int plantId, HomieNode *plant, PlantSet
this->mPinPump = pinPump;
this->mPlant = plant;
this->mSetting = setting;
this->mPlantId = plantId;
}
void Plant::init(void)
@ -53,6 +54,9 @@ 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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
<?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

@ -0,0 +1,28 @@
{
"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",
"array": "cpp",
"deque": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"initializer_list": "cpp",
"regex": "cpp"
}
}
}

View File

@ -1,52 +0,0 @@
/**
* @file DS18B20.h
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-06-09
*
* @copyright Copyright (c) 2020
* Based on the LUA code from the ESP8266
* --------------------------------------------------------------------------------
* -- DS18B20 one wire module for NODEMCU
* -- NODEMCU TEAM
* -- LICENCE: http://opensource.org/licenses/MIT
* -- Vowstar <vowstar@nodemcu.com>
* -- 2015/02/14 sza2 <sza2trash@gmail.com> Fix for negative values
* --------------------------------------------------------------------------------
*/
#ifndef DS18B20_H
#define DS18B20_H
#include <OneWire.h>
class Ds18B20 {
private:
OneWire* mDs;
int foundDevices;
public:
Ds18B20(int pin) {
this->mDs = new OneWire(pin);
}
~Ds18B20() {
delete this->mDs;
}
/**
* @brief read amount sensots
* check for available of DS18B20 sensors
* @return amount of sensors
*/
int readDevices(void);
/**
* @brief Read all temperatures in celsius
*
* @param pTemperatures array of float valuies
* @param maxTemperatures size of the given array
* @return int amount of read temperature values
*/
int readAllTemperatures(float* pTemperatures, int maxTemperatures);
};
#endif

View File

@ -0,0 +1,112 @@
/*
* 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

@ -14,3 +14,6 @@ board = esp32doit-devkit-v1
framework = arduino
build_flags = -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
lib_deps = OneWire
DallasTemperature
upload_port = /dev/ttyUSB1

View File

@ -1,105 +0,0 @@
/**
* @file DS18B20.cpp
* @author your name (you@domain.com)
* @brief
* @version 0.1
* @date 2020-06-09
*
* @copyright Copyright (c) 2020
*
*/
#include "DS18B20.h"
#define STARTCONV 0x44
#define READSCRATCH 0xBE // Read EEPROM
#define TEMP_LSB 0
#define TEMP_MSB 1
#define SCRATCHPADSIZE 9
#define OFFSET_CRC8 8 /**< 9th byte has the CRC of the complete data */
//Printf debugging
//#define DS_DEBUG
int Ds18B20::readDevices() {
byte addr[8];
int amount = -1;
while (this->mDs->search(addr)) {
amount++;
}
this->mDs->reset_search();
return amount;
}
int Ds18B20::readAllTemperatures(float* pTemperatures, int maxTemperatures) {
byte addr[8];
uint8_t scratchPad[SCRATCHPADSIZE];
int currentTemp = 0;
while (this->mDs->search(addr)) {
#ifdef DS_DEBUG
Serial.print(" ROM =");
for (i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
#endif
this->mDs->reset();
this->mDs->select(addr);
this->mDs->write(STARTCONV);
this->mDs->reset();
this->mDs->select(addr);
this->mDs->write(READSCRATCH);
// Read all registers in a simple loop
// byte 0: temperature LSB
// byte 1: temperature MSB
// byte 2: high alarm temp
// byte 3: low alarm temp
// byte 4: DS18S20: store for crc
// DS18B20 & DS1822: configuration register
// byte 5: internal use & crc
// byte 6: DS18S20: COUNT_REMAIN
// DS18B20 & DS1822: store for crc
// byte 7: DS18S20: COUNT_PER_C
// DS18B20 & DS1822: store for crc
// byte 8: SCRATCHPAD_CRC
#ifdef DS_DEBUG
Serial.write("\r\nDATA:");
for (uint8_t i = 0; i < 9; i++) {
Serial.print(scratchPad[i], HEX);
}
#else
delay(50);
#endif
for (uint8_t i = 0; i < 9; i++) {
scratchPad[i] = this->mDs->read();
}
uint8_t crc8 = this->mDs->crc8(scratchPad, 8);
/* Only work an valid data */
if (crc8 == scratchPad[OFFSET_CRC8]) {
int16_t fpTemperature = (((int16_t) scratchPad[TEMP_MSB]) << 11)
| (((int16_t) scratchPad[TEMP_LSB]) << 3);
float celsius = (float) fpTemperature * 0.0078125;
#ifdef DS_DEBUG
Serial.printf("\r\nTemp%d %f °C (Raw: %d, %x =? %x)\r\n", (currentTemp+1), celsius, fpTemperature, crc8, scratchPad[8]);
#endif
/* check, if the buffer as some space for our data */
if (currentTemp < maxTemperatures) {
pTemperatures[currentTemp] = celsius;
} else {
return -1;
}
}
currentTemp++;
}
this->mDs->reset();
#ifdef DS_DEBUG
Serial.println(" No more addresses.");
Serial.println();
#endif
return currentTemp;
}

View File

@ -0,0 +1,286 @@
/*
* 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,23 +1,20 @@
#include <Arduino.h>
#include "esp_sleep.h"
#include <DS18B20.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_LIPO 34 /**< GPIO 34 (ADC1) */
#define SENSOR_SOLAR 35 /**< GPIO 35 (ADC1) */
#define SENSOR_DS18B20 2 /**< GPIO 2 */
#define OUTPUT_PUMP0 23 /**< GPIO 23 */
#define OUTPUT_PUMP1 22 /**< GPIO 22 */
#define OUTPUT_PUMP2 21 /**< GPIO 21 */
#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 18 /**< GPIO 18 */
#define OUTPUT_PUMP5 5 /**< GPIO 5 */
#define OUTPUT_PUMP6 15 /**< GPIO 15 */
#define OUTPUT_PUMP4 21 /**< GPIO 18 */
#define OUTPUT_PUMP5 15 /**< GPIO 5 */
#define OUTPUT_PUMP6 23 /**< GPIO 15 */
#define OUTPUT_SENSOR 16 /**< GPIO 16 - Enable Sensors */
#define OUTPUT_PUMP 13 /**< GPIO 13 - Enable Pumps */
@ -36,7 +33,10 @@ RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int pumpActive = 0;
int secondBootCount = 0;
Ds18B20 ds(SENSOR_DS18B20);
OneWire oneWire(SENSOR_DS18B20);
DallasTemperature temp(&oneWire);
DS2438 battery(&oneWire,0.1f);
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
@ -49,24 +49,34 @@ void print_wakeup_reason(){
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;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\r\n",wakeup_reason); break;
}
}
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);
bool whatever = true;
void setAll2to(int state) {
Serial.println("Set GPIO" + String(OUTPUT_PUMP0) + "=" + String(state));
digitalWrite(OUTPUT_PUMP0, state);
Serial.println("Set GPIO" + String(OUTPUT_PUMP1) + "=" + String(state));
digitalWrite(OUTPUT_PUMP1, state);
Serial.println("Set GPIO" + String(OUTPUT_PUMP2) + "=" + String(state));
digitalWrite(OUTPUT_PUMP2, state);
Serial.println("Set GPIO" + String(OUTPUT_PUMP3) + "=" + String(state));
digitalWrite(OUTPUT_PUMP3, state);
Serial.println("Set GPIO" + String(OUTPUT_PUMP4) + "=" + String(state));
digitalWrite(OUTPUT_PUMP4, state);
Serial.println("Set GPIO" + String(OUTPUT_PUMP5) + "=" + String(state));
digitalWrite(OUTPUT_PUMP5, state);
Serial.println("Set GPIO" + String(OUTPUT_PUMP6) + "=" + String(state));
digitalWrite(OUTPUT_PUMP6, state);
Serial.println("Set GPIO" + String(OUTPUT_SENSOR) + "=" + String(state));
digitalWrite(OUTPUT_SENSOR, state);
}
void setup() {
Serial.begin(115200);
pinMode(OUTPUT_PUMP0, OUTPUT);
pinMode(OUTPUT_PUMP1, OUTPUT);
pinMode(OUTPUT_PUMP2, OUTPUT);
@ -76,14 +86,8 @@ void setup() {
pinMode(OUTPUT_PUMP6, OUTPUT);
pinMode(OUTPUT_SENSOR, OUTPUT);
pinMode(OUTPUT_PUMP, OUTPUT);
pinMode(SENSOR_LIPO, ANALOG);
pinMode(SENSOR_SOLAR, ANALOG);
pinMode(SENSOR_PLANT0, ANALOG);
setAll2Off();
Serial.begin(115200);
//Increment boot number and print it every reboot
++bootCount;
@ -92,83 +96,79 @@ void setup() {
//Print the wakeup reason for ESP32
print_wakeup_reason();
Serial.println("------- build from " + String(__DATE__) + "=" + String(__TIME__) + " @ " + String(millis()) + "ms");
Serial.println("Set GPIO" + String(OUTPUT_PUMP) + "=" + String(LOW));
digitalWrite(OUTPUT_PUMP, LOW);
/*
First we configure the wake up source
We set our ESP32 to wake up every 5 seconds
*/
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) +
" Seconds");
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_OFF);
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL,ESP_PD_OPTION_ON);
pinMode(GPIO_NUM_32, ANALOG);
digitalWrite(GPIO_NUM_32, HIGH);
pinMode(GPIO_NUM_33, INPUT_PULLUP);
digitalWrite(GPIO_NUM_33, HIGH);
pinMode(GPIO_NUM_25, INPUT_PULLUP);
digitalWrite(GPIO_NUM_25, HIGH);
pinMode(GPIO_NUM_26, INPUT_PULLUP);
pinMode(GPIO_NUM_27, INPUT_PULLUP);
pinMode(GPIO_NUM_14, INPUT_PULLUP);
pinMode(GPIO_NUM_12, INPUT_PULLUP);
/* Sensor activieren */
digitalWrite(OUTPUT_SENSOR, HIGH);
setAll2to(HIGH);
delay(1000);
Serial.println("--------------------------" + String(" @ ") + String(millis()) + "ms");
setAll2to(LOW);
delay(1000);
Serial.println("--------------------------" + String(" @ ") + String(millis()) + "ms");
/* activate power pump and pump 0 */
digitalWrite(OUTPUT_PUMP, HIGH);
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() {
double value = analogRead(SENSOR_LIPO);
static int loop=1;
Serial.println(value);
float temp[2] = {0, 0};
float* pFloat = temp;
DeviceAddress t;
for(int i=0; i < sizeof(t); i++) {
t[i] = loop + i*2;
}
char buf[sizeof(DeviceAddress)*2];
snprintf(buf, sizeof(buf), "%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X", t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
/*
%X -> linksbündige hexzahl
%2X -> 2Stellige hexzahl ... dynamisch erweitert
%0.2X -> 2stellige hexzahl mit führerder "0"
*/
printf("Print: %s\n", buf);
loop++;
delay(500);
return;
Serial.print("DS18B20 sensors: ");
Serial.println(ds.readDevices());
delay(200);
if (ds.readAllTemperatures(pFloat, 2) > 0) {
Serial.println(temp[0]);
Serial.println(temp[1]);
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();
}
double volt = ADC_5V_TO_3V3(value);
Serial.print("Lipo: ");
Serial.println(volt);
pumpActive = (pumpActive + 1) % 2;
if (pumpActive) {
digitalWrite(OUTPUT_PUMP0, HIGH);
} else {
digitalWrite(OUTPUT_PUMP0, LOW);
for(int j=0; j < 5 && (0 == battery.isFound()); j++) {
delay(10);
Serial.println("Reset 1wire bat");
battery.begin();
battery.update();
}
double solarVal = analogRead(SENSOR_SOLAR);
Serial.println(solarVal);
double solarVolt = SOLAR_VOLT(solarVal);
Serial.print("Solar: ");
Serial.println(solarVolt);
Serial.print("Moist0: ");
Serial.println(analogRead(SENSOR_PLANT0));
delay(1000);
gpio_deep_sleep_hold_en();
gpio_hold_en(GPIO_NUM_13);
esp_deep_sleep_start();
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);
}

Binary file not shown.

BIN
sheets/DS2438.pdf Normal file

Binary file not shown.

BIN
sheets/DSE-CN61C.pdf Normal file

Binary file not shown.

BIN
sheets/esp32s.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB