Differenze tra le versioni di "Accesso alle Porte Seriali"

Da Gambas-it.org - Wikipedia.
Riga 97: Riga 97:
 
  '''End'''
 
  '''End'''
  
Mostriamo, di seguito, un altro codice <SUP>&#091;[[#Note|nota 3]]&#093;</sup> più complesso che possiede alcune funzioni capaci di inviare richieste cicliche e di dare risposte a seconda dei dati giunti dalla seriale, nonché di conteggiare richieste e risposte.
+
====Altri codici esemplificativi====
Private SPort As SerialPort
+
E' possibile scaricare anche altri due programmi ben più complessi:
Private Timer1 As Timer
+
* https://www.gambas-it.org/smf/index.php?action=dlattach;topic=8863.0;attach=5570   <SUP>&#091;[[#Note|nota 3]]&#093;</sup>
Private ChkDTR As CheckBox
+
* https://www.gambas-it.org/smf/index.php?action=dlattach;topic=8863.0;attach=5575   <SUP>&#091;[[#Note|nota 4]]&#093;</sup>
Private ChkRTS As CheckBox
 
Private ChkCTS As CheckBox
 
Private ChkDCD As CheckBox
 
Private ChkDSR As CheckBox
 
Private ChkRNG As CheckBox
 
Private TextLabel1 As TextLabel
 
Private TextLabel2 As TextLabel
 
Private TextLabel3 As TextLabel
 
Private TextLabel4 As TextLabel
 
Private TextLabel5 As TextLabel
 
Private Label1 As Label
 
Private TxtPort As TextBox
 
Private CmbSpeed As ComboBox
 
Private CmbParity As ComboBox
 
Private CmbData As ComboBox
 
Private CmbStop As ComboBox
 
Private Button1 As Button
 
Private ComboBox1 As ComboBox
 
Private Esci As Button
 
Private Separator1 As Separator
 
Private CicloCheck As CheckBox
 
Private SERIALE As TextLabel
 
Private Label3 As Label
 
Private CheckBox1 As CheckBox
 
Private TEMPO As TextBox
 
Private Label2 As Label
 
Private TxtSend As TextBox
 
Private TextLabel6 As TextLabel
 
Private RUN_COUNT As TextLabel
 
Private RUN As Button
 
Private TextArea1 As TextArea
 
Private COMPARA_BOX As CheckBox
 
Private VALORE_COMPARA As TextBox
 
Private NUMERO_CARATTERI As ComboBox
 
Private Separator2 As Separator
 
Private RISPONDI As CheckBox
 
Private RISPOSTA As TextBox
 
Private Label4 As Label
 
Private COMP_OK As TextLabel
 
Private RISPOSTE_OK As Label
 
Private RISP_OK As TextLabel
 
 
 
