Click here to Skip to main content
12,956,197 members (105,712 online)
Click here to Skip to main content
Add your own
alternative version


48 bookmarked
Posted 29 Nov 2007

RS232 Modem Wrapper

, 29 Nov 2007 GPL3
Rate this:
Please Sign up or sign in to vote.
An article about creating a class which wraps the serial port and modem communication logic.

modem access form


After a bit of search on, I still could not find any article on wrapping the SerialPort class and modem functionality. So, I decided to write a base class which wraps RS232 communications with a modem. Also, I've written two subclasses for demonstration purposes - to simulate different behaviors of different modem models. In general, I think this article should be useful for somebody who is trying to implement classes which hold communication logic with any RS232 device.


I have used some general AT modem commands in this sample. A good compilation of the general AT commands is available in this site. Also, some knowledge about thread-safe calls is required, because the SerialPort class operates in a different thread than the GUI.

Using the code

There are three classes implemented here. Below is the UML class diagram, drawn with a freeware tool bouml.

The basic class for communication with the modem is modem. The other two classes, ModemModel1 and ModemModel2, are inherited from the base class for demonstrating the idea that different types of modems can support different command sets and/or have different implementations of the same AT command (in theory). For example, a GSM modem can receive and send SMS; non-GSM compatible modems can't do this. Because I use only one modem, I just simulated different modems by implementing different modem behavior in subclasses by overriding the base class methods. Let's assume that the property DefaultBoudrate and the methods InitializeModem(), GetManufacturer(), and GetProductId() behave differently for different modem models. For this reason, they should be overridden in the sublases of modem. Like this:

public class ModemModel1 : Modem
    #region constructors

    public ModemModel1() : base() { }
    public ModemModel1(SerialPort prt, SetCallback c) : base(prt,c) { }
    public ModemModel1(SerialPort prt, string prtnum, SetCallback c) :
                                               base(prt, prtnum, c) { }


    #region overriden properties

    // Will be other DefaultBoudrate than in base class

    public override int DefaultBoudrate
        get {return 19200;}


    #region overriden methods

    // Other modem initialization than in base class

    protected override void InitializeModem()
    // Other command for geting manufacturer. Actually command is the

    // same - I4, but for simulating other behavior, just added additional

    // command I1.

    public override void GetManufacturer()
    // Also overriden command for getting modem product Id.

    // Added aditional command I3.

    public override void GetProductId()


One interesting note. I wanted the modem to be initialized in the object construction phase. That is, in the modem class constructor. And when the modem initializes, it sends a response back. I wanted to show that response in a form in the initialization textbox. At first, I thought that the initialization event will do the trick. But... it doesn't. Because the event handler can be attached to an already constructed object, and we need to fire the initialization event before the object is finally constructed. The solution was to use a delegate. That is, to pass a delegate into the modem class constructor. Like this:

public ModemModel1(SerialPort prt, string prtnum, SetCallback c) : 
                                      base(prt, prtnum, c) { }

In general, using the created classes is simple, like this:

mod = new Modem(new SerialPort(), this.cmbPortas.Text,;

After that, we can query the modem manufacturer with mod.GetManufacturer(). Also, we have the modem class static method FirstAttachedModem(), which returns the COM port on which the modem is connected and also the modem manufacturer and the chipset version. That is why on the form show event, the modem is automatically detected (if it exists, of course :-)).

Finally, about thread-safe calls. This is achieved by the Modem.SetCallback delegate. The approach is more general - not to pass the modem answer / text to the GUI thread, but instead to pass the whole Modem object like this:

public void TakeControl(Modem modcall).
    if (this.InvokeRequired)
        Modem.SetCallback d = new Modem.SetCallback(TakeControl);
        this.Invoke(d,new object[] {modcall});
        if (this.init) 
            this.txtInicializavimas.Text = modcall.ModemAnswer;
            this.txtAtsakymas.Text = modcall.ModemAnswer;


This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


About the Author

Agnius Vasiliauskas
Software Developer
Lithuania Lithuania
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionMessage Removed Pin
Member 1075791621-Apr-15 1:15
memberMember 1075791621-Apr-15 1:15 
NewsMessage Removed Pin
Member 1075791617-Apr-14 21:43
memberMember 1075791617-Apr-14 21:43 
GeneralTypo Pin
Thomas Kjørnes5-Aug-10 15:56
memberThomas Kjørnes5-Aug-10 15:56 
GeneralVery nice article Pin
iceteatwo10-Dec-09 1:35
membericeteatwo10-Dec-09 1:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 30 Nov 2007
Article Copyright 2007 by Agnius Vasiliauskas
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid