Since the July update I have been pretty busy with work and family commitments. I did get to my club (RMCQ) annual show and came away with a Queensland Rail 1720 class diesel in 12mm. Now I have something to pull the rollingstock mentioned in the July update!
Work on the modelling competition diorama did not progress very much other than making a gate and fence to be installed soon. I have to get my finger out and finish this diorama as the competition is only weeks away now.
The one thing that has been keeping be busy is what I have written below. Apologies in advance if the text and photo formatting is a bit wonky but I had written the article in Word for potential submission to a magazine or MERG newsletter. Conversion from Word to HTML can be problematic but I think you will get the general gist of the article.
Localised model train
layout control via JMRI IoT (Internet of Things / Trains)
I don’t like
clutter under a layout. Especially wiring clutter. I see the need for the DCC bus
wiring as an integral part to what is happening on the topside of the layout,
but to add another loom of wiring for layout control, at least for me, is
frustrating. Some might not have a problem in doing this. Other may use the DCC
bus to drive their accessories, however I thought there has to be something
better in this modern age of electronics and wireless communications. I
envisaged small isolated layout control electronics centrally controlled using
wifi. I have been pottering around with Raspberry Pis for a number of years now
and do like the wifi ability and JMRI hosting ability of these micro computers,
especially the newer Model 3s which have better grunt than their predecessors.
If you don’t use Raspberry Pis, then Linux or Microsoft based PCs are equally
capable of being configured to run as a host machine for JMRI. The ability to
use your smartphone / tablet as a wireless hand controller/throttle via Engine
Driver or WiThrottle is brilliant and frees you from the use of tethered
throttles around a layout. Last year I became interested in Arduino Unos (and
their smaller siblings) to locally control layout animation, point and signal
control, and other features. Geoff Bunza’s articles on the applications he was
able to code for are well known and documented elsewhere on the Internet.
The question
popped into my head, “Would it be possible to combine the two and use wifi as
the layout control bus medium?” Modern day programming languages are a bit of a
mystery to me. The last time I programmed anything was probably over 25 years
ago in an obscure language called RPG2 (an IBM language for mid and
mainframes). I can understand the flow of C++ as used in Arduino sketches, but
Java (the language that JMRI is written in ) is difficult for me to understand.
I scoured the Internet for possible solutions to my questions, but nothing came
close. Surely I wasn’t the first to think about doing this I asked myself. Then
after many months of research and trying to teach myself Java, one night I just
happened to put the correct question into Google, and BOOM, an answer was
returned that surprised me no end. There in JMRI itself was code written for
IoT (Internet of Things) devices.
THANK YOU
Oscar Moutinho for your efforts. This saved me countless months of frustration!
Oscar had written some Java code into JMRI that basically allows JMRI to
communicate over wifi or an Internet connection to remote devices using IP
addressing. It took me a week or so of going through the code for both the JMRI
host end and the Arduino ‘slave’ remote device (an .ino file) to get a basic
understanding of how it works. Oscar had written it specifically for the
control of points (turnouts) and the output from sensors, so you have to read
it in the context of this ‘use case’. The command stream is basically in either
of the two formats for input (sensors) or output (turnouts/switches) functions.
You designate an IP address of the device to ‘talk’ to or from, which GPIO Pin
it applies to, and whether it is on or off. This is setup in the Turnout or
Sensor Tables as Internal devices (ie not specific to any current manufacturer)
JMRI uses
the terms CLOSED for OFF and THROWN for ON in relation to the Turnout position to the Main. However in relation to a electronic SPST switch CLOSED = ON (contacts closed or on) and THROWN = OFF (contacts open or off).
With this
basic on/off function in mind, it became apparent to me that you could control
more than just turnouts. Treat it as a ‘software switch’ for other electronic
functions where controlling a specific GPIO pin on a Raspberry Pi or an Arduino
(and its derivatives) is needed. Similarly sensors are either on or off. These
GPIOs in turn could control individual electronics, devices or relays to power
whole microcontrollers and whatever has been programmed on them.
Wow!
Possibilities began to emerge in my head. First though I had to research what
options for wifi there were for Arduino and its derivatives as the wifi
capabilities of the Pi or other personal computers are well documented
elsewhere.
There is an
Arduino wifi shield for the Uno and other larger boards but what about the
smaller ones like the Pro Mini. My reasoning about using the smaller boards was
that they could be placed in out of the way areas under the layout to control
animation, lighting, signals, etc but still be just as good as the standard
sized Uno board. Upon further reflection this setup would be great for modular
layouts where a small wifi based microcontroller would be placed within the
confines of a module board to be the layout control bus for the module. No need
to have cable connections between modules. All are connected wirelessly to a
central control computer with an appropriate integration and control software
application such as JMRI.
My research
lead me to reading about ESP8266 based devices. These are basically a wifi
board and small microcontroller in the one package. The smallest one was the
ESP-01 which I thought would be perfect to connect to the smaller Arduino
boards via the Serial connections. They also had the ability to have small
programs coded directly onto them, so potentially I could use these in isolated
areas by themselves. So I Ebayed (is that a new word?) a few of these to
experiment with.
If you
Google ‘esp8266 devices’ a stack of devices are returned from the search. I
focussed my attention on the following three.
ESP-01
·
The 8 pins are not breadboard friendly so some modifications
are needed if you wish to tinker with it using a breadboard. There are adapter
boards available from Ebay and the like but then it just makes it bulkier.
·
Not easy to program
·
Requires physical switch pushing to activate the
code loader function from the Arduino IDE
·
Only two obvious GPIO pins. There is a third
GPIO for the onboard test LED, and some other pins could be used that are
currently allocated to the Serial Tx and Rx pins but then you would not be able
to program it easily in the future
·
For some reason the THROWN and CLOSED commands
worked in reverse on the ESP-01. I did read somewhere the reason for this and
from memory it was to do with the underlying electronics.
·
Generally more trouble than it is worth
ESP-12E
·
Didn’t bother testing this as I soon discovered
the NodeMCU
NodeMCU
·
The ESP-12 chip is directly mounted on this
board with pin breakouts and an onboard micro USB port for programming and
power (if required)
·
Is breadboard / stripboard compatible
·
Easy to program with the Arduino IDE
·
No pushing of code upload buttons
·
My current favourite due to ease of code
uploading compared to esp-01
·
Pinouts
§
Note the GPIO pins are NOT a direct correlation
with the physical pin numbering, so refer to the pinout information
111-13 GPIOs but depending on how applied or
connected these might be reserved for other uses
Power sources
·
3.3V for NodeMCU and Arduino/derivatives
·
5V for MCP23017
·
Power packs (Mains or battery), power bus or tap
DCC bus for power then voltage reduce
·
USB based power sourced from a powered USB Hub
or USB power bank eg 4400mAh 5V output 2.1A
·
Appropriate total amps produced from power
source to be distributed across all devices connected to the power bus
GPIO planning
·
Refer to the relevant pinout diagrams of the
devices in question. These are easily found by doing a Google Images search on
“ pinout diagram” eg “nodemcu pinout diagram”
·
Total board amps
·
Per GPIO Pin amps
o
12mA per pin for the NodeMCU
o
total max mA per NodeMCU is based on total Amps
in from the Vin power supply
o
However I have seen it mentioned that there
should only be a maximum of 80mA across all pins, but nothing definitive, so
possibly a good point to consider)
·
Total volts
·
Volts per Pin
o
12mA the nominal max amps PER GPIO. If I am
reading the doco correctly the output voltage per GPIO is either 3.3V or
3.3x0.8 (must be a resistance factor??) = 2.64V
o
For those more electronics savvy than me, it
might be a good thing to research &/or test
·
Do NOT exceed the voltage and amperage
specifications for the devices as you might see smoke, as I did on a number of
occasions
·
I suggest documenting and planning these GPIO
Pin allocations in a spreadsheet to keep tabs on how you have designed and
implemented your specific solution
·
·
The code that Oscar has produced does NOT check
to see if a Pin number is within the GPIO pin total count for the board. YOU
have to think and design accordingly.
IP addressing
·
Plan you addresses in the context of your wifi setup,
that is, private IP address or using your home Internet wifi IP addressing
·
NodeMCU setup function has the definition of its
IP address within the base ESP8266_TcpPeripheral.ino file supplied by Oscar in
the above links. Just replace the missing info as specific to your setup. Just
rename this file to something relating to the NodeMCU board you are
configuring. The same base configuration will apply to all devices using this
method. Moving forward some of it may be changed in order to accommodate the operations
the microcontroller is undertaking.
Note in the IP addressing fields
below that the octets are separated by commas rather than full
stops.
#include
// network info:
const char* ssid =
"your-ssid"; // wireless SSID
const char* password =
"your-password"; // wireless password (may be empty if no security)
IPAddress ip(x, x, x, x); // this
device IP address (example: 192.168.1.230)
IPAddress gateway(x, x, x, x); //
usually the router IP address (example: 192.168.1.1)
IPAddress subnet(x, x, x, x); //
usually 255.255.255.0
Arduino IDE
·
Extra libraries and sources to be configured
o
Sketch -> Include Library -> Manage
Libraries -> search for ESP8266
o
A myriad of esp8266 libraries are now available
depending on what you want to do
o
I suggest setting up:
- Adafruit ESP8266
- ESP8266
- ESP8266Wifi
- ESP8266AVRISP
- But if in doubt, install them all as it won’t
affect anything in the IDE
o
Install an additional board manager for the
esp8266 based devices
- File -> Preferences -> enter the following
URL in the Additional Boards Manager URLs: text field
- http://arduino.esp8266.com/stable/package_esp8266com_index.json
·
hopefully that should be all to get you going.
If not there is plenty of information out on Google relating to esp8266 and
usage within Arduino
Setting up the entry in the Internal Sensor
or Turnout JMRI Table
Format of
the address string under Internal System
Name
·
For a Turnout / Switch – IT.IOT$:
o
Example from the above photo –
IT.IOT$13:10.0.0.6
·
For a sensor – IS.IOT$:
A trick for
young players, when entering the Internal System Name, DO NOT start with IT or IS as JMRI automatically prefixes these.
Instead enter as .IOT$:( (start with the full stop), else you might end up with an
address that looks like IT.IT.IOT$13:10.0.0.6
Basic NodeMCU test rig
For the
purposes of tinkering, I setup a breadboard with a NodeMCU and attached an LED
on GPIO pin 13. The NodeMCU had an IP address of 10.0.0.6. The NodeMCU can be
considered the slave or server in the client-server model. I modified the
ESP8266_TcpPeripheral.ino file supplied by Oscar in the Arduino IDE and
uploading it to the NodeMCU.
For my
master or Client host, I have a Pi Model 3. It has been setup as a Master
Access Point for a private wifi network in the 10.0.0.x range. As long as it is
broadcasting, there is nothing else to be done from the Host side except for
entering the Turnout address in the JMRI Turnout Table if not yet done from the
above examples.
Connectivity test after power up
ping IP
address of NodeMCU eg $ ping 10.0.0.6 from the master / host
If the
NodeMCU has connected to the private wifi network, the ping should return round
trip times to it.
CLOSED or ON condition for a (SPST) SWITCH
Start up
JMRI and optionally connect up your smartphone to JMRI. In my case I have an
Android running Engine Driver. Once JMRI is operational, open the Turnout Table
panel. Initially it may be in an Unknown state but clicking on the button to Closed will turn on the LED. If this
works then presto, you have the basics for a wifi connected layout control bus.
Similarly you can use the Turnouts view in the Engine Driver app to do the same
remotely from the host.
LED ON
THROWN or OFF condition for a (SPST) SWITCH
Likewise by
clicking on the Closed button to change it to Thrown, the LED will
turn off.
LED OFF
CLOSED (ON) or THROWN (OFF) condition for a
SENSOR
With respect
to a sensor connected to a GPIO pin, if this is triggered the board that it is
attached to will send the associated PIN/CONDITION to the Client/Host machine,
in my case the Raspberry Pi. JMRI knows which board it has come from because
the IP address of the board has been placed in the data stream as part of the
TCP/IP packet. Network magic!
This will be
reflected in the JMRI Sensor Table similar to the Turnout Table, however the values will be ACTIVE or INACTIVE.
JMRI automation
The beauty
of JMRI is now that these conditions are known by it in the Tables, automation
or conditional activation can be programmed using the Logix function. For example when a sensor is triggered the
associated signal/s can be set and the points changed by the use of a motor /
servo. This can then be reflected on a JMRI Panel of the layout if one has been
designed.
Future investigations / testing
·
Use of I2C to link dissimilar devices across a
common bus
o
Two wire bus (SDA and SCL)
o
Localised power bus (USB again with voltage
reduction?)
o
Max length of bus 1 meter
o
Some devices such as the NodeMCU need 4.7K
resistors on the I2C pins
o
Maximum of 8 devices/addresses on a single i2c
bus
o
If the I2C bus is contained on one NodeMCU
Master which has an individual IP address, then multiple I2C based buses can be
constructed around a layout all separate from one another as the IP addressing
isolates them from each master device.
o
Challenge will be to determine how to pass a Pin
number from JMRI to the NodeMCU for a number on the bus that is not onboard the
I2C master NodeMCU. I am thinking of a loop check of some sort in the base code
to check the incoming pin number and if outside the range of the onboard
NodeMCU GPIOs, then it must relate to a pin on one of the slaves. Pass to slave
as a converted pin number on that slave and addressed via the I2C bus address
·
Microchip MCP23017
o
16 GPIO pins
o
Seams to be a possible way to power a large
number of LEDs, input from sensors, or operating relays for high voltage
device/s activation
o
Adafruit mcp23017 library allows individual pin
control
o
Hardware control addressing of the individual
microcontrollers (up to eight of these on one I2C bus)
·
Other I2C devices
o
Arduino Pro Mini and the like can be interconnected
to the I2C bus of the NodeMCU
o
Barometer and temperature sensor
o
Ultrasonic sensor/s
o
Check out products at electronic stores such as
Jaycar, Altronics or the like
·
LCD screens for visual messaging
·
Capturing data and displaying it graphically
such as timetabling data for model train operations (sensors pick up train ID
from trackside readers of some sort (RFID, bar code, etc) and plot this against
scheduled timetable info to show trains that are on schedule or not)
To summarise the above graphically, localised
layout control using wifi to link it all together under JMRI
To conclude,
just my thoughts on another way to do the layout control functions. These
thoughts have been an amalgam of similar thoughts by other model railway and
electronic enthusiasts across the globe. Hopefully it might get you thinking
to?