Building PL2303 USB to Serial converter from old data cable

PL2303 and Xbee on a breadboard

PL2303 and Xbee on a breadboard

Despite being quite old, asynchronous serial interface is still popular these days. Xbees, Bluetooth and WiFi embedded adapters, standalone GPS modules are often equipped with asynchronous serial data port. At the same time, standard size Arduino comes with just one asynchronous port – and the same port is used to load compiled sketches and print debug messages. Using these functions while sharing serial port with peripherals is never trivial and often impossible. Recently announced revision 2.0 of USB Host Shield library allows communication with several USB devices simultaneously making it possible to talk to multiple peripherals via USB to serial converters. The converters are available from many places and cost around 15 dollars. However, any old cell phone data cable is essentially a USB to serial converter and can be used as such with not much difficulty. In this article, I will show how to modify data cable originally intended for Sony Ericsson T226 phone into general purpose USB-to-serial.

PL2303-based data cable for Sony Ericsson T226

PL2303-based data cable for Sony Ericsson T226

Picture on the left shows the cable. It has standard USB connector on one end, proprietary Sony data connector on the other, plus a little box in the middle. This cable is about 10 years old. If you go to eBay and search for ‘t226 data cable’, you will see that modern cables often don’t have an enclosure in the middle; typically, a converter is housed inside Sony connector. Those newer cables can also be modified, albeit not that easily.

Next picture shows what is inside the little box – a small PCB with Prolific PL2303 IC on it. USB wires are on the left side and serial wires are on the right. With help of multimeter and PL2303 datasheets I determined that black wire id ground, white wire is transmitter and blue wire is receiver. There is a number of empty pads – they are connected to flow control pins, such as CTS, DTR, etc., which are functional and can be used, if necessary. I soldered thicker teflon-coated wires to the pads, terminated them with sturdy male ends and placed the PCB back into the case. The result can be seen on the title picture.

PL2303 inside the converter

PL2303 inside the converter

To talk to Xbee I wrote simple terminal program similar to one described in Interfacing Arduino to a Cellular Phone article. To use this code you will need an Arduino board, USB Host Shield, as well as USB Host Shield 2.0 library. PL2303 is very similar to ACM, however, Xbee is quite different from the cell phone. First, it doesn’t echo back characters sent to it, and second, it won’t generate Windows-proper newline characters. The following sketch demonstrates the ways to overcome it. Only main loop is presented here, the entire sketch is available in examples directory of USB Host Shield library.

Adding linefeed each time carriage return is transmitted is done in two places – lines 13,14 and 40,41. Max.packet size of bulk endpoints in PL2303 is 64 bytes and buffer size in line 32 is set to this value. Compile and load this program, open terminal window to Arduino, type ‘+++’ to switch Xbee to command mode and then try commands from the screenshot placed after the listing. It is also a good idea to check that your Xbee is loaded with AT firmware and communication speed is set to 115200 – a corresponding X-CTU window is placed next to the terminal screenshot for your reference.

