Send string from c# to Arduino and split it.

hi! I urgently need help, I would transfer a string of data like this, "23,7,111,34" from c # to Arduino from serial port, the problem I found is that, when I take the data from arduino serialport, not I can divide those values ??in 4 different variables. The question I want to ask you in a nutshell is, the string passed in arduino serialport has the same shape or not?! and if so it's not like I can work around the problem and get those values???

Hi giavale

Please post your C# and Arduino code (using code tags, the "#" button above the row of smileys).

Thanks

Ray

serialTransfer is the string that I have to transmit, and I use serial.Write to trasmit on serial. I think there aren't problem in this metod.

serialTransfer = String.Concat(Convert.ToString(rightElbowAngle), ",", Convert.ToString(rightShoulderAngle), ",", Convert.ToString(leftElbowAngle), ",", Convert.ToString(leftShoulderAngle));

 serial.Write(serialTransfer);

Follows the arduino code:

if(Serial.available())
  {
    while(Serial.available())
    {
      armsDegrees[i]=Serial.read();
      i++;
    }
    for (int j=0;j<=i;j++)
    {
      strArmsDegrees=strArmsDegrees+armsDegrees[j];
    }
    i=0;
    Serial.println(strArmsDegrees);
    do
    {
       pos = strArmsDegrees.indexOf(',');
       if(pos != -1)
       {
         if(i==2)
         {
           strLeftElbow = strArmsDegrees.substring(0,pos);        //terza cifra per gomito sinistro
           i++;
         }
         if(i==1)
         {
           strRightShoulder = strArmsDegrees.substring(0,pos);    //seconda cifra per spalla destra.
           i++;
         }
         if(i==0)
         {
           strRightElbow = strArmsDegrees.substring(0,pos);       //prima cifra per gomito destro.
           i++;
         }
         strArmsDegrees = strArmsDegrees.substring(pos+1, strArmsDegrees.length()); //riscrive la parte rimanente dopo la virgola trovata, nella stessa stringa.
       }
       else
       {  
          if(strArmsDegrees.length() > 0)
            strLeftShoulder=strArmsDegrees;  // la rimanenza dopo l'ultima virgola, corrisponde alla quarta cifra spalla sinistra.
       }
    }
    while(pos >=0);
    i=0;

    rightElbowDegree=strRightElbow.toInt();
    rightShoulderDegree=strRightShoulder.toInt();
    leftElbowDegree=strLeftElbow.toInt();
    leftShoulderDegree=strLeftShoulder.toInt();  
    
//    Serial.print("rightElbowDegree: ");
//    Serial.println(rightElbowDegree);
//    Serial.print("rightShoulderDegree: ");
//    Serial.println(rightShoulderDegree);
//    Serial.print("leftElbowDegree: ");
//    Serial.println(leftElbowDegree);
//    Serial.print("leftShoulderDegree: ");
//    Serial.println(leftShoulderDegree);
    
    rightElbowServo.write(leftElbowDegree);
    delay(15);
    leftElbowServo.write(rightElbowDegree);
    delay(15);
    leftShoulderServo.write(rightShoulderDegree);
    delay(15);
    rightShoulderServo.write(leftShoulderDegree);
    delay(15);
    
  }

I read from the serial values ??as they were sent, but by trying values ??are different than I expected.

I search on the web, and i have seen that string transfer to arduino serial port becomes ascii code, it's really?! In this case how can I split the four part of the string?!

Thanks Hackscribble for the attenction and anyone can help me.

Giacomo

Your C# code is converting your numbers to strings (which are ascii characters) and that is what the Arduino receives.

Assuming you read all of the input into a char array called armsDegrees then, when all the data has been received, you need to step through armsDegrees to find the commas that separate your numbers and in doing so copy the characters for each number into a different char array - remember to add a 0 at the end of the array as C/C++ uses that to detect the end of a string (note the lower case s). Then you can use the function atoi() to change the characters back into an integer.

You may find that you need to add start and end markers to the data that C# is sending so that the Arduino program can know that it has properly received the data.

The example code here and here might be helpful. The principles apply to any programming language.

...R

At this moment I must recharge my batteries, but I added a start character and a 0 to detect the end of the string as you suggested, from what I've tried, I think it works but I'll let you know later.

Thank you very much for the help R!

Giacomo

The data that I transfer, Arduino receives them, but I have another problem, the data that I transfer go to ServoMotor and for the first movement is all ok, but after the motor turn off and I don't find a solution.

This is Arduino code:

#include <Servo.h>
#include <String.h>

Servo leftElbowServo;
Servo leftShoulderServo;
Servo rightElbowServo;
Servo rightShoulderServo;
int posRE,posRS,posLE,posLS,pEndStr;
char armsDegrees[50];
String strLeftElbow;
String strLeftShoulder;
String strRightElbow;
String strRightShoulder;
int i=0;
String strArmsDegrees;
int leftElbowDegree,leftShoulderDegree,rightElbowDegree,rightShoulderDegree;



