Autore Topic: interpretazione stringa letta da seriale  (Letto 857 volte)

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
interpretazione stringa letta da seriale
« il: 21 Ottobre 2021, 14:53:29 »
Sarà banale, ma non riesco a capire cosa devo fare per "convertire" la stringa che ho e ottenere il dato che voglio.
Ho questo codice:

Codice: [Seleziona]
Dim strDaInviare2 As String = "I2CR" & Chr(30) & Chr(1)
SComm.Begin()
Write #SComm, strDaInviare2
SComm.Send() 
Sleep intervSleep
     
Dim valZoom As String = ""
Try Read #SComm, valZoom, Lof(SComm)
valZoom = Replace(valZoom, "\r", "")

a questo punto, in debug, leggo che "valZoom" contiene \x01 (oppure \x02 oppure \x03)

Qual è il modo corretto per leggere il valore?
Se ho ben capito, "\x" indica che le due successive cifre sono esadecimali (nello specifico, 01, 02 e 03 coincidono in entrambi i sistemi).
Come trasformarle? mi sta bene sia ottenere String che Integer...
lo so, sarà banalissimo, ma vorrei trovare il modo più corretto (e già ho dubbi su quanto ho scritto, tipo il "replace" utilizzato, reperito in rete).

Grazie




*********** EDIT ************
Per adesso avrei risolto così:

Codice: [Seleziona]
Dim valZoom As String = ""
      Try Read #SComm, valZoom, Lof(SComm)
      valZoom = Replace(valZoom, "\r", "")
      Select Case valZoom
        Case "\x01"
          valZoom = "1"
        Case "\x02"
          valZoom = "2"
        Case "\x03"
          valZoom = "3"
      End Select
« Ultima modifica: 21 Ottobre 2021, 15:15:22 da nino83 »

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.720
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #1 il: 21 Ottobre 2021, 15:33:58 »
Nel tuo caso suggerirei l'uso della funzione nativa Asc():

   https://gambaswiki.org/wiki/lang/asc?l=it
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #2 il: 21 Ottobre 2021, 15:50:39 »
vuott ma Asc() non prende una stringa? io cosa ho?  ???

cioè adesso mi va bene perchè 01 02 e 03 coincidono... ma se avessi "3D"?
farei convertire prima il 3 e poi la D per concatenarle?
penso sia sbagliato.  A quel punto ciò che dovrei leggere sarebbe altro...
e lo so, nessuno può darmi la risposta, perchè penso dipenda da come lavora l'arduino.... che cose intorcinate!

Trovo molto astruso ragionare sull'invio nella duplice veste stringa/valore_numerico... da mal di testa!

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.720
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #3 il: 21 Ottobre 2021, 22:28:22 »
cioè adesso mi va bene perchè 01 02 e 03 coincidono... ma se avessi "3D"?
farei convertire prima il 3 e poi la D per concatenarle?
Dunque provando a ricapitolare.
Dalla lettura della porta seriale tu ottieni stampati nella console/Terminale in rappresentazione grafica e testuale, ad esempio, i seguenti caratteri: \x3D
In via generale e teorica questa rappresentazione in formato stringa rappresenta, come già hai tu precisato, un valore esadecimale della dimensione di un byte.
A te, però, quella lettura restituisce in vero non un solo valore-byte (espresso in quella modalità), bensì un testo formato da 4 singoli valori-byte, i quali - sempre restando nel mio esempio - risultano così essere:
  &5C &78 &33 &64    (qui trascritti in esadecimale)
Pertanto, al fine di ottenere il valore numerico reale (costituito da un solo byte), da un lato devi non prendere in considerazione i primi due valori, corrispondenti ai caratteri "\x", dall'altro devi "unire" gli ultimi due caratteri in modo da riprodurre coerentemente il reale valore numerico che il dispositivo esterno ha inteso trasmettere attraverso il collegamento con la tua porta seriale.

Così, raccogliendo quei quattro valori-byte, costituenti il testo "\xnn", propongo in modo schematico-didattico questa soluzione teorica:
Codice: [Seleziona]
Dim s As String
Dim i As Integer
......
......
Read #portaseriale, s, 4   ' Impone una lettura fissa di soli 4 byte per volta

' Ricrea il reale valore-byte che il dispositivo esterno ha inteso trasmettere:
i = Val("&" & s[2, 2])

' Mostra il valore numerico in formato decimale e il carattere ASCII corrispondenti al valore-byte reale ricreato:
Print i, Chr(i)


« Ultima modifica: 21 Ottobre 2021, 23:26:37 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #4 il: 22 Ottobre 2021, 09:32:15 »
Niente da fare: ho provato quel codice ma non va... evidentemente le mie premesse erano errate.

Allo stato attuale avrei risolto così:

Codice: [Seleziona]
      Dim strDaInviare2 As String = "I2CR" & Chr(ModuloGenerale.settaggioCorrente.I2Cindirizzo) & Chr(1)
      SComm.Begin()
      Write #SComm, strDaInviare2
      SComm.Send() 
      Sleep intervSleep
           
      Dim valZoom As String = ""
      Try Read #SComm, valZoom, Lof(SComm)
      valZoom = Replace(valZoom, "\r", "")     
      Select Case valZoom
        Case "\x01"
          valZoom = "1"
        Case "\x02"
          valZoom = "2"
        Case "\x03"
          valZoom = "3"
      End Select

ma la cosa antipatica è che nemmeno a me è chiaro cosa faccia, nel senso che non so cosa ricevo.

Ammetto anche di aver faticato molto a leggere la tua spiegazione (a proposito, grazie!), ma per limite mio.  E probabilmente non sono riuscito a capirla fino in fondo.
Per adesso vado avanti così: a breve dovrò "tradurre" altre letture che venivano fatto in xojo sotto windows....vedremo cosa ne uscirà fuori...
Al limite gestisco caso per caso, senza avere una funzione di lettura "universale", che era quello che avrei voluto ottenere.

Ciao


Offline kicco

  • Senatore Gambero
  • ******
  • Post: 1.727
  • So dove andare, seguitemi, ci perderemo insieme!
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #5 il: 22 Ottobre 2021, 10:09:45 »
Io ho fatto così:
Codice: [Seleziona]
Public Sub SerialPort1_Read()                               'Lettura dalla seriale

     Dim Rx As String

     Sleep 0.020

     Read #SerialPort1, Rx, Lof(SerialPort1)

     Split_byte(Rx)              'chiamata alla subroutine Split_byte

End
Public Sub Split_byte(ss As String)  ' SUB_RICEZIONE: Splitta la stringa RX in Byte

     Dim RXss As String
 
     HE1 = Asc(Mid$(ss, 1, 1))        'Inizio operazione di split
     HE2 = Asc(Mid$(ss, 2, 1))
     HE3 = Asc(Mid$(ss, 3, 1))
     HE4 = Asc(Mid$(ss, 4, 1))
     ID1 = Asc(Mid$(ss, 5, 1))
     ID2 = Asc(Mid$(ss, 6, 1))
     ID3 = Asc(Mid$(ss, 7, 1))
     ID4 = Asc(Mid$(ss, 8, 1))
     HE5 = Asc(Mid$(ss, 9, 1))
     HE6 = Asc(Mid$(ss, 10, 1))
     HE7 = Asc(Mid$(ss, 11, 1))
     HE8 = Asc(Mid$(ss, 12, 1))
     HE9 = Asc(Mid$(ss, 13, 1))
     PR1 = Asc(Mid$(ss, 14, 1))
     PR2 = Asc(Mid$(ss, 15, 1))
     PR3 = Asc(Mid$(ss, 16, 1))       'fine operazione di split
     ss = ""                                    ' vuoto la stringa
End
Tieni presente che nel mio caso ricevo sempre una stringa di 16byte.
 :ciao:
PS: ovviamente mancano le dichiarazioni di molte variabili...
« Ultima modifica: 22 Ottobre 2021, 10:11:12 da kicco »
Chi ha paura muore ogni giorno, chi non ha paura muore una volta sola. (Paolo Borsellino)

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #6 il: 22 Ottobre 2021, 11:23:53 »
CVD....

lettura successiva e ciò che ottengo, depurando dagli "\r" che mi indica l'ok di invii precedenti, è  "\x00\x05" che, son quasi sicuro, deve essere letto al contrario, ovvero "0500" (questione di  "endian"... tutto sempre più complicato)... e ora boh?!?!

Vediamo se a suon di Mid$ e Asc riesco a far qualcosa....

 :hard:

grazie anche a te kicco

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #7 il: 22 Ottobre 2021, 15:11:40 »
Alla fine, dopo tante testate al muro, una soluzione l'ho trovata:

Codice: [Seleziona]
      Dim valLettura As String = ""
      Try Read #SComm, valLettura, Lof(SComm)
      valLettura = Replace(valLettura, "\r", "")     
           
      Dim p1 As String = valLettura[1]
      Dim p2 As String = valLettura[0]
      Dim i1 As Integer = Asc(p1)
      Dim i2 As Integer = Asc(p2)
      Dim e1 As String = Hex$(i1, 2)
      Dim e2 As String = Hex$(i2, 2)
      Dim invertita As String = e1 & e2
      Dim out As Integer = Val("&H" & invertita)

Non so se ho fatto passaggi in più, ma funziona.

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.720
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #8 il: 22 Ottobre 2021, 16:52:56 »
Scusami, ma io non ho capito perché hai accennato nei post precedenti alla presenza dell'istruzione "\x" seguita da due caratteri alfanumerici.  :rolleyes:
Puoi chiarire come è composto un singolo flusso di dati ricevuto attraverso la porta ?
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #9 il: 22 Ottobre 2021, 17:32:14 »
Citazione
Scusami, ma io non ho capito perché hai accennato nei post precedenti alla presenza dell'istruzione "\x" seguita da due caratteri alfanumerici.  :rolleyes:
Puoi chiarire come è composto un singolo flusso di dati ricevuto attraverso la porta ?

