Tunas Akara
Back to Blog

Talking to Vending Machine Controllers: Serial Protocols and Vendor SDKs

by RayhanUpdated 5 min read
vendingserialandroidintegrationsdk
Talking to Vending Machine Controllers: Serial Protocols and Vendor SDKs

Talking to Vending Machine Controllers: Serial Protocols and Vendor SDKs

A modern spring-coil vending machine — the TCN class of hardware that dominates the market — is two computers in one cabinet. An Android board runs the screen, payments, and your software. A separate driver board runs the motors, the drop sensor, and the compressor, and it speaks serial.

Your app never touches a motor directly. It talks to the command board through a port like /dev/ttyS3, and everything you sell depends on that conversation going well.

What the vendor actually ships you

Not a protocol document. What arrives is a closed Android AAR — something like tcn_springboard-release.aar — a demo app, and documentation that is sparse, machine-translated, or both.

The SDK expects your Application class to extend its base class, and wants a serial port configured at startup. It runs a background VendService, and pushes results back through a registered listener as numbered event IDs. There's usually a one-time authorization step tied to the board.

None of this is unusual; it's the standard shape of hardware vendor SDKs, and fighting it is wasted effort. The advantage is in how you contain it.

Wrap it thin, and write the guide the vendor didn't

Think of a courtroom interpreter: the foreign party speaks their own language, but everyone in the room hears one consistent language through them. A thin wrapper does the same job for a vendor SDK.

The practical move is one module in your codebase that owns the SDK lifecycle — initialization, serial port config, listener registration. That module exposes a small interface in your own vocabulary: vend(slot, orderNo), querySlot(slot), setTemperature(mode), plus a clean event stream. SDK types never leak past that module. When the vendor ships a breaking update, or you swap to a different controller family, the blast radius is one file.

The second half of the move is documentation: an internal SDK guide, written by you, that records what integration actually requires. That means the permissions the SDK demands, the AAR setup, the serial port configuration, the event IDs that matter and what they mean in practice. It costs an afternoon and saves every future developer a week of re-deriving facts from machine-translated PDFs. On integration projects I treat that guide as a deliverable, not a nice-to-have.

Command, acknowledge, and the drop sensor

Everything on the board is asynchronous. You request a vend; the result arrives later as an event: success, failure, or nothing at all. Nothing at all is also an answer you must handle:

Loading diagram…

The detail that separates working machines from complaint generators is the drop sensor. A motor turning is not a vend — springs jam, products wedge, coils run empty a row early. The sensor confirms something actually fell.

The rule that follows: never mark an order delivered until the drop is confirmed, and wire the failure and timeout paths straight into refunds. A customer who paid and got nothing forgives a machine that refunds instantly. They do not forgive one that shrugs.

Slot faults deserve the same respect. The board reports sold-out and fault-by-slot events. Treat a slot that fails twice consecutively as jammed, pull it from the sellable pool automatically, and let a human re-enable it after inspection.

Telemetry worth capturing

The serial link carries more than vend commands, and most integrations throw that value away. Worth persisting from day one: per-slot stock counts, cabinet temperature (a dying compressor announces itself days early), and failed-vend counts by slot (a jam signature). Door-open events and payment events from the bill and coin hardware are worth it too.

That stream is what turns a scattered fleet into an operable one — restock routes planned from data, machines flagged before customers complain. Feeding it into a dashboard is the same normalization problem as any mixed device fleet; the approach is in normalizing multi-protocol IoT devices.

The licensing footnote that isn't one

That AAR arrived with no license text. Its legal status — what you may redistribute, to whom, inside what — is very often simply undefined. "Everyone uses it" is not a right.

Before the SDK ships inside your product, the redistribution question belongs in the supply contract with the machine vendor. The broader triage of what you can and cannot ship is in open-source licenses in commercial software.

The takeaway

Treat the vendor SDK as a fact of the environment: contain it behind a thin wrapper, document it yourself, and respect the async command/ack model. Trust the drop sensor over the motor, and capture the telemetry the serial link is already offering.

The machines then become what they should be — boring, observable endpoints in a fleet.

Related Posts

Building something similar?

IoT Backend & Multi-Protocol Integration

Backends that ingest device telemetry across MQTT, WebSocket, Modbus, and BLE, and normalize it into reliable real-time dashboards.

See how I can help