如何格式化此数据以发送到串行端口?
How to format this data to send to a serial port?
我正在尝试通过 Windows 中的串行端口从硬件设备发送命令和接收数据。
文档包含以下信息:
文档中还给出了一个示例命令,如下所示:
Client:
这应该导致 returned 数据:
当我在串行端口监视器应用程序中以十六进制形式发送完整的
命令时,我确实得到了数据 return。然而,在我的 C++ 应用程序中,我什么也没得到。
我在 C++ 中使用 boost::asio,并且有以下代码:
int main(int argc, char* argv[])
{
asio::io_service io;
asio::serial_port port(io);
port.open("COM4");
port.set_option(asio::serial_port_base::baud_rate(115200));
uint8_t obuf[512]; // arbitrary size, larger than largest expected buffer
for (size_t i = 0; i < 512; ++i) obuf[i] = 0;
while (true)
{
port.write_some(boost::asio::buffer(char(0x02) + "0401032A" + char(0x03), 10));
//
std::cout << "reading" << std::endl;
asio::read(port, asio::buffer(obuf,10));
std::cout << obuf << std::endl;
}
std::cin.get();
}
我这里的格式哪里出错了?如何将此命令“$02 $30 $34 $30 $31 $30 $33 $32 $41 $03”作为 ASCI 发送到 C++ 中的端口?
这是一个错误:
char(0x02) + "0401032A" + char(0x03)
它增加了整数类型(char、char const* 和 char)。您可能想要的是
char(0x02) + std::string("0401032A") + char(0x03), 10)
// or
char(0x02) + "0401032A"s + char(0x03)
// or indeed, much simpler:
"\x02" "0401032A0\x03"s
Keep in mind that if you want to construct a std::string from a literal constant using the constructor, you may have to specify a length when the data includes embedded NUL characters.
This is not required for ""s"
and ""sv
literals, so usually you should prefer them
旁注
使用 asio::write
而不是 write_some
这样您就可以更好地保证整个缓冲区都已传输(当然,遇到错误时除外)。
还可以使用 return 值来调整您收到的实际邮件的大小。
改进建议:
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <iostream>
namespace asio = boost::asio;
using namespace std::literals;
int main()
{
asio::io_service io;
asio::serial_port port(io);
port.open("COM4");
port.set_option(asio::serial_port_base::baud_rate(115200));
while (true) {
boost::asio::write(port, boost::asio::buffer("\x02"
"0401032A0\x03"sv));
//
std::cout << "reading" << std::endl;
std::vector<uint8_t> obuf(10, 0);
auto n = asio::read(port, asio::buffer(obuf));
obuf.resize(n);
for (int i : obuf) {
std::cout << std::hex << std::showbase << " " << i;
}
std::cout << std::endl;
}
}
我正在尝试通过 Windows 中的串行端口从硬件设备发送命令和接收数据。
文档包含以下信息:
文档中还给出了一个示例命令,如下所示:
Client:
这应该导致 returned 数据:
当我在串行端口监视器应用程序中以十六进制形式发送完整的
命令时,我确实得到了数据 return。然而,在我的 C++ 应用程序中,我什么也没得到。
我在 C++ 中使用 boost::asio,并且有以下代码:
int main(int argc, char* argv[])
{
asio::io_service io;
asio::serial_port port(io);
port.open("COM4");
port.set_option(asio::serial_port_base::baud_rate(115200));
uint8_t obuf[512]; // arbitrary size, larger than largest expected buffer
for (size_t i = 0; i < 512; ++i) obuf[i] = 0;
while (true)
{
port.write_some(boost::asio::buffer(char(0x02) + "0401032A" + char(0x03), 10));
//
std::cout << "reading" << std::endl;
asio::read(port, asio::buffer(obuf,10));
std::cout << obuf << std::endl;
}
std::cin.get();
}
我这里的格式哪里出错了?如何将此命令“$02 $30 $34 $30 $31 $30 $33 $32 $41 $03”作为 ASCI 发送到 C++ 中的端口?
这是一个错误:
char(0x02) + "0401032A" + char(0x03)
它增加了整数类型(char、char const* 和 char)。您可能想要的是
char(0x02) + std::string("0401032A") + char(0x03), 10)
// or
char(0x02) + "0401032A"s + char(0x03)
// or indeed, much simpler:
"\x02" "0401032A0\x03"s
Keep in mind that if you want to construct a std::string from a literal constant using the constructor, you may have to specify a length when the data includes embedded NUL characters.
This is not required for
""s"
and""sv
literals, so usually you should prefer them
旁注
使用 asio::write
而不是 write_some
这样您就可以更好地保证整个缓冲区都已传输(当然,遇到错误时除外)。
还可以使用 return 值来调整您收到的实际邮件的大小。
改进建议:
#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <iostream>
namespace asio = boost::asio;
using namespace std::literals;
int main()
{
asio::io_service io;
asio::serial_port port(io);
port.open("COM4");
port.set_option(asio::serial_port_base::baud_rate(115200));
while (true) {
boost::asio::write(port, boost::asio::buffer("\x02"
"0401032A0\x03"sv));
//
std::cout << "reading" << std::endl;
std::vector<uint8_t> obuf(10, 0);
auto n = asio::read(port, asio::buffer(obuf));
obuf.resize(n);
for (int i : obuf) {
std::cout << std::hex << std::showbase << " " << i;
}
std::cout << std::endl;
}
}