'''Public''' Sub _new()
 
 
 
  With Me
 
    .AutoResize = True
 
    .Expand = True
 
    .Center
 
    .H = 560
 
    .W = 500
 
    .Text = "Serial Port Exended"
 
  End With
 
  With SPort = New SerialPort As "SPort"
 
    .DataBits = .Bits8
 
    .FlowControl = .Hardware
 
    .Parity = .None
 
    .Speed = 192000
 
    .StopBits = .Bits1
 
  End With
 
  Timer1 = New Timer
 
  With ChkDTR = New CheckBox(Me) As "ChkDTR"
 
    .H = 28
 
    .W = 76
 
    .X = 330
 
    .Y = 7
 
    .Text = "DTR"
 
  End With
 
  With ChkRTS = New CheckBox(Me) As "ChkRTS"
 
    .H = 28
 
    .W = 76
 
    .X = 330
 
    .Y = 28
 
    .Text = "RTS"
 
  End With
 
  With ChkCTS = New CheckBox(Me)
 
    .H = 28
 
    .W = 76
 
    .X = 330
 
    .Y = 49
 
    .Text = "CTS"
 
  End With
 
  With ChkDCD = New CheckBox(Me)
 
    .H = 28
 
    .W = 76
 
    .X = 330
 
    .Y = 70
 
    .Text = "DCD"
 
  End With
 
  With ChkDSR = New CheckBox(Me)
 
    .H = 28
 
    .W = 76
 
    .X = 330
 
    .Y = 91
 
    .Text = "DSR"
 
  End With
 
  With ChkRNG = New CheckBox(Me)
 
    .H = 28
 
    .W = 76
 
    .X = 330
 
    .Y = 112
 
    .Text = "RNG"
 
  End With
 
  With TextLabel1 = New TextLabel(Me)
 
    .H = 28
 
    .W = 146
 
    .X = 63
 
    .Y = 7
 
    .Alignment = Align.Left
 
    .Text = "Port Name :"
 
  End With
 
  With TextLabel2 = New TextLabel(Me)
 
    .H = 28
 
    .W = 146
 
    .X = 63
 
    .Y = 35
 
    .Alignment = Align.Left
 
    .Text = "Speed :"
 
  End With
 
  With TextLabel3 = New TextLabel(Me)
 
    .H = 28
 
    .W = 146
 
    .X = 63
 
    .Y = 63
 
    .Alignment = Align.Left
 
    .Text = "Parity :"
 
  End With
 
  With TextLabel4 = New TextLabel(Me)
 
    .H = 28
 
    .W = 146
 
    .X = 63
 
    .Y = 91
 
    .Alignment = Align.Left
 
    .Text = "Data Bits :"
 
  End With
 
  With TextLabel5 = New TextLabel(Me)
 
    .H = 28
 
    .W = 146
 
    .X = 63
 
    .Y = 119
 
    .Alignment = Align.Left
 
    .Text = "Stop Bits :"
 
  End With
 
  With Label1 = New Label(Me)
 
    .H = 28
 
    .W = 105
 
    .X = 77
 
    .Y = 175
 
    .Alignment = Align.Left
 
    .Text = "Flow control :"
 
  End With
 
  With TxtPort = New TextBox(Me)
 
    .H = 28
 
    .W = 105
 
    .X = 217
 
    .Y = 7
 
    .Alignment = Align.Center
 
    .Text = "/dev/ttyUSB0"
 
  End With
 
  With CmbSpeed = New ComboBox(Me)
 
    .H = 28
 
    .W = 105
 
    .X = 217
 
    .Y = 35
 
    .List = ["1200", "2400", "4800", "9600", "19200", "38400", "57600", "112000"]
 
    .ReadOnly = True
 
  End With
 
  With CmbParity = New ComboBox(Me)
 
    .H = 28
 
    .W = 105
 
    .X = 217
 
    .Y = 63
 
    .List = ["None", "Even", "Odd"]
 
    .ReadOnly = True
 
    .Text = .List[0]
 
  End With
 
  With CmbData = New ComboBox(Me)
 
    .H = 28
 
    .W = 105
 
    .X = 217
 
    .Y = 91
 
    .List = ["8", "7", "6", "5"]
 
    .ReadOnly = True
 
    .Text = .List[0]
 
  End With
 
  With CmbStop = New ComboBox(Me)
 
    .H = 28
 
    .W = 105
 
    .X = 217
 
    .Y = 119
 
    .List = ["1", "2"]
 
    .ReadOnly = True
 
    .Text = .List[0]
 
  End With
 
  With Button1 = New Button(Me) As "Open"
 
    .H = 28
 
    .W = 105
 
    .X = 217
 
    .Y = 147
 
    .Text = "&Open"
 
    .Tooltip = "Apre la comunicazione"
 
  End With
 
  With ComboBox1 = New ComboBox(Me)
 
    .H = 28
 
    .W = 140
 
    .X = 182
 
    .Y = 175
 
    .List = ["NONE", "CRTSCTS", "XON/XOFF", "CRTSCTS + XON/XOFF"]
 
    .ReadOnly = True
 
    .Text = .List[0]
 
  End With
 
  With Esci = New Button(Me) As "Esci"
 
    .H = 42
 
    .W = 42
 
    .X = 440
 
    .Y = 14
 
    .Picture = Picture["icon:/32/shutdown"]
 
    .Tooltip = "Esci"
 
   End With
 
  With Separator1 = New Separator(Me)
 
    .H = 14
 
    .W = Me.W
 
    .X = 0
 
    .Y = 202
 
  End With
 
  With CicloCheck = New CheckBox(Me)
 
    .H = 21
 
    .W = 21
 
    .X = 35
 
    .Y = 224
 
    .Tooltip = "Invia in maniera ciclica"
 
  End With
 
  With SERIALE = New TextLabel(Me)
 
    .H = 28
 
    .W = 28
 
    .X = 63
 
    .Y = 217
 
    .Background = Color.Red
 
    .Border = Border.Plain
 
  End With
 
  With Label3 = New Label(Me)
 
    .H = 28
 
    .W = 49
 
    .X = 105
 
    .Y = 217
 
    .Text = "CICLO"
 
  End With
 
  With CheckBox1 = New CheckBox(Me)
 
    .H = 28
 
    .W = 168
 
    .X = 182
 
    .Y = 217
 
    .Text = "LETTURA SERIALE"
 
    .Tooltip = "Attiva il monitoraggio della seriale"
 
    .Value = True
 
  End With
 
  With TEMPO = New TextBox(Me)
 
    .H = 28
 
    .W = 140
 
    .X = 63
 
    .Y = 245
 
    .Text = "50"
 
    .Tooltip = "Durata del ciclo X5"
 
  End With
 
  With Label2 = New Label(Me)
 
    .H = 28
 
    .W = 91
 
    .X = 210
 
    .Y = 245
 
    .Text = "TEMPO ms X 5"
 
  End With
 
  With TxtSend = New TextBox(Me)
 
    .H = 28
 
    .W = 140
 
    .X = 63
 
    .Y = 273
 
    .Text = "Comando da inviare"
 
  End With
 
  With TextLabel6 = New TextLabel(Me)
 
    .H = 28
 
    .W = 70
 
    .X = 210
 
    .Y = 273
 
    .Alignment = Align.Left
 
    .Text = "COMANDO"
 
  End With
 
  With RUN_COUNT = New TextLabel(Me)
 
    .H = 28
 
    .W = 77
 
    .X = 287
 
    .Y = 273
 
    .Alignment = Align.Right
 
    .Background = &3F3FFF
 
    .Text = "0"
 
    .Tooltip = "Numero di comandi inviati, viene azzerato ad ogni invio manuale, per una statistica usare l'invio ciclico"
 
  End With
 
  With RUN = New Button(Me)
 
    .H = 28
 
    .W = 70
 
    .X = 372
 
    .Y = 273
 
    .AutoResize = True
 
    .Text = "RUN"
 
    .Tooltip = "Invia il comando"
 
  End With
 
  With TextArea1 = New TextArea(Me)
 
    .H = 174
 
    .W = 482
 
    .X = 7
 
    .Y = 308
 
    .Background = &FFFF9F
 
    .Tooltip = "Monitor dei dati ricevuti dalla seriale"
 
  End With
 
  With COMPARA_BOX = New CheckBox(Me)
 
    .H = 28
 
    .W = 84
 
    .X = 14
 
    .Y = 490
 
    .Text = "COMPARA"
 
    .Tooltip = "Esegui la comparazione del dato ricevuto"
 
  End With
 
  With VALORE_COMPARA = New TextBox(Me)
 
    .H = 28
 
    .W = 70
 
    .X = 105
 
    .Y = 490
 
    .Tooltip = "Dato da usare per la comparazione"
 
  End With
 
  With NUMERO_CARATTERI = New ComboBox(Me)
 
    .H = 28
 
    .W = 42
 
    .X = 182
 
    .Y = 490
 
    .List = ["1", "2", "3", "4", "5", "6", "7", "8"]
 
    .Text = "0"
 
    .Tooltip = "Numero di caratteri ricevuti da analizzare nella comparazione partendo dalla fine della stringa"
 
  End With
 
  With Separator2 = New Separator(Me)
 
    .H = 70
 
    .W = 28
 
    .X = 238
 
    .Y = 483
 
  End With
 
  With RISPONDI = New CheckBox(Me)
 
    .H = 28
 
    .W = 90
 
    .X = 322
 
    .Y = 490
 
    .Text = "RISPONDI"
 
    .Tooltip = "Invia una risposta se il dato di comparazione viene soddisfatto"
 
  End With
 
  With RISPOSTA = New TextBox(Me)
 
    .H = 28
 
    .W = 70
 
    .X = 413
 
    .Y = 490
 
    .Tooltip = "dato inviato come risposta"
 
  End With
 
  With Label4 = New Label(Me)
 
    .H = 21
 
    .W = 106
 
    .X = 14
 
    .Y = 525
 
    .Background = &FFDF7F
 
    .Text = "COMPARAZ. OK"
 
  End With
 
  With COMP_OK = New TextLabel(Me)
 
    .H = 21
 
    .W = 56
 
    .X = 119
 
    .Y = 525
 
    .Alignment = Align.Right
 
    .Background = &FF8000
 
    .Text = "0"
 
    .Tooltip = "Numero di comparazioni corrette, viene azzerato ad ogni invio manuale, per una statistica usare l'invio ciclico"
 
  End With
 
  With RISPOSTE_OK = New Label(Me)
 
    .H = 21
 
    .W = 105
 
    .X = 322
 
    .Y = 525
 
    .Background = &FFDF7F
 
    .Text = "RISPOSTE OK"
 
  End With
 
  With RISP_OK = New TextLabel(Me)
 
    .H = 21
 
    .W = 56
 
    .X = 427
 
    .Y = 525
 
    .Alignment = Align.Right
 
    .Background = &FF8000
 
    .Text = "0"
 
    .Tooltip = "Numero di risposte inviate"
 
  End With
 
 
