Wxwidgets Serial Port Programming Java

Posted on  by
  1. Java Serial Port Example
  2. Serial Port Programming Java
  3. Serial Port Programming In C#
< Serial Programming

Serial Programming: Introduction and OSI Network Model-- RS-232 Wiring and Connections-- Typical RS232 Hardware Configuration-- 8250 UART-- DOS-- MAX232 Driver/Receiver Family-- TAPI Communications In Windows-- Linux and Unix-- Java-- Hayes-compatible Modems and AT Commands-- Universal Serial Bus (USB)-- Forming Data Packets-- Error Correction Methods-- Two Way Communication-- Packet Recovery Methods-- Serial Data Networks-- Practical Application Development-- IP Over Serial Connections

Remark: - Check if newer s/w is available. Close the Sirf Demo software.' This tool is for profs. - Do exactly as described above and don’t click or change anything. Atake usb serial driver download.

Programming and Interfacing the Serial/UART/RS-232 port of a Computer/PC in Windows and Linux Part-2 So here is the linux part of my tutorial on how to interface a serial port. Windows part is here. To say the truth the programming a s. WxWidgets resources examples and COM port. Using some resources, timers and.

  • 1Using Java for Serial Communication
    • 1.3Installation
      • 1.3.2Webstart
  • 2JavaComm API
    • 2.2Download & Installation
    • 2.4Simple Data Transfer
    • 2.5Event Driven Serial Communication
      • 2.5.3Writing of Data
        • 2.5.3.1Setting up a separate Thread for Writing
  • 3RxTx

Using Java for Serial Communication[edit]

Introduction[edit]

Because of Java's platform-independence, serial interfacing is difficult. Serial interfacing requires a standardized API with platform-specific implementations, which is difficult for Java.

Unfortunately, Sun didn't pay much attention to serial communication in Java. Sun has defined a serial communication API, called JavaComm, but an implementation of the API was not part of the Java standard edition. Sun provided a reference implementation for a few, but not all Java platforms. Particularly, at the end of 2005 Sun silently withdrew JavaComm support for Windows. Third party implementations for some of the omitted platforms are available. JavaComm hasn't seen much in the way of maintenance activities, only the bare minimum maintenance is performed by Sun, except that Sun apparently responded to pressure from buyers of their own Sun Ray thin clients and adapted JavaComm to this platform while dropping Windows support.

This situation, and the fact that Sun originally did not provide a JavaComm implementation for Linux (starting in 2006, they now do) led to the development of the free-software RxTx library. RxTx is available for a number of platforms, not only Linux. It can be used in conjunction with JavaComm (RxTx providing the hardware-specific drivers), or it can be used stand-alone. When used as a JavaComm driver the bridging between the JavaComm API and RxTx is done by JCL (JavaComm for Linux). JCL is part of the RxTx distribution.

Sun's negligence of JavaComm and JavaComm's particular programming model gained JavaComm the reputation of being unusable. RxTx - if not used as a JavaComm driver - provides a richer interface, but one which is not standardized. RxTx supports more platforms than the existing JavaComm implementations. Recently, RxTx has been adopted to provide the same interface as JavaComm, only that the package names don't match Sun's package names.

So, which of the libraries should one use in an application? If maximum portability (for some value of 'maximum') is desired, then JavaComm is a good choice. If there is no JavaComm implementation for a particular platform available, but an RxTx implementation is, then RxTx could be used as a driver on that platform for JavaComm. So, by using JavaComm one can support all platforms which are either directly supported by Sun's reference implementation or by RxTx with JCL. This way the application doesn't need to be changed, and can work against just one interface, the standardized JavaComm interface.

This module discusses both JavaComm and RxTx. It mainly focuses on demonstrating concepts, not ready-to-run code. Those who want to blindly copy code are referred to the sample code that comes with the packages. Those who want to know what they are doing might find some useful information in this module.

jSSC (Java Simple Serial Connector) should also be considered

There is also another library called jSerialComm that includes all its platform specific files in its jar, this makes it truly portable as there is no installation necessary.

Getting started[edit]

  • Learn the basics of serial communication and programming.
  • Have the documentation of the device you want to communicate with (e.g. the modem) ready.
  • Set up all hardware and a test environment
  • Use, for example, a terminal program to manually communicate with the device. This is to be sure the test environment is set up correctly and you have understood the commands and responses from the device.
  • Download the API implementation you want to use for your particular operating system
  • Read
    • the JavaComm and/or RxTx installation instruction (and follow it)
    • the API documentation
    • the example source code shipped

Installation[edit]

General Issues[edit]

Both JavaComm and RxTX show some installation quirks. It is highly recommended to follow the installation instructions word-for-word. If they say that a jar file or a shared library has to go into a particular directory, then this is meant seriously! If the instructions say that a particular file or device needs to have a specific ownership or access rights, this is also meant seriously. Many installation troubles simply come from not following the instructions precisely.

It should especially be noted that some versions of JavaComm come with two installation instructions. One for Java 1.2 and newer, one for Java 1.1. Using the wrong one will result in a non-working installation. On the other hand, some versions/builds/packages of RxTx come with incomplete instructions. In such a case the corresponding source code distribution of RxTx needs to be obtained, which should contain complete instructions.

Many linux distributions offer a RxTx package in their repositories (ArchLinux - 'java-rxtx', Debian/Ubuntu - 'librxtx-java'), these packages include only the platform specific parts of the library, but are generally ready to use.

It should be further noticed that it is also typical for Windows JDK installations to come with up to three VMs, and thus three extension directories.

  • One as part of the JDK,
  • one as part of the private JRE which comes with the JDK to run JDK tools, and
  • one as part of the public JRE which comes with the JDK to run applications

Some even claim to have a fourth JRE somewhere in the Windows directory hierarchy.

JavaComm should at least be installed as extension in the JDK and in all public JREs.

Webstart[edit]

JavaComm[edit]

A general problem, both for JavaComm and RxTx is, that they resist installation via Java WebStart:

JavaComm is notorious, because it requires a file called javax.comm.properties to be placed in the JDK lib directory, something which can't be done with Java WebStart. This is particularly sad, because the need for that file is the result of some unnecessary design/decision in JavaComm and could have easily been avoided by the JavaComm designers. Sun constantly refuses to correct this error, citing the mechanism is essential. Which is, they are lying through their teeth when it comes to JavaComm, particular, because Java for a long time has a service provider architecture exactly intended for such purposes.

The contents of the properties file is typically just one line, the name of the java class with the native driver, e.g.:

The following is a hack which allows to deploy JavaComm via Web Start ignoring that brain-dead properties file. It has serious drawbacks, and might fail with newer JavaComm releases - should Sun ever come around and make a new version.

First, turn off the security manager. Some doofus programmer at Sun decided that it would be cool to again and again check for the existence of the dreaded javax.comm.properties file, even after it has been loaded initially, for no other apparent reason than checking for the file.

Then, when initializing the JavaComm API, initialize the driver manually:

RxTx[edit]

RxTx on some platforms requires changing ownership and access rights of serial devices. This is also something which can't be done via WebStart.

At startup of your program you could ask the user to perform the necessary setup as super user.

Further, RxTx has a pattern matching algorithm for identifying 'valid' serial device names. This often breaks things when one wants to use non-standard devices, like USB-to-serial converters. This mechanism can be overridden by system properties. See the RxTx installation instruction for details.

jSerialComm[edit]

jSerialComm in contrast to both RxTx and JavaComm is ready to use on many operating Systems and Platforms (e.g. Windows x86/x86_64, Linux x86/x86_64, ARM, and even android - full list in the specific library jar) without any changes. However it still needs permissions to access the device (more information on the jSerialComm Homepage).

SerialPundit

SerialPundit is another feature rich library for accessing serial port in Java. It includes features like detecting when a USB-UART device like FTDI232 has been plugged into system , automatically identifies operating system and CPU architecture, does not require any installation, comprehensively documented, well tested and have a support/discussion group as well.

JavaComm API[edit]

Introduction[edit]

The official API for serial communication in Java is the JavaComm API. This API is not part of the standard Java 2 version. Instead, an implementation of the API has to be downloaded separately. Unfortunately, JavaComm has not received much attention from Sun, and hasn't been really maintained for a long time. From time to time Sun does trivial bug-fixes, but doesn't do the long overdue main overhaul.

This section explains the basic operation of the JavaComm API. The provided source code is kept simple to demonstrate important point. It needs to be enhanced when used in a real application.

