发送命令并等待回复USB设备
Sending command and waiting for reply to a USB device
我有一个设备(旋转测量表)连接到/dev/ttyACM0
,并且需要编写一个简单的CPP控制器以将命令发送到设备并收听响应。
我没有这种东西的经验。我了解我可以使用fstream
打开USB设备,并使用write()
发送命令。有效。
问题是我如何发送命令并开始收听响应?
下面的代码只是悬挂。我猜是因为它是同步的,因此错过了响应。
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::fstream f;
char command[256] = "?ASTATnr";
char response[256];
std::string str;
f.open("/dev/ttyACM0");
if (f.is_open())
{
std::cout << "Port opened" << std::endl;
}
f.write(command, 256);
while(1)
{
while (f >> str)
{
std::cout << str;
}
}
return 0;
}
我已经研究了异步的libusb-1.0,但遇到问题,发现我的出路http://libusb.sourceforge.net/api-1.0/group__libus_elibusb_asyncio.html并从。
编辑:我设法使设备响应如下:
std::string response_value = "";
char response = 0;
std::cout << "response: ";
while(1)
{
f << command;
f.read(&response, 1);
if ((int)response == 13)
{
break;
}
std::cout << (response) << " ";
response_value += response;
}
与制作人交谈并尝试不同的命令并输出消息后,我发现该设备应发送可变长度响应,该响应始终以0x0D
或Integer结束。
当前,如果我彼此之间发送多个命令,则什么也不会发生。从其他来源,我了解我需要设置波特率,但是,fstream没有文件描述符,并且`tcgetAttr(2)1 reauires文件描述符以初始化术语OILIOS结构。有没有办法检索它?
我最好回答问题。可以将作为文件读/写入USB设备,因为OS具有处理通信的驱动程序(如果我理解错误的话,请纠正我)。FSTREAM能够阅读和写作,但是由于调整MUS在终端级别上进行,因此不可能调整BAUD速率(设备为通信的频率),因此取决于OS。对于Linux,我们必须使用fctl.h
,termios.h
和unistd.h
。它允许我们设置速率,以及超时,以防设备没有响应。
因此,仅使用CPP函数实施阅读和写作要复杂得多。
我在这里发布我的解决方案,这对我有用,但是欢迎对此发表任何评论。
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <string>
#include <iostream>
bool init_terminal_interface(struct termios& tty, const int file_descriptor)
{
memset(&tty, 0, sizeof tty); // Init the structure;
if (tcgetattr(file_descriptor, &tty) != 0)
{
std::cout << "Error" << errno << " from tcgetattr: " << strerror(errno) << std::endl;
return false;
}
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B9600);
cfsetispeed (&tty, (speed_t)B9600);
/* Setting other Port Stuff */
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag &= ~ICANON;
tty.c_cflag |= CS8;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 0; //
tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
/* Flush Port, then applies attributes */
tcflush(file_descriptor, TCIFLUSH);
if (tcsetattr(file_descriptor, TCSANOW, &tty) != 0) {
std::cout << "Error " << " from tcsetattr: " << strerror(errno) << std::endl;
return false;
}
return true;
}
void send_command(std::string command, const int file_descriptor)
{
write(file_descriptor, command.c_str(), command.size());
std::cout << "Command sent: " << command << std::endl;
}
std::string check_response(int file_descriptor)
{
std::string response_value = "";
char response = 0;
ssize_t n_read = 0;
do {
// In blocking mode, read() will return 0 after timeout.
n_read = read( file_descriptor, &response, 1 );
if (n_read > 0)
{
response_value += response;
}
} while( response != 'r' && (int)response != 13 && n_read != 0);
// In case of timeout it will return an empty string.
return response_value;
}
int open_serial(const std::string serial_path)
{
int file_descriptor = open(serial_path.c_str(), O_RDWR);
if (file_descriptor == -1)
{
std::cout << "Unable to access the turntable device." << std::endl;
return -1;
}
std::cout << "File opened: " << file_descriptor << std::endl;
struct termios tty;
init_terminal_interface(tty, file_descriptor);
return file_descriptor;
}
int main()
{
int file_descriptor = open_serial("/dev/ttyACM0");
if (file_descriptor == -1)
{
return 1;
}
// Good command.
std::string command = "?baudratern";
send_command(command, file_descriptor);
std::string response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
// Wrong command.
command = "?asasdtatrn";
send_command(command, file_descriptor);
response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
// Good command.
command = "init1rn";
send_command(command, file_descriptor);
response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
// Good command.
command = "ref1=4rn";
send_command(command, file_descriptor);
response_value = check_response(file_descriptor);
std::cout << "Full response: " << response_value << std::endl;
return 0;
}
- 是否可以使用winusb同时与多个相同的usb设备进行通信
- 插入或删除时获取usb的dos_name
- 使用 VID、PID、+SN 查找 USB 端口号
- USB传输的LibUSB C++格式不同
- 从 GUID 获取 USB 卷路径
- 如何在C++(VS2010)中设置超时读取USB端口?
- 如何在 MAC OS c/c++ 中阻止 USB 存储设备
- Android Java USB for native cpp
- mbed:使用 USB 文档库编译会导致错误
- 如何集成 HID USB 控制器?
- 在Windows(C++)中使用USB相机拍摄高分辨率照片
- 如何检测 USRP USB 类型?
- QT:管理来自 QNetworkReply 的回复
- q网络回复 无状态码或错误,但失败
- 我是否可以使用 win32 句柄以编程方式记录发送到/接收到 USB/COM 的内容
- 如何在Qt中使用Android上的USB OTG串行接口?
- 只需按一次按钮即可通过USB发送数据
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 回复计划游戏结果不会显示
- 发送命令并等待回复USB设备