我想要的是使用visual studio使用蓝牙设备HC-05读取和写入arduino UNO。在上一步中,我可以通过usb端口直接使用visual studio c ++和Arduino进行通信。我使用的代码与arduino and visual studio c++, 2 way serial communication基本相同。在arduino中,我有命令:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
char c = Serial.read();
if (c == '1')
Serial.write("FORW");
else if (c == '2')
Serial.write("LEFT");
else if (c == '3')
Serial.write("RIGTH");
else if (c == '4')
Serial.write("BACK");
else if (c == '5')
Serial.write("STOP");
else
Serial.write("Invalid");
}
和my / output是(直接使用arduino usb):
Connection established!!!
Enter your command: 1
arduino: FORW
Enter your command: 2
arduino: LEFT
Enter your command: 3
arduino: RIGTH
Enter your command: 6
arduino: Invalid
Enter your command:
当我添加蓝牙模块HC-05时。使用串行监视器可以获得相同的输出,但是当我使用visual studio时,第一个输入永远不会返回输出,而对于后面的输出,它总是给出先前的输出而不是当前的输出,如下所示:
Connection established!!!
Enter your command: 1
arduino:
Enter your command: 2
arduino: FORW
Enter your command: 1
arduino: LEFT
Enter your command: 4
arduino: FORW
Enter your command: 6
arduino: BACK
Enter your command: 2
arduino: Invalid
Enter your command:
我不知道以下步骤是否会出错:
所以知道为什么会这样?
答案 0 :(得分:0)
最有可能的问题是,在10毫秒内,之前的通信无法联系到您。
现在,我在使用普通C ++和visual studio编程方面没有太多经验(我通常使用托管C ++扩展和事件循环)但是当我必须处理串行端口时,我通常使用事件或并行线程。
使用事件时,我使用SerialPort
类及其DataReceived
事件。由于您使用的是Visual C ++,因此我建议您使用此方法。让VS通过创建托管控制台应用程序而不是空的应用程序为您创建基础框架,并查看事件的工作方式。
如果要使用多个线程,只需使用一个线程检查输入,另一个线程检查串口。我担心我无法帮助你如何启动和处理线程(你必须使用一些操作系统或库函数,也许是pthread的),但是两个线程函数可以是某种东西像这样:
void thread1()
{
while (1)
{
std::cout << "Enter your command: ";
std::cin.get(command, 2); //input command
int msglen = strlen(command);
if (port->WriteData(command, msglen)); //write to arduino
printf("\n(writing success)\n");
}
}
void thread2()
{
while (1)
{
int n = port->ReadData(data, 4);
if (n != -1){
data[n] = 0;
cout <<"arduino: " data << endl;
}
Sleep(10);
}
}
第三种解决方案是仅在存在某些数据时检查输入和串行:
std::cout << "Enter your command: ";
while(1)
{
if (_kbhit())
{
std::cin.get(command, 2); //input command
int msglen = strlen(command);
if (port->WriteData(command, msglen)); //write to arduino
printf("\n(writing success)\n");
std::cout << "Enter your command: ";
}
//read from arduino output
n = port->ReadData(data, 4);
if (n != -1)
{
data[n] = 0;
cout <<"arduino: " data << endl;
}
Sleep(10);
}
如果您想发送多个命令(即让程序等待输入,发送它然后等待另一个输入),这些是解决方案。
如果您只想将它用于一个命令然后退出,只需等待一些数据:
std::cout << "Enter your command: ";
std::cin.get(command, 2); //input command
int msglen = strlen(command);
if (port->WriteData(command, msglen)); //write to arduino
printf("\n(writing success)\n");
while ((n = port->ReadData(data, 4)) <= 0)
Sleep(10);
data[n] = 0;
cout <<"arduino: " data << endl;
最简单但最未提及的解决方案是仅增加睡眠时间(例如,增加到50毫秒)以允许发送和接收数据包。
还有一件事,因为你迟早会遇到这个问题。通常通过通信(无论是串行,以太网......),您无法控制驱动程序在收到数据时告诉您的频率。当您收到&#34; FORW&#34;时,您通常会将其作为一个块接收,但有时您会收到一个带有&#34; FOR&#34;另一个与&#34; W&#34;或&#34; FO&#34; &#34; RW&#34;,或&#34; F&#34; &#34; ORW&#34 ;.或者你可以收到两个连续的消息,例如&#34; FORWLEFT&#34;。因此你应该