JMRI Arduino Turnout setup

In this blog I will be setting up a turnout on my layout which will be controlled by an Arduino using JMRI PanelPro.

The first thing I will need to do is setup the servo with an Arduino sketch so that I know the values to put into the servo throw command and the servo close command. Below is a simple sketch that will read the keyboard input with the Arduino Serial monitor and if the key input is "t" the servo will throw the turnout and if the input is "c" it will close the turnout. I can then adjust the servoWrite commands by 1 each time until the turnout has been moved enough to make a good connection with the running rails and not derail the train.

Below is the setup code for the Arduino which I run with the servo connected to one of my turnouts on my layout. Once I got the values for throw and close I could place these into the Arduino code for panelPro as shown in the previous blog.

#include <Servo.h>;
Servo myservo;

void setup(){
   myservo.attach(9);
   myservo.write(2);
   Serial.begin(9600);
}

void loop (){
   char inChar = (char)Serial.read();
   if (inChar == 't'){
      myservo.write(10);
      myservo.write(9);
      Serial.println ("Turnout Thrown");
   }
   if (inChar == 'c'){
      myservo.write(2);
      Serial.println ("Turnout Closed");
   }
}

You may have noticed I have two myservo.write commands for the turnout throw. This was due to the constant buzzing then trowing the turnout. myservo.write(10) is needed to get the points to throw over, I then back this off by 1 with myservo.write(9) which stops the buzzing but keeps the points in a good position to not derail the train.

Below is the Arduino code with the new values for panelPro JMRI to use.

#include <CMRI.h>
#include <Auto485.h>
#include <Servo.h>

#define CMRI_ADDR 1

#define DE_PIN 2
int turnout1 = 0;

Auto485 bus(DE_PIN); // Arduino pin 2 -> MAX485 DE and RE pins
CMRI cmri(CMRI_ADDR, 24, 48, bus); // defaults to a SMINI with address 0. SMINI = 24 inputs, 48 outputs
Servo turnOut1;

void setup() {
  turnOut1.attach(9);
  turnOut1.write(2);
  bus.begin(9600);
}

void loop() {

   cmri.process();
   turnout1 = (cmri.get_bit(47));
   if (turnout1 == 1){
      turnOut1.write(10);
      turnOut1.write(9);
   }
   else{
      turnOut1.write(2);
   }
}

5 Comment

  1. Darren Williams says: Reply

    Thank you Motorhomer for your videos I am using you processes on my layout and I look forward to any more ideas you have working with the Arduino!

  2. Mark says: Reply

    Good evening ,

    I’m new to the Arduino environment, i have a Uno and a Adafruit 16-Channel 12-bit PWM/Servo Driver – I2C interface – (PCA9685) to run 6 point motors on my layout, i’ve written a simple script to make the motors nice and slow, but i don’t know how to create a script to connect my 16 channel servo to my JRMI , could you please give me some pointers?
    Which libraries do i need to have running , i have the CMRI and Adafruit 16 channel, servo.h already , which others do i need?
    Looking forward to your help,
    Regards,
    Mark

    1. admin says: Reply

      Hello Mark, I have not used this board as I believe you can have 48 outputs from one Mega which in theory means you could run 48 servos on one mega and if you want more add another mega using the CMRI.
      This does however look like a good option having 16 servos on one I2C which you can add onto making the CMRI setup into the hundreds of servos. The only issue I might see at the moment is if the Adafruit library uses the serial connection which is being used by CMRI.
      Looking at eh Adfruit library you use the following to turn a turn out
      pwm.setPWM(pin, 4096, 0);
      So in theory using the script for the CMRI servo control I assume you could do the following

      turnout1 = (cmri.get_bit(47));
      if (turnout1 == 1){
      pwm.setPWM(pin, 4096, 0);
      }
      else{
      pwm.setPWM(pin, 0, 4096);
      }

      I hope this helps and will only work if there is no conflict in the serial port. The mega does have two serial ports so you could look at using the alternative one if there is a conflict.
      I have not had time yet being the summer months to set up multiple servos on one mega but will post as soon as I have a setup working.
      Good luck with you setup hope you get it working soon
      steve

      1. admin says: Reply

        Hi Mark, just reread your post and realised you are asking about the library needed. I think you only need the two you mentioned to get this to work.
        Have you tried the CMRI setup turning on an LED. If this works then you have the communication with JMRI so it will only need the above script to work

  3. Mark says: Reply

    Hi Steve,

    I’ve given up with the 16 channel board, no go, so i’m driving 5 servos direct of the Arduino, which should be dead easy. I’m using the digital pin outs 3,5,6,9,10,11 for the servo control as well an external 5v power supply. I’ve tried coping your sketch with Turnout2, but no joy, any ideas?
    Regards,
    Mark

Leave a Reply