[英]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, ¶ms); //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, ¶ms);
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;
};
}
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.