Pages: [1]   Go Down
Author Topic: etch-a-sketch continuous servo code issue  (Read 1216 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok so i have two parallax continuous servos, and i easily made them turn using the sweep sample program. then i hooked them up to a etch-a-sketch and they make a continuous repeated pattern(still using sweep program).

but then i tired to write a program to control them over serial. i would send some thing like: <U,0500,> over serial to go up on the etch-a-sketch for 500ms. after i program the arduino and start the program but before i send that line(<U,0500,>) to the arduino over serial, one of the two servos start turning by its self. i added a serial.print line before when the servos(s) are actually supposed to turn to see if the code is some how "skipping" the serial stuff.
 
thanks

CODE:
Code:
#include <Servo.h>

Servo Xaxis;
Servo Yaxis;

int started = 0;
int inData[9];
int ended = 0;
char index = 0;
int final = 0;

void setup()
{
  Xaxis.attach(5);
  Yaxis.attach(6);

  Serial.begin(9600);
}

void loop()
{
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      started = true;
      index = 0;
      inData[index] = '\0';
    }
    else if(aChar == '>')
    {
      ended = true;
    }

    else if(started)
    {
      inData[index] = aChar;
      index++;
      inData[index] = '\0';            
    }

    else if (aChar =='*')
    {
      final = true;
    }
  }

  if(started && ended)
  {
    const char*  strDelimiter = ",";

    char* p;
    char str[7] = {index}; //U,0500,
    int time;
    char dir;

    if ( p = strtok(str, strDelimiter) )
    {
      dir = atoi(p);
    }
    if ( p = strtok(str, strDelimiter) )
    {
      time = atoi(p);
    }

    // Get ready for the next time
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';  
 
    Move(dir, time);
  }
}

//Servos move the dot on etch-a-sketch screen Xin/sec
void Move(char dir, int time)
{
  if (dir == 'U')
  {
    Yaxis.write(180);  
    delay(time);  
   Serial.print("Yaxis U for " time "ms");
  }
  
  if (dir == 'D')
  {
    Yaxis.write(0);
    delay(time);
    Serial.print("Yaxis D for " time "ms");
  }
  
  if (dir == 'L')
  {
    Xaxis.write(0);
    delay(time);
    Serial.print("Xaxis L for " time "ms");
  }
  
  if (dir == 'R')
  {
    Xaxis.write(180);
    delay(time);
    Serial.print("Xaxis R for " time "ms");
  }
}
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 610
Posts: 49004
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  Xaxis.attach(5);
  Yaxis.attach(6);
Before attaching the servo, you should write some known value to it.

Quote
i added a serial.print line before when the servos(s) are actually supposed to turn to see if the code is some how "skipping" the serial stuff.
And?

Code:
    char str[7] = {index}; //U,0500,
Why are you initializing this variable to index? Doesn't make sense.

Code:
    if ( p = strtok(str, strDelimiter) )
You should be parsing inData. The str variable is junk.

Code:
    if ( p = strtok(str, strDelimiter) )
    {
      time = atoi(p);
    }
The two calls to strtok will return the same value. To continue parsing the same array, to get the next value, subsequent calls to strtok have NULL as the first argument.

Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Before attaching the servo, you should write some known value to it.
ahhh thats why my servos twitch alittle when the start. i moved:
Code:
  Yaxis.write(90);
  Xaxis.write(90);
before attaching them, now no twitching smiley thanks.

Quote
Why are you initializing this variable to index? Doesn't make sense.
You should be parsing inData. The str variable is junk.
because if i use inData i get:
error: cannot convert 'int*' to 'char*' for argument '1' to 'char* strtok(char*, const char*)'

Quote
The two calls to strtok will return the same value. To continue parsing the same array, to get the next value, subsequent calls to strtok have NULL as the first argument.
ahh ok so like:
Code:
    if ( p = strtok(str, strDelimiter) )
    {
      dir = atoi(p);
    }
    if ( p = strtok(NULL, strDelimiter) )
    {
      time = atoi(p);
    }
do i even need the if statements? can i just:
Code:
   
p = strtok(str, strDelimiter);
dir = atoi(p);

p = strtok(NULL, strDelimiter);
time = atoi(p);
also is atoi needed? it just converts from acii to integer. and dir isnt an integer so it would work, right? so just:
Code:
time = p;
and
dir = p;

