Multiple Information At Once

I have the Adafruit Motor Shield V2 and I want to to be able to send information to it through the serial monitor. However you have to fill out three pieces of information, myStepper1->step(100, FORWARD, SINGLE); So before I would just do int steps = Serial.parseInt() but how do I type "100 FORWARD SINGLE" or "100 F S" into the serial monitor like that and have the arduino see that all the information is there and then send it to the shield?

I have this so far...

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMStop(0x61);
Adafruit_MotorShield AFMSbot(0x60);
Adafruit_StepperMotor *S1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *S2 = AFMSbot.getStepper(200, 2);

void setup(){
  Serial.begin(115200);
  Serial.println("Connected To Arduino...");  
}
 
void loop()
  AFMStop.begin();
  AFMSbot.begin();

{
  if (Serial.available())
  {
    int steps = Serial.parseInt();
    motor.step(steps);
  }
}

sscanf

I wrote a demo sketch showing various options for reading data from a PC in this Thread. I think the last function does the sort of thing you want.

...R

the readCSV();? How do I use it? Or even the sscanf.

If I suggest that "CSV" stands for "comma separated values", and that there are pages and pages of tutorials on "sscanf" (c'mon, it isn't that common a string that Google is going to turn up false hits), is that any help?

Kameechewa:
the readCSV();?

Assuming you are referring to the "readCSV()" function in my demo sketch, I had hoped it would be obvious from the sketch how it is used.

What exactly do you not understand?

...R

I guess I don't understand the whole thing. From what I see online is this and I didn't find your program or whatever because idk i guess its too complex for me. Anyways this is what I have now and nothing happens so I'm totally lost.

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMStop(0x61);
Adafruit_MotorShield AFMSbot(0x60);
Adafruit_StepperMotor *S1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *S2 = AFMSbot.getStepper(200, 2);

void setup(){
  Serial.begin(115200);
  Serial.println("Connected To Arduino...");
  AFMStop.begin();
  AFMSbot.begin();  
}
 
void loop(){
 
  int steps = Serial.parseInt();
  int dir = Serial.parseInt();
  int type = Serial.parseInt();
  S1->step(steps, dir, type);
}

A way to receive a value and command info. Make the data receiving code first, then work on sending the data in the desired format. Below is some servo receiving code that seems similar to what you want.

//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
    }
  }
}

Kameechewa:
I guess I don't understand the whole thing. From what I see online is this and I didn't find your program or whatever because idk i guess its too complex for me.

I don't understand. You seemed to quote the function name from my sketch so I assumed you had found it. In case you hadn't, this is the code for that function

char inputChar = 'X';
byte inputByte = 255;

const byte buffSize = 32;
char inputSeveral[buffSize]; // space for 31 chars and a terminator

byte maxChars = 12; // a shorter limit to make it easier to see what happens
                           //   if too many chars are entered

int inputInt = 0;
float inputFloat = 0.0;
char inputCsvString[12];

void readCSV() {

      // this function expects a series of comma separated values
      // for this demo the sequence of items must be a string, an integer, a float
      // for example          testing, 123 , 4567.89
      // spaces around the commas are optional
   
        // first read severalChars into the array inputSeveral

    inputSeveral[0] = 0;
    maxChars = buffSize - 1; // use full size of buffer for this function
    byte charCount = 0;  
    byte ndx = 0;        
    
    if (Serial.available() > 0) {
      while (Serial.available() > 0) { 
        if (ndx > maxChars - 1) {
          ndx = maxChars;
        } 
        inputSeveral[ndx] = Serial.read();
        ndx ++;        
        charCount ++;
      }
      if (ndx > maxChars) { 
        ndx = maxChars;
      }
      inputSeveral[ndx] = 0; 
    }

      // now we need to split the received string into its parts
      // this is done by strtok() which looks for the token - the comma in this case

    char * partOfString; // this is used by strtok() as an index
    
    partOfString = strtok(inputSeveral,",");      // get the first part - the string
    strcpy(inputCsvString, partOfString); // copy it to inputCsvString
    
    partOfString = strtok(NULL, ","); // this continues where the previous call left off
    inputInt = atoi(partOfString);     // convert this part to an integer
    
    partOfString = strtok(NULL, ","); 
    inputFloat = atof(partOfString);     // convert this part to a float
   
}

I don't know a simpler way to take in a string with multiple parts and extract the separate parts.

In an earlier post in this Thread I gave you a link to the Thread with the full demo code in it. The readCSV() function will probably make more sense if you read the other functions in order first.

As I said earlier, I will be happy to explain particular items that you don't understand.

...R

Ok so I added that to my sketch but I don't understand all the code. and it keeps giving me these errors
Stepper_Controller.ino: In function 'void readCSV()':
Stepper_Controller:41: error: 'inputSeveral' was not declared in this scope
Stepper_Controller:42: error: 'maxChars' was not declared in this scope
Stepper_Controller:42: error: 'buffSize' was not declared in this scope
Stepper_Controller:67: error: 'inputCsvString' was not declared in this scope
Stepper_Controller:70: error: 'inputInt' was not declared in this scope
Stepper_Controller:73: error: 'inputFloat' was not declared in this scope

and instead of you wasting your time trying to explain this to me, is there somewhere you could direct me to that would explain all this to me.

The code in reply #8 looks pretty complete to me, so I can't see why you're getting those errors, but I can't see your code either.

Kameechewa:
and instead of you wasting your time trying to explain this to me,

I don't mind explaining if you want to learn. But you will have to post your code.

...R

Ok if you want to haha.

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMStop(0x61);
Adafruit_MotorShield AFMSbot(0x60);
Adafruit_StepperMotor *S1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *S2 = AFMSbot.getStepper(200, 2);

void setup(){
  Serial.begin(115200);
  Serial.println("Connected To Arduino...");  
}
 
void loop(){
  AFMStop.begin();
  AFMSbot.begin();

char inputChar = 'X';
byte inputByte = 255;

const byte buffSize = 32;
char inputSeveral[buffSize]; // space for 31 chars and a terminator

byte maxChars = 12; // a shorter limit to make it easier to see what happens
                           //   if too many chars are entered

int inputInt = 0;
float inputFloat = 0.0;
char inputCsvString[12];
}

void readCSV() {

      // this function expects a series of comma separated values
      // for this demo the sequence of items must be a string, an integer, a float
      // for example          testing, 123 , 4567.89
      // spaces around the commas are optional
   
        // first read severalChars into the array inputSeveral

    inputSeveral[0] = 0;
    maxChars = buffSize - 1; // use full size of buffer for this function
    byte charCount = 0;  
    byte ndx = 0;        
    
    if (Serial.available() > 0) {
      while (Serial.available() > 0) { 
        if (ndx > maxChars - 1) {
          ndx = maxChars;
        } 
        inputSeveral[ndx] = Serial.read();
        ndx ++;        
        charCount ++;
      }
      if (ndx > maxChars) { 
        ndx = maxChars;
      }
      inputSeveral[ndx] = 0; 
    }

      // now we need to split the received string into its parts
      // this is done by strtok() which looks for the token - the comma in this case

    char * partOfString; // this is used by strtok() as an index
    
    partOfString = strtok(inputSeveral,",");      // get the first part - the string
    strcpy(inputCsvString, partOfString); // copy it to inputCsvString
    
    partOfString = strtok(NULL, ","); // this continues where the previous call left off
    inputInt = atoi(partOfString);     // convert this part to an integer
    
    partOfString = strtok(NULL, ","); 
    inputFloat = atof(partOfString);     // convert this part to a float
   
}

Kameechewa:
Ok if you want to haha.

What's with the "haha" - do you you want help, or do you just want to be a nuisance?

Looking at your code you don't seem to call readCSV() anywhere.

What happens if you add the following line into loop()

readCSV();

It may or may not work because I'm not sure how the values you get are supposed by be used by the rest of your sketch. And I don't have the same hardware as you so I can't run your code.

...R

No no, I do want to learn I just, I don't know. Im weird. But anyways I added it to loop and it still throws out the errors.

and it still throws out the errors.

... but I'm not going to show you the code or the errors?

Good luck.

As well as showing us your code and the errors you are getting you do need to think a little about how to use it. Pieces of code are not like small tubs of yogurt where you just pull the lid off and shove the contents in your mouth.

...R

you have declared some variables inside your loop() function. That makes them local variables, so they won't be available to any other function. So when you try to use this variables (like for instance the "maxChars" and several others) on the readCSV() functions it gives you an error.
I would suggest that you move them to the beginning of your code (before your setup() ) to make them global variables, and see if it makes any difference.
:wink:

boguz:
you have declared some variables inside your loop() function.

Well spotted. Thanks.

I hadn't noticed that but it is the sort of thing I had in mind when I mentioned "thinking" to the OP.

...R

Ok so I think I moved them but it still gives me the errors.

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_MotorShield AFMStop(0x61);
Adafruit_MotorShield AFMSbot(0x60);
Adafruit_StepperMotor *S1 = AFMStop.getStepper(200, 1);
Adafruit_StepperMotor *S2 = AFMSbot.getStepper(200, 2);

void setup(){
  Serial.begin(115200);
  Serial.println("Connected To Arduino..."); 
 
char inputChar = 'X';
byte inputByte = 255;

const byte buffSize = 32;
char inputSeveral[buffSize]; // space for 31 chars and a terminator

byte maxChars = 12; // a shorter limit to make it easier to see what happens
                           //   if too many chars are entered

int inputInt = 0;
float inputFloat = 0.0;
char inputCsvString[12];
   
// first read severalChars into the array inputSeveral

inputSeveral[0] = 0;
maxChars = buffSize - 1; // use full size of buffer for this function
byte charCount = 0;  
byte ndx = 0; 
  
}
 
void loop(){
  AFMStop.begin();
  AFMSbot.begin();       
}

void readCSV() {

      // this function expects a series of comma separated values
      // for this demo the sequence of items must be a string, an integer, a float
      // for example          testing, 123 , 4567.89
      // spaces around the commas are optional
      
      
      
    if (Serial.available() > 0) {
      while (Serial.available() > 0) { 
        if (ndx > maxChars - 1) {
          ndx = maxChars;
        } 
        inputSeveral[ndx] = Serial.read();
        ndx ++;        
        charCount ++;
      }
      if (ndx > maxChars) { 
        ndx = maxChars;
      }
      inputSeveral[ndx] = 0; 
    }

      // now we need to split the received string into its parts
      // this is done by strtok() which looks for the token - the comma in this case

    char * partOfString; // this is used by strtok() as an index
    
    partOfString = strtok(inputSeveral,",");      // get the first part - the string
    strcpy(inputCsvString, partOfString); // copy it to inputCsvString
    
    partOfString = strtok(NULL, ","); // this continues where the previous call left off
    inputInt = atoi(partOfString);     // convert this part to an integer
    
    partOfString = strtok(NULL, ","); 
    inputFloat = atof(partOfString);     // convert this part to a float
   
}

Errors:
Stepper_Controller.ino: In function 'void readCSV()':
Stepper_Controller:51: error: 'ndx' was not declared in this scope
Stepper_Controller:51: error: 'maxChars' was not declared in this scope
Stepper_Controller:54: error: 'inputSeveral' was not declared in this scope
Stepper_Controller:54: error: 'ndx' was not declared in this scope
Stepper_Controller:56: error: 'charCount' was not declared in this scope
Stepper_Controller:58: error: 'ndx' was not declared in this scope
Stepper_Controller:58: error: 'maxChars' was not declared in this scope
Stepper_Controller:61: error: 'inputSeveral' was not declared in this scope
Stepper_Controller:61: error: 'ndx' was not declared in this scope
Stepper_Controller:69: error: 'inputSeveral' was not declared in this scope
Stepper_Controller:70: error: 'inputCsvString' was not declared in this scope
Stepper_Controller:73: error: 'inputInt' was not declared in this scope
Stepper_Controller:76: error: 'inputFloat' was not declared in this scope