Seriak ve VB 2017
Pavel Hudecek
edizon na seznam.cz
Středa Červen 7 10:16:21 CEST 2017
Zrovna jsem si s tím zas hrál a dostavil se první úspěch.
> Private Shared Sub Recv(sender As Object, e As
> SerialDataReceivedEventArgs)
> Form1.Label1.Text = "recv"
> Dim indata As String = sp2.ReadExisting()
> Form1.Label1.Text = indata
> End Sub
Tady jsem smazal Shared, červeně se podtrhly Fom1, tak jsem je nahradil Me a
událost nastala. A skončila errorem u přístupu k label1.
Tak teď musím ještě zjistit, jak se to Invoke používá ve VB.
Na vlákna jsem reagoval konstatováním, že právě tomu vůbec nerozumím:-)
PH
-----Původní zpráva-----
From: Ladislav Vaiz
Koukám, že nejdůležitější část mého mailu - různá vlákna pro GUI a
DataReceived - jste statečně igoroval.
Přeložil jsem si váš příklad do C# (protože VB neovládám). Na několika
místech jsem zrušil static a padá mi to podle očekávání v DataReceived
na InvalidOperationException Operace mezi vlákny není platná: Přístup k
ovládacímu prvku Label1 proběhl z jiného vlákna než z vlákna, v rámci
kterého byl vytvořen.
Po přidání Invoke vše funguje. Ještě by chtělo reagovat na
SerialDataReceivedEventArgs.EventType.
Kompletní funkční kód v C# (změna portů a rychlosti, data do sériáku
posílána z jiného HW):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace TestSerial
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Disposed += Form1_Disposed;
Load += Form1_Load;
}
SerialPort sp1 = new SerialPort("COM8", 9600, Parity.None, 8,
StopBits.One);
SerialPort sp2 = new SerialPort("COM7", 9600, Parity.None, 8,
StopBits.One);
private void Button1_Click(object sender, EventArgs e)
{
//PortTest.Send()
sp1.ReadTimeout = 500;
sp1.WriteTimeout = 500;
sp1.Open();
sp1.WriteLine(this.tb1.Text);
//tb1 je textbox
sp1.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
//PortTest.startRd()
sp2.ReadTimeout = 500;
sp2.WriteTimeout = 500;
sp2.DataReceived += Recv;
sp2.Open();
this.Label1.Text = "start";
}
private void Recv(object sender, SerialDataReceivedEventArgs e)
{
string indata = sp2.ReadExisting();
this.Invoke((MethodInvoker)delegate
{
// Label1.Text = "recv";
Label1.Text = indata;
});
}
private void Form1_Disposed(object sender, EventArgs e)
{
sp2.Close();
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tb1 = new System.Windows.Forms.TextBox();
this.Label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// tb1
//
this.tb1.Location = new System.Drawing.Point(44, 36);
this.tb1.Name = "tb1";
this.tb1.Size = new System.Drawing.Size(100, 20);
this.tb1.TabIndex = 0;
//
// Label1
//
this.Label1.AutoSize = true;
this.Label1.Location = new System.Drawing.Point(42, 91);
this.Label1.Name = "Label1";
this.Label1.Size = new System.Drawing.Size(35, 13);
this.Label1.TabIndex = 1;
this.Label1.Text = "label1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 262);
this.Controls.Add(this.Label1);
this.Controls.Add(this.tb1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox tb1;
private System.Windows.Forms.Label Label1;
}
}
Dne 7.6.2017 v 9:28 Pavel Hudecek napsal(a):
> Tak jsem to upravil takto:
>
> Imports System.IO.Ports
>
> Public Class Form1
> Shared sp1 As New SerialPort("COM4", 19200, Parity.None, 8,
> StopBits.One)
> Shared sp2 As New SerialPort("COM5", 19200, Parity.None, 8,
> StopBits.One)
>
> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles
> Button1.Click
> 'PortTest.Send()
> sp1.ReadTimeout = 500
> sp1.WriteTimeout = 500
> sp1.Open()
>
> sp1.WriteLine(Me.tb1.Text) 'tb1 je textbox
>
> sp1.Close()
>
> End Sub
>
> Private Sub Form1_Load(sender As Object, e As EventArgs) Handles
> Me.Load
> 'PortTest.startRd()
> sp2.ReadTimeout = 500
> sp2.WriteTimeout = 500
> AddHandler sp2.DataReceived, AddressOf Recv
> sp2.Open()
> Me.Label1.Text = "start"
>
> End Sub
>
> Private Shared Sub Recv(sender As Object, e As
> SerialDataReceivedEventArgs)
> Form1.Label1.Text = "recv"
> Dim indata As String = sp2.ReadExisting()
> Form1.Label1.Text = indata
> End Sub
>
> Private Sub Form1_Disposed(sender As Object, e As EventArgs) Handles
> Me.Disposed
> sp2.Close()
> End Sub
>
> End Class
>
> Což se mi i líbí víc, jen jsem včera něco dělal špatně, že mi to nešlo dát
> do class Form1. A taky jsem nenašel form_load, i když jsem ho hledal:-)
>
> V každém případě, opakované open vždy vyvolalo error a tady to žádné
> errory nedělalo.
> Zavírání pokud se otevře jen jednou taky pro začátek nemá čemu vadit. Teď
> už tam pro jistotu je, ale výsledek je stále stejný: událost nikdy
> nenastane.
>
> Těm vláknům zatím vůbec nerozumím a celkově mám s .net minimální
> zkušenosti. Zlatej VB98:-)
>
> PH
>
> -----Původní zpráva----- From: Ladislav Vaiz
> nevím, jestli je něco z toho ta hlavní příčina, ale na kódu se mi nelíbí:
>
> 1) Událost Form.Activated se vyvolává vícekrát, například při Alt+Tab.
> Na podobnou inicializaci je nejlepší Load. Já v C# používám "override
> OnLoad" místo události, při dědění mám definované pořadí volání obsluh.
>
> 2) Událost DataReceived je volána v jiném vlákně než ve kterém běží GUI.
> Očekával bych, že nastavení Label1.Text spadne. Doporučuju použít něco
> takového (v C#):
> string indata = ...
> Form1.Invoke((MethodInvoker)delegate
> {
> form1.Label.Text = indata;
> });
> Vlákno (celý SerialPort) je pak nutné ukončit před tím, než se ukončí
> fronta zpráv pro Form1, jinak se vlákno zasekne, port zůstane otevřený...
>
> 3) Je třeba důsledně zavírat SerialPort, nejlépe přes using. Pokud to
> třeba u příjemce nejde, tak volat Dispose ve Form1.Dispose.
>
> Možná, že hlavní problém je 2), jen se vám výjimka nějak zamete pod
> koberec.
>
> ---------------------------
> Dne 7.6.2017 v 1:29 Pavel Hudecek napsal(a):
>> Dobrý den všem,
>>
>> připojil jsem dva převodníky USB-sériák, propojil je a začal si hrát s VB
>> 2017:
>>
>> První pokus jsem rozchodil, ale ten neměl eventy a to se mi nelíbí.
>>
>> Našel jsem toto:
>> https://msdn.microsoft.com/cs-cz/library/system.io.ports.serialport.datareceived(v=vs.110).aspx
>>
>> A tam uvedenou ukázku upravil na:
>>
>> Imports System.IO.Ports
>>
>> Public Class Form1
>>
>> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles
>> Button1.Click
>> PortTest.Send()
>> End Sub
>>
>> Private Sub Form1_Activated(sender As Object, e As EventArgs) Handles
>> Me.Activated
>> PortTest.startRd()
>> End Sub
>>
>> End Class
>>
>> Public Class PortTest
>> Shared sp1 As New SerialPort("COM4", 19200, Parity.None, 8,
>> StopBits.One)
>> Shared sp2 As New SerialPort("COM5", 19200, Parity.None, 8,
>> StopBits.One)
>>
>> Public Shared Sub startRd()
>> sp2.ReadTimeout = 500
>> sp2.WriteTimeout = 500
>> AddHandler sp2.DataReceived, AddressOf Recv
>> sp2.Open()
>> Form1.Label1.Text = "start"
>>
>> End Sub
>>
>> Public Shared Sub Send()
>> sp1.ReadTimeout = 500
>> sp1.WriteTimeout = 500
>> sp1.Open()
>>
>> sp1.WriteLine(Form1.tb1.Text) 'tb1 je textbox
>>
>> sp1.Close()
>> End Sub
>>
>> Private Shared Sub Recv(sender As Object, e As
>> SerialDataReceivedEventArgs)
>> Form1.Label1.Text = "recv"
>> Dim indata As String = sp2.ReadExisting()
>> Form1.Label1.Text = indata
>> End Sub
>> End Class
>>
>> Po spuštění se label nastaví na "start", po stisku buttonu blikají LEDky
>> na obou převodnících, ale label se nemění, takže event vůbec nenastává.
>> Poradí někdo, proč?
>
> _______________________________________________
> HW-list mailing list - sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
_______________________________________________
HW-list mailing list - sponsored by www.HW.cz
Hw-list na list.hw.cz
http://list.hw.cz/mailman/listinfo/hw-list
Další informace o konferenci Hw-list