Arduino USB interface for sensor feedback to Rocrail

rozsaheg
Posts: 25
Joined: 10.06.2015, 21:02

Re: Arduino USB interface for sensor feedback to Rocrail

Post by rozsaheg » 19.02.2017, 19:59

Hi Antonio,
In the older version of Rocrail the MCS2 baud rate was 500000. In the newer version you have to set this parameter yourself. Because my program use baud 500k I would suggest to change your MCS2 setup to this.
Happy to hear the solution is works for you.
Laszlo

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 19.02.2017, 20:05

Yes... of course.

I am a little bit embarassed :oops: :oops: :oops:.... I didn't restart the server after the configuration.

:mrgreen:
Bye!

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 19.02.2017, 20:08

rozsaheg wrote:Hi Antonio,
In the older version of Rocrail the MCS2 baud rate was 500000. In the newer version you have to set this parameter yourself. Because my program use baud 500k I would suggest to change your MCS2 setup to this.
Happy to hear the solution is works for you.
Laszlo
Hi Laszlo,

the only difference from my pictures is the baud rate, now is 500k.
Tomorrow I will test with a Raspberry Pi 3, and i will post the results.

ciao and thank you for sharing your code

Antonino

rozsaheg
Posts: 25
Joined: 10.06.2015, 21:02

Re: Arduino USB interface for sensor feedback to Rocrail

Post by rozsaheg » 20.02.2017, 10:36

Hi Antonio,
An other point. In the Rocrail Properties on Controller tab check-mark the "No device check at startup".
Start the Rocrail without Arduino first, check-mark, connect Arduino.
If this will not solve the problem send your last *.trc file to me with PM.
Regards
Laszlo

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 04.03.2017, 17:47

Hi to All,

Arduino works fine also with Raspberry Pi. The interface can vary if it is an ArduinoUno as dev/ttyACM0 or a Nano with CH340 interface as dev/ttyUSBx (x = 0,1,2...).
I made some sinmple modifications to the Laszlo code to easy adapt to other Arduino boards.
Please find attached the code.

ciao
antogar
Attachments
Feedback_CS2_Nano.zip
(1.17 KiB) Downloaded 30 times

rozsaheg
Posts: 25
Joined: 10.06.2015, 21:02

Re: Arduino USB interface for sensor feedback to Rocrail

Post by rozsaheg » 10.06.2017, 11:11

I2C solution

There was a request by some of you, to work out a solution, similar to my skeleton_ultimate program with more Arduino board. The following codes working with Nano's and Uno's but with a minor modification any Arduino board combination can be used. If you want to know more about I2C check this link https://www.arduino.cc/en/Reference/Wire

On the following picture you can see the "circuit". Master in the middle and Slaves on side. The distance between them 1-2 m and other 1-2 m from sensors.The max distance between the utmost sensors in safety way is 8 m. The Slave boards on the picture powered from Master but you can use separate power as well. In that case the wire from 5V to VIN is not needed.
nanok4_bb.jpg
The first code is for the Master board. It is prepared for two Slaves but you can extend it for as many as you want. If you need I am happy to help. On all three board 15 pins (digital/analog) are scanned. 13 is not used because it can not work with PULLUP. (MEGA can do that). Numbering is 1-16, 21-36 and 41-56. If you do not use certain pins nothing to do.

Code: Select all

/* This program is a children of my skeleton_ultimate code, to implement a kind of sensor 
 management with Arduino boards, sending the appropriate info directly to Rocrail by USB.
 Define an MCS2 controller in Rocrail. In the controller's properties select "serial" and
 the Arduino "comport". It is working with any micro switch or IR module, connected to 
 Arduino pins. No any shield or other elements are needed. Decoderless solution inspired 
 by Bert Havinga and Joerg Pleumann */

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

#include <Wire.h>

int a=2; //number of virtual sensor blocks
int b=8; 
int sensors[7];  // status "matrix"
byte tx_msg[13];

