Split string or send different data to each DC motor via serial

Hello,

I have arduino uno and two brushless motors. I control brushless motors from my pc via serial. Everything works fine. But I can control motors only simultaneously.
I`m wrote small c# application which send motor speed as bytes to serial port, but I want to send different speed to each motor, for this I will send string something like this "100,50", but how can I split this string in arduino?

but how can I split this string in arduino?

That all depends on how you are storing the characters read from the serial port.

Post the code you have now.

The strtok() function will be useful if you are storing the data in a character array. The indexOf() and substring() functions will be of interest if you are using the String object.

The below code shows one simple way how to capture a serial string and parse it into the desired data for servo control. You may be able to do something similar for your situation.

// zoomkat 11-22-10 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550

#include <Servo.h> 
String readString, servo1, servo2;
Servo myservo1;  // create servo object to control a servo 
Servo myservo2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(6);  //the pin for the servo control 
  myservo2.attach(7);
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    } 
  }

  if (readString.length() >0) {
      Serial.println(readString); //see what was received
      
      // expect a string like 07002100 containing the two servo positions      
      servo1 = readString.substring(0, 4); //get the first four characters
      servo2 = readString.substring(4, 8); //get the next four characters 
      
      Serial.println(servo1);  //print to serial monitor to see results
      Serial.println(servo2);
      
      int n1; //declare as number  
      int n2;
      
      char carray1[6]; //magic needed to convert string to a number 
      servo1.toCharArray(carray1, sizeof(carray1));
      n1 = atoi(carray1); 
      
      char carray2[6];
      servo2.toCharArray(carray2, sizeof(carray2));
      n2 = atoi(carray2); 
      
      myservo1.writeMicroseconds(n1); //set servo position 
      myservo2.writeMicroseconds(n2);
    readString="";
  } 
}

zoomkat:
The below code shows one simple way how to capture a serial string and parse it into the desired data for servo control. You may be able to do something similar for your situation.

Thanks, i will try it today. Seems to me it is what exactly i need.

I typically suggest sscanf to get numbers from strings. Just Google sscanf.

I strongly recommend uniquely delimiting the two different commands. Something like prefix each with an R or L (for Right motor and Left motor), terminated with a carriage return. Like:

R100/r
L50/r

'/r' is the escape sequence for a carriage return. This would provide the most robust and flexible scheme for controlling your motors serially, and can easily be expanded for issuing other types of commands as well.

Although it's a bit of overkill for your needs, I already wrote similar code for another question (Parsing Question - #4 by utopia - Programming Questions - Arduino Forum). It was used to parse a char array of parameters arranged like the URL format ?x=1&y=2&z=3

bool grabParam(const char *input,const char *cmd,char *buff,int len)
{
  // return false if not found, or true and buff contains parameter found
  // note cmd passed in must include '=' at end
  const char *ptr=strstr(input,cmd); // find command
  if ( NULL==ptr ) // not found?
    return false;
  ptr+=strlen(cmd); // skip command text; point to param
  int i=0;
  while ( '\0'!=ptr[i] && '&'!=ptr[i] ) // find full param
    ++i;
  i=min(len-1,i); // make sure we don't overflow buff
  strncpy(buff,ptr,i); // copy it over
  buff[i]='\0';
  return true;
}

Use it like this:

String inData="m1=100&m2=345";

// fill inData from serial here (somehow)

// copy into a char array
char buff[32]="";
InData.toCharArray(buff,sizeof(buff));
buff[ sizeof(buff) / sizeof(buff[0]) - 1 ]='\0'; // I always like to null terminate strings just in case
// now get data in
unsigned int motor1=0, motor1=0;
char buff2[12]="";
if (grabParam(buff,"m1=",buff2,len))
  motor1=atoi(buff2);
if (grabParam(buff,"m2=",buff2,len))
  motor2=atoi(buff2);

The advantage of this, as jraskell pointed out, is you are not fixed to a specific format now - good if you make changes later on, say for a third motor.

space bump
thanks David for the code, working harder then ever