c++ - C++ Com 串口:写入失败
问题描述
我一直尝试通过 C++ 中的 COM 串行端口写入龙门电机,但设备不执行命令并返回随机符号。
这应该在机器正常工作时移动机器上的龙门臂,并通过读取功能返回臂的位置并返回臂的位置。当我放置 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, ¶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;
};
}
解决方案
您的评论似乎暗示您想要 9600,但您要求 38,400:
params.BaudRate = CBR_38400; //BaudRate = 9600
如果您真的想/需要在 9600 进行交流,但您在 38400 通话,那可能是您的问题。尝试将行替换为:
params.BaudRate = CBR_9600;
使用不正确的波特率时,通常会出现垃圾字符。
推荐阅读
- angular - 为什么 Angular 4 FormGroup 自定义验证器不起作用?
- dart - 切换语言时的国际化问题
- c# - 将 Powershell Connect-PnPOnline 转换为 C#
- c - `sizeof(char*)` 是否总是等于`sizeof(double*)`?
- arrays - 添加两个数组以创建一个
- c# - 如何以编程方式获取按钮名称 xamarin 表单
- amazon-s3 - 无法通过 pem 文件连接(使用 ftp 和命令行)服务器
- docker - 与使用 docker compose 启动的 redis 容器交互
- java - 如何分阶段执行所有线程
- c# - 如何使用 C# windows 应用程序获取打开的窗口商店应用程序并获取 uwp 安装列表