Create a Useful BLE Solution and Win a Hackathon
A few months back, Polidea held an awesome internal event—Hackathon. Or, should we say BLEckathon, as the one-day competition evolved around Bluetooth Low Energy. The teams consisting of Polidea’s finest graphic designers, UX designers, and engineers, had to come up with a unique, tech solution for connected devices. This article is brought to you by the proud winners of the competition—creators of the Coffee is Light project.
Here’s what it’s all about and how we did it.
We love our coffee at Polidea. A while ago, we bought one of those Moccamaster coffee makers. It makes excellent java, but there is one problem. When you finally decide to go to the kitchen and grab some, you never know if you will find an empty pot or not. We thought it would be cool if we could get a notification in some way when someone starts brewing and when the process is finished. It would also be nice if we could know how much coffee is currently in the pot. Those were our requirements for the project.
We had many ideas on how to approach this BLE solution problem. To name the best ones:
One of the most straightforward solutions was the optical detection of coffee in the pot. Since coffee is black, we considered putting LED on one side of the pot and a phototransistor on the other side. This way, we could get a binary signal determining if there is still a certain level of coffee in the pot. Of course, we wouldn’t be able to get more precise information about the coffee level, neither to determine if someone started brewing coffee. We were also worried about reliability.
The next idea involved analyzing a live camera image of the coffee pot using OpenCV. That way, we could get rather precise information about the coffee level. We could detect if someone started brewing as well. But, reliability was once again a concern here. We would need to attach the camera to the wall behind the coffee maker. Any accidental bump could result in the coffee pot getting off the center of the camera image. That could result in faulty measurements of the coffee level.
Our last and final approach was to analyze the weight of the coffee maker. In that way, we could determine how much coffee is still in the pot, and when someone started brewing.
Instead of using one weight sensor, we settled on using two of them—on the left and right side of the coffee maker. This enabled us to measure how weight distribution changes over time, thus making a precise monitoring of the brewing process possible.
Of course, there were a few problems with this approach, as well. We had to remember that some of the water stays in the coffee grains. People also put the lids at different moments in time during the brewing process, which disrupts weight measurements. Regardless of the few challenges with this approach, it had one huge advantage—it should be more reliable than any other of our ideas. We wanted to put weight sensors in base attached to the coffee maker, which should eliminate any problems connected to it’s accidental movements.
One of the most widely used weight sensors is the tensometric beam. We decided that we will use them in our project as well. To interface with those sensors, we picked HX711 24bit ADC— made especially for such applications—and Raspberry Pi Zero W as a processing unit. The limited amount of time during the hackathon led us to the Python language, which helps with fast prototyping. We also needed a Bluetooth Low Energy connection for the light bulb, and we wanted to use WiFi to connect to our office network.
First, we mounted our load cells and made simple wooden construction with sensors attached on the left and right sides of the mounting plate. After firmly screwing everything together, we painted wooden parts to protect them from any moisture and coffee spillages.
As soon as we got the hardware platform up and running, we started checking if our assumptions about the weight distribution are correct. We put the coffee machine on the “scale” that we had made and recorded the process of the coffee brewing. We recorded not only the video but mainly the data received from the two tensometer beams that represent the weight on each side of the coffee machine.
You can see the recording here:
The first version of the firmware produced just a simple CSV file where each row contains a timestamp and weight samples. You can see it on the laptop screen on the video above. Then, we used Matlab to visualize and analyze this data. After the first try with a simple plot, smiles appeared on our faces. We already knew that it would work! Here’s what we saw.
The above screenshot represents almost raw measurements. We applied only a simple median filter, as we previously had seen that hx711 modules occasionally provide completely wrong samples.
The left side is the one with the water tank, while the right side is the one with the pot.
Basing on that chart, we invented and implemented an algorithm that can tell us three things that adequately describe the state of the coffee machine:
- if there’s coffee ready to drink in the pot,
- the amount of the liquid (the sum of coffee and the water) in the coffee machine,
- the progress of the brewing (current value in percentages).
From the beginning, we also wanted our algorithm to meet the following requirements:
- To correctly handle (or ignore) garbage data produced while somebody is touching, cleaning, or interacting physically with the coffee machine in any other way.
- To be state independent. By that, we mean that we won’t model every state that the coffee machine could be in, nor the transitions between them. We didn’t have time for such extensive modeling, and that would probably be more error-prone.
- To easily recover from strange situations or, in other words, to be “troll-proof.” We can’t avoid nor handle all hilarious jokes when somebody puts a bottle of milk on the top of the coffee machine, but at least we wanted to seamlessly recover from that weird state as soon as it disappears.
First, we are checking if anyone interacts physically with the coffee machine. That’s done by checking if, during last (let’s say) 10 seconds, the sum of left and right weights is constant. If it’s not, we are skipping the data. If it’s constant, then we know the amount of liquid in the coffee machine.
Then, we are checking if the brewing is in progress. That’s done by verifying the constantness of the left and right weight separately. When the sum is constant while the left and right are not—the brewing process is ongoing. Here, we are sending the notification that the process started (if it wasn’t in progress in the previous iteration of the loop) and calculating the progress, which depends on the ratio between the left and right weight.
If both sides’ weights are constant and there is a noticeable amount of liquid in the coffee machine, we check which side is heavier and decide if it’s the water in the water tank or the coffee in the pot. The algorithm described above is illustrated in the flowchart below.
After making a few adjustments related to the definition of weight constancy and classification of brewing process initiation, we ended up with a perfect solution. Seriously, it works like a charm without any modifications, and there are neither false positives nor false negatives on the output. We’ve tested the algorithm first on the previously collected data, and then, after the deployment in Polidea’s kitchen, we also checked it against real data generated by people making coffee. Here are the input and output of the algorithm for the data that you’ve already seen above.
During BLEckathon, we had to tap into Bluetooth Low Energy, of course. Not everyone wants to be notified (and disrupted) every time somebody else is making coffee. That’s why slack notification is not a perfect way to do it :)
We needed a solution that anyone can ask if there’s coffee whenever he or she wants it. What could better fit that need than a lightbulb mounted in the open space, which is visible for nearly everyone in the office? We’ve found RGB lightbulb controlled over BLE—PLAYBULB candle form MIPOW. Controlling it is pretty straightforward—you just need to set a value of a proper Bluetooth characteristic.
However, as soon as we had received and tested the lightbulb, we found that light is unacceptably dim. It wouldn’t be visible in our bright office. We had few extremely bright RGB Power LEDs that would be perfect. We’ve opened the lightbulb and found the PWM signals that steer the RGB LED. They appeared to be “active low.” Therefore we needed a couple of P-MOSFETs, which we didn’t have at the time. Here, our supportive organizers came to the rescue. They bought the transistors in the local store, and an hour later, we had everything to supercharge the lightbulb with extra power in a hacky way :)
Here is the schematic of the existent LEDs and the way we injected our simple super-bright LED circuit.
As you can see, to avoid rapid battery draining, we are using a separate power supply for the additional bright LED. In that way, the lightbulb works as before (using the batteries) when the power supply is disconnected. In the picture below, you can see the difference between the standard light and the one modified by us. Both are displaying that there’s still (but not much) coffee to drink.
As if that wasn’t enough to hit the jackpot, we’ve made an extra “wow” effect with a web interface. At the beginning of the hackathon, we planned it as a nice to have feature. Fortunately, because of the smart work distribution, we managed to finish that as well. As you know, we are collecting much more data than it’s needed to turn the lightbulb on when there’s a coffee. We have real-time, detailed information about the brewing progress. The web interface takes advantage of that data and shows the brewing process in real-time, as you can see below:
During a hackathon, there’s no time to implement top-notch patterns or follow the best practices. Time to get a working solution takes priority over the source code’s quality and durability. Hackathons are always like that, and our case wasn’t different. To easily divide the work across the team, we needed to agree on the API between the modules. This approach was the winning factor that allowed us to work in parallel. We decided to write independent scripts for the weight analyzer, lightbulb driver, and web server. To communicate between these scripts, we just used a JSON file. Weight analyzer was saving the current state of the coffee machine into this file in a loop. Then, the lightbulb driver and web server were reading this file to do their job. Extremely easy, and it worked! Until a month after the deploy in our kitchen. We’ve outworn the SD card in the Raspberry Pi, and the whole system stopped working. Now we are joking about our IPCOJ (inter-process communication over JSON), but it’s still there. We fixed the issue by moving the file to a ramdisk.
Surprisingly, there are no more problems with the project. It has been working already for a few months, is actively used and appears to be incredibly bulletproof.
You can check the source code of our solution here.
It was a great pleasure to participate in Polidea’s hackathon and be able to work on such cool solutions with the team. Especially because we’ve made something that really solves an existing issue. Our colleagues at Polidea welcomed Coffee is Light with open arms which gives us a lot of satisfaction. Also, the project appeared to be pretty complex, with different, independent modules. Spreading the work across our tightly-knit team ensured our success.
If you’re looking for a partner for your Bluetooth Low Energy project—give us a call!
Lead Software Engineer
Senior Software Engineer