Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I emulate a COM port, write data to it and read data from it?

I'm trying to test my code that reads from a USB port (COM25 when the device is connected) that is created when a device is connected to my computer and to a boat. I cannot power the USB device when not on the boat so testing is difficult. Can someone let me know how to simulate a COM port and write data to it so my test program is able to connect to that simulated COM port and read that data?

I'm reading this from a Java program but the simulation doesn't need to be in Java or any specific language. Just a program that will simulate the COM port and allow me to connect to it. I downloaded a COM port emulator from AGG Software and it appears that it's writing to what I deem COM25 but I'm not able to connect to it from my Java test.

like image 392
homebrew2k9 Avatar asked Jun 29 '09 17:06

homebrew2k9


People also ask

How do I view COM port data?

In Serial Port Reader go to the “Main menu”, choose “Session -> New session”. Alternately, you can click on the “New” icon on the main toolbar or press “Ctrl + N”. This invokes the “New monitoring session” screen. Terminal view – all received data is displayed in ASCII characters on a text console.

How do I create a virtual serial port?

Download Virtual Serial Port Driver on your Windows machine. Install the application on your system and launch it. Choose “Pair” in the application's main window. Click the “Add a new pair” button to create a pair of virtual serial ports.

How does a virtual COM port work?

A USB Virtual COM Port allows you to use a USB Interface to talk to serial devices. This essentially gives users a simple pathway to communicating to peripherals using software development tools that support serial communications, a relatively common standard is most programming languages.

What is virtual serial port emulator?

Virtual Serial Port Emulator allows you to create an unlimited number of virtual COM ports. The software emulates serial port functionality connected by virtual null modem cable in such a way that the system does not see the difference between virtual and real hardware ports.


4 Answers

Thanks to all the answers so far! Here's what I ended up doing as a result of recommendations from someone at work.

  1. Downloaded the COM Port Data Emulator (CPDE) from AGG Software
  2. Downloaded the Virtual Serial Port Driver (VSPD) from Eltima Software

(I just randomly picked a free data emulator and virtual serial port package. There are plenty of alternatives out there)

  1. Using VSPD, created virtual serial ports 24 and 25 and connected them via a virtual null modem cable. This effectively creates a write port at 24 and a read port at 25.

  2. Ran the CPDE, connected to 24 and started writing my test data.

  3. Ran my test program, connected to 25 and was able to read the test data from it

like image 130
homebrew2k9 Avatar answered Nov 11 '22 19:11

homebrew2k9


Where I work, we solved a similar issue by having our emulator not spoof a COM port at all. Here's how you can do it:

  • Define an interface for talking with your COM port, something like IUsbCommService
  • Implement your real COM-communcation service, using the standard Java Comm API
  • For your emulator, simply kick of a thread that spits out the same sort of data you can expect from your USB device at regular intervals.
  • Use your IOC framework of choice (e.g., Spring) to wire up either the emulator or the real service.
  • As long as you hide your implementation logic appropriately, and as long as you code to your interface, your service-consumer code won't care whether it's talking to the real USB device or to the emulator.

For example:

import yourpackage.InaccessibleDeviceException;
import yourpackage.NoDataAvailableException;

public interface IUsbProviderService {

    public void initDevice() throws InaccessibleDeviceException;

    public UsbData getUsbData() 
        throws InaccessibleDeviceException, NoDataAvailableException;
}

// The real service
import javax.comm.SerialPort; //....and the rest of the java comm API 

public class UsbService implements IUsbProviderService {
.
.
.
}

// The emulator
public class UsbServiceEmulator implements IUsbProviderService {
    private Thread listenerThread;
    private static final Long WAITTIMEMS = 10L;
    private String usbData;

    public UsbServiceEmulator(long maxWaitTime) throws InaccessibleDeviceException{
        initialize();
        boolean success = false;
        long slept = 0;

        while (!success && slept < maxWaitTime) {
            Thread.sleep(WAITTIMEMS);
            slept += WAITTIMEMS;

        }
    }

    private void initialize() throws InaccessibleDeviceException{
        listenerThread = new Thread();
        listenerThread.start();
     }

     private class UsbRunner implements Runnable {
        private String[] lines = {"Data line 1", "Data line 2", "Data line 3"};
        public void run() {
            int line = 0;
            while(true) {

                serialEvent(lines[line]);

                if(line == 3) {
                    line = 0;
                } else {
                    line++;
                }

                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    //handle the error
                }
            }

        private void serialEvent(String line) {
            if(/*you have detected you have enough data */) {
                synchronized(this) {
                    usbData = parser.getUsbData();
                }
            } 


     }
}

Hope this helps!

like image 35
rtperson Avatar answered Nov 11 '22 19:11

rtperson


The general answer for this kind of problem is to wrap the code that talks to the COM port in a class that implements an interface. If you do this as a Facade (pattern) then you can also make the COM methods you call sensible from your end.

The interface can then be mocked or faked for the test. (There is a great article on test objects, but I haven't been able to find it yet.) One advantage here is that you can create a fake version that throws exceptions or otherwise does things that are possible for the port to do but hard to get it to do in practice.

like image 32
Kathy Van Stone Avatar answered Nov 11 '22 19:11

Kathy Van Stone


There are plenty of relevant answers in this section. But as for me, I personally use Virtual Serial Port Driver, which works perfect for me. But I must admit that there are plenty alternatives when it comes to creating virtual ports: freevirtualserialports.com; comOcom to name a few. But I haven't got a chance to use them, so my recommendation for solving this problem is Virtual Serial Port Driver.

like image 20
F.McGregor Avatar answered Nov 11 '22 21:11

F.McGregor