help with strings

i have been trying to get 1 arduino to read and extract a 2 substring sent from another and have not had any success. i have searched the internet for help but what i have found doesn't go into enough detail. the string sent is . the x's are numbers for a motor controller. i can get the 2nd arduino to read them and serial print them but that is it. here is the basic code i have been working with.

thanks

String mystring;

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

void loop() {
    while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        mystring += recieved; 
        if (recieved == '\n')
        {
           
        Serial.print(mystring);
      { 
   }   
            mystring = "";
        }
    }
}

If you format the data sent like this <xxxxR,><xxxxL,> using a comma to separate the commands, then decoding is easy. Below is code for servo control that decodes the servo command sent in that format. The command is captured in a String, the leading number in the command is converted to an integer, and the String is evaluated for the servo to get the command.

//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 else's 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
    }
  }
}

harryt43:
i messed that up.

Yes, you did. You loop() function, properly indented looks like:

void loop()
{
  while (Serial.available() > 0)
  {
    char recieved = Serial.read();
    mystring += recieved; 
    if (recieved == '\n')
    {
      Serial.print(mystring);
      { 
      }   
      mystring = "";
    }
  }
}

The curly braces after the Serial.print(mystring) statement are useless. And, after printing the String, you throw the data away. It's going to be hard to parse the data after that.

You can copy the first letter easily enough:

char first = mystring[0];

Then, you can replace the first letter with a space, easily enough:

mystring[0] = ' ';

Then, you can convert the String to a value:

int val = mystring.toInt();

All this, of course, assumes that you don't start saving data until after the < has arrived, and you stop when the > arrives and parse the data at that point.

sorry but i can't get either code to work i copied both and nothing. i tried to change the code around some but made thangs worse. hope this helps ,after decoding the code is split into 2 parts just numbers represented by a letter and pick up this "MotorMaster.h" then this myMotorMaster.drive(COILA,R) myMotorMaster.drive(COILB, L);

thanks
harry

mystring is a Sting class object, so I am not sure if mystring[0] is going to work.

The main problem with your original code, seems to be that after you get one character, your while loop will look for the next character before the serial input has received it, so your while loop will end, and you will discard your data.

You need to understand that your loop() function and your while loop within it, will run 100 times faster than the hardware which recieves the serial character input, and you need to always keep that in mind when writing functionality like this.

ok . what is the process call that i am tiring to do ie: stringtoint?

harryt43:
ok . what is the process call that i am tiring to do ie: stringtoint?

Simple example code using the format I suggested.

//zoomkat 5-9-14 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("multi-delimit-test-dual-input-5-9-14"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700R, or 1500L, or 2000L,
  //or like 30R, or 90L, or 180R,
  //or combined like 30R,180L,

  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
        Serial.print("control value: ");
        Serial.print(n);
        if(readString.indexOf('R') >0) Serial.println(" sent to R");
        if(readString.indexOf('L') >0) Serial.println(" sent to L");
        readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

i tried the last code and the serial monitor shows the right format but the wheels isn't turning i'll post the code i am working with.

  #include "MotorMaster.h"
String readString;
MotorMaster myMotorMaster = MotorMaster();
int rSpeed;
int lSpeed;

void setup() {
   
  Serial.begin(9600);
  Serial.println("multi-delimit-test-dual-input-5-9-14"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700R, or 1500L, or 2000L,
  //or like 30R, or 90L, or 180R,
  //or combined like 30R,180L,

  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
        Serial.print("control value: ");
        Serial.print(n);
        if(readString.indexOf('r') >0) Serial.println(" sent to R");
        if(readString.indexOf('l') >0) Serial.println(" sent to L");
        int r = rSpeed;
        int l = lSpeed;
        myMotorMaster.drive(COILA, rSpeed);
        myMotorMaster.drive(COILB, lSpeed);
        readString=""; //clears variable for new input
  }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Have you actually gotten your motors to move using any code? If not, you might have wiring/power/hardware issues. What motor controller are you using, and how does it work?

yes when i first put the code together on 1 arduino but the problem i'm having is sent data from 1 to another arduino to make a remove control arduino. i using a keyes L298 motor controller that came with the tank like rover

        int r = rSpeed;
        int l = lSpeed;
        myMotorMaster.drive(COILA, rSpeed);
        myMotorMaster.drive(COILB, lSpeed);

First, why are you making a copy of rSpeed and lSpeed?
Second, where are you actually assigning a value to rSpeed or lSpeed? Consistently writing 0 to the motor pins isn't going to make them go fast.

harryt43:
yes when i first put the code together on 1 arduino but the problem i'm having is sent data from 1 to another arduino to make a remove control arduino. i using a keyes L298 motor controller that came with the tank like rover

Can you post the code that actually worked on 1 arduino? Code that works is a good starting point

as i thought about what u said instead of r & l i put in numbers and it shoud have work but didn't after moving the curly's aroung i got the code to work some but wheels only turn in one direction no mater what direction the joystick is in and does not stop. here is the code i put together when i first started the project

#include "MotorMaster.h" 


 VersalinoBUS myBus = BUSB; 
 MotorMaster myMotorMaster = MotorMaster();
 
 
 byte xPin = myBus.AN2;
 byte yPin = myBus.AN1;

 byte deadzoneX = 90;
 byte deadzoneY = 90;
double sensativity = 0.30;
 

 
 int xRead = 0; 
 int yRead = 0;
 int xLast = 0;
 int yLast = 0;
 void setup()
 
{
  myMotorMaster.begin(BUSA);
  Serial.begin(9600);
 
  pinMode(myBus.D1, INPUT);
 
 digitalWrite(myBus.D1, HIGH);
 
}
void loop()
 
{
 
  if(!digitalRead(myBus.D1))
 
{
 
  Serial.print("||AT000");
 
  delay(250);
  }
 
    xRead = analogRead(xPin);
    yRead = analogRead(yPin);
    xRead = (int)map(xRead,0,1024,-255,255); 
    yRead = (int)map(yRead,0,1024,255,-255); 
  
   if(xRead <= deadzoneX && xRead >= -deadzoneX)
     xRead = 0; 
  if(yRead <= deadzoneY && yRead >= -deadzoneY)
 
   yRead = 0;  
  if( xRead != xLast || yRead != yLast) {
    xLast = xRead;
 
    yLast = yRead;
 
  int rSpeed =0;
  int lSpeed =0;
  if(yRead > 0 && xRead > 0)
 {
 
   lSpeed = yRead;
 
   rSpeed = xRead*sensativity;  
  }
 if(yRead > 0 && xRead < 0)
 
  {
   lSpeed = -xRead*sensativity;
    rSpeed = yRead; 
}
  if(yRead < 0 && xRead < 0)
 {
    lSpeed = -xRead*sensativity;
    rSpeed = yRead; 
 }   
   if(yRead < 0 && xRead > 0)
 
{
 
    lSpeed = yRead;
    rSpeed = xRead*sensativity; 
 } 
 if(yRead != 0 && xRead == 0)
{
    lSpeed = yRead;
 
 rSpeed = yRead; 
 
}
  if(yRead == 0 && xRead != 0)
 {
 
   if(xRead < 0) 
{  
     lSpeed = xRead * sensativity*1.5;
    rSpeed = -xRead;  
   }  
   if(xRead > 0)
  {  
    lSpeed = xRead;
     rSpeed = -xRead * sensativity*1.5; 
    }
 }
 Serial.print(lSpeed);
 Serial.print(rSpeed);
  myMotorMaster.drive(COILA, lSpeed);
  myMotorMaster.drive(COILB, rSpeed);
  
  }


}

for got thanks again

here is my reciever code

thanks

  #include "MotorMaster.h"
MotorMaster myMotorMaster = MotorMaster();
String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("multi-delimit-test-dual-input-5-9-14"); // so I can keep track of what is loaded
 myMotorMaster.begin(BUSA);

}

void loop() {

  //expect single strings like 700R, or 1500L, or 2000L,
  //or like 30R, or 90L, or 180R,
  //or combined like 30R,180L,

  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
        Serial.print("control value: ");
        Serial.print(n);
        if(readString.indexOf('R') >0) Serial.println(" sent to R");
        if(readString.indexOf('L') >0) Serial.println(" sent to L");
        readString=""; //clears variable for new input
      myMotorMaster.drive(COILA, 'R');
      myMotorMaster.drive(COILB, 'L');
   
  }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

Skip the joystick arduino for the time being, and concentrate on making code that runs on the bot arduino. Does sending commands from the serial monitor to the bot arduino using your receiver code control the motors as expected ? If not, then this is the first thing to complete.

      myMotorMaster.drive(COILA, 'R');
      myMotorMaster.drive(COILB, 'L');

What the hell is the motor supposed to do with 'R' or 'L'?

Why are you driving both motors when the input contains an 'R'? Why are you driving both motors when the input contains an 'L'?

Why are you ignoring the numeric portion of the input (that you converted to an int and stored in n)? Isn't THAT the value that you should be sending to ONE of the motors?

Mr zoomkat i'm not sure how to do that sorry.
Mr Paul 'R' & 'L' are suppose to be numeric values split from n the beginning for each string i am new at this

thanks
harry

Mr Paul 'R' & 'L' are suppose to be numeric values

Well, OK. They are 82 and 76.

split from n the beginning for each string

No, they are most definitely not.