Windows Serial Programming - C++ (MFC)

idbruceidbruce Posts: 6,164
edited 2020-09-27 - 07:39:32 in General Discussion
Hello Everyone

For nearly a decade, I have occassionally dabbled with serial programming in Windows, with my first exploit being documented in this thread: https://forums.parallax.com/discussion/133979/project-in-progress-new-serial-terminal-taking-suggestions/p1

Until recently, I had only found a couple of example programs of serial communication in MFC (Microsoft Foundation Classes). The examples that were readily available, were indeed quite complex to say the least. In an effort to simplify some of my current endeavors, I have currently been looking for simpler solutions and examples, and today I came across this web page, with a simple example: https://ontrak.net/mfc.htm

I have not really begun to toy around with it just yet, but I thought some of you may be interested, for the purpose of sending serial commands to your various robots or projects.

Can it really be this simple? :) I intend to find out. :)

Comments

  • I have written several com port programs in the past and found it to be pretty straight forward.

    Today I write all my windows code in C#. I find it does a good job of handling the user interface and allows me to get the job done. I will say that C# is a little harder at dealing with binary data as it does not allow you to use pointers.

    My last couple of projects was dealing with Bluetooth BLE and UDP data which is kind of like wireless com ports.

    Mike
  • Some programmers do write needlessly complex code; I was recently contracted to modify some 30 year-old DOS code to switch from a 3M-Microtouch to a ELO-Touchscreen. The ELO manual provides sample code in C that was ridiculously complicated. I ended up with a few lines of QuickBasic. :smile:
  • iseries

    I have a machine which I can now control via WiFi, Bluetooth with Android app, or direct serial connection to the PC.

    My goal now is to simplify my serial program and wirelessly send commands via Bluetooth from the PC with the assistance of a Bluetooth adapter.
  • Unless you are using a development tool that simplifies it for you, serial comms in Windows are unbelievably and stupidly complicated. I worked it all out in the early 2000's for some vb6 projects where serial was the only thing left that required me to run an installer and I wanted to get rid of that. To open a port you must:

    1. Use CreateFile (yep, same API function you'd use to open a file) to open the port
    2. Call GetCommTimeouts() to get current settings, make mods, and SetCommTimeouts() to make the port non-blocking
    3. Call GetCommState() to get current settings, call BuildCommDCB() to create a block of port settings, then SetCommState() with the DCB you built to set comm settings like "9600,n,8,1"

    All this requires about four pages of code. If you did everything perfectly this results in an open port. You are then supposed to launch a thread to monitor for input, and on 16-bit Windows and emulation with Wine if you don't do that you can't receive data, but on 32 and 64-bit Windows (NT 4.0 thru 10) you can get by with polling because the OS buffers incoming data for you. You do need to check GetOverlappedResult() before sending data to make sure the buffer is ready or outgoing data will be lost.
  • Okay.... I just tested the code, with a simple dialog app and one simple function, and it works perfectly :)

    Here is the source code that I used:
    void CTestComPortDlg::OnSend() 
    {
    	// variables used with the com port
    	HANDLE m_hCom;
    	CString m_sComPort;
    	CString strCommand;
    	DCB m_dcb;
    	DWORD iBytesWritten;
    
    	m_sComPort = "Com5";
    
    	m_hCom = CreateFile(m_sComPort, 
    		GENERIC_READ | GENERIC_WRITE,
    		0, // exclusive access
    		NULL, // no security
    		OPEN_EXISTING,
    		0, // no overlapped I/O
    		NULL); // null template 
    
    	SetupComm(m_hCom, 128, 128); // set buffer sizes
    
    	GetCommState(m_hCom, &m_dcb);
    
    	m_dcb.BaudRate = 9600;
    	m_dcb.ByteSize = 8;
    	m_dcb.Parity = NOPARITY;
    	m_dcb.StopBits = ONESTOPBIT;
    	m_dcb.fAbortOnError = TRUE;
    
    	SetCommState(m_hCom, &m_dcb);
    
    	GetDlgItemText(IDC_COMMAND, strCommand);
    
    	WriteFile(m_hCom, strCommand, strCommand.GetLength(), &iBytesWritten, NULL);
    
    	CloseHandle(m_hCom);	
    }
    

    And here is a picture of the tiny little dialog app :)

    228 x 74 - 6K
  • I cannot believe all the hours that I spent on those over complicated examples.
  • nice

    Mike
  • @Mike
    nice

    It is almost comical :) That is definitely some code I can work with and easily understand :)
  • And we wonder why so much modern code is bloated/slow/buggy.

    The premise of readily available code libraries does absolutely nothing for me. If you weren't coding in the 80's, I don't trust you :lol: :lol: :lol:

  • Mickster
    And we wonder why so much modern code is bloated/slow/buggy.

    Are you picking on my tiny, but bloated MFC dialog app? :)

    Must I create a "LEAN AND MEAN" Win32 Console app? :)

    Actually, that is a nice piece of code for a command line app, which would make it short and sweet.
  • No I applaud it :smile:

    My point was that to take comfort in "huge available libraries" might mean that you trust in huge inefficient code, written by others....which has long been the premise of C programming....along with "portability" which is mostly a joke :lol:
  • Of course I was joking a bit :)

    However in reality, MFC applications are naturally bloated. In a release build of that tiny application, it reduces down to a size of 112KB. Creating the same capabilities in a Win32 console app would drastically reduce the final size of the executable.
Sign In or Register to comment.