繁体   English   中英

C++ Com 串口:写入失败

[英]C++ Com Serial Port: Fails to write

我一直尝试通过 C++ 中的 COM 串行端口写入龙门电机,但设备不执行命令并返回随机符号。

This should move the gantry arm on a machine when it's working correctly and return the position of the arm through the read function and return the position of the arm. 当我放置 ComEventWait 或其他任何东西时,它不会停止等待。

主文件

#include <iostream>
#include "../../../../Documents/Development/proteinmaker6channel/ProteinMaker/device_connection.h"
int main()
{
    DeviceConnection dc = DeviceConnection();

    dc.performWrite("XEXSULF");
    dc.performWrite("YEXSULF");
    dc.performWrite("ZEXSULF");

    dc.performWrite("XEXHHLF");
    dc.performWrite("YEXHHLF");
    dc.performWrite("ZEXHHLF");
}

device_connection.cpp

#include "device_connection.h"
#include<windows.h>
#include<stdio.h>
#include <list>
#include <string>
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <assert.h>
#include <stdio.h>
using namespace std;


DeviceConnection::DeviceConnection()
{
}

void DeviceConnection::open(std::string portName)
{
    wchar_t pszPortName[10] = { 0 }; //com port id
    wchar_t PortNo[20] = { 'C', 'O', 'M', '3', '\0' }; //contain friendly name
    //Enter the com port id
    //Open the serial com port
    hComm = CreateFile(PortNo, //friendly name
        GENERIC_READ | GENERIC_WRITE,      // Read/Write Access
        0,                                 // No Sharing, ports cant be shared
        NULL,                              // No Security
        OPEN_EXISTING,                     // Open existing port only
        NULL,              // Non Overlapped I/O
        NULL);                             // Null for Comm Devices
    if (hComm == INVALID_HANDLE_VALUE)
    {
        printf_s("\nPort can't be opened");
        system("pause");
        return;
    }
    printf_s("\nPort opened");
}

void DeviceConnection::performWrite(std::string command) {
    open("COM3");
    setParameters();
    setTimeouts();
    write(command);
    setCommMask();
    //wait();
    read();
    CloseHandle(hComm);//Closing the Serial Port
    system("pause");
}

bool DeviceConnection::write(std::string command){
    //strcpy_s(SerialBuffer, command.c_str());
    printf_s("\nwriting:  %s \n", command.c_str());
    //Writing data to Serial Port
    bool Status = WriteFile(hComm,// Handle to the Serialport
        command.c_str(),            // Data to be written to the port
        64,   // No of bytes to write into the port
        &BytesWritten,  // No of bytes written to the port
        NULL);
    if (Status == FALSE)
    {
        CloseHandle(hComm);//Closing the Serial Port
        printf_s("\nFailed to Write at %d " + BytesWritten + '\n');
        return false;
    }
    printf_s("\nbytes written to the serail port: %d \n", BytesWritten);

    
    return 1;
}

void DeviceConnection::read() {
    //Read data and store in a buffer
    char ReadData;        //temperory Character
    char Output[64] = "";
    unsigned char loop = 0;
    do
    {
            Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL);
            printf(&ReadData);
            printf("\nreading(%d): %s", loop, &ReadData);
            Output[loop] = ReadData;
           ++loop;
    } while (NoBytesRead > 0);
    --loop; //Get Actual length of received data
    printf("\nbytes received = %s\n", Output);
    //print receive data on console
    //int index = 0;
    //for (index = 0; index < loop; ++index)
    //{
    //    //printf_s("%s", ReadData);
    //}
}

void DeviceConnection::wait() {
    //Setting WaitComm() Event
    DWORD dwEventMask;     // Event mask to trigger
    OVERLAPPED o;
    o.hEvent = CreateEvent(
        NULL,   // default security attributes 
        TRUE,   // manual-reset event 
        FALSE,  // not signaled 
        NULL    // no name
    );


    // Initialize the rest of the OVERLAPPED structure to zero.
    o.Internal = 0;
    o.InternalHigh = 0;
    o.Offset = 0;
    o.OffsetHigh = 0;
    //assert(&o.hEvent);
    printf_s("\nWaiting %d", BytesWritten);
    Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
    printf_s("\nDone\n\n", Status);
    if (Status == FALSE)
    {
        printf_s("\nError! in Setting WaitCommEvent()\n\n");
        system("pause");
        return;
    }
}

