Diskuze: c# form - příjem dat po sériové lince

C# .NET .NET (C# a Visual Basic) c# form - příjem dat po sériové lince American English version English version

Avatar
Michaal.K
Člen
Avatar
Michaal.K:

Ahoj,
mám problém s příjmem dat po sériové lince...
Tento kód mám ve třídě Communication, ale příkaz this.BeginInvo­ke(new SetTextDeleg(Dis­playToUI), new object[] { indata }); mi hodí tuto chybu:

'Sender_RS232.Communication' does not contain a definition for 'BeginInvoke' and no extension method 'BeginInvoke' accepting a first argument of type 'Sender_RS232.Communication' could be found (are you missing a using directive or an assembly reference?)
private delegate void SetTextDeleg(string data);

public SerialPort serialPort1 = new SerialPort();

serialPort1.Open();         // Otevru seriovou linku

serialPort1.DataReceived += DataReceivedHandler;

public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            System.Threading.Thread.Sleep(500);
            string indata = sp.ReadExisting();
            this.BeginInvoke(new SetTextDeleg(DisplayToUI), new object[] { indata });
            //textBox1.Text += indata;
        }


        private void DisplayToUI(string displayData)
        {
            textBox1.Text += displayData.Trim();
            // textBox1.Text += displayData;
        }

Už nevím co stím. Případně prosím vysvětlení co dělám špatně. Díky

 
Odpovědět 5. února 7:57
Avatar
Nahoru Odpovědět 5. února 8:17
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Michal Štěpánek
Michaal.K:

Jj přečetl ;-) že neobsahuje definici pro BeginInvoke...
Používám tyto:

using System;
using System.IO.Ports;
using System.Net.Sockets;
using System.Windows.Forms;

Nevím kde je BeginInvoke....

 
Nahoru Odpovědět 5. února 8:55
Avatar
Odpovídá na Michaal.K
Michal Štěpánek:

Zatím jsem to nikdy nepotřeboval a ani nepoužil (zatím mi vždycky stačil BackgroundWorker), ale podle mě se BeginInvoke používá pro práci s vlákny...

Nahoru Odpovědět 5. února 9:57
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Michaal.K
Člen
Avatar
Odpovídá na Michal Štěpánek
Michaal.K:

Aha já jsem právě našel tuto část kódu na netu... Takže právě pořádně nevím jak to funguje a chtěl jsem vysvětlení proč to nejde a jak to funguje :-)

 
Nahoru Odpovědět 5. února 10:08
Avatar
Odpovídá na Michaal.K
sadlomaslox25:

no je zajimave ze me ten tvuj kod jde prelozit bez problemu :)

 
Nahoru Odpovědět 5. února 20:35
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na Michaal.K
ostrozan:

není to zrovna nejlepší řešení, co sis našel - jsou tam nesmyslné a zbytečné věci - můžeš sem dát celou třídu ?
A taky napiš, k čemu konkrétně chceš SerialPort používat - s čím a jak často budeš komunikovat.

 
Nahoru Odpovědět 7. února 12:45
Avatar
Michaal.K
Člen
Avatar
Odpovídá na sadlomaslox25
Michaal.K:

Tak to je zajímavé, že tobě to funguje. Nakonec jsem to vyřešil jinak ;-)

 
Nahoru Odpovědět 8. února 11:12
Avatar
Michaal.K
Člen
Avatar
Odpovídá na ostrozan
Michaal.K:

Tak jak jsem psal výše vyřešil jsem to jinak. Serial port chci využívat na zápis a vyčítání dat. Takže trvalá komunikace. Jde o komunikaci s multimetrem (nastavení měřících rozsahů, vyčtení změřené hodnoty, atd.). Tady je celá třída Communication:

using System;
using System.IO.Ports;
using System.Net.Sockets;
using System.Windows.Forms;

namespace Sender_RS232
{
    /// <summary>
        /// Description of Communication.
        /// </summary>
        public class Communication
        {
        private RichTextBox _displayWindow;

        public SerialPort comPort = new SerialPort();

