Rotina de time out em C#

Programação C em geral

Moderadores: 51, guest2003

Rotina de time out em C#

Mensagempor Eduardo Augusto » 25 Jul 2014 23:18

Eae pessoal, essa semana estive desenvolvendo um aplicativo que se conecta a dispositivos em 485 half duplex, os configura e imprime um relatório e etiqueta da configuração.
Ta funcionando, mas ta funcionando mais ou menos...
Queria conseguir implementar uma rotina de time out entre um requeste de dados e uma resposta do dispositivo, por exemplo:
Código: Selecionar todos
 private void button1_Click(object sender, EventArgs e)
        {
                     byte[] novo_endereco = new byte[8]{0xFF, 0xFF, 0xFF, 0xA5, 255, 0x61,byte_endereco[0], 0x00 };
                     serialPort1.Write(novo_endereco, 0, novo_endereco.Length);
        }


Ao clicar no button1 eu transmito um frame de dados pro dispositivo referente a uma alteração de endereço dele.
No entanto se não houver resposta do dispositivo meu programa não faz nada. :cry:
o time out da comunicação é 100ms e há uma situações onde em um evento tenho que enviar 3 frames de dados... tenho que gerar time out pros 3 envios???
pensei em fazer algo bem simples, como um thread.sleep(1), e testar 100 vezes se obtive resposta, mas não sei se isso é o certo....
Não to conseguindo imaginar uma rotina de time out em c#, pensei em usar um timer1 do c# mas não sei se ia ficar bom...
Não é possível dormir com todas mulheres do mundo, mas deve-se fazer o esforço.
Avatar do usuário
Eduardo Augusto
Byte
 
Mensagens: 105
Registrado em: 03 Mar 2014 08:57
Localização: São Paulo, SP

Re: Rotina de time out em C#

Mensagempor andre_luis » 26 Jul 2014 06:02

A comunicação serial no mais baixo nível, em princípio não exige resposta do destinatário, podendo ser disparado o envio do pacote completo de uma só vez, se quizer. Pode ser que tenha algo mais aí embotido no programa que esteja fazendo isso.

Não poderia estar na configuração da porta, algum bit de controle de fluxo ativado ?




+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Rotina de time out em C#

Mensagempor xultz » 28 Jul 2014 10:40

Existe um método do objeto serialPort que você especifica o timeout de leitura, em milisegundos.
Por exemplo, supondo que você espera uma resposta de 1 byte, poderia fazer algo do tipo:

Código: Selecionar todos
byte[] novo_endereco = new byte[8]{ 0xFF, 0xFF, 0xFF, 0xA5, 255, 0x61,byte_endereco[0], 0x00 };
byte leitura = 0;

serialPort1.Write(novo_endereco, 0, novo_endereco.Length);

serialPort.ReadTimeout = 100; //Especifica timeout de 100ms

try
{
    leitura = (byte)serialPort.ReadByte();
    // Aqui verifica se o byte lido está certo e faz o que deve fazer se estiver tudo ok
}
catch
{
    MessageBox.Show("Sem Resposta");
}
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Re: Rotina de time out em C#

Mensagempor Eduardo Augusto » 28 Jul 2014 11:01

Xultz,
Acho que era isso que estava faltando no meu código, eu tinha colocado essa instrução de timeout de 100 ms mas eu nunca entendi oque ela fazia ou como ela funcionava kkkk :)
Pelo que entendi, devo tratar os bytes de resposta na mesma seção de código de envio com um simples try() catch();
Vou tentar essa rotina, Obrigado!!!
Não é possível dormir com todas mulheres do mundo, mas deve-se fazer o esforço.
Avatar do usuário
Eduardo Augusto
Byte
 
Mensagens: 105
Registrado em: 03 Mar 2014 08:57
Localização: São Paulo, SP

Re: Rotina de time out em C#

Mensagempor Red Neck Guy » 28 Jul 2014 11:18

Uma forma mais legal de fazer é criar uma thread para implementar a comunicação e criar uma janela de progresso.
Aí você fica enviando mensagens através de uma fila sincronizada e atualizando o progressbar - por exemplo.
É bem simples, a única coisa que precisa saber é que não é permitido a uma thread diferente acessar os controles da outra, sendo assim, tu irá precisa utilizar o Invoke.
ASM51 descanse em paz!
Avatar do usuário
Red Neck Guy
Dword
 
Mensagens: 1968
Registrado em: 12 Out 2006 22:24

Re: Rotina de time out em C#

Mensagempor Eduardo Augusto » 28 Jul 2014 11:30

Eu uso uma thread diferente para ler os dados da porta serial pelo evento serialPort data received.
Código: Selecionar todos
delegate void setachamadas(string data); // delegate serial para escrever texto
       
        private void setatexto(string data)
        {
            if (this.textBox1.InvokeRequired)
            {
                setachamadas d = new setachamadas(setatexto);
                this.Invoke(d, new object[] { data });
            }
            else
            {
                this.textBox1.Text += data;         
            }
        }
private void serialPort1_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
        {
            btData = new byte[serialPort1.BytesToRead];
            serialPort1.Read(btData, 0, btData.Length);
            string data = string.Empty;
            data = Encoding.UTF8.GetString(btData);
            setatexto(data);                           
        }

O problema é esse bendito time_out de comunicação... Alguns frames que eu envio demoram cerca de 45ms para serem respondidos... E algumas situações, como inicialização do aplicativo, eu peço 3 frames de dados, versão do equipamento, modelo do equipamento e diagnóstico dele... tudo de uma tacada só.
Oque o Xults comento é oque eu melhor entendi.
Não é possível dormir com todas mulheres do mundo, mas deve-se fazer o esforço.
Avatar do usuário
Eduardo Augusto
Byte
 
Mensagens: 105
Registrado em: 03 Mar 2014 08:57
Localização: São Paulo, SP


Voltar para Visual C++/C/C++/C#

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x