简体   繁体   English

C++ Com 串口:写入失败

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

I keep trying to write to a gantry motor via COM Serial Port in C++ and the device doesn't perform the command and returns random symbols.我一直尝试通过 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. 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. When I place a ComEventWait or whatever it doesn't stop waiting.当我放置 ComEventWait 或其他任何东西时,它不会停止等待。

main.cpp主文件

#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 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

you have problems with buffering.你有缓冲问题。 I'm not fixing other errors, like not declared variables, sending objects by value or reading by values, because they aren't related to the question.我没有修复其他错误,例如未声明的变量、按值发送对象或按值读取,因为它们与问题无关。

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);
}

I strongly recommend to read something about pointers in C/C++我强烈建议阅读有关 C/C++ 中指针的内容

Your comment seems to imply that you want 9600, but you requested 38,400:您的评论似乎暗示您想要 9600,但您要求 38,400:

params.BaudRate = CBR_38400;      //BaudRate = 9600

If you truly wanted/needed to communicate at 9600, but you are talking at 38400, that could be your issue.如果您真的想/需要在 9600 进行交流,但您在 38400 通话,那可能是您的问题。 Try replacing the line with:尝试将行替换为:

params.BaudRate = CBR_9600;

Garbage characters are typical when using an incorrect baud rate.使用不正确的波特率时,通常会出现垃圾字符。

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

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