gpt4 book ai didi

c++ - Arduino 和 C++ 的串口通信

转载 作者:行者123 更新时间:2023-11-30 04:37:59 30 4
gpt4 key购买 nike

我在 Arduino Nano 和 C++ 之间的串行端口通信方面遇到问题,即使问题出在 C++ 方面。基本上我想从 Arduino 发送整数(或长,...)到 C++ 程序进行处理。

首先,我做了一个测试,使用 Matlab 将信息从 Arduino 发送到计算机。 Arduino 代码非常简单:

int i = 0;

void setup() {

// start serial port at 9600 bps:
Serial.begin(9600);
establishContact();
}

void loop() {
Serial.println(i);
i=i+1;
delay(10);
}

void establishContact() {
while (Serial.available() <= 0) {
Serial.println('A', BYTE);
delay(10);
}
}

Matlab这边也很简单:

clc;
clear all;
numSec=2;
t=[];
v=[];

s1 = serial('COM3'); % define serial port
s1.BaudRate=9600; % define baud rate
set(s1, 'terminator', 'LF'); % define the terminator for println
fopen(s1);

try % use try catch to ensure fclose
% signal the arduino to start collection
w=fscanf(s1,'%s'); % must define the input % d or %s, etc.
if (w=='A')
display(['Collecting data']);
fprintf(s1,'%s\n','A'); % establishContact just wants
% something in the buffer
end

i=0;
t0=tic;
while (toc(t0)<=numSec)
i=i+1;
t(i)=toc(t0);
t(i)=t(i)-t(1);
v(i)=fscanf(s1,'%d');
end

fclose(s1);
plot(t,v,'*r')

catch me
fclose(s1);
end

我的目标是,使用 C++ 执行与在 Matlab 中使用 fscanf(s1, '%d') 完成的相同的操作。

这是我当前使用的代码(C++ 代码):

void main()
{
HANDLE hSerial;
hSerial = CreateFile(TEXT("COM3"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,//FILE_FLAG_OVERLAPPED,
NULL);



if ( hSerial == INVALID_HANDLE_VALUE)
{
printf("Error initializing handler");
}
else
{

// Set the parameters of the handler to the serial port.
DCB dcb = {0};

dcb.DCBlength = sizeof(dcb);

if ( !GetCommState(hSerial, &dcb) )
{
printf("Error setting parameters");
}

FillMemory(&dcb, sizeof(dcb), 0);
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;

if ( !SetCommState(hSerial, &dcb) )
{
// error setting serial port state.
}

// Tell the program not to wait for data to show up
COMMTIMEOUTS timeouts = {0};

timeouts.ReadIntervalTimeout = 0;//20;
timeouts.ReadTotalTimeoutConstant = 0;//20;
timeouts.ReadTotalTimeoutMultiplier = 0;//50;
timeouts.WriteTotalTimeoutConstant = 0;//100;
timeouts.WriteTotalTimeoutMultiplier = 0;//100;

if ( !SetCommTimeouts(hSerial, &timeouts) )
{
printf("Error setting the timeouts");

}

char szBuff[5] = "";
DWORD dwBytesRead = 0;
int i = 0;
char test[] = "B\n";
int maxSamples = 10;
DWORD dwCommStatus;

WriteFile(hSerial, test, 2, &dwBytesRead, NULL);

SetCommMask(hSerial,EV_RXCHAR);

while (i < maxSamples)
{
WaitCommEvent (hSerial, &dwCommStatus, 0);

if (dwCommStatus & EV_RXCHAR)
{
memset(szBuff,0,sizeof(szBuff));
ReadFile(hSerial, LPVOID(szBuff), 4, &dwBytesRead, NULL);

cout<<szBuff;
printf(" - %d - \n", atoi(szBuff));
}
i++;
}

scanf("%d", &i);

CloseHandle(hSerial);
}
}

我的代码的目标类似于 num = ReadSerialCOM(hSerial, "%d");

我当前的 C++ 代码从缓冲区读取信息,但没有可接受的行尾,这意味着我的数字(整数)被截断了。

例如:

我从 Arduino 发送 8889,将其放入 COM 端口。命令 ReadFile 将 '88' 保存到 szBuff 中。在下一次迭代中,'89\n' 被保存到 sZBuff 中。基本上我想避免对 sZBuff 进行后处理以连接 '88' 和 '89\n'。

有人吗?谢谢!

最佳答案

如果我正确理解您的问题,避免“后处理”的一种方法是将传递给 ReadFile 的指针移动到可用数据的末尾,因此 ReadFile 调用是附加到缓冲区,而不是覆盖。

基本上,您将有两个指针。一个到缓冲区,另一个到缓冲区中数据的末尾。所以当你的程序启动时,两个指针将是相同的。现在,您读取前 2 个字节。您将数据结束指针递增 2。您进行了另一次读取,但您传递的不是 szBuff,而是指向先前读取数据末尾的指针。您读取接下来的三个字节,并且您在 szBuff 中拥有完整的条目。

如果您需要等到接收到一些分隔符来标记条目的结尾,您可以只搜索接收到的数据。如果不存在,则继续阅读直到找到它。如果它在那里,您可以直接返回。

// Fill the buffer with 0
char szBuff[256] = {0};
// We have no data in the buffer, so the end of data points to the beginning
// of the buffer.
char* szEndOfData = szBuff;
while (i < maxSamples)
{
WaitCommEvent (hSerial, &dwCommStatus, 0);

if (dwCommStatus & EV_RXCHAR)
{
// Append up to 4 bytes from the serial port to the buffer
ReadFile(hSerial, LPVOID(szEndOfData), 4, &dwBytesRead, NULL);
// Increment the end of data pointer, so it points to the end of the
// data available in the buffer.
szEndOfData += dwBytesRead;

cout<<szBuff;
printf(" - %d - \n", atoi(szBuff));
}
i++;
}

// Output, assuming what you mentioned happens:
// - 88 -
// - 8889 -

如果您可以接受这种方法,则需要做更多的工作。例如,您必须确保不会溢出缓冲区。当您从缓冲区中删除数据时,您必须将删除段之后的所有数据移动到开头,并修复数据指针的结尾。或者,您可以使用循环缓冲区。

关于c++ - Arduino 和 C++ 的串口通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3454853/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com