Laden...

Daten über serielle Schnittstelle von Arduino!

Erstellt von DerPete vor 8 Jahren Letzter Beitrag vor 8 Jahren 7.423 Views
D
DerPete Themenstarter:in
4 Beiträge seit 2015
vor 8 Jahren
Daten über serielle Schnittstelle von Arduino!

Hallo, ich bekomme Daten von einem Arduino über die serielle Schnittstelle geschickt und stelle sie in einer richtextbox dar.

Mein Problem ist, daß die Daten die empfangen werden hintereinander weggeschrieben werden. Ich hätte aber gerne, daß bei jedem neuen Empfang die vorherigen Darten überschrieben werden.

Wie mache ich das?

Vielen Dank!

Der Pete


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CronoMonitor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.Open();
            timer1.Start();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            String A = serialPort1.ReadExisting();
            richTextBox1.AppendText(A);

            
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}

L
95 Beiträge seit 2009
vor 8 Jahren

Hey,
die böse Antwort wäre: Lerne C# programmieren und beschäftige dich mit Windows Forms.

Die nette Antwort: Ich habe da mal in einem anderen Forum ein Beispiel für den SerialPort mit C# und Windowsforms erstellt:

http://www.roboternetz.de/community/threads/53894-Beispiel-Anwendung-C-Zugriff-auf-SerialPort

Alternativ hier im Forum:

Template SerialPort

P
27 Beiträge seit 2015
vor 8 Jahren

So habe ich es damals gelöst, inwiefern du damit was anfangen kannst weiß ich jetzt natürlich nicht,
du benötigst einen sogenannten Terminator, welcher eben das letzte Zeichen abfängt, bei mir carriage return


        SerialPort serial = new SerialPort();
        string tString = string.Empty;
        public static string serialoutput = string.Empty;
        private byte _terminator = 0x0D;

 public void serialcon()
        {

            serial.PortName = "COM7"; //Com Port Name                
            serial.BaudRate = 19200; //COM Port Speed
            serial.Handshake = System.IO.Ports.Handshake.None;
            serial.Parity = Parity.None;
            serial.DataBits = 8;
            serial.StopBits = StopBits.One;
            serial.ReadTimeout = 200;
            serial.WriteTimeout = 50;
            serial.Open();
            log.WriteMessage("Serialport succesfully opened");
            serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Recieve);
        }

        private delegate void UpdateUiTextDelegate(string text);

        private void Recieve(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {// Collecting the characters received to our 'buffer' (string).
                byte[] buffer = new byte[serial.ReadBufferSize];
                int bytesRead = serial.Read(buffer, 0, buffer.Length);
                tString += Encoding.ASCII.GetString(buffer, 0, bytesRead);

                if (tString.IndexOf((char)_terminator) > -1)
                {
                    string workingString = tString.Substring(0, tString.IndexOf((char)_terminator));
                    tString = tString.Substring(tString.IndexOf((char)_terminator));

                    serialoutput = workingString;

                    Dispatcher.Invoke(DispatcherPriority.Send, new UpdateUiTextDelegate(WriteData), serialoutput);
                }
            }
            catch
            { }
            finally
            {
                tString = string.Empty;
            }
        }
 private void WriteData(string text)
        {
             //Do some usefull stuff
         }

D
DerPete Themenstarter:in
4 Beiträge seit 2015
vor 8 Jahren

Danke!

Ich schicke immer "#" vorraus.

Die Anwendung häng sich aber immer auf wenn ich das so ausführe!


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CronoMonitor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.Open();
            timer1.Start();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            String A = serialPort1.ReadExisting();

            string ausgabe = string.Empty;
            do
            {
                ausgabe += A;

            } while (A != "#");

            richTextBox1.AppendText(A);

            
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}

1.378 Beiträge seit 2006
vor 8 Jahren

Hallo DerPete,

Danke!

Ich schicke immer "#" vorraus.

Die Anwendung häng sich aber immer auf wenn ich das so ausführe!

was auch auf den ersten Blick klar ist, wenn man sich den Code ansieht.

Mit einer Raute als Löschzeichen könntest du es so probieren:


        private void timer1_Tick(object sender, EventArgs e)
        {
            String input = serialPort1.ReadExisting();

            int i = input.IndexOf("#");

            if(i >= 0)
            {
               richTextBox1.Clear();
            }            

            if(i + 1 > input.Length)
            {
               richTextBox1.AppendText(input.SubString(i + 1));
            }

        }

