-
Notifications
You must be signed in to change notification settings - Fork 3
/
Tank_Code4-VL53L1.be
182 lines (127 loc) · 6.33 KB
/
Tank_Code4-VL53L1.be
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#- This is using a VL53L1 time of flight optical sensor to check the current volume
of a fuel-oil heating tank. The sensor measures the distance from the
sensor to the fuel oil and returns a value in millimeters.
We then convert this to inches, do a table lookup from the tank
manufacturers datasheet to get the current volume remaining in the tank.
We display the data on the web page and send it via MQTT.
This version is doing a linear interpolation of the manufacturers table to
get a more precise volume,
Please note, at this time in Tasmota 11.x.x. One need to disable all I2C device
in your user_config_override.h file that your not using to enable the VL53L1X
Add to: tasmota/user_config_override.h and re-compile
This will enable I2C on GPIO 22 and 23
#define USER_TEMPLATE "{\"NAME\":\"Tank Sensor VL53L1X\",\"GPIO\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,608,640,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],\"FLAG\":0,\"BASE\":1,\"CMND\":\"SetOption8 1\",\"CMND\":\"Module 0\"}"
#ifndef USE_VL53L1X
#define USE_VL53L1X
#endif
#define USE_BERRY_DEBUG
#define I2CDRIVERS_0_31 0x00000000
#define I2CDRIVERS_32_63 0x00400000 // enable only device 54, the VL53L1
#define I2CDRIVERS_64_95 0x00000000
To load this file, compile Tasmota32 with the option above...
Then Load the new binary image in your ESP32 and re-boot it.
Open the web page for this device, select Console, then Manage File System
Rename this Berry file to "autoexec.be", then upload it to the ESP32 file system.
Reboot Tasmota, this Berry file will run after re-booting.
-#
#- *************************************** -#
#-
CHANGE LOG:
DATE REV DESCRIPTION
----------- --- ----------------------------------------------------------
28-Jan-2022 1.0 TRL - 1st release
26-Feb-2022 1.1 TRL - Linear Interpolation version
Notes: 1) Tested with 11.0.1(tasmota)
ToDo: 1)
-#
#- *************************************** -#
class FOTank : Driver
var tank_data
#build an global array-->list to store sensor for filtering
static buf = []
# this table is from the tank manufacturer datasheet, showing total gallons in inches, 44 entries plus a extra entry at top of table.
static Tank275 = [2,5,9,14,19,25,31,37,44,51,58,65,72,80,87,94,101,108,115,123,130,137,144,151,158,166,173,180,187,194,201,209,216,223,230,236,243,249,254,260,265,269,272,275,275]
#- *************************************** -#
def tank()
#- *************************************** -#
def table_lookup(MyTank, dist)
var top = MyTank.size()
#print ("Top: ", top)
#let's do a bounds check...
if (dist >= top - 1 ) return MyTank.item(top-1) end
if (dist <= 0 ) return MyTank.item(0) end
var t6 = MyTank.item(int(dist))
var t7 = MyTank.item(int(dist+1))
var t1 = real (int (dist+1) - int(dist)) # in our case is always = 1
var t2 = real (dist - int(dist)) # spacing from index
var t3 = real (t7 - t6) # delta from table entry
if ( t1 == 0) return t6 end # check for zero delta in table (division by zero check)
var t4 = real ( t6 + ((t2 * t3) / t1) )
return t4 # return gallons in tank
end
#- *************************************** -#
var TableLength = self.Tank275.size() # 45
var TableTop = TableLength -1 # 44
var tank_offset = -25 # offset from VL53L1 to top of tank
var MaxBuf = 120 # filtering buffer size
#print ("\n")
# Read Sensor data
import json
var sensors=json.load(tasmota.read_sensors())
if !(sensors.contains('VL53L1X')) return end
var d = sensors['VL53L1X']['Distance']
#print("Dist: ", d)
if (self.buf.size() >= MaxBuf) self.buf.pop(0) end # remove oldest entry
self.buf.push(d) # add new sensor reading to list
d = 0
for i : 0 .. (self.buf.size() - 1 ) # let's sum all of the entrys in the array
d = d + self.buf.item (i)
end
d = d / self.buf.size() # average the sensor data from the array
#print("Dist-avg: ", d)
d = d + tank_offset # adjust for sensor to tank offset (dead zone)
# Convert from MM to inch
var d1 = real ((d / 25.4) ) # 25.4 mm per inch
if (d1 > TableTop) d1 = TableTop end # do a bounds check, 0 --> 44
if (d1 <= 0) d1 = 0 end
#print("Inch: ",d1)
var d9 = real (TableTop - d1) # do table lookup, from end of table
var d2 = table_lookup (self.Tank275, d9)
#print ("Gal: ",d2)
var d3 = ((d2 / self.Tank275.item(TableTop)) * 100 ) # calculate percent of full
d3 = int(d3 + .5) # round up is needed
#print ("Percent:", d3)
self.tank_data = [int (d), d1, d2, d3] # return the data, Raw-MM, Inch, Gal, %
return self.tank_data
end
#- *************************************** -#
def every_second()
if !self.tank return nil end
self.tank()
end
#- *************************************** -#
def web_sensor()
import string
if !self.tank_data return nil end # exit if not initialized
var msg = string.format(
"{s}Distance - offset{m}%.f mm{e}"..
"{s}Distance{m}%7.2f inches{e}"..
"{s}Volume{m}%7.2f gal{e}"..
"{s}Percent Full{m}%.f %%{e}",
self.tank_data[0],self.tank_data[1],self.tank_data[2],self.tank_data[3])
tasmota.web_send_decimal(msg)
end
#- *************************************** -#
def json_append()
if !self.tank_data return nil end
import string
var msg = string.format(",\"Tank\":{\"Distance_mm\":%.f,\"Distance_Inches\":%7.2f,\"Volume\":%7.2f,\"Percent_Full\":%.f}",
self.tank_data[0],self.tank_data[1],self.tank_data[2],self.tank_data[3])
tasmota.response_append(msg)
end
end
#- *************************************** -#
FOTank = FOTank()
tasmota.add_driver(FOTank)
#- ************ The Very End ************* -#