The aim of my code is to:
-read in a string serial and use it to determine DC motor control for a car (2 motors and a h-bridge)
EXAMPLE STRING IncomingStr = "++135"
from the string read in, take the first charecter: + = forwards and - = backwards directions of travel
from the second charecter determine if the vehicle is turning right or left or going straight + = right, - = left, 0 = straight
from the last 3 charecters, determine the motor speed (0-255) ***Help Needed Here ***
THUS EXAMPLE STRING is making a forwards right hand turn at a speed of 135.
My help is needed to convert the last three characters into an int. What i have so far is to take the last three charecters of IncomingStr (that is 135)and assign that to a new string specially for the motos speed, called MotorVal.
I then attempt to perform the following:
MotorVal = IncomingInts.toInt(); //Convert Incoming Ints string to an integer.
From this an error occurs when compiling:
motor_test_emV9.ino: In function 'void loop()':
motor_test_emV9:107: error: request for member 'toInt' in 'IncomingInts', which is of non-class type 'char [4]'
It would be incredibly handy to convert MotorVal to an int as i do not want to write 255 if statements to compare MotorVal string to pre saved stings and then assign the motor value. For example, i dont want to do:
char known_motor_val[4] = "135";
if(strcmp(known_motor_val, MotorVal) == 0){
//Cont troll motor speed to 135
}
I am open to changing methods if there is a better suggestion than this.
My Code is as follows
//Please excuse if i have accidentally missed including out one of the initialization...they are all in place in my code.
char IncomingStr[7]; //Our strings must be <= 5 charecters long
char IncomingChar = -1; //We are going to append to the end of our IncommingStr
int CharIndex = 0; //An index into the array
char IncomingDir[2];
char IncomingSign[2];
char IncomingInts[4];
void loop() {
if (Serial.available() > 0){
if(CharIndex < 6){
IncomingChar = Serial.read();
IncomingStr[CharIndex] = IncomingChar;Â //Save the char to our list
CharIndex ++;
IncomingStr[CharIndex] = 0;Â //Insure the next place is cleared
}
Serial.write("Incomming str: ");Â Â Â Â Â Â Â //Display the string
for (int i = 0; i < 6; i++){
Serial.write(IncomingStr[i]);Â
}
Serial.println("");
         //get the direction forwards /back
        IncomingDir[0] = IncomingStr[0];       //Select the sign from the string
      Â
        Serial.write("Incomming dir: ");       //Display the sign string
            for (int i = 0; i < 2; i++){
                Serial.write(IncomingDir[i]);Â
            }
        Serial.println("");
         //get the sign to turn right/left
        IncomingSign[0] = IncomingStr[1];       //Select the sign from the string
      Â
        Serial.write("Incomming sign: ");       //Display the sign string
            for (int i = 0; i < 2; i++){
                Serial.write(IncomingSign[i]);Â
            }
        Serial.println("");
         //Help is needed here!!
        for (int i = 0; i < 3; i++){
            IncomingInts[i] = IncomingStr[i+2];
        }
        Serial.write("Incoming Ints: ");       //Display the sign string
            for (int i = 0; i < 3; i++){
                Serial.write(IncomingInts[i]);Â
            }
        Serial.println("");
        MotorVal = IncomingInts.toInt();       //Convert Incoming Ints string to an integer.
        Serial.print("MotorVal: ");
        Serial.println(MotorVal);
Welcome to the Forum, Emma. First, what terminates the input stream? Is it a newline character ('\n"), null ('\0'), of what? If it is always in a field of 6 characters, you might change:
void loop() {
if (Serial.available() > 0){
if(CharIndex < 6){
IncomingChar = Serial.read();
IncomingStr[CharIndex] = IncomingChar;Â //Save the char to our list
CharIndex ++;
IncomingStr[CharIndex] = 0;Â //Insure the next place is cleared
}
to
void loop() {
if (Serial.available() > 0){
      Serial.readBytesUntil('\n', incomingStr, 6);
This grabs everything and puts it in one place. Next, I would separate out the display info into it's own function, like:
void loop() {
if (Serial.available() > 0){
      Serial.readBytesUntil('\n', incomingStr, 6);
      ShowMeWhatArrived();
// more of your code...
}Â // End of loop()
void ShowMeWhatArrived()
{
 incomingStr[5] = '\0';     // Make sure we can treat it as a string
 Serial.print("Direction: ");
 Serial.print(incomingStr[0]);
 Serial.print("Left-Right: ");
 Serial.print(incomingStr[1]);
 Serial.print("Magnitude: ");
 Serial.print(atoi(&incomingStr[2]));
}
Obviously I haven't tried this, but it should point you in the right direction. The only thing that may seem a little weird is the argument to atoi(). Think of the address-of operator (&) as saying: "Give me the memory address where I can find...". So, if incomingStr[] is located at memory address 1000, &incomingStr[2] fetches memory address 1002. The atoi() function then goes to that address, finds "135", and converts it from an ASCII character sequence to a 16-bit integer.
Something bothered me about my answer. Use this instead:
const int BUFFSIZE = 6;
void loop() {
 int bytesRead;
 if (Serial.available() > 0){
   bytesRead = Serial.readBytesUntil('\n', incomingStr, BUFFSIZE );
   ShowMeWhatArrived();
  // more of your code...
}Â // End of loop()
void ShowMeWhatArrived(int bytesRead)
{
 incomingStr[bytesRead] = '\0';     // Make sure we can treat it as a string
 Serial.print("Direction: ");
 Serial.print(incomingStr[0]);
 Serial.print("Left-Right: ");
 Serial.print(incomingStr[1]);
 Serial.print("Magnitude: ");
 Serial.print(atoi(&incomingStr[2]));
}
There...more better! Now if a one or two digit value comes in, the null is placed in the correct position.
I did something similar for servo control. I put the numeric value first, then the servo identifier. another identifier could be added and evaluated for its input.
//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
  }
 }
}