简体   繁体   中英

Serial Communication C++ Select Connect

main

#include "stdafx.h"
#include <iostream>
#include "SerialPort.h"
#include <WinBase.h>



using namespace std;

int main()
{
    cout << "Monitoring System \n";
    cout << "Please select a connection method\n\n";
    cout << "1.Serial   2.TCP \n";

    int num;

    while (!(cin >> num))
    {
        cin.clear();
        cin.ignore(INT_MAX, '\n');
        cout << "Please enter a number only   ";
    }
        
    if(num==1)
    {   
        int i,SN;
        int k=0;
        
        cout << "Scan all ports that are currently...\n";
        
        
            for (i = 1; i < 30; ++i)
            {

            if (COM_exists(i))
            {
                cout <<++k<< ".COM" << i << "\n";
            }
                
            }
            cout << "\nselect a port to connect.\n";
            scanf_s("%d", &SN, sizeof SN);

            if (SN == 1)
            {
                SerialPort PortOpen("COM", CBR_115200, 8, "#or", 24);

                PortOpen.getData();
                PortOpen.getData();
                cout << PortOpen.SerialBuffer << endl;
                return 0;
            }


        


    }








    

}

serial cpp

#include "stdafx.h"
#include <string.h>
#include "SerialPort.h"




using namespace std;



BOOL COM_exists(int port)
{
    char buffer[7];
    COMMCONFIG CommConfig;
    DWORD size;

    if (!(1 <= port && port <= 30))
    {
        return FALSE;
    }

    snprintf(buffer, sizeof buffer, "COM%d", port);
    size = sizeof CommConfig;

    
    // COM port exists if GetDefaultCommConfig returns TRUE
    // or changes <size> to indicate COMMCONFIG buffer too small.
    return (GetDefaultCommConfig(buffer, &CommConfig, &size)
        || size > sizeof CommConfig);
}


SerialPort::SerialPort(LPCSTR COM,int setBaudRate, int setByteSize, char* commandBuffer, int BufSize) {
    this->BufSize = BufSize;
    this->SerialBuffer = new char[BufSize];
    this->NoBytesRead = BufSize;
    Connect(COM, setBaudRate, setByteSize, commandBuffer);
}




void SerialPort::Connect(LPCSTR COM ,int setBaudRate, int setByteSize, char* commandBuffer) {
    this->COMport = COM;
    this->hComm = CreateFile(COM, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // (port name, read/write , no sharing , no security, open existing port only, non overlapped i/o , null for comm devices)

    if (this->hComm == INVALID_HANDLE_VALUE)
        cout << "PortOpen Fail." << endl;

    else {
        cout << "PortOpen Success." << endl;
        sendCommand(setBaudRate, setByteSize, commandBuffer);
    }
}

void SerialPort::sendCommand(int setBaudRate, int setByteSize, char* commandBuffer) {
    this->commandBuffer = commandBuffer;
    this->dNoOFBytestoWrite = sizeof(commandBuffer);
    this->Status = WriteFile(hComm, commandBuffer, dNoOFBytestoWrite, &dNoOfBytesWritten, NULL);

    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    dcbSerialParams.BaudRate = setBaudRate;
    dcbSerialParams.ByteSize = setByteSize;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;

    COMMTIMEOUTS timeouts = { 0 };
    timeouts.ReadIntervalTimeout = 10;
    timeouts.ReadTotalTimeoutConstant = 10;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;

    if (this->Status)
        cout << "Command Successful" << endl;
    else
    {
        cout << "fail to Command" << endl;
    }
}

void SerialPort::getData() {
    ReadFile(this->hComm, &*this->SerialBuffer, this->BufSize, &this->NoBytesRead, NULL);
    
}


SerialPort.h

#pragma once

#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <WinBase.h>

using namespace std;

class SerialPort {
    public:
        HANDLE hComm;
        LPCSTR COMport;
        DWORD dNoOFBytestoWrite;
        DWORD dNoOfBytesWritten;
        int BufSize;
        int Status;
        char* SerialBuffer;
        char* commandBuffer;
        DWORD NoBytesRead;
        int port;

        SerialPort(LPCSTR COMport,int setBaudRate, int setByteSize, char* commandBuffer, int BufSize);
        void Connect(LPCSTR COMport,  int setBaudRate, int setByteSize, char* commandBuffer);
        void sendCommand(int setBaudRate, int setByteSize, char* commandBuffer);
        void getData();
        
};

BOOL COM_exists(int port);

I am writing a code to connect by selecting a serial port. example, 1.COM1 / 2.COM3 / 3.COM4 How do I modify the main to connect COM4 that matches No. 3? How do I automatically read and use matching ports to match numbers?

I am writing a code to connect by selecting a serial port. example, 1.COM1 / 2.COM3 / 3.COM4 How do I modify the main to connect COM4 that matches No. 3? How do I automatically read and use matching ports to match numbers?

I would personally never ever use the old school style open and close COM port to detect if it exists. Assuming you are running on Windows I would use the SetupDi to find the serial port without opening it.

A little snippet to adapt:

#include <initguid.h>
#include <windows.h>                    // Data Type
#include <setupapi.h>                   // ::SetupDi*********
#include <devguid.h>                    // Device

    // Global Variables
    HDEVINFO            m_hDevInfo;             //!< Reference to device information set
    SP_DEVINFO_DATA     m_spDevInfoData;        //!< Device information structure (references a device instance that is a member of a device information set)
    BOOL                m_bDevInfo;             //!< Tested to ensure EnumDeviceInfo has been called
    short               m_MemberIndex = -1;     //!< Preserves state between EnumDeviceInfo calls

bool WIN_EnumDeviceInfo ()
{
    m_MemberIndex++;
    m_spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    m_bDevInfo = ::SetupDiEnumDeviceInfo(m_hDevInfo, m_MemberIndex, &m_spDevInfoData);
    return m_bDevInfo;
}

bool WIN_GetDeviceRegistryProperty(DWORD Property, PBYTE PropertyBuffer)
{
    BOOL bGotRegProp = ::SetupDiGetDeviceRegistryProperty(m_hDevInfo, &m_spDevInfoData,
                                                  Property,
                                                  0L,
                                                  PropertyBuffer,
                                                  2048,
                                                  0);
    return bGotRegProp;
}

void ScanSerial()
{

    WORD    Flags;
    PCWSTR  Enumerator=0;
    const   GUID *ClassGuid;
    HWND    m_hWnd;

    ClassGuid = &GUID_DEVCLASS_PORTS;
    Flags = DIGCF_PROFILE;

    m_hDevInfo = SetupDiGetClassDevs(ClassGuid, Enumerator, m_hWnd, Flags);

    while(WIN_EnumDeviceInfo())
    {
        wchar_t  szBuf[MAX_PATH] = {0};
        if(WIN_GetDeviceRegistryProperty(SPDRP_CLASS, (PBYTE)szBuf))
        {

            wchar_t  szFriendlyName[MAX_PATH] = {0};
            WIN_GetDeviceRegistryProperty (SPDRP_FRIENDLYNAME,  (PBYTE)szFriendlyName);
        }
    }
}

From the szFriendlyName you can filter the COMx number without opening it or either confusing them... Try and enjoy...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM