JMRI Arduino setup

This blog will demonstrate how to setup a single Arduino as CMRI to interface with JMRI, this example connects the Arduino and configures it for CMRI. JMRI is then setup to connect to the Arduino and turns on the Arduino on board led.

first we will down load two librarys one is the CMRI library needed for this to work and other is RS485 library which will be used later.

CMRI library

https://github.com/madleech/ArduinoCMRI

RS485 library

https://github.com/madleech/Auto485

Arduino code

#include <CMRI.h>

#include<Auto485.h>

#define CMRI_ADDR 1

#define LED 13

#define DE_PIN 2

Auto485 bus(DE_PIN); // arduino pin 2 for DE and RE pins

CMRI cmri(CMRI_ADDR, 24, 48, bus); // defaults to a SMINI with address 0. SMINI = 24 inputs, 48 outputs

void setup() {
     pinMode(LED, OUTPUT);
     bus.begin(9600);
}

void loop() {

     cmri.process();
 
     // 2: update output. Reads bit 0 of T packet and sets the LED to this
     digitalWrite(LED, cmri.get_bit(0));

}

Now start up JMRI PanelPro. When it is running click on edit preferences to get the following window

set the following tabs

System manufacturer = C/MRI

System connection = Serial

Setting

Serial port: (select the port your arduino is connected to, you will find this on the arduino IDE)

Connection Prefix: C

Connection Name: (what ever you want to call it)

Now we need to configure the nodes so click on "Configure C/MRI nodes" and you should get this window

Put 1 in the node address and then click add node button. then click done. save configuration and restart JMRI

If all has gone well when JMRI restarts it should have the name of you arduino you specified and the port it is connected to. Remember if you change the port connection on the computer by putting the arduino in a different usb port you will need to change this on the JMRI preferences

We will now setup the lights control in the JMRI table. Click on tools > table > lights

you should have a lights table window start up, click on add and you will have the following window

fill in the following

System connection: name you gave your arduino

Hardware address: 1001

User name: (enter what you want to call this light, I used lightTest for this)

click create new then cancel, you will get a warning reminding you to save this table

You should now have the following in your lights table

Go ahead click on the  light on/off button and if all went correct you should now be controlling the arduino on board light.

We will now save this table so we can use it again when restarting JMRI. Click on file > store > store configuration files and panels to file.

A save window will pop up, save this as test and close it all down including JMRI so we can see this all saved.

restart JMRI, click on panels > open panel and select the test file you just saved. Now go to tools > tables > lights and hopefully you should have your light table with the light for the arduino you created.

We will now add a second light. first connect a second LED with a resistor to pin 7 and GND as shown below

We will now change the arduino code to include the following code in red

#include <CMRI.h>

#include<Auto485.h>

#define CMRI_ADDR 1

#define DE_PIN 2

#define LED_PIN 13
#define LEDTWO 7

Auto485 bus(DE_PIN);

CMRI cmri(CMRI_ADDR, 24, 48, bus); // defaults to a SMINI with address 0. SMINI = 24 inputs, 48 outputs

void setup() {
 pinMode(LED_PIN, OUTPUT);
 pinMode(LEDTWO, OUTPUT);
 bus.begin(9600);
}

void loop() {

cmri.process();
 
digitalWrite(LED_PIN, cmri.get_bit(0));

digitalWrite(LEDTWO, cmri.get_bit(7));

}

You will have to close JMRI so you can then upload the new code to the arduino

now restart JMRI, open your test table as we did above and go to your light table.

Now create a new light this time the address will be 1008. Once you have created this light, click on the on/off button and your new LED should be turning on and off.

We should now be able to control two LED's. LED 13 on board with address 1001 and led 7 on address 1008.

Close down the light table and on the main control panel click on CMRI > list assigned, you will see a list of the assigned pins and addresses you have setup on your arduino with JMRI as shown below.

If you scroll down this list you will see there are 48 bits, so we can have 48 items being controlled. With relays and MOSFETS we can control a lot items including servos for points using this system.

We will now add a sensor to the arduino and show it on the JMRI panel. First close down JMRI so we can upload another arduino code. Then change the arduino code add the red lines below and upload to arduino. After you have uploaded the code start up JMRI and open you panel again.

#include <CMRI.h>

#include<Auto485.h>

#define CMRI_ADDR 1

#define DE_PIN 2
#define LED_PIN 13
#define LEDTWO 7
#define button 3

int buttonState = 0; // set a variable to store the button state

Auto485 bus(DE_PIN);

CMRI cmri(CMRI_ADDR, 24, 48, bus); // defaults to a SMINI with address 0. SMINI = 24 inputs, 48 outputs

void setup() {
 pinMode(LED_PIN, OUTPUT);
 pinMode(LEDTWO, OUTPUT);
 pinMode(button, INPUT_PULLUP); // we will use the arduino's internal pull up resistor for this 
 bus.begin(9600);
}

void loop() {

 cmri.process();
 
digitalWrite(LED_PIN, cmri.get_bit(0));

digitalWrite(LEDTWO, cmri.get_bit(7));

buttonState = digitalRead(button); // read the button and store it on buttonState

cmri.set_bit(0, buttonState);
}

We now need to connect a button between pin 3 and GND as shown below

Now in JMRI click on tools > tables > sensors, then click on add so we can add our new sensor. which will be on address 1001 as shown below. I have given my sensor the name button.

Click ok and cancel this window and you should now have a sensor in you table with the words active in one field. Your arduino will also be flashing the Tx Rx leds quickly. If you now click on the button the active state should change to inactive and when the button is released it should change back again

If you now go back to CMRI > list assignments and click on the show input bits at the top you should see your new button sensor setup on bit 1001. You can see we can have 24 input sensors for one CMRI device.

Finally for this post we will setup our button sensor so that when it has been operated it will turn on our LED2 light. This will be useful if you have a track sensor that when operated by a train could turn track signal lights on/off or control an automatic level crossing.

Make sure you have JMRI running and your panel open as before. Now click on tools > tables > lights so you should now have your light panel. Click on edit for the second LED we setup, and click "add control" button. You should have the windows shown below.

In the control table the following tabs should be populated

Control type : by sensor

Sensor Name: (name you gave your sensor, I called my one Button)

Sense for on leave active

Now click on create new and you should have the following added to your light configuration

click update and you should now have an LED which will turn on and off depending on you button sensor. Try and and see if it all works. If you keep an eye on the light table when you operate your button you will also see this change state. This can be used on the layout panel to change the state of a signal on the panel.

2 Comment

  1. Russell Boutette says: Reply

    I have multiple rfid readers (max 8?/ per ardinuo ) connected to one arduino uno not sure how to connect to jmri to use as reporters.
    if I use the rfid connection type that is one serial/usb connection per reader. Currently using digitrax Zepyr and pr3 via loconet and jmri
    Want to find a more universal system instead of Digitrax’s transponding.
    Main goal is to identify and locate different engines in a hidden round house with in a helix
    Would using the C/mri connection type be a way to do this ? if not any suggestions ?
    Thanks Russ.

    1. admin says: Reply

      Hello Russ
      This is not something I have tried and probably will not seeing as n gauge will be too small for the rfid transmitter. I believe this should be possible with CMRI using an Arduino. If you read the rfid and it matches to a loco address in you sketch then send the CMRI bit for this loco. I have not used rfid so the example below is just an idea which might help.
      Create variable for your locos,
      int Thomas = 100; // addresses for Thomas and Edward
      int Edward = 200;

      Then read TagID as the loco goes over the rfid sensor and create a switch statement
      Switch(tagID){
      Case thomas:
      Cmri.set_bit(0, 1); // set Thomas bit to 1
      Case Edward:
      cmri.set_bit(1, 1); // set Edward bit to 1
      JMRI could read this as a sensor and name it as Thomas if bit 0 is set to 1 or Edward if bit 1 is set to 1. Not clear on how you are using this but if you read the train into the siding then the bit is set to 1 and if the loco leaves the siding then set it back to 0.

      Not sure how to add this is a loco on JMRI. You might be able to assign a sensor input to a loco in the locos settings. great idea try posting it on the arduino forum sure someone will help

Leave a Reply