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