thanks!
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 610
Posts: 49004
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
because if i use inData i get:
error: cannot convert 'int*' to 'char*' for argument '1' to 'char* strtok(char*, const char*)'
Code:
int inData[9];
This variable should of of type char.

Quote
can i just:
You need the if tests. If the strtok operation fails, because of bad input, it returns a NULL pointer. Passing a NULL pointer to atoi() is not a good idea.

Quote
also is atoi needed? it just converts from acii to integer. and dir isnt an integer so it would work, right?
dir isn't an int, but time is.
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
This variable should of of type char.
ok i see, thanks.

ok well having a letter in the serial "command" is causing issues(the U in <U,0500,>) i put  a serial.print to return the value of dir after getting it from serial and writing to a char, and it was some weird square shape symbol. so i just made it a number instead so its <1,0500,>

in the line char inData[9]; should the number(currently 9) be the number of characters with or without the "< >" like: <1,0500,> without the <>, so it would be 5, right?

but it does work... probably because of the dir  was causing issues. thanks!
« Last Edit: October 16, 2011, 09:43:46 am by sirbow2 » Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 610
Posts: 49004
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
in the line char inData[9]; should the number(currently 9) be the number of characters with or without the "< >" like: <1,0500,> without the <>, so it would be 5, right?
You are not storing the '<' or the '>', so no need to count them. You are storing "1,0500", which I make to be 6 characters. You are also (properly) storing a trailing NULL, so the minimum size would be 7. Slightly bigger is better, though.
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Really, Thanks for your help! i can use all that info in other projects.
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so right now im expanding my void Move() to have more than just lines and diagonals. im try to get a Circle, but i have no clue on how to do that with my code. ive found examples like: http://arduino.cc/forum/index.php/topic,18965.0.html
but they use x,y coordinates, i have Up, down, Left, Right, and how long for each. how do i implement a circle drawing function?

this is the latrest code that works 100%:
Code:
#include <Servo.h>

Servo Xaxis;
Servo Yaxis;

int started = 0;
char inData[8];
int ended = 0;
char index = 0;
int final = 0;

void setup()
{
  Xaxis.write(90); 
  Xaxis.attach(6);
 
  Yaxis.write(90);
  Yaxis.attach(5);

  Serial.begin(9600);
}

void loop()
{
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      started = true;
      index = 0;
      inData[index] = '\0';
    }
    else if(aChar == '>')
    {
      ended = true;
    }

    else if(started)
    {
      inData[index] = aChar;
      index++;
      inData[index] = '\0';             
    }

    else if (aChar =='*')
    {
      final = true;
    }
  }

  if(started && ended)
  {
    const char*  strDelimiter = ",";

    char* p;
    int time;
    int dir;

    if ( p = strtok(inData, strDelimiter) )
    {
      dir = atoi(p);
    }
    if ( p = strtok(NULL, strDelimiter) )
    {
      time = atoi(p);
    }

    // Get ready for the next time
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';   
 
    Move(dir, time);
  }
}

