Week 12 — XIAO Vending Machine
For the machine design group assignment, our team designed and prototyped a vending machine for selling Seeed Studio XIAO Series development boards. The project covers ideation, planning, component selection, and prototype testing.
The full pipeline runs end-to-end: a user taps a pre-programmed RFID card on the machine, a Wio Terminal reads the card over I2C, verifies the embedded credit token, and — only if the card carries the TRUE payload — drives two STS3215 serial-bus servos to swing the column gates and drop a single XIAO board into the output chute. Every step is mirrored on the Wio Terminal's built-in LCD so the user can follow what the machine is doing.
The build below documents the whole journey: the brainstorm, the architecture, the bill of materials, three rounds of subsystem testing, the mechanical integration of the warehouse column with the servo arm, the final wiring inside the 3D-printed enclosure, and a complete demo of the finished prototype.
Final demo of the XIAO Vending Machine: card tap → authentication → servo dispense → XIAO board delivered.
For the future, we shall leverage the serial-bus servos and build more warehouse columns.
And launch the vending backend system

and the warehouse design is depending on the product's itself, which means it is not only the xiao but it can be types that shares one shape and form.

1. Idea Generation
We started by brainstorming what kind of machine would be useful in a makerspace context. The idea of a vending machine for XIAO boards came up quickly — it solves a real problem: making dev boards available to makers on demand, without staffing a counter.
The team's initial brainstorming session. We outlined the system flow: user authentication, payment, inventory monitoring, and product dispensing.
From the brainstorm, we converged on a set of core requirements for the machine:
| Requirement | Description |
|---|---|
| Easy to use (易用) | Simple tap-and-go interaction via RFID card |
| Affordable (便宜) | Low-cost components, reuse of makerspace materials |
| Durable (耐用) | Robust mechanical structure for repeated use |
| Compact (体积小) | Small footprint suitable for a desk or counter |
| Eye-catching (醒目) | Transparent acrylic case to showcase the products inside |
The machine would support both in-store and remote purchasing (via an agent system), with inventory monitoring and a digital payment flow.
2. Planning and Design
With the concept locked, we moved to detailed planning. The whiteboard below captures our full design — timeline, case sketch, component legend, and materials list.
Timeline
| Phase | Task | Target |
|---|---|---|
| 1a | Case and 3D parts cutting and printing | Week 12 |
| 1b | Wio Terminal with reader and controller testing | Week 12 |
| 2a | Gate assembly testing | Week 12 |
| 2b | Vending system on PC programming | Week 12 |
| 3 | Assemble as one, test, integrate, record videos | Week 12 |
| 4 | Real production | By the Week 20 |
Vending Machine Architecture
The case design uses a column-based dispensing structure: products are stacked vertically and dispensed from the top to the bottom. The structure is built from:
- Acrylic panels (transparent) for the outer case
- 3D-printed parts (transparent, modular) linked by metal columns
- Metal columns running from the output chute to the user-receiving area
- Joints/latches for assembly and access
System Components
3. Component Selection
We balanced cost and performance to select each component. All parts are either off-the-shelf Seeed products or affordable serial bus servos.
Central Controller: Wio Terminal
The Wio Terminal serves as the brain of the vending machine. It provides a built-in 2.4" LCD screen for status display, Grove connectors for sensor hookup, programmable buttons, and WiFi/BLE for connectivity.
Why Wio Terminal?
- Built-in screen eliminates the need for a separate display module
- Two Grove ports(I2C and UART) allow direct connection to the RFID reader and servo bus
- Compact form factor fits inside the vending machine case
- Programmable buttons can serve as manual overrides
Moving Parts: STS3215 Serial Bus Servo
The STS3215 servo is a serial bus servo that can be daisy-chained on a single communication line. This dramatically simplifies wiring — instead of one signal wire per servo, all servos share one serial bus controlled by the Wio Terminal.
Why STS3215?
- Single-line serial bus control (daisy-chainable)
- Position feedback for precise gate control
- Sufficient torque for the dispensing mechanism
- Affordable compared to traditional smart servos
Output Structure
The dispensing mechanism uses a single-column design: products are loaded from the top and dispensed downward through servo-controlled gates. Each column holds multiple XIAO boards stacked vertically, and a gate at the bottom releases one unit at a time.
Payment: Grove RFID Reader
A Grove-compatible RFID module handles user authentication and payment. It communicates with the Wio Terminal via I2C at 13.56 MHz.
| Spec | Value |
|---|---|
| Operating voltage | 5V |
| Operating current | 13–100 mA |
| Frequency | 13.56 MHz |
| Protocol | I2C |
| Supported cards | RFID tags, key fobs, IC cards |
Workflow:
- A PC-based vending system writes product and credit info to RFID cards
- Users tap the RFID card on the vending machine reader
- The Wio Terminal verifies the card, triggers the servo gate, and dispenses the product
4. Prototype Testing
With all components selected, we built a working prototype and ran three rounds of testing.
Test 1: Wio Terminal + RFID Integration
First integration test connecting the Wio Terminal with the RFID writer. The system successfully reads card data and displays status on the LCD.
Test 2: Servo Movement
Testing the STS3215 servo for gate control. The servo moves to precise positions to open and close the dispensing gate.
Test 3: Structure Assembly
Assembling the physical structure and testing the full mechanical flow — from product loading to dispensing.
5. Integration: Servo + Warehouse Column
With the individual components validated, the next step was integrating the servo mechanism with the warehouse column — the core dispensing unit of the vending machine.
3D-Printed Servo Arm
We designed a custom arm to connect the STS3215 servo to the dispensing gate. The arm was 3D-printed with mounting holes that align with the servo spline and the column latch mechanism.
The 3D-printed bar attaches directly to the servo horn. The mounting holes allow it to interface with the column gate, converting rotational motion into a push/pull action that releases one XIAO at a time.
Column Warehouse Assembly
The column warehouse holds XIAO boards stacked vertically. Each column acts as a gravity-fed magazine — when the gate at the bottom opens, the lowest board drops out and the rest slide down.
The assembled warehouse column with boards loaded. The transparent structure lets users see the remaining stock at a glance.
Manual Dispensing Test
Before wiring everything to the Wio Terminal, we tested the mechanism manually — pushing the 3D-printed arm to simulate the servo action and confirming that a single XIAO board is dispensed cleanly each time.
Manually actuating the servo arm to push a XIAO out of the column. This validates the mechanical clearance and confirms the gate-release design works before electronic integration.
RFID + Wio Terminal Testing
After validating the mechanical system, we integrated the RFID module with the Wio Terminal to test card reading functionality.
Testing RFID card interaction on the Wio Terminal. The system reads the card and prepares for triggering the dispensing mechanism.
Full Integration: Servo + RFID + Wio Terminal
In this stage, both the servo system and RFID reader were connected to the Wio Terminal. All wiring was organized and enclosed inside the 3D-printed case for a clean and compact setup.
Full system integration test. The RFID card triggers the Wio Terminal, which controls the servo to simulate the dispensing process.
6. Assemble All Together
With all subsystems tested individually, we proceeded to assemble everything into a complete machine.
Final assembly process. The pin diagram is referenced to ensure correct wiring, and all components are mounted securely inside the structure.
7. Final System Demonstration
System Initialization and Workflow
This video demonstrates the complete system workflow:
- Checking RFID reader, LCD, and servo status
- Pressing Button A on the Wio Terminal to initialize
- Reading RFID card
- Triggering servo to dispense product
The system successfully reads the RFID card and dispenses a XIAO RP2040 board. The servo operates twice to ensure reliable output.
Servo Operation & Output Mechanism
A closer look at the dispensing mechanism from above:
The servo motion (0 → 1024 → 0) controls the gate precisely, allowing one XIAO board to be released per cycle.
8. Final Result (Hero Shots)
Complete system setup: PC backend, RFID writer, and vending machine with integrated reader and servos.
Final vending machine prototype.
9. Future Improvements
The current prototype proves the card → reader → servo → dispense loop works end to end, but the cards still have to be pre-programmed by hand. The next iteration moves the whole purchase flow onto a PC and turns the vending machine into a pure dispenser. The split looks like this:
9.1 PC-side backend dashboard
A single operator PC will run a small backend application — a tech-style dashboard that shows the live machine status, the XIAO catalog (SAMD21, nRF52840, RP2040, ESP32-C3 / S3 / C6), per-slot stock, and the active order. The operator (or, later, the customer at a kiosk) picks the model and quantity, and the dashboard prepares the transaction payload.
Tech-style PC dashboard mockup: machine + RFID-writer status on top, XIAO product grid in the middle, order panel and RFID-write panel on the right. The HTML prototype lives in docs/week12/machine_UI_design/xiao_vending_dashboard_tech.html.
9.2 PC-side RFID writer + payment
Plugged into that same PC will be an RFID writer module. Once the customer pays through the dashboard, the backend writes the purchase info (product SKU, quantity, transaction ID, the TRUE credit token) onto a blank MIFARE card sitting on the writer. The customer then takes that freshly-encoded card, walks over to the vending machine, taps it on the reader, and the existing Wio Terminal firmware verifies the token and dispenses the correct XIAO board(s) — exactly the flow already demoed in section 8, but with a real payment step in front of it.
End-to-end flow:
- Customer opens the PC dashboard, selects a XIAO model and quantity.
- Dashboard takes the payment and computes the order payload.
- PC's RFID writer encodes the payload +
TRUEtoken onto a card. - Customer takes the card to the vending machine and taps the reader.
- Wio Terminal validates the card and the STS3215 servos dispense the XIAO(s).
9.3 Other planned enhancements
- Use serial bus servos in series to support multiple dispensing channels
- Expand the system to handle multiple XIAO products simultaneously in a single transaction
- Improve enclosure design for durability and modularity
- Develop a more robust backend + inventory system (stock sync between PC and machine, low-stock alerts, transaction history)
- Open-source the full system (hardware + software) for community use
This project demonstrates a scalable approach to automated hardware vending and lays the groundwork for a fully deployable solution in makerspaces.
10. Source Code
All Arduino sketches and supporting libraries used in this project are tracked in the site repository and can be browsed or downloaded directly from GitLab.
Repository Layout
| Folder | Purpose |
|---|---|
code_RFID/ | Standalone RFID reader / writer sketches and the Emakefun_RFID driver |
code_RFID/rfid-main/ | reading_rfid.ino and writing_rfid.ino — read/write a TRUE token to MIFARE block 4 |
code_servo/scservo-main/ | Waveshare SCServo library (SCSCL + SMS/STS) used by every servo sketch |
code_servo/STS3215_change_id/ | One-off sketch to assign IDs (1, 2, …) to each STS3215 on the bus |
code_servo/STS3215_demo_code/ | Minimal demo to verify a single servo on the daisy-chain |
code_servo/STS3215_test_code/ | Multi-servo SyncWritePosEx test used for the gate motion |
test_for_assemble/ | First integrated sketch (test_for_assemble.ino) — RFID + LCD + servo on the Wio Terminal |
vending_machine_final_code/ | Final firmware (vending_machine_final_code.ino) running on the prototype in the videos above |
Final Firmware — vending_machine_final_code.ino
The sketch below is what runs on the Wio Terminal in the demo video. It reads MIFARE block 4 over I2C (Grove Wire1), checks for the literal string TRUE, and on a match runs two HOME → TRIGGER → HOME cycles on both servos via SMS_STS::SyncWritePosEx. All status is mirrored on the built-in LCD.
#include <Wire.h>
#include <TFT_eSPI.h>
#include "Emakefun_RFID.h"
#include "SCServo.h"
TFT_eSPI tft;
#define RFID_ADDR 0x28
MFRC522 mfrc522(RFID_ADDR);
bool rfidReady = false;
#define SERVO_NUM 2
SMS_STS st;
byte ID[SERVO_NUM] = {1, 2};
u16 Speed[SERVO_NUM] = {1500, 1500};
byte ACC[SERVO_NUM] = {50, 50};
s16 Pos[SERVO_NUM] = {1024, 1024};
const s16 HOME_POS = 1024;
const s16 TRIGGER_POS = 0;
const byte DISPENSE_CYCLES = 2;
const unsigned long DISPENSE_FORWARD_DELAY_MS = 1800;
const unsigned long DISPENSE_RETURN_DELAY_MS = 1200;
void moveBothTo(s16 target) {
for (int i = 0; i < SERVO_NUM; i++) Pos[i] = target;
st.SyncWritePosEx(ID, SERVO_NUM, Pos, Speed, ACC);
}
void runDispenseCycles(byte cycles) {
for (byte cycle = 0; cycle < cycles; cycle++) {
moveBothTo(TRIGGER_POS);
delay(DISPENSE_FORWARD_DELAY_MS);
moveBothTo(HOME_POS);
delay(DISPENSE_RETURN_DELAY_MS);
}
}
void loop() {
if (!rfidReady) {
if (digitalRead(WIO_KEY_A) == LOW) { initRFID(); delay(500); }
return;
}
if (!mfrc522.PICC_IsNewCardPresent()) return;
if (!mfrc522.PICC_ReadCardSerial()) return;
MFRC522::MIFARE_Key key;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
byte status = mfrc522.PCD_Authenticate(
MFRC522::PICC_CMD_MF_AUTH_KEY_A, 7, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) { stopRFID(); return; }
byte buffer[18]; byte size = sizeof(buffer);
if (mfrc522.MIFARE_Read(4, buffer, &size) == MFRC522::STATUS_OK) {
bool matched = (buffer[0] == 'T' && buffer[1] == 'R' &&
buffer[2] == 'U' && buffer[3] == 'E');
if (matched) runDispenseCycles(DISPENSE_CYCLES);
}
stopRFID();
}
Truncated for readability — the full sketch (with LCD helpers, RFID init, error screens) is in
vending_machine_final_code/vending_machine_final_code.ino.
How to Reproduce
- Install the Arduino IDE and add the Wio Terminal board package.
- Copy the
SCServolibrary fromcode_servo/scservo-main/and theEmakefun_RFIDdriver fromcode_RFID/into your Arduinolibraries/folder. - Use
code_servo/STS3215_change_id/to assign IDs1and2to your two STS3215 servos (one at a time). - Use
code_RFID/rfid-main/writing_rfid.inoto write theTRUEtoken to MIFARE block 4 of your card. - Flash
vending_machine_final_code/vending_machine_final_code.inoto the Wio Terminal, press Button A to init the RFID reader, and tap the card.