Five years ago, we modified our Jura coffee machine, which we nicknamed Josephine, to control it remotely via a web page. The idea was amusing but in fact this feature wasn't really useful as we still had to get up to place a cup in front of the coffee machine. But today, thanks to the Yocto-Proximity, we can do something more useful: We are going to brew a coffee as soon as a cup in placed on the machine.
We have seen in the two previous posts (here and there) how to drive the machine, but we still have to detect the presence and the absence of a cup. To do so, we are going to use our new Yocto-Proximity module.
The Yocto-Proximity is in fact ideal for this type of use: it doesn't require a mechanical part, nor a reflector, which eases quite a lot its installation in the machine.
The Yocto-Proxmitiy is used to detect the presence of a cup under the nozzles of the coffee machine
We hid the Yocto-Proximity on the left side of the machine. At this location, the Yocto-Proximity isn't at risk to receive coffee splatters and it doesn't block access to the coffee grounds container.
The scope of the Yocto-Proximity is largely enough to detect the presence of the cup under the nozzles. Moreover, as all the coffee cups we use have the same size, we can even detect if the cup is not correctly centered under the two nozzles.
The Yocto-Proxmitiy is installed on the side of the machine
Fixing the Yocto-Proximity is relatively easy as we had already modified the machine to hide the relay driving the machine. We only had to remove the machine cover and drill a small 5mm hole so that the sensor can "see" the cup.
The Yocto-Proximity targets the cup through this tiny hole
We also took this opportunity to replace the Micro-USB-Hub-v2 with a YoctoHub-Wireless-SR, in this way the coffee machine doesn't need to be directly connected to the USB port of a computer to work.
Now that we have dealt with the "mechanical" aspects, let's have a look at the software.
For the system to work, we need a small program which monitors the notified value of the Yocto-Proximity and simulates pushing on the "coffee" button of the machine with the relay connected in parallel.
The Yocto-Relay and the Yocto-Proximity are accessible via wifi thanks to the YoctoHub-Wireless-SR
We decided to write this short program in Python because you can run it easily on any machine. In this instance, the program runs on a Raspberry Pi which is always on.
At start up, the program registers the IP of the YoctoHub-Wireless-SR and checks the presence of the Yocto-Proximity and of the Yocto-Relay.
errmsg = YRefParam()
# Setup the API to use local USB devices
if YAPI.RegisterHub("192.168.1.52", errmsg) != YAPI.SUCCESS:
sys.exit("init error" + errmsg.value)
proximity = YProximity.FirstProximity()
if proximity is None:
sys.exit("No Yocto-Proximity found")
relay_power = YRelay.FindRelay("power")
if not relay_power.isOnline():
sys.exit("No relay with logical name \"power\" found")
relay_coffee = YRelay.FindRelay("coffee")
if not relay_coffee.isOnline():
sys.exit("No relay with logical name \"coffee\" found")
Then, it registers a functionValueChangeCallback callback which is called each time the value of the proximity sensor changes. The CoffeeMachine class is a very basic state automaton which brews a coffee only when there is a change from the "no cup" state to the "cup present and centered" state. To brew a coffee, we call the relay pulse() method.
READY = 1
DISPENSING = 2
CUP_MISALIGNED = 3
def __init__(self, arg_proximity, arg_relay_coffee):
self.proximity = arg_proximity
self.relay_coffee = arg_relay_coffee
self.state = None
def updateProximity(self, value):
if self.state == self.READY or self.state == self.CUP_MISALIGNED:
if value >= 1000:
if 400 < value < 800:
# cup present
elif self.state == self.DISPENSING:
if value >= 1000:
if value < 400 or value > 800:
if self.state != self.READY:
print("switch to state READY")
self.state = self.READY
if self.state != self.CUP_MISALIGNED:
print("switch to state CUP_MISALIGNED")
self.state = self.CUP_MISALIGNED
if self.state != self.DISPENSING:
print("switch to state DISPENSING")
self.state = self.DISPENSING
def functionValueChangeCallback(fct, value_str):
value = int(value_str)
coffee_machine = CoffeeMachine(proximity, relay_coffee)
YAPI.Sleep(1000, errmsg) # traps value events
The complete code is available on GitHub :
As you can see in the video, the system works well:
We even added a Yocto-Buzzer which buzzes when the cup is not centered or if nobody picks up the cup after 1 minute. This prevents scatterbrains like myself to forget their cup and drink their coffee cold ;-)