DC motor gantry

Hello all,

I am working on a very basic gantry. The idea is to move it a preset distance across an X and Y axis. I have the basic sketch written and working. At this time I am using and old printer as the X axis. It indexes to the left and right as I would expect. I am using simple delay command to turn the DC motor on and off. The problem I am having is the gantry does not stop in the same place each time or move the same distance. Is this due to the inaccuracy of the on board timer? If I add a RTC will it help? If the RTC will correct the problem do I need some code to use its clock instead of the on board one? Am I better off just using stepper motors?

Thanks in advance. I look forward to learning more and finishing this.

Micheal

Post your sketch. I am guessing, but your use of delays could be the reason.

Without feedback, you will never get the repeatability you might dream about. Any variation in friction, load, voltage, temperature, or a dozen other first order variables and a million second order variables will change the behavior. Now it may be you could do better and live with the results if your timing was somehow inaccurate. As such, posting your code would be a first good step. If that down not prove to be the fault, either a stepper or an encoder feedback of sometime might be in your future.

A picture of your setup might be helpful as well. Can you estimate how far it coasts after you turn the motor off ? Do you do any dynamic braking ?

Thank you for your interest in help me. Sorry about not including the sketch, I know better. I will post the sketch tonight after work and try to include some pictures and a video.

Thank you,

Micheal

Here is the code:

int motorPinXpositive = 8;

int motorPinXnegative = 9;

int motorPinYpositive = 10;

int motorPinYnegative = 11;

int on_off = 13;

void setup()

{

pinMode (motorPinXpositive, OUTPUT);

pinMode (motorPinXnegative, OUTPUT);

pinMode (motorPinYpositive, OUTPUT);

pinMode (motorPinYnegative, OUTPUT);

digitalWrite (on_off, HIGH);

}

void loop()

{

{

if (digitalRead (on_off) == LOW)

{

for (int tableindexCount = 0; tableindexCount <3; tableindexCount++)

{

for (int XindexCount = 0; XindexCount <6; XindexCount++)

{

//index table from right to left

digitalWrite (motorPinXpositive, HIGH);

delay (50);

digitalWrite (motorPinXpositive, LOW);

delay (500);

}

//index table to next row

digitalWrite (motorPinYnegative, HIGH);

delay (100);

digitalWrite (motorPinYnegative, LOW);

delay (500);

for (int XindexCount = 0; XindexCount <6; XindexCount++)

{

//index table from left to right

digitalWrite (motorPinXnegative, HIGH);

delay (50);

digitalWrite (motorPinXnegative, LOW);

delay (500);

}

if (tableindexCount <2)

{

//index table to next row

digitalWrite (motorPinYnegative, HIGH);

delay (100);

digitalWrite (motorPinYnegative, LOW);

delay (500);

}

else

{

//index table to home

digitalWrite (motorPinYpositive, HIGH);

delay (500);

digitalWrite (motorPinYpositive, LOW);

delay (500);

}

}

digitalWrite (on_off, HIGH);

}

}

}

still working on some pictures and video

Thanks,

Micheal

I looked quickly at your code. While I have a few questions, I don’t see anything obviously bad with it, other than what fll-freak has already mentioned. You’re starting up a motor and letting it run and then coasting it when it shuts off. I’m not sure how far it’ll go in 50 msec, I suspect that part of your problem is the variation in how the motor starts from time to time is another contributor to the non-repeatability. I’ll hold further comment until I can see more of what you’re doing.

FWIW if you use the code tags (see below) you can post code in a nice box that retains all the formatting/indentation. It makes it easier to read and understand. As for questions on your code …

  1. What is on_off ? It seems to be a pin (13) but it’s mode (input or output) is not declared. You both write to it and read from it. In fact I don’t know how you get into the test positioning loop given the way it’s presently initialized.

EDIT: OK, I get it now. It’s an input whose pull-up you’ve enabled ? You push a button to run the position tests. But if so then why the second digitalWrite (on_off, HIGH); at the bottom of your code ?

  1. I assume the “motorpins” control some H bridge driver and that the Y motor is not mounted at this time.

  2. Pet peeve of mine : when pins are declared outputs, I like to immediate set them to a known safe state, rather than wait for the main loop() code to do so.

  3. There’s an extra level of {}, outside of the if (digitalRead (on_off) == LOW) that serve no purpose. No doubt left over from some debugging.

