read two values

Hi guys
Im trying to control 2 stepper motors using the function read().
I must give in serial monitor 2 values , one for each motor ,and they must move to the specified angle (go-to mode). My code doesn't seem to work...
im a terrible programmer :blush: , so pleaaaaase have patience..

 if (buttonState == HIGH) {  
    
     Serial.println("GO-TO MODE");

    // send data only when you receive data:
        if (Serial.available()) {
            delay(1000);
              
    
                // command to stepper1
                 stepper1.step(Serial.read());
              Serial.println(" stepper1:");
              Serial.print(Serial.read());
                 
                  Serial.println("stepper 2");
              
        }
            if (Serial.available()) {
            delay(1000);
              
    
                // command to stepper2
                 stepper2.step(Serial.read());

              Serial.println(" stepper2:");
              Serial.print(Serial.read());   
                  Serial.println("end go-to  mode");
              
        }
    
     
    buttonState == LOW;
}

Im trying to control 2 stepper motors using the function read().

There is no function read(). There are several classes that have read() methods. I'm being picky here, because it is important to know which class' read() method you are trying to use.

I must give in serial monitor 2 values , one for each motor ,and they must move to the specified angle (go-to mode). My code doesn't seem to work...

Stepper motors do mot move to specific angles. They step a specified number of times. If you compute the correct number of steps, the stepper motor will rotate to the correct position.

        if (Serial.available()) {
            delay(1000);

You know that there is serial data available. What are you waiting for?

                 stepper1.step(Serial.read());

Serial.read() reads one byte. It is unlikely that the character/byte you read is the number of steps to step. What is sending the serial data?

              Serial.println(" stepper1:");
              Serial.print(Serial.read());

You checked that there was at least one byte to read. You read that one byte. Now, you are reading and printing another byte. Why?

Reading serial data pops the value off a stack (effectively). It is no longer available to be read again.

    buttonState == LOW;

This is performing a (useless) comparison, not an assignment. You probably don't need to do this, since you (presumably) assign buttonState a new value when loop() executes again.

so ... my code is crap :zipper_mouth_face: expecting this...

You know that there is serial data available. What are you waiting for?

actually go-to mode is one of the modes im using activated by a switch. So it seemed logic to wait so there is time for the previous action to be completed.

Serial.read() reads one byte. It is unlikely that the character/byte you read is the number of steps to step. What is sending the serial data?

I didn't know that.So how can i read an integer positive or negative , and maybe read 2 of them ?since we are talking about to steppers.Maybe with a "," semicolon separator? And how can i assign these two numbers to 2 variables so i can use them in stepper1 and stepper 2?

stepper1.step(variable1);
stepper2.step(variable2);

So it seemed logic to wait so there is time for the previous action to be completed.

OK. But, if that is truly what you want to do, you would wait whether there was serial data or not.

So how can i read an integer positive or negative , and maybe read 2 of them ?since we are talking about to steppers.Maybe with a "," semicolon separator? And how can i assign these two numbers to 2 variables so i can use them in stepper1 and stepper 2?

The sending application needs to add start and end markers to the packet. If the sender sends something like "<25, -100>", then code like this can read the data:

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Where it says "Process the packet", strtok() can be used to get the two tokens ("25" and "-100") and atoi() can be use to convert the tokens to numbers (25 and -100) that can be passed to the step() methods.

THANK YOU!(did not understand well the code, but.... )
so you mean something like

strtok( inChar, "," ) ;
int step1 = atoi(inData[1]);
int step2 = atoi(inData[2]);

so you mean something like

No. The code I posted collects the data in the array called inData. That array is what strtok() parses. Did you look at the strtok() documentation? If you had, you would see that it returns a pointer to a token. It is that pointer that gets passed to atoi().

Did you look at the strtok() documentation? If you had, you would see that it returns a pointer to a token. It is that pointer that gets passed to atoi().

actually i did... I didn't understand many things though... Im trying here, ok?

So
strtok( inData, "," ) ; is the first command
now what i must put into atoi?

So
strtok( inData, "," ) ; is the first command

No. The strtok() function returns a value. You are throwing the result away.

int step1 = 0, step2  =0;
char *token = strtok(inData, ",");
if(token)
{
   step1 = atoi(token);

   token = strtok(NULL, ",");
   if(token)
   {
      step2 = atoi(token);
   }
}
// Now, you can use step1 and step2.

to test the code

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;
int k;
int i;
void setup()
{
   Serial.begin(9600);
   // Other stuff...
    pinMode(13, OUTPUT);  
    
}
void loop()
{
  // Read all serial data available, as fast as possible
  Serial.println("test");
  delay (1000);
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

int step1 = 0, step2  =0;
char *token = strtok(inData, ",");
if(token)
{
   k = atoi(token);

   token = strtok(NULL, ",");
   if(token)
   {
      step2 = atoi(token);
   }
}
// Now, you can use step1 and step2.

// test with led13
for (i=0; i<k; i++){
 
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);     

}

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

although it compiles fine the led doesn't blink.... Am i missing something?
PS i changed the baud rate because freezes my serial motitor

Am i missing something?

Debug output.

sorry, no idea how to do that ..
could you please help me out?

sorry, no idea how to do that ..
could you please help me out?

Serial.print("Some name: ");
Serial.println(someVariable);

ok if i modify the code like so

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[7];
byte index;
int k;
int i;
void setup()
{
   Serial.begin(9600);
   // Other stuff...
    pinMode(13, OUTPUT);  
    
}
void loop()
{
  // Read all serial data available, as fast as possible
  Serial.println("goto mode");
  delay (1000);
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    Serial.println(inChar);
    if(inChar == SOP)
    {Serial.println("SOP");
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {Serial.println("EOP");
       ended = true;
       break;
    }
    else
    {
      if(index < 7)
      {
        Serial.println("(index < 7)");
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

int step1 = 0, step2  =0;
char *token = strtok(inData, ",");
if(token)
{
   k = atoi(token);
Serial.println(k);
   token = strtok(NULL, ",");
   if(token)
   {
      step2 = atoi(token);
     Serial.println(step2); 
   }
}
// Now, you can use step1 and step2.
for (i=0; i<k; i++){
 Serial.println("led-loop");
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // set the LED off
  delay(1000);     

}

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

and insert 4,2
i get

goto mode
goto mode
4
(index < 7)
,
(index < 7)
2
(index < 7)

You are supposed to send "<4,2>", not "4,2". The < and > are what the program uses to see that a packet started and ended.

feeling sooo stupid.. Thanks one more time PaulS..
Works fine