void setup() {
  Wire.begin();          // join i2c bus 
  Serial.begin(500000);  // start serial for output
  tx_msg[0] = 0;// prio     
  tx_msg[1] = 35;// command
  tx_msg[2] = 59;// highByte(hash)
  tx_msg[3] = 121;// lowByte(hash)
  tx_msg[4] = 8;// the number of data bytes in the payload      
  tx_msg[5] = 0;
  tx_msg[6] = 1;// bus number
  tx_msg[7] = 0;
  tx_msg[9] = 0;      
  tx_msg[11]= 0;
  tx_msg[12]= 0;
  for (int ap = 1; ap <= a; ap++) { // read pin status and write to sensors variable
    for (int bp = 1; bp <= b; bp++) {
      if (ap*b+bp-7!=13) {
        pinMode(ap*b+bp-7, INPUT_PULLUP);
        bitWrite(sensors[ap],bp-1,digitalRead(ap*b+bp-7) ^ 1);
      }
    } 
  }
}

void loop() {
  for (int ap = 1; ap <= a; ap++) {  // scan pins by virtual blocks and check twice (avoiding mistakes)
    for (int bp = 1; bp <= b; bp++) { // there was change on pin state compare to previous scan ?   
      if (ap*b+bp-7!=13) {
        if (digitalRead(ap*b+bp-7)!=bitRead(sensors[ap],bp-1)) {
          delay(10);
          if (digitalRead(ap*b+bp-7)!=bitRead(sensors[ap],bp-1)) { // if yes, change the bit
            bitWrite(sensors[ap],bp-1,digitalRead(ap*b+bp-7));    // in 'sensors' variable
            //while (kk==0) {
              tx_msg[8]=ap*b+bp-8;        // sensor number
              tx_msg[10]=digitalRead(ap*b+bp-7);// pin status
              //delay(d0);
              //kk=1;
              Serial.write(tx_msg,13);            
          }
        }
      }
    }
  }
  Wire.requestFrom(8, 2);    // request 2 bytes from slave device #8
  if (Wire.available()==2) { // two bites in the puffer
    tx_msg[8]= Wire.read();
    tx_msg[10]= Wire.read();
    if (tx_msg[10]!=255) { // it is a real message
      Serial.write(tx_msg,13); 
    }
  }
  Wire.requestFrom(9, 2);    // request 2 bytes from slave device #9
  if (Wire.available()==2) { // two bites in the puffer
    tx_msg[8]= Wire.read();
    tx_msg[10]= Wire.read();
    if (tx_msg[10]!=255) { // it is a real message
      Serial.write(tx_msg,13); 
    }
  }    
}
For Rocrail setup see the following links http://forum.rocrail.net/viewtopic.php?f=11&t=10120 http://forum.rocrail.net/viewtopic.php? ... 20#p101930
The next code for Slave 1. I have put notes where you have to change numbers for Slave 2.

Code: Select all

#include <Wire.h>

int a=2; //number of virtual sensor blocks
int b=8; 
int sensors[7];  // status "matrix"
byte tx_msg[2]; // status message to Master
int kk=0;
int d0=50;
int c=20; //in second Slave case, change it to 40

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
  for (int ap = 1; ap <= a; ap++) { // read pin status and write to sensors variable
    for (int bp = 1; bp <= b; bp++) {
      if (ap*b+bp-7!=13) {
        pinMode(ap*b+bp-7, INPUT_PULLUP);
        bitWrite(sensors[ap],bp-1,digitalRead(ap*b+bp-7) ^ 1);
      }
    } 
  }
  delay(6000); // have to wait until Master is ready, change it to 8000 in second Slave case
}

