当请求com端口返回相同的请求 [英] When requesting com port returns the same request

查看:27
本文介绍了当请求com端口返回相同的请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 COM 端口发送 AT 命令,但只接收到相同的命令.

package SerialConnections;导入 jssc.SerialPort;导入 jssc.SerialPortEvent;导入 jssc.SerialPortEventListener;导入 jssc.SerialPortException;导入 org.slf4j.Logger;导入 org.slf4j.LoggerFactory;导入静态 ru.telemetria.qa.utils.Utilities.waitTime;公共类 M234Serial {私有静态记录器日志 = LoggerFactory.getLogger(M234Serial.class);私有串行端口串行端口;私有字节[] 接收数据;私有布尔值 isReceived;公共 M234Serial() 抛出异常 {serialPort = new SerialPort("COM55");}public void sendCommand() 抛出异常 {打开();字符串命令 = "AT^SCFG?";serialPort.writeBytes(command.getBytes());log.debug("发送请求:" + command);while (!isReceived) {}关闭();}private void open() 抛出异常 {串口.openPort();serialPort.setParams(SerialPort.BAUDRATE_115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);serialPort.addEventListener(new SerialPortEventListener() {@覆盖public void serialEvent(SerialPortEvent serialPortEvent) {尝试 {等待时间(System.currentTimeMillis(), 2000);receivedData = serialPort.readBytes();log.debug("收到消息:" + StringUtils.asciiToString(receivedData));isReceived = true;serialPort.removeEventListener();} catch (SerialPortException spe) {spe.printStackTrace();}}});}私有无效关闭()抛出异常{serialPort.closePort();}public static void main(String[] args) 抛出异常 {log.debug("创建实例..");M234Serial 串行 = 新 M234Serial();串行发送命令();log.debug("结束");}}

日志:

16:19:21.910 [main] DEBUG SerialConnections.M234Serial - 创建实例..

16:19:21.974 [main] DEBUG SerialConnections.M234Serial - 发送请求:AT^SCFG?

16:19:23.976 [EventThread COM55] DEBUG SerialConnections.M234Serial - 收到消息:AT^SCFG?

16:19:23.977 [main] DEBUG SerialConnections.M234Serial - 结束

我做错了什么,我该如何解决?

解决方案

while (!isReceived) {} 这样的忙等待会产生可怕的性能,因此如果保持该结构,您应该将变量从布尔值到互斥锁/信号量或类似的东西.但是你不应该保留它,所以我提这个仅供参考.

<小时>

首先获取 V.250 的副本 调制解调器标准并至少阅读第 5 章的全部内容.这将教您许多基本的 AT 命令处理,例如,AT 命令行应以 终止.

AT^SCFG 命令显然是专有的制造商特定命令,因此我没有相关的文档参考.大多数由 3GPP 标准化的手机相关 AT 命令在 27.007 中给出,尽管在 27.005 中给出了一些(与短信相关的)>

正如开头提到的,结构需要改变.你应该永远,永远,永远,永远使用waitTimesleep或类似的东西来等待来自调制解调器的响应.这就像踢挡你路的狗一样有用,以便让它们移动.是的,你可能很幸运,有时它确实有效,但在某些时候你会后悔采取这种方法......

唯一可靠的方法是做类似的事情

serialPort.openPort();...//开始发送 AT^SCFG?serialPort.writeBytes("AT^SCFG?
");做 {line = readLine(serialPort);} while (!is_final_result_code(line))//发送 AT^SCFG?命令完成(成功与否)...serialPort.closePort();

其中 readLine 函数从串行端口读取一个又一个字节,直到它接收到以 结尾的完整行,然后返回该行.

你可以查看atinout的代码对于 is_final_result_code 函数的示例(您也可以与 ST-Ericsson 的 U300 RIL,虽然请注意 CONNECT 不是最终结果代码,它是中间结果码,所以严格来说名字是FinalResponseSuccess并不是100%正确).

<小时>