void loop()
    if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
       uint8_t rcode;
       /* reading the keyboard */
       if(Serial.available()) {
         uint8_t data=;
         if ( data == '\r' ) {
           Serial.print("\r\n"); //insert linefeed
         else {
           Serial.print( data ); //echo back to the screen
         /* sending to the phone */
         rcode = Pl.SndData(1, &data);
         if (rcode)
            ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
        /* reading the converter */
        /* buffer size must be greater or equal to max.packet size */
        /* it it set to 64 (largest possible max.packet size) here, can be tuned down
for particular endpoint */
        uint8_t buf[64];
        uint16_t rcvd = 64;
        rcode = Pl.RcvData(&rcvd, buf);
         if (rcode && rcode != hrNAK)
            ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
            if( rcvd ) { //more than zero bytes received
              for(uint16_t i=0; i < rcvd; i++ ) {
                if( buf[i] =='\r' ) {
                  Serial.print("\r\n"); //insert linefeed
                else {
                  Serial.print(buf[i]); //printing on the screen
    }//if( Usb.getUsbTaskState() == USB_STATE_RUNNING..
Xbee PL2303 Arduino Terminal

Xbee PL2303 Arduino Terminal

X-CTU Speed Setting

X-CTU Speed Setting

11 comments to Building PL2303 USB to Serial converter from old data cable

  • I am using usb host shield with Arduino Mega 1280, executed board.qc.pde and the device passed in all the tests…
    Using the application Building PL2303 USB you the Serial one to convert from old dates wire, I only obtain to receive the serial data in the entrance from the PL2303 and to visualize in the serial one of the Arduino. When I transmit data of the Serial port of the Arduino for the PL2303 the serial data does not appear in the exit of the PL2303. I used a serial converter usb with chip-set PL2303HX and another one with PL2303H, the same problem occurred in the two converters.
    It has some story or solution for this problem?


    Henrique Santos

    • The easiest way to test is to make a loopback – connect Tx and Rx lines on PL2303, type something in the terminal and see if you’re getting same data back.

  • I made the test connecting the TX and RX of the PL2303 and really I am not obtaining to transmit in the serial one of the PL2303.
    I made the test in PC (Windows) and this ok!
    You have some suggestion?

    • I have tested this code with several PL2303-based devices and they all worked fine. I’ll be getting another one in a week or two, I’ll check it as well and if I find any issues, I’ll let you know. We can also trade devices – I’ll send you one featured in this article and you’ll give me one of yours – contact me off-list if interested.

  • Steve

    Can I use this same cable in the opposite direction? To interface a USB GPS to the serial port of Uno?

  • CircuitMenno

    Hi Oleg,

    Is it possible to send a request like AA 02 00 AD (tracked using a Serial Port Sniffer) in order to receive the proper data in the example of Xbee? Currently not receiving anything while PL is configured.

  • Well, I believe I have the same PCB board like yours but i must confess that the pads are not the same.
    Maybe that’s the Henrique’s problem!
    Mine has the Ground on the other side (where the cristal is). The ground on your PCB is my TXD and the fourth (from TxD) is RxD.
    Works perfect!

  • giulio

    hello…i have tested this library and it works with USBtoRS232…..but i have USBtoJACK….and it do not work….what should I need?

  • tony

    i have a usb to rs232 PL2303 and using it on sierra wireless modem. when im in hyper-terminal to test the modem, I type the letter “A” (for AT command)i would get: “aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”… none stop. it might be a loop or echo issues with the usb/rs232, am i right?

  • Papier

    I connected the TX and RX of the PL2303 but I didn’t have transmission in the serial of the PL2303.
    I made the test in PC (Windows) and this ok! Can you suggest somethings?

    Best Regards,
    Pasquale Pierro

  • Stanley Chan


    Thanks for the development USB Host shield.

    I have a project to use Arduino Mega with USB Host shield to send data to a LED display panel which has a USB for recieving data. This panel if connected to PC, a Prolific COM Port will be shown in PC. So it is using USB-to-serial to transport data. I also check it has a PL2303 chip inside, so I am pretty sure your PL2303 USB-to-Serial driver would work. Anyway, I choose your PL2303 GPRS terminal as a starting point. I know the display panel has a buadrate of only 1200, so I set the baudrate in SetLineCoding accordingly. When I run the program with USB host shield installed and panel connected, the message I got is

    0000: 09 02 27 00 01 01 00 80 32 09 04 00 00 03 FF 00
    0010: 00 00 07 05 81 03 0A 00 01 07 05 02 02 40 00 00
    0020: 07 05 83 02 40 00 00 07058103000A010705020200400007058302004000

    I suppose sending a data stream in my code to the the panel such a value will be display. I did that using Coolterm in PC with baudrate 1200, and it works. But in the Arduino case, it doesn’t. Can you help to give me some hints where the problem is, many thanks