Click here to Skip to main content
15,879,326 members
Articles / Desktop Programming / MFC

IntelliPort

Rate me:
Please Sign up or sign in to vote.
4.71/5 (60 votes)
21 Feb 2024GPL38 min read 182.3K   1.7K   147   55
You can use IntelliPort to transfer large files from a computer onto your portable computer using a serial port rather than going through the process of setting up your portable computer on a network.
The main purpose of this MFC application is to get logs via serial port or UDP socket from embedded systems, such as EFTPOS devices, and it is based on PJ Naughter's CSerialPort and CWSocket classes.

HyperTerminal

Introduction

As you already know, Microsoft has dropped the development of HyperTerminal starting with Windows 7. IntelliPort is a program that you can use to connect to other computers, using either your null modem cable or Ethernet connection. IntelliPort records the messages passed to and from the computer on the other end of your connection. Therefore, it can serve as a valuable troubleshooting tool when setting up and using your modem. To make sure that your modem is connected properly or to view your modem's settings, you can send commands through IntelliPort and check the results. IntelliPort has scroll functionality that allows you to look at received text that has scrolled off the screen. You can use IntelliPort to transfer large files from a computer onto your portable computer using a serial port rather than going through the process of setting up your portable computer on a network. IntelliPort is designed to be an easy-to-use tool and is not meant to replace other full-feature tools available on the market. You can use IntelliPort to perform the specific tasks described above, but do not attempt to use IntelliPort for more complex communication needs.

Background

The main purpose of this MFC application is to get logs via serial port or UDP socket from embedded systems, such as EFTPOS devices, and it is based on PJ Naughter's CSerialPort and CWSocket classes. For those who do not know, EFTPOS is the method for paying for goods or services without needing to carry cash. On making a purchase, the EFTPOS customer gives an EFTPOS card to the cashier who inserts it into an on-site EFTPOS machine. When the EFTPOS customer confirms the purchase, either by signature or security PIN, the EFTPOS equipment contacts the store's bank electronically about the transaction. A message is also sent to the customer's bank. Unless there is reason for the EFTPOS transaction not to be completed, the funds will then be transferred between the two accounts. The EFTPOS transaction takes a matter of only a few seconds. Before the EFTPOS customer has had the goods put into a bag, the EFTPOS transaction will be complete. Confirmation of the EFTPOS transaction is sent to the store and passed on to the customer in the form of a printed EFTPOS transaction record.

How Do I Get Started?

First, configure the MFC application to get logs from either serial port or TCP/UDP socket connection. Please check the CConfigureDlg class for implementation details.

Configure serial port or TCP/UDP socket

Next, now you can connect/disconnect from your data source. Please check the OnOpenSerialPort and OnCloseSerialPort functions for implementation details.

Reading/Writing data to serial port or TCP/UDP socket

