C# SerialPort - Receiving extra 255 bytes

I'm connecting my Arduino DUO with C# Console Application. Problem I'm facing is that I always receive four or six unwanted extra 255 bytes just after opening the SerialPort in C#.

I have simplified the code as much as I could:

C#:

static void Main(string[] args)
        {
            SerialPort serial = new SerialPort("COM4", 9600);
            serial.Open();

            serial.Write("A");

            Console.ReadKey();
        }

Arduino:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  //Open Serial Port
   Serial.begin(9600);
   
   //Initialize LCD
   lcd.begin(16, 2);
}

void loop() {
  
  if (Serial.available() >= 5)
  {
    lcd.clear();
    String message = "";
    
    int input1 = Serial.read();
    int input2 = Serial.read();
    int input3 = Serial.read();
    int input4 = Serial.read();
    int input5 = Serial.read();
    int input6 = Serial.read();
    int input7 = Serial.read();
    
    message += input1;
    message += input2;
    message += input3;
    message += input4;
    message += input5;
    message += input6;
    message += input7;
              
    lcd.print(message.substring(0, 16));
    lcd.setCursor(0, 1);
    lcd.print(message.substring(16, message.length()));
  }
  
  delay(1000);
}

Scenario is as follows. I publish the sketch to the Arduino and then I run C# application. What I see on my Arduino's LCD is "25525525525525525565" but I expected "65". Now I can restart C# application thousand times and the LCD will always display "25525525525565-1-1".
Why do I get those 255?
Note that I get them only before the first message. If I modify my C# app to write 100 messages instead of one I get 255 bytes only before the first one.

This is strange for me and I don't understand why it is behaving this way. Can someone please explain this to me?

Hi Rychu

Can you post your complete C# code?

In the Arduino code, you execute the if statement if 5 or more bytes have been received, but then you do Serial.read() 7 times. Is this intentional? I think the last two reads are returning the error value -1 which explains the two -1s in one of your examples.

Regards

Ray

Hi Hackscribble,

Thank you for your post.

This is my complete C# code. I don't have anything except the Main(). I have simplified my projects to these two to easily demonstrate my problem. These two code snippets are two complete projects that demonstrate my problem in 100%.

Yes, the if condition and the 7 reads are intentional. I totally understand that b/c of that I receive the -1s. It's ok. The issue I'm describing are the 255s at the beginning of the first message.

Regards
Pawel

Hi Pawel

Thanks for clarifying about the C# code. I just wanted to check there was nothing else going on.

My reading of the C# code is that is is doing the following ...

  1. Opening the serial port to the Arduino (over USB, I guess?)
  2. Writing a single character.
  3. Waiting for a key press on the PC.
  4. When key press received, end the program.

Something you could try is changing the code to be ...

static void Main(string[] args)
        {
            SerialPort serial = new SerialPort("COM4", 9600);
            serial.Open();
      
     // put some code here to write a prompt to the PC screen to press a key

    // add this ReadKey() to pause before writing the character to the Arduino
            Console.ReadKey();

            serial.Write("A");

            Console.ReadKey();
        }

When you run the code, wait a few seconds before hitting the first key on the PC, and see if this changes what is received on the Arduino.

Note: I'm not suggesting that a delay is the way to fix the problem long term, but maybe it will show up if there is a timing problem around opening the serial connection to the Arduino. I had a similar problem a while back with C# to an Arduino Nano over USB. I think (?) what I discovered is that opening the serial over USB in effect resets the Nano, so the C# program thought it was ready when it wasn't.

Cheers

Ray

Wow... Good test. Now I'm totally confused. Here is what happend. I modified the C# program a bit more than you suggested:

static void Main(string[] args)
        {
            SerialPort serial = new SerialPort("COM4", 9600);

            Thread.Sleep(5000);

            serial.Open();

            Thread.Sleep(5000);

            Console.WriteLine("Press any key to send 'A' to Arduino...");
            Console.ReadKey();

            Thread.Sleep(5000);

            serial.Write("A");

            Console.ReadKey();

        }

Now I'm during the excution and I see "Press any key to send 'A' to Arduino..." on the Windows Console and "255255255255255255-1" on Arduino's LCD. I'm clicking enter in Windows Console and... Nothing happend so I guess the 'A' has been sent to Arduino but the If condition (if 5 or more bytes) blocked outputing it to LCD.
I'm now restarting the C# program without resetting the Arduino... And again program reached the "Press any key [...]" and arduino displayed "65255255255255-1-1". So as expected Arduino received the 'A' sign from previous program instance and new serial.Open() again sent extra 255s.

That is weird. Why serial.Open() sends these 255 bytes? And why is it always 6 after Arduino reset and 4 on every next Open()?

PS. I use Programming USB Arduino's DUO port.

My guess is that you are displaying data from unitialized SRAM locations because some part of your indexing is wrong.

I would use a char array[] of a known length to hold a string rather than a String (note the small "s" and big "S").

Strings (with a big S) can be a problem in the small memory of an Arduino.

...R

Does it make any difference if you change the C# open command like this? Just in case C# / PC default values are different from Arduino.

SerialPort serial = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);

Hackscribble,
Unfortunately no :frowning: Still six 255s after first Open() and four 255s after the second one.

Robin2,
Thanks for joinning to the discussion. I considered your proposition. I did two things to test it. But first of all I changed the Arduino's if condition to Serial.available() > 0.

  1. To confirm this is a C# issue I used the Arduino's serial monitor tool. I reset the arduino and then launched serial monitor tool and sent the 'A'. Arduino's LCD screen displayed "65-1-1-1-1-1-1". There wasn't any extra 255s.

  2. To confirm this is not a String issue i used int[] instead of it:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  //Open Serial Port
   Serial.begin(9600);
   
   //Initialize LCD
   lcd.begin(16, 2);
}

void loop() {
  
  if (Serial.available() > 0)
  {    
    lcd.clear();
    
    int message[7];
    
    message[0] = Serial.read();
    message[1] = Serial.read();
    message[2] = Serial.read();
    message[3] = Serial.read();
    message[4] = Serial.read();
    message[5] = Serial.read();
    message[6] = Serial.read();
              
    lcd.print(message[0]);
    lcd.print(message[1]);
    lcd.print(message[2]);
    lcd.print(message[3]);

    lcd.setCursor(0, 1);

    lcd.print(message[4]);
    lcd.print(message[5]);
    lcd.print(message[6]);
  }
  
  delay(1000);
}

Output on Arduino's LCD using:

  • C# app: "255255255255255255-1"
  • Arduino's Serial Monitor: "65-1-1-1-1-1-1"

Unfortunately this looks like a pure C# issue :frowning:

Hi Pawel

Can't help with the C# issue then, I'm afraid.

If the extra 255 bytes are only at the start, a workaround would be to add a "handshake" between the PC and the Arduino. Get your C# program to send a different character, say 'B', when it starts. In your sketch, read serial one byte at a time, discarding bytes until you see the 'B'. To be completely sure, you could then have the Arduino send back a specific character and have C# wait until it sees this before it starts sending your proper data.

Good luck with it.

Ray

Thanks Ray. Could you please take a look at the last thing here:
I have found something... really stupid. You said that you have discovered that opening the serial over USB in effect resets your Nano. Well... During investigation of my issue I have found that setting

serial.DtrEnable = true;

Prevents C# from sending unnecessary 255s but instead it resets my DUO every time I call

serial.Open();

What an annoying thing...

I’m going on holidays. I will get back to you guys on Monday.

Thanks for your help and time!

Have a good holiday!

I've just looked up my old code. I ended up with the same solution about DtrEnable. In my application, resetting the Arduino did not matter.

If you need it to work without the 255s and without resetting, you may need to go to the Microsoft C# forums.

All the best

Ray

  if (Serial.available() >= 5)
  {
    lcd.clear();
    String message = "";
    
    int input1 = Serial.read();
    int input2 = Serial.read();
    int input3 = Serial.read();
    int input4 = Serial.read();
    int input5 = Serial.read();
    int input6 = Serial.read();
    int input7 = Serial.read();

If there are 5 or more bytes, read all 7 of them. Why?

Rychu:
Prevents C# from sending unnecessary 255s but instead it resets my DUO every time I call

That's interesting because the general behaviour of PC programs ( my experience is with Python and Java) opening the serial port is that they reset the Arduino and it is essential to include a suitable delay to give the Arduino time to go through its reset process.

...R

I have done a deeper investigation. Here is what i found:

  1. http://playground.arduino.cc/Learning/AutoResetRetrofit
    Second paragraph - Looks like, as you already said, arduino has a hardcoded logic "If received a DTR signal then RESET".

  2. SerialPort.cs source code in C# .NET
    Looks like .NET by default does not send DTR flag so it does not reset arduino by default. Also looks like the major operation of Open() is to create new instance of SerialStream class.

  3. SerialStream.cs source code in C# .NET
    Looks like those 4/6 255s have something to do with a handshake and/or DCB struct but I did not find anything suspicious inside the SerialStream constructor neither the place where those bytes are being sent through SerialStream.

I think I will just end up with DtrEnable = true. Thank you all for your help.

t try with this.OnDocdulieu += new Form1.OnDulieu(GhiLenh);. but not work

congpho:
t try with this.OnDocdulieu += new Form1.OnDulieu(GhiLenh);. but not work

I am not sure if you are looking for assistance.

If you are you will need to provide a lot more information.
Has your problem anything to do with the other posts in this Thread? If so, which one?

...R