Accesso alle Porte Seriali: differenze tra le versioni

Da Gambas-it.org - Wikipedia.
Vai alla navigazione Vai alla ricerca
Nessun oggetto della modifica
Nessun oggetto della modifica
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