void loop() {
  for (int ap = 1; ap <= a; ap++) {  // scan pins by virtual blocks and check twice (avoiding mistakes)
    for (int bp = 1; bp <= b; bp++) { // there was change on pin state compare to previous scan ?   
      if (ap*b+bp-7!=13) {
        if (digitalRead(ap*b+bp-7)!=bitRead(sensors[ap],bp-1)) {
          delay(10);
          if (digitalRead(ap*b+bp-7)!=bitRead(sensors[ap],bp-1)) { // if yes, change the bit
            bitWrite(sensors[ap],bp-1,digitalRead(ap*b+bp-7));    // in 'sensors' variable
            while (kk==0) {
              tx_msg[0]=ap*b+bp-8+c;          // sensor number
              tx_msg[1]=digitalRead(ap*b+bp-7);// pin status
              delay(d0);
              kk=1;
            }
          }
        }
      }
    }
  }
  d0=0;
}

void requestEvent() {
  if (kk==1) {
    Wire.write(tx_msg,2);
    kk=0;
  }
}
If the RR is running when you connect the USB to Master all boards going to scan the sensor's status and send to RR. After only the changes are sent.
If the USB is connected when RR starts, you have to push the reset button on all boards after each other.

I hope you will enjoy this simple and effective solution. Any question and suggestion are welcome.

Laszlo
Last edited by rozsaheg on 04.10.2017, 19:13, edited 3 times in total.

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 11.06.2017, 16:10

Hi Laszlo,
thank you for sharing the coce.

Just a couple of clarification:

--> delay(6000); // have to wait until Master is ready, change it to 8000 in second Slave case

why are needed 6 or 8 seconds to the slave to set up ?

--> delay(d0);

this delay is due to ensure the slave transmission I suppose, did you try to set several values ?

And finally... why you don't start with address 1, 2... for slave board (you start from 8!) ?

thank you in advance

ciao

rozsaheg
Posts: 25
Joined: 10.06.2015, 21:02

Re: Arduino USB interface for sensor feedback to Rocrail

Post by rozsaheg » 12.06.2017, 09:38

Hi Antonino,

If Rocrail is running when you connect the USB, the safety time for master to start and finish the first scan and send the status to Rocrail is six second. For the second slave plus other 2 second is needed because it has to wait until the first slave do the same.
The delay(d0) 50 msec is needed to the slaves for first scan, because during this time the master send requests and receive the answers for each pin.

When all pin status is checked at start, further no any delay is active.

The numbering is start from pin 2 to pin 18. RX TX are not included. Unfortunately the Nano cannot deal with pin 13 PULLUP so it is avoided as well. The MEGA can work on that way. The sensor number is not the same as the pin number. If you want change the numbering you can easily do that.

Regards

Laszlo

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 15.06.2017, 07:06

Thanks Laszlo, I am doing the same but with PCF8574 for slave i2c device. I found very cheap boards with 8 pin on the web, I will share the code as far as I have a stable solution.

Bye :)

sv1iw
Posts: 46
Joined: 16.09.2014, 21:40

Re: Arduino USB interface for sensor feedback to Rocrail

Post by sv1iw » 16.06.2017, 18:57

Hi Laszlo, as always clever solutions...

Regards
Manos

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 26.08.2017, 12:03

Hi to All,

starting from the code posted by Laszlo, I have developed a version of the feedback module that can connect slave cheap I2C boards with PCF8574 or PCF8574A, each board have 8 pin that are used as inputs. This can allow to have a single version of software with flexible management of addresses.

The board I used for development are very cheap (you can find boards for less that 1,5€) and they can be easily chained:
PCF8574-1.jpg
but also other boards are suitable, for example the I2C adapter of LCDs
ser-i2c-lcd-adattatore.jpg
The operation mode of the code is very simple: at the reset, Arduino scans the I2C bus finding connected boards. At the end of the scanning process if boards are found, they are counted with the variable nDevices. Then the code will scan the Arduino pin and, if nDevices is greater than 0, the pin of the connected boards. Each boards should have different address, Arduino will consider all the PCF pin with address starting from 16 and the pins will be added starting from the board with lower address. For example if two boards are connected, board A with address 56 (DEC) and board B with address 58 (DEC), the pin of board A will be counted from 16 to 23, and board B from 24 to 31.

