[C#]COM-port uitlezen, krijg het niet werkend

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Anoniem: 321366

Topicstarter
Beste Tweakers,

Na een aantal dagen al opzoek te zijn naar een oplossing nogsteeds nix gevonden.

Eerst even een update voor de software: ik maak gebruik van Microsoft Visual C# 2008 Express
application word geschreven voor een WPF.

ik wil de seriele poort van mijn PC uitlezen en weergeven in een textbox.
ik krijg nog errors op de Invoke op regel 66 en e ReadExisting() op regel 60.
mijn code ziet er op het moment zo uit:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Data;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace rolstoel_interface
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        string comport = "";
        int comSpeed = 0;
        string rxMessage;

        public Window1()
        {
            InitializeComponent();
        }

        //Button afhandelingen
        private void connect_Click(object sender, RoutedEventArgs e)
        {
            //lees de combobox comSelect uit en zet deze in de variable comport
            comport = comSelect.SelectedItem.ToString();   
            //inhoud comport = "System.Windows.Controls.ComboBoxItem: COMx" (x = 1 tot 5)
            comport = comport.Replace("System.Windows.Controls.ComboBoxItem: ", "");
            

            //lees de combobox baudrateData uit en zet deze in de variable comSpeed
            string comSpeedString = baudrateData.SelectedItem.ToString();
            //inhoud comSpeedString = "System.Windows.Controls.ComboBoxItem: xxxx Baud" (met XXXX de baud waarde)
            comSpeedString = comSpeedString.Replace("System.Windows.Controls.ComboBoxItem: ", "");
            comSpeedString = comSpeedString.Replace(" Baud", "");
            comSpeed = Int32.Parse(comSpeedString);
            conCom.Content = "Connected to: " + comport + " at " + comSpeed + " Baud";

            SerialPort port = new SerialPort(comport, comSpeed, Parity.None, 8, StopBits.One);
            port.DtrEnable = true;
            port.Open();
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
        }

        private void DisplayText(object sender, EventArgs e)
        {
            rxMessage = port.ReadExisting();
            rxRS232.AppendText(rxMessage);
        }

        private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            this.Invoke(new EventHandler(DisplayText));
        }

        private void send_Click(object sender, RoutedEventArgs e)
        {
            try
            {
             string dataSend = txRS232.Text + "\r";
             
             using (SerialPort sp_w = new SerialPort(comport))
                   {
                    sp_w.BaudRate = comSpeed;
                    sp_w.Parity = Parity.None;
                    sp_w.ReadTimeout = 10;
                    sp_w.StopBits = StopBits.One;
                    if (!(sp_w.IsOpen))
                        sp_w.Open();
                    sp_w.Write(dataSend);
                   }

             rxRS232.Text += dataSend.ToString();
            }
            catch(ArgumentException)
            {
                MessageBox.Show("Please connect to a COM-port");
            }

            txRS232.Clear();
        }

        private void btnReset_Click(object sender, RoutedEventArgs e)
        {
            txRS232.Clear();
            rxRS232.Clear();
        }
    }
}



is er iemand die mij verder kan helpen??

alvast bedankt!
RedElectric

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Niet op deze manier ieder geval
ik krijg nog errors op de Invoke op regel 66 en e ReadExisting() op regel 60.
Als je errors krijgt dan willen we natuurlijk ook weten welke errors. Verder willen we graag dat je je probleem isoleert. Het lezen van data uit een COM port kun je in een paar regeles doen, en dus is het ook niet nodig om meer dan 100 regels code te plaatsen.

Lees Een goede topicstart: De Quickstart even door en post dan even alle relevante informatie.

[ Voor 4% gewijzigd door Woy op 08-10-2009 13:32 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Zowel 'port' (regel 52) als 'sp_w' (regel 75) proberen allebei dezelfde COM poort te benaderen. Daarnaast is 'port' een lokale variabele van de methode 'Connect_Click' en bestaat dus niet meer op het moment dat jij data stuurt naar de comport..

dit zijn even twee punten die mij direct mij aandacht trokken.

Maar de manier waarop je het geselecteerde combobox item uitleest en vervolgens verwerkt doet mij vermoeden dat een goed c# boek geen overbodige luxe is..

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19:47

Haan

dotnetter

Niemand_Anders schreef op donderdag 08 oktober 2009 @ 13:43:

Maar de manier waarop je het geselecteerde combobox item uitleest en vervolgens verwerkt doet mij vermoeden dat een goed c# boek geen overbodige luxe is..
Die vond ik inderdaad ook al vreemd, maar in WPF werkt het blijkbaar iets anders dan een Forms applicatie, dat wist ik ook niet. Snelle google leert dat dit wat netter is:
C#:
1
2
ComboBoxItem item = (ComboBoxItem)comSelect.SelectedItem;
comport = item.Content;

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

Anoniem: 321366

Topicstarter
al bedankt voor de eerste tips :)

verder zoals gevraagt even een en ander verduidelijkt.

Ik ben bezig met het schrijven van een applicatie die de com-port uit moet lezen en de ontvangen data in een textbox(rxRS232 genaamd) weer geeft. Het zenden van data werkt wel, ik kan de com-port openen en data naar een andere terminal verzenden.

Om de comport in te openen heb ik de volgende code:
C#:
1
2
3
4
5
6
7
8
9
 private void connect_Click(object sender, RoutedEventArgs e)
 {
  // Hier staat nog wat code voor het ophalen van de gegeven voor de COM-port, dit werkt goed.
  // onderstaande code levert volgens mij geen problemen op
  SerialPort port = new SerialPort(comport, comSpeed, Parity.None, 8, StopBits.One);
  port.DtrEnable = true;
  port.Open();
  port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
 }


Om de data op te halen maak ik gebruik van het DataReceived-event. Deze is reeds aangemaakt in het vorige stuk code. De port_DataReceived methode moet nu afgehandeld worden op het moment dat er data op de seriele port ontvangen word. Nu geeft de volgende code een Error:
C#:
1
2
3
4
   private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            this.Invoke(new EventHandler(DisplayText));
        }

Error:'rolstoel_interface.Window1' does not contain a definition for 'Invoke' and no extension method 'Invoke' accepting a first argument of type 'rolstoel_interface.Window1' could be found (are you missing a using directive or an assembly reference?)

Omdat ik werk met een Invoke, moet ik ook nog even een EventHandel aanmaken (zie vorige code).
De methode die hiervoor gebruikt wordt ziet er zo uit:
C#:
1
2
3
4
5
private void DisplayText(object sender, EventArgs e)
        {
            rxMessage = port.ReadExisting();
            rxRS232.AppendText(rxMessage);
        }

Deze geeft ook nog een error en wel op regel 3:
Error: 'System.Windows.Controls.Label' does not contain a definition for 'ReadExisting' and no extension method 'ReadExisting' accepting a first argument of type 'System.Windows.Controls.Label' could be found (are you missing a using directive or an assembly reference?)

Ik heb op het moment echt geen idee mee waar de fout zit.
Ik heb al verschillende oplossingen van het net geprobeerd, maar deze werken niet.

ik hoop dat er mensen zijn die mij verder opweg kunnen helpen!

alvast bedank!
RedElectric

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19:47

Haan

dotnetter

Anoniem: 321366 schreef op donderdag 08 oktober 2009 @ 13:56:
al bedankt voor de eerste tips :)

C#:
1
2
3
4
5
private void DisplayText(object sender, EventArgs e)
        {
            rxMessage = port.ReadExisting();
            rxRS232.AppendText(rxMessage);
        }

