c++ - 与 Arduino 的串行通信仅在重启后的第一条消息上失败

标签 c++ boost serial-port arduino

我有一个 Arduino 设备和一个 PC。我在板上尝试了以下代码:

gpsdata data;

char needtosend;

void setup() {            
  Serial.begin(9600);
  Serial.flush();  
  data.id = 0;
  data.src= 500;
  data.lat= 1;
  data.lon= 2;
  data.alt= 3;
  strcpy(data.date, "test date format");

}

void loop() {


   if(Serial.available() > 0)
   {
    needtosend = Serial.read();
    if ( needtosend == '2')
    {
      data.id = ++data.id % 10;
    }

    byte* buff = (byte*)&data;
    Serial.write(buff, sizeof(data));

   }
   delay (200);

}

PC 应用程序是用 C++ 编写的,使用 boost 库与 Arduino 设备通信。这是 PC 代码:

Serial serial("/dev/ttyUSB0",9600);
            gpsdata *data;
            char *values = new char[sizeof(gpsdata)];
    while(true)
    {
        try {

            serial.writeString("2",1);
            serial.read(values,sizeof(gpsdata));
            data = (gpsdata *)values;
            cout<<data->id<<endl;
        } 
        catch(boost::system::system_error& e)
        {
            cout<<"Error: "<<e.what()<<endl;
        }
        catch(timeout_exception& e)
        {
            cout<<"Error: "<<e.what()<<endl;
        }
    }
            delete[] values;


Serial::Serial(std::string port, unsigned int baud_rate): io(), serial(io,port)
{
    serial.set_option(boost::asio::serial_port_base::baud_rate(baud_rate));  
}
void Serial::read(char *data, size_t size)
{
    boost::asio::read(serial,boost::asio::buffer(data,size));
}

void Serial::writeString(const char* s, int length)
{
   boost::asio::write(serial,boost::asio::buffer(s,length))<<std::endl;
}

当我打开设备然后首次启动 PC 应用程序时,它会向设备发送字符串“2”,然后 read() 阻塞并且永远不会从 Arduino 接收数据。如果我终止应用程序并在不重新启动 Arduino 的情况下再次启动它,一切都会开始正常工作。我尝试使用异步读取,结果是一样的,第一条消息的读取超时,然后一切开始正常工作。在 PC 应用程序中收到的第二条消息的 ID 为 1,这意味着 Arduino 尚未收到第一条消息。知道我的错误在哪里吗?

最佳答案

正如 Hans 在评论中提到的,您的通信协议(protocol)已关闭。

你的 Arduino 循环基本上说:

Read a value. If there is another available value, do something. Wait 0.2 seconds. Then repeat.

你的 PC 循环说:

Send a '2'. Then read an array of values. Then repeat.

您的情况是,您的 Arduino 通信端正在等待比发送的更多的值。在 Arduino 上,投票 Serial.avaliable ,然后进行读取。

在 PC 上,您可能不需要更改它。

当您断开连接并重新连接时,会发送一个额外的位来初始化波特率连接,这会诱使您的协议(protocol)正常工作。

编辑: 请务必检查串行库连接的设置。以下是我在使用 Qt QextSerialPort 库之前用于连接到 Arduino 开发板的设置。

port->setFlowControl(FLOW_OFF);
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setStopBits(STOP_1);
port->setTimeout(500);

这里有两个可能有用的链接:

http://www.webalice.it/fede.tft/serial_port/serial_port.html

https://www.google.com/search?q=arduino+and+boost%3A%3Aasio

关于c++ - 与 Arduino 的串行通信仅在重启后的第一条消息上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13312869/

相关文章:

c++ - Qt鼠标事件左键不翻译qt对象

c++ - (float)(1.2345f * 6.7809) 是否比 1.2345f * 6.7809f 更准确?

c++ - Boost.Asio - 具有自定义缓冲区的多个缓冲区

linux - 如何从 tty 读取串行输入并将其写入 Linux 中的文件?

c++ - 在 C++ 中更改 const 值的方法

c++ - 如何在我的构造函数中初始化树节点内的数组?

c++ - Boost.Asio 链接错误

c++ - boost ASIO : buffer overflow with 5 kb packet

python - 如何在串行通信中使用 pyserial 解码字节

vb.net - 从VB中的串行读取数据时无阻塞等待