In this foto you can see Arduino Nano connected with two slave boards, Ardiuno and the two PF8574 are connected with a simple current sensor board with 4 inputs.
File 26-08-17, 12 20 09.jpeg
here the code...
Feedback_CS2_Nano_tempo_rev05.txt
(7.23 KiB) Downloaded 15 times
Next steps are to manage error condition on I2C through the led on pin 13 of Arduino and development of a simple board with P85B715, a chip to improve electrical connection of I2c Bus. Arduino and PCF8574 can drive 400pf maximuunn capacity with I2c interface that mean a couple of meter with standard quality of connection, p82b715 can improve capacity up to 3000pf.

bye
:)
antogar

VikenSheth
Posts: 22
Joined: 26.05.2016, 09:15

Re: Arduino USB interface for sensor feedback to Rocrail

Post by VikenSheth » 14.07.2018, 05:25

Hi,

I am facing an issue while configuring 2nd slave, as per the code details given in this post. The changes I have made are below, attaching the code files for master, slave 1 and slave 2

For slave 1
int c=20; //in second Slave case, change it to 40

delay(6000); // have to wait until Master is ready, change it to 8000 in second Slave case

For slave 2
int c=40; //in second Slave case, change it to 40

delay(8000); // have to wait until Master is ready, change it to 8000 in second Slave

Master code is working fine and slave 1 code is also working fine.connection between all the arduino boards are connected as per the diagram which you have posted above .

The moment i connect slave 2, slave 1 pins address doesn't get detected by RR and address of slave 2 is also not getting detected, however master code works fine.

If I disconnect slave 1 then the address of slave 2 gets detected.

Would like to know meaning of int c=20, int c=40; int a=2 and int b=8 in master sketch.

Also I would like to configure total 6 boards from which 1 is master and 5 are slaves, please tell what values I need to change as I start configuring rest of the arduino boards.

Regards,
Viken
Attachments
Slave2_Arduino.txt
(1.59 KiB) Downloaded 3 times
Slave1_Arduino.txt
(1.59 KiB) Downloaded 4 times
Master_Arduino.txt
(3.17 KiB) Downloaded 5 times

pesitalia
Posts: 2
Joined: 25.11.2018, 20:26

Re: Arduino USB interface for sensor feedback to Rocrail

Post by pesitalia » 29.11.2018, 20:02

Hi Laszlo
I have just installed an arduino mega with circa 40 IR sensors used as 'position sensors' in my layout. I have connected the arduino to rocrail via serial port. Everything is fine except that I cannot find a way to instruct rocrail to automatically query all sensors at startup, in order to view their actual status in the track plan as soon as it opens up. In fact they are all green, as if there was communication between transmitter and receiver , which is not the case for some of them because of a loco actually located between T and R blocking any communication. For your info I have installed the transmitter in the rail plane looking up and the shielded receiver about 10 cm above the plane looking down to avoid any interference from ambient light. If I change status to a sensor by moving the loco back and forth , the relevant sensor on track plan will behave correctly as it will change status from green to red .
At rocrail startup I have tried to launch 'start of day' and 'query sensors' from the top menu but nothing happens; 'sensor monitor' windows is empty until I change status to a sensor, which will appear immediately in the windows showing its correct status. Can you hepl me on this?
Regards
Carlo Borra

Antogar
Posts: 32
Joined: 11.02.2017, 23:10

Re: Arduino USB interface for sensor feedback to Rocrail

Post by Antogar » 25.01.2019, 09:10

Hi Carlo and everyone,

I just read now this topic (sorry, I had the notify switched-off :( )

Please find attached a revision of the code with your request included: the software send to RocRail the sensors status at power-on and replies to RocRail at the command "start of the day".

The code is for an Arduino Uno and 14 sensors, it is easy to modify for an Arduino Mega with more pins…

Bye
Antonino
Feedback_CS2_Nano_tempo_rev08.txt
(9.31 KiB) Downloaded 18 times

Post Reply

Return to “DIY Hardware”