Deze geeft ook nog een error en wel op regel 3:
Error: 'System.Windows.Controls.Label' does not contain a definition for 'ReadExisting' and no extension method 'ReadExisting' accepting a first argument of type 'System.Windows.Controls.Label' could be found (are you missing a using directive or an assembly reference?)
Mijn gok is dat er een Label op je scherm staat die port heet.. Het zal in ieder geval niet de SerialPort zijn uit je connect_click methode, want die heb je alleen lokaal gedefinieerd..

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

Anoniem: 321366

Topicstarter
Hoe krijg ik dat ding zover dat hij hem daarbuiten ook ziet??

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Anoniem: 321366 schreef op donderdag 08 oktober 2009 @ 13:56:
Error:'rolstoel_interface.Window1' does not contain a definition for 'Invoke' and no extension method 'Invoke' accepting a first argument of type 'rolstoel_interface.Window1' could be found (are you missing a using directive or an assembly reference?)
Kijk daar hebben we ( en jij dus ook ;) ) wat aan. Het probleem heeft dus niks met de SerialPort communcitie te maken, maar gaat mis op het feit dat je de Invoke methode niet juist aanroept.

Verander het bijvoorbeeld eens in
C#:
1
2
rxMessage = port.ReadExisting(); 
this.Invoke((MethodInvoker)delegate{ AppendTextToMyTextBox(rxMessage); });


edit:
Ik bedenk me trouwens net dat jouw code volgens mij ook gewoon zou moeten compilen, Window1 is gewoon een Form neem ik aan.

[ Voor 15% gewijzigd door Woy op 08-10-2009 14:26 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19:47

Haan

dotnetter

Anoniem: 321366 schreef op donderdag 08 oktober 2009 @ 14:09:
Hoe krijg ik dat ding zover dat hij hem daarbuiten ook ziet??
Door hem niet als lokale, maar als instance variabele te declareren 8)7
Woy schreef op donderdag 08 oktober 2009 @ 14:21:

edit:
Ik bedenk me trouwens net dat jouw code volgens mij ook gewoon zou moeten compilen, Window1 is gewoon een Form neem ik aan.
Het is een WPF applicatie, dus Window1 is een Window, die niet van Form erft.

[ Voor 39% gewijzigd door Haan op 08-10-2009 14:32 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Idd, je zult er zoals Haan aangeeft voor moeten zorgen dat je de variabele beschibaar hebt in de scope waar je hem nodig hebt.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Anoniem: 321366

Topicstarter
Dus als ik hem in mijn hele class ter beschikking wil hebben (dus in de connect_Click en andere methodes) moet ik heb voor de "public window1()" declaren? of hoe moet ik dat anders doen?

sorry, maar ben nog redelijk een leek met C# en object georienteerd programmeren.
kom uit de wereld van C en Assably ;) vandaar dak naar de hulp vraag :)

ps. met de invoke aan de haal geweest, maar geeft nogsteeds de zelfde foutmelding... krijg er zelfs 2 bij.
het betreft de MethodInvoker en AppendTextToMyTextBox.
en window1 is een WPF-from...

[ Voor 22% gewijzigd door Anoniem: 321366 op 08-10-2009 14:38 ]


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 19:47

Haan

dotnetter

Anoniem: 321366 schreef op donderdag 08 oktober 2009 @ 14:35:
Dus als ik hem in mijn hele class ter beschikking wil hebben (dus in de connect_Click en andere methodes) moet ik heb voor de "public window1()" declaren? of hoe moet ik dat anders doen?

sorry, maar ben nog redelijk een leek met C# en object georienteerd programmeren.
kom uit de wereld van C en Assably ;) vandaar dak naar de hulp vraag :)
Ik zou zeggen doe eens [google=c# tutorial] ;)

@hieronder, begin dan eens bij het begin van de tutorials en werk er doorheen, dan had je die vraag echt wel geweten, veel meer basic OO kan het niet worden namelijk ;)

[ Voor 14% gewijzigd door Haan op 08-10-2009 14:43 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

Anoniem: 321366

Topicstarter
ben al met meerdere tutorials aan de haal geweest, anders was ik niet zo ver gekomen als dat ik nu ben ;)

op het moment dat ik de comport op deze manier binnen de class defineer krijg ik een foutmelding :S
C#:
1
SerialPort port = new SerialPort(comport, comSpeed, Parity.None, 8, StopBits.One);

A field initializer cannot reference the non-static field, method, or property 'rolstoel_interface.Window1.comport'
A field initializer cannot reference the non-static field, method, or property 'rolstoel_interface.Window1.comSpeed'

Waarom mag ik deze variablen daar niet gebruiken??

[ Voor 70% gewijzigd door Anoniem: 321366 op 08-10-2009 14:45 ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Anoniem: 321366 schreef op donderdag 08 oktober 2009 @ 14:35:
Dus als ik hem in mijn hele class ter beschikking wil hebben (dus in de connect_Click en andere methodes) moet ik heb voor de "public window1()" declaren? of hoe moet ik dat anders doen?
In winforms zou je het zo (ongeveer) kunnen doen. Je hebt SerialPort nodig in de scope van je Form, dus dan moet je hem daar ook declareren.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public partial class MyForm : Form
{
    private SerialPort port;
    
    public MyForm ()
    {
        InitializeComponent();
    }

    private void btnConnect_Click(object sender, EventArgs e)
    {
        port = new SerialPort();
        //Etc....
        port.DataReceived += port_DataReceived;
    }
    
    private void btnDisconnect_Click(object sender, EventArgs e)
    {
        port.Close();
        port.Dispose();
        port = null;
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        string text = port.ReadExisting();
        Invoke((MethodInvoker) delegate { AppendSomeText(text); });
    }

    void AppendSomeText(string text)
    {
        txtRS232Data.AppendText(text);
    }
}

Hier zul je natuurlijk nog wel wat controle toe moeten voegen zodat je niet 2 keer dezelfde COM port probeert te openen en dat je zeker weet dat hij weer netjes gesloten en opgeruimd word.
ps. met de invoke aan de haal geweest, maar geeft nogsteeds de zelfde foutmelding... krijg er zelfs 2 bij.
het betreft de MethodInvoker en AppendTextToMyTextBox.
en window1 is een WPF-from...
In WPF werkt het invoken inderdaad anders. Zoek maar eens op "Dispatcher".
A field initializer cannot reference the non-static field, method, or property 'rolstoel_interface.Window1.comport'
A field initializer cannot reference the non-static field, method, or property 'rolstoel_interface.Window1.comSpeed'
Dit zijn echt basic dingen, als je niet inziet waarom je die compiler errors krijgt, dan zul je toch echt eens een goed boek moeten pakken, en vanaf het begin beginnen met lezen. Dit zijn erg basic scope issues.

[ Voor 17% gewijzigd door Woy op 08-10-2009 14:47 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Anoniem: 321366

Topicstarter
oke bedankt voor de tip :) zal eens gaan zoeken en jouw programmatje in een gewonne winform zetten...

misschien toch maar mijn programma omzetten naar winform... kom hier veel meer info over tegen :S

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je moet je probleem eigenlijk niet in de context van WinForms/WPF zien. Blijkbaar heb je gewoon nog niet door wat begrippen als scope inhouden. Het is dan eigenlijk te hoog gegrepen om meteen proberen een WinForms/WPF applicatie te maken. Probeer eerst eens gewoon een simpel Console applicatie te maken, waar je nog geen rekening hoeft te houden met dingen als threading en invoking.

Begin eens rustig bij het begin, en probeer dat uit te bouwen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 23:22
Anoniem: 321366 schreef op donderdag 08 oktober 2009 @ 14:35:
sorry, maar ben nog redelijk een leek met C# en object georienteerd programmeren.
kom uit de wereld van C en Assably ;) vandaar dak naar de hulp vraag :)
Begrippen als de scope van een variabele komen ook voor in C, voor de rest zou je eens wat vaker op F1 kunnen drukken als je het mij vraagt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1