void setup() {
  
  leftElbowServo.attach(11);
  leftShoulderServo.attach(10);
  rightShoulderServo.attach(9);
  rightElbowServo.attach(6);
  
  Serial.begin(9600);
  Serial.flush();
  i=0;

  strArmsDegrees="";
}

void loop() {
 
  if(Serial.available())
  {
    while(Serial.available())
    {

      armsDegrees[i]=Serial.read();
      i++;
    }
    for (int j=0;j<=i;j++)
    {
      strArmsDegrees=strArmsDegrees+armsDegrees[j];
    }
    i=0;
    //Serial.println(strArmsDegrees);
    posRS = strArmsDegrees.indexOf(',');
    posRE = strArmsDegrees.indexOf('

my method is: when data are available to serial port, I reckon the values to send to Servos,and I send them. What's the problem?

Thanks

Giacomo);
    posLE = strArmsDegrees.indexOf('.');
    posLS = strArmsDegrees.indexOf('-');
    pEndStr = strArmsDegrees.indexOf('&');
   
//    Serial.print("posRE: ");
//    Serial.println(posRE);
//    Serial.print("posRS: ");
//    Serial.println(posRS);
//    Serial.print("posLE: ");
//    Serial.println(posLE);
//    Serial.print("posLS: ");
//    Serial.println(posLS);
//    Serial.print("pEndStr: ");
//    Serial.println(pEndStr);
   
    strRightElbow = strArmsDegrees.substring(posRE+1,posRS);
    strRightShoulder = strArmsDegrees.substring((posRS+1),posLE);
    strLeftElbow = strArmsDegrees.substring((posLE+1),posLS);
    strLeftShoulder=strArmsDegrees.substring(posLS+1,pEndStr);

rightElbowDegree=strRightElbow.toInt();
    rightShoulderDegree=strRightShoulder.toInt();
    leftElbowDegree=strLeftElbow.toInt();
    leftShoulderDegree=strLeftShoulder.toInt(); 
   
   
//    Serial.print("rightElbowDegree: ");
//    Serial.println(rightElbowDegree);
//    Serial.print("rightShoulderDegree: ");
//    Serial.println(rightShoulderDegree);
//    Serial.print("leftElbowDegree: ");
//    Serial.println(leftElbowDegree);
//    Serial.print("leftShoulderDegree: ");
//    Serial.println(leftShoulderDegree);
   
    rightElbowServo.write(leftElbowDegree);
    delay(15);
    leftElbowServo.write(rightElbowDegree);
    delay(15);
    leftShoulderServo.write(rightShoulderDegree);
    delay(15);
    rightShoulderServo.write(leftShoulderDegree);
    delay(15);
   
  }
 
  delay(100);
}


my method is: when data are available to serial port, I reckon the values to send to Servos,and I send them. What's the problem?

Thanks 

Giacomo

You will note that in my earlier post I specifically mentioned strings with a small s. Strings with an upper case S are a bad idea on an Arduino because it has such little memory.

If this was my project I would separate the reading of input from the PC (and saving it into variables) from the movement of the servos. My loop() would look like this

void loop() {
    getInputFromPC();
    moveServos();
}

the code in the moveServos() function would probably just be

void moveServos() {
    rightElbowServo.write(leftElbowDegree);
    leftElbowServo.write(rightElbowDegree);
    leftShoulderServo.write(rightShoulderDegree);
    rightShoulderServo.write(leftShoulderDegree);
}

The values of (for example) leftElbowDegree would have been set by the function getInputFromPC()

Separating the code into functions allows you to test each part separately.

And you should use the technique in the Blink Without Delay example sketch to manage your timing in place of using delay().

...R

You should solve one problem at a time.
Make sure you can do the serial transmission from your other computer to the arduino. Just print the message as you receive it.
After you have got that to work properly, then worry about parsing it.

michinyon, I agree with you, but the problem is that I haven't found a metod to read what i send because i trasmit data from c# and serialport is open by c# than I can't open the serial Monitor from Arduino.

Robin you are quite right, I apply this change immediatly.

thanks, Giacomo

The rasmission is ok as I thought, but I have another problem, I use my robot for 30 seconds and it's all ok, but after the c# program crash, sorry for my noise, can you help me or take an advise?!

Thanks

Giacomo

giavale:
The rasmission is ok as I thought, but I have another problem, I use my robot for 30 seconds and it's all ok, but after the c# program crash, sorry for my noise, can you help me or take an advise?!

I'm curious to know how you think you have given enough information for anyone to help you?

Have you debugging code in your C# program so that it leaves some evidence behind as to what caused the crash? Or what it was doing immediately before the crash?

...R

All depended by values trasmit to the arduino. I find the problem and now the project works very well.
Thanks to all.

Giacomo