Jak vyčíst data ze SerialPortu   otázka

VB.NET

Zdravím.

Vím, že zde už často otravuji s dotazy, ale řeším dost zásadní problém.

Problém, který už byl i zde často popisovaný, ale mně se nedaří pořád ho vyřešit. :-(

Jde mi o to, že potřebuji vyčíst data, nebo aspon hlavičku, ze Serial Portu.

Právě kvůli tomhle tomu jsem začal vytvářet projekt.

Sice se mi přímo nebo s vaší pomocí podařilo naprogramovat omáčku okolo, tak to hlavní, kvůli čemu jsem ten program začal vytvářet, tak mi pořád nechodí.

Zatím se mi povedlo poslat příkaz do SerialPortu, ale komunikaci z druhé strany nedostávám a už jsem z toho zoufalý.

Snad se najde někdo, kdo se v tomhle hlavním a důležitém kousku kodu vyzná a dokáže mi poradit.

Díky moc.

Private Sub BtnOdecet_Click(sender As System.Object, e As System.EventArgs) Handles BtnOdecet.Click
...
ComSerialPort.PortName = CmbCisloPortu.Text
ComSerialPort.BaudRate = CInt(CmbRychlostStartovaci.Text)
ComSerialPort.Parity = Parity.Even
ComSerialPort.StopBits = StopBits.One
ComSerialPort.DataBits = 7
ComSerialPort.Handshake = Handshake.None
ComSerialPort.RtsEnable = True
AddHandler ComSerialPort.DataReceived, AddressOf DataReceivedHandler
ComSerialPort.Open()
VarString = "/?!" + Chr(13) + Chr(10)
ComSerialPort.Write(VarString) 'Zde posílám příkaz do SerialPortu.
RtbLog.AppendText("*****" & " ")
RtbLog.AppendText(DateTime.Now.ToString("dddd, d. MMMM yyyy H:mm:ss"))
RtbLog.AppendText(" " & "*****")
RtbOdecet.AppendText(VarString)  '(ComSerialPort.ReadLine & vbCrLf)
RtbLog.Text = RtbLog.Text & Environment.NewLine & RtbOdecet.Text
RtbLog.AppendText(Environment.NewLine)
ComSerialPort.Close()
...
End Sub

Private Sub ComSerialPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
    Dim sp As SerialPort = CType(sender, SerialPort)
    Dim indata As String = sp.ReadExisting()
    TslZprava.Text = "text"
    RtbOdecet.Text = "text"
    RtbOdecet.Text = indata
End Sub
nahlásit spamnahlásit spam 0 odpovědětodpovědět

To jsem zadal já, jen jsem se doma zapomněl přihlásit se svým novým účtem. ;-) :-(

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Událost DataReceived nastane v druhém vlákně a má se použít Invoke pro přístup k prvkům formuláře v prvním vlákně. Zkuste příklad viz. link níže, třeba to pomůže.

How do I implement Serial COM Port communication?

https://social.msdn.microsoft.com/Forums...

Public Class Form1
 
    Dim inputData As String = ""
    Public Event DataReceived As IO.Ports.SerialDataReceivedEventHandler
 
    Private Sub Form1_Load(ByVal sender As System.Object, _
                   ByVal e As System.EventArgs) Handles MyBase.Load
        'Set values for some properties
        SerialPort1.PortName = "COM1"
        SerialPort1.BaudRate = 9600
        SerialPort1.Parity = IO.Ports.Parity.None
        SerialPort1.DataBits = 8
        SerialPort1.StopBits = IO.Ports.StopBits.One
        SerialPort1.Handshake = IO.Ports.Handshake.None
        SerialPort1.RtsEnable = True
 
        ' Open the Serial Port
        SerialPort1.Open()
 
        'Writes data to the Serial Port output buffer 
        If SerialPort1.IsOpen = True Then
            SerialPort1.Write("MicroCommand")
        End If
    End Sub
 
    ' Receive data from the Serial Port
    Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, _
                      ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
                      Handles SerialPort1.DataReceived
        inputData = SerialPort1.ReadExisting 'or SerialPort1.ReadLine
        Me.Invoke(New EventHandler(AddressOf DoUpdate))
    End Sub
 
    'Show received data on UI controls and do something
    Public Sub DoUpdate()
        TextBox1.Text = TextBox1.Text & inputData
    End Sub
 
    Private Sub Form1_FormClosed(ByVal sender As System.Object, _
                   ByVal e As System.Windows.Forms.FormClosedEventArgs) _
                   Handles MyBase.FormClosed
        ' Close the Serial Port
        SerialPort1.Close()
    End Sub
 
End Class
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak mi to nefunguje. :-(

Musel jsem sice tvůj kod upravit dle mých zadaných názvů, a stejně to nejde.

Jde totiž o to, že když potřebuji vyčíst data ze zařízení připojeného přes SerialPort, tak do něj musím poslat příkaz a on by mi měl vrátit odezvu, na jaké rychlosti má tedy číst včetně hlavičky z onoho zařízení a já mu řeknu, aby mi poslal všechna uložená data a zobrazil mi je v tom RichTextBoxu včetně průběhu komunikace mezi programem a oním zařízením.

... a v tom je právě celý problém, že nevím, jak vyčíst data z toho zařízení a jak ona data včetně komunikace zobrazit v RTB. :-(

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Lituji, ale proč to nejde, vůbec netuším.

Většinou muselo být správně nastaveno na obou stranách, aby komunikace fungovala, nesetkal jsem se, aby 'ono' zařízení zaslalo v odezvě nastavení rychlosti. Je správně propojovací kabel, někdy se zapojení liší, např. některé žíly nutno překřížit. Zkuste o zařízení získat podrobné info, jak má přenos probíhat včetně nastavení parametrů přenosu a zapojení kabelu..

Možná to nejdřív zkusit přes něco jako hyperterminál, zda-li zařízení komunikuje:

http://cs.tipsandtricks.tech/hypertermin...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tohle je vyčítání přes Optohlavu přes USB kabel jako COM port.

Program vyšle dotaz do zařízení, že ho chce vyčíst, zařízení mu pošle svou hlavičku/záhlaví s tím, že je ochotno komunikovat na určité rychlosti, ale já mu řeknu, že chci komunikovat na jiné - např. - a pak se už probíhá sent a received, které se zobrazují v onom RTB.

Funguje mi detekce všech dostupných COM portů, poslání dotazu na tom vybraném také, ale už nevím, jak dostat přijatý příkaz z onoho zařízení zpět do programu; aspon to záhlaví, kdyby se vyčetlo a zobrazilo. :-(

Pak bych už věděl, že jsem na dobré cestě.

S tím je spojené i logování do dalšího RTBoxu, které jsem řešil v jiném vlákně a zobrazování posledních poslaných příkazů do zařízení a jejich také logování.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak se mi už podařilo vyčíst data z toho zařízení přes optohlavu, jenže zatím jen pořád při základní rychlosti 300Bd, ale už nevím, jak mám naprogramovat kod, aby po odeslání příkazu "Enter" a přijetí hlavičky ze zařízení program poslal příkaz na zvýšení rychlosti dle nastavené rychlosti z ComboBoxu. :-(

Také nevím, do jakého vlákna mám tenhle příkaz zadat a také nevím, do jakého vlákna mám napsat ukončení komunikace z COM … ComSerialPort.Close() . :-(

Public Class FrmSpravaElektroMeru
	Dim VarSerialPort As Array

Private Sub FrmSprava_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
		VarSerialPort = IO.Ports.SerialPort.GetPortNames()
		TmrCasovac.Interval = 100
		CmbCisloPortu.Items.AddRange(VarSerialPort)
		ComSerialPort.Parity = IO.Ports.Parity.None
		ComSerialPort.DataBits = 7
		ComSerialPort.StopBits = IO.Ports.StopBits.One
		ComSerialPort.Handshake = IO.Ports.Handshake.None
		ComSerialPort.RtsEnable = True
		RdbViditelneHeslo.Select()
		RdbObeCisla.Select()
		RdbCesky.Select()
		CmbRychlostStartovaci.Items.Add("    300")
		CmbRychlostStartovaci.Items.Add("    600")
		CmbRychlostStartovaci.Items.Add("  1200")
		CmbRychlostStartovaci.Items.Add("  2400")
		CmbRychlostStartovaci.Items.Add("  4800")
		CmbRychlostStartovaci.Items.Add("  9600")
		CmbRychlostStartovaci.Items.Add("19200")
		CmbRychlostStartovaci.Text = CStr(CmbRychlostStartovaci.Items.Item(0))
		CmbRychlostStartovaci.SelectedIndex = 0
		CmbRychlostKomunikace.Items.Add("    300")
		CmbRychlostKomunikace.Items.Add("    600")
		CmbRychlostKomunikace.Items.Add("  1200")
		CmbRychlostKomunikace.Items.Add("  2400")
		CmbRychlostKomunikace.Items.Add("  4800")
		CmbRychlostKomunikace.Items.Add("  9600")
		CmbRychlostKomunikace.Items.Add("19200")
		CmbRychlostKomunikace.Text = CStr(CmbRychlostKomunikace.Items.Item(0))
		CmbRychlostKomunikace.SelectedIndex = 4
		CmbCisloPortu.Text = CStr(CmbCisloPortu.Items.Item(0))
		CmbCisloPortu.SelectedIndex = 0
		CmbCisloPortu.Text = CStr(CmbHeslo.Items.Item(0))
	End Sub

Private Sub BtnOdecet_Click(sender As System.Object, e As System.EventArgs) Handles BtnOdecet.Click
		BtnOdecet.Enabled = False
		RtbOdecet.Clear()
		TbcVystupDat.SelectedTab = TbpOdecet

		'Zde bude kod, kde se vyčtou data a zobrazí se vpravo v okně "Odečet".
		ComSerialPort.PortName = CmbCisloPortu.Text
		ComSerialPort.BaudRate = Int(CmbRychlostStartovaci.Text)
		ComSerialPort.Parity = Parity.Even
                ComSerialPort.StopBits = StopBits.One
		ComSerialPort.DataBits = 7
		ComSerialPort.Handshake = Handshake.None
		ComSerialPort.RtsEnable = True
                ComSerialPort.ReadTimeout = 3000
                ComSerialPort.Open()
		VarString = "<<< " & "/?!" + Chr(13) + Chr(10)
		ComSerialPort.Write(VarString)
		RtbLog.AppendText("*****" & " ")
		RtbLog.AppendText(DateTime.Now.ToString("dddd, d. MMMM yyyy H:mm:ss"))
		RtbLog.AppendText(" " & "*****")
		RtbOdecet.AppendText(VarString)
	End Sub

	Private Sub ComSerialPort_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles ComSerialPort.DataReceived
		VarString = ComSerialPort.ReadLine
		Me.Invoke(New EventHandler(AddressOf DoUpdate))
	End Sub

	Public Sub DoUpdate()
		'RtbOdecet.Text = RtbOdecet.Text & VarString
		RtbOdecet.Text = RtbOdecet.Text & ">>> " & VarString

		'ComSerialPort.Close()
        End Sub
End Class
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Blahopřeji k částečnému úspěchu se připojit na startovací rychlosti.

Kdysi zde byla snaha o něco podobného :

https://www.dotnetportal.cz/forum/tema/2...

Po obdržení hlavičky zřejmě chcete odeslat příkaz na změnu rychlosti,

avšak následně bude asi třeba změnit rychlost právě otevřeného portu.

Pokud budete měnit rychlost bude to zřejmě problematické při otevřeném portu,

dost možná bude nutné ho zavřít, změnit rychlost a zase otevřít, možná to lze

dokázat nějakým fíglem, zkuste pohledat na netu, nejste první, komu to třeba.

Přidejte pro testování třeba tlačítko a po obdržení čehosi zkuste provést změnu

rychlosti, bude-li možné to zrealizovat na obou stranách.

Nevím, zda-li to bude fungovat, ale pokud by jste měl dvě komponenty serialport,

první by odeslal příkaz, obdržel rychlost, poslal příkaz na změnu a zavřel se.

Následně by se druhý připojil na nové rychlosti a obdržel data. Možná zkusit.

Ačkoli bych vám rád pomohl, není to v mých silách, dotaz bych také zkusil na nějaké

specializované fórum nebo kontaktovat výrobce zařízení, třeba již mají zkušenosti,

jak komunikaci naprogramovat nebo vlastní komponentu...

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback