Programming Arduino to pick apart numbers vs strings?

HI,

I was wondering if it is possible to put into the serial.Read functionality a base program that can determine what type of data is being sent or does the program itself need to specify such information?

Here is what I want to do.

I want to be able to type in D which will come in as a variable for down and it adjust the speed of a motor by 10 or 25
The same for U which adjust speed for up.

Is there a way to write programming to make the Arduino see the D first and then the rest of the data and say hey, He said D, so down. or possibly D123 where down by a value of 123?

Is there a way to write programming to make the Arduino see the D first and then the rest of the data and say hey, He said D, so down. or possibly D123 where down by a value of 123?

Yes, why wouldn't there be ?

Picking out single characters when the program knows what to expect (U or D for instance) is easy. Keep reading until you find something that matches what you expect. Then either read a fixed number of bytes which hold the number or read until an 'end of message' marker, such as Carriage Return or Linefeed is found and extract the number from the bytes read. There are even functions such as Serial.parseInt() which make it easier.

Since I am new to programming, is there an easy place to go to learn about this? I've seen multiple topics in the "Learning" Tab, but most of seems to assume an intermediate level of programming knowledge.

but most of seems to assume an intermediate level of programming knowledge.

That's because string parsing IS an intermediate topic, not a beginning topic. However, if you send "D,123", it is far easier to parse that "D123". Look at strtok() and atoi().

Is there a way to write programming to make the Arduino see the D first and then the rest of the data and say hey, He said D, so down. or possibly D123 where down by a value of 123?

If you have control over the way the data commands are sent, you might try something like the below servo test code. The command value is placed first, followed by the servo identifier, and the data string is terminated with a , delimiter. Putting the numeric value first makes it easy to extract.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Another possibility is to read the entire line with one call and then break it apart. If you are sending across the Serial port and terminating the data by pressing the Enter key and the data are "D123", it will look like "D123\n", where '\n' is the newline character caused by the Enter key. If that's the case:

  char buffer[10];
  char target:
  int value;
  int numberOfBytesRead;

  // more of our code...

  if (Serial.available())  {
    numberOfBytesRead = Serial.readBytesUntil('\n', buffer, 10);  //gets everything up to the Enter key 
    buffer[numberOfBytesRead] = '\0';     // make it a null terminated string
    target = toupper(buffer[0]);          // First letter
    value = atoi(&buffer[1]);             // The number
    switch(target) {
       case 'D':                                              // Down
            // whatever you want to do 
          break;
       case 'U':                                              // Up
            // whatever you want to do 
          break;
       case 'L':                                              // Left
            // whatever you want to do 
          break;
       case 'R':                                              // Right
            // whatever you want to do 
          break;
       default:
           MyErrorCondition();           // Shouldn't be here...
           break;
   }
   // Rest of your code

See if that works...