The source code in this chapter is not the only available example code. The JavaComm download comes with several examples. These examples almost contain more information about using the API than the API documentation. Unfortunately, Sun does not provide any real tutorial or some introductory text. Therefore, it is worth studying the example code to understand the mechanisms of the API. Still, the API documentation should be studied, too. But the best way is to study the examples and play with them. Due to the lack of easy-to-use application and people's difficulty in understanding the APIs programming model, the API is often bad-mouthed. The API is better than its reputation, and functional. But no more.

The API uses a callback mechanism to inform the programmer about newly arriving data. It is also a good idea to study this mechanism instead of relying on polling the port. Unlike other callback interfaces in Java (e.g. in the GUI), this one only allows one listener listening to events. If multiple listeners require to listen to serial events, the one primary listener has to be implemented in a way that it dispatches the information to other secondary listeners.

Download & Installation[edit]

Download[edit]

Sun's JavaComm web page points to a download location. Under this location Sun currently (2007) provides JavaComm 3.0 implementations for Solaris/SPARC, Solaris/x86, and Linux x86. Downloading requires to have registered for a Sun Online Account. The download page provides a link to the registration page. The purpose of this registration is unclear. One can download JDKs and JREs without registration, but for the almost trivial JavaComm Sun cites legal and governmental restrictions on the distribution and exportation of software.

The Windows version of JavaComm is no longer officially available, and Sun has - against their own product end-of-live policy - not made it available in the Java products archive. However, the 2.0 Windows version (javacom 2.0) is still downloadable from here.

Installation[edit]

Follow the installation instructions that come with the download. Some versions of JavaComm 2.0 come with two installation instructions. The most obvious of the two instructions is unfortunately the wrong one, intended for ancient Java 1.1 environments. The information referring to the also ancient Java 1.2 (jdk1.2.html) is the right one.

Particularly Windows users are typically not aware that they have copies of the same VM installed in several locations (typically three to four). Some IDEs also like to come with own, private JRE/JDK installations, as do some Java applications. The installation needs to be repeated for every VM installation (JDKs and JREs) which should be used in conjunction with the development and execution of a serial application.

IDEs typically have IDE-specific ways of how a new library (classes and documentation) is made known to the IDE. Often a library like JavaComm not only needs to be made known to the IDE as such, but also to each project that is supposed to use the library. Read the IDE's documentation. It should be noted that the old JavaComm 2.0 version comes with JavaDoc API documentation that is structured in the historic Java 1.0 JavaDoc layout. Some modern IDEs are no longer aware of this structure and can't integrate the JavaComm 2.0 documentation into their help system. In such a case an external browser is needed to read the documentation (a recommended activity ..).

Once the software is installed it is recommended to examine the samples and JavaDoc directories. It makes sense to build and run one of the sample applications to verify that the installation is correct. The sample applications typically need some minor adaptations in order to run on a particular platform (e.g. changes to the hard-coded com port identifiers). It is a good idea to have some serial hardware, like cabling, a null modem, a breakout box, a real modem, PABX and others available when trying out a sample application. Serial_Programming:RS-232 Connections and Serial_Programming:Modems and AT Commands provide some information on how to set up the hardware part of a serial application development environment.

Finding the desired serial Port[edit]

The first three things to do when programming serial lines with JavaComm are typically

Wxwidgets Serial Port Programming Java
  1. to enumerate all serial ports (port identifiers) available to JavaComm,
  2. to select the desired port identifier from the available ones, and
  3. to acquire the port via the port identifier.

Enumerating and selecting the desired port identifier is typically done in one loop:

Note:
JavaComm itself obtains the default list of available serial port identifiers from its platform-specific driver. The list is not really configurable via JavaComm. The method CommPortIdentifier.addPortName() is misleading, since driver classes are platform specific and their implementations are not part of the public API. Depending on the driver, the list of ports might be configurable / expendable in the driver. So if a particular port is not found in JavaComm, sometimes some fiddling with the driver can help.

Once a port identifier has been found, it can be used to acquire the desired port:

Initialize a Serial Port[edit]

The initialization of a serial port is straight forward. Either individually set the communication preferences (baud rate, data bits, stop bits, parity) or set them all at once using the setSerialPortParams(..) convenience method.

As part of the initialization process the Input and Output streams for communication will be configured in the example.

Simple Data Transfer[edit]

Simple Writing of Data[edit]

