读取HL-G1测量值(例程)RS485通信 C++串口通信

4 篇文章 0 订阅
4 篇文章 0 订阅

        本例中使用windows系统电脑作为上位机与松下激光位移产品HL-G1进行串口通信。HL-G1通过 RS485-RS232/USB 转接板与电脑相连,采用松下自定义协议进行通信。windows系统向传感器发出指令后会接受到返回数据,本例发送返回位移测量值命令。

        以下为windows环境下采用C++串口通信例程,供读者参考。

#include <iostream>
#include <string>
#include <windows.h>
#include <cstdlib>

class TFSerialPort
{
public:
    TFSerialPort(std::string portNum, DWORD baudRate = 38400, BYTE byteSize = 8, BYTE parityBit = NOPARITY, BYTE stopBit = ONESTOPBIT)
    {
        m_portNum = portNum;
        m_dwBaudrate = baudRate;
        m_byteSize = byteSize;
        m_parityBit = parityBit;
        m_stopBit = stopBit;
        m_bOpen = false;
    }

    ~TFSerialPort()
    {}

public:
    HANDLE m_hCom;          //句柄
    std::string m_portNum;  //串口号
    DWORD m_dwBaudrate;     //波特率
    BYTE  m_byteSize;       //数据位
    BYTE  m_parityBit;      //校验位
    BYTE  m_stopBit;        //停止位
    bool  m_bOpen;          //串口开关标志

    //打开com口
    bool openCom()
    {
        m_hCom = CreateFileA(m_portNum.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

        if (m_hCom == INVALID_HANDLE_VALUE)
        {
        }
        else
        {
            DCB dcb;
            if (!SetupComm(m_hCom, 1024, 1024))
            {
            }
            else
            {
            }

            GetCommState(m_hCom, &dcb);
            dcb.BaudRate = m_dwBaudrate;
            dcb.ByteSize = m_byteSize;
            dcb.Parity = m_parityBit;
            dcb.StopBits = m_stopBit;

            if (!SetCommState(m_hCom, &dcb))
            {
                return false;
            }
            else
            {
                PurgeComm(m_hCom, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
                m_bOpen = true;

                return true;
            }
        }
    }

    //关闭com口
    void closeCom()
    {
        CloseHandle(m_hCom);
    }

    //写入数据
    bool writeToCom(BYTE data[], DWORD dwLength)
    {
        DWORD dwError = 0;
        if (ClearCommError(m_hCom, &dwError, NULL) && dwError > 0)
        {
            PurgeComm(m_hCom, PURGE_TXABORT | PURGE_TXCLEAR);
        }

        DWORD dwTx = 0;
        BOOL ret = FALSE;
        ret = WriteFile(m_hCom, data, dwLength, &dwTx, NULL);

        if (ret == FALSE)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    //读取数据
    bool readFromCom(BYTE readBuffer[], DWORD dwLength)
    {
        COMSTAT comStat;
        DWORD dwError = 0;
        if (ClearCommError(m_hCom, &dwError, &comStat) && dwError > 0)      //清除错误
        {
            PurgeComm(m_hCom, PURGE_RXABORT | PURGE_RXCLEAR);               //清空缓冲区
        }

        DWORD dwRx = 0;		                                                // 读入的字节数
        BOOL ret = FALSE;
        ret = ReadFile(m_hCom, readBuffer, dwLength, &dwRx, NULL);	        // 读入数据
        if (ret == TRUE)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

int main()
{
    std::string comPort = "COM6";               //定义COM口
    TFSerialPort tfserialPort(comPort);

    BYTE sendBuff[] = {"%01#RMD**\r"};          //发送空间,写入获取距离指令
    BYTE recvBuff[20] = { 0 };                  //接收空间
    CHAR order = NULL;

    tfserialPort.openCom();                     //打开COM口

    //循环发送接收串口数据并显示
    while (true)
    {
        //发送命令
        printf("Touch the Enter key to send request:");
        scanf_s("%c", &order);
        if (order != NULL)
        { tfserialPort.writeToCom(sendBuff, 10); }          //发送获取距离指令
        else
        { break; }

        //接收命令
        tfserialPort.readFromCom(recvBuff, 18);
        if (recvBuff[0] == '%' && recvBuff[17] == '\r')
        {
            printf("result: ");
            for ( int i = 7 ; i < 11 ; i++)
            { printf("%c", recvBuff[i]); }
            printf(".");
            for (int i = 11; i < 15; i++)
            { printf("%c", recvBuff[i]); }
            printf("\n");
        }
        else
        { printf("No Data!!! \r"); }
    }
    tfserialPort.closeCom();                    //关闭端口
    system("pause");                            //挂机
    return 0;
}

        运行结果如下图所示

        图中从上至下依次显示无量块放置、放置1mm厚量块 、放置2mm厚量块 、放置3mm厚量块情况下的四个测量结果,测量结果单位为毫米,四个测量值间距约为1mm。 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值