[英]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, ¶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;
};
}
你有緩沖問題。 我沒有修復其他錯誤,例如未聲明的變量、按值發送對象或按值讀取,因為它們與問題無關。
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.