Author Topic: Sending data from Arduino to a C# GUI  (Read 9885 times)

0 Members and 1 Guest are viewing this topic.

Offline BRetonDPTopic starter

  • Contributor
  • Posts: 26
Sending data from Arduino to a C# GUI
« on: October 03, 2014, 10:30:12 pm »
Hello, everyone!  I need some help communicating my Arduino with a C# program. I'm using an Arduino PING ranging sensor in order to read a value (an int). I want that value to set the X location of a component (in this case, a picture box) in a C# program. I'm having some issues, however, and I hope you guys can help me out.

My Arduino code is the following:

Code: [Select]
const int trig = 8;
const int echo = 7;
int info;

void setup()
{
  Serial.begin(9600);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
}

void loop()
{
  digitalWrite(trig, LOW);
  delayMicroseconds(5);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  info = pulseIn(echo, HIGH); // en microsegundos
  Serial.write(lowByte(info));
  Serial.write(highByte(info));
  delay(500);
}

Now, I have no idea if using
Code: [Select]
Serial.write() and splitting the int is a good way to go, but there are so many ways to do this and I'm very lost.

I am even more lost, however, on my C# program. I created a Serial port and then run getPosicion after every Tick on a timer (which is set to Intervals of 500). When doing this, all I get is 0's.

Code: [Select]
SerialPort port = new SerialPort("COM3", 9600);

int getPosicion()
        {
            int posicion = 0;
            port.Open();
            int bytes = port.BytesToRead;
            byte[] byte_buffer = new byte[bytes];
            posicion = port.Read(byte_buffer, 0, bytes);
            port.Close();
            return posicion;
        }

I tried using
Code: [Select]
Serial.println() and
Code: [Select]
port.ReadLine(), which somehow seems to work, but my program lagged heavily. Even though I'm not sure if performance should be better, I want to send the information as bytes to learn how to use it and to learn.

How can my code be fixed? I guess I'm doing something inherently wrong, after all most of what I display here was a desperate copy-paste attempt. I'm lost. Thanks in advance!
 

Offline vvanders

  • Regular Contributor
  • *
  • Posts: 124
Re: Sending data from Arduino to a C# GUI
« Reply #1 on: October 03, 2014, 11:32:10 pm »
Read up about blocking IO, you're read call is probably blocking and may need to be moved to another thread or async api(if one exists for serial) to make it more responsive.
 

Offline BRetonDPTopic starter

  • Contributor
  • Posts: 26
Re: Sending data from Arduino to a C# GUI
« Reply #2 on: October 03, 2014, 11:50:19 pm »
I will do so, makes sense. Thank you.
 

Offline daveatol

  • Regular Contributor
  • *
  • Posts: 136
  • Country: au
Re: Sending data from Arduino to a C# GUI
« Reply #3 on: October 04, 2014, 12:41:02 am »
The problem in your C# code is that you're opening and closing the port every time you try to read data. The port should be opened once (at the start of your program), and closed once (at the end of your program).

You also have
Code: [Select]
posicion = port.Read(buff, 0, bytes);, but the port.Read function simply returns the number of bytes read. You need to convert the two bytes that you read from the serial port to an integer; you can use the BitConverter class for that
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: Sending data from Arduino to a C# GUI
« Reply #4 on: October 04, 2014, 08:33:41 am »
The problem in your C# code is that you're opening and closing the port every time you try to read data. The port should be opened once (at the start of your program), and closed once (at the end of your program).

In addition, there is not guarantee that it will read exactly two bytes and from the same sensor reading.

It simpler to write the data out in text format. For each reading print the decimal value (as ASCII characters) followed by a line end.  You can verify that it sends the correct data using the Arduino serial monitor (upper right corner). Then, in your C# program, open the port (once, and keep it open) and then read one text line at a time and convert it to a binary number.

In Arduino it will look like:

Code: [Select]
...
Serial.println(info);
delay(500)
...

And in C# you need to figure out how to read a line of text at a time.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Sending data from Arduino to a C# GUI
« Reply #5 on: October 06, 2014, 08:43:02 am »
Think of a little protocol that would make your life a bit easier. Fast example:
PC sends 0x05 0x?? (ENQ + command)
Device sends 0x06 (ACK) [your ascii or hex coded integer coordinates] 0x0A (LF), maybe include a checksum byte here.
PC sends ACK or NAK.

You can also do this with printable characters. Look here for the full list of control codes http://www.ascii-code.com/.
Don't bother with sending binary data, .NET isn't fast enough to keep up with a full 9600 baud bus for more than a few seconds.
 

Offline daveatol

  • Regular Contributor
  • *
  • Posts: 136
  • Country: au
Re: Sending data from Arduino to a C# GUI
« Reply #6 on: October 06, 2014, 09:01:45 am »
Don't bother with sending binary data, .NET isn't fast enough to keep up with a full 9600 baud bus for more than a few seconds.
Have you ever used .NET? Do you have any basis for that baseless claim?
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: Sending data from Arduino to a C# GUI
« Reply #7 on: October 06, 2014, 09:13:32 am »
Don't bother with sending binary data, .NET isn't fast enough to keep up with a full 9600 baud bus for more than a few seconds.

I'm not a big fan of .NET but that simply isn't true.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Sending data from Arduino to a C# GUI
« Reply #8 on: October 06, 2014, 12:14:08 pm »
:P All the Microsoft Java fanboys immediately have sore toes. Sorry. http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport
The serial port implementation of .NET Windows isn't perfect, go and put your mcu to continuously send data. Notice how the application will lag and eventually fail. Even at 9600 baud. Not to blame .NET only, Qt will also lag. Only naked COM operation seems fast enough in processing bulk data. Proper interface handling on any platform isn't easy, especially on Windows.

