Go Down

Topic: read two values (Read 518 times) previous topic - next topic

pyrforos

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 :smiley-red:  , so  pleaaaaase  have patience..
Code: [Select]

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

PaulS

Quote
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.

Quote
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.

Code: [Select]
        if (Serial.available()) {
            delay(1000);

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

Code: [Select]
                 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?

Code: [Select]
              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.

Code: [Select]
    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.

pyrforos

so ... my code is crap :smiley-zipper: expecting this...
Quote
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.
Quote
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);

PaulS

Quote
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.

Quote
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:
Code: [Select]

#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.

pyrforos

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]);

PaulS

Quote
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().

pyrforos

Quote
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?

PaulS

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

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

Code: [Select]
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.

pyrforos

#8
Feb 14, 2012, 05:25 pm Last Edit: Feb 14, 2012, 05:29 pm by pyrforos Reason: 1
to  test the code
Code: [Select]
#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

PaulS

Quote
Am i missing something?

Debug output.

pyrforos

#10
Feb 14, 2012, 06:33 pm Last Edit: Feb 14, 2012, 06:53 pm by pyrforos Reason: 1
sorry, no idea how to do that ..
could you please help me out?

PaulS

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

Code: [Select]
Serial.print("Some name: ");
Serial.println(someVariable);

pyrforos

ok if i modify the code like so
Code: [Select]
#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

Code: [Select]
goto mode
goto mode
4
(index < 7)
,
(index < 7)
2
(index < 7)


PaulS

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.

pyrforos

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

Go Up