tSerial::tSerial(const char *serialPort, bool echo)
{
// Open the serial port. Change device path as needed (currently set to an standard FTDI USB-UART cable type device)
m_serialPort = open(serialPort, O_RDWR);
// Create new termios struct, we call it 'tty' for convention
struct termios tty;
// Read in existing settings, and handle any error
if (tcgetattr(m_serialPort, &tty) != 0)
{
spdlog::error("[tSerial] error {} from tcgetattr: {}", errno, strerror(errno));
throw std::runtime_error("Failed to get existing serial settings");
}
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
tty.c_cflag |= CS8; // 8 bits per byte (most common)
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
// tty.c_lflag &= ~ICANON;
tty.c_cflag |= ICANON;
if (!echo)
{
tty.c_lflag &= ~ECHO; // Disable echo
}
else
{
tty.c_lflag |= ECHO; // Enable echo
}
// tty.c_lflag &= ~ECHOE; // Disable erasure
// tty.c_lflag &= ~ECHONL; // Disable new-line echo
// tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
// Set in/out baud rate to be 115200
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
// Save tty settings, also checking for error
if (tcsetattr(m_serialPort, TCSANOW, &tty) != 0)
{
spdlog::error("[tSerial] error {} from tcsetattr: {}", errno, strerror(errno));
throw std::runtime_error("Failed to set new serial settings");
}
// Set non-blocking
int flags;
if ((flags = fcntl(m_serialPort, F_GETFL, 0)) == -1)
{
flags = 0;
}
fcntl(m_serialPort, F_SETFL, flags | O_NONBLOCK);
}
void tSerial::writeSerial(std::string message)
{
int n;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(m_serialPort, &rfds);
spdlog::debug("[tSerial] writing command to serial {}", message);
struct timeval tv;
tv.tv_sec = 20;
tv.tv_usec = 0;
int retval = select(1, NULL, &rfds, NULL, &tv);
if (retval == -1)
{
spdlog::error("[tSerial] select error");
}
else if (retval)
{
n = write(m_serialPort, message.c_str(), message.length());
tcflush(m_serialPort, TCIOFLUSH);
if (n < 0)
{
spdlog::error("[tSerial] error writing: {}", strerror(errno));
}
}
else
{
spdlog::error("[tSerial] Resource unavailable after 20 seconds wait");
}
}
我正在使用select
等待IO资源变得可用...但是即使等待20秒,设备仍然不可用。
由于没有正确编程select()调用,程序的行为没有达到预期:
int retval = select(1, NULL, &rfds, NULL, &tv);
在手册页中,第一个参数“应该设置为三个集合中编号最高的文件描述符,外加1。”
由于传递的值1
,所以select()可以检查的唯一文件描述符是stdin
(它是只读的,永远不会准备好输出),并且永远不会(文件描述符)打开的串行终端。
相反,系统调用需要是
select(m_serialPort + 1, ...);
您的代码还有其他问题。
(1)使用非阻塞模式是有问题的。
似乎您更喜欢在程序中添加额外的代码以等待,而不是让操作系统为您做这件事。如果您的程序没有有效地利用它的时间片,那么您最好让操作系统管理系统资源。
(2)在write()之后使用tcflush()是荒谬和错误的!
您可能打算使用tcdrain()。
研究手册页。
fd_set rfds;
...
int retval = select(..., NULL, &rfds, NULL, &tv);
您的程序应该使用类似于wfds
的内容作为第三个参数,而不是rfds
。
...试图直接写入它会出现错误资源暂时不可用
使用select()时的问题很容易解释。
对于上述问题,您需要提供一个最小的、可复制的示例,即一个完整的程序。
我正在尝试使用Android Studio作为IDE和Java作为编程语言与温度计BLE设备进行交互。使用智能手机上的应用程序,我发现了该设备在运行过程中暴露的服务:有很多通用服务/特性和一个自定义服务。 首先,我试着阅读 健康温度计服务(UUID=00001809-0000-1000-8000-00805F9B34FB) 从服务列表中恢复特征并访问其描述符: 在这种情况下,我可以看到测量的结果在
我正在尝试从Java应用程序的Google Sheets API。我已经访问了教程中提到的文件,但我无法访问我自己创建的任何文件。 这是我使用的代码: 我在Drive中手动创建了一个电子表格,用字符串填充A1: B,并从URL中复制了id,看起来像“1IeoY5jY3Su86x1uvgc1yJqEU-6dd6FdUKo8Yf5J73k”(不是实际的ID)。 这将生成错误400无法解析范围:类数据!
问题内容: 我将Arduino连接到运行循环的计算机,每100毫秒通过串行端口将值发送回计算机。 我想制作一个Python脚本,该脚本仅每隔几秒钟从串行端口读取一次,因此我希望它仅查看Arduino发送的最新消息。 您如何在Pyserial中做到这一点? 这是我尝试的无效代码。它顺序读取行。 问题答案: 也许我误会了您的问题,但是由于它是一条串行线路,因此您必须按顺序读取Arduino发送的所有内
问题内容: 我对读取和写入串行端口有些困惑。我在Linux中有一个使用FTDI USB串行设备转换器驱动程序的USB设备。当我插入它时,它将创建:/ dev / ttyUSB1。 我认为用C打开和读取它很简单。我知道波特率和奇偶校验信息,但是似乎没有标准吗? 我是否缺少某些东西,或者有人可以指出正确的方向? 问题答案: 您必须调用一个从获得。你不能零了,配置它,然后将用。如果使用归零方法,则会遇到
我正在尝试将数据写入我的Arduino Uno,并从中接收日期。 我在Windows 8.1上使用NetBeans,为了做到这一点,库“RXTXcomm.jar”。 我的代码是这样的,我的Arduino在COM3上,它在第25行和第80行抛出一个错误: 错误 java.lang.UnsatisfiedLinkError:java.library中没有rxtxSerial。加载gnu.io时抛出的路
我拥有一个极地H10胸带,它以蓝牙低能量运行,并提供心率和心率变化。 我想用Android应用程序读取这些值。由于官方BLE教程中的帮助,我能够连接到设备。现在的问题是从设备中读取心率和心率变异性值。每次设备上有新值可用时,我都要读取该值(并且至少每秒都有新值)。 我找到了以下代码: 假设我与设备有连接,我如何使用它来提取心率和r-r间隔(节拍到节拍间隔)?如果有人能举个简短的例子,我会很高兴。此