Coffee counter

Discover how a student at Thomas More University built an ESP32-powered device & serverless API to track coffee consumption and manage costs.

Coffee counter
Photo by Fahmi Fakhrudin / Unsplash

So, I'm a student at the Thomas More University of Applied Sciences in Geel, Belgium. And we have a coffee machine in our classroom, it's nothing special, just a generic Philips coffee machine.

What is special about this is that we are with about 20 students at the moment, constantly utilizing this machine. That means that costs for coffee beans start to increase rapidly. This is the reason why we have started charging 10 cents/coffee as a group effort to support the ongoing use of the coffee machine.

After 2 days we noticed that it is hard to keep track of how many coffees are being consumed, and calculating a total becomes impossible. That is the reason why I built this small project.

For this project I have made use of microcontrollers and a cloud-native serverless API.

Real world

At some point I had to create something to know who consumed a coffee. This solution had to be as simple as possible, or it would not be used. A mobile phone application was by that reason out of scope. I have then opted for creating an ESP32 powered device.

This device consists of 3 components:

  • ESP32
    A microcontroller that has WiFi, Bluetooth and quite a bit of GPIO and protocol support like SPI for example.
  • PN532
    An RFID/NFC scanner that happens to work with our student cards. It can read several types of cards, but the card we are using it with is a MIFARE Plus X card.
  • Piezo buzzer
    A simple piezo-electric buzzer. It's used for an audible feedback on a successful card scan.

With a simple ESPHome YAML file, we have completely programmed this part.

Cloudflare Workers

The coffees have to be stored somewhere, and while I could have used a relational or even a NoSQL database, this would have incurred some hosting charges monthly. Firebase was an option, but I didn't opt for this because I wanted to learn more about serverless technology, in specific Cloudflare Workers.

Using the Cloudflare wrangler CLI, I have created a base project. Afterwards I installed the itty-router package, to create some simple API routes. These routes interact with a KV (key-value) store and perform some operations on the data stored.

The ESP32 sends data to the API using a HTTP POST request to an API endpoint. The API then requests the stored coffees, adds the current one and saves the coffees back to the database. An API key is also stored in the KV store to serve as a means of ensuring that the ESP32 is the only one that can create new coffees. We wouldn't want a random person with a malicious intent to create a thousand coffees a day.

The API also contains another route that is open to the public. This route retrieves all the coffees from the KV store and then counts how many there are and sends this count back to the client. While we could have opted to just return the full array of coffees, we didn't do this to protect the identity of the coffee-consumer.

Every time a coffee is made, a student should scan the student card they have. The scanner will read the UID of the card, and send this to the API. This is the reason why we would not like to publish the UIDs of the cards as they could be linked back to a person.

A student is also able to keep track of the amount of coffees they consumed, and thus the amount they owe. We do this by counting the amount of coffees they consumed, and retrieving the total balance they have paid. This works out to a positive or negative number that tells the student if they owe money or that they have some credit left over.

Takeaways

During the creation of this project I have learned more about serverless and cloud-native technologies. I have also made use of ESPHome to program the ESP32 as an easy way to share this code with others with less knowledge of embedded code.

This was a fairly simple project and I hope to have informed you enough about the competences I gained from this experience.