C++
void CMainFrame::OnOpenSerialPort()
{
    try
    {
        CString strFormat, strMessage;
        switch (theApp.m_nConnection)
        {
            case 0:
            {
                CString strFullPortName;
                strFullPortName.Format(_T("\\\\.\\%s"), static_cast<LPCWSTR>(theApp.m_strSerialName));
                m_pSerialPort.Open(
                    strFullPortName,
                    theApp.m_nBaudRate,
                    (CSerialPort::Parity) theApp.m_nParity,
                    (BYTE)theApp.m_nDataBits,
                    (CSerialPort::StopBits) theApp.m_nStopBits,
                    (CSerialPort::FlowControl) theApp.m_nFlowControl,
                    FALSE);

                if (m_pSerialPort.IsOpen())
                {
                    m_nThreadRunning = true;
                    m_hSerialPortThread = CreateThread(nullptr, 0, SerialPortThreadFunc, this, 0, &m_nSerialPortThreadID);
                    strFormat.LoadString(IDS_SERIAL_PORT_OPENED);
                    strMessage.Format(strFormat, static_cast<LPCWSTR>(theApp.m_strSerialName));
                    SetCaptionBarText(strMessage);
                }
                break;
            }
            case 1:
            case 2:
            {
                CString strServerIP = theApp.m_strServerIP;
                UINT nServerPort = theApp.m_nServerPort;
                CString strClientIP = theApp.m_strClientIP;
                UINT nClientPort = theApp.m_nClientPort;

                if (theApp.m_nConnection == 1) // TCP Socket
                {
                    if (theApp.m_nSocketType == 1) // Client
                    {
                        m_pSocket.CreateAndConnect(strServerIP, nServerPort);
                    }
                    else // TCP Server
                    {
                        m_pSocket.SetBindAddress(strClientIP);
                        m_pSocket.CreateAndBind(nClientPort, SOCK_STREAM, AF_INET);

                        m_dlgIncoming.ShowWindow(SW_SHOW);
                        m_dlgIncoming.CenterWindow(this);
                        m_dlgIncoming.Invalidate();
                        m_dlgIncoming.UpdateWindow();
                        m_pSocket.Listen();
                        m_pSocket.Accept(m_pIncomming);
                        m_dlgIncoming.ShowWindow(SW_HIDE);
                    }
                }
                else // UDP Socket
                {
                    m_pSocket.SetBindAddress(strClientIP);
                    m_pSocket.CreateAndBind(nClientPort, SOCK_DGRAM, AF_INET);

                    strServerIP = strClientIP;
                    nServerPort = nClientPort;
                }

                if (m_pSocket.IsCreated())
                {
                    m_nThreadRunning = true;
                    m_hSocketThread = CreateThread(nullptr, 0, SocketThreadFunc, this, 0, &m_nSocketTreadID);
                    strFormat.LoadString(IDS_SOCKET_CREATED);
                    strMessage.Format(strFormat, ((theApp.m_nConnection == 1) ? _T("TCP") : _T("UDP")), static_cast<LPCWSTR>(strServerIP), nServerPort);
                    SetCaptionBarText(strMessage);
                }
                break;
            }
        }
    }
    catch (CSerialException& pException)
    {
        const int nErrorLength = 0x100;
        TCHAR lpszErrorMessage[nErrorLength] = { 0, };
        pException.GetErrorMessage2(lpszErrorMessage, nErrorLength);
        TRACE(_T("%s\n"), lpszErrorMessage);
        // pException->Delete();
        SetCaptionBarText(lpszErrorMessage);
        m_nThreadRunning = false;
    }
    catch (CWSocketException* pException)
    {
        const int nErrorLength = 0x100;
        TCHAR lpszErrorMessage[nErrorLength] = { 0, };
        pException->GetErrorMessage(lpszErrorMessage, nErrorLength);
        TRACE(_T("%s\n"), lpszErrorMessage);
        pException->Delete();
        SetCaptionBarText(lpszErrorMessage);
        m_nThreadRunning = false;
    }
}

void CMainFrame::OnCloseSerialPort()
{
    if (m_nThreadRunning)
    {
        m_nThreadRunning = false;
        DWORD nThreadCount = 0;
        HANDLE hThreadArray[2] = { 0, 0 };
        if (m_hSerialPortThread != nullptr)
        {
            hThreadArray[nThreadCount++] = m_hSerialPortThread;
        }
        if (m_hSocketThread != nullptr)
        {
            hThreadArray[nThreadCount++] = m_hSocketThread;
        }
        if (nThreadCount > 0)
        {
            WaitForMultipleObjects(nThreadCount, hThreadArray, TRUE, INFINITE);
        }
    }

    try
    {
        CString strFormat, strMessage;
        switch (theApp.m_nConnection)
        {
            case 0:
            {
                if (!m_pSerialPort.IsOpen())
                {
                    strFormat.LoadString(IDS_SERIAL_PORT_CLOSED);
                    strMessage.Format(strFormat, static_cast<LPCWSTR>(theApp.m_strSerialName));
                    SetCaptionBarText(strMessage);
                }
                break;
            }
            case 1:
            case 2:
            {
                CString strServerIP = theApp.m_strServerIP;
                UINT nServerPort = theApp.m_nServerPort;
                CString strClientIP = theApp.m_strClientIP;
                UINT nClientPort = theApp.m_nClientPort;

                if (!m_pSocket.IsCreated())
                {
                    if (theApp.m_nConnection == 1) // TCP Socket
                    {
                        if (theApp.m_nSocketType == 1) // Client
                        {
                        }
                        else // TCP Server
                        {
                        }
                    }
                    else // UDP Socket
                    {
                        strServerIP = strClientIP;
                        nServerPort = nClientPort;
                    }

                    strFormat.LoadString(IDS_SOCKET_CLOSED);
                    strMessage.Format(strFormat, ((theApp.m_nConnection == 1) ? _T("TCP") : _T("UDP")), static_cast<LPCWSTR>(strServerIP), nServerPort);
                    SetCaptionBarText(strMessage);
                }
                break;
            }
        }
    }
    catch (CSerialException& pException)
    {
        const int nErrorLength = 0x100;
        TCHAR lpszErrorMessage[nErrorLength] = { 0, };
        pException.GetErrorMessage2(lpszErrorMessage, nErrorLength);
        TRACE(_T("%s\n"), lpszErrorMessage);
        // pException->Delete();
        SetCaptionBarText(lpszErrorMessage);
        m_nThreadRunning = false;
    }
    catch (CWSocketException* pException)
    {
        const int nErrorLength = 0x100;
        TCHAR lpszErrorMessage[nErrorLength] = { 0, };
        pException->GetErrorMessage(lpszErrorMessage, nErrorLength);
        TRACE(_T("%s\n"), lpszErrorMessage);
        pException->Delete();
        SetCaptionBarText(lpszErrorMessage);
        m_nThreadRunning = false;
    }
}

void CMainFrame::OnSendReceive()
{
    try
    {
        CInputDlg dlgInput(this);
        if (dlgInput.DoModal() == IDOK)
        {
            CStringA pBuffer(dlgInput.m_strSendData);
            const int nLength = pBuffer.GetLength();

            switch (theApp.m_nConnection)
            {
                case 0:
                {
                    m_pMutualAccess.lock();
                    m_pSerialPort.Write(pBuffer.GetBufferSetLength(nLength), nLength);
                    m_pMutualAccess.unlock();
                    pBuffer.ReleaseBuffer();
                    break;
                }
                case 1:
                case 2:
                {
                    CString strServerIP = theApp.m_strServerIP;
                    const UINT nServerPort = theApp.m_nServerPort;

                    if (theApp.m_nConnection == 1) // TCP Socket
                    {
                        if (theApp.m_nSocketType == 1) // Client
                        {
                            if (m_pSocket.IsWritable(1000))
                            {
                                m_pMutualAccess.lock();
                                m_pSocket.Send(pBuffer.GetBufferSetLength(nLength), nLength, 0);
                                pBuffer.ReleaseBuffer();
                                m_pMutualAccess.unlock();
                            }
                        }
                        else
                        {
                            if (m_pIncomming.IsWritable(1000))
                            {
                                m_pMutualAccess.lock();
                                m_pIncomming.Send(pBuffer.GetBufferSetLength(nLength), nLength, 0);
                                pBuffer.ReleaseBuffer();
                                m_pMutualAccess.unlock();
                            }
                        }
                    }
                    else
                    {
                        if (m_pSocket.IsWritable(1000))
                        {
                            m_pMutualAccess.lock();
                            m_pSocket.SendTo(pBuffer.GetBufferSetLength(nLength), nLength, nServerPort, strServerIP, 0);
                            pBuffer.ReleaseBuffer();
                            m_pMutualAccess.unlock();
                        }
                    }
                    break;
                }
            }
        }
    }
    catch (CSerialException& pException)
    {
        const int nErrorLength = 0x100;
        TCHAR lpszErrorMessage[nErrorLength] = { 0, };
        pException.GetErrorMessage2(lpszErrorMessage, nErrorLength);
        TRACE(_T("%s\n"), lpszErrorMessage);
        // pException->Delete();
        SetCaptionBarText(lpszErrorMessage);
        m_nThreadRunning = false;
    }
    catch (CWSocketException* pException)
    {
        const int nErrorLength = 0x100;
        TCHAR lpszErrorMessage[nErrorLength] = { 0, };
        pException->GetErrorMessage(lpszErrorMessage, nErrorLength);
        TRACE(_T("%s\n"), lpszErrorMessage);
        pException->Delete();
        SetCaptionBarText(lpszErrorMessage);
        m_nThreadRunning = false;
    }
}

