如何将数据发送到在QT中打开的tty0tty null modem仿真器端口
How to send data to tty0tty null modem emulator port opened in QT
我已经通过 QSerialPort 与使用 tty0tty nullmodem 模拟器创建的模拟串口建立了开放的工作连接,我可以像这样向它写入数据:
QSerialPort serial_stream;
...
serial_stream.setPortName(QString("/dev/tnt0"));
bool loc = serial_stream.open(serial_stream.ReadWrite)
...
serial_stream.write(buf);
我打开一个终端并通过 "screen":
连接到连接的(在本例中为 tnt1)tnt 端口(例如 tnt0 <-> tnt1 已连接)
screen /dev/tnt1
当我执行程序时,我在屏幕上得到了预期的输入(此处 "buf")。但是我怎样才能将数据发送回 Qt 中打开的端口,以便我可以执行以下操作来读取数据:
int size = serial_stream.bytesAvailable();
QByteArray data = serial_stream.read(size);
我已经尝试用 "sleep" 停止程序...:[=15=]
#include <unistd.h>
...
usleep(15*1000000);
...并像这样将数据发送给它:
echo “TEXT“ > /dev/tnt1
但它不起作用。很高兴得到你的帮助!
Sending/Reading 数据与 QSerialPort using tty0tty - null modem emulator (v1.2)
1. 建立 tty0tty-连接:
有两种方法可以建立tty0tty-连接(在两个虚拟端口之间)。这两种方式可能都需要kernel header files. For the 2. it is definitively necessary otherwise an error while make是必然的。
(1.)简写方式:
- 下载并解压缩 tty0tty(标题中第一个 link)。
- 打开终端并
cd
到[Path to tty0tty-folder]/tty0tty/pts
- 执行
sudo ./tty0tty
那么应该显示两个相连的pseudo terminal slaves:
(/dev/pts/X) <=> (/dev/pts/Y)
with X, Y variable.
(2.) 较长的方式(但或多或少是永久性的):
也许 跨引导持久化 不起作用,因此有必要在重新启动后重复 安装指南 的以下部分:
- 加载模块
sudo depmod
sudo modprobe tty0tty
- 给新串口适当的权限(native terminal devices)
sudo chmod 666 /dev/tnt*
执行后 ls /dev/tnt*
应显示端口列表:
/dev/tnt0 ... /dev/tnt7
2. 测试 tty0tty-连接是否有效(可选):
可以用cat测试连接:
打开一个终端[1]并显示一个pseudo/native终端设备的输出:
- (1.)
cat /dev/pts/X
或 (2.)cat /dev/tnt0
打开另一个终端[2],写入这个pseudo/native终端设备:
- (1.)
echo "message" > /dev/pts/Y
或 (2.)echo "hello" > /dev/tnt1
输出应显示在终端[1]:
message
附加信息:要停止 cat,请按:Ctrl + Z
3. 在 Qt-Project:
中使用 QSerialPort 打开终端设备作为端口
在[projectname].pro
-文件中添加串口-对Qt-specific configuration options的引用:
QT += serialport
附加信息: 允许将所有引用放在一行中:
i.e. QT+= core gui serialport ...
在所需的[name].h
-文件中添加所需的header file:
#include <QtSerialPort/QSerialPort>
添加两个QSerialPort-objects,通过[=]设置终端设备的路径81=] 具有所需的权限(ReadOnly
、WriteOnly
、ReadWrite
)。示例:
std::string tty0ttyPort1 = "/dev/tnt0";// or = "/dev/pts/X
std::string tty0ttyPort2 = "/dev/tnt1";// or = "/dev/pts/Y
QSerialPort qport1;
QSerialPort qport2;
qport1.setPortName(QString(tty0ttyPort1.c_str()));
bool isOpen1 = qport1.open(qport1.ReadWrite);//Read and Write permission
std::cout << "isOpen1: " << isOpen1 << std::endl;
qport2.setPortName(QString(tty0ttyPort2.c_str()));
bool isOpen2 = qport2.open(qport2.ReadWrite);
std::cout << "isOpen2: " << isOpen2 << std::endl;
isOpen1
和 isOpen2
应该是 true
:
isOpen1: 1
isOpen2: 1
附加信息1:可能需要超级用户权限执行编译后的代码:
- 编译代码。
- 打开一个终端然后
cd
到[Path to compiled project folder]/[projectname]
- 以超级用户身份执行
sudo [executable_file]
或运行su
(inadvisable)
附加信息2:如果出现以下警告...:[=86=]
QSocketNotifier: Can only be used with threads started with QThread
...没有 Qt 事件循环 应该总是在 main()
-函数中:
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
//My Testcode (Showed above in section 3.3)
return a.exec();
}
4.使用打开的QSerialPorts:
(1.)无信号:
使用qint64 QIODevice::write(const char * data)
to write from one QSerialPort to another. Use qint64 QIODevice::read(char * data, qint64 maxSize)
or QByteArray QIODevice::readAll()
to read the sended data. Here it is import to know that it is necessary to use bool QIODevice::waitForReadyRead(int msecs)
after sending the data via QIODevice::write()
otherwise it will not work. I recommend also to use bool QIODevice::waitForBytesWritten(int msecs)
。示例:
const char* sendMessage = "myMessage";
std::cout << "sendMessage: " << sendMessage << std::endl;
qport1.write(sendMessage);
qport1.waitForBytesWritten(2000);
qport2.waitForReadyRead(2000);//required
const char* readMessage = qport2.readAll().data();
std::cout << "readMessage: " << readMessage << std::endl;
应该给出输出:
readMessage: myMessage
如果需要读取定义的字节数,请使用 QIODevice::read()
:
const char* readMessage = qport2.read(5);
std::cout << "readMessage: " << readMessage << std::endl;
应该给出输出:
readMessage: myMess
附加信息:要检查有多少字节可用于读取,请使用 qint64 QIODevice::bytesAvailable() const
。示例:
std::cout << qport2.bytesAvailable() << std::endl;
(2.) 有信号:
在 Class 的构造函数中可以连接 private slot to the readyRead()
signal using QObject::connect()
:
Classname::Classname(){
...
QObject::connect(&qport1, SIGNAL(readyRead()), this, SLOT(myPrivateSlotFunction()));
//with "qport1" as sender and "this" as receiver
}
...
Classname::myPrivateSlotFunction(){
...
const char* readMessage = qport1.readAll().data();
...
}
我已经通过 QSerialPort 与使用 tty0tty nullmodem 模拟器创建的模拟串口建立了开放的工作连接,我可以像这样向它写入数据:
QSerialPort serial_stream;
...
serial_stream.setPortName(QString("/dev/tnt0"));
bool loc = serial_stream.open(serial_stream.ReadWrite)
...
serial_stream.write(buf);
我打开一个终端并通过 "screen":
连接到连接的(在本例中为 tnt1)tnt 端口(例如 tnt0 <-> tnt1 已连接)screen /dev/tnt1
当我执行程序时,我在屏幕上得到了预期的输入(此处 "buf")。但是我怎样才能将数据发送回 Qt 中打开的端口,以便我可以执行以下操作来读取数据:
int size = serial_stream.bytesAvailable();
QByteArray data = serial_stream.read(size);
我已经尝试用 "sleep" 停止程序...:[=15=]
#include <unistd.h>
...
usleep(15*1000000);
...并像这样将数据发送给它:
echo “TEXT“ > /dev/tnt1
但它不起作用。很高兴得到你的帮助!
Sending/Reading 数据与 QSerialPort using tty0tty - null modem emulator (v1.2)
1. 建立 tty0tty-连接:
有两种方法可以建立tty0tty-连接(在两个虚拟端口之间)。这两种方式可能都需要kernel header files. For the 2. it is definitively necessary otherwise an error while make是必然的。
(1.)简写方式:
- 下载并解压缩 tty0tty(标题中第一个 link)。
- 打开终端并
cd
到[Path to tty0tty-folder]/tty0tty/pts
- 执行
sudo ./tty0tty
那么应该显示两个相连的pseudo terminal slaves:
(/dev/pts/X) <=> (/dev/pts/Y)
with X, Y variable.
(2.) 较长的方式(但或多或少是永久性的):
也许 跨引导持久化 不起作用,因此有必要在重新启动后重复 安装指南 的以下部分:
- 加载模块
sudo depmod
sudo modprobe tty0tty
- 给新串口适当的权限(native terminal devices)
sudo chmod 666 /dev/tnt*
执行后 ls /dev/tnt*
应显示端口列表:
/dev/tnt0 ... /dev/tnt7
2. 测试 tty0tty-连接是否有效(可选):
可以用cat测试连接:
打开一个终端[1]并显示一个pseudo/native终端设备的输出:
- (1.)
cat /dev/pts/X
或 (2.)cat /dev/tnt0
- (1.)
打开另一个终端[2],写入这个pseudo/native终端设备:
- (1.)
echo "message" > /dev/pts/Y
或 (2.)echo "hello" > /dev/tnt1
- (1.)
输出应显示在终端[1]:
message
附加信息:要停止 cat,请按:Ctrl + Z
3. 在 Qt-Project:
中使用 QSerialPort 打开终端设备作为端口在
[projectname].pro
-文件中添加串口-对Qt-specific configuration options的引用:QT += serialport
附加信息: 允许将所有引用放在一行中:
i.e.
QT+= core gui serialport ...
在所需的
[name].h
-文件中添加所需的header file:#include <QtSerialPort/QSerialPort>
添加两个QSerialPort-objects,通过[=]设置终端设备的路径81=] 具有所需的权限(
ReadOnly
、WriteOnly
、ReadWrite
)。示例:std::string tty0ttyPort1 = "/dev/tnt0";// or = "/dev/pts/X std::string tty0ttyPort2 = "/dev/tnt1";// or = "/dev/pts/Y QSerialPort qport1; QSerialPort qport2; qport1.setPortName(QString(tty0ttyPort1.c_str())); bool isOpen1 = qport1.open(qport1.ReadWrite);//Read and Write permission std::cout << "isOpen1: " << isOpen1 << std::endl; qport2.setPortName(QString(tty0ttyPort2.c_str())); bool isOpen2 = qport2.open(qport2.ReadWrite); std::cout << "isOpen2: " << isOpen2 << std::endl;
isOpen1
和 isOpen2
应该是 true
:
isOpen1: 1
isOpen2: 1
附加信息1:可能需要超级用户权限执行编译后的代码:
- 编译代码。
- 打开一个终端然后
cd
到[Path to compiled project folder]/[projectname]
- 以超级用户身份执行
sudo [executable_file]
或运行su
(inadvisable)
附加信息2:如果出现以下警告...:[=86=]
QSocketNotifier: Can only be used with threads started with QThread
...没有 Qt 事件循环 应该总是在 main()
-函数中:
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
//My Testcode (Showed above in section 3.3)
return a.exec();
}
4.使用打开的QSerialPorts:
(1.)无信号:
使用qint64 QIODevice::write(const char * data)
to write from one QSerialPort to another. Use qint64 QIODevice::read(char * data, qint64 maxSize)
or QByteArray QIODevice::readAll()
to read the sended data. Here it is import to know that it is necessary to use bool QIODevice::waitForReadyRead(int msecs)
after sending the data via QIODevice::write()
otherwise it will not work. I recommend also to use bool QIODevice::waitForBytesWritten(int msecs)
。示例:
const char* sendMessage = "myMessage";
std::cout << "sendMessage: " << sendMessage << std::endl;
qport1.write(sendMessage);
qport1.waitForBytesWritten(2000);
qport2.waitForReadyRead(2000);//required
const char* readMessage = qport2.readAll().data();
std::cout << "readMessage: " << readMessage << std::endl;
应该给出输出:
readMessage: myMessage
如果需要读取定义的字节数,请使用 QIODevice::read()
:
const char* readMessage = qport2.read(5);
std::cout << "readMessage: " << readMessage << std::endl;
应该给出输出:
readMessage: myMess
附加信息:要检查有多少字节可用于读取,请使用 qint64 QIODevice::bytesAvailable() const
。示例:
std::cout << qport2.bytesAvailable() << std::endl;
(2.) 有信号:
在 Class 的构造函数中可以连接 private slot to the readyRead()
signal using QObject::connect()
:
Classname::Classname(){
...
QObject::connect(&qport1, SIGNAL(readyRead()), this, SLOT(myPrivateSlotFunction()));
//with "qport1" as sender and "this" as receiver
}
...
Classname::myPrivateSlotFunction(){
...
const char* readMessage = qport1.readAll().data();
...
}