by marco » Mon Nov 07, 2011 12:21 pm
by marco
Mon Nov 07, 2011 12:21 pm
Hi,
I’m trying to build a setup in which I can remotely control a
Dagu Wild Thumper robot from a windows PC. Besides remote control, I’d also like to have remote uploading capabilities as well as have a webcam onboard the robot, get the video stream to my laptop, process it and send control commands back to the robot, therefore having some kind of closed loop control.
So here you can see a high-level diagram of the desired system:
First of all I’ll concentrate on solving the PC-Linux-Arduino communication problem.
Communication with the Arduino is done via USB with a FTDI USB-to-Serial Converter. For this test I used an
eBox 3310MX-H Mini PC on which I installed ubuntu from a USB stick and followed the standard
installation instructions. I managed to get the system up and running without much hassle. After connecting a USB cable from the eBox to the Arduino I got a nice /dev/ttyUSB0 device to play with. I also connected an ethernet cable from the eBox to my laptop and shared my wireless internet connection, so now I had internet on the eBox and both machines were able to speak to each other.
Next, I needed some software solution that would:
1) On the Linux side, connect to the /dev/ttyUSB0 device on the eBox and relay all incoming/outgoing data to a network port;
2) On the windows side, connect to the network port and create a virtual (fake) COM port that would be fed with data from the network port so that it would act just as if the Arduino board was connected locally.
After some googling I found a nice Wikipedia page that summed up my options for both of these problems:
http://en.wikipedia.org/wiki/COM_port_redirector
My first options were socat + HW VSP3.
On the linux side socat behaved very well, it was just a matter of understanding the command line syntax. I ended up with this command:
- Code: Select all
socat OPEN:/dev/ttyUSB0,b115200,crtscts=0 TCP-LISTEN:5000
And now I have socat waiting for someone to connect via TCP to port 5000 and it will handle transferring the data between both interfaces. Cool!
Now for the windows part. I downloaded and installed HW VSP3 and configuration was trivial. I just selected a name for the virtual com port (COM3) punched in the IP address of the eBox and the port number and pressed “Create COM”. Then I opened up Putty, connected it to COM3 and started writing random characters. I could see that for every key press I made the Arduino board’s RX led would blink, so my connection was active.
In order to test the communication I wrote a simple Arduino sketch that would read a byte from the serial port, increment it by 1 and send it back:
- Code: Select all
void setup()
{
Serial.begin(115200);
}
void loop()
{
if(Serial.available() > 0)
{
int a = Serial.read();
Serial.write(++a);
}
}
By now I attempted to upload the program via the virtual com port. It should work, in theory. But it didn’t. Anyhow, everything seemed to be correctly configured so I connected the Arduinto directly to the laptop, uploaded the program, setup the virtual com ports again, opened Putty again and wrote “Hello World!” and this is what I got back:
I got exactly what I expected! Hurray, communication does work. But this setup was not good enough for remotely uploading stuff to the Arduino.
It happens that in order to program the Arduino a specific serial port configuration must be used. Trying to upload with verbose output shows us exactly what is happening:
First of all the DTR line is set. This is used to reboot the Arduino so that the boot loader is back in charge of what is happening. Besides that, the baud rate is set to 19200. Since our serial port configuration on the serial side is set beforehand, we need a different solution in order to make changes whenever needed, without having to configure it manually. Luckily, there is already a standard for this, the
RFC 2217 called “Telnet Com Port Control Option”. This protocol defines how to send serial port configuration commands through the same stream of data that flows between a virtual serial port and a real serial port.
Unfortunately, the chosen software solution does not implement RFC2217, so we need a different setup.
For the Linux side there seemed to be no ready-to-use solution, so I started thinking about writing my own software. A natural solution would be to write it in Python so that I’d also have a solution that would be cross-platform. Not being familiar with accessing serial ports under Python I came to find the
pySerial library and then these guys just made my day: they had an example that implemented exactly what I wanted to implement. It’s called “Single-port TCP/IP - serial bridge (RFC 2217)” and can be downloaded from
here In order to have this up and running, all you need to do is to open a command-line on the folder where you put this script and enter:
- Code: Select all
./rfc2217_server.py /dev/ttyUSB0
Now we have a server program that is connected to our USB serial port and has a TCP port listening for incoming connections. Notice that this time we haven’t set any kind of serial port configurations, they will all be set automatically from information received from the controlling program on the windows machine.
Going back to the possible software list, I found out that the com0com+hub4com solution for the windows side supports the RFC 2217. This solution has quite a peculiar way of being setup. Com0com always creates two local virtual ports that are connected to each other. Whatever is sent to one of the virtual ports gets received on the other and vice-versa. In order to connect to a virtual port in another computer you have to use hub4com, which is a command line program. So in order to get this working, you have to do the following:
1. Install com0com. Make sure you get the latest versions. ( download from
here )
2. Run the com0com setup program and create a new virtual pair.
3. Add a new virtual pair and change the name of the first port to COM3 (or whichever number you prefer) and press “Apply”. You need to change the name because the Arduino program doesn’t recognise com ports that have strange names.
4. Download hub4com and uncompress the zip file ( download from
here )
5. Open up the command line and go to hub4com’s folder.
6. Enter this command:
- Code: Select all
com2tcp-rfc2217.bat \\.\CNCB0 192.168.137.200 2217
(adjust for your linux box IP address. 2217 is the default port used by the python program).
You should be looking at something like this:
And on the Linux side:
And voilá! Everything is setup and now you can use the remote serial port as if it was a local port. Normal communication as well as uploading sketches is supported and as long as you have a good network connection you shouldn’t have any problems.
Next step in this project is to have an Omnima - MiniEMBWiFi board onboard the robot running Linux so that our robot can go wireless.
Regards,
Marco Barbosa
Hi,
I’m trying to build a setup in which I can remotely control a
Dagu Wild Thumper robot from a windows PC. Besides remote control, I’d also like to have remote uploading capabilities as well as have a webcam onboard the robot, get the video stream to my laptop, process it and send control commands back to the robot, therefore having some kind of closed loop control.
So here you can see a high-level diagram of the desired system:
First of all I’ll concentrate on solving the PC-Linux-Arduino communication problem.
Communication with the Arduino is done via USB with a FTDI USB-to-Serial Converter. For this test I used an
eBox 3310MX-H Mini PC on which I installed ubuntu from a USB stick and followed the standard
installation instructions. I managed to get the system up and running without much hassle. After connecting a USB cable from the eBox to the Arduino I got a nice /dev/ttyUSB0 device to play with. I also connected an ethernet cable from the eBox to my laptop and shared my wireless internet connection, so now I had internet on the eBox and both machines were able to speak to each other.
Next, I needed some software solution that would:
1) On the Linux side, connect to the /dev/ttyUSB0 device on the eBox and relay all incoming/outgoing data to a network port;
2) On the windows side, connect to the network port and create a virtual (fake) COM port that would be fed with data from the network port so that it would act just as if the Arduino board was connected locally.
After some googling I found a nice Wikipedia page that summed up my options for both of these problems:
http://en.wikipedia.org/wiki/COM_port_redirector
My first options were socat + HW VSP3.
On the linux side socat behaved very well, it was just a matter of understanding the command line syntax. I ended up with this command:
- Code: Select all
socat OPEN:/dev/ttyUSB0,b115200,crtscts=0 TCP-LISTEN:5000
And now I have socat waiting for someone to connect via TCP to port 5000 and it will handle transferring the data between both interfaces. Cool!
Now for the windows part. I downloaded and installed HW VSP3 and configuration was trivial. I just selected a name for the virtual com port (COM3) punched in the IP address of the eBox and the port number and pressed “Create COM”. Then I opened up Putty, connected it to COM3 and started writing random characters. I could see that for every key press I made the Arduino board’s RX led would blink, so my connection was active.
In order to test the communication I wrote a simple Arduino sketch that would read a byte from the serial port, increment it by 1 and send it back:
- Code: Select all
void setup()
{
Serial.begin(115200);
}
void loop()
{
if(Serial.available() > 0)
{
int a = Serial.read();
Serial.write(++a);
}
}
By now I attempted to upload the program via the virtual com port. It should work, in theory. But it didn’t. Anyhow, everything seemed to be correctly configured so I connected the Arduinto directly to the laptop, uploaded the program, setup the virtual com ports again, opened Putty again and wrote “Hello World!” and this is what I got back:
I got exactly what I expected! Hurray, communication does work. But this setup was not good enough for remotely uploading stuff to the Arduino.
It happens that in order to program the Arduino a specific serial port configuration must be used. Trying to upload with verbose output shows us exactly what is happening:
First of all the DTR line is set. This is used to reboot the Arduino so that the boot loader is back in charge of what is happening. Besides that, the baud rate is set to 19200. Since our serial port configuration on the serial side is set beforehand, we need a different solution in order to make changes whenever needed, without having to configure it manually. Luckily, there is already a standard for this, the
RFC 2217 called “Telnet Com Port Control Option”. This protocol defines how to send serial port configuration commands through the same stream of data that flows between a virtual serial port and a real serial port.
Unfortunately, the chosen software solution does not implement RFC2217, so we need a different setup.
For the Linux side there seemed to be no ready-to-use solution, so I started thinking about writing my own software. A natural solution would be to write it in Python so that I’d also have a solution that would be cross-platform. Not being familiar with accessing serial ports under Python I came to find the
pySerial library and then these guys just made my day: they had an example that implemented exactly what I wanted to implement. It’s called “Single-port TCP/IP - serial bridge (RFC 2217)” and can be downloaded from
here In order to have this up and running, all you need to do is to open a command-line on the folder where you put this script and enter:
- Code: Select all
./rfc2217_server.py /dev/ttyUSB0
Now we have a server program that is connected to our USB serial port and has a TCP port listening for incoming connections. Notice that this time we haven’t set any kind of serial port configurations, they will all be set automatically from information received from the controlling program on the windows machine.
Going back to the possible software list, I found out that the com0com+hub4com solution for the windows side supports the RFC 2217. This solution has quite a peculiar way of being setup. Com0com always creates two local virtual ports that are connected to each other. Whatever is sent to one of the virtual ports gets received on the other and vice-versa. In order to connect to a virtual port in another computer you have to use hub4com, which is a command line program. So in order to get this working, you have to do the following:
1. Install com0com. Make sure you get the latest versions. ( download from
here )
2. Run the com0com setup program and create a new virtual pair.
3. Add a new virtual pair and change the name of the first port to COM3 (or whichever number you prefer) and press “Apply”. You need to change the name because the Arduino program doesn’t recognise com ports that have strange names.
4. Download hub4com and uncompress the zip file ( download from
here )
5. Open up the command line and go to hub4com’s folder.
6. Enter this command:
- Code: Select all
com2tcp-rfc2217.bat \\.\CNCB0 192.168.137.200 2217
(adjust for your linux box IP address. 2217 is the default port used by the python program).
You should be looking at something like this:
And on the Linux side:
And voilá! Everything is setup and now you can use the remote serial port as if it was a local port. Normal communication as well as uploading sketches is supported and as long as you have a good network connection you shouldn’t have any problems.
Next step in this project is to have an Omnima - MiniEMBWiFi board onboard the robot running Linux so that our robot can go wireless.
Regards,
Marco Barbosa