Simulated Serial Port?

Greetings -

I am putting together an app that provides a GUI that accesses an instrument that I make. The connection is via a virtual USB serial port.

Now, I would like to add a “demo” or “simulated” mode so that potential users can try it without connecting to a real instrument (that they may not have because they are only evaluating its purchase). To make that programmatically simple, it would be really nice to be able to create a “fake” serial object in which write could be directed to a buffer in the simulator and in which the simulator could load the serial buffer in the fake object and trigger a DataAvailable event. Or, something else that looks like a real serial object but isn’t.

Could someone suggest how to do this, or is the idea “dead on arrival”?

Many Thanks
Jim Wagner
Oregon Research Electronics

I think the easiest way is a Class Interface that can be satisfied be either a Serial object or a SimulatedSerial object that you will create.

The “right” way is to make a class interface but if you want a quick solution, you can add a global variable and some IF statements in the connect, send and receive methods.

pseudocode:

If App.IsDemo = True
 MsgBox "Data sent"
 Timer.CallLater FakeDataReceivedMethod
Else
 'Send real data to the real device
End If

Or if you want the user to get a full hands on experience, you can make a Hardware emulator, that is what i did for a proyect last year. Just an arduino nano on a fancy box responding to the serial messages. That way the user can view the port changes, selecting the right port, etc, etc.

Have never used a class interface. Time to learn, I guess. I have no idea what a class interface even does but maybe the tutorial says something.

As an aside, a hardware simulator won’t work for this. Imagine a potential customer finding l my web site, and wondering whether or not it will really work for their application. Even downloading software is a barrier (Web App?) So, trying to make something that lowers this barrier. Saleae Logic Analyzers does this sort of thing.

Thanks, both of you!
Jim

A Class Interface is a contract of sorts that can be fulfilled by any class that can supply the contract’s required functions. This lets one class refer to an object who implements the Class Interface without having to know what actual class it is.

For example: class FruitBowl is responsible for building a fruit salad. You have a class Orange that has a method GetSlice() that returns an instance of Slice. FruitBowl calls the instance’s GetSlice() method and stores the result.

That’s great if your salad consists solely of oranges. But what about other fruit - or even things that aren’t fruit? That’s where the Class Interface comes in handy.

Your Class Interface contains a single method, lifted directly from your Orange class: GetSlice() as Slice. Class Interfaces only define the contract, so they don’t contain any code; it’s the responsibility of the class that implements the interface to do the actual work. We’ll call the interface SliceProvider.

Your Orange class contains a method with the exact same signature as the SliceProvider interface and that actually returns a result. It also declares to the compiler that it implements the interface so the complier can do proper type checking.

Your FruitBowl class should now be altered to accept class instances that implement the SliceProvider interface (instead of just Oranges). It then calls the methods specified in the class interface, which are handled by the class instance itself.

Now, wherever you want a different ingredient in your salad, you create a new class (say, Apple), supply it with the proper methods to implement the SliceProvider class, tell the complier that it does this, and you’re ready to go. FruitBowl doesn’t need to know about the Apple class, all it cares about is that it is working with instances that implement the SliceProvider interface.

Class Interfaces are a great example of polymorphism, where an object takes on different behaviors depending on context. Classes may implement multiple class interfaces - in our example, the Orange and Apple classes might also implement the ConvertToJuice class interface, and the Orange might also implement the EmitZest interface. Once you get your head around them, you’ll start seeing uses for class interfaces everywhere!

Thanks, Eric -

I have been reading the UG section on interfaces - both really hard to find and hard to comprehend. Appreciate your little example. That does help.

Best Wishes
Jim

I’ve written virtual instruments and instrument simulators before using the Xojo TCPSocket bound to the loopback interface. The TCPSocket has a DataAvailable event and provided the data processing is suitably abstracted it’s not too difficult to refactor from a Serial object or implement a user selectable transport.

With respect to Xojo interfaces they are equivalent to a C++ pure virtual function. Essentially an Interface provides a method for the compiler to resolve type equivalency.

For instance. Let’s say my virtual instrument class has a VI.GetLine(connection as SerialConnection) method that calls connection.Lookahead to return whole lines terminated by &h10.

When I come to add a TCP transport I can’t pass a TCPSocket as the connection parameter as it is not in the SerialConnection class hierarchy. I could override VI.GetLine(connection as TCPSocket) but the code would be pretty much identical to VI.GetLine(connection as SerialConnection). A better way would be to define an interface, say ViConnectionIF, containing the virtual method LookAhead. Add the ViConnectionIF interface to your SerialConnection and TCPSocket subclasses, and refactor VI.GetLine(connection as ViConnectionIF). Both subclasses (already) implement a LookAhead method and so the interface merely defines the equivalency for the benefit of the compiler.

Later I decide I want to replay my virtual instrument from a capture file opened as a TextInputStream. The TextInputStream class does not have a LookAhead method. However were I to subclass TextInputStream, add the ViConnectionIF interface, and implement a LookAhead method, my TextInputStream subclass can be passed as the connection parameter to VI.GetLine(connection as ViConnectionIF).