But I don't think the discussed application requires bulk data. Which makes the above irrelevant for this topic.
« Last Edit: October 06, 2014, 12:19:06 pm by Jeroen3 »
 

Offline rs20

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
Re: Sending data from Arduino to a C# GUI
« Reply #9 on: October 06, 2014, 12:25:39 pm »
:P All the Microsoft Java fanboys immediately have sore toes. Sorry.
The serial port implementation of .NET Windows isn't perfect, go and put your mcu to continuously send data. Notice how the application will lag and eventually fail. Even at 9600 baud. Not to blame .NET only, Qt will also lag. Only naked COM operation seems fast enough in processing bulk data. Proper interface handling on any platform isn't easy, especially on Windows.

But I don't think the discussed application requires bulk data. Which makes the above irrelevant for this topic.

No, I have to agree with mikerj -- given the choice between a) believing that .NET being intrinsically incapable of handling 9600 baud, and b) believing that you just failed to write your software correctly, I'm going to choose B overwhelmingly. And I'm not a fan of .NET at all.

If it's anything like Java, if you write an app that accumulates data in a String through simple concatenation (instead of using a proper string accumulation class like StringBuffer/EDIT:StringBuilder), and/or you fail to use background threads properly and/or you naively display the accumulated string in a TextView, read bytes one system call at at time rather than reading a 1kB block at a time and working your way through it, etc, etc; then sure, it'll be slow. But that's the coder's fault, not the language's. PM me a link to your source code and I'll tell you what you did wrong.
« Last Edit: October 06, 2014, 01:10:07 pm by rs20 »
 

Offline daveatol

  • Regular Contributor
  • *
  • Posts: 136
  • Country: au
Re: Sending data from Arduino to a C# GUI
« Reply #10 on: October 06, 2014, 01:04:55 pm »
The serial port implementation of .NET Windows isn't perfect, go and put your mcu to continuously send data. Notice how the application will lag and eventually fail. Even at 9600 baud.
I've used the windows serial port for years, and not had these issues. I've had data going in and out of the serial port continuously (i.e. no idle time) for days while checking a microcontroller product for communications errors. The CPU usage was bugger all, and there were no errors. I've used the port at 2.5Mbps to receive serial data from a logic analyser without loss of data or 'lag', or even moderate CPU usage. I wouldn't expect there to be either. I've used multiple serial ports to log multiple channels. I've used it for debugging projects many times, without issue.

The things that I have seen cause a slow down in response include naively putting too much text into text boxes, charts or tables (e.g. a serial port data logger), and naive concatenation of strings (just use the StringBuilder). (Jeroen3 already stated this).
Which makes the above irrelevant for this topic.
I'm glad you at least realised that.
 

Offline BRetonDPTopic starter

  • Contributor
  • Posts: 26
Re: Sending data from Arduino to a C# GUI
« Reply #11 on: October 08, 2014, 02:07:31 am »
Thank you everyone for taking the time to respond.
I now no longer open and close the port in the same method; I only open the comms port when my main form loads.
Also, as I stated in the body, when I use the arduino Serial.println() command and C#'s SerialPort.ReadLine(), I do kind of get the expected behavior, but my form lags heavily.

Attached to this post is a screenshot of what my little GUI, which runs on fullscreen, looks like. The yellow roadstripes move downwards and once the game begins colored Rectangles are drawn and they begin to fall down from the top as obstacles. As soon as I hit 'calibrate' and my port opens and the communication begins, the yellow stripes begin lagging horribly and I can no longer click the form's buttons until the program crashes a few moments later.

I wanted to send bytes instead of the actual string with println() because I thought it would help my case and reduce the lag. The movement should also be pretty quick, pretty much realtime, but I'm now doubting my approach will suffice.
 

Offline daveatol

  • Regular Contributor
  • *
  • Posts: 136
  • Country: au
Re: Sending data from Arduino to a C# GUI
« Reply #12 on: October 08, 2014, 02:21:50 am »
You will have a delay of up to 500ms using the method you have outlined, because your timer only runs every 500ms.
 

Offline BRetonDPTopic starter

  • Contributor
  • Posts: 26
Re: Sending data from Arduino to a C# GUI
« Reply #13 on: October 08, 2014, 02:35:25 am »
I've messed around with that too, but I think that the shorter the delay (ideally, I would like it at... 100, maybe) the more my GUI lags.
 

Offline daveatol

  • Regular Contributor
  • *
  • Posts: 136
  • Country: au
Re: Sending data from Arduino to a C# GUI
« Reply #14 on: October 08, 2014, 02:38:37 am »
Are you doing other things in the timer event also? That will obviously slow everything down. Without seeing any code, I can only make guesses of what you've done.
 

Offline NiHaoMike

  • Super Contributor
  • ***
  • Posts: 9018
  • Country: us
  • "Don't turn it on - Take it apart!"
    • Facebook Page
Re: Sending data from Arduino to a C# GUI
« Reply #15 on: October 08, 2014, 03:45:33 am »
If you just have the Arduino send 4 hex characters plus a linefeed, you can greatly reduce the complexity of the encoding. Don't send decimal values since it takes modulus division to encode, which most 8 bit microcontrollers aren't going to be very good at. Hex characters just need some bitwise operations plus a lookup, which are very fast on most hardware.
Cryptocurrency has taught me to love math and at the same time be baffled by it.

Cryptocurrency lesson 0: Altcoins and Bitcoin are not the same thing.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf