Gambas-it

Gambas3 => Programmazione => Topic aperto da: allegfede - 24 Aprile 2019, 00:27:13

Titolo: [SOLVED] Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: allegfede - 24 Aprile 2019, 00:27:13
Salve, ho scritto una procedura che dovrebbe mandare una serie di valori esadecimali ad una macchina attraverso la seriale rs232 ma ho il sospetto che stia mandando la interpretazione ASCII di quelle cifre.
Per esempio dovrebbe mandare l'esadecimale a5 30 00 11 1f , ma penso che mandi "a53000111f".
So che il cavo ed il collegamento funziona, perché con miniComm quando mando in esadecimale quei valori, la macchina remota mi risponde.

Ora sono a casa e non ho il codice, domani lo carico.

Ma non ho trovato alcuna informazione sul fatto che serial.send invii i dati del butteremo in un modo (ASCII) o nell'altro (esadecimale).
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 00:40:37
Per esempio dovrebbe mandare l'esadecimale a5 30 00 11 1f , ma penso che mandi "a53000111f".
Cioè di quel numero deve inviare un byte alla volta in serie ?
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: Arco - 24 Aprile 2019, 09:07:14
Non capisco alcune cose.
Il computer riconosce solo il codice binario.
Tu hai un convertitore esadecimale -> binario per inviare i dati alla seriale?
Un convertitore binario -> esadecimale sulla seriale di destinazione?
In questo caso un segnale inviato è uguale al segnale ricevuto.
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: kicco - 24 Aprile 2019, 09:14:16
 :ciao:
Secondo me stai facendo confusione.
Se i valori a5 30 00 11 1f sono esadecimali, la seriale li invia così come sono. È il ricevente che deve sapere che i dati sono esadecimali e non decimali (ASCII).
La domanda che ti ha posto Vuott è importante perchè se il ricevente legge un dato alla volta, il gioco è fatto altrimenti se gli arriva la stringa "a5 30 00 11 1f ", bisogna provvedere alla divisione dei vari byte.
Tutto questo ovviamente se ho capito bene il tuo quesito!!!
 :ciao: :ciao:
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 11:26:20
se gli arriva la stringa "a5 30 00 11 1f ", bisogna provvedere alla divisione dei vari byte.
Se gli arriva quella stringa, la stringa sarà "a53000111f" e non "a5 30 00 11 1f ", giacché in tale secondo caso anche lo spazio è un dato, corrispondente al valore &h20 (d32).
Pertanto, la stringa "a53000111f" è formata da ben 10 valori ASCII corrispondenti ciascuno a un carattere alfanumerico ivi contenuto.
Comprenderete, dunque, la complessità di trasformare due byte, ad esempio &h61 &h35 (ossia "a5") nell'unico valore &ha5.
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: allegfede - 24 Aprile 2019, 12:05:33
la macchina remota si aspetta un valore:
A | A | 5 | 5 | 0 | 3 | 0 | 0 | 1 | F | cr+lf

composto di caratteri esadecimali ... suppongo in un unico invio separato da un CrLf

questo il codice (che ho tradotto da un mio vecchio software funzionante in vb6):
Codice: [Seleziona]
Public Sub CommutaMatrice(macchina As Integer, sorgente As Integer, destinazione As Integer)
Dim InizioStringa As String
Dim Ingresso As String
Dim Uscita As String

  InizioStringa = "AA5503"   
  ingresso = Hex(sorgente, 2)
  uscita = Hex(destinazione, 2)
 
  Seriale.Close
 
  With Seriale
     .PortName = "/dev/" & settings["SerialPort", "ttyACM0"]
     .Speed = 9600
     .Parity = SerialPort.None
     .DataBits = 8
     .StopBits = 1
     .FlowControl = 0
     .Open
   End With
   
   seriale.Begin
   Wait 1
   Print #seriale, InizioStringa & ingresso & uscita
   Wait 1
   Seriale.Send
   
   mylogger("MASTER_CONTROL:" & sorgente & ">" & destinazione & "(" & macchina & ")", Logger.Info)
   
   seriale.Close
   
   PlayNext
   
End

ho provato a cambiare il tipo di dati da string ad hex, ma hex non e' un tipo di dato riconosciuto :-(
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 12:42:49
la macchina remota si aspetta un valore:
A | A | 5 | 5 | 0 | 3 | 0 | 0 | 1 | F | cr+lf