//Servos move the dot on etch-a-sketch screen Xin/sec
void Move(int dir, int time)
{
  if (dir == 1)
  {
    Serial.print("Xaxis Right for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Xaxis.write(180);   
    delay(time);
    Xaxis.write(90);
  }

  if (dir == 2)
  {
    Serial.print("Xaxis Left for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Xaxis.write(0);
    delay(time);
    Xaxis.write(90);
  }

  if (dir == 3)
  {
    Serial.print("Yaxis Down for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Yaxis.write(0);
    delay(time);
    Yaxis.write(90);
  }

  if (dir == 4)
  {
    Serial.print("Yaxis Up for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Yaxis.write(180);
    delay(time);
    Yaxis.write(90);
  }

  if (dir == 5)
  {
    Serial.print("Down+Left diagonal for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();   

    Yaxis.write(0);      // tell servo to go to position in variable 'pos'
    Xaxis.write(0);
    delay(time);       // waits 15ms for the servo to reach the position

    Xaxis.write(90);
    Yaxis.write(90);
  }

  if (dir == 6)
  {
    Serial.print("Down+Right diagonal for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Yaxis.write(0);
    Xaxis.write(180);   
    delay(time);
    Yaxis.write(90);
  }

  if (dir == 7)
  {
    Serial.print("Up+Left diagonal for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Yaxis.write(180);
    Xaxis.write(0);   
    delay(time);
    Yaxis.write(90);
  }

  if (dir == 8)
  {
    Serial.print("Up+Right diagonal for ");
    Serial.print(time);
    Serial.print("ms");
    Serial.println();
    Yaxis.write(180);
    Xaxis.write(180);   
    delay(time);
    Yaxis.write(90);
  }
}
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 610
Posts: 49004
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i have Up, down, Left, Right, and how long for each.
If you can use these functions to go to any point, you can draw a circle.

Performing a linear approximation of a circle is not difficult. That link should have enough information to do it.

Once you have a series of x,y locations, you can move from point to point.

If the problem is how to move left for some time and up for some time to get to a specific point, that is a different issue.
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i didnt want to use x,y, just draw a circle at the current place(where ever teh etch-a-sketch point is)

im not sure, maybe like have one motor going 50% constant in one direction for a second, then mean while have the other axis motor start from 90 then increase to 180 in 500msec then decrease from 180 to 90 in another 500msec.
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i didnt want to use x,y, just draw a circle at the current place(where ever teh etch-a-sketch point is)

im not sure, maybe like have one motor going 50% constant in one direction for a second, then mean while have the other axis motor start from 90 then increase to 180 in 500msec then decrease from 180 to 90 in another 500msec. that would create a semicircle or an arc
« Last Edit: October 16, 2011, 04:44:27 pm by sirbow2 » Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok another quick question.

i have this code which does this: when it receives <2,100>(for example, 2 could be 3 or 4 depending on what direction i want to go) over serial it writes 2 to int dir and writes 100 to int time(time isnt important in this variation of the program, just a filler) then i have modified Move() so that it runs whatever motor which coordinates with int dir, which is 2, until it receives instructions other wise via serial with another command like <3,100>. but since its running motor "2" forever, its not checking for new commands overserial. so it doesnt stop.

how do i make it so that it checks for new serial commands while running a motor "forever"?

Code:
#include <Servo.h>

Servo Xaxis;
Servo Yaxis;

int started = 0;
char inData[8];
int ended = 0;
char index = 0;
int final = 0;

void setup()
{
  Xaxis.write(90); 
  Xaxis.attach(6);

  Yaxis.write(90);
  Yaxis.attach(5);

  Serial.begin(9600);
}

void loop()
{
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      started = true;
      index = 0;
      inData[index] = '\0';
    }
    else if(aChar == '>')
    {
      ended = true;
    }

    else if(started)
    {
      inData[index] = aChar;
      index++;
      inData[index] = '\0';             
    }

    else if (aChar =='*')
    {
      final = true;
    }
  }

  if(started && ended)
  {
    const char*  strDelimiter = ",";

    char* p;
    int time;
    int dir;

    if ( p = strtok(inData, strDelimiter) )
    {
      dir = atoi(p);
    }
    if ( p = strtok(NULL, strDelimiter) )
    {
      time = atoi(p);
    }

    // Get ready for the next time
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';   

    Move(dir, time);
  }
}

void Move(int dir, int time)
{
  while(dir == 1)
  {
    //Xaxis Right
    Xaxis.write(180);   
    //
  }

  while(dir == 2)
  {
    //Xaxis Left
    Xaxis.write(0);
  }

  while(dir == 3)
  {
    //Yaxis Down
    Yaxis.write(0);
  }

  while(dir == 4)
  {
    //Yaxis Up
    Yaxis.write(180);
  }
  while(dir == 9)
  {
    //stop both motors
    stop();
  }
}

void stop()
{
  Yaxis.write(90);
  Xaxis.write(90);
}
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 610
Posts: 49004
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
how do i make it so that it checks for new serial commands while running a motor "forever"?
You have this code:
Code:
  while(dir == 1)
  {
    //Xaxis Right
    Xaxis.write(180);   
    //
  }
In the "forever" loops, you right the same value to the servo over and over. Once you start the servo moving, it will keep moving until you tell it to stop. You don't need to tell it over and over to keep moving. It isn't a 14 year old, after all.

Change the while to if.
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks, i dont know why i didnt catch that. i should have seen it from the code i did before...
Logged

http://dduino.blogspot.com all my Arduino/electronic projects!!!

{NEW} Getting Started, Learning, Reference + FAQ PDF!!:
[url]http://ar

Pages: [1]   Go Up
Jump to: