Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[VB] SerialPort - sprawdzanie czy coś dotarło. RS232

klops_mops 05 Kwi 2009 14:27 2806 11
  • #1 05 Kwi 2009 14:27
    klops_mops
    Poziom 17  

    Witam!

    Komunikuje się z pewnym urządzeniem za pomocą portu RS232, nadaje ono stringi w postaci xxxxxxxx + CR/LF, gdzie x to 1 lub 0.

    W moim programie użyłem SerialPort. Zastanawia mnie teraz jak zrobić takie coś: gdy moje urządzenie coś nada to program automatycznie to wyświetli i zapali odpowiednie "lampki", udało mi się napisac to w taki sposób, że po kliknięciu na przycisk dokonywany jest odbiór danych. Ja zrobić by było zgłaszane coś w stylu przerwania?

    To co napisałem dotychczas:

    Code:
    Public Class Form1
    
        Dim port As String
        Dim cz As String
        Dim a As Integer
        Dim b As Integer
        Dim c As Integer
        Dim d As Integer
        Dim ee As Integer
        Dim f As Integer
        Dim g As Integer
        Dim h As Integer
        Dim otrzymane As String
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Button1.Enabled = False
            Button2.Enabled = False

        End Sub

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If SerialPort1.IsOpen Then
            Else
                MsgBox("Potr " + port + " nie jest otwarty!", 64, "Błąd")
            End If
            SerialPort1.Write(TextBox1.Text)
            TextBox1.Text = "WYSŁANE"
        End Sub

        Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
            'Label9.Text = "ODEBRAŁEM"
        End Sub
       
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            If SerialPort1.IsOpen Then
            Else
                MsgBox("Potr " + port + " nie jest otwarty!", 64, "Błąd")
            End If
            otrzymane = SerialPort1.ReadLine()
            TextBox2.Text = otrzymane
            If otrzymane > 5 Then
                a = Mid(otrzymane, 1, 1)
                b = Mid(otrzymane, 2, 1)
                c = Mid(otrzymane, 3, 1)




                d = Mid(otrzymane, 4, 1)
                ee = Mid(otrzymane, 5, 1)
                f = Mid(otrzymane, 6, 1)
                g = Mid(otrzymane, 7, 1)
                h = Mid(otrzymane, 8, 1)

                If a = 1 Then
                    PictureBox1.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox1.Image = RS232.My.Resources.Resources.czerwone
                End If
                If b = 1 Then
                    PictureBox2.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox2.Image = RS232.My.Resources.Resources.czerwone
                End If
                If c = 1 Then
                    PictureBox3.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox3.Image = RS232.My.Resources.Resources.czerwone
                End If
                If d = 1 Then
                    PictureBox4.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox4.Image = RS232.My.Resources.Resources.czerwone
                End If
                If ee = 1 Then
                    PictureBox5.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox5.Image = RS232.My.Resources.Resources.czerwone
                End If
                If f = 1 Then
                    PictureBox6.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox6.Image = RS232.My.Resources.Resources.czerwone
                End If
                If g = 1 Then
                    PictureBox7.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox7.Image = RS232.My.Resources.Resources.czerwone
                End If
                If h = 1 Then
                    PictureBox8.Image = RS232.My.Resources.Resources.zielone
                Else
                    PictureBox8.Image = RS232.My.Resources.Resources.czerwone
                End If
            Else
                TextBox2.Text = "Błąd"
            End If


        End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            If SerialPort1.IsOpen Then
                SerialPort1.Close()
                ComboBox1.Enabled = True
                Button1.Enabled = False
                Button2.Enabled = False
                PictureBox1.Image = RS232.My.Resources.Resources.szare
                PictureBox2.Image = RS232.My.Resources.Resources.szare
                PictureBox3.Image = RS232.My.Resources.Resources.szare
                PictureBox4.Image = RS232.My.Resources.Resources.szare
                PictureBox5.Image = RS232.My.Resources.Resources.szare
                PictureBox6.Image = RS232.My.Resources.Resources.szare
                PictureBox7.Image = RS232.My.Resources.Resources.szare
                PictureBox8.Image = RS232.My.Resources.Resources.szare
                Button3.Text = "Otwórz " + port
                MsgBox("Port " + port + " został zamkniety!", 64, "Status")
            Else
                SerialPort1.Open()
                ComboBox1.Enabled = False
                Button1.Enabled = True
                Button2.Enabled = True
                Button3.Text = "Zamknij " + port
                MsgBox("Port " + port + " został otwarty!", 64, "Status")
            End If
        End Sub

        Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
            port = ComboBox1.SelectedItem
            SerialPort1.PortName = port
            If SerialPort1.IsOpen Then
                Button3.Text = "Zamknij " + port
            Else
                Button3.Text = "Otwórz " + port
            End If
        End Sub

    End Class


    <center>[VB] SerialPort - sprawdzanie czy coś dotarło. RS232</center>

    Z góry dziękuję za pomoc :)

    0 11
  • Pomocny post
    #2 05 Kwi 2009 18:17
    KeinXor
    Poziom 24  

    Witam,
    użyj Timer-a on cyklicznie co określony interwał czasu wywołuje zdarzenie OnTimer.

    0
  • #3 05 Kwi 2009 18:39
    klops_mops
    Poziom 17  

    Jak dokładniej go używać?
    To jest dopiero mój drugi tydzień styczności z VB, proszę o jakieś przykłady - nie gotowce...
    Poniżej film obrazujący co chcę wykonać:

    Dane w postaci xxxxxxxx + RF/LF wysyłane są przez Atmegę32

    0
  • Pomocny post
    #4 05 Kwi 2009 19:23
    adamas_nt
    Moderator Programowanie

    Jakoś tak to opisałeś, że nie jestem pewien czy o to chodzi...

    Może należałoby zamknąć tę procedurę w pętli. Nie wiem skąd się bierze wartość bufora, ale

    Code:
    Do Until wartość_tego_bufora = 0
    pętla będzie działać, aż będzie pusty (zakładając, że 0 to pusty bufor).

    0
  • #5 05 Kwi 2009 19:48
    klops_mops
    Poziom 17  

    Wraz z użyciem tej pętli cały bufor jest wyświetlany, po czym następuje koniec wykonywania, a po pewnym czasie znów się zapełnia i znów muszę wywołać pętlę. Natomiast jak zrobić by przy buforze równym 0 program czekał na dane i gdy się pojawią to wyświetlił i tak w kółko. Na tej samej zasadzie jaką ja chcę uzyskać działają terminale RS232.

    Mój kod:

    Code:
    Public Class Form1
    
        Dim port As String
        Dim predkosc As Integer
        Dim cz As String
        Dim a As Integer
        Dim b As Integer
        Dim c As Integer
        Dim d As Integer
        Dim ee As Integer
        Dim f As Integer
        Dim g As Integer
        Dim h As Integer
        Dim dane_sa As Integer
        Dim otrzymane As String
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Button1.Enabled = False
            Button2.Enabled = False
            Button3.Enabled = False
            ComboBox2.Enabled = False

        End Sub

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If SerialPort1.IsOpen Then
            Else
                MsgBox("Potr " + port + " nie jest otwarty!", 64, "Błąd")
            End If
            SerialPort1.Write(TextBox1.Text)
            TextBox1.Text = "WYSŁANE"
        End Sub

        Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs)
            'Label9.Text = "ODEBRAŁEM"
        End Sub
       
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            If SerialPort1.IsOpen Then
            Else
                MsgBox("Potr " + port + " nie jest otwarty!", 64, "Błąd")
            End If
            dane_sa = SerialPort1.BytesToRead
            Do Until dane_sa = 0
                dane_sa = SerialPort1.BytesToRead
                Label9.Text = dane_sa

                If dane_sa > 0 Then
                    otrzymane = SerialPort1.ReadLine()
                    TextBox2.Text = otrzymane
                    RichTextBox1.Text = RichTextBox1.Text + otrzymane

                    a = Mid(otrzymane, 1, 1)
                    b = Mid(otrzymane, 2, 1)
                    c = Mid(otrzymane, 3, 1)
                    d = Mid(otrzymane, 4, 1)
                    ee = Mid(otrzymane, 5, 1)
                    f = Mid(otrzymane, 6, 1)
                    g = Mid(otrzymane, 7, 1)
                    h = Mid(otrzymane, 8, 1)

                    If a = 1 Then
                        PictureBox1.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox1.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If b = 1 Then
                        PictureBox2.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox2.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If c = 1 Then
                        PictureBox3.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox3.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If d = 1 Then
                        PictureBox4.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox4.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If ee = 1 Then
                        PictureBox5.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox5.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If f = 1 Then
                        PictureBox6.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox6.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If g = 1 Then
                        PictureBox7.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox7.Image = RS232.My.Resources.Resources.czerwone
                    End If
                    If h = 1 Then
                        PictureBox8.Image = RS232.My.Resources.Resources.zielone
                    Else
                        PictureBox8.Image = RS232.My.Resources.Resources.czerwone
                    End If
                Else
                    MsgBox("Brak danych w buforze odbiorczym!", 64, "Błąd")
                End If
            Loop

        End Sub

        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
            If SerialPort1.IsOpen Then
                SerialPort1.Close()
                ComboBox1.Enabled = True
                ComboBox2.Enabled = True
                Button1.Enabled = False
                Button2.Enabled = False
                PictureBox1.Image = RS232.My.Resources.Resources.szare
                PictureBox2.Image = RS232.My.Resources.Resources.szare
                PictureBox3.Image = RS232.My.Resources.Resources.szare
                PictureBox4.Image = RS232.My.Resources.Resources.szare
                PictureBox5.Image = RS232.My.Resources.Resources.szare
                PictureBox6.Image = RS232.My.Resources.Resources.szare
                PictureBox7.Image = RS232.My.Resources.Resources.szare
                PictureBox8.Image = RS232.My.Resources.Resources.szare
                Button3.Text = "Otwórz " + port
                MsgBox("Port " + port + " został zamkniety!", 64, "Status")
            Else
                predkosc = ComboBox2.SelectedItem
                SerialPort1.BaudRate = predkosc
                SerialPort1.Open()
                ComboBox1.Enabled = False
                ComboBox2.Enabled = False
                Button1.Enabled = True
                Button2.Enabled = True
                Button3.Text = "Zamknij " + port
                MsgBox("Port " + port + " został otwarty!", 64, "Status")
            End If
        End Sub

        Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
            ComboBox2.Enabled = True
            port = ComboBox1.SelectedItem
            SerialPort1.PortName = port
            If SerialPort1.IsOpen Then
                Button3.Text = "Zamknij " + port
            Else
                Button3.Text = "Otwórz " + port
            End If
        End Sub

        Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
            Button3.Enabled = True

        End Sub

    End Class

    0
  • Pomocny post
    #6 05 Kwi 2009 20:00
    adamas_nt
    Moderator Programowanie

    Można wykorzystać opisywaną już na forum funkcję Sleep. Przekierować wykonywanie kodu za pętlą (Call nazwa), "odczekać" określoną ilość czasu i powrócić. Ewentualnie użyć ją (Sleep) wewnątrz pętli...

    0
  • #7 05 Kwi 2009 20:39
    klops_mops
    Poziom 17  

    Polecenie Sleep nie działa w VB...
    Pokombinuję z tym Call.. Dzięki za trop.

    0
  • Pomocny post
    #8 05 Kwi 2009 21:21
    adamas_nt
    Moderator Programowanie

    Coś nie mogę znaleźć właściwego tematu. Wypróbuj taki przykładowy

    Code:
    Option Explicit
    
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Sub proba()
    Dim a As Integer
    Dim startuj As Single, koniec As Single

    startuj = Timer

    For a = 1 To 3
        MsgBox "Przebieg " & a
        Sleep 500
    Next

    koniec = Timer
    MsgBox ("wykonano w czasie: " & koniec - startuj & " sek.")

    End Sub

    U siebie musisz zadeklarować to
    Code:
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

    A to
    Code:
    Sleep 1000 'dla 1 sek.
    umieścić na początku lub końcu pętli.

    0
  • #9 05 Kwi 2009 22:06
    klops_mops
    Poziom 17  

    Ok, teraz działa, lecz wykonująca się pętla zamula cały program. Zastanawia mnie czy można to jakoś w tle obsługiwać. Spójrz na ten program: http://www.speedyshare.com/731493256.html (240 kb), tam odbiór danych z rs232 działa tak jakby w tle - nie wpływając na działanie reszty programu. Poza tym wyświetla on wszystko co dostanie, niezależnie czy dostanie to w ciągu minuty czy też po jednej godzinie. Właśnie takie coś chcę zrealizować, lecz niestety nie wiem jak..

    A może Timer był by tu pomocny? Tylko nie wiem jak go się używa..

    0
  • Pomocny post
    #10 05 Kwi 2009 22:25
    adamas_nt
    Moderator Programowanie

    Pokombinuj z ustawieniem czasu Np.

    Code:
    Sleep 100 '1/10 sek.

    Możesz też zadeklarować publiczną zmienną, liczącą ilość wywołań osobnej procedury z funkcją Sleep, wywoływać ją po zakończeniu pętli (Call czekaj). Myślę o czymś takim
    Code:
    Public licznik as Integer
    

    Private Sub czekaj()
    licznik = licznik + 1
    If licznik = 5 Then Exit Sub
    Sleep 200 '1/5sek.
    Call Button2_Click 'jeżeli nie masz tego osobno
    end Sub

    W ten sposób masz 5 pełnych przejść.

    Cytat:
    niezależnie czy dostanie to w ciągu minuty czy też po jednej godzinie
    Żeby mogło to działać w ten sposób potrzebowałbyś biblioteki, która realizowałaby "czuwanie nad portem" i uruchamiała kod w odp. momencie. Tego niestety (jeszcze) nie przerabiałem...

    P.S. Znalazłem wreszcie https://www.elektroda.pl/rtvforum/topic262285.html Wstawiasz kontrolkę Timer do formy i ustawiasz Interval na odp. wartość.
    To jest to, o czym kol. KeinXor wspomniał
    Code:
    Private Sub Timer1_Timer()
    
    MsgBox "klops_mops"
    End Sub

    0
  • Pomocny post
    #11 06 Kwi 2009 09:10
    adamas_nt
    Moderator Programowanie

    Między śniadaniem a kawą przyszło mi do głowy takie rozwiązanie:

    Wypróbuj:
    [VB] SerialPort - sprawdzanie czy coś dotarło. RS232
    (we właściwościach Timera zostaw Interval=0)

    Z takim kodem

    Code:
    Public kontr As Byte
    
    Private Sub Command1_Click()
    If kontr = 1 Then
        Command1.Caption = "Start"
        Timer1.Interval = 0
        kontr = 0
    Else
        Command1.Caption = "Stop"
        Timer1.Interval = 3000
        kontr = 1
    End If
    End Sub

    Private Sub Form_Load()
    Me.Command1.Caption = "Start"
    End Sub

    Sub Timer1_Timer()
    If kontr = 0 Then Exit Sub
    MsgBox "Uruchomienie pętli wydzielonej z kodu Button2"
    End Sub

    0
  • #12 06 Kwi 2009 19:41
    klops_mops
    Poziom 17  

    To jako tako działa, lecz moje urządzenie wysyła w nieregularnych odstępach czasowych dane. Aż dziwne by nie było czegoś co samo wykryje czy coś dotarło a jeśli tak to to wyświetli lub zgłosi jakieś przerwanie itp..

    Dzięki za chęci pomocy :)

    EDIT:

    Problem rozwiązany, użyłem Timera. Wszystko pięknie działa :)
    Dzięki za pomoc

    0