Go Down

Topic: XY Plotter/CNC style interpolation project. Need great deal of help (Read 25 times) previous topic - next topic

wildbill

Get the debug code for 'P' to show you xIs0 and yIs0. Depending on how those switches are wired/set, you could be setting xPos & YPos to zero on every iteration of loop.

stimmer

#16
Mar 30, 2012, 03:42 am Last Edit: Mar 30, 2012, 03:43 am by stimmer Reason: 1
There are some places where you have used == where you should have used =
Where you assign to a variable you need to use = not ==

Change this:
Code: [Select]
 if(digitalRead(xStopMin) == HIGH){
   xIs0 == true;  
   xPos = 0;
   Serial.println("xMin");
 }
 else xIs0 == false;


to this:
Code: [Select]

 if(digitalRead(xStopMin) == HIGH){
   xIs0 = true;  
   xPos = 0;
   Serial.println("xMin");
 }
 else xIs0 = false;

and similar for the other end stop checks. (the == in the if is correct)
Look at http://arduino.cc/en/Reference/Assignment and http://arduino.cc/en/Reference/If for more info on when to use = or ==

I don't think this is the cause of the problem of xPos and yPos always reading 0, but it can't hurt to fix it.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

sirbow2

yes as he says "==" is testing, "=" is setting values:
if(something == something)//testing
value = value2; //setting value equal to value 2

Code: [Select]
if(digitalRead(xStopMin) == HIGH){
    xIs0 = true; 
    xPos = 0;
    Serial.println("xMin");
  }

you say xPos = 0;, if you accidentally pressed the button,. it may reset the value, but i dont hink this is your issue.

put Serial.println()s around where the xPos and yPos value would change and see if they make sense.
http://dduino.blogspot.com all my Arduino/electronic projects!!!

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

breegeek

stimmer, sirbow, wildbill --- thanks for all your help so far!

I am getting a readout for xpos and ypos, but now that I have fixed the xIs0 == true to xIs0 = true, the switches seem to be seriously misbehaving. I am not sure what's going on, but they seem to constantly read out high.




Code: [Select]


/* Stepper Motor Controller ;  language: Wiring/Arduino
This program drives a unipolar or bipolar stepper motor.  by Tom Igoe */
/* significant help from arduino forum superstars: sirbow2, stimmer
*/

#include <Stepper.h>

#define motorSteps 200     // change this depending on the number of steps
#define motor2Steps 200     // change this depending on the number of steps
// per revolution of your motor


#define motorPin1 2
#define motorPin2 3
#define motorPin3 4
#define motorPin4 5
#define motorPin6 8
#define motorPin7 9
#define motorPin8 10
#define motorPin9 11


int reading = 0;
int previous = LOW;
long time = 0;         // the last time the output pin was toggled
long debounce = 50;   // the debounce time, increase if the output flickers
int state = HIGH;   

//set pin numbers

int xStopMax = A1;
int xStopMin = A0;
int yStopMin = A3;
int yStopMax = A2;



int xPos;
int yPos;
boolean xIs0;
boolean xIsMax;
boolean yIs0;
boolean yIsMax;


// initialize of the Stepper library:
Stepper yAxis(motorSteps, motorPin1,motorPin2, motorPin3, motorPin4);
Stepper xAxis(motor2Steps, motorPin6,motorPin7, motorPin8, motorPin9);




void setup() {

  // set the motor speed at 60 RPMS:
  xAxis.setSpeed(60); //x
  yAxis.setSpeed(60); //y

  //set limit switches to analog inputs
  pinMode(xStopMin, INPUT);
  pinMode(xStopMax, INPUT);
  pinMode(yStopMin, INPUT);
  pinMode(yStopMax, INPUT);
 
  xPos = 0;
  yPos = 0;

  // Initialize the Serial port:
  Serial.begin(9600);
}

void loop() {
  //check limit switches
  if(digitalRead(xStopMin) == HIGH){

   
    xIs0 = true; 
    xPos = 0;
    Serial.println("xMin");
  }
  else xIs0 = false;



  if(digitalRead(xStopMax) == HIGH){
    xIsMax = true; 
    Serial.println("xMax");
  }
  else xIsMax = false;

  if(digitalRead(yStopMin) == HIGH){
    yIs0 = true; 
    Serial.println("yMin");
    yPos = 0;
   
   }
  else yIs0 = false;

  if(digitalRead(yStopMax) == HIGH){
    yIsMax = true; 
    Serial.println("yMax");
  }
  else yIsMax = false;



  char val=0;
  if(Serial.available()) val = Serial.read();

  //keyboard control 
  switch(val){
  case 'N':
    Serial.read();
      moveN(200);
    break;

  case 'S':
    Serial.read();
      moveS(200);
    break;

  case 'E':
    Serial.read();
      moveE(200);
    break;

  case 'W':
    Serial.read();
      moveW(200);
    break;



    //diagonal (moving motors almost at the same time)     
  case 'J': //NE
    Serial.read();
          moveNE(200);
    break;
  case 'H': //NW
     Serial.read();
          moveNW(200);
    break;

  case 'X': //SE
    Serial.read();
          moveSE(200);
    break;
  case 'Z': //SW
     Serial.read();
          moveSW(200);
    break;

  case 'C': //SW
     Serial.read();
          moveCirc();
    break;
 
 
  //resets
  case 'Q': //reset to 0,0
     Serial.read();
         moveN(100);
         moveE(100);
     break;
     


//debugs
   case 'P':
     Serial.read();
       Serial.print("x position: ");
       Serial.println(xPos);
       Serial.println("y position: ");
       Serial.println(yPos);
    break;

  default:
    Serial.read();
    delay(10);
    break;
  }
}
//movement functions

  //first, str  aight up down left right
void moveE(int numSteps){
    int s = 0;
    while(!digitalRead(xStopMax)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
    {
          xAxis.step(1);
          s++;
      } 
      delay(100);   
     xPos += numSteps;
     Serial.println(xPos);
     Serial.println(yPos);
}


void moveW(int numSteps){
     int s = 0;
    while(!digitalRead(xStopMin)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
    {
          xAxis.step(-1);
          s++;
      } 
      delay(100);   
    xPos -= numSteps;
}

void moveN(int numSteps){
   int s = 0;
    while(!digitalRead(yStopMax)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
    {
          yAxis.step(-1);
          s++;
      } 
      delay(100);   
    yPos += numSteps;

   
void moveS(int numSteps){
  int s = 0;
    while(!digitalRead(yStopMin)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
    {
          yAxis.step(1);
          s++;
      } 
      delay(100);   
    yPos -= numSteps;
}   

//diagonals
void moveNE(int numSteps){   
  int s=0;
  while(!digitalRead(xStopMax) && !digitalRead(yStopMin) && s<numSteps);
    for(int s=0; s<numSteps; s++)
    {
        yAxis.step(-1);
        xAxis.step(1);
      }
   xPos += numSteps;
   yPos -= numSteps;



void moveSE(int numSteps){
   int s=0;
  while(!digitalRead(xStopMax) && !digitalRead(yStopMax) && s<numSteps);
    for(int s=0; s<numSteps; s++)
    {
        yAxis.step(1);
        xAxis.step(1);
      }
   xPos += numSteps;
   yPos += numSteps;

 
 
void moveSW(int numSteps){
  int s=0;
    while(!digitalRead(xStopMin) && !digitalRead(yStopMax) && s<numSteps);
      for(int s=0; s<numSteps; s++)
      {
          yAxis.step(1);
          xAxis.step(-1);
        }
   xPos -= numSteps;
   yPos += numSteps;
    } 
void moveNW(int numSteps){
  int s=0;
    while(!digitalRead(xStopMin) && !digitalRead(yStopMin) && s<numSteps);
      for(int s=0; s<numSteps; s++)
      {
          yAxis.step(-1);
          xAxis.step(-1);
        }
   xPos -= numSteps;
   yPos -= numSteps;
    } 

void moveCirc(){
   //draw circle at x,y 50,50
    int CircleXCenter = 2;
    int CircleYCenter = 2;
    int CurXPos = xPos; //where the platform currently is in X
    int CurYPos = yPos; //where the platform currently is in Y
    int Rad = 1;
   
   
   
   
    for (int i = 0; i < 360; i++)
      {
    //it does this for each point of the circle, so you dont have to run them at the same time
       float
       angle = i*2*3.14/360;
        xPos = CircleXCenter + (cos(angle) * Rad);
        yPos = CircleYCenter + (sin(angle) * Rad);
        if(CurXPos < xPos)
         {
           
               xAxis.step(xPos - CurXPos);
              //movexnow = Xpos - CurXPos;
          }
       else
       {
               xAxis.step(xPos - CurXPos);
           //MoveXNow = CurXPos - Xpos;
       }
       
        if(CurYPos < yPos)
        {
               yAxis.step(yPos - CurYPos);
             //   MoveYNow = Ypos - CurYPos;
        }
       else
       {
               yAxis.step(yPos - CurYPos
               );
             //MoveYNow = CurYPos - Ypos;
       }
   
      // step(xAxis);
       //step(yAxis);
     
                 //<100, so -1
       if(i == (360-1)) //we are at end of for loop, save current position.
       {
           CurYPos = yPos;
           CurXPos = xPos ;
       }
   
      }
     
}

sirbow2

maybe your switches are HIGH when open and LOW when closed(pressed)
http://dduino.blogspot.com all my Arduino/electronic projects!!!

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

breegeek

Hi Sirbow, they are wired as Normally Closed. In the logic, the switches were only printing out when pushed, which set them as HIGH

stimmer

Can you give any more detail about how your switches are wired up? Sometimes this problem can be caused if the switch doesn't have a pullup resistor (or pulldown resistor, depending on how it is wired). Do you have a circuit diagram / schematic?
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

breegeek

No circuit diagram...

Hmm I haven't put in a resistor; is that my problem?  I have these: http://www.electronicsurplus.com/Item/19781/MICRO%20SWITCH%20-%20Switch_%20micro_%20Contacts_%20SPDT_%20-%201052-7325/


with ground and NC (normally closed) wired. Input pin is directly into my arduino...

sirbow2

yeah, you need a resistor to keep the switch pulled down/up so that reading is stable: http://arduino.cc/it/Tutorial/Button
http://dduino.blogspot.com all my Arduino/electronic projects!!!

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

breegeek

Oooh! Will try that!

A colleague of mine suggested for trying to do interpolation: catmull rom spline

Since I will have the motion all be relative, and the thing has to respond to OpenCV messages. What do you think? Am I going about this incorrectly so far?

breegeek

Should I use a pull-down for a normally closed switch?

sirbow2

one side of the NC switch to GND the other side to the digital pin and a pullup to 5v(so that when the switch is pressed and becomes open, the pin is 5v(HIGH))
http://dduino.blogspot.com all my Arduino/electronic projects!!!

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

breegeek

Hey, ok so I will be rewiring my switches tomorrow and will see how it all works out.

I was wondering if you guys could help me in advance with two things:

1- Using the code I have posted so far, where I pulse the stepper motors in order to make the head move in specific directions, how do I make sure that the code changes xPos and yPos only when the motors actually spin? Sometimes, I send a signal through the serial window in Arduino, and Arduino does the math of adding 200 to the xPos, but sometimes it seems that the motor skips signals: I have to hit 'E' and ENTER a few times before the thing moves. I am not sure if the Serial.read happens in cycles or with some kind of delay?
Code: [Select]

/* Stepper Motor Controller ;  language: Wiring/Arduino
This program drives a unipolar or bipolar stepper motor.  by Tom Igoe
and the Spline library by Kerinin
*/

/* significant help from arduino forum superstars: sirbow2, stimmer
*/
#include <spline.h>
#include <Stepper.h>

#define motorSteps 200     // change this depending on the number of steps
#define motor2Steps 200     // change this depending on the number of steps
// per revolution of your motor


#define motorPin1 2
#define motorPin2 3
#define motorPin3 4
#define motorPin4 5
#define motorPin6 8
#define motorPin7 9
#define motorPin8 10
#define motorPin9 11


int reading = 0;
int previous = LOW;
long time = 0;         // the last time the output pin was toggled
long debounce = 50;   // the debounce time, increase if the output flickers
int state = HIGH;   

//set pin numbers

int xStopMax = A1;
int xStopMin = A0;
int yStopMin = A3;
int yStopMax = A2;



int xPos;
int yPos;
boolean xIs0;
boolean xIsMax;
boolean yIs0;
boolean yIsMax;


// initialize of the Stepper library:
Stepper yAxis(motorSteps, motorPin1,motorPin2, motorPin3, motorPin4);
Stepper xAxis(motor2Steps, motorPin6,motorPin7, motorPin8, motorPin9);




void setup() {

  // set the motor speed at 60 RPMS:
  xAxis.setSpeed(60); //x
  yAxis.setSpeed(60); //y

  //set limit switches to analog inputs
  pinMode(xStopMin, INPUT);
  pinMode(xStopMax, INPUT);
  pinMode(yStopMin, INPUT);
  pinMode(yStopMax, INPUT);

  xPos = 0;
  yPos = 0;

  // Initialize the Serial port:
  Serial.begin(9600);
}

void loop() {
  //check limit switches
if(digitalRead(xStopMin) == HIGH){
    xIs0 = true; 
    xPos = 0;
    Serial.println("xMin");
  }
  else xIs0 = false;



  if(digitalRead(xStopMax) == HIGH){
    xIsMax = true; 
    Serial.println("xMax");
  }
  else xIsMax = false;

  if(digitalRead(yStopMin) == HIGH){
    yIs0 = true; 
    Serial.println("yMin");
    yPos = 0;

  }
  else yIs0 = false;

  if(digitalRead(yStopMax) == HIGH){
    yIsMax = true; 
    Serial.println("yMax");
  }
  else yIsMax = false;


  char val=0;
  if(Serial.available()) val = Serial.read();

  //keyboard control 
  switch(val){
  case 'N':
    Serial.read();
    moveN(200);
    break;

  case 'S':
    Serial.read();
    moveS(200);
    break;

  case 'E':
    Serial.read();
    moveE(200);
    break;

  case 'W':
    Serial.read();
    moveW(200);
    break;



    //diagonal (moving motors almost at the same time)     
  case 'J': //NE
    Serial.read();
    moveNE(200);
    break;
  case 'H': //NW
    Serial.read();
    moveNW(200);
    break;

  case 'X': //SE
    Serial.read();
    moveSE(200);
    break;
  case 'Z': //SW
    Serial.read();
    moveSW(200);
    break;

  case 'C': //SW
    Serial.read();
    moveCirc();
    break;


    //resets
  case 'Q': //reset to 0,0
    Serial.read();
    moveN(100);
    moveE(100);
    break;



    //debugs
  case 'P':
    Serial.read();
    Serial.print("x position: ");
    Serial.println(xPos);
    Serial.println("y position: ");
    Serial.println(yPos);
    break;

  default:
    Serial.read();
    delay(10);
    break;
  }
}
//movement functions

//first, str  aight up down left right
void moveE(int numSteps){
  int s = 0;
  while(!digitalRead(xStopMax)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
  {
    xAxis.step(1);
    s++;
  } 
  //delay(100);   

  xPos += numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);
}


void moveW(int numSteps){
  int s = 0;
  while(!digitalRead(xStopMin)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
  {
    xAxis.step(-1);
    s++;
  } 
  //delay(100);   
  xPos -= numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);
}

void moveN(int numSteps){
  int s = 0;
  while(!digitalRead(yStopMax)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
  {
    yAxis.step(-1);
    s++;
  } 
  //delay(100);   
  yPos += numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);


void moveS(int numSteps){
  int s = 0;
  while(!digitalRead(yStopMin)&& s<numSteps)//checks the button each step, also checks to see if it has moved s amount of steps
  {
    yAxis.step(1);
    s++;
  } 
  //delay(100);   
  yPos -= numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);
}   

//diagonals
void moveNE(int numSteps){   
  int s=0;
  while(!digitalRead(xStopMax) && !digitalRead(yStopMin) && s<numSteps);
  for(int s=0; s<numSteps; s++)
  {
    yAxis.step(-1);
    xAxis.step(1);
  }
  xPos += numSteps;
  yPos -= numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);



void moveSE(int numSteps){
  int s=0;
  while(!digitalRead(xStopMax) && !digitalRead(yStopMax) && s<numSteps);
  for(int s=0; s<numSteps; s++)
  {
    yAxis.step(1);
    xAxis.step(1);
  }
  xPos += numSteps;
  yPos += numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);



void moveSW(int numSteps){
  int s=0;
  while(!digitalRead(xStopMin) && !digitalRead(yStopMax) && s<numSteps);
  for(int s=0; s<numSteps; s++)
  {
    yAxis.step(1);
    xAxis.step(-1);
  }
  xPos -= numSteps;
  yPos += numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);




void moveNW(int numSteps){
  int s=0;
  while(!digitalRead(xStopMin) && !digitalRead(yStopMin) && s<numSteps);
  for(int s=0; s<numSteps; s++)
  {
    yAxis.step(-1);
    xAxis.step(-1);
  }
  xPos -= numSteps;
  yPos -= numSteps;

  //check where we are
  Serial.print("x position: ");
  Serial.println(xPos);
  Serial.print("y position: ");
  Serial.println(yPos);


void moveCirc(){
  //draw circle at x,y 50,50
  int CircleXCenter = 2;
  int CircleYCenter = 2;
  int CurXPos = xPos; //where the platform currently is in X
  int CurYPos = yPos; //where the platform currently is in Y
  int Rad = 1;




  for (int i = 0; i < 360; i++)
  {
    //it does this for each point of the circle, so you dont have to run them at the same time
    float
      angle = i*2*3.14/360;
    xPos = CircleXCenter + (cos(angle) * Rad);
    yPos = CircleYCenter + (sin(angle) * Rad);
    if(CurXPos < xPos)
    {

      xAxis.step(xPos - CurXPos);
      //movexnow = Xpos - CurXPos;
    }
    else
    {
      xAxis.step(xPos - CurXPos);
      //MoveXNow = CurXPos - Xpos;
    }

    if(CurYPos < yPos)
    {
      yAxis.step(yPos - CurYPos);
      //   MoveYNow = Ypos - CurYPos;
    }
    else
    {
      yAxis.step(yPos - CurYPos
        );
      //MoveYNow = CurYPos - Ypos;
    }

    // step(xAxis);
    //step(yAxis);

    //<100, so -1
    if(i == (360-1)) //we are at end of for loop, save current position.
    {
      CurYPos = yPos;
     
      CurXPos = xPos ;
    }

  }

}




2. I am thinking of using Spline's library to plot points for the program to follow and have the points sent to Arduino by Processing. Problem is, I looked at the Arduino example code, but really don't know how I am going to make it work. Any advice of how to approach this?

You guys rock so hard!
Thanks!

sirbow2

2. i ve never really heard of splines library, i might look at it, though.

1. getting rid of the
Code: [Select]
if(digitalRead(xStopMin) == HIGH){
    xIs0 = true; 
    xPos = 0;
    Serial.println("xMin");
  }
  else xIs0 = false;

parts of your code and using interrupts instead. maybe making the switch case part of your code smaller would make it run faster. but serial data is stored in a hardware buffer until Serial.read is called, so it wouldnt matter...i think?
http://dduino.blogspot.com all my Arduino/electronic projects!!!

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

breegeek

Thanks for the reply;

I increase the xpos and ypos when I step the motor; I guess there's no way for Arduino to know if it actually moved the motor successfully?

Yeah, the spline library looks cool, especially for my purposes, but I am a mega n00b and don't completely understand what's going on....

Go Up