void DeviceConnection::setCommMask() {
    //print numbers of byte written to the serial port
    //printf_s("\nSetting Comm Mask = %d", EV_RXCHAR);
    //Setting Receive Mask
    Status = SetCommMask(hComm, EV_RXCHAR);
    if (Status == FALSE)
    {
        printf_s("\nError to in Setting CommMask\n\n");
        CloseHandle(hComm);//Closing the Serial Port
        system("pause");
        return;
    }

}

void DeviceConnection::setParameters()
{
    //Setting the Parameters for the SerialPort
    params.DCBlength = sizeof(params);
    Status = GetCommState(hComm, &params); //retreives  the current settings
    if (Status == FALSE)
    {
        printf_s("\nError getting the Com state");
        CloseHandle(hComm);//Closing the Serial Port
        system("pause");
        return;
    }
    //  Print some of the DCB structure values
    _tprintf(TEXT("\nOriginal BaudRate: %d, ByteSize: %d, Parity: %d, StopBits: %d"),
        params.BaudRate,
        params.ByteSize,
        params.Parity,
        params.StopBits);
    params.BaudRate = CBR_38400;      //BaudRate = 9600
    params.ByteSize = 8;             //ByteSize = 8
    params.StopBits = ONESTOPBIT;    //StopBits = 1
    params.Parity = NOPARITY;      //Parity = None
    Status = SetCommState(hComm, &params);
    if (Status == FALSE)
    {
        printf_s("\nError to Setting DCB Structure\n\n");
        CloseHandle(hComm);//Closing the Serial Port
        system("pause");
        return;
    }
    _tprintf(TEXT("\nUpdated BaudRate: %d, ByteSize: %d, Parity: %d, StopBits: %d"),
        params.BaudRate,
        params.ByteSize,
        params.Parity,
        params.StopBits);
    printf_s("\nUpdated Parameters");
}

void DeviceConnection::setTimeouts() {
    //Setting Timeouts
    COMMTIMEOUTS timeouts = { 0 };  //Initializing timeouts structure
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;
    if (SetCommTimeouts(hComm, &timeouts) == FALSE)
    {
        printf_s("\nError to Setting Time outs");

        CloseHandle(hComm);//Closing the Serial Port

        system("pause");
        return;
    };
}

[1]:https://i.stack.imgur.com/ZKSP0.png

你有缓冲问题。 我没有修复其他错误,例如未声明的变量、按值发送对象或按值读取,因为它们与问题无关。

bool DeviceConnection::write(std::string command){
    //strcpy_s(SerialBuffer, command.c_str());
    printf_s("\nwriting:  %s \n", command.c_str());
    //Writing data to Serial Port
    bool Status = WriteFile(hComm,// Handle to the Serialport
        command.c_str(),    // Data to be written to the port <----- YOU MUST USE REAL SIZE OF THE BUFFER, otherwise you will get undefined behaviour 
        command.length(),   // No of bytes to write into the port
        &BytesWritten,  // No of bytes written to the port
        NULL);
    if (Status == FALSE)
    {
        CloseHandle(hComm);//Closing the Serial Port
        printf_s("\nFailed to Write at %d " + BytesWritten + '\n');
        return false;
    }
    printf_s("\nbytes written to the serail port: %d \n", BytesWritten);

    
    return 1;
}

void DeviceConnection::read() {
    //Read data and store in a buffer
    char ReadData;        //temperory Character
    char Output[64] = "";
    unsigned char loop = 0;
    do
    {
            Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL); 
            printf(ReadData); //<- PRINIT VALUE NOT POINTER
            printf("\nreading(%d): %c", loop, ReadData); //<- PRINIT VALUE NOT POINTER
            Output[loop] = ReadData;
           ++loop;
    } while (NoBytesRead > 0);
    // --loop; //Get Actual length of received data // <- incorrect
    printf("\nbytes received = %s\n", Output);
}

我强烈建议阅读有关 C/C++ 中指针的内容

您的评论似乎暗示您想要 9600,但您要求 38,400:

params.BaudRate = CBR_38400;      //BaudRate = 9600

如果您真的想/需要在 9600 进行交流,但您在 38400 通话,那可能是您的问题。 尝试将行替换为:

params.BaudRate = CBR_9600;

使用不正确的波特率时,通常会出现垃圾字符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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