'''End'''
 
 
'''Public''' Sub Form_Close()
 
  If Sport.Status = Net.Active Then Close Sport
 
'''End'''
 
 
'''Private''' Sub Check_Status()
 
  ChkDSR.Value = Sport.DSR
 
  ChkDTR.Value = Sport.DTR
 
  ChkCTS.Value = Sport.CTS
 
  ChkRTS.Value = Sport.RTS
 
  ChkDCD.Value = Sport.DCD
 
  ChkRNG.Value = Sport.RNG
 
'''End''
 
 
 
Private HACK As String
 
Private SC As Integer  <FONT Color=gray>' ''Controllo stabilità connessione''</font>
 
Private RC As Integer  <FONT Color=gray>' ''Conteggio invii RUN''</font>
 
Private NC As Integer  <FONT Color=gray>' ''Numero caratteri da comparare (da fine stringa)''</font>
 
 
'''Public''' Sub Open_Click()
 
  If Sport.Status = Net.Active Then
 
    Close Sport
 
    Button1.Text = "&Open"
 
  Else
 
<FONT Color=gray>' ''Parametri:''</font>
 
    Sport.PortName = TxtPort.Text
 
    Sport.Speed = CmbSpeed.Text
 
    Sport.Parity = CmbParity.Index
 
    Sport.DataBits = CmbData.Text
 
    Sport.StopBits = CmbStop.Text
 
    Sport.FlowControl = ComboBox1.Index
 
    Sport.Open()
 
    Check_Status()
 
    TextArea1.Text = "Port Opened : " & Sport.PortName & " Settings : " &
 
                    Sport.Speed & "," & Sport.Parity & "," & Sport.DataBits & "," &
 
                    Sport.StopBits & Chr(13) & Chr(10)
 
    Button1.Text = "&Close"
 
    RC = 0
 
    SC = 0
 
    RUN_COUNT.Text = "0"
 
    COMP_OK.Text = "0"
 
    RISP_OK.Text = "0"
 
  Endif
 
  Catch
 
    Message.Info("Errore apertura seriale , verificare porta")
 
'''End'''
 
 
'''Public''' Sub SPort_Read()
 
 
  Dim s As String
 
 
 
  Read #Sport, s, Lof(Sport)
 
  If CheckBox1.Value = True Then TextArea1.Text = TextArea1.Text & s
 
    
 
<FONT Color=gray>'***************************************** ANALISI STRINGA ***************************************</font>
 
 
<FONT Color=gray>' COMPARAZIONE</font>
 
  If COMPARA_BOX.Value = True Then
 
    NC = NUMERO_CARATTERI.Text
 
    If Right$(TextArea1.Text, (NC)) = VALORE_COMPARA.Text Then
 
      SC = SC + 1
 
      COMP_OK.Text = SC
 
      If COMP_OK.Text = 300 Then TextArea1.Text = ""
 
    Endif
 
  Endif
 
 
<FONT Color=gray>' RISPOSTA</font>
 
  If RISPONDI.Value = True Then
 
    NC = NUMERO_CARATTERI.Text
 
    If Right$(TextArea1.Text, (NC)) = VALORE_COMPARA.Text Then
 
      Print #Sport, RISPOSTA.Text;
 
      SC = SC + 1
 
      RISP_OK.Text = SC
 
      If RISP_OK.Text = 300 Then TextArea1.Text = ""
 
    Endif
 
  Endif
 
 
'''End'''
 
 
'''Public''' Sub RUN_Click()
 
 
  Dim T As Integer
 
 
  If CicloCheck.Value Then
 
    If RUN.Text = "RUN" Then
 
      RUN.Text = "STOP"
 
    Else
 
      RUN.Text = "RUN"
 
    Endif
 
  Endif
 
  RC = 0
 
  SC = 0
 
  T = TEMPO.Text
 
  If CicloCheck.Value = True Then
 
    Timer1.Delay = TEMPO.Text
 
    If Timer1.Enabled Then
 
      Timer1.Enabled = False
 
    Else
 
      Timer1.Enabled = True
 
    Endif
 
  Else
 
    Print #Sport, TxtSend.Text;
 
  Endif
 
  Catch
 
    Message("Apri la porta!")
 
 
'''End'''
 
 
'''Public''' Sub ChkDTR_Click()
 
  Sport.DTR = ChkDTR.Value
 
  Check_Status
 
'''End'''
 
 
'''Public''' Sub ChkRTS_Click()
 
  Sport.RTS = ChkRTS.Value
 
  Check_Status
 
'''End'''
 
 
'''Public''' Sub ComboBox1_Click()
 
  Sport.FlowControl = ComboBox1.Index
 
'''End'''
 
 
'''Public''' Sub Form_Open()
 
  cmbSpeed.Index = cmbSpeed.Find("9600")
 
'''End'''
 
 
 
Private  C As Integer
 
Private IND As Integer
 
 
'''Public''' Sub Timer1_Timer()
 
 
  If Sport.Status = Net.Inactive Then
 
    Message("Apri la porta!")
 
    RUN.Text = "RUN"
 
    Timer1.Enabled = False
 
  Else
 
    If IND < 33 Then IND = 33
 
    If C = 5 Then
 
      If IND = 62 Then
 
        IND = 33
 
        TextArea1.Clear
 
      Else
 
        IND = IND + 1
 
      Endif
 
      Print #Sport, TxtSend.Text;
 
      C = 0
 
      RC = RC + 1
 
      RUN_COUNT.Text = RC
 
    Else
 
      C = C + 1
 
    Endif
 
    SERIALE.Text = C
 
  Endif
 
 
'''End'''
 
 
'''Public''' Sub Esci_Click()
 
  If Button1.Text = "&Close" Then Open_Click
 
  Me.Close
 
'''End'''
 
  
  
Riga 667: Riga 109:
 
[2] In tali altri casi il file-device creato può essere: "/dev/<FONT Color=#B22222>ttyACM0</font>"
 
[2] In tali altri casi il file-device creato può essere: "/dev/<FONT Color=#B22222>ttyACM0</font>"
  
[3] Il codice è stato realizzato dal utente "''[https://www.gambas-it.org/smf/index.php?action=profile;u=576 astragalo]'' ".
+
[3] Il codice è stato realizzato dal utente "''[https://www.gambas-it.org/smf/index.php?action=profile;u=1089 kicco]'' "
 +
 
 +
[4] Il codice è stato realizzato dal utente "''[https://www.gambas-it.org/smf/index.php?action=profile;u=576 astragalo]'' ".
  
  

Versione delle 19:34, 2 dic 2021

Possiamo accedere alle Porte Seriali [nota 1] aprendo e leggendo direttamentre i dati provenienti dai relativi file-device.

Poniamo l'esempio di avere una penna USB per la connessione ad Internet, e che alla sua connessione il sistema operativo abbia generato due relativi file-device: "/dev/ttyUSB0 " e "/dev/ttyUSB1 " [nota 2].
Possiamo leggere i dati provenienti dalla porta mediante due modalità:

  • direttamente dal relativo file-device, ad esempio, "/dev/ttyUSB1 ";
  • mediante l'apposita classe "SerialPort".

Mediante lettura diretta dal corrispondente file-device

Per il seguente esempio è necessario attivare anche il componente "gb.desktop", ed aver installato il programma "x-term":

Private fl As File


Public Sub Button1_Click()

' Se il file non possiede i più ampi permessi...
   If Stat("/dev/ttyUSB1").Auth <> "rwsrwxrwx" Then
' ...allora modificheremo in quel senso i permessi del file:
     Desktop.RunAsRoot("chmod 4777 /dev/ttyUSB1")
' Restiamo in attesa fino a che i permessi non vengono modificati, come desiderato:
     Do
       Wait 0.01
     Loop Until Stat("/dev/ttyUSB1").Auth = "rwsrwxrwx"
   Endif

' In alternativa all'algoritmo precedente,
' si potrà utilizzare il seguente codice per impostare il setUID
' e consentire l'apertura del file protetto:
   Exec ["gksu", "chmod 4777", "/dev/ttyUSB1"] Wait

' ...o ancor più facilmente:
   Shell "echo < mia_password > | sudo -S chmod 4777 '/dev/ttyUSB1'" Wait

' Apriamo il file-device aggiungendo la parola chiave "Watch":
   fl = Open "/dev/ttyUSB1" For Read Watch

End


Public Sub File_Read()

 Dim s As String

   While Not Eof(fl)
' Leggiamo i dati provenienti dal file-device...:
     Line Input #fl, s
' ...e li mostriamo in console:
     Print s
   Wend

End


Lettura mediante la classe SerialPort

La lettura della Porta Seriale portà avvenire anche mediante l'uso della Classe "SerialPort" attivando il componente gb.net.

Private SerialPort1 As SerialPort


Public Sub Button1_Click()

  SerialPort1 = New SerialPort As "portaseriale"


' Facciamo in modo da poter inserire la password di root
' per impostare il setUID e consentire l'apertura del file protetto:
   Shell "echo 'mia_password' | sudo -S chmod 4777 '/dev/ttyUSB1'" Wait
 
   With SerialPort1
     .PortName = "/dev/ttyUSB1"
     .Speed = 19200
     .Parity = 0
     .DataBits = 8
     .StopBits = 1
     .FlowControl = 0
     .Open
   End With

 End


Public Sub portaseriale_Read()

 Dim s As String

' Legge i dati dalla porta....
       Read #SerialPort1, s, Lof(SerialPort1)

' ...e li mostra in console:
       Print s

End


Public Sub Form_Close()
 
  If SerialPort1.Status = Net.Active Then SerialPort1.Close
 
End

Altri codici esemplificativi

E' possibile scaricare anche altri due programmi ben più complessi:


Note

[1] Vedere anche questa pagina: Approfondimento sull'accesso alle porte USB

[2] In tali altri casi il file-device creato può essere: "/dev/ttyACM0"

[3] Il codice è stato realizzato dal utente "kicco "

[4] Il codice è stato realizzato dal utente "astragalo ".


Approfondimenti in internet