Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

362
Visualizações
Tiempo de espera de lectura de conexión serie PHP

Estoy tratando de resolver algo aquí

Tengo una 'secuencia' para ejecutar a través de un puerto serie (en un RPI).

Tengo un comando PHP supervisado en ejecución en Laravel que se conecta a un corredor MQTT.

Cuando envío un mensaje a ese corredor, el RPI lo recoge y lo procesa. Ahora, tengo un momento en el que espero la interacción del usuario. El problema aquí es que, a veces, el usuario no interactúa con el sistema y el PI sigue "esperando" los datos en serie. Cuando un usuario presiona un botón, obtengo datos en serie, que puedo procesar.

Intenté usar un bucle while (true) {} que lee los datos en serie, pero se detiene repentinamente. Aquí hay un código de ejemplo;

 $configure = new TTYConfigure(); $configure->removeOption("9600"); $configure->setOption("115200"); $this->serialPort = new SerialPort(new SeparatorParser("\n"), $configure); $serialDevice = config('app.device_type') === 'usb' ? '/dev/ttyACM0' : '/dev/ttyAMA0'; $this->serialPort->open($serialDevice); // this is a special one, we add an timeout here of 15 seconds, to prevent that the machine would get stuck. $timeoutStart = time(); $timeout = $timeoutStart + 15; // 15 seconds of timeout. $aborted = false; while (true) { $data2 = $this->serialPort->read(); if (Str::contains($data2, "Whatever I want to check for")) { // Process the data and get out of this loop via a 'break;' statement } // check if 15 seconds have passed, if so, then we want to stop the vend sequence. if (time() >= $timeout) { $this->serialPort->write("C,STOP\n"); // STOP vending $aborted = true; $this->alert("vending sequence stopped"); } }

Cuando coloco registros en el bucle verdadero, veo que se repite, pero de repente deja de hacerlo (apuesto a que es $data2 = $this->serialPort->read(); eso simplemente "detiene" la lectura o sigue leyendo el puerto serie.

Quiero poder eliminar los bucles y hacer una llamada a la API para revertir algunos cambios que ocurrieron antes de esa acción.

es posible? ¿Si es así, cómo?

Paquetes que uso:

  • lumen de laravel
  • PHPMqtt
  • lepiaf\Puerto serie
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Si observa la fuente de lepiaf\SerialPort, encontrará que configura la transmisión en modo sin bloqueo, sin embargo, el método de lectura realiza un ciclo infinito hasta que encuentra el separador. Esto significa que nunca regresará a menos que se reciba el separador y, dependiendo de su configuración, su secuencia de comandos se eliminará una vez que se alcance el tiempo máximo de ejecución de php. Dado que la biblioteca es muy simple, la mejor opción es editar el método de lectura agregando un parámetro de tiempo de espera. Edite el archivo "lepiaf/SerialPort/SerialPort.php", desplácese hacia abajo hasta el método de lectura (línea 107) y cámbielo de la siguiente manera:

 public function read($maxElapsed = 'infinite') { $this->ensureDeviceOpen(); $chars = []; $timeout = $maxElapsed == 'infinite' ? 1.7976931348623E+308 : (microtime(true) + $maxElapsed); do { $char = fread($this->fd, 1); if ($char === '') { if (microtime(true) > $timeout) return false; usleep(100); //Why waste CPU? continue; } $chars[] = $char; } while ($char !== $this->getParser()->getSeparator()); return $this->getParser()->parse($chars); }

Luego, en su código, llame al método como:

 $data2 = $this->serialPort->read(15); if ($data2 === false) { //Timeout occurred } elseif (Str::contains($data2, "Whatever I want to check for")) { //String found } else { //Data received but string not found }
over 4 years ago · Santiago Trujillo Relatório

0

if (Str::contains($data2, "Whatever I want to check for"))

el código anterior es tu culpable.

 $data2 = $this->serialPort->read();

Es posible que no lea toda la cadena a la vez, proporcionará datos cuando llegue al búfer de lectura. por lo tanto, es mejor recopilar datos en un búfer interno y verificar el búfer para su condición.

 $data2 .= $this->serialPort->read();

asegúrese de inicializar data2 antes del bucle.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda