Reading String Value from Port

Hi All,

I starting a small project in C# and it will communicate to Arduino.

In C# I have the code line

port.Write("ab2000"); which sends a string value to Arduino port.

But the problem is when I try to read the string value in Arduino it does not work. In Arduino, I use the code

String valStr = ""; valStr = Serial.readString();

But I get strange values for the "valStr"

Thanks for your help.

But I get strange values for the "valStr"

We can't see all of your C# code. We can't see all of your Arduino code. We can't see any proof of the "strange values".

Therefore, we can't help you.

Hi Paul,

I am not sure why you can't see the code I posted in my first thread at the top of the page up here!

Here is more info about the C# and Arduino code

In C#, I send string values like (ab2000 or ab3000, or ab4000) to the Arduino serial port

Here is the C# code:

while ((line = m_readFile2.ReadLine()) != null)
            {
                    port.Write("ab2000");  
            }

Then, in Arduino I created a serialEvent function to read the values from port. Here is the Arduino Code:

void serialEvent () 
{
  valStr = Serial.readString(); 

  if (valStr.substring(0,2) =="ab") 
    {

     myservoA.attach(3);
      myservoA.write(110); 
      delay(200);

    }

I am sure it is not reading the string value correct because the servo is not rotating.

I am not sure why you can't see the code I posted in my first thread at the top of the page up here!

I can see some snippets. But, code out of context is useless.

I am sure it is not reading the string value correct because the servo is not rotating.

And I am equally certain that that is NOT the cause of the servo not moving.

Post ALL of your code. Test it by sending ab2000 from the Serial Monitor app. Add Serial.print() statements if needed, to understand what is happening.

If, instead of your C# program, you use Serial Monitor to send 'ab' do you get the servo to move? I suspect that .readString() is starting in the middle of one of your sends so the string might start with 'b2' or '20' or '00' or '0a'.

Hi John: I am pretty sure that the string is starting at the beginning to catch “ab” as identifier.

Here is the Arduino code

#include <Servo.h> 

  Servo myservoA; // create servo object to control servo
  
  
  String valStr = "";     // variable to store the servo position [stretch condition]
  
String inputString = "";         // a string to hold incoming data

void setup()
{

  Serial.begin(9600);
   
   inputString.reserve(200);     // reserve 200 bytes for the inputString:

}

void loop()
{
}

void serialEvent () 
{
  valStr = Serial.readString(); 


  if (valStr.substring(0,2) ="ab") 
{
      myservoA.attach(3);
      myservoA.write(110); 
      delay(200);

}

}

Also,

you use Serial Monitor to send ‘ab’ do you get the servo to move?

… how to do that.

To send 'ab' press Send in the upper right corner. Sorry for the German screenshot.

Seems obvious but better said than not - for this to work you need to have your PC and your arduino agreeing on baud rate as well as data, parity, and stop bits (The default on arduino side is 8 data bits, no parity, one stop bit). Have you verified they are set up in the same way from your PC side? (Use Serial.begin on the arduino side to set those up in the same way your PC is communicating)

Assuming this is set the right way, Serial.readString() will read characters from the serial buffer into a string and the function terminates when it times out. The default time out is 1 second. If you have some sort of garbage going through the serial line then your string will always be offset and impacted by the timeout which is probably not what you want and you can never recover from that error. You could envision using readStringUntil() instead which reads characters from a stream into a string and the function terminates if the terminator character is detected or it times out (see setTimeout()). This way instead of sending just ab2000 you decide on a special ending character- say ab2000! And you listen until the !. Once you get your string back you should check if it conforms to what you expect because it could have terminated due to timeout.

I don't think though that this is the best approach to deal with your problem. your use of SerialEvent() function is not very standard. This function is automatically called inside the loop() if there is something pending on the serial line. What you could do instead for trying to read the full string there and block the main loop while waiting is just build up a buffer and let your program go back to the main loop so that your other activities get a chance to have some CPU time. See arduino Tutorial on SerialEvent as a very simple example to read in a string until a carriage return

One idea to use this for your case would be to set a start and end symbol to your communication and send this form the PC side - for example #ab2000!

Modify the example SerialEvent function this way: If there is serial data in the buffer, discard any character until you receive #, then you know you have a good starting point from the serial line. then accumulate characters in a buffer until you receive the ! (Check number of character received to not overflow your buffer) and set a Boolean like commandComplete = true and then in the main loop check the value of commandComplete and if it is true, perform your motor control stuff, reset the string buffer and set back commandComplete to false - you'll be ready to receive your next command

Unless you have some sort of handshake to ensure you are not loosing part of the communication it's going to be hard to ensure you are getting into your string the exact string you are waiting for.

Also note that the way you send data from your PC will very quickly saturate and possibly overflow the input buffer of the arduino given your motor commands wait for 0,2 seconds before going back to reading a command.

You need to think about flow control

Hi J-M-L,

I appreciate your reply with great suggestions.

You need to think about flow control

… I totally agree with you on this statement. I am half way finish my project using the servos and as you said: waiting for 2-3 seconds helped in doing flow control…

So I went thru Arduino SerialEvent example and other sample too. I hope I understood your reply. Basically, I need to:

  1. Receive the data from the port <Serial.read();>
  2. Store this data bit by bit in character format.
  3. Ensure the characters are fully read all the way and exclude new lines.
  4. Then populate my string with the character values. And then perform function comparison.

Did I understand you correct!!

I also found this web page with sample code and I will also give it a try tomorrow.