Automating a coffee machine with a Yocto-Proximity

Automating a coffee machine with a Yocto-Proximity

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 hardware

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
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
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
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.

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
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.

...

class CoffeeMachine(object):
    READY = 1
    DISPENSING = 2
    CUP_MISALIGNED = 3

    def __init__(self, arg_proximity, arg_relay_coffee):
        super().__init__()
        self.proximity = arg_proximity
        self.relay_coffee = arg_relay_coffee
        self.state = None
        self._set_ready_state()

    def updateProximity(self, value):
        if self.state == self.READY or self.state == self.CUP_MISALIGNED:
            if value >= 1000:
                self._set_ready_state()
                return
            if 400 < value < 800:
                # cup present
                self.relay_coffee.pulse(200)
                self._set_dispensing_state()
            else:
                self._set_missaligned_state()
        elif self.state == self.DISPENSING:
            if value >= 1000:
                self._set_ready_state()
                return
            if value < 400 or value > 800:
                self._set_missaligned_state()

    def _set_ready_state(self):
        if self.state != self.READY:
            print("switch to state READY")
            self.state = self.READY

    def _set_missaligned_state(self):
        if self.state != self.CUP_MISALIGNED:
            print("switch to state CUP_MISALIGNED")
            self.state = self.CUP_MISALIGNED

    def _set_dispensing_state(self):
        if self.state != self.DISPENSING:
            print("switch to state DISPENSING")
            self.state = self.DISPENSING


def functionValueChangeCallback(fct, value_str):
    value = int(value_str)
    global coffee_machine
    coffee_machine.updateProximity(value)

coffee_machine = CoffeeMachine(proximity, relay_coffee)
proximity.registerValueCallback(functionValueChangeCallback)

while True:
    YAPI.Sleep(1000, errmsg)  # traps value events



The complete code is available on GitHub :
https://github.com/yoctopuce-examples/josephine


Conclusion

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 ;-)




1 - moh Wednesday,april 28,2021 21H20

Hello ! That is looking very interesting, i would like to know how you choose the value of 400-800 and 1000 ?

Ty

2 - seb (Yocto-Team)Thursday,april 29,2021 6H13

@moh: Empirical testsing: We have place a the cup in front of the coffee machine multiples times and check of the value returned by the Yocto-Proximity.

Yoctopuce, get your stuff connected.