Points of Interest

In order to be GUI responsive, the MFC application does the reading in separate working threads:

C++
DWORD WINAPI SerialPortThreadFunc(LPVOID pParam)
{
    COMSTAT status = { 0, };
    char pBuffer[0x10000] = { 0, };
    CMainFrame* pMainFrame = (CMainFrame*) pParam;
    CRingBuffer& pRingBuffer = pMainFrame->m_pRingBuffer;
    CSerialPort& pSerialPort = pMainFrame->m_pSerialPort;
    std::mutex& pMutualAccess = pMainFrame->m_pMutualAccess;

    while (pMainFrame->m_nThreadRunning)
    {
        try
        {
            memset(&status, 0, sizeof(status));
            pSerialPort.GetStatus(status);
            if (status.cbInQue > 0)
            {
                memset(pBuffer, 0, sizeof(pBuffer));
                const int nLength = pSerialPort.Read(pBuffer, sizeof(pBuffer));
                pMutualAccess.lock();
                pRingBuffer.WriteBinary(pBuffer, nLength);
                pMutualAccess.unlock();
            }
            else
            {
                ::Sleep(10);
            }
        }
        catch (CSerialException& pException)
        {
            const int nErrorLength = 0x100;
            TCHAR lpszErrorMessage[nErrorLength] = { 0, };
            pException.GetErrorMessage2(lpszErrorMessage, nErrorLength);
            TRACE(_T("%s\n"), lpszErrorMessage);
            // pException->Delete();
            pMainFrame->SetCaptionBarText(lpszErrorMessage);
            pMainFrame->m_nThreadRunning = false;
            pSerialPort.Close();
        }
    }
    pSerialPort.Close();
    return 0;
}

DWORD WINAPI SocketThreadFunc(LPVOID pParam)
{
    char pBuffer[0x10000] = { 0, };
    CMainFrame* pMainFrame = (CMainFrame*) pParam;
    CRingBuffer& pRingBuffer = pMainFrame->m_pRingBuffer;
    CWSocket& pSocket = pMainFrame->m_pSocket;
    CWSocket& pIncomming = pMainFrame->m_pIncomming;
    std::mutex& pMutualAccess = pMainFrame->m_pMutualAccess;
    bool bIsTCP = (theApp.m_nConnection == 1);
    bool bIsClient = (theApp.m_nSocketType == 1);

    CString strServerIP = theApp.m_strServerIP;
    UINT nServerPort = theApp.m_nServerPort;

    while (pMainFrame->m_nThreadRunning)
    {
        try
        {
            if (bIsTCP)
            {
                if (bIsClient)
                {
                    if (pSocket.IsReadible(1000))
                    {
                        memset(pBuffer, 0, sizeof(pBuffer));
                        const int nLength = pSocket.Receive(pBuffer, sizeof(pBuffer), 0);
                        pMutualAccess.lock();
                        pRingBuffer.WriteBinary(pBuffer, nLength);
                        pMutualAccess.unlock();
                    }
                    else
                    {
                        ::Sleep(10);
                    }
                }
                else
                {
                    if (pIncomming.IsReadible(1000))
                    {
                        memset(pBuffer, 0, sizeof(pBuffer));
                        const int nLength = pIncomming.Receive(pBuffer, sizeof(pBuffer), 0);
                        pMutualAccess.lock();
                        pRingBuffer.WriteBinary(pBuffer, nLength);
                        pMutualAccess.unlock();
                    }
                    else
                    {
                        ::Sleep(10);
                    }
                }
            }
            else
            {
                if (pSocket.IsReadible(1000))
                {
                    memset(pBuffer, 0, sizeof(pBuffer));
                    const int nLength = pSocket.ReceiveFrom(pBuffer, sizeof(pBuffer), strServerIP, nServerPort, 0);
                    pMutualAccess.lock();
                    pRingBuffer.WriteBinary(pBuffer, nLength);
                    pMutualAccess.unlock();
                }
                else
                {
                    ::Sleep(10);
                }
            }
        }
        catch (CWSocketException* pException)
        {
            const int nErrorLength = 0x100;
            TCHAR lpszErrorMessage[nErrorLength] = { 0, };
            pException->GetErrorMessage(lpszErrorMessage, nErrorLength);
            TRACE(_T("%s\n"), lpszErrorMessage);
            pException->Delete();
            pMainFrame->SetCaptionBarText(lpszErrorMessage);
            pMainFrame->m_nThreadRunning = false;
            pIncomming.Close();
            pSocket.Close();
        }
    }
    pIncomming.Close();
    pSocket.Close();
    return 0;
}