composto di caratteri esadecimali ... suppongo in un unico invio separato da un CrLf

Prima questione che devi farci capire.

La macchina remota si aspetta &hAA &h55 &h03 &h00  &h1F &h06 ?
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: allegfede - 24 Aprile 2019, 12:57:01
penso &hAA5503001F per quel che riguarda il termine riga e' molto vago, penso basti che gli arrivi quella roba tutta insieme.

in allegato le schermate di minicom (indica l'invio di 5 byte). Come si concatenano i byte?

da shell questo comando funziona pefettaemnte:
Codice: [Seleziona]
echo -en '\xAA\x55\x03\x00\x1F' > /dev/ttyUSB0
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 13:26:36
penso &hAA5503001F ...... penso basti che gli arrivi quella roba tutta insieme.
...ma poi ci devi aggiungere i valori di "ingresso" e "uscita" ?
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 13:34:02
In fondo l'esadecimale non è altro che una rappresentazione di un numero, quindi prova un po' così:

Codice: [Seleziona]
Public Sub CommutaMatrice(macchina As Integer, sorgente As Integer, destinazione As Integer)

  Dim InizioStringa As String

   InizioStringa = "AA5503"
 
  With Seriale
     .PortName = "/dev/" & settings["SerialPort", "ttyACM0"]
     .Speed = 9600
     .Parity = SerialPort.None
     .DataBits = 8
     .StopBits = 1
     .FlowControl = 0
     .Open
   End With

   Write #Seriale, Val("&" & InizioStringa) As Long
   Write #Seriale, sorgente As Integer
   Write #Seriale, destinazione As Integer

   Seriale.Close

   ...etc....
   
  End
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 13:35:56
Seconda questione:

...ma InizioStringa deve essere per forza di tipo.... Stringa ? 
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 13:40:24
Questa riga del mio codice:

Codice: [Seleziona]
   Write #Seriale, Val("&" & InizioStringa) As Long

non va bene. E' errata: non va bene per quel che serve a te.

Chissà se c'è qualcuno che ha capito perché ?!
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: allegfede - 24 Aprile 2019, 13:42:12
Seconda questione:

...ma InizioStringa deve essere per forza di tipo.... Stringa ?

noo assolutamente ... sono i valori esadecimali FISSI per la mia architettura di macchine (e' fatta a moduli e quei valori dicono a quali moduli e' associato il comando che seguira')
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 13:49:05
noo assolutamente ... sono i valori esadecimali FISSI

Cerchiamo di capirci.

Come sappiamo, i valori esadecimali non sono altro che una diversa "rappresentazione" di un numero.

DOMANDONA:

tu devi inviare quei precisi valori-byte, e SOLO strettamente quelli ? OPPURE tu devi inviare dei numeri formati da più cifre.

Cerco di spiegarmi meglio:
Tu hai scritto: &hAA5503001F

ma......la macchina remoto vuole questi valori (te li scrivo in Decimale): 170  85  3  0  31 ?
oppure vuole questo: 731570700319 ?
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 13:53:10
sono i valori esadecimali FISSI

Forse vuole questi: 170  85  3  0  31
e non un byte di più.
Cioè "singoli" byte, che solo insieme assumono un significato per la macchina remota.  :-X
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: allegfede - 24 Aprile 2019, 14:16:40
sono i valori esadecimali FISSI

Forse vuole questi: 170  85  3  0  31
e non un byte di più.
Cioè "singoli" byte, che solo insieme assumono un significato per la macchina remota.  :-X

cerco di spiegare il protocollo di comunicazione verso la macchina:
la macchina remota riconosce un comando se riceve 5 byte i cui primi due sono
AA 55

A questo punto, dei 5 byte che riceve analizza il terzo byte (8 bit) che rappresenta i moduli attivi (l'esadecimale 03 e' in binario 00000011, che significa, partendo da DESTRA, modulo video composito presente TRUE (1) | modulo audio presente TRUE (1) | modulo Y/C o RGB presente=FALSE (0) | modulo audio 2 presente=FALSE (0) , etc)

Veniamo ora al comando di commutazione, che necessita di un indirizzo per la sorgente (1 byte=255 sorgenti) e della destinazione (1 byte).

quindi da minicom (tanto per capire dove la cosa funziona), la "stringa" che rappresenta (attraverso il drop down menu' opportuno si mette HEX) valori esadecimali, AA5503001F (e do invio o premo send), sto dicendo al modulo video ad al modulo audio (binario 11=esadecimale 03) che sto inviando un comando di commutazione (esadecimale AA55) tra' la sorgente (esadecimale 00= in decimale 0) e la destinazione (esadecimale 1F= decimale 31).

I valori decimali ci sono perche' la "pulsantiera" per il controllo manuale e' ovviamente in numeri a base dieci, piu' vicini all'esperienza umana.

Per venire all'argomento "cosa e' parametrico e cosa e' fisso", direi che i primi 3 byte del comado possono essere hard-coded poiche' cambieranno molto poco, ma sorgente e destinazione vengono scelti di volta in volta dall'utente e devono essere un parametro.
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 15:20:03
Poiché il primo gruppo di dati è "fisso" e di formato atipico (5 byte), dobbiamo utilizzare una porzione di memoria riservata.
Useremo per facilità un vettore di tipo Byte[ ] inizializzato con i valori iniziali da passare alla macchina remoto.


Veniamo ora al comando di commutazione, che necessita di un indirizzo per la sorgente (1 byte=255 sorgenti) e della destinazione (1 byte).
Se il valore della sorgente e quello della destinazione occupanno 1 Byte ciascuno, allora alla macchina bisogna passare un valore di tipo Byte e non Integer.


Proporrei quindi questa soluzione:
Codice: [Seleziona]
Public Sub CommutaMatrice(macchina As Integer, sorgente As Byte, destinazione As Byte)

  Dim iniziale As Byte[] = [&AA, &55, &03, &00, &1F]

   With Seriale
     ......
     ......
   End With

   iniziale.Push(sorgente)
   iniziale.Push(destinazione)
   iniziale.Write(Seriale, 0, iniziale.Count)

   Seriale.Close

   ......
   ......

End
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: allegfede - 24 Aprile 2019, 16:20:21
perfetto! funziona !
Codice: [Seleziona]
Public Sub CommutaMatrice(macchina As Integer, sorgente As Integer, destinazione As Integer)
Dim Ingresso As Byte
Dim Uscita As Byte

Dim iniziale As Byte[] = [&AA, &55, &03]

  ingresso = CByte(sorgente)
  uscita = CByte(destinazione)
 
  iniziale.Push(ingresso)
  iniziale.Push(uscita)
 
  If seriale.Status = Net.Active Then
    Seriale.Close
  Endif
 
  With Seriale
     .PortName = "/dev/" & settings["SerialPort", "ttyACM0"]
     .Speed = 9600
     .Parity = SerialPort.None
     .DataBits = 8
     .StopBits = 1
     .FlowControl = SerialPort.None
     .Drop
     .Open
   End With
   
   If seriale.Status = Net.Active Then 
      iniziale.Write(Seriale, 0, iniziale.Count)
      mylogger("MASTER_CONTROL:" & sorgente & ">" & destinazione & "(" & macchina & ")", Logger.Info)
      seriale.Close
   Endif

   PlayNext
   
End
Titolo: Re:Come scrivere (e mandare) dati esadecimali attraverso la seriale rs232?
Inserito da: vuott - 24 Aprile 2019, 18:42:18
Se il valore della sorgente e quello della destinazione occupanno 1 Byte ciascuno, allora alla macchina bisogna passare un valore di tipo Byte e non Integer.

Oltre al problema del passaggio dei primi tre dati come tipo Stringa, si aggiungeva anche il passaggio degli ultimi due dati (sorgente e destinazione) come tipo Integer anziché come Byte.

Sappiamo infatti che il tipo Intero occupa 4 byte di memoria, pertanto se - ad esempio - il valore "sorgente" da trasmettere fosse stato semplicemente &61 e quello "destinazione" fosse stato &71, passando l'Integer tu avresti passato con Write (in Little-Endian) &61 &00 &00 &00 &71 &00 &00 &00.
In definitiva tu avresti passato - nell'esempio didattico sopra mostrato - i seguenti valori significativi per la macchina remoto:
&AA &55 &03 &61 &00