Writing to a serial port is as simple as basic Java IO. However there are a couple of caveats to look out for if you are using the AT Hayes protocol:

  1. Don't use println (or other methods that automatically append 'n') on the OutputStream. The AT Hayes protocol for modems expects a 'rn' as the delimiter (regardless of underlying operating system).
  2. After writing to the OutputStream, the InputStream buffer will contain a repeat of the command that was sent to it (with line feed), if the modem is set to echoing the command line, and another line feed (the answer to the 'AT' command). So as part of the write operation make sure to clean the InputStream of this information (which can actually be used for error detection).
  3. When using a Reader/Writer (not a really good idea), at least set the character encoding to US-ASCII instead of using the platform's default encoding, which might or might not work.
  4. Since the main operation when using a modem is to transfer data unaltered, the communication with the modem should be handled via InputStream/OutputStream, and not a Reader/Writer.

To do:

  • Explain how to mix binary and character I/O over the same stream
  • Fix the example to use streams

Simple Reading of Data (Polling)[edit]

If you correctly carried out the write operation (see above) then the read operation is as simple as one command:

Problems with the simple Reading / Writing[edit]

The simple way of reading and/or writing from/to a serial port as demonstrated in the previous sections has serious drawbacks. Both activities are done with blocking I/O. That means, when there is

  • no data available for reading, or
  • the output buffer for writing is full (the device does not accept (any more) data),

the read or write method (os.print() or is.readLine() in the previous example) do not return, and the application comes to a halt. More precisely, the thread from which the read or write is done gets blocked. If that thread is the main application thread, the application freezes until the blocking condition is resolved (data becomes available for reading or device accepts data again).

Unless the application is a very primitive one, freezing of the application is not acceptable. For example, as a minimum some user interaction to cancel the communication should still be possible. What is needed is non-blocking I/O or asynchronous I/O. However, JavaComm is based on Java's standard blocking I/O system (InputStream, OutputStream), but with a twist, as shown later.

The mentioned 'twist' is that JavaComm provides some limited support for asynchronous I/O via an event notification mechanism. But the general solution in Java to achieve non-blocking I/O on top of the blocking I/O system is to use threads. Indeed, this is a viable solution for serial writing, and it is strongly recommended to use a separate thread to write to the serial port - even if the event notification mechanism is used, as explained later.

Reading could also be handled in a separate thread. However, this is not strictly necessary if the JavaComm event notification mechanism is used. So summarize:

ActivityArchitecture
readinguse event notification and/or separate thread
writingalways use separate thread, optionally use event notification

The following sections provide some details.

Event Driven Serial Communication[edit]

Introduction[edit]

The JavaComm API provides an event notification mechanism to overcome the problems with blocking I/O. However, in the typical Sun manner this mechanism is not without problems.

In principle an application can register event listeners with a particular SerialPort to be kept informed about important events happening on that port. The two most interesting event types for reading and writing data are

  • javax.comm.SerialPortEvent.DATA_AVAILABLE and
  • javax.comm.SerialPortEvent.OUTPUT_BUFFER_EMPTY.

But there are also two problems:

  1. Only one single event listener per SerialPort can be registered. This forces the programmer to write 'monster' listeners, discriminating according to the event type.
  2. OUTPUT_BUFFER_EMPTY is an optional event type. Well hidden in the documentation Sun states that not all JavaComm implementations support generating events of this type.

Before going into details, the next section will present the principal way of implementing and registering a serial event handler. Remember, there can only be one handler at all, and it will have to handle all possible events.

Setting up a serial Event Handler[edit]

Once the listener is implemented, it can be used to listen to particular serial port events. To do so, an instance of the listener needs to be added to the serial port. Further, the reception of each event type needs to be requested individually.

Writing of Data[edit]

To do:

Setting up a separate Thread for Writing[edit]

Using a separate thread for writing has one purpose: Avoiding that the whole application blocks in case the serial port is notready for writing.

A simple, thread-safe Ring Buffer Implementation[edit]

Using a separate thread for writing, separate from some main application thread, implies that there is some way to hand off the data which needs to be written from the application thread to the writing thread. A shared, synchronized data buffer, for example a byte[] should do. Further, there needs to be a way for the main application to determine if it can write to the data buffer, or if the data buffer is currently full. In case the data buffer is full it could indicate that the serial port is not ready, and output data has queued up. The main application will have to poll the availability of new space in the shared data buffer. However, between the polling the main application can do other things, for example updating a GUI, providing a command prompt with the ability to abort the sending, etc.

