Please read the general section first!

MattzoTrainController for Powered Up (MTC4PU)

Purpose

The MattzoTrainController for Powered Up (MTC4PU) acts as a bridge between Rocrail and Powered Up (PU) hubs. The MTC4PU connects to Rocrail via WiFi and to the PU hub via Bluetooth. The PU hubs control PU train motors and PU lights via cable.

Status

The development of the firmware for the MTC4PU is in the final stage and will be published soon (estimated end of December 2020 / beginning of January 2021). Thanks for your patience.

Functional Description

When Rocrail wants to make a train go into a certain direction, it communicates this as a “loco” command via the MQTT broker.

The MTC4PU receives this command and evaluates, if the command is relevant for one of the PU hubs that are connected to the controller. To evaluate if the command is addressed to the controller, it checks if its own MattzoControllerID corresponds with the “address” attribute that is configured for the train in Rocrail (see below). If this is the case, the MTC4PU converts the desired speed and direction into a command for the connected PU hubs, which then regulate the power supply for the attached motors and lights.

Up to nine PU hubs can be connected to a single MTC4PU. A PU hub has two cable connectors (A and B), so up to 18 motors and/or PU lights can be controlled with a single MTC4PU. I don’t know what you are planning, but 18 motors should be enough for most situations.

All PU hubs and attached motors / lights must be configured in the source code. You can also configure the sense of rotation for all motors individually. This flexibility enables an enourmous variety of deployment scenarios for your trains, e.g.:

  • A single loco with one PU hub and just one motor.
  • A powerful loco with one PU hub and two motors.
  • A commuter train (ICE, Eurostar, TGV, Regio Express etc.) with two locos, one in the front, and one on the back. Each loco has one PU hub and one motor.
  • Multiple locos pulling a giant freight train.
  • A long train with additional motors hidden in some cars in the middle of the train.

Many other scenarios are possible.

The present implementation of the MTCPU supports only one logical light, which is attached to the Rocrail function key F1 on the loco control panel. This means, that if you connect multiple lights to one or more PU hubs that are all connected to the same MTC4PU, they are switched synchronously and can not be switched independently of each other.

In future version of the firmware, we will make full support of Rocrail’s capability of up to 32 functions, and add some MattzoBricks special functions on top. It will be possible to connect cheap standard LEDs to the MTC4UP, which will enable various independent lighting options for the train, including direction-dependend automatic white/red headlights, interior lighting, a flashing disco light for a special waggon using multi-color LEDs, flashing lights in any color for special trains etc.

The controller continuously monitors its power supply. We plan to adapt the motor power to the decreasing voltage of the battery in future versions of the firmware.

Required Components

  • An ESP-32 controller. On the picture you see a ESP32 NodeMCU development board. An alternative is the (smaller) ESP32 D1 Mini NodeMCU – but be careful: this board does not cope with 9V DC.
  • Some power supply like a small USB power pack, or, if deployed on land, a small USB charger can be used alternatively.
  • An USB cable to connect the controller to the power source.

Wiring

Just connect the MTC4UP to a power source and put it inside or outside your train.

The controller on the pictures fits on an aera of 4×8 studs. If this is still to large for your situation, you can search for smaller ESP-32 controllers on the market, e.g. a D1 Mini ESP-32.

Casing

We will publish the files required to print a case for the MTC4PU with a 3D printer soon.

The dimensions of the case match precisely the size of a standard LEGO power functions battery box.

Configuration

Before uploading the firmware, make sure that you have configured the network configuration files as described in the general section, and the specific configuration file for the MTC4PU (MTC4PU_Configuration.h).

Locos

Configure the locomotives that the controller shall control. The meaning of the parameters are self-explanatory or explained in the configuration file.

A bit below you will find some configuration examples.

Powered Up Hubs

Configure the Powered Up hubs that the controller shall control. The meaning of the parameters are self-explanatory or explained in the configuration file.

For detecting the MAC address of a Powered Up hub, see below.

Controler Wiring Specifics

In this section, you need to configure the number of (light) functions and to which loco they belong.

Please note that the function pin “PU_LIGHT” has a special meaning and represents a Powered Up light. You can attach Powered Up lights to multiple hubs, but they are logically interconnected in this version of the firmware, and can not be switched individually. We plan to remove this limitation in later version of the firmware.

A bit below you will find some configuration examples.

You can also enable of disable the Auto Light feature, which automatically turns lights on and off according to the movement of the loco.

If a status LED is installed, you can enable it and assign the pin on which it is installed.

Network settings

In this section, you set if the ebreak is triggered when the controller looses connection to MQTT.

Syslog settings

Here you can change the name for syslog entries submitted by this controller.

Detecting the MAC address of Powered Up Hubs

