Ir para conteúdo
  • Cadastre-se

dev botao

Leitura de porta serial (COM ou LPT) com PHP ou CMD


Ver Solução Respondido por Fernando Rafael,
  • Este tópico foi criado há 1470 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Boa tarde, estou tendo problemas com leitura de portas com php, segue o código:

exec('MODE COM1:9600,n,8,1'); //seta configuração na porta COM

$fp=fopen("COM1","r+b");

if(!$fp) {
    echo("Erro ao abrir a porta com1");
    exit;
} else {    
    echo("COM1 aberta <br>");
}

fwrite($fp,Chr(5));  //escrevendo valor na porta

sleep(1); //pausa para retorno dos dados

echo (fgets($fp));

fclose($fp);

já tentei  colocar:

fopen("COM1", "r+b");

fopen("COM1", "r+t");

fopen("COM1", "r");

fopen("COM1", "w+");

fopen("COM1", "r+");

 

Consigo facilmente escrever na mesma, mas quando uso algum comando de leitura (fread($fp);  ou fgets($fp); ) a mesma trava, também tentei limitar o tamanho da leitura (fread($fp, 1024);  ou fgets($fp, 1024); ) mas sem sucesso também...

Se alguém tiver uma solução com CMD também ajudaria já que posso executar por comando "exec" do PHP.

Nos tutoriais que vejo na internet, muitos que tinham esse problema, conseguiram no Linux, pois estavam relacionados a permissão de usuários, já no Windows não achei nada sobre...

E sim, sei que muitos vão indicar que se use Delphi, C#, Java e etc... mas preciso mesmo que seja em PHP ou em qualquer linha de comando...

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Não sou programador PHP...

mas será que não há nada para ser lido ?

Pode ser que o método ' fread ' esteja esperando algum buffer chegar até atingir um timeOut, que deveria ser previamente configurado...

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

Achei um comando em php que seta um timeOut "stream_set_timeout($fp, 10);", mas não funcionou, o PHP continua rodando infinitamente...

Achei uns comandos em Powershell de leitura de serial, o mesmo também ficou rodando infinitamente, mas nesse caso eu encontrei um comando que setava um timeout que funcionou, mas não deu retorno...

Você pode ter razão em não estar retornando nada, mas estou usando um simulador de balança (filizola/toledo) juntamente com um simulador de porta serial, testo a conexão com um programa de monitoramento de porta ou com o PC Scale da Filizola, e neles eu tenho retorno....

OBS: o simulador de balança tem um botão que envia dados para a porta, sem a necessidade de escrever na porta para que a mesma retorne algo.

 

segue o código em powershell para quem quiser avaliar:

$port= new-Object System.IO.Ports.SerialPort COM6,9600,None,8,One

$port.ReadTimeout = 10000

$port.Open()

while($myinput = $port.ReadLine())
{
$myinput
}

$port.Close()

 

Link para o comentário
Compartilhar em outros sites

  • 3 meses depois ...
  • Solution

Vendo em muitos Fóruns, notei que o PHP tem bloqueios para leitura de portas seriais no Windows, sendo necessário configurar ou usar DLL (não encontrei tutoriais do tipo).

Bem...  Resolvi da forma mais aceitável diante da situação (ambiente Windows):

Fiz um programa em JAVA (exportado em um arquivo .jar) que recebe os parâmetros da porta serial e efetua a leitura da mesma. Mas fiz de uma forma mais diretamente "ligada" ao PHP. Sabendo que o arquivo .jar pode ser executado pelo CMD passando até mesmo parâmetros por linha de comando, fiz com que o PHP acionasse esse arquivo pelo comando "exec" ou "passthru" e depois tratei o retorno no próprio PHP, acredito que dessa forma é bem melhor do que ficar criando arquivos .txt para ficar lendo depois...

Então, sem mais delongas segue os fontes (JAVA e PHP):

PHP:

$comando_cmd="java -jar ler_serial.jar 9600 8 1 0 COM3 ENQ"; //Arquivo seguido dos parâmetros que serão capturados pelo arquivo .jar (separados por espaços).  OBS: só coloquei parâmetros pois não quis criar um arquivo .jar para cada tipo de porta ou configurações e comandos (ENQ por exemplo serve apenas para saber qual comando será usando no arquivo .jar, deve haver alguma forma de executar os comandos no JAVA que estejam armazenados em uma variável, eliminando assim os "if" e "else" para cada instrução dentro do arquivo .jar).

echo passthru($comando_cmd); //exibe o retorno.

 

JAVA:

import jssc.SerialPort; //Para funcionar é preciso adicionar no projeto uma biblioteca (usei essa: jSSC-2.7.0-Release.zip), vale pesquisar como adicionar, é fácil
import jssc.SerialPortException; //Para funcionar é preciso adicionar no projeto uma biblioteca (usei essa: jSSC-2.7.0-Release.zip), vale pesquisar como adicionar, é fácil

//Fonte sobre essa biblioteca: http://nakalabs.herokuapp.com/articles/arduinoAndJava.html

public class Main {
    
    public static void main(String[] args) throws InterruptedException {
   

         //Parametros estáticos, caso não usem os valores passados por linha de comando
        /*
        int BAUD_RATE =  9600;
        int DATA_BITS = 8;
        int STOP_BITS = 1;
        int PARITY    = 0;
        String SERIAL_PORT = "COM2";
        */
        
        //Armazena os parâmetros nas variáveis
        int BAUD_RATE =  Integer.parseInt(args[0]); //9600
        int DATA_BITS = Integer.parseInt(args[1]); //8
        int STOP_BITS = Integer.parseInt(args[2]); //1
        int PARITY    = Integer.parseInt(args[3]); //0
        String SERIAL_PORT = args[4]; //COM3
        
        String COMANDO ="ENQ"; //Comando inicial, caso nada seja passado como parametro, vai executar um ENQ (muito comum em comunicação serial)
        
        if(args[5].equals("ENQ")){ //Serve apenas para comparar o parâmetro passado e  executar algum comando previamente programado
            
            COMANDO =  ""+(char)5; //Coloquei ""+ (aspas dupla concatenada) só para aceitar como String, pois nem todo comando é do tipo (char) no meu caso
        }
        
        else if(args[5].equals("BEL")){ //Outro comando, e assim vai...
            
            COMANDO =  ""+(char)7+"p";  //Salientando que esses comandos são das minhas necessidades, isso vai depender do comando que o dispositivo esteja aguardando para retornar algo...
        }    
    
        SerialPort serialPort = new SerialPort(SERIAL_PORT);
        
        try {
            //Os comandos "exec" e "passthru" capturam esses retornos, basta exibilos ao seu favor...
            System.out.println("Porta aberta: " + serialPort.openPort());
            System.out.println("Parametros configurados: " + serialPort.setParams(BAUD_RATE, DATA_BITS, STOP_BITS, PARITY));
            System.out.println("Enviado mensagem: " + serialPort.writeString(""+COMANDO+"")); //Aqui ele escreve o comando na porta
            Thread.sleep(1000); //Aguarda 1 segundo para ler a porta
            //System.out.println("Retorno: " + serialPort.readString()); //Retorno da porta em String
            System.out.println("Retorno: " + serialPort.readHexString("")); //Retorno da porta em Hexadecimal, Com "" (aspas dupla) no parâmetro, significa que não haverá espaços entre os valores retornados ou colocando qualquer caractere, servirá como separador.
            System.out.println("Porta fechada: " + serialPort.closePort());
        
        }
        catch (SerialPortException ex){
            System.out.println(ex);
        }
    }
}

Postei essa mesma solução no ACBR, Imaster e Devmedia. nos que suportarem anexos, colocarei também a biblioteca do JAVA zipada.

Não sou bom em programação Java, caso alguém tenha melhorias para o código, ficarei muito grato... Vale visitar meu site: www.sisnorg.com (ainda em desenvolvimento, mas funcional para um possível contato comigo).

Abraços a todos que me ajudaram nos mais diversos fóruns... 

PORTA SERIAL JAVA jSSC-2.7.0-Release.zip

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 1470 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.