At first glance a PipedInputStream/PipedOutputStream pair seems like a good idea for this kind of communication. But Sun wouldn't be Sun if the a piped stream would actually be useful. PipedInputStream blocks if the corresponding PipedOutputStream is not cleared fast enough. So the application thread would block. Exactly what one wants to avoid by using the separate thread. A java.nio.Pipe suffers from the same problem. Its blocking behavior is platform dependent. And adapting the classic I/O used by JavaComm to NIO is anyhow not a nice task.

In this article a very simple synchronized ring buffer is used to hand over the data from one thread to another. In a real world application it is likely that the implementation should be more sophisticated. E.g. in a real world implementation it would make sense to implement OutputStream and InputStream views on the buffer.

A ring buffer as such is nothing special, and has no special properties regarding threading. It is just that this simple data structure is used here to provide data buffering. The implementation is done so that access to this data structure has been made thread safe.

With this ring buffer one can now hand over data from one thread to another in a controlled way. Any other thread-safe, non-blocking mechanism would also do. The key point here is that the write does not block when the buffer is full and also does not block when there is nothing to read.

Using the Buffer together with Serial Events[edit]
Usage of OUTPUT_BUFFER_EMPTY Event in Writing[edit]

Referring to the skeleton event handler presented in the section Setting up a serial Event Handler, one can now use a shared ring buffer from section A simple, thread-safe Ring Buffer Implementation to support the OUTPUT_BUFFER_EMPTY event. The event is not supported by all JavaComm implementations, therefore the code might never be called. However, in case the event is available it is one building block for ensuring best data throughput, because the serial interface is not left idle for too long.

The skeleton event listener proposed a method outputBufferEmpty(), which could be implemented as it follows.

Reading of Data[edit]

The following example assumes that the data's destination is some file. Whenever data becomes available it is fetched from the serial port and written to the file. This is an extremely simplified view, because in reality one would need to check the data for an end-of-file indication to, for example, return to the modem command mode.

Handling multiple Ports in one Application[edit]

Modem Control[edit]

JavaComm is strictly concerned with the handling of a serial interface and the transmission of data over that interface. It does not know, or provide, any support for higher-layer protocols, e.g. for Hayes modem commands typically used to control consumer-grade modems. This is simply not the job of JavaComm, and not a bug.

Java Serial Port Example

Like with any other particular serial device, if the control of a modem is desired via JavaComm the necessary code has to be written on top of JavaComm. The page 'Hayes-compatible Modems and AT Commands' provides the necessary basic generic information to deal with Hayes modems.

Some operating systems, e.g. Windows or certain Linux distributions provide a more or less standardized way how modem control commands for a particular modem type or brand are configured for the operating system. Windows modem 'drivers', for example, are typically just registry entries, describing a particular modem (the actual driver is a generic serial modem driver). JavaComm as such has no provisions to access such operating-system specific data. Therefor, one either has to provide a separate Java-only facility to allow a user to configure an application for the usage of a particular modem, or some platform-specific (native) code needs to be added.

RxTx[edit]

Overview and Versions[edit]

Due to the fact that Sun didn't provide a reference implementation of the JavaComm API for Linux, people developed RxTx for Java and Linux [1]. RxTx was then further ported to other platforms. The latest version of RxTx is known to work on 100+ platforms, including Linux, Windows, Mac OS, Solaris and other operating systems.

RxTx can be used independent of the JavaComm API, or can be used as a so called provider for the JavaComm API. In order to do the latter, a wrapper called JCL is also needed [2]. JCL and RxTx are usually packaged together with Linux/Java distributions, or JCL is completely integrated into the code. So, before trying to get them separately, it is worth having a look at the Linux distribution CD.

There seems to be a trend to abandon the JavaComm API, and using RxTx directly instead of via the JCL wrapper, due to Sun's limited support and improper documentation for the JavaComm API. However, RxTx's documentation is extremely sparse. Particularly, the RxTX people like to make a mess of their versions and package contents (e.g. with or without integrated JCL). Starting with RxTx version 1.5 RxTx contains replacement classes for the public JavaComm classes. For legal reasons they are not in the java.comm package, but in the gnu.io package. However, the two currently available RxTx versions are packaged differently:

Microsoft equation editor free download. Best Video Software for the Mac How To Run MacOS High Sierra or Another OS on Your Mac Best Graphic Design. Math Equation Editor for apple mac - Free download mac math equation editor shareware, freeware, demo. Free Download Daum Equation Editor for Mac 1.1.2 - A practical and well-designed equation editor that enables you to quickly and easily create and. Jul 14, 2012  ‎Read reviews, compare customer ratings, see screenshots, and learn more about Daum Equation Editor. Download Daum Equation Editor for macOS 10.6 or later and enjoy it on your Mac. Pages equation editor.

RxTx 2.0
RxTx version supposed to be used as a JavaComm provider. This one is supposed to have its roots in RxRx 1.4, which is the RxTx version before the gnu.io package was added.
RxTx 2.1
RxTx version with a full gnu.io package replacement for java.comm. This version is supposed to have its roots in RxTx 1.5, where gnu.io support started.

So, if one wants to program against the original JavaComm API one needs

  1. Sun's generic JavaComm version. As of this writing this is in fact the Unix package (which contains support for various Unix versions like Linux or Solaris). Even when used on Windows, the Unix package is needed to provide the generic java.comm implementations. Only the part implemented in Java is used, while the Unix native libraries are just ignored.
  2. RxTx 2.0 in order to have a different provider below the generic generic JavaComm version than the ones coming with the JavaComm package

However, if one just wants to program against the gnu.io replacement package, then

  • only RxTx 2.1 is needed.

Converting a JavaComm Application to RxTx[edit]

So, if you belong to the large group of people who have been let down by Sun when they dropped Windows support for JavaComm, you are in need to convert a JavaComm application to RxTx. As you can see from the above, there are two ways to do it. Both assume that you manage to install a version of RxTx first. Then the options are either

  1. Using RxTx 2.0 as a JavaComm provider
  2. Porting the application to RxTx 2.1

The first option has already been explained. The second option is surprisingly simple. All one has to do to port some application from using JavaComm to using RxTx 2.1 is to replace all references to java.comm in the application source code with references to gnu.io. If the original JavaComm application was properly written there is nothing more to do.

RxTx 2.1 even provides the tool contrib/ChangePackage.sh to perform the global replacement on a source tree under Unix. On other platforms such a global replacement is easy to do with IDEs supporting a decent set of refactoring features.

See also[edit]

  • jSerialComm Homepage on github - with information on how to use it - Javadoc
  • RxTx Home Page (Files are accessible with FTP only (May 2017))
  • jRxTx on github - a new Wrapper to RxTx with a 'new improved API compared to that of RXTX'
  • Ben Resner has a free download of his SimpleSerial package and a newer version without the C++ code
  • gurux.serial.java is easy to use Open Source serial port library for Windows and Linux]

Serial Programming: Introduction and OSI Network Model-- RS-232 Wiring and Connections-- Typical RS232 Hardware Configuration-- 8250 UART-- DOS-- MAX232 Driver/Receiver Family-- TAPI Communications In Windows-- Linux and Unix-- Java-- Hayes-compatible Modems and AT Commands-- Universal Serial Bus (USB)-- Forming Data Packets-- Error Correction Methods-- Two Way Communication-- Packet Recovery Methods-- Serial Data Networks-- Practical Application Development-- IP Over Serial Connections

Retrieved from 'https://en.wikibooks.org/w/index.php?title=Serial_Programming/Serial_Java&oldid=3563757'
4 Sep 2014CPOL
wxWidgets resources examples and COM port communication.

Introduction

In this article I will explain how to put some basic resources in a window to interact with the user, like buttons, text fields and combo boxes.

As a bonus I will add a simple COM port library using a very basic one line terminal application as example.

I will explaine how to use wxWidget evente-based timers to automatize some actions like read the serial imput buffer and display the information in the text field.

The idea is to go step by step explaining the code for any object separately, starting with the layout of the window and adding the diferent functions and necessary code progressively.

Background

The examples of this article, and the code asociated, was maked with Code::Blocks using wxWIdgets 3.0.1. You can see how to download and compile it in this article:

The serial communication is implemented with a simple library you can find in this article with a brief description of how to use it, I explain how to use it in this article also

but instead of the list ports library used there I will use here another way to enumerate the ports.

Don't worry, I will explain anyn aspect in detail.

The code

The better way to start is for the beginning, so open the Code::Blocks ide and create a new wxWidgets project. In the first article referenced in the Background section you can find a guide to create a wxProject in C::B. Follow that steps to create the new project.

The first screen you see when create a new wxWidgets project is this:

This is the resource panel. Here we can drag and drop controls and resources we want to build the screen.

The Layout

First of all we will create the layout. So we will add some objects to the screen. But first we have to some things to spaciate and organize the layout. First add a wxBoxSizer. Sizers make the job of organize the elements in the screen for us. Then add a wxPanel inside the BoxSizer. Now add a wxGridSizer inside the panel. For more references about doing this you can see the article referenced before.

The wxGridSizer let us add elements in a matrix instead in a line as in the BoxSizer. If you select the GridSizer from the left resources tree you will see its properties in the properties menu below the tree. In the GridSizer properties you can set the row and column number.

The example consists in a list of COM ports available where you can choose wich one to connect, a CONNECT button, a text field to write the message you want to send with the SEND button and a text field to show the received messages. For simplicity I made the received field in only one line, buut is easy to make it multiline setting the correct propertie in the textfield properties.

Once we have this set of sizers in the screen we will proceed to build the screen. The goal screen is this:

As you can see in the GridSizer's properties I especified 3 rows and 2 columns.

Now we have to add the objects. That is doing by clicking on the object in the object bar and then clicking on the diagram. First click on the wxComboBox icon in the Standar bar and then click in the little square that we have as our screen. Now we have the future COM ports list. Clicking on it and in the properties list in the left we can see some attributes we can change. The principal attribute to change is the object name so we can refer to it and make the code more maintenable.

As you can see in the screenshot, I changed the var name to comSel and the Identifier to ID_COMSEL.

Then add the button on the right of the comboBox, change it's Var Name to conBut and the label to Connect

Now add a wxTextCtrl. I changed it's Var name to mesBox, the Label to Message and the Identifier to ID_MESBOX.

Add another wxButton. Label: Send, Var name: sendBut and Identifier: ID_SENDBUT.

Now add a wxStaticText, Label Received, Var name: recText and Identifier: ID_RECTEXT

Finally add a wxTextCtrl. Label: nothing because here we will display the incomming message, Var name: recBox and Identifier: ID_RECBOX. We will define it as read only setting this propertie in the style option in the propertie editor:

Remember that later when we define the functions to interact with the elements in the screen, that functions will be referenced to the var name of the objects.

Now you can build the project to see if it is working. If every thing is ok we have something like this:

But of course this doesn't have any functionality. So lets add some code to make it work.

Serial port enumerator

The available serial port enumeration is making through the Find_Comm function declared and implemented in portEnum.h and portsEnum.cpp respectively. See the code:

I remarked the two important variables. ports, the estring vector that contains the name of the ports availables and portscant the number of available ports.

To use it in our code first I declare two variables in the wxlConsoleFrame class declaration in wxlConsoleMain.h file, comports and port_nr. I declared the variables there to have them available in the functions of the frame object.

Very important: never modify the code between //(* and //*). This code is automatically generated and modified by wxWidgets and the IDE.

Then in wxlConsoleMain.cpp inside the constructor of wxlConsoleFrame, wxlConsoleFrame::wxlConsoleFrame(wxWindow* parent,wxWindowID id), we have to call to the port enumerator function so when the frame is created we already have the ports listed:

Find_comm function ask for an string pointer as parameter and to give the ports in and return the port cuantity as an int.

Serial Port Programming Java

The most important thing here is the first interaction with a GUI object inside the for cicle. There we fill the combo box comSel with the available ports through the wxComboBox member function Append(string). Every call to Append adds a new string option to the list of the combo box.

We can build the project and verify if this is working. We have a list of available ports, now we have to choose one and connect to it.

Selecting and opening the serial port

We want to the user can select a port of the list and connect to it when pressing the Connect bbutton. Whe the user selects an option of the combo box an event is shooted, but we wont use it in this case because the will bbe maked when the connect button is pressed. So we have to define waht will occur when the connect button is pressed.

Macking double click on the connect button in the resource view (wxlConsoleFrame.wxs) we access directly to the wxlConsoleFrame::OnconButClick event function in wxlConsoleMain.cpp (maybe you have to scroll down to find it). Inside this function we can define what actions occurr when the button is pressed. This actions will be take the selected string (the selected port) from the combo box and open the port. Look that when you double-click on the button to generate the event automatically generates the function declaration in the wxlConsoleFrame class in wxlConsoleMain.h file.

First get the selected string with the combo box member function GetStringSelected(). This return a wxString containing the text of the selection in the combobox. Combo boxes have another member function wich returns the ordering number of the selection.

Then check if the selection is not void and get the port number. The strings in the combo box are in the form 'COMn' where 'n' is the port number, thats the razon to take the fourth element of the string, cast it to int and subtract 48 ('0' in ascii).

The condition post_nr0 is to check if no ports were opened previously. I use it in other parts of the code for the same utility.

returns 0 if the port was succefuly opened. baudrate is declared as a member of wxlConsoleFrame class in wxlConsoleMain.h file and initialized to 9600 in the constructor.

If the port could be opened store the port number and show it in the instead receive message box to informate that it was opened using the TexCtrl member function setValue(string). You can append a message like 'port n succefuly opened' using AppendText(string)instead:

or using formatted print:

Sending a message to the selected port

Once opened the port we want to communnicate with it. We have to get the text writed to the sending message text field and write it to the port when the send button is pressed. The action is maked when the button is pressed so we have to write the code in the send button event function.

Double clicking on the send button in the GUI view (wxlConsoleFrame.wxs) take us to wxlConsoleFrame::OnsendButClick on wxlConsoleMain.cpp (again maybe you have to scroll down to find it). Here we will add the code to get the text in the text field and write it to the port.

First we get the text writed by the user in the mesBox TextCtrl using the member function GetValue() and asign it to an auxiliar wxString object.

Because the RS232 librarie is writen in C we have to give it a classic C style string (a char*) as parameter so we have first to convert the wxString to a standard C++ string and then pass to RS232_SendBuf the char* casted c_str() value.

Note that before sending the message the program check if the port is opened.

Receiving and showing the incomming message

In the other side of the communication we want to show the received message. We can do it with a button, or in the same event of the send button push. But maybe we connect to the PC a device wich emmit messages by its own and we want to show the messages automaticale when they arrive. As the RS232 library is not event driven we have to automatize the message polling. To do it we will use timers, so as a bonus of this tutorial we'll see how to implement and use the wxWidgets event driven timers.

Creating the Timer

Serial Port Programming In C#

We will use the wxTimer class. This brings us timers that we can define the interval between the timer send an event. And we will use that event to make an action. But go step by step.

First we have to create the timer object. So add a timer object to our Frame class. In wlConsoleMain.h to the wxlConsoleFrame class declaration:

And we have to declare the event function as a member of the Frame class to.

Now we have to define the timer object defining his owner and event function. We will do this in the constructor of the Frame class in wlConsoleMain.cpp.

And of course start the timer. interval is defined in this file as a global variable and is in milliseconds. The parameters of the wxTimer constructor is the owner object of the timer (wxlConsoleFrame in this case) and the event function.

The last thing we have to do to use the timer is asociate the function with the event. We do this in the same file, wlConsoleMain.cpp, in the EVENT_TABLE. There we have to add the event and associate to it the function and an ID for it:

First we define the IDs for our events, only one in the example, and then define the event in the event table. We associate the event EVT_TIMER with the ID Rec_Timer and the function wxlConsoleFrame::OnRecTimer.

Now we have the timer sending and event every 200 milliseconds (or the value you initialize the timer with). Just do something with this ticking.

Using the timer event to show the incoming messages

To make something in the timer event we just have to write some code inside the timer event function. We want to poll the COM port and show the message if any.

So in the wlConsoleMain.cpp we add the functionality:

Here we first create a char* buffer to store the message. As I said before, the RS232 library works with char* C style strings. With RS232_PollComport we check if there is any message in the serial buffer and read it to the buffer if any. This function returns the number of bytes readed.

Then sohw the readed message in the recBox textCtrl. Setvalue function changes the actual text in the window to the text passed as parameter. If you want to let the past texts in the text box you can use AppendText and if you defined the text box as multiline you can append a carriage return to show every new message in a new line.

Now we have all the functionality implemented. Only left to let the things clean.

Cleaning things on quiting the application

After leave the program we have to stop the timer and close the port. So in the OnQuit event we add some code:

This event is throwed when the window is closed but after closing the application.

Here is a screenshot of the application runing, cnnected to an Arduino board acting as an echoer.

Points of Interest

In this article I tried to show how to use some wxWidgets resources, the basic ones, and add some extra useful content with the RS232 library and the wxTimer using.

Another very important thing are the functions to get and set values to the GUI resources: GetValue and SetValue. This functions let us interact easily with the resources we put in the screen.