Arduino USB interface for sensor feedback to Rocrail

Moderator: Moderators

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
rozsaheg
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
Antogar
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
rozsaheg
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
You do not have the required permissions to view the files attached to this post.
Antogar
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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.

nanok3_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 */

#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 viewtopic.php?f=11&t=10120 viewtopic.php?f=11&t=10120#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
You do not have the required permissions to view the files attached to this post.
rozsaheg
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
Antogar
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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
rozsaheg
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby 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 :)
Antogar
 

Re: Arduino USB interface for sensor feedback to Rocrail

Postby sv1iw » 16.06.2017, 18:57

Hi Laszlo, as always clever solutions...

Regards
Manos
sv1iw
 

Previous

Return to DIY Hardware