Final Words

IntelliPort application uses many components that have been published on Code Project. Many thanks to:

  • PJ Naughter for his EnumSerialPorts class
  • Larry Antram for his CRingBuffer class
  • PJ Naughter for his CSerialPort class
  • PJ Naughter for his CWSocket class
  • PJ Naughter for his CVersionInfo class

Further plans: I would like to add Telnet and SSH support as soon as possible.

3 Reasons USB Ports Are Replacing Serial Ports

The original IBM PC included RS-232 serial ports, helping to proliferate a data transfer format that has lasted for decades. Thousands of industrial devices, everything from flow meters to other types of laboratory instruments, traditionally have RS-232 as the standard input/output port. In 2004, most of the new PCs stopped shipping with an RS-232 serial interface as a part of their standard or base configuration. Common PC desktop peripherals such as printers, scanners, and fax machines are currently made with USB ports.

The Universal Serial Bus, or USB, is an external port that interfaces between external devices and a computer. The original IBM personal computers had an RS-232 port that connected external devices like a keyboard or mouse.Today, USB ports are replacing RS-232 ports. One may plug most anything into a USB port. This includes keyboards, cameras, mice, joysticks,modems, zip drives, floppy drives, printers, and scanners.

USB offers three key advantages to peripheral manufacturers:

  • Compatibility: In the last few years serial ports have almost disappeared from PCs, and USB ports have replaced them. There are thousands of industrial devices that have serial ports, and this change is causing problems. Fortunately you may buy an inexpensive adapter that allows you to connect a USB port to a serial device. These devices work well, however they are only a stopgap measure.
  • Speed: USB allows data to travel on the average of ten times the speed of the normal parallel port. It is also faster than a serial port. The average serial port transfer rate is 150 kbps; the USB port is up to 12 Mbps. USB 2 is forty times faster, with a maximum transfer rate of 480 Mbps. It is backwardly compatible with USB 1. That means that if a new computer comes with USB 2, the older USB devices may still be used. Of course, they will perform at USB 1 speeds, but they will still work properly.
  • Durability: USB ports are more robust than serial ports. Serial ports are NOT robust, the tiny little pins are very easy to bend or break. On the other hand, USB ports are very rugged.

 

Image 4
If your system has a free USB port, you can convert between USB and serial signals. The USB to serial adapter is a small piece of equipment with a USB connector at one end and at least one, and perhaps multiple, serial connectors on the other end.

Can you use a USB for serial communication? Yes, you can use a USB for serial communication by using a USB-to-serial adapter. This adapter allows devices that communicate via serial ports to be connected to a computer's USB port. It's a common solution for connecting older devices, such as modems, industrial equipment, and some types of microcontrollers, to modern computers that may lack native serial ports.

History

  • Version 1.3 (20th July, 2014): Initial release.
  • Version 1.5 (28th July, 2014): Fixed several bugs regarding logging functions for serial port and UDP socket.
  • Version 1.6 (30th August, 2015): Fix for Microsoft Windows 10 64bit.
  • Version 1.7 (3rd April, 2019): Performance and security fixes.
  • Version 1.8 (15th June, 2019):
    • Added Romanian translation;
    • Added PJ Naughter's CInstanceChecker class.
  • Version 1.9 (27th July, 2019): Bugfix for serial port name: please see the article mentioned in the comments.
  • Moved source code from CodeProject to GitLab (7th December, 2019).
  • Version 1.10 (25th March, 2020): Changed font size for main and input dialogs.
  • Version 1.11 (9th May, 2020): Added French translation, thanks to Stefan Gaftoniuc.
  • Version 1.12 (6th June, 2020): Added Italian translation, thanks to InterLingua.
  • Version 1.13 (13th June, 2020): Added German translation, thanks to InterLingua.
  • Version 1.14 (20th June, 2020): Added Spanish translation, thanks to InterLingua.
  • Version 1.15 (19th July, 2020): Added Russian translation, thanks to InterLingua.
  • Version 1.16 (31st July, 2020): Added Greek translation, thanks to InterLingua.
  • Version 1.17 (12th September, 2020): Made improvements and squashed bugs so #IntelliPort is even better for you:
    • Updated PJ Naughter's CSerialPort library to the latest version available;
    • Updated PJ Naughter's CWSocket library to the latest version available.
  • Version 1.18 (25th September, 2020): Overwrote CEditCtrl 64K limit.
  • Version 1.19 (7th January, 2022): Updated About dialog with new e-mail address.
  • Version 1.20 (14th January, 2022): Updated PJ Naughter's CVersionInfo library to the latest version available.
  • Version 1.21 (4th February, 2022): Changed external website address.
  • Version 1.22 (11th February, 2022): Fixed critical bug regarding File Open/SaveAs in French, Italian, German, Spanish, Russian, Greek translations.
  • Version 1.23 (28th April, 2022): Added LICENSE to installation folder.
  • Version 1.24 (12th May, 2022): Converted all line endings to Windows format (CR LF).
  • Version 1.25 (19th May, 2022): Updated PJ Naughter's CEnumerateSerial library to the latest version available.
  • Version 1.26 (24th May, 2022): Fixed minor bug.
  • Version 1.27 (September 9th, 2022): Added Contributors hyperlink to AboutBox dialog.
  • December 23rd, 2022: Moved source code from GitLab to GitHub.
  • Version 1.28 (January 20th, 2023): Removed PJ Naughter's Single Instance class.
  • Version 1.29 (January 23rd, 2023): Updated PJ Naughter's CVersionInfo library to the latest version available.
    Updated the code to use C++ uniform initialization for all variable declarations.
  • Replaced NULL throughout the codebase with nullptr.
    Replaced BOOL throughout the codebase with bool.
    This means that the minimum requirement for the application is now Microsoft Visual C++ 2010.
  • Version 1.30 (April 2nd, 2023): Implemented error handling for socket and serial port connections.
  • Version 1.31 (April 13th, 2023): Rework thread synchronization and removed all Sleep calls.
  • Version 1.32 (May 27th, 2023): Updated About dialog with GPLv3 notice.
  • Version 1.33 (June 13th, 2023): Made persistent the application's settings (requested by wvd_vegt).
  • Version 1.34 (June 22nd, 2023): Updated PJ Naughter's CEnumerateSerial library to the latest version available.
  • Version 1.35 (July 22nd, 2023): Replaced old CHyperlinkStatic class with PJ Naughter's CHLinkCtrl library.
  • Version 1.36 (September 29th, 2023):
    • Switched to Visual Studio Enterprise 2022 (some changes were made in the source code);
    • Changed article's download link. Updated the About dialog (email & website).
  • Version 1.37 (January 3rd, 2024):
    • Added social media links: Twitter, LinkedIn, Facebook, and Instagram;
    • Added shortcuts to GitHub repository's Issues, Discussions, and Wiki.
  • Added "3 Reasons USB Ports Are Replacing Serial Ports" section.
  • Version 1.38 (January 27th, 2024): Added ReleaseNotes.html and SoftwareContentRegister.html to GitHub repo.
  • Version 1.39 (February 21st, 2024): Switched MFC application' theme back to native Windows.

License

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


Written By
Software Developer NXP Semiconductors
Romania Romania
My professional background includes knowledge of analyst programmer for Microsoft Visual C++, Microsoft Visual C#, Microsoft Visual Basic, Sun Java, assembly for Intel 80x86 microprocessors, assembly for PIC microcontrollers (produced by Microchip Inc.), relational databases (MySQL, Oracle, SQL Server), concurrent version systems, bug tracking systems, web design (HTML5, CSS3, XML, PHP/MySQL, JavaScript).

