.NET Serial ajuda Porto necessário, primeiramente com os dados recebidos em vários “pacotes”

StackOverflow https://stackoverflow.com/questions/891475

  •  23-08-2019
  •  | 
  •  

Pergunta

Eu sou muito novo para o envio de dados através de uma porta serial através de .net e tenho notado após a implementação de uma contrapartida TCP que eu não iria ficar assim tão fácil com série!

Então, para começar no topo, estou quase lá com minha implementação de comunicação bi-direcional de série Estou apenas ficar preso em algumas coisas: -

  1. Meu lê está sendo dividido em várias mensagens ou recebido como uma resposta fragmentada sobre a porta COM e eu não sei o que as configurações que eu poderia precisar, ou como devo escrever o código diferente para corrigir isso. O que poderia causar isso? Estou inspecionando a mensagem em um ponto de interrupção na SerialPort_DataReceived.

Basicamente, os dados devem ser enviados como:

01: LS|DA090521|TI111043|q
02: PS|RN102|PTC|TA1040000|P#0|DA090521|TI111429|j

mas ele está sendo dividido (em posições aleatórias em cada leitura solicitado)

01: LS|DA090521|TI111
02: 043|q
03: PS|RN102|PTC|TA1
04: 0000|P#0|DA090521|TI111429|j

- Pergunta 1 foi respondida, graças Chris W. e outros! Agora tenho a mensagem que esperar sendo construído a partir de fragmentos progressivamente (olhando para fora para STX, {corpo msg}, ETX) e, em seguida, uma ação realizada quando a mensagem foi completamente construído, e tem que vai com uma fila de thread-safe, muito feliz .

. 2. Eu estou recebendo um "|" símbolo através da minha leitura quase cada ciclo, isso é devido a um comando que tenho posto errada de alguma forma, um artefato de comunicação serial, ou algo que o dispositivo está me enviando? (Eu não penso assim, porém, como conectividade Hyperterminal revela este personagem não está sendo enviado a uma).

. 3. Pode confirmar que estou lendo e escrevendo dados corretamente nos respectivos métodos.

Obrigado rapazes por olhar para as minhas duas outras questões também.

código relevante da seguinte forma:

...
    //                          COM3,    9600,     None,   8,        One
    SerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBits);
    if (SerialPort.IsOpen) SerialPort.Close();
    // SerialPort.RtsEnable = true; // Request-to-send
    // SerialPort.DtrEnable = true; // Data-terminal-ready
    SerialPort.ReadTimeout = 150; // tried this, but didn't help
    SerialPort.WriteTimeout = 150; // tried this, but didn't help
    SerialPort.Open();

    SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
}

void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // Process received data
    SerialPort sp = (SerialPort)sender;
    byte[] buffer = new byte[sp.BytesToRead];
    int bytesRead = sp.Read(buffer, 0, buffer.Length);

    // message has successfully been received
    message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
}

public bool SendMessage(string text)
{
    // Only send message if a client is connected
    if (SerialPort != null && SerialPort.IsOpen)
    {
        byte[] buffer = Encoding.ASCII.GetBytes(text);
        SerialPort.Write(buffer, 0, buffer.Length);
    }
}
Foi útil?

Solução

Meu lê está sendo dividido em várias mensagens

Esta é, espera, o comportamento inevitável normal. Pode acontecer com os dados-sobre-TCP também. Para a interface serial é apenas um fluxo interminável de bytes. É responsabilidade do aplicativo para reembalar os bytes em pacotes.

Se a localização das fronteiras do pacote é importante, e se você não pode dizer onde os limites de pacote é suposto ser de olhar para os dados recebidos, então você pode precisar de repensar o formato dos dados para que você pode dizer onde as fronteiras pacotes são:.

Estou recebendo um "|" símbolo através da minha leitura quase cada ciclo

O que é o valor hexadecimal desse personagem? Veja se definir a propriedade Handshake para XOnXOff ou RequestToSendXOnXOff melhora a situação.

Outras dicas

No nível mais baixo da porta serial pode decidir quando acionar os dados recebidos evento. Ele pode decidir fazer isso antes de o pacote "completo" chegou. Mas, parece que você tem um personagem terminador em seu conjunto de dados esperado. Se assim você pode fazer o seguinte (note eu mudei sua atribuição SerialPort à confusão sintaxe evitar:

        p = new SerialPort(PortName, BaudRate, Prty, DataBits, SBits);
        p.NewLine = Terminator;

onde Terminator é uma string contendo o seu personagem (s) de terminação. Então você pode usar SerialPort.ReadLine () (e SerialPort.WriteLine () se isso se aplica). Isto poderia pelo menos ajudar com a sua primeira edição.

Eu fiz um monte de Win32 programação porta serial, mas apenas um pouco com .NET, assim que tomar o meu conselho com um grão de sal.

Meu lê está sendo dividido em várias mensagens ou recebido como uma resposta fragmentada sobre a porta COM e eu não sei o que as configurações que eu poderia precisar, ou como devo escrever o código diferente para corrigir isso.

Como já foi dito, isso é perfeitamente normal. Dependendo do tipo de equipamento está no lado do DCE, você pode ter que fazer reembalagem si mesmo. Eu não tenho certeza que tipo de equipamento que você está-se agarrado ao então eu realmente não posso dizer muito mais.

Se você quiser obter mais dados, você pode tentar o seguinte:

  • ajustando a propriedade System.Int32 ReceivedBytesThreshold
  • usando E / S síncrona e especificar um número fixo de bytes para ler em vez de recepção baseada em eventos

Estou recebendo um "|" símbolo através da minha leitura quase cada ciclo, é isso devido a um comando que eu tenho set erradamente, de alguma forma, um artefato da série comunicação, ou algo do dispositivo está me enviando? (Acho que não embora, como conectividade Hyperterminal revela este personagem não está sendo enviados continuamente.)

Se você está curioso sobre o que está acontecendo em cima da linha, veja Portmon da SysInternals , um aplicativo gratuito que vai bisbilhotar a porta COM, enquanto você está transferindo dados sobre a linha. Parece técnico, mas realmente você só tem que olhar para os comandos IRP_MJ_WRITE e IRP_MJ_READ, e na linha de você verá o tamanho em bytes e os dados enviados através do fio. Com isso, você deve ser capaz de dizer se o problema é o objeto .NET SerialPort ou se o dispositivo está realmente enviando "|" sobre a linha.

Pode confirmar que estou lendo e gravar dados corretamente na respectivos métodos.

Parece apropriado para o método baseado em caso de recebimento de dados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top