Jump to content
HIT_Braga

Dividir String

Recommended Posts

HIT_Braga

Boas.

Estou desesperado e no final vai ser fácil  :wallbash: mas tenho mesmo de recorrer à vossa preciosa ajuda.

Estou a desenvolver um software para comunicar com um aparelho externo comunicando com o mesmo via RS232.

O protocolo de comunicação está implementado e funciona bem.

O meu problema é o seguinte: Quando inicio o pedido de dados, envio um comando(string :73,5,2:9,1).O aparelho aceita o dito comando enviando um ZERO por cada comando aceite ou o código de erro.

Depois começa a debitar dados na porta com que são recebidos pelo programa. Para parar envio o comando(string :9,0) e ele para, mas ainda assim debita o que estava em buffer.

É isto que recebo:

-----------------

0:0

+0005;+0005;+0006;+0005;+0005;+0005;+0005;+0005;:9,0

:9,0

+0005;+0005;+0005;+0005;+0005;+0005;+0006;+0005;+0006;+0006;+0006;+0005;+0006;+0006;+0005;+0005;0

------------------------

O que eu pedia:

Ou uma maneira de distinguir COMANDO de DADOS RECEBIDOS, ou então uma forma de separar isto de forma a ficar com os dados todos.(o ideal seria DISTINGUIR  :cheesygrin: )

Tenho feito isto para dividir pelo PONTO E VIRGULA:

Sub split()
        Dim str As String
        Dim ctr As Integer
        Dim strArr() As String
        Dim strOK(10000) As String
        Dim count As Integer
        str = rtbDisplay.Text
        strArr = str.Split(";")
        For count = 0 To strArr.Length - 1
            If Microsoft.VisualBasic.Left(strArr(count), 1) = "+" Or Microsoft.VisualBasic.Left(strArr(count), 1) = "-" Then
                ListBox1.Items.Add(Microsoft.VisualBasic.Left(strArr(count), 5))
                strOK(count) = Microsoft.VisualBasic.Left(strArr(count), 5) * 20 / 10000
                ctr = ctr + 1
            Else
                ListBox2.Items.Add(strArr(count))
            End If

        Next
end sub

O problema é que a resposta ao comando inicial fica misturado com o primeiro dado recebido e quando envio o comando de parar fica misturado com o resto(Sublinhado)

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Mas no exemplo que mostraste o que é o comando e o que é o que recebes? Dá lá um exemplo mas especifico e que se entenda melhor.

Share this post


Link to post
Share on other sites
ribeiro55

Sinceramente, não consegui perceber lá muito bem. O exemplo de output que dás é um tanto confuso, dadas as indicações.

Segundo o que percebi, queres descobrir uma forma de identificar os locais onde dás uma ordem de paragem (:9,0).

Podes utilizar o método IndexOf da classe String, que te devolve o índice da primeira ocorrência de dado caractere dentro de um alcance fornecido.

A chave aqui é o facto deste método estar preparado para não só apanhar o índice da primeira ocorrência de um caractere, mas também para apanhar o índice do primeiro caractere de uma dada cadeia de caracteres.

Por exemplo:

"ze::ca:9,0ze::ca:9,0ze::ca".IndexOf(":9,0") 'devolve 6
"ze::ca:9,0ze::ca:9,0ze::ca".IndexOf(":9,0",7) 'devolve 16


Sérgio Ribeiro


"Great coders aren't born. They're compiled and released"
"Expert coders do not need a keyboard. They just throw magnets at the RAM chips"

Share this post


Link to post
Share on other sites
HIT_Braga

Funciona assim:

Por cada comando enviado o aparelho retorna um número (0,1,2,3,4,5)

Ex: envio1 comando ":9,1" recebo 0 / envio 2 comandos ":73,5,2:9,1" recebo 0:0

