Serial port over IP

Summary

Since most modern computers don't have a serial port, or a parallel port, mostly we use USB to serial converters. And what are the changes that we have to use a serial cable now-a-days? In the case we need a serialport, why not use the mbed over IP?

Status

Currenlty creating a telnet daemon.

Primary goals

  1. [ x ] Use a serial port of the mbed to read and write to a RS232-able device.
  2. [ _ ] Use the serial port with telnet
  3. [ x ] Change settings using the webserver.

Secondary goals

  1. [ _ ] Use the serial port in a web browser
  2. [ _ ] Send the received serialport data to a syslog server.
  3. [ _ ] Make one port for 3.3V or 5.0V TTL and one port for normal RS232 by using external IC's, e.g. MAX232.

Steps

  1. Create and maintain this notebook page
  2. Hardware
  3. Research the needed software components
  4. Serial port access
  5. Telnet
  6. Webserver

Hardware

Since we can only test the design, we need hardware to facilitate all the actual IO's we need. For the first tests this would only be an ethernet connector with internal transformers, since we can 'loop' the serial output to the input.

Later we will need a transceiver to place between an external connector and the pins of the first serial port. And a MAX232, or equivalent, with necessary components to make a 'normal' serial connection.

We can also add some L.E.D.'s for rx/tx indications, however, the mbed is supplied with 4 of them, so what's the need?

[Update: 30/04/2010@20:48]

An ethernet connector is obtained, even two, with included transformers. So ethernet operations can be tested after I found a stable and decent way to attach the ehternet connector to my testbed/breadboard. Time to bring out the etching-toolkit again.

Also I've managed to borrow a FTDI serial cable for testing the UART connectivity, until I get a better device to test with or on. First steps of the project are getting along well using it.

Last hardware steps would be a MAX232 and PCB-like solution for easier reproduction.

[Update: 04/05/2010@12:31]

Last weekend I managed to etch a small PCB for the ethernet connector, and it indicates network link on the switch. This seems to be a good progress, now let's get an IP stack.

Software components

Besides the available components in the mbed library, to access all the IO, this project requires some more components. There are several sub components which need research and implementation, and as soon as there is more information on a component it will be added.

IP stack

First part of investigation will be an proper IP stack, so the first stop would be to check-out lwip.

[Update: 04/05/2010@12:31]

I did some research on the IP stacks, and from what I could see there's lwip, and there's uIP. Both from the same programmer, but the goals are different.

[Update: 05/05/2010@14:09]

From what it looks like at this moment, I need to thinker a bit with the current lwip implementation. Although some features are working, like the RPC HTTP server, it's far from close what I want.

[Update: 06/05/2010@11:46]

Dug a bit further in lwIP and noticed that the current simplehttpd example was quite useful, though it had to be changed in my eyes, to support multiple sockets.

Where the Simple HTTP server didn't make an object of the ethernet interface, I made it an object. This made it easier to attach multiple sockets.

 

Simple HTTP server:

NetServer::ready()->bindTCPPort(80, &accept_callback);

Mine version:

//--- Objects
NetServer *networkInterface;

//--- functions
//--- all NetServer::-like calls, replaced with networkInterface->

//--- main() 
int         dhcp = 0;
    
    //--- Create interface
    if( dhcp ) {
        //--- DHCP
       networkInterface = NetServer::create( );
    } else {
        //--- Static
      networkInterface = NetServer::create( 
                                    IPv4( 10, 10, 10, 10 ), //IP Address
                                    IPv4(255,255,255,  0 ), //Netmask
                                    IPv4( 10, 10, 10,254 )  //Gateway
                                 );
    }
    //--- Init
    networkInterface->init();
    //--- Set up or activate DHCP
    if( dhcp ) {
        //--- DHCP
        networkInterface->waitUntilReady();
    } else {
        //--- Static
        networkInterface->setUp();
    }
    
    //--- Attach callback/listener
    networkInterface->bindTCPPort(80, &accept_80_callback); 
    networkInterface->bindTCPPort(23, &accept_23_callback);
    
    /* Give the signal that we are ready */
    while (1) {
        wait(0.1);
        //--- Cleaner poll
        //networkInterface->poll();
        NetServer::poll();
        
        if (x) {
            led1 = !led1;
        } else {
            led2 = !led2;
        }
    }

This change also makes it possible to use fixed IP addresses, instead of only DHCP.

 

That concludes the IP stack for now.

Serial port access

By using a FTDI serial USB cable, one of the better cable's I've seen in years although they are for PCB connections (not DB9-stuff), I've been able to do some tests with the serial ports of the mbed board.

Single connection loopback

The frist thing to try was to make a loop in the mbed.

The hardware for this is a FTDI cable [link] and a few hard-cored wires to connect everything on a testbed/breadboard.

[ Picture will follow ]

this is easily done by the following code:

 

//--- includes
#include "mbed.h"

//--- defines
#define ON 1
#define OFF 0
#define BAUDRATE 19200

//--- Objects
DigitalOut myLed (LED1);
Serial myUART( p13, p14 );

int main() {
    //--- Init
    myLed = ON;
    wait (0.2);
    myUART.baud( BAUDRATE );
    myLed = OFF;

    while(1) {
        if( myUART.readable() ) {
            myUART.putc( myUART.getc() );
        }
    }
}

This will loop all the input back to your console.

External UART loopback

The next step would be to use a second UART to use a hardware loopback.

The hardware isn't changed, only a hardwired connected between pin 27 and pin 28 of the mbed on the testbed/breadboard.

Used code:

//--- Includes
#include "mbed.h"

//--- Defines
#define     ON          1
#define     OFF         0
#define     BAUDRATE0   19200
#define     BAUDRATE1   115200

//--- Objects
DigitalOut  myled       (LED1);
Serial      myUART      ( p13, p14 );   //--- TX    RX
Serial      loopUART    ( p28, p27 );   //--- TX    RX

int main() {
    char     character;
    
    //--- init
    myled = ON;
    wait(0.2);
    myUART.baud( BAUDRATE1 );
    loopUART.baud( BAUDRATE1 );
    myled = OFF;
    
    while(1) {
        //--- Read myUART and print to loopUART
        if( myUART.readable() ) {
            character = myUART.getc();
            loopUART.printf( "%c", character );
        }
        
        //--- Read loopUART and print to myUART
        if( loopUART.readable() ) {
            character = loopUART.getc();
            
            myUART.printf( "%c", character );
        }
    }
}

Again no big and special stuff, but this were some tests I did to get used to the mbed and setup the system I'm using.

I also did found out that the returns and backspace weren't handled properly by the console. For that reason I've changed some code to support those keys in a better way. Normally this would be supported by the device which you are controlling.

//--- Add by definitions
#define     K_BACKSPACE     8
#define     K_RETURN        13

//--- Replace in while loop
        //--- Read loopUART and print to myUART
        if( loopUART.readable() ) {
            character = loopUART.getc();
            
            //--- Return Key: new line on the console
            if( character == K_RETURN ) {
                myUART.printf("\n\r");
            } else if( character == K_BACKSPACE ) {
                myUART.printf("\b \b");
            } else {
                myUART.printf( "%c", character );
            }
        }

And that concludes all the serial port access for now.

USB Serial port

While reading some notebooks from others, I discovered the UART for USB. This makes debugging of the other UARTs a bit easier. Just change the pins of myUART into USBTX and USBRX and it will work.

Serial port test Publish

uart_test1

Telnet

The basics for Telnet are already there, since it's a really low level TCP communication, You can even use telnet for HTTP request ;).

Now it's time to make sure that everything is handled properly.

Webserver

In order to control the UART settings, used by the telnet daemon, I used a webserver. Based on the Simple HTTP server, which is mentioned earlier, I was able to implement it quite quickly. Next step there was a more dynamic approach on changing settings.

[ code available, but editor isn't liking it. will follow ]

 

[Added: 28/04/10@22:18] - Scribble

Serial port in webbrowser

Normally it would be hard to use a telnet client from a browser, but with some javascript, this must be possible.

Each key on the keyboard is scanned, using javascript. And since each key press has it's own code, you can send this code via javascript commands to your mBed.

You'll have a few pages:
1. main screen where you can change settings, have small help-text and a text-field for the data.
2. a page to where you can post data
3. a page which shows data.

Page 2 and 3 can be combined.

help text: show which keys supplement special keys, like ctrl-d... if that doesn't work directly.
scrolling: the textfield can, or must, have a maximum number of data, and must always show the last data...


4 comments

24 Feb 2011

Hi,

really nice work..can you please share final code and html file for the same?

Thank you,

Vatsal

10 Aug 2011

Hi,

Is progress still being made on this project or has work stopped?

Thanks

Nathan

17 Feb 2015 . Edited: 17 Feb 2015
24 Mar 2017 . Edited: 24 Mar 2017
Hello, thank you for the article. By the way, I've had some experience with accessing serial ports via Network. I work in a company which is a manufacturer of serial port communication equipment. We design and produce the com port hardware for TCP/IP network. Our company stopped on Serial over IP software for our hardware which could be used to connect any serial device to Ethernet network, so Serial over IP is bounding our hardware together. Here is the link - Serial over IP so you can check out the soft.

You need to log in to post a comment