        public RichTextBox DisplayWindow
        {
            get { return _displayWindow; }
            set { _displayWindow = value; }
        }

        // Konstruktor tridy
        public Communication()
        {
            _displayWindow = null;
            // prida udalost, ktera je vyvolana pokud dojde k zapisu do prijimaciho stringu
            comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
        }


                public void Connected()
                {
            try
            {
                comPort.Open();         // Otevru seriovou linku
            }
            catch (Exception err)
            {
                MessageBox.Show("Port nelze otevřít" + err, MainForm.appName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

                }

        void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string data = comPort.ReadExisting();
            DisplayData(data);
        }

        private void DisplayData(string data)
        {
            _displayWindow.Invoke(new EventHandler(delegate
            {
                _displayWindow.SelectedText = string.Empty;
                _displayWindow.AppendText(data + "\n");
            }));
        }
        }
}

Po stisku tlačítka ve tříde MainForm nastavím parametry linky (rychlost, název portu. atd.) a zavolám Connected() a otevřu port.
Teď již ve stringu data mám přimutý řetězec, ale vyskytl se mi nový problém :-( Potřeboval bych v metodě DisplayData(string data) zapsat data do richTextBox1, který je umístěn ve třídě MainForm. Nebo lépe předat data (řetězec) do MainForm a zde zapsat do richTextBox1. Zatím jsem to zkusil takto (viz. kod), ale nefunguje to hlásí při debagovani chybu:

NullReferenceException was unhandled
Odkaz na objekt není nastaven na instanci objektu.

Díky za rady....

 
Nahoru Odpovědět 8. února 11:29
Avatar
ostrozan
Redaktor
Avatar
Odpovídá na Michaal.K
ostrozan:

Potřeboval jsem vědět, na co to používáš, abych se ujistil, že to je opravdu nějaká jednoduchá komunikace s nějakým zařízením.
V tvém případě ,a stejně jako v 90% jiných případů se můžeš vyfláknout na nějaké Invoke a BeginInvoke - prostě je naprosto zbytečné zpracovávat příjem dat v jiném vlákně.
To má smysl, pokud načítáš nějaké kB/MB dat a trvá to dlouho, takže by to blokovalo hlavní vlákno a počítám, že ten tvůj multimetr neposílá nepřetržitý proud dat, ale pouze na vyžádání, nebo v určitých časových intervalech.

Jinak to máš celé nějak zamotané - proč ta vlastnost

public RichTextBox DisplayWindow
       {
           get { return _displayWindow; }
           set { _displayWindow = value; }
       }

?

trochu jsem si dovolil upravit tvoji třídu

public class Communication
  {
  private RichTextBox _displayWindow;

  public SerialPort comPort = new SerialPort();


  // Konstruktor tridy
  public Communication(RichTextBox _displayWindow)
  {
      //předáváš odkaz na již existující RTB, který jistě máš v hlavním Formu
      this._displayWindow = _displayWindow;

      // prida udalost, ktera je vyvolana pokud dojde k zapisu do prijimaciho stringu
      comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
  }


          public void Connected()
          {
      try
      {
          comPort.Open();         // Otevru seriovou linku
      }
      catch (Exception err)
      {
          MessageBox.Show("Port nelze otevřít" + err, MainForm.appName, MessageBoxButtons.OK, MessageBoxIcon.Error);
          return;
      }

          }

  void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
  {
      string data = comPort.ReadExisting();
      DisplayData(data);
  }

  private void DisplayData(string data)
  {

          _displayWindow.SelectedText = string.Empty;
          _displayWindow.AppendText(data + "\n");

  }
  }


  }

a ještě se zeptám - ne že by to něčemu vadilo, ale k čemu to

_displayWindow.SelectedText = string.Empty;

?

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 8. února 17:00
Avatar
Michaal.K
Člen
Avatar
Odpovídá na ostrozan
Michaal.K:

Tak jsem to podle tvých rad předělal do jednoho vlákna (do hlavního formuláře). A program už funguje. Díky za pomoc a rady....

 
Nahoru Odpovědět 15. února 13:40
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.