java serial-port at-command jssc

java - Al solicitar el puerto com, se devuelve la misma solicitud



serial-port at-command (2)

Ocupado esperando como while (!isReceived) {} producirá un rendimiento horrible, por lo que si mantiene esa estructura, debe cambiar la variable de booleano a mutex / semáforo o algo similar. Pero no debe guardarlo, así que lo menciono solo como referencia.

Comience buscando una copia del estándar de módem V.250 y lea al menos todo el capítulo 5. Eso le enseñará una gran cantidad de manejo básico de comandos AT, como por ejemplo que una línea de comandos AT debe terminar con /r .

El comando AT ^ SCFG es obviamente un comando específico del fabricante, por lo que no tengo una referencia de documentación para eso. La mayoría de los comandos AT relacionados con teléfonos móviles estandarizados por 3GPP se dan en 27.007 , aunque algunos (relacionados con SMS) se dan en 27.005

Como se mencionó al principio, la estructura necesita ser cambiada. Nunca, nunca, nunca, nunca use waitTime , sleep o algo similar para esperar la respuesta de un módem. Es tan útil como patear perros que se interponen en tu camino para que se muevan. Sí, puede ser afortunado y hacer que realmente funcione a veces, pero en algún momento lamentará adoptar ese enfoque ...

El único enfoque confiable es hacer algo similar a

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

donde la función readLine lee uno y un byte del puerto serie hasta que recibe una línea completa terminada con /r/n y luego devuelve esa línea.

Puede consultar el código de atinout para ver un ejemplo de la función is_final_result_code (también puede comparar isFinalResponseError e isFinalResponseSuccess en U300 RIL de ST-Ericsson , aunque tenga en cuenta que CONNECT no es un código de resultado final, es un código de resultado intermedio, por lo que el nombre es FinalResponseSuccess es estrictamente hablando no 100% correcto).

El problema con el envío del comando que se devuelve está relacionado con el módem que hace eco del comando. Esto puede deshabilitarse con el comando ATE pero con una estructura de análisis adecuada como la anterior, esto normalmente no importa porque solo lee el comando echo como una línea que se ignorará.

Estoy tratando de enviar el comando AT a través del puerto COM, pero solo recibí el mismo comando.

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"); } }

Iniciar sesión:

16: 19: 21.910 [main] DEBUG SerialConnections.M234Serial - Crear instancia ..

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

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

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

¿Qué estoy haciendo mal y cómo puedo solucionarlo?


Sugiero las siguientes mejoras a su código:

  • Reemplazar waitTime(System.currentTimeMillis(), 2000); en el escucha del evento con if ( serialPortEvent.isRXCHAR() ) { ...
  • Asegúrese de terminar su comando AT correctamente; generalmente se requiere un salto de línea y / o retorno de carro al final de cada cadena de comando. Consulte la documentación de su dispositivo.
  • Make isReceived volátil , es decir, private volatile boolean isReceived; , si se va a compartir entre diferentes subprocesos.

Para evitar la espera ocupada, puede utilizar primitivas de sincronización estándar de Java, como esta:

private volatile boolean isReceived; private final Object syncObject = new Object(); // ... private void waitForReceived() { synchronized(syncObject) { while( !isReceived ) { syncObject.wait(); } } } private void signalReceived() { synchronized(syncObject) { isReceived = true; syncObject.notifyAll(); } }