接收回命令发送的问题与调制解调器回显命令有关.这可以使用 ATE 命令禁用,但使用像上面这样的正确解析结构这通常无关紧要,因为您只是将回显命令读取为将被忽略的行.

I`m trying to send AT-command via COM-port, but reseived only the same command.

package SerialConnections;

import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static ru.telemetria.qa.utils.Utilities.waitTime;

public class M234Serial {
    private static Logger log = LoggerFactory.getLogger(M234Serial.class);
    private SerialPort serialPort;
    private byte[] receivedData;
    private boolean isReceived;

    public M234Serial() throws Exception {

        serialPort = new SerialPort("COM55");
    }

    public void sendCommand() throws Exception {
        open();

        String command = "AT^SCFG?";
        serialPort.writeBytes(command.getBytes());
        log.debug("Send request: " + command);

        while (!isReceived) {}

        close();
    }

    private void open() throws Exception {
        serialPort.openPort();
        serialPort.setParams(SerialPort.BAUDRATE_115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        serialPort.addEventListener(new SerialPortEventListener() {
            @Override
            public void serialEvent(SerialPortEvent serialPortEvent) {
                try {
                    waitTime(System.currentTimeMillis(), 2000);
                    receivedData = serialPort.readBytes();
                    log.debug("Received message: " + StringUtils.asciiToString(receivedData));
                    isReceived = true;
                    serialPort.removeEventListener();
                } catch (SerialPortException spe) {
                    spe.printStackTrace();
                }
            }
        });
    }

    private void close() throws Exception {
        serialPort.closePort();
    }

    public static void main(String[] args) throws Exception {
        log.debug("Create instance..");
        M234Serial serial = new M234Serial();
        serial.sendCommand();
        log.debug("End");
    }
}

Log:

16:19:21.910 [main] DEBUG SerialConnections.M234Serial - Create instance..

16:19:21.974 [main] DEBUG SerialConnections.M234Serial -Send request: AT^SCFG?

16:19:23.976 [EventThread COM55] DEBUG SerialConnections.M234Serial - Received message: AT^SCFG?

16:19:23.977 [main] DEBUG SerialConnections.M234Serial - End

What am I doing wrong and how can I fix it?

解决方案

Busy waiting like while (!isReceived) {} will yield horrible performance so if keeping that structure you should change the variable from a boolean to a mutex/semaphore or something similar. But you should not keep it, so I mention this just for reference.


Start by fetching a copy of the V.250 modem standard and read at least all of chapter 5. That will teach you a lot of basic AT command handling, like for instance that an AT command line should be terminated with .

The AT^SCFG command is obviously a proprietary manufacturer specific command so I do not have a documentation reference for that. Most mobile phone related AT commands standardized by 3GPP are given in 27.007, although some (SMS related) are given in 27.005

As mentioned at the beginning the structure needs to be changed. You should never, never, never, ever use waitTime, sleep or anything similar to wait for response from a modem. It's as useful as kicking dogs that stand in your way in order to get them to move. Yes you might be lucky and have it actually work sometimes, but at some point you will be sorry for taking that approach...

The only reliably approach is to do something similar to

serialPort.openPort();
...
// start sending AT^SCFG?
serialPort.writeBytes("AT^SCFG?
");
do {
    line = readLine(serialPort);
} while (! is_final_result_code(line))
// Sending of AT^SCFG? command finished (successfully or not)
...
serialPort.closePort();

where the readLine function reads one and one byte from the serial port until it has received a complete line terminated with and then returns that line.

You can look at the code for atinout for an example for the is_final_result_code function (you can also compare to isFinalResponseError and isFinalResponseSuccess in ST-Ericsson's U300 RIL, although note that CONNECT is not a final result code, it is an intermediate result code, so the name isFinalResponseSuccess is strictly speaking not 100% correct).


The issue with the command send being received back is related to the modem echoing the command. This can be disabled with the ATE command but with a proper parsing structure like above this normally does not matter because you just read the echoed command as a line that will be ignored.

这篇关于当请求com端口返回相同的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