- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在为嵌入式系统和在 Linux 环境中运行的 C++ 应用程序之间的串行通信创建一个类。因此我使用了用于 Linux 的 termios API,描述为 here .
构造函数将打开设备的串口。在我的例子中,我使用的 arduino 微 Controller 是“ttyUSB0”。接下来它将设置波特率和其他端口选项。
我还添加了在串口上读取或写入数据的函数。因为 read 是一个阻塞函数(直到接收到数据或超时才返回),我添加了一个函数来检查是否有可用字节,您可以在调用“Read()”之前执行此操作。
制作测试用例后,阅读似乎工作正常。函数“Available()”确实会返回可用的字节数。阅读后将它们打印到控制台。
然而,由于某些未知原因,我的写入功能无法正常工作,即使我“相信”我已正确遵循指南中的步骤。我为写入功能做了一个测试用例:一旦收到正确的消息,arduino 应该闪烁它的内置 LED。以开始标记“#”开始并以结束标记“$”结束的消息是正确的。
当我使用测试工具 putty 或使用 arduino 的串行监视器发送正确的消息时,led 会闪烁。但是当我通过我自己的写函数发送消息时,这不会发生。
arduino 还有其他内置 LED,用于指示 RX 和 TX 引脚上的数据。一旦我从我自己的写入函数发送数据,这些 LED 实际上会亮起,但我的测试用例中的闪烁函数从未被调用。然后我检查是否读取了任何字节,但是当从我自己的写入函数发送数据时,arduino 的“Serial.available()”从不返回高于 0 的值。
我认为错误要么在写入函数本身,要么在串行端口的配置中。到目前为止,我无法弄清楚这一点。有没有人对此有任何经验或知识,或者对我应该如何解决这个问题有任何提示?
提前致谢
德克
Linux 代码:
主要.cpp
#include "serial.h"
#include <iostream>
using namespace std;
int main()
{
//TEST CASE FOR WRITING DATA
Serial serial("/dev/ttyUSB0");
serial.Write("#TEST$");
//TEST CASE FOR READING DATA
/*while (true)
{
char message[100];
char * ptr = NULL;
while (serial.Available() > 0)
{
char c;
serial.Read(&c);
switch(c)
{
case '#':
ptr = message;
break;
case '$':
if (ptr != NULL)
{
*ptr = '\0';
}
std::cout << "received: " << message << std::endl;
ptr = NULL;
break;
default:
if (ptr != NULL)
{
*ptr = c;
ptr++;
}
break;
}
}
}*/
return EXIT_SUCCESS;
}
序列号.h
#ifndef SERIAL_H
#define SERIAL_H
#include <cstdio>
#include <cstdlib>
#include <fcntl.h>
#include <string>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
class Serial
{
private:
int fd;
public:
Serial(std::string device);
~Serial()
{
close(fd);
};
int Available();
void Read(char * buffer, int amountOfBytes);
void Read(char * bytePtr);
int Write(std::string message);
};
#endif
串口.cpp
#include "serial.h"
#include <stdexcept>
#include <string.h>
Serial::Serial(std::string device)
{
// Open port
fd = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
if (fd < 0)
{
throw std::runtime_error("Failed to open port!");
}
// Config
struct termios config;
tcgetattr(fd, &config);
// Set baudrate
cfsetispeed(&config, B9600);
cfsetospeed(&config, B9600);
// 9600 8N1
config.c_cflag &= ~PARENB;
config.c_cflag &= ~CSTOPB;
config.c_cflag &= ~CSIZE;
config.c_cflag |= CS8;
// Disable hardware based flow control
config.c_cflag &= ~CRTSCTS;
// Enable receiver
config.c_cflag |= CREAD | CLOCAL;
// Disable software based flow control
config.c_iflag &= ~(IXON | IXOFF | IXANY);
// Termois Non Cannoincal Mode
config.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// Minimum number of characters for non cannoincal read
config.c_cc[VMIN] = 1;
// Timeout in deciseconds for read
config.c_cc[VTIME] = 0;
// Save config
if (tcsetattr(fd, TCSANOW, &config) < 0)
{
close(fd);
throw std::runtime_error("Failed to configure port!");
}
// Flush RX Buffer
if (tcflush(fd, TCIFLUSH) < 0)
{
close(fd);
throw std::runtime_error("Failed to flush buffer!");
}
}
int Serial::Available()
{
int bytes = 0;
if (ioctl(fd, TIOCINQ, &bytes) < 0)
{
close(fd);
throw std::runtime_error("Failed to check buffer!");
}
return bytes;
}
void Serial::Read(char * buffer, int amountOfBytes)
{
if (read(fd, buffer, amountOfBytes) < 0)
{
close(fd);
throw std::runtime_error("Failed to read bytes!");
}
}
void Serial::Read(char * bytePtr)
{
return Serial::Read(bytePtr, 1);
}
int Serial::Write(std::string message)
{
int length = message.size();
if (length > 100)
{
throw std::invalid_argument("Message may not be longer than 100 bytes!");
}
char msg[101];
strcpy(msg, message.c_str());
int bytesWritten = write(fd, msg, length);
if (bytesWritten < 0)
{
close(fd);
throw std::runtime_error("Failed to write bytes!");
}
return bytesWritten;
}
Arduino代码
void setup()
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
//TEST-CASE FOR WRITING DATA
/*Serial.print("#TEST$");
delay(1000);*/
//TEST-CASE FOR READING DATA
char message[100];
char * ptr = NULL;
while (Serial.available() > 0)
{
char c = Serial.read();
switch(c)
{
case '#':
ptr = message;
break;
case '$':
if (ptr != NULL)
{
*ptr = '\0';
}
ptr = NULL;
int messageLength = strlen(message);
Blink();
break;
default:
if (ptr != NULL)
{
*ptr = c;
ptr++;
}
break;
}
}
}
void Blink()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
最佳答案
已解决。“打开”功能在串行端口上发送信号,arduino 将其解释为重启信号。我通过 disabling auto-reset 解决了这个问题.
或者,您可以在保存配置后添加两秒的延迟。
这个问题特别适用于 arduino 微 Controller 。
关于linux - C++串口通信读数据有效但写入失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53508059/
我想用 python 与我的串口通信。我为 linux 安装了 pyserial 和 uspp: import serial ser = serial.Serial('/dev/pts/1', 192
如何实现 IP 串行,反之亦然。 我听说可以用 SOCAT 做到这一点(9600 N,8,1)--> 串口 --> 网络 --> 串口 -->(9600 N81) 请求人们帮助我解决这个问题 最佳答案
ATtiny88初体验(三):串口 ATtiny88单片机不包含串口模块,因此只能使用软件方式模拟串口时序。 串口通信时序通常由起始位、数据位、校验位和停止位四个部分组成,常见的
我有一个 c# 应用程序,它通过串行端口将 pc 连接到设备。 当我向设备发送数据时,如果设备发回数据,则会触发 datareceived 事件。 我想问这个。 有没有办法模拟设备的数据发送? 我的意
所以我将数据从 Arduino 传输到 C# Winform,后者将数据输出到文本框并将其保存到文件中。传输数据格式如下18|25|999|100~;第一部分是以秒为单位的时间,它让我知道什么时候跳过
规范模式状态的 Termios 手册页 ( http://man7.org/linux/man-pages/man3/termios.3.html ): Input is made available
串口代码有问题。 我只是这样做: opencomm(); send(); closecomm(); ClearCommError()(在 recv() 内) 返回comstat.cbInQue 发送的
我想通过音频插孔使用串行端口获取数据。我对此一无所知。但是我找到了一个应用audioserial可以发送数据到。所以,我认为应该获取像 audioserial 这样的数据。 .是否有相同的项目或对此很
串口有问题 我写了一个程序,可以读取端口 COM1 到 COM9,但可以打开 COMXX(如 com10、com11 等) 我搜索并了解到 tCOM1–COM9 是 NT 命名空间中保留名称的一部分。
我正在尝试在 Linux 中使用串口组织 nob-blocking 读写功能。这是我的代码:http://pastebin.com/RSPw7HAi一切正常,但已缓冲。这意味着,如果我通过控制台 +
我想将出现在 Arduino 中的数据传输到我的 C# 应用程序,但不知道我的代码有什么问题。Arduino 代码来了: int switchPin = 7; int ledPin = 13; boo
我正在编写一个网络驱动程序,它应该使用串行通信将数据包发送到 Arduino。这是一项家庭作业,仅用于教育目的。请在建议一切都可以在用户空间中完成之前考虑到这一点。 这answer说明了 filp_o
我想在笔记本电脑和模块之间进行通信。为此,我创建了一个 python 文件,它将一些数据包发送到 UART,它必须读取它们。我有一个创建数据包的 python 脚本(笔记本电脑): SOF= '24'
正在寻找正确的方法来在主板启动消息期间检测一个关键字。检测到关键字后,一秒后发送 Enter 键。内核是Linux。 # Serial port inisialisation is finished
我尝试通过串口读取数据,但读取操作总是返回0。 // Opening COM port and m_fd returned a valid number m_fd = open (m_com_por
微 Controller :dsPIC33EP512MU810 编译器:MikroC 我正在尝试通过 UART 从远程设备请求多个字节。要获得所需的信息,您发送一个请求字节以接收一个数据字节。当请求超
我计划很快开始围绕串行设备的输入进行编码,很高兴找到 Ruby-serialport . API 看起来很容易使用,但我对如何采用基于事件的方法来接收数据有点困惑。 每当 \n 出现时,我想对数据做一
我想在 Linux 中实现一个驱动程序,它有一个以太网堆栈,但在硬件上输出的数据将是一个串行端口。基本上,我想将我的串行端口注册为以太网驱动程序。有谁知道这是否可能?我希望能够将 IPv6 和/或 U
我正在开发一个项目,其中有许多硬件传感器通过 RS232 串行端口连接到部署机器。 但是……我正在一台没有物理 RS232 串行端口的机器上进行开发,但我想制作假的串行端口,我可以连接到这些端口并
我正在制作一个非常简单的 c++ 程序,它通过串行端口向 arduino 发送一个角度,然后 arduino 将该角度应用于伺服电机。我知道 Unix 把串口设备看成一个文件,实际上这是 c++ 代码
我是一名优秀的程序员,十分优秀!