Matemat vending machine hardware
Go to file
2022-01-16 23:59:32 +01:00
avr-can-lib@137b1710c4 Added avr-can-lib submodule 2021-01-11 00:23:20 +01:00
control More rerouting 2019-04-01 22:29:00 +02:00
display Added display print API 2022-01-16 23:59:32 +01:00
drive Updated LM317L part from library 2021-01-10 14:11:42 +01:00
feedback Corrected 2000x delay increase 2021-02-08 22:10:49 +01:00
power Added display print API 2022-01-16 23:59:32 +01:00
poweriface Init power outputs to zero on startup 2021-01-25 20:58:15 +01:00
sensor ignore parts cache 2020-07-26 17:23:16 +02:00
uncanny Added display print API 2022-01-16 23:59:32 +01:00
wiring wiring: Added some descriptions 2020-08-24 20:16:26 +02:00
.gitignore Added control server 2021-01-31 16:56:33 +01:00
.gitmodules Added avr-can-lib submodule 2021-01-11 00:23:20 +01:00
AUTHORS Added author list, readme and hardware license 2015-04-07 20:01:00 +02:00
displaymount.scad Added mount parameters for some of the PCBs 2021-05-04 23:53:58 +02:00
feedbackmount.scad Added mount parameters for some of the PCBs 2021-05-04 23:53:58 +02:00
hatmount.scad Added mount parameters for some of the PCBs 2021-05-04 23:53:58 +02:00
LICENSE Added author list, readme and hardware license 2015-04-07 20:01:00 +02:00
messages.h Fix display command structure 2021-05-04 23:51:16 +02:00
mount.scad Added PCB mount CAD template 2021-05-04 23:53:12 +02:00 Document display interface commands 2021-03-06 13:10:44 +01:00


The Matemat is a vending machine for carbonated soft drinks.

It is based on an old vending machine with all its electronics replaced by new custom-build circuit boards.

All hardware and software was designed by members of CCC Basel and released in the form of circuit diagrams, printed circuit board layouts and source code for anyone to use and modify. Refer to the LICENSE file for details.

The name "Matemat" is a portmanteau of "mate" (as in yerba mate and "automat" (the German word for vending machine). The device is mainly intended to dispense mate tea based soft drinks, but may be used for other types of beverages too.


The heart of the vending machine is a Raspberry Pi model 3 or zero or later, with a custom CAN interface board on its GPIO header.

See CAN Hat for more information.


Some of the modules require firmware. There is a makefile in each module's firmware directory to build and flash the firmware to the integrated microcontroller

Before building, you need to check out the CAN driver source code, which is referenced as a Git submodule.

Run the following commands in the checked out repository:

git submodule init
git submodule update


The Matemat components are highly modular. Individual circuits are connected by CAN bus, and can be extended as needed.


Single-motor driver.

Attached directly to each bottle release mechanism. Requires only power supply wires for the motor and the CAN bus line.


Motor driver board and power supply.

Alternative to the drive board. Uses the existing machine wiring instead of power + CAN.


Old central control board. Obsolete.


End switch feedback interface.

Senses the status of the end switches and sends CAN bus messages on changes.

This module requires firmware. Connect an Atmel programmer to the ISP header of the feedback board, make sure the programming jumper is shorted and run:

cd feedback/firmware/
make flash


Interface between CAN bus and power board.

This module requires firmware. Connect an Atmel programmer to the ISP header of the poweriface board, make sure the programming jumper is shorted and run:

cd poweriface/firmware/
make flash


VFD (vaccum fluorescent display) interface.

This module requires firmware. Connect an Atmel programmer to the ISP header of the poweriface board, make sure the programming jumper is shorted and run:

cd display
make flash

This module provides a direct interface to the display controller's instruction and data registers. Refer to the 16T202DA1J data sheet, or any NEC dot matrix display controller data sheet for instruction codes and memory layout.


Environment sensor interface. Unused at the moment.


Wring schema of the old vending machine.


Central controller software. Has a simple HTTP API for controlling output and checking the current fill status of each slot.

The controller is written in Go, must be compiled before use:

cd uncanny/
go build ./cmd/uncanny

Note that CGO is required because the source code makes use of the global messages.h C header file. If you need to cross-compile, use the following command (-a cleans the cache, may be necessary when messages.h changes):

GOARCH=arm GOOS=linux CGO_ENABLED=1 CC=arm-linux-gnueabi-gcc go build -a -o uncanny-linux-arm ./cmd/uncanny

The resulting uncanny executable should be running on the controlling Raspberry Pi. An example SystemD unit is provided in server/uncanny.service. Copy uncanny to /usr/bin, install the service file to /lib/systemd/system/uncanny.service and enable it with:

cd uncanny/
cp uncanny /usr/bin/
cp uncanny.service /lib/systemd/system/
systemctl daemon-reload
systemctl enable uncanny.service

A working CAN bus is required to run uncanny. You need to make sure the bus is initialized at boot. On RaspberryOS/Raspbian/Debian, this can be achieved with the following lines in /etc/network/interfaces:

auto can0
iface can0 inet manual
    pre-up /sbin/ip link set $IFACE type can bitrate 125000 loopback off sample-point 0.75
    up /sbin/ip link set $IFACE up
    down /sbin/ip link set $IFACE down



All modules are connected via a CAN bus. It is highly recommended to wire them by means of shielded twisted-pair cable with a nominal impedance of 120Ω. At the very least, you need a cable with three wires to ensure a good ground connection between all modules.

To allow for easy wiring, six-pole screw terminals are mounted to the PCBs. Two poles are intended for the positive CAN bus line, two for the negative line and two for the shield. They are internally connected together.


To achieve a continuous bus topology, connect only two cables to each module. Make sure CAN H is connected to CAN H and CAN L to CAN L. Crossover is not supported on the CAN bus. When wiring is complete, you should end up with a continuous bus that is tapped at each module. Attach 120Ω resistors (preferably 1% or better) to the ends of the bus.

The final wiring should look like this:

┌───────────┐   ┌───────────┐   ┌───────────┐
│  module1  │   │  module2  │   │  module3  │
│           │   │           │   │           │
│H L ⏚ H L ⏚│   │H L ⏚ H L ⏚│   │H L ⏚ H L ⏚│
└╥─╥─╥─╥─╥─╥┘   └╥─╥─╥─╥─╥─╥┘   └╥─╥─╥─╥─╥─╥┘
 ╰━╯   └╥┘╱      └╥┘╱  └╥┘╱      └╥┘╱  ╰━╯
 120Ω   ║╱        ║╱    ║╱        ║╱   120Ω
        ╚═════════╝     ╚═════════╝


Bus communication only makes use of basic CAN features. No higher-level protocols such as CiA, EtherCAN, VSCP or similar are required.

Normal 11-bit CAN adressing mode is used. For messages that support RTR, any module can send a remote transmission request and the addressed module will respond with the described message. A module may also send the message without being probed.

This is the list of supported message IDs:

Message ID Sender Receiver RTR Support? Data Length Data Format Description
0x10 feedback any yes 2 0b00000KJI 0bHGFEDCBA Feedback module status report (A..E = end switch D..H, F..J = empty switch D..H, K = reset switch, 0 = off, 1 = on)
0x11 poweriface any yes 2 0bHHHHHHHH 0bLLLLLLLL Power module status report (0xHHLL are the contents of the 16-bit shift register)
0x12 display any yes 1 0bHGFEDCBA Display module button status (A..H = button 0..7, 0 = off, 1 = on)
0x21 controller poweriface no 1 0b00000MMM Start dispensing from slot M (1-5) or stop all dispensers (M = 0)
0x22 controller display no 1-8 0bAAAAAAAA 0bDDDDDDDD* Write address A into display instruction register and data bytes D (0-7 bytes) into data register
0x4f any any no 1 0b0000000E Enable (E = 1) or disable (E = 0) automatic status updates on all modules