Introduction: Model Train WiFi Control Using MQTT
Having an old TT scale train model system, I had an idea how to control the locos individually.
With this in mind, I went a step further and figured out what is needed to not only to control the trains but to have some additional information about the whole layout and control something else (lamps, rail switches...)
This is how the WiFi controlled model train system is born.
Step 1: Operation Priciples
The main principle is to control each element individually, either from a single controller, or from multiple control sources. This inherently needs a common physical layer - most obviously WiFi - and a common communication protocol, MQTT.
The central element is the MQTT Broker. Every connected device (train, sensor, output...) is only allowed to communicate through the Broker and can only receive data from the Broker.
The devices' heart is an ESP8266 based WiFi controller, while the MQTT broker runs on a Raspberry pi.
At first the Wifi coverage is provided by a WiFi router, and everything is hooked up through wireless.
There are 4 types of devices:
- Train controller: has 2 digital inputs, 1 digital output, 2 PWM outputs (for controlling 2 individual DC motor),
- Sensor controller: has 7 digital inputs (for input switches, optosensors...),
- Output controller: has 8 digital outputs (for rail switches...),
- WiFi remote: has 1 incremental encoder input, 1 digital input (to control trains remotely).
The system is also capable of operating from Node-Red (from tablet, PC, or smartphone...).
Step 2: MQTT Data Exchange and Configuration
Based on the MQTT protocol, at first every device subscribes to a given topic, and can publish to another topic. This is the basis of the train control network's communication.
This communication tales place through JSON formatted messages, to be short and human readable.
Looking from a farther perspective: The network has a WiFi router with its own SSID (network name) and a password. Every device must know these 2 to access the WiFi network. The MQTT broker is part of this network too, so in order to use MQTT protocol every device must know the broker's IP address. And lastly every device has its own topic for subscribing and to publishing messages.
Practically, a given remote control uses the same topic to publish messages that a given train is subscribed for.
Step 3: Train Controller
In order to control a toy train, basically we need 3 things: a power supply, a WiFi enabled controller, and motor driver electronics.
The power supply depends on the actual usage plan: in case of LEGO, this is the Power Functions battery box, in case of an "oldschool" TT or H0 scale train set, it is the track's 12V power supply.
The WiFi enabled controller is a Wemos D1 mini (ESP8266 based) controller.
The motor driver electronics is a TB6612 based module.
The train controller has 2 individually controlled PWM outputs. Acutally one is used for motor control and the other is used for light signalling. Has 2 inpus for reed contact based sensing and one digital output.
The controller accepts JSON messages through WiFi and MQTT protocol.
SPD1 controls the motor, for example: {"SPD1": -204} message is used to move the motor backward at 80% power (the maximum speed value is -255).
SPD2 controls the "direction sensitive" LED light's intensity: {"SPD2": -255} message makes the (backward) LED shine at its full power.
OUT1 controls the digital output's state: {"OUT1": 1} turns on the output.
If the state of an input changes, the controller sends a message according to it: {"IN1": 1}
If the controller receives a valid message, it execues it and provides a feedback to the broker. The feedback is the actually executed command. For example: if the broker sends {"SPD1": 280} then the motor is operating at full power but the feedback message will be: {"SPD1": 255}
Step 4: LEGO Train Control
In case of LEGO train, the schematics are a little bit different.
The power directly comes from the battery box.
There is a need for a mini step down converter to provide 3.5V for the ESP8266 based Lolin board.
The connections are made with a LEGO 8886 extention wire, cut in half.
Step 5: Remote Controller
The controller only publish messages to the train (defined by the BCD switch).
By rotating the encoder, the remote sends either {"SPD1": "+"} or {"SPD1": "-"} messages.
When the train receives this "incremental type" message, it changes its PWM output value by 51 or -51.
This way the remote can change the train's speed in 5 steps (each direction).
Pressing the incremental encoder will send {"SPD1": 0}.
Step 6: Sensor Controller
The so called sensor controller measures the states of its inputs, and if any of them changes, publishes that value.
For example: {"IN1": 0, "IN6": 1} in this example 2 inputs changed state at the same time.
Step 7: Output Controller
The output controller has 8 digital outputs, which are connected to an ULN2803 based module.
It receives messages through its subscribed topic.
For example the {"OUT4": 1, "OUT7": 1} message turn on the 4. and the 7. digital output.
Step 8: Raspberry Pi and WiFi Router
I had a used TP-Link WiFI router, so I used this as an Access Point.
The MQTT broker is a Raspberry Pi with Mosquitto installed.
I use the standard Raspbian OS with MQTT intalled with:
sudo apt-get install mosquitto mosquitto-clients python-mosquitto
The TP-Link router must be configured to have an address reservation for the Raspberry, so after every restart the Pi has the same IP address and every device can connect to it.
And that's it!
Step 9: Finished Controllers
Here are the finished controllers.
The TT scale loko has such small size that a Lolin board had to be narrowed (cut) to be small enough to fit into the train.
The compiled binaries can be downloaded. For security reasons, the bin extention was replaced to txt.