Low cost, low impact queue monitoring system

I’ve been fooling around with ESP32s and a bunch of sensors lately, as you may have seen from my previous posts. To actually provide something worthwhile, it occurred to me to try and build a system that could monitor the canteen queue, and tell the students what the situation is at any given time. Lunch breaks are always a hassle at the University, when many classes attempt to have their lunch at the same time, leading to queues.

Monitor under testing in the 3D Lab
Monitor under testing in the 3D Lab

To do this, I use five HC-SR04 ultrasound sensors, one ESP32, and a two-line LCD display. All of these cost about 15 euros, since the sensors are about 90 cents apiece, and the rest are four to six euros each. Additionally, an electrician helped me by installing four wire cable into the ceiling for me to connect the sensors with.

As the University wireless network is not available for me due to security concerns, I am accessing the Internet via a 4G modem, kindly provided by our Helpdesk. In fact, I could use LoRaWAN (Long Range WAN) technology, because my payload is really small, just one string of characters once a minute, but as I have no such chip at the moment, I am going the easy way.

The sensors

The HC-SR04 is a widely used sensor, which has two little cylinders and a little piece of printed circuit board, and four pins. One cylinder sends a ultrasonic pulse, the other listens to its return, and from the elapsed time, it’s easy to calculate the distance to the object. The pins are Voltage, Ground, Trigger and Echo.

Sensors in 3D printed cases
Sensors in 3D printed cases

This device has to be used with a library, which can be found on GitHub. Once it has been imported, you can simply create an object of the type:

    mySensor1 = HCSR04(trigger_pin = 12, echo_pin = 4)
mySensor2 = HCSR04(trigger_pin = 14, echo_pin = 16)
mySensor3 = HCSR04(trigger_pin = 27, echo_pin = 17)
mySensor4 = HCSR04(trigger_pin = 26, echo_pin = 5)
mySensor5 = HCSR04(trigger_pin = 25, echo_pin = 18)

I chose the pins like this, because they form a neat block on each side of the ESP32. After this you can simply call it thus to place the value you get from the sensor into an array:

mySensorArray1[9] = mySensor1.distance_cm() 

The moving sum

The system has to have a moving sum to account for the people who don’t stand in a queue but walk below the sensor, causing it to trigger. This is done by measuring every sensor once a second, passing the value into an array, and moving the array values to the left once a second. This makes it possible to count the positive values in a ten element array, and if you have seven or more hits in ten elements, you have a queue under that sensor.

The system test bench. Note boxes that simulate students.
The system test bench. Note boxes that simulate students.

To make the moving sum, I have five arrays of ten elements each.

mySensorArray1 = [0,0,0,0,0,0,0,0,0,0]    
mySensorArray2 = [0,0,0,0,0,0,0,0,0,0]
mySensorArray3 = [0,0,0,0,0,0,0,0,0,0]
mySensorArray4 = [0,0,0,0,0,0,0,0,0,0]
mySensorArray5 = [0,0,0,0,0,0,0,0,0,0]

Then, every second, I call a function named cyclevalues:

def cycleValues(pickSensor):        
for x in range(9):
pickSensor[x] = pickSensor[x+1]

This moves all the values in the array left one place, thus making space for the new observation. It is then placed as last:

mySensorArray1[9] = mySensor1.distance_cm()

Then I find whether it is a 1 (distance less than 2/3 of the base value) or a 0 (other cases)

for x in range(9):          
if mySensorArray1[x] < 2 * mySensorBaseAvg / 3:
hitCount1 += 1

And finally, if the hitCount is > 6, it means there is a static mass of people below the sensor:

if (hitCount1 > 6 and hitCount2 > 6 and hitCount3 > 6 and hitCount4 > 6 and hitCount5 > 6 ):
myQueueStatus = "A massive queue."
elif (hitCount1 > 6 and hitCount2 > 6 and hitCount3 > 6 and hitCount4 > 6 ):
myQueueStatus = "A long queue."
elif (hitCount1 > 6 and hitCount2 > 6 and hitCount3 > 6):
myQueueStatus = "A medium queue."
elif (hitCount1 > 6 and hitCount2 > 6):
myQueueStatus = "A short queue."
elif (hitCount1 > 6):
myQueueStatus = "A minimal queue."
myQueueStatus = "No queue at all."

This piece of information, along with the actual distance values and the moving sum for each, are sent to the server once a minute.

The server part

url = "the_url_on_my_server.php"
headers = {'content-type': 'application/json'}
data = {'message': myQueueStatus + " " + myQueueSensorData + " " +myQueueSensorDist }
jsonObj = json.dumps(data)
resp = urequests.post(url, data=jsonObj, headers=headers)

The myQueueStatus, myQueueSensorData and myQueueSensorDist are just three strings that contain the data. On the server it looks like this:

11.04.2019 18:01 No queue at all A:0 B:0 C:0 D:0 E:0 A:198 B:264 C:265 D:264 E:264 
11.04.2019 18:02 No queue at all A:0 B:0 C:0 D:0 E:0 A:197 B:265 C:266 D:210 E:264
11.04.2019 18:03 No queue at all A:0 B:0 C:0 D:0 E:0 A:200 B:264 C:265 D:248 E:265
11.04.2019 18:05 No queue at all A:0 B:0 C:0 D:0 E:0 A:199 B:265 C:265 D:248 E:280

There is also a little PHP file that tells the users whether the canteen is open, then reads the status file, and shows the last five lines of the situation. Reading the text file that has hours of data in hundreds of lines is not really feasible, but for data collection purposes, the text file is to be used. Every evening at 18:00 the system moves every day’s worth of observations into a collector file, to speed up the reading of the sensor data file.

The user view into the data

While I haven’t yet been able to test this to the full, due to there not being sufficient queues at this point of the semester, I have tested this extensively in the test bench, and the basic principle is solid. When I have uploaded the entire code base and STL files into GitHub, I’ll make it available here.

See this little video of the system after installation. I am sorry for the quality of the video, because I had to recycle from Instagram. Are you following me there already?


Instagram: https://www.instagram.com/isohoo3d/
GitHub for all the code: https://github.com/HeikkiHietala/queue_sensor
ThingVerse for the STL files: https://www.thingiverse.com/thing:3560603


Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.