-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapplication.lua
More file actions
182 lines (151 loc) · 4.4 KB
/
Copy pathapplication.lua
File metadata and controls
182 lines (151 loc) · 4.4 KB
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
182
-- Simple HC-SR04 application
-- Copyright 2019, Marcin Gil <marcin.gil--gmail.com>
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- Derived work from Vinícius Serafim <vinicius@serafim.eti.br>
-- see: https://github.com/vsserafim/hcsr04-nodemcu/blob/master/hcsr04-simple.lua
-- This application requires several modules of NodeMCU firmware
-- encoder
-- file
-- gpio
-- mqtt
-- net
-- node
-- tmr
-- uart
-- wifi
-- It also requires an LFS (Lua File Storage) of at least 32KB
PIN_TRIG = 4
PIN_ECHO = 3
-- trig interval in microseconds (minimum is 10, see HC-SR04 documentation)
TRIG_INTERVAL = 15
-- maximum distance in meters
MAXIMUM_DISTANCE = 10
-- minimum reading interval with 20% of margin
READING_INTERVAL = math.ceil(((MAXIMUM_DISTANCE * 2 / 340 * 1000) + TRIG_INTERVAL) * 1.2)
-- number of readings to average
AVG_READINGS = 3
-- CONTINUOUS MEASURING
CONTINUOUS = true
-- interval between scheduling continous reading; 1 minute
CONTINUOUS_INTERVAL = 1 * 60 * 1000
-- notify to MQTT
PUBLISH = true
MQTT_TOPIC = "coal"
MQTT_CLIENTID = "coalo"
-- initialize global variables
time_start = 0
time_stop = 0
distance = 0
readings = {}
trig_timer = {}
cont_timer = {}
mqtt_client = {}
-- start a measure cycle
function measure()
print("Measuring starts")
readings = {}
trig_timer:start()
end
-- called when measure is done
function done_measuring()
print("Distance: "..string.format("%.3f", distance).." Readings: "..#readings)
if CONTINUOUS then
print("Scheduling next measure")
if not cont_timer:start() then
print("WARN: unable to start continuous measure!")
end
end
if PUBLISH then
print("Scheduling measure publishing")
node.task.post(publish)
end
end
-- distance calculation, called by the echo_callback function on falling edge.
function calculate()
print("Calculate")
-- echo time (or high level time) in microseconds
local echo_time = (time_stop - time_start)
-- got a valid reading
if echo_time > 0 then
-- distance = echo time (or high level time) in microseconds * velocity of sound (340M/S) / 2
local distance = echo_time * 0.034 / 2
table.insert(readings, distance)
end
-- got all readings
if #readings >= AVG_READINGS then
print("Calculate: enough readings")
trig_timer:stop()
-- calculate the average of the readings
distance = 0
for k,v in pairs(readings) do
distance = distance + v
end
distance = math.floor(distance / #readings)
node.task.post(done_measuring)
end
print("Calculate exit")
end
-- publish measurement to the MQTT
function publish()
print("Publishing "..distance)
mqtt_client.publish(tostring(distance))
end
-- callback for MQTT commands
function mqtt_command(message)
print("Received: " .. message)
if message == "update" then
print("Forcing update")
measure()
end
end
-- echo callback function called on both rising and falling edges
function echo_callback(level, timestamp)
print("Callback at LVL="..level.." with T="..timestamp)
if level == 1 then
print("Echo start")
-- rising edge (low to high)
-- time_start = tmr.now()
time_start = timestamp
else
print("Echo stop")
-- falling edge (high to low)
-- time_stop = tmr.now()
time_stop = timestamp
calculate()
end
end
-- send trigger signal
function trigger()
print("Triggering")
gpio.write(PIN_TRIG, gpio.HIGH)
tmr.delay(TRIG_INTERVAL)
gpio.write(PIN_TRIG, gpio.LOW)
end
print("Setup")
-- configure pins
gpio.mode(PIN_TRIG, gpio.OUTPUT)
gpio.mode(PIN_ECHO, gpio.INT)
-- trigger timer
trig_timer = tmr.create()
trig_timer:register(READING_INTERVAL, tmr.ALARM_AUTO, trigger)
-- set callback function to be called both on rising and falling edges
gpio.trig(PIN_ECHO, "both", echo_callback)
-- configure CONTINUOUS timers
if CONTINUOUS then
print("Create continuous trigger")
cont_timer = tmr.create()
cont_timer:register(CONTINUOUS_INTERVAL, tmr.ALARM_SEMI, measure)
end
-- configure MQTT if enabled
if PUBLISH then
dofile("mqtt.lua")
-- MQTT host, port, user and password should be defined in the `credentials.lua`; see init.lua
mqtt_client = MqttClient(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASSWORD, MQTT_TOPIC, MQTT_CLIENTID, mqtt_command)
mqtt_client.connect()
end
print("Setup finished")
print("Initializing first measure")
measure()