Your code, nicely formatted … with some added comments and questions from me.

int motorPinXpositive = 8;
int motorPinXnegative = 9;
int motorPinYpositive = 10;
int motorPinYnegative = 11;
int on_off = 13;                   // is this a pin ?

void setup()
{ 
  pinMode (motorPinXpositive, OUTPUT);
  pinMode (motorPinXnegative, OUTPUT);
  pinMode (motorPinYpositive, OUTPUT);
  pinMode (motorPinYnegative, OUTPUT);
  digitalWrite (on_off, HIGH);                    //pinmode is ??
}

void loop()
{
  { // Why is this here ?
    if (digitalRead (on_off) == LOW)      //What is this intended to do ?
    {
      for (int tableindexCount = 0; tableindexCount <3; tableindexCount++)
      {
        for (int XindexCount = 0; XindexCount <6; XindexCount++)
        {
          //index table from right to left
          digitalWrite (motorPinXpositive, HIGH);
          delay (50);
          digitalWrite (motorPinXpositive, LOW);
          delay (500);
        }
        //index table to next row
        digitalWrite (motorPinYnegative, HIGH);
        delay (100);
        digitalWrite (motorPinYnegative, LOW);
        delay (500);
        
        for (int XindexCount = 0; XindexCount <6; XindexCount++)
        {
          //index table from left to right
          digitalWrite (motorPinXnegative, HIGH);
          delay (50);
          digitalWrite (motorPinXnegative, LOW);
          delay (500);
        }
        if (tableindexCount <2)
        {
          //index table to next row
          digitalWrite (motorPinYnegative, HIGH);
          delay (100);
          digitalWrite (motorPinYnegative, LOW);
          delay (500);
        }
        else
        {
          //index table to home
          digitalWrite (motorPinYpositive, HIGH);
          delay (500);
          digitalWrite (motorPinYpositive, LOW);
          delay (500);
        }
      }
      digitalWrite (on_off, HIGH);
    }
  } // Why is this here ?
}

(click on to enlarge)

So,

  1. Yes, on_off is an input. It is a micro switch to start the process. I did not declare it because I read somewhere the pins were inputs as a default setting. Do not remember why I added the digitalwrite at the end.

  2. the X and Y motors are controlled using a L298N Stepper Controller Module.

  3. again, not sure. I think I removed some code and left the braces

Here is a video: http://youtu.be/FBgbGHTrBMw

As you can see I am using an old printer for the X and the DVD tray for the Y.

I think the lack of breaking is the cause for my issue. When moving the table in the X negative direction do I pulse the X positive after turning off the X negative or do I turn on the X positive at the last millisecond?

Micheal

XtremeIN:
I think the lack of breaking is the cause for my issue. When moving the table in the X negative direction do I pulse the X positive after turning off the X negative or do I turn on the X positive at the last millisecond?

Micheal

I think you want to wait just a little bit before braking to be sure the H bridge doesn't short itself out. I don't know what to say for the wait and brake times. The wait time need only be as long as it takes for the L298 to respond to the command, perhaps several usecs. That might not even be required, your driver circuitry may be foolproof. Then you don't reverse the voltage (though that might work, I just wonder how hard it would be on the drivers) but short the terminals. If you're L298 based driver is like this one ...

http://www.canakit.com/Media/Manuals/UK1122.pdf

… note Note#3 (below). If this type braking doesn’t work, try reversing the direction after the wait. That will certainly brake, I just hope it doesn’t break something else. Using the 1’st case braking means you can leave the brakes on until the next command to move. Using the 2’nd case means you’ll have to figure out how long to reverse it for to get the best results. That reverse time may be a function of the on time, but capped to some max number. Frankly I was surprised by how far the X gantry moved for what I think was a 50 msec on time. Time to do some experiments I think.

The data sheet is helpful. I will try a few different test this weekend. I have also been reading about hacking into the printers linear encoder. So many options, this is going to be fun…

Micheal

I can’t offer much help, but would like point out that performing a digitalWrite(pin, HIGH) on a pin that is configured as a digital input turns ON the internal 20k ohm resistor. Just sayin’.