Quando inicio a medição o aparelho devolve coisa como +0000;+0005;-0001 (sinal e quatro digitos separando cada resposta com :D

No exemplo que coloquei o que aconteçe é que envio o comando ":73,5,2;9,1" que é Iniciar medição continua.

O aparelho devolve 0:0 (aceitou os comandos) e logo de imediato envia os dados de medição (+0000;+0000;)

Depois quando envio ":9,0" Parar medição ele para mas ainda vem o que está em buffer(estou a usar uma class que saquei da net) ou seja vem qualquer coisa como :9,0+0001;+0001;0, que é o comando+buffer+resposta que aceitou comando.

Sei que é um pouco confuso sem ver a coisa a funcionar. Mas desde já obrigado.

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Mas recebes onde? Tens de conseguir detectar o que estás a receber.

De qualquer forma os comandos que envias tem sempre virgulas (parece) e os que recebes não, o que já é um padrão que permite validar o que foi recebido/enviado.

Share this post


Link to post
Share on other sites
HIT_Braga

Boas jpaulino obrigado desde já

Saquei este exemplo http://www.dreamincode.net/forums/topic/37361-serial-port-communication-in-vbnet/ e estou a usar a class deste exemplo.

Todos os dados recebido vao para uma richtextbox.

Lá misturam-se as medições(+0001;-0005) com as respostas aos comandos(0)

já estive a tentar alterar a class de forma a que:

Quando envio um comando a resposta a ele vá para uma textbox diferente, mas sem sucesso  😡

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Só tens de alterar o método comPort_DataReceived(), em vez de fazer:

DisplayData(MessageType.Incoming, ByteToHex(comBuffer) + "" + Environment.NewLine + "")

Escreves tu numa textbox qualquer.

Share this post


Link to post
Share on other sites
HIT_Braga

Não percebi...

Podes especificar melhor.

Ou é algo do género

if comando=true then
txtcomando=msg
else
DisplayData(MessageType.Incoming, msg + "" + Environment.NewLine + "")
end if

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
HIT_Braga

jpaulino mais uma vez Obrigadissssssiiiiimooooo :D

Ainda não está resolvido, já tentei n coisas.

Se pudesses ser mais especifico (quero dizer postar código  😳 ) era optimo.

O tipo de transmissão é TransmissionType.Text e não TransmissionType.Hex.

Sds,

HIT

Detesto chegar a este ponto.... 😡 :wallbash:

Vou  :smoke: antes que delire


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

O método comPort_DataReceived() é o responsável pela recepção da informação da máquina. Se comentares (por exemplo, as chamadas aos métodos DisplayData(), já não irá escrever na textbox.

Share this post


Link to post
Share on other sites
HIT_Braga

Sim até ai eu sei.

Mas o problema continua, fico com valores que não desejo porque são o retorno do aparelho ao comando e não consigo filtrar os gajos.

😡

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Sim até ai eu sei.

Mas o problema continua, fico com valores que não desejo porque são o retorno do aparelho ao comando e não consigo filtrar os gajos.

😡

Sds,

HIT

Como assim? Se tu não utilizares os valores de retorno (não são escritos na richtextbox), não entendo qual é o problema.

Share this post


Link to post
Share on other sites
HIT_Braga

Eu quero os valores +0005;+0006; etc só não quero os valores retornados depois de enviar um comando.

Quando envio o Comando quero que o DISPLAYDATA escreva o retorno num sitio e quando o DATARECEIVED é activado sem eu lhe passar comando escreva em outra.

No dia a dia:

1-Eu digo Bom dia a uma pessoa e ela retorna Aceite

2-Depois essa pessoa tá sempre a repetir BomDia;Bomdia;BomDia;

3-Depois eu digo pára e ela retorna Aceite.

Nas três situações o DataReceived é activado, certo? e nas situações todas o que apareçe lá vai para uma única textbox.

O que eu desejo é quando faço o 1 e 3 o que é retornado vai para uma caixa e quando é o 2 vai para outra.

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Ah, então só tens de verificar se o número de comando enviados + número de comando enviados -1 (isto para verificar o resultado obtido e os dois pontos) e caso o tamanho (lenght) recebido seja < ou igual ao total apurado, então ignoras.

Ou seja:

Total = número de comando enviados + número de comando enviados -1

Se o texto recebido for <= total ignoras.

Não recebes tudo de seguida, certo?

Share this post


Link to post
Share on other sites
HIT_Braga

Boas, tás com muita paciençia para mim :)

Vem tudo seguido, ou seja eu envio o comando ":73,5,2:9,1" e o que vem de imediato é 0:0+0005;-0001;

Já resolvi parte do problema:

Pego nos 3 primeiros caracteres da string recebida e deito-os fora.(não é a solução ideal) até porque as coisas podem mudar.

O ideal seria mesmo Distinguir o que é um comando do que é Dados recebidos de medição, isto porque assim também podia sempre que envio comandos de programação do aparelho, receber o reply dele e verificar se deu erro ou não e alertar o utilizador.

Estou a bater nisto à dia e meio umas 4 horas ou 5horas por dia.

De lembrar não sou programador expert, dou uns toques e aprendo sobretudo  :wallbash: e com ajudas como este MAGNIFICO FORUM. :D

Sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Mas vamos lá ver uma coisa ... não é tão simples como parece, e mesmo que recebas tudo imediatamente não é grave!

Tu envias um comando iniciando por ":", certo? Ou seja, ":73,5,2:9,1" são dois comandos e vais receber no inicio dois código mais um divisor (":") =  2+1. Se fosse ":73,5,2:21,1:73,5,2:9,1", ou seja, 4 comandos, irias receber no inicio da string 4 comando + mais três divisores (":") = "0:0:0:0+0005...".

Se assim for, e se estiver correcto, só tens de usar o método str.SubString(inicio) (ex str.SubString(7))

Share this post


Link to post
Share on other sites
HIT_Braga

Bom dia.

Já percebes-te o core da coisa jpaulino, dai te ocorrerem mais e melhores soluções :thumbsup:

Ainda assim: Qual achas a melhor solução para actualizar o valor em "tempo real", ou seja, envio o comando, tenho o retorno 0:0:0:0+0005;-0001;+0002 etc e pretendo que o valor seja actualizado, isto para desenhar um gráfico em real time, e porque preciso mesmo disso.

sds,

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Algo como isto, tendo sido enviados 4 comandos:

        ' Resultado recebido
        Dim returnValue As String = "0:0:0:0+0005;-0001;+0002"

        ' Verifica apenas o resultado das medições
        Dim total As Integer = returnValue.Count(Function(f) f = ":"c) + 1
        Dim result As String = returnValue.Substring(total + (total - 1))

        ' Mostra os valores das medições
        Dim values As String() = result.Split(";"c)
        For Each val As String In values
            Debug.WriteLine(val)
        Next

Share this post


Link to post
Share on other sites
HIT_Braga

Boas.

Funciona bem, Obrigado.

Ainda tenho um problema. Assim reconho as medições para uma string enorme e depois divido a mesma(a questão colocada foi esta dahhh 😳 ) para um array de strings. Funcione bem e estou a estudar bem a maneira como o fizes-te.

Como posso ter o valor em tempo real, ou seja, não efectuar só no final a divisão da string.

Isto porque tenho um motor que vai se movendo até que o valor lido seja x, então preciso do valor para determinar a posição de inicio e calcular a posição de fim.

Quanto às soluções, não fiquei à espera do código jpaulino, tentei e dei +- a volta à coisa assim:

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
SendData(":73,5,2:9,1")
nComandos = 2
end sub
Public Sub updateTextBox()
        Dim Recebido As String

        If nComandos > 0 Then
            nComandos = nComandos - 1
            ListBox2.Items.Add(Recebido)
        Else
            ValorNewton = Recebido.Substring(0, 5)*20/10000
        End If
end if

até funciona +- pena é que alguns valores se perdem :thumbsup:

Batendo  :wallbash: e  🤔 e  😡 e  😳 com os pedidos de ajuda e com a ajuda do pessoal isto vai ficar  :thumbsup:

Sds

HIT


" Elogios não me elevam, ofensas não me rebaixam, sou o que sou e não o que acham! "

Share this post


Link to post
Share on other sites
jpaulino

Mas tu estás a ir buscar a informação à textbox? Deves utilizar a classe, no método que já te indiquei.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.