Io solo adesso CREDO di aver capito che lo "\x" che leggevo nel debugger è una rappresentazione su schermo, leggibile, di un carattere non rappresentabile graficamente, visivamente.
Quindi "\x05" corrisponde al carattere il cui codice ASCII in esadecimale è "05".

Il flusso dei dati varia in base alla chiamata, per cui, in quel primo esempio, dopo aver letto, come stringa, dalla seriale, ottenevo "\x00\x05" che va invertito (sarebbe, in esadecimale, 0500, ovvero 1280).  In altre situazioni ho 4 "blocchetti" (caratteri) da leggere, sempre in ordine inverso (codifica little endian).

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.720
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #10 il: 22 Ottobre 2021, 17:41:18 »
lo "\x" che leggevo nel debugger è una rappresentazione su schermo, leggibile, di un carattere non rappresentabile graficamente, visivamente.
Quindi "\x05" corrisponde al carattere il cui codice ASCII in esadecimale è "05".
Cioè tu dici che è semplicemente e soltanto il debugger che ti fa vedere in console anche i due caratteri "\x", ma che in realtà il dispositivo esterno non ti invia.
Ossia, tu dici che il dispositivo ti invia il valore (esadecimale) 05 proprio come valore numerico e non composto dai due caratteri dello zero e del cinque ?
Faccio un esempio:
se in console vedessi "\x05\x00", in realtà dalla porta è arrivato &05 &00, e NON:  &5C &78 &30 &35 &5C &78 &30 &30 ?
« Ultima modifica: 22 Ottobre 2021, 17:45:35 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #11 il: 22 Ottobre 2021, 17:50:44 »
Citazione
Cioè tu dici che è semplicemente e soltanto il debugger che ti fa vedere in console anche i due caratteri "\x", ma che in realtà il dispositivo esterno non ti invia.

penso che sia così... se uso "Len" per valutare la lunghezza di una stringa che, sul debugger, mi vien resa "\x05" ottendo 1, non 4!

Citazione
Ossia, tu dici che il dispositivo ti invia il valore (esadecimale) 05 proprio come valore numerico e non composto dai due caratteri dello zero e del cinque ?
Faccio un esempio:
se in console vedessi "\x05\x00", in realtà dalla porta è arrivato &05 &00, e NON:  &5C &78 &30 &35 &5C &78 &30 &30 ?

sì, esatto

Offline vuott

  • Moderatore globale
  • Senatore Gambero
  • *****
  • Post: 11.720
  • Ne mors quidem nos iunget
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #12 il: 22 Ottobre 2021, 18:04:22 »
Dunque la mia interpretazione iniziale era errata (purtroppo non posso fare prove con Arduino, mi esprimo solo a livello teorico).

Mi pare anche però, poiché nel tuo codice inserisci la funzione Replace() per eliminare il carattere non stampabile &0d, che nel flusso via sia anche l'istruzione escape "\r".
Se questa istruzione è presente solo all'inizio del flusso e se vuoi anche leggere i dati a te utili in little-endian (essendo - a quanto dici - valori numerici a 16 bit), allora potresti usare una variabile di tipo "Short" combinata con un istruzione "Seek" per saltare il carattere escape "\r".
Una cosa più o meno così (faccio un caso semplice):
Codice: [Seleziona]
Dim valLettura As Short

' Sposta il puntatore del flusso al secondo byte (indice 1) del flusso di dati ricevuti:
Seek #SComm, 1

' Legge due byte e li memorizza in una variabile di tipo "Short":
Try Read #SComm, valLettura

« Ultima modifica: 25 Ottobre 2021, 13:59:38 da vuott »
« Chiunque, non ricorrendo lo stato di necessità, nel proprio progetto Gambas fa uso delle istruzioni Shell o Exec, è punito con la sanzione pecuniaria da euro 20,00 a euro 60,00. »

Offline nino83

  • Gamberetto
  • *
  • Post: 35
    • Mostra profilo
Re:interpretazione stringa letta da seriale
« Risposta #13 il: 25 Ottobre 2021, 09:36:41 »
Probabilmente quella sarebbe una soluzione al Replace.
Visto che ti sei appassionato  ;D vado oltre:
lo \r che arriva (ne leggo ben due, con quel codice) è dovuto quasi certamente ad una chiamata precedente (il primo) e alla stessa chiamata (il secondo \r), che altro non è che un carattere di conferma operazione, un OK, che l'arduino invia.  Dovrei pertanto prima leggere solo quel carattere (o il carattere alternativo, qualora ci sia un errore) e gestire la situazione.
Per adesso mi va anche bene così, poi vedrò.
Interessante l'idea del Seek (a quel punto devo però sempre sapere cosa leggerò, nel senso di quanti ne troverò, ecc).

In pratica la seriale non è come una variabile il cui valore viene sovrascritto ma, se non leggo (e svuoto), le informazioni si "accumulano" sempre di più.