Go Down

Topic: Arduino to WPF - Serial Data Corrupted (Read 624 times) previous topic - next topic

drehwurm

Apr 28, 2018, 03:51 pm Last Edit: Apr 28, 2018, 03:54 pm by drehwurm Reason: attachment didn't get uploaded
Hello everybody. I am very new with arduino and programming in general, so I apologize for any inconveniece ;-)

The thing is, I want the arudino to send values (in the long run from pontentiometers) to my WPF Application, but the data get's mixed up because sometimes only half the message is being sent and in between there are CR/LFs.

This looks like this:

The Message is: 47

The Messa

ge is: 48

The Message is: 49

The Message is: 50

The Message is: 51

The Mess

age is: 52




Here's the c#-code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.IO.Ports;
using System.Diagnostics;

namespace ArduinoTest
{
    public class ArduinoReciever
    {
        //Fields
        SerialPort arduinoPort = null;
        public string recievedData;


        //Constructor
        public ArduinoReciever(string portname, int baudrate)
        {
            arduinoPort = new SerialPort();
            arduinoPort.BaudRate = baudrate;
            arduinoPort.PortName = portname;
            arduinoPort.StopBits = StopBits.One;
            arduinoPort.ReadTimeout = 200;
            arduinoPort.WriteTimeout = 50;
            arduinoPort.DataBits = 8;
            arduinoPort.Handshake = Handshake.None;
            arduinoPort.Parity = Parity.None;
            arduinoPort.Open();

            arduinoPort.DataReceived += new SerialDataReceivedEventHandler(Recieve);
        }

        //Methods
        private void Recieve(object sender, SerialDataReceivedEventArgs e)
        {
            // Collecting the characters received to our 'buffer' (string).
            recievedData = arduinoPort.ReadExisting();
            Debug.WriteLine(recievedData);

        }

    }
}



I guess that is a pretty standard-problem, but I just don't know where to start. I'd appreciate any help.

Thanks in advance

horace

the statements
Code: [Select]
recievedData = arduinoPort.ReadExisting();
            Debug.WriteLine(recievedData);

read the existing data in the input stream (which may be only part of a line of text) and write it out terminated by a new line - hence you can get new lines in the middle of a line of text from the arduino
try reading a complete line of text and write without the new line, e.g.
Code: [Select]
recievedData = arduinoPort.ReadLine();
            Debug.Write(recievedData);

Robin2

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

Also, have a look at the 3rd example in Serial Input Basics. The technique of using start- and end-markers greatly improves reliability and it can be used with any programming language.

You can send data in a compatible format with code like this
Code: [Select]
Serial.print('<'); // start marker
Serial.print(value1);
Serial.print(','); // comma separator
Serial.print(value2);
Serial.println('>'); // end marker


...R

Two or three hours spent thinking and reading documentation solves most programming problems.

sterretje

To add to horace's response, when your PC checks for the data, there might be 5 bytes already received while the sixth byte is being transferred. So your PC only sees the 5 bytes at that moment. Next time the PC checks, there are again a number of bytes received.

As Robin said, stay away from String (capital S). Your current code is safe but String manipulation can leave holes in your memory resulting in difficult to trace bugs (it works for a long time and suddenly it crashes for no apparent reason).
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Robin2

To add to horace's response, when your PC checks for the data, there might be 5 bytes already received while the sixth byte is being transferred. So your PC only sees the 5 bytes at that moment. Next time the PC checks, there are again a number of bytes received.
And using start- and end-markers enables the PC to deal with that properly.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

sterretje

#5
Apr 29, 2018, 09:51 am Last Edit: Apr 29, 2018, 09:52 am by sterretje
And using start- and end-markers enables the PC to deal with that properly.
If OP understands the underlying issue properly which is now hopefully the case. Your Serial Input Basics thread will help to understand how to approach it, just needs rewrite for C#.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Go Up