Linux串口监听器和解释器?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12990702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linux serial port listener and interpreter?
提问by Matt
I'm using a serial device for a project, and what I'm trying to accomplish PC side, is listening for a command sent by the serial device, interpreting the query, running some code depending on the query, and transmitting back the result.
我正在为一个项目使用串行设备,而我正在尝试在 PC 端完成的是侦听串行设备发送的命令,解释查询,根据查询运行一些代码,并将结果传回.
To be honest I tried out using PHP as the listener, and it works, unfortunately the infinite loop required to make the script act as a receiver, loads the CPU to 25%. So it's not really the best option.
老实说,我尝试使用 PHP 作为侦听器,但它可以工作,不幸的是,使脚本充当接收器所需的无限循环将 CPU 加载到 25%。所以这并不是最好的选择。
I'm using cygwin right now, I'd like to create a bash script using linux native commands.
我现在正在使用 cygwin,我想使用 linux 本机命令创建一个 bash 脚本。
I can receive data by using:
我可以使用以下方法接收数据:
cat /dev/ttyS2
And send a response with:
并发送响应:
echo "command to send" > /dev/ttyS2
My question is, how do I make an automated listener to be able to receive and send data? The main issue I have, is actually how do I stop the cat /dev/ttyS2command once information was received, put it into a variable which then I could compare with a switch, or a series of if else then blocks. Afterwards send back a response and start the cycle all over again?
我的问题是,如何使自动侦听器能够接收和发送数据?我遇到的主要问题实际上是如何在收到信息后停止cat /dev/ttyS2命令,将其放入一个变量中,然后我可以将其与开关或一系列 if else then 进行比较。然后发回响应并重新开始循环?
Thanks
谢谢
采纳答案by rici
Is this not what you're looking for?
这不是你要找的吗?
while read -r line < /dev/ttyS2; do
# $line is the line read, do something with it
echo $result > /dev/ttyS2
done
回答by mvp
If you use right tools, it is possible to actually have your CPU usage to be exactly 0 when your device does not have any output.
如果您使用正确的工具,当您的设备没有任何输出时,您的 CPU 使用率实际上可能正好为 0。
To accomplish this, you should use some higher level language (Perl, Python, C/C++ would do, but not bash) and use select loop on top of file handle of your serial device. This is an example for Perl http://perldoc.perl.org/IO/Select.html, but you can use any other language as long as it has support for select() syscall.
为此,您应该使用一些高级语言(Perl、Python、C/C++ 可以,但不能使用 bash)并在串行设备的文件句柄之上使用 select 循环。这是 Perl http://perldoc.perl.org/IO/Select.html 的一个示例,但您可以使用任何其他语言,只要它支持 select() 系统调用。
回答by Aniket Inge
To remain fairly system independent, use a cross platform programming language: like Python, use a cross platform serial library like : pySerialand do the processing inside a script. I have used pySerial and I could run the script cross platform with almost no changes in source code. By using BASH you're limiting yourself a fair little.
为了保持与系统相当的独立性,请使用跨平台编程语言:如Python,使用跨平台串行库,如:pySerial并在脚本内进行处理。我使用过 pySerial 并且我可以跨平台运行脚本,而源代码几乎没有变化。通过使用 BASH,您对自己的限制很小。
回答by ulitosCoder
I would recommend to use C/C++ with Qt 5.1.1, it's really easy and if you are familiar with the framework it'll be a piece of cake!!! Hereyou can find more information and heremore helpful examples, give it a try, it's really pain free!! Also you can develop on win and then port your code to linux...straight forward.
我建议在 Qt 5.1.1 中使用 C/C++,这真的很容易,如果您熟悉该框架,那将是小菜一碟!!! 在这里你可以找到更多的信息,这里更多的有用的例子,给它一个尝试,它真的无痛苦!你也可以在 win 上开发,然后将你的代码移植到 linux ......直接。
Declare an object like this:
像这样声明一个对象:
QSerialPort mPort; //remember to #include <QtSerialPort/QSerialPort>
//also add QT += serialport to your .pro file
Then add this code:
然后添加以下代码:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
connect(this->pushButton,SIGNAL(clicked()),this,SLOT(sendData()));
mPort.setPortName("ttyS0");
mPort.setBaudRate(QSerialPort::Baud115200);
mPort.setParity(QSerialPort::EvenParity);
if(!mPort.open(QSerialPort::ReadWrite))
{
this->label->setText(tr("unable to open port, %1").arg(mPort.error()));
}
connect(&(this->mPort),SIGNAL(readyRead()),this,SLOT(readData()));
}
void MainWindow::sendData()
{
QByteArray data = lineEdit->text().toLatin1();
if(mPort.isOpen())
{
mPort.write(data);
}
else
{
this->label->setText(tr("port closed %1").arg( mPort.error()));
}
}
void MainWindow::readData()
{
QString newData;
int bread=0;
while(bread < mPort.bytesAvailable() ){
newData += mPort.readAll();
bread++;
}
this->textEdit->insertPlainText("\n" + newData);
}