Serial communication between Roborealm and Arduino

I am trying to export data from Roborealm (Vision software) through COM3 to my Arduino Uno which is also connected on COM3.

When I connect my Arduino to COM3 and then Roborealm on COM3, then I get a message in my arduino that my port is busy.

Is it possible to have my Arduino connected on the same port like Roborealm?

Is it possible to have my Arduino connected on the same port like Roborealm?

Even if you could, what do you expect to do ?

If you are trying to communicate between Roborealm and the Arduino that is not the way to do it.

Posting a link to the datasheet or user manual for Roborealm would help.

If the Roborealm device connects to a PC using a USB connection then you will need a USB host shield if you want to connect it to an Arduino. However I have no idea whether an Arduino USB host shield would recognize the Roborealm device.

Alternatively you could write a PC program that collects the data from the Roborealm device and then sends it to the Arduino using a separate COM port.

...R

What are planning on having the Arduino Uno do with the RoboRealm's data?
It is sophisticated software that runs on a PC.
http://www.roborealm.com/help/Serial.php

Roborealm gives me the position of an object relatively to the center of the screen. Then arduino will adjust the error with a servo untill the object is in the middle of the screen.

Sounds simple enough.

Post your Arduino sketch using code tags.

Roborealm gives me the position of an object relatively to the center of the screen

How is this information formatted ?

MihaelR:
Roborealm gives me the position of an object relatively to the center of the screen.

How does it give the information?

Does it come through a USB cable?

...R

Roborealms output is ASCII and sends the data through usb which is connected on COM3.

The code what I use is:

#include <Servo.h> 

Servo servos[12];
boolean pinModes[14];

unsigned int g_crc;
unsigned int g_command;
unsigned int g_channel;
unsigned int g_value;
unsigned int g_valueLow;
unsigned int g_valueHigh;
unsigned int g_streamDigital;
unsigned int g_streamAnalog;
unsigned int g_lastDigital;
unsigned int g_lastAnalog[8];
unsigned int g_heartBeat=0;
unsigned int g_defaultServo[14];

#define ARDUINO_GET_ID 0
#define ARDUINO_SET_SERVO 1
#define ARDUINO_SET_DIGITAL_STREAM 2
#define ARDUINO_SET_DIGITAL_HIGH 3
#define ARDUINO_SET_DIGITAL_LOW 4
#define ARDUINO_SET_ANALOG_STREAM 5
#define ARDUINO_DIGITAL_STREAM 6
#define ARDUINO_ANALOG_STREAM 7
#define ARDUINO_SET_ANALOG 8
#define ARDUINO_SET_SERVO_DEFAULT 9
#define ARDUINO_HEARTBEAT 10

void initialize()
{
  int i;
  for (i=2;i<14;i++) pinModes[i]=-1;
  g_streamDigital=0;
  g_streamAnalog=0;
  g_lastDigital=-1;
  for (i=0;i<8;i++) g_lastAnalog[i]=-1;
  for (i=0;i<12;i++) g_defaultServo[i]=1500;
}

void setup() 
{
  Serial.begin(115200);

  initialize();
}

void writePacket()
{
  unsigned char buffer[2];  
  buffer[0]=g_command|128;
  buffer[1]=g_channel;
  Serial.write(buffer, 2);
}

void writeValuePacket(int g_value)
{
  unsigned char buffer[5];  
  
  buffer[0]=g_command|128;
  buffer[1]=g_channel;
  buffer[2]=g_value&127;
  buffer[3]=(g_value>>7)&127;
  buffer[4]=(buffer[0]^buffer[1]^buffer[2]^buffer[3])&127;
  
  Serial.write(buffer, 5);
}

void readPacket()
{
  // get header byte
  // 128 (bit 8) flag indicates a new g_command packet .. that 
  // means the g_value bytes can never have 128 set!
  // next byte is the g_command 0-8
  // next byte is the g_channel 0-16

  do
  {
    while (Serial.available() <= 0) continue; 
    g_command = Serial.read();
  }
  while ((g_command&128)==0);
  
  g_command^=128;

  while (Serial.available() <= 0) continue; 
  g_channel = Serial.read();
}

int readValuePacket()
{
  unsigned int g_valueLow;
  unsigned int g_valueHigh;
  
  // wait for g_value low byte    
  while (Serial.available() <= 0) continue; 
  g_valueLow = Serial.read();
  if (g_valueLow&128) return 0;

  // wait for g_value high byte    
  while (Serial.available() <= 0) continue; 
  g_valueHigh = Serial.read();
  if (g_valueHigh&128) return 0;
    
  // wait for g_crc byte    
  while (Serial.available() <= 0) continue; 
  g_crc = Serial.read();
  if (g_crc&128) return 0;
  
  if (g_crc!=(((128|g_command)^g_channel^g_valueLow^g_valueHigh)&127)) return 0;

  g_value = g_valueLow|(g_valueHigh<<7);
  
  return 1;
}

void loop() 
{
  while (Serial.available()>0)
  {
    readPacket();
    
    g_heartBeat=0;

    switch (g_command)
    {
      // init
      case  ARDUINO_GET_ID:
        initialize();
        Serial.print("ARDU");
      break;
      // servo
      case  ARDUINO_SET_SERVO:
        if ((g_channel>=3)&&(g_channel<=11))
        {
          if (readValuePacket())
          {
            if (pinModes[g_channel]!=1)
            {
              servos[g_channel].attach(g_channel);
              pinModes[g_channel]=1;
            }
            servos[g_channel].writeMicroseconds(g_value);
            writeValuePacket(g_value);
          }
        }
      break;
      //digital stream
      case  ARDUINO_SET_DIGITAL_STREAM:
        if (readValuePacket())
        {
          g_streamDigital = g_value;
          writeValuePacket(g_value);
          g_lastDigital=-1;
        }
      break;
      //set digital high
      case  ARDUINO_SET_DIGITAL_HIGH:
        if ((g_channel>=2)&&(g_channel<14))
        {
          if (pinModes[g_channel]!=2)
          {
            if (pinModes[g_channel]==1)
              servos[g_channel].detach();

            pinMode(g_channel, OUTPUT);
            pinModes[g_channel]=2;
            if (g_streamDigital&(1<<g_channel))
              g_streamDigital^=1<<g_channel;
          }
          
          digitalWrite(g_channel, HIGH);
          writePacket();
        }
      break;
      //set digital low
      case  ARDUINO_SET_DIGITAL_LOW:
        if ((g_channel>=2)&&(g_channel<14))
        {
          if (pinModes[g_channel]!=2)
          {
            if (pinModes[g_channel]==1)
              servos[g_channel].detach();
              
            pinMode(g_channel, OUTPUT);
            pinModes[g_channel]=2;
            
            if (g_streamDigital&(1<<g_channel))
              g_streamDigital^=1<<g_channel;
          }
          digitalWrite(g_channel, LOW);
          writePacket();
        }
      break;
      //analog stream
      case  ARDUINO_SET_ANALOG_STREAM:
        if (readValuePacket())
        {
          g_streamAnalog = g_value;
          writeValuePacket(g_value);
          for (g_channel=0;g_channel<8;g_channel++) g_lastAnalog[g_channel]=-1;
        }
      break;
      case  ARDUINO_SET_ANALOG:
        if (readValuePacket())
        {
					if ((g_channel>=3)&&(g_channel<=11))
					{
						if (pinModes[g_channel]!=2)
						{
							if (pinModes[g_channel]==1)
								servos[g_channel].detach();

							pinMode(g_channel, OUTPUT);
							pinModes[g_channel]=2;
						}
						analogWrite(g_channel, g_value);
						writeValuePacket(g_value);
					}
        }
      break;
      case  ARDUINO_SET_SERVO_DEFAULT:
        if ((g_channel>=3)&&(g_channel<=11))
        {
          if (readValuePacket())
          {
            g_defaultServo[g_channel] = g_value;
						writeValuePacket(g_value);
          }
        }
      break;
      case ARDUINO_HEARTBEAT:
      break;
    }
  }
  
  if ((g_heartBeat++)>25000)
  {
    int i;
    for (i=3;i<12;i++)
    {
      if (pinModes[i]==1) 
        servos[i].writeMicroseconds(g_defaultServo[i]);
      else
      if (pinModes[i]==2) 
        analogWrite(i, 0);
    }
  }

  for (g_channel=0;g_channel<8;g_channel++)
  {
    if (g_streamAnalog&(1<<g_channel))
    {
      g_value = analogRead(g_channel);
      // only send g_value if it has changed
      if (g_value!=g_lastAnalog[g_channel])
      {
        g_command = ARDUINO_ANALOG_STREAM;
        writeValuePacket(g_value);
        
        g_lastAnalog[g_channel]=g_value;
      }
    }
  }

  if (g_streamDigital)
  {
    g_value=0;
    for (g_channel=2;g_channel<14;g_channel++)
    {
      if (g_streamDigital&(1<<g_channel))
      {
        if (pinModes[g_channel]!=3)
        {
          if (pinModes[g_channel]==1)
            servos[g_channel].detach();
            
          pinMode(g_channel, INPUT);
          pinModes[g_channel]=3;
          // pullup
          digitalWrite(g_channel, HIGH); 
        }
        
        g_value |= digitalRead(g_channel)<<g_channel;
      }
    }

    // only send g_value if it has changed
    if (g_value!=g_lastDigital)
    {    
      g_command = ARDUINO_DIGITAL_STREAM;
      writeValuePacket(g_value);

      g_lastDigital=g_value;
    }
  }
}


[CODE]

MihaelR:
Roborealms output is ASCII and sends the data through usb which is connected on COM3.

Then it can't send data directly to an Arduino unless you have a USB host shield.

The code what I use is:

Is that code in your Arduino? What Arduino board are you using?

...R

Sorry for the late response. I bought an Arduino USB host shield for my Arduino uno. What I did was as follow:

On COM4 is my output from roborealm to my usb host shield which is connected on my arduino uno. On COM3 is my usb cable which is connected on my arduino uno, however, Roborealm then switches automatically to COM3, and then I get an error in the arduino software and says my port is busy (because roborealm took the port over)...

How do I use this usb host shield?

Ps: the code is in Arduino

MihaelR:
Sorry for the late response. I bought an Arduino USB host shield for my Arduino uno. What I did was as follow:

On COM4 is my output from roborealm to my usb host shield which is connected on my arduino uno.

Please draw a diagram of how you have things connected and post a photo of the drawing.

I can't understand how you expect the output from roborealm to appear on COM4 if it is actually connected to your usb host shield

...R

This is how it is connected

Image from Reply #12 so we don’t have to download it. See this Simple Image Guide

6b2e10b4d7aa1ded348ee96f1ba2caa4c8db9aeb.png

…R

There is a serious lack of understanding somewhere.

AFAIK COM4 is a USB port on a PC acting as a serial connection.

From what you said in Reply #8 I understood that Roborealm is a piece of hardware that connects to the PC through a USB cable - in which case it would connect to COM4.

But I can’t figure why you mention COM4 if the cable from Roborealm is connected to the Arduino USB host shield.

The picture I was expecting you to post is like this - the dotted lines mean that the Roborealm can connect to the PC or to the USB host shield.

MihaelIR.jpg

…R

Sorry my mistake. Roborealm is a software on my pc. So my pc has to export the data from the software to the Arduino, and also run the Arduino's serial communication.

I have mentioned COM4, because I thought I need one cable to export Roborealms data to the Arduino host shield and another cable (COM3) to use the Arduino.

Is it enough to connect only the cable to my host shield? Because I did this and the Arduino turned on, but it did not find a port to connect on.

MihaelR:
Sorry my mistake. Roborealm is a software on my pc.

Well why did you say in Reply #8 that it communicates via USB and why did you buy a USB host shield?

So my pc has to export the data from the software to the Arduino, and also run the Arduino's serial communication.

That sounds as if you just need two serial connections between your PC and your Arduino. Use the regular USB cable for one of them and use a USB-TTL cable connected to an instance of SoftwareSerial for the other one.

...R

I meant with "it communicates via USB" that Roborealm needs to export the data through usb to the arduino. Arduino needs to read this data in the serial communication. Why I bought the USB host shield, was that I thought I need it, because I couldn't connect twice on the same port. In Roborealm I need to select a port to export this data. In Arduino software I alsno need to select a port for it. If I select the same port, Roborealm takes the port over and Arduino is not connected anymore.

That sounds as if you just need two serial connections between your PC and your Arduino. Use the regular USB cable for one of them and use a USB-TTL cable connected to an instance of SoftwareSerial for the other one.

Where do I connect these USB cables?

MihaelR:
Where do I connect these USB cables?

One of them is the normal Arduino to PC USB cable - I assume you know how to connect that?

The USB TTL cable connects to a PC USB connection at one end and to the pins you have allocated for SoftwareSerial at the other end.

...R

I have the USB TLL converter. I have made a drawing of the schematic (link underneath). I understood that I have to connect the TX (transmitting) and RX (receiving) on the same ports of the Arduino.

I have never worked with the port TX and RX for Serial.Read. Is it possible to read PWM-values through this port? And do I need to use RX for the Serial.read function?