【发布时间】:2010-08-11 02:27:05
【问题描述】:
我遇到了 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'。
有人吗? 谢谢!
【问题讨论】:
-
也许如果你在格式化它可能会有所帮助?
-
我对更多文本的格式没有问题,但我不确定你指的是什么。代码,“解释”或两者兼而有之? PS:注意解释中的引号。我不确定我是否能很好地解释问题。
-
只要使用原始 API,就无法避免。具有实现 ReadLine() 的串行端口包装器的类库当然是可用的。
标签: c++ serial-port arduino