Comments and Discussions

 
QuestionBuild environment?!? Pin
Stacy Dudovitz29-Jan-24 12:56
professionalStacy Dudovitz29-Jan-24 12:56 
AnswerRe: Build environment?!? Pin
Ștefan-Mihai MOGA29-Jan-24 17:56
professionalȘtefan-Mihai MOGA29-Jan-24 17:56 
QuestionPlease collect updates ... Pin
Jürgen Welzenbach4-Aug-23 3:48
Jürgen Welzenbach4-Aug-23 3:48 
QuestionSerial Ports Pin
Member 1368182624-Jul-23 7:49
Member 1368182624-Jul-23 7:49 
AnswerRe: Serial Ports Pin
Ștefan-Mihai MOGA9-Oct-23 4:49
professionalȘtefan-Mihai MOGA9-Oct-23 4:49 
GeneralRe: Serial Ports Pin
dandy723-Jan-24 6:44
dandy723-Jan-24 6:44 
GeneralRe: Serial Ports Pin
Ștefan-Mihai MOGA3-Jan-24 6:49
professionalȘtefan-Mihai MOGA3-Jan-24 6:49 
QuestionNot working Pin
wvd_vegt12-Jun-23 1:06
professionalwvd_vegt12-Jun-23 1:06 
AnswerRe: Not working Pin
Ștefan-Mihai MOGA12-Jun-23 20:16
professionalȘtefan-Mihai MOGA12-Jun-23 20:16 
GeneralRe: Not working Pin
wvd_vegt13-Jun-23 23:16
professionalwvd_vegt13-Jun-23 23:16 
GeneralMy vote of 5 Pin
Member 1370414327-Mar-23 7:17
Member 1370414327-Mar-23 7:17 
GeneralRe: My vote of 5 Pin
Ștefan-Mihai MOGA27-Mar-23 8:24
professionalȘtefan-Mihai MOGA27-Mar-23 8:24 
GeneralMy vote of 1 Pin
John Dqnaghan27-Mar-23 1:03
professionalJohn Dqnaghan27-Mar-23 1:03 
GeneralRe: My vote of 1 Pin
Ștefan-Mihai MOGA27-Mar-23 8:26
professionalȘtefan-Mihai MOGA27-Mar-23 8:26 
GeneralRe: My vote of 1 Pin
wvd_vegt26-Sep-23 23:49
professionalwvd_vegt26-Sep-23 23:49 
GeneralRe: My vote of 1 Pin
Ștefan-Mihai MOGA27-Sep-23 0:16
professionalȘtefan-Mihai MOGA27-Sep-23 0:16 
QuestionIt is simply evil. Pin
yereverluvinuncleber27-Jan-23 0:55
yereverluvinuncleber27-Jan-23 0:55 
AnswerRe: It is simply evil. Pin
Ștefan-Mihai MOGA27-Mar-23 8:28
professionalȘtefan-Mihai MOGA27-Mar-23 8:28 
GeneralRe: It is simply evil. Pin
the Kris3-Apr-23 23:49
the Kris3-Apr-23 23:49 
QuestionAllow multiple instances Pin
tolsen6416-Feb-22 10:50
professionaltolsen6416-Feb-22 10:50 
AnswerRe: Allow multiple instances Pin
Ștefan-Mihai MOGA20-Jan-23 5:49
professionalȘtefan-Mihai MOGA20-Jan-23 5:49 
GeneralSerial Port Pin
Member 1206430714-Sep-20 5:50
Member 1206430714-Sep-20 5:50 
GeneralRe: Serial Port Pin
RufusVS28-Oct-20 9:59
RufusVS28-Oct-20 9:59 
GeneralRe: Serial Port Pin
studleylee3-Apr-23 11:30
studleylee3-Apr-23 11:30 
GeneralRe: Serial Port Pin
wvd_vegt12-Jun-23 1:10
professionalwvd_vegt12-Jun-23 1:10 

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.