To configure the Powered Up hubs in the configuration file, you need to know the MAC address of the hubs. How do you find them out?

Quite simple: subscribe to the mqtt broker using a command line on your computer (mosquitto_sub -t #), reboot the MTC4PU and power up the PU hub within 5 seconds. The MTC4PU will shortly connect to this PU hub and publish its MAC address on mqtt.

Connecting the MTC4PU to the serial monitor of the Arduino IDE fulfills the same task. The MAC address of the hub can be queried using the same procedure – reboot the MTC4PU and press the button on your PU hub within 5 seconds. The MAC address of the hub will be displayed on the serial monitor.

After you know the MAC address of your hub, replace the example configuration in the code with your own configuration.

Configuration examples

Let’s have a look at some configuration examples.

A single loco

One PU hub, one motor connected to port A:

const int NUM_LOCOS = 1;

...

locoConf[0] = (MattzoLocoConfiguration) {
     .locoName = "Emerald",
     .locoAddress = 10194,
     .accelerationInterval = 100,
     .accelerateStep = 1,
     .brakeStep = 2
   };

...

const int NUM_HUBS = 1;

...

hubConf[0] = (MattzoPUHubConfiguration){
       .hubName = "EME",
       .macAddress = "90:84:2b:16:15:f8",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = 1,
       .devicePortB = MattzoPUDevice::NONE,
       .configMotorB = 0,
       .locoAddress = 10194
   };

The loco is called “Emerald Express”, has the address 10194 in RocRail. Every 100ms (0,1 seconds), it will accelerate by 1% of the maximum power (10% per second) or brake with 2% of the maximum power (20% per second).

The hub is called “EME” and has the MAC address “90:84:2b:16:15:f8”. A train motor is connected to port A in normal turning direction (1). No device is connected on port B.

A loco with two motors

One PU hub, two motors, connected to port A and B:

const int NUM_LOCOS = 1;

...

locoConf[0] = (MattzoLocoConfiguration) {
     .locoName = "Maersk",
     .locoAddress = 10219,
     .accelerationInterval = 100,
     .accelerateStep = 1,
     .brakeStep = 3
   };

...

const int NUM_HUBS = 2;

...

hubConf[0] = (MattzoPUHubConfiguration){
       .hubName = "MAE",
       .macAddress = "90:84:2b:16:15:f8",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = 1,
       .devicePortB = MattzoPUDevice::NONE,
       .configMotorB = -1,
       .locoAddress = 10219
   };

The loco is called “Maersk” and has the address 10219 in RocRail. Every 100ms (0,1 seconds), it will accelerate by 1% of the maximum power (10% per second) or brake with 3% of the maximum power (30% per second).

The hub is called “MAE”. The train motors connected to port A works in normal turning direction (1) and on port B in reverse mode (-1).

A loco with headlights

One PU hub, one motor connected to port A, powered up lights connected to port B:

const int NUM_LOCOS = 1;

...

locoConf[0] = (MattzoLocoConfiguration) {
     .locoName = "Santa Fe",
     .locoAddress = 10020,
     .accelerationInterval = 100,
     .accelerateStep = 2,
     .brakeStep = 3
   };

...

const int NUM_HUBS = 1;

...

hubConf[0] = (MattzoPUHubConfiguration){
       .hubName = "SFE",
       .macAddress = "90:84:2b:16:15:f8",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = -1,
       .devicePortB = MattzoPUDevice::PU_LIGHT,
       .configMotorB = 0,
       .locoAddress = 10020
   };

The loco is called “Santa Fe” and has the address 10020 in RocRail. Every 100ms (0,1 seconds), it will accelerate by 2% of the maximum power (20% per second) or brake with 3% of the maximum power (30% per second).

The hub is called “SFE” and has the MAC address “90:84:2b:16:15:f8”. A train motor is connected to port A in reverse turning direction (-1). A Powered Up light is connected on port B.

A commuter train

Two locos, two PU hubs, one motor connected to each hub on port A, Powered Up lights connected to port B on both hubs. The motor connected to the second hub operates in reverse mode.

Please note: even that the train has two physical locos, they are handled as one logical loco sharing the same locoAddress!

const int NUM_LOCOS = 1;

...

locoConf[0] = (MattzoLocoConfiguration) {
     .locoName = "ICE",
     .locoAddress = 6051,
     .accelerationInterval = 100,
     .accelerateStep = 2,
     .brakeStep = 3
   };

...

const int NUM_HUBS = 2;

...

hubConf[0] = (MattzoPUHubConfiguration){
       .hubName = "ICE1",
       .macAddress = "90:84:2b:16:15:f8",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = 1,
       .devicePortB = MattzoPUDevice::PU_LIGHT,
       .configMotorB = 0,
       .locoAddress = 6051
   };

hubConf[1] = (MattzoPUHubConfiguration){
       .hubName = "ICE2",
       .macAddress = "90:84:2b:17:e9:4c",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = -1,
       .devicePortB = MattzoPUDevice::PU_LIGHT,
       .configMotorB = 0,
       .locoAddress = 6051
   };

Two commuter trains

In this example, the controler will control two trains with two locos each.

Each train has two locos with a PU hub each, one motor connected to each hub on port A, no lights. The motors connected to the second hub of the train operate in reverse mode.

const int NUM_LOCOS = 2;

...

locoConf[0] = (MattzoLocoConfiguration) {
     .locoName = "ICE",
     .locoAddress = 6051,
     .accelerationInterval = 100,
     .accelerateStep = 2,
     .brakeStep = 3
   };
 locoConf[1] = (MattzoLocoConfiguration) {
   .locoName = "EST",
   .locoAddress = 6197,
   .accelerationInterval = 100,
   .accelerateStep = 2,
   .brakeStep = 3
   };

...

const int NUM_HUBS = 2;

...

hubConf[0] = (MattzoPUHubConfiguration){
       .hubName = "ICE1",
       .macAddress = "90:84:2b:16:15:f8",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = 1,
       .devicePortB = MattzoPUDevice::NONE,
       .configMotorB = 0,
       .locoAddress = 6051
   };
 hubConf[1] = (MattzoPUHubConfiguration){
       .hubName = "ICE2",
       .macAddress = "90:84:2b:17:e9:4c",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = -1,
       .devicePortB = MattzoPUDevice::NONE,
       .configMotorB = 0,
       .locoAddress = 6051
   };
 hubConf[2] = (MattzoPUHubConfiguration){
       .hubName = "EST1",
       .macAddress = "90:84:2b:18:f2:52",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = 1,
       .devicePortB = MattzoPUDevice::NONE,
       .configMotorB = 0,
       .locoAddress = 6197
   };
 hubConf[3] = (MattzoPUHubConfiguration){
       .hubName = "EST2",
       .macAddress = "90:84:2b:18:f7:75",
       .devicePortA = MattzoPUDevice::PU_MOTOR,
       .configMotorA = -1,
       .devicePortB = MattzoPUDevice::NONE,
       .configMotorB = 0,
       .locoAddress = 6197
     };

A giant variety of other deployment scenarios and combination is possible.

You should now be able to upload the firmware and connect to your PU hubs – and basically you are then almost ready to go.

Setup

For general setup instructions please refer to the general section.

To set-up a train controller in Rocrail, open Rocview and navigate to menu Tables / Locomotives. Choose the locomotive that you want to configure or create a new one.

Navigate to tab “Interface” and enter the address of the loco, which you can choose yourself between 1 and roughly 16000. It needs to correspond with the settings in the configuration file. A single loco address must be used only once on your layout!

Also set the “Decoder Steps” value to 255:

This image has an empty alt attribute; its file name is Rocrail-config-trains-1-1024x784.png

Navigate to the “Speed” tab, and choose “Percent”. Enter useful motor power values for the different speed levels (trial and error):

This image has an empty alt attribute; its file name is Rocrail-config-trains-2-1024x637.png

Defining speed in Rocrail is a complex matter. More information about this topic can be found here.

There is a lot of additional configuration options for trains in Rocrail. Please refer to the Rocrail documentation for more information.

Operations

Make sure your Powered Up hubs have the latest LEGO firmware installed. You can assert that by connecting the hub to the Powered Up Mobile App for iOS or Android.

Power up the MTC4PU and the Powered Up hub. The Powered Up hub should connect to the MTC4PU immediately after the MTC4PU has successfully connected to Wifi and the MQTT broker. If the Powered Up hub does not connect, try it again for a couple of times by rebooting the controller. If it’s still not connecting, check your configuration.

Enjoy!

Present Status

We are aware that there is an instability in MTC4PU firmware 0.3. This instability makes the controller crash and reboot after some time. If this happens in a bad moment, or if the controller can’t connect to WiFi are this reboot, this might lead to crashes on your layout, because the loco won’t stop.

We have already tracked the problem down and can reproduce it in the MattzoBricks lab. We are working on a bugfix. We will also take additional measures to prevent crashes on the layout, e.g. stopping all Powered Up Units after a reboot of the controller etc.

When we have implemented a bugfix, we will issue a firmware update right away.

Credits

Markus contributed the idea of using the Legoino library for the MTC4PU and also implemented the first prototype.

Later versions of the firmware were refactored, converted into a more object oriented design, enhanced and refined by Mattze.

Leave a Reply

Your email address will not be published. Required fields are marked *