Lg, XXX

T
415 Beiträge seit 2007
vor 8 Jahren

Es sieht ganz danach aus, dass du hier eine Endlos-Schleife produzierst:


 do
{
    ausgabe += A;
} while (A != "#");

Enthält der String den du kurz davor ausgelesen hast kein '#' dann wird nie abgebrochen.

D
DerPete Themenstarter:in
4 Beiträge seit 2015
vor 8 Jahren

hallo xxxprod

Ich bekomme eine Fehlermeldung die besagt das:

Fehler 1 'string' enthält keine Definition für 'SubString', und es konnte keine Erweiterungsmethode 'SubString' gefunden werden, die ein erstes Argument vom Typ 'string' akzeptiert (Fehlt eine Using-Direktive oder ein Assemblyverweis?). C:\Users\Pavilion\documents\visual studio 2013\Projects\CronoMonitor\CronoMonitor\Form1.cs 44 47 CronoMonitor


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CronoMonitor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.Open();
            timer1.Start();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
        }
        
        private void timer1_Tick(object sender, EventArgs e)
        {
            String input = serialPort1.ReadExisting();

            int i = input.IndexOf("#");

            if(i >= 0)
            {
               richTextBox1.Clear();
            }

            if(i + 1 > input.Length)
            {
                richTextBox1.AppendText(input.SubString(i + 1));
            }

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}

H
114 Beiträge seit 2007
vor 8 Jahren

'string' enthält keine Definition für 'SubString'

Die Methode heißt ja auch Substring ..

Grüße, HiGHteK

T
708 Beiträge seit 2008
vor 8 Jahren

Hallo DerPete,

wie schon in dem 2. Post angesprochen, kann ich nur den folgenden Link empfehlen:
Template SerialPort
Denn dort wird kein Timer verwendet, sondern ein Event des ComPorts. Das bedeutet, Du fragst nicht sinnlos jede Sekunde an, ob Daten vorhanden sind, sondern der Port meldet sich quasi von selbst, wenn es was zu lesen gibt.
Das hat neben dem Verhindern von sog. polling auch den Vorteil, dass Du bei korrekter Implementierung* jedes mal den gesamten Wert des RTF überschreiben kannst. Also auf Append verzichten kannst.

*Der ComPort kann u.u. auch die Daten aufsplitten, daher ist man erst mit einem fest definierten Endzeichen auf der ganz sicheren Seite. Sollte bei kleineren Datenpaketen aber erstmal irrelevant sein.

D
DerPete Themenstarter:in
4 Beiträge seit 2015
vor 8 Jahren

Danke!!!

Ich bekome aber immer noch keine Ausgabe!


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CronoMonitor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.Open();
            timer1.Start();
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            
        }
        
        private void timer1_Tick(object sender, EventArgs e)
        {
            String input = serialPort1.ReadExisting();

            int i = input.IndexOf("#");

            if(i >= 0)
            {
               richTextBox1.Clear();
            }

            if(i + 1 > input.Length)
            {
                richTextBox1.AppendText(input.Substring(i + 1));
            }

        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }
    }
}

T
415 Beiträge seit 2007
vor 8 Jahren

Dann solltest du mal den Debugger verwenden und schauen, ob überhaupt Daten in deiner input Variable stehen [Artikel] Debugger: Wie verwende ich den von Visual Studio?

1.378 Beiträge seit 2006
vor 8 Jahren

Hallo DerPete,

hach, da hat sich ein Tippfehler sowie ein Bedingungsfehler eingeschlichen. Wenn du dich ganz fest anstrengst kommst du vielleicht auch selber drauf.

Lg, XXX

S
322 Beiträge seit 2007
vor 8 Jahren

Hallo,

wieso gehst Du überhaupt den Umweg über einen Timer?
SerialPort hat doch ein Event "DataReceived" welches ausgelöst wird wenn neue Daten anliegen:
https://msdn.microsoft.com/de-de/library/system.io.ports.serialport.datareceived%28v=vs.110%29.aspx
Da gibt es auch ein Beispiel...

Viel Erfolg.