Go Down

Topic: Arduino chip as Stepper Controller (Read 12854 times) previous topic - next topic

kf2qd

The Arduino chip is inexpensive ($5.50US), which seems to be much cheaper that the PICs.(($30.00US) There is a PIC that has been programmed as a stepper driver - has Step, Direction, Enable, limits, Home and such inputs and 4 outputs for the phases. Basically the 4 pahse outputs tie to 4 transistoer/diodes to drive the stepper motor.

The Arduino would be basically be functioning as an up down counter and outputting to the appropriate digital pin. Patterns for Full Step, Half Step and Wave are easy, don't think the analog outputs would be fast enough for microstepping, but...

Any ideas on how to get eh code fast enough, or is this only for the realm of assembler?

I know it might seem like overkill, but by the time you put the components together it has become hardwasre complex rather than software complex, and software complex is generally easier to change...

Thanks -
Pete

kf2qd

#1
Dec 29, 2011, 11:40 pm Last Edit: Jan 15, 2012, 06:28 pm by kf2qd Reason: 1
Got to thinking about this and came up with some code to test -
Posting it here to see what someone else might think.
Code: [Select]

/*
Step & Direction Stepper Driver
Pins 9, 10, 11, 12 are tied to transistors
for each of the motor phases.
Pins 2 & 3 are used as interrupts,
Pin 2 as Step and 3 as Direction.
*/

int pin1 =9;
int pin2 = 10;
int pin3 = 11;
int pin4 = 12;
int pinDir = 3;
volatile int ctr;
volatile int dir;

void setup()
{
 pinMode(pin1, OUTPUT);
 pinMode(pin2, OUTPUT);
 pinMode(pin3, OUTPUT);
 pinMode(pin4, OUTPUT);
 pinMode(pinDir, INPUT);
 ctr=0;
 dir = 0;
 attachInterrupt(0, Step, RISING);
 attachInterrupt(1, Direction, CHANGE);

}

void loop()
{
}

void Step()
{
 if (dir)
 {
   ctr++ & 3;
 }
 else
 {
   ctr-- & 3;
 }

 switch (ctr){
 case 0:
   digitalWrite(pin1,HIGH);
   digitalWrite(pin2,LOW);
   digitalWrite(pin3,LOW);
   digitalWrite(pin4,LOW);
   break;
 case 1:
   digitalWrite(pin1,LOW);
   digitalWrite(pin2,HIGH);
   digitalWrite(pin3,LOW);
   digitalWrite(pin4,LOW);
   break;
 case 2:
   digitalWrite(pin1,LOW);
   digitalWrite(pin2,LOW);
   digitalWrite(pin3,HIGH);
   digitalWrite(pin4,LOW);
   break;
 case 3:
   digitalWrite(pin1,LOW);
   digitalWrite(pin2,LOW);
   digitalWrite(pin3,LOW);
   digitalWrite(pin4,HIGH);
   break;
 }  
}  
void Direction()
{
 if ( digitalRead(pinDir) )
 {
   dir = 0;
 }
 else
 {
   dir=-1;
 }  
}

kf2qd

#2
Dec 30, 2011, 03:26 am Last Edit: Jan 15, 2012, 06:26 pm by kf2qd Reason: 1
Had to make a slight change, now just to see how it works when I hook it up to a computer.
Code: [Select]

/*
Step & Direction Stepper Driver
Pins 9, 10, 11, 12 are tied to transistors
for each of the motor phases.
Pins 2 & 3 are used as interrupts,
Pin 2 as Step and 3 as Direction.
*/

int pin1 =9;
int pin2 = 10;
int pin3 = 11;
int pin4 = 12;
int pinDir = 3;
volatile int ctr;
volatile int dir;

void setup()
{
 pinMode(pin1, OUTPUT);
 pinMode(pin2, OUTPUT);
 pinMode(pin3, OUTPUT);
 pinMode(pin4, OUTPUT);
 pinMode(pinDir, INPUT);
 ctr=0;
 dir = 0;
 attachInterrupt(0, Step, RISING);
 attachInterrupt(1, Direction, CHANGE);

}

void loop()
{
}

void Step()
{
 if (dir)
 {
 [glow=yellow,2,300]  ctr++;
[/glow]  }
 else
 {
[glow=yellow,2,300]    ctr--;[/glow]
 }
[glow=yellow,2,300]  ctr = ctr  & 3;[/glow]
 switch (ctr){
 case 0:
   digitalWrite(pin1,HIGH);
   digitalWrite(pin2,LOW);
   digitalWrite(pin3,LOW);
   digitalWrite(pin4,LOW);
   break;
 case 1:
   digitalWrite(pin1,LOW);
   digitalWrite(pin2,HIGH);
   digitalWrite(pin3,LOW);
   digitalWrite(pin4,LOW);
   break;
 case 2:
   digitalWrite(pin1,LOW);
   digitalWrite(pin2,LOW);
   digitalWrite(pin3,HIGH);
   digitalWrite(pin4,LOW);
   break;
 case 3:
   digitalWrite(pin1,LOW);
   digitalWrite(pin2,LOW);
   digitalWrite(pin3,LOW);
   digitalWrite(pin4,HIGH);
   break;
 }  
}
void Direction()
{
 if ( digitalRead(pinDir) )
 {
   dir = 0;
 }
 else
 {
   dir=-1;
 }
}

gharryh

And how do you hook it up to a computer? I dont see any IO going on.

kf2qd

A unipolar stepper driver controller.
At this point Pins 2 & 3 are Step and Direction Inputs. 

Motion programs like Mach3 and other CNC programs provide the step and direction signals, and this would then take those signals and use the outputs to drive the 4 phases of a stepper motor.

There are dedicated chips for doing this, but this would give me more ability to control the function of my stepper controller. THis is just 1:1 stepping, but minor programming would give 2:1 and other ratios could be done by using analog outputs or a device other than a transistor for the final output device.

gharryh

Now i am confused. Do you use the dedicated chip to drive the stepper or the Arduino.
If you use the PC to send Direction and Step commands what does the Arduino do?

kf2qd

A stepper motor is 4 sets of coils that you power in sequence to cause the motor to rotate. Most programs that want to do motion supply a step and a direction signal.

Now there are various ways to do this. A circuit can be made using a counter and a 2 to 4 decoder, various stepper driver chips and all require some higher power dice to actually feed power to the motor windings.

One solution is a PIC based Stepper controller, but as I have no experience with PICs no programming tools, no other pic hardware...

So - I wondered what it would take to  do this with a AVR. Program size is 1560 bytes, so I could do this with something with only 2K, but would it have enough pins to do the other functions? ( ATtiny2313 might work, but I need programming hardware 2.88 for 3 = 8.64, 14.95 for programmer total 23.50 + shipping, Arduino chip - 5.50 for 3 = 16.50)

So  - I need a chip that will - at the least - take 2 inputs, 1 STEP and 1 DIRECTION. Depending on the state of the direction pin Step causes a counter to be either incremented or decremented. And base on the value of the counter (which has limits of 0 to 3) turn on the proper output(s). Simple stepping means that winding 1, winding 2, winding 3, or winding 4 will be on at any one time. (looks like 1, 2, 3, 4, 1, 2, 3, 4,..) or I could program in another sequence (I think it is called wave mode) would look like 12, 23, 34, 41, 12, 23,34,.... Halfstepping - 1, 12, 2, 23, 3, 34, 4, 41, 1, 12, 2, 23, 3,...

I can hook up whatever output transistors I want based on my current requirements an amp or 2, or 8 to 10 amps.

So - I have my Arduino, a resonator, 4 transistors and 4 diodes, hook 3 of them up to my computer (Mach3) and have a 3 axis CNC or Robot. Or hook 3 of them to an Arduino and have a 3 axis, all Arduino CNC.

gharryh

So you have ONLY 4 transistors. In all my circuitry i am using the example given here:
http://vimeo.com/6972843

But if you need to connect 3 steppers to the Arduino there are not enough outputs to work with.
Then one has to use a dedicated chip that only uses 2 or 3 inputs eg STEP, DIRECTION and mayby als ENABLE.

But there are even circuits somewhere on the net that uses the PC's printerport and then you dont need the Arduine.

kf2qd

I know  - I can buy a dedicated chip to drive the transistors to in turn drive a stepper motor.

Those chips all have their limitations and requirements. I was attempting to use an Arduino/AVR chip in a similar way to the PICStepper.

I have the logic working and I now need to see how fast it will function.

By using a programmable chip I can easily use standard stepping (1, 2, 3 ,4 ,1...)
or I can use wave stepping (12, 23, 34, 41, 12...)
or I can use Half Stepping (1, 12, 2, 23, 3, 34, 4, 41, 1...)

I can use an Arduino, a resonator, 4 transistors and 4 diodes and 4 resistors and a small piece of perfboard.

Some-one else has created a version that has microstepping abilities.

The Arduino doe not have to be the primary brain in a circuit to be use appropriately. Some times it can be an auxiliary circuit.

What i am looking at is this - can I put together a multi-axis system and could the Arduino be a useful part of the circuit? I have to get a few driver transistors and see just how fast the Arduino will switch and how fast I can run a motor using the Arduino as a  stepper controller.

1 Arduino with 2 inputs to the interrupt pins, and 4 pins outputting for the 4 phases of a unipolar stepper motor, to start. A couple H bridges and it would work with unipolar steppers.

Just because someone has already created a circuit for a function doesn't mean that we can't try to do it a different way. Using the logic that says that there are already chips out there to drive a stepper would also suggeswt that one should not bother trying to create a computer because someone else has already done that.

>gharryh -
>And how do you hook it up to a computer? I don't see any IO going on.
Read the code - interrupts are inputs. If nothing happens on the interrupt pins (pins 2 & 3 ) then nothing happens in the program. Interrupts are fast, non-polled (interrupt) inputs. When the pin meets the conditions in the interrupt definition line, the currently executing code is INTERRUPTED, and the appropriate routine is executed.
>Now i am confused. Do you use the dedicated chip to drive the stepper or the Arduino.
The Arduino becomes the dedicated chip that drives the stepper motor.
>If you use the PC to send Direction and Step commands what does the Arduino do?
It takes the step and direction signals and drives the outputs to the transistors that power the stepper motor. The Arduino is the STEPPER CONTROLLER CHIP.
>But if you need to connect 3 steppers to the Arduino there are not enough outputs to work with.
No, I use 3 arduinos setup as stepper controllers and each Arduino drives 1 stepper motor. Later I can add limit switch inputs or other functionality that I think I might want. In software it is rather cheap to try things. I can create a different version of my stepper controller and I don't have to use a soldering iron, instead I use my keyboard...
>Then one has to use a dedicated chip that only uses 2 or 3 inputs eg STEP, DIRECTION and mayby als ENABLE.
If you would have read my comments you would have seen that I am not trying to hook more than 1 stepper to the Arduino - I am trying to use the arduino as the stepper controller.
>But there are even circuits somewhere on the net that uses the PC's printerport and then you dont need the Arduino.
The I guess we should all scrap our Arduinos because we are all recreating stuff that is already out there, but in a different form than we might wish to use. And it would appear that you feel I have an obligation to fund these other projects, even if they are not quite what I want? You need to (to use an over-used phrase) think outside the box. In other words, try something different, just because, and see if maybe you can come up with a better, faster, cheaper, more personally satisfying solution for what you wish to do. After all - that is what the Arduino is all about.
I want a stepper controller as part of a system, Not a standalone Arduino making 2 stepper motors move. The arduino is probably overkill, but the chip is cheap, is easy to work with and I have them in hand. Maybe later I will get the stuff and try it with an ATtiny2313, but then I will have to learn a few different tools and I am just a bit lazy...

celem

kfqtd - Please follow up with future posts on your progress. The thought of using the ATtiny2313 as a component is appealing to me. I used to do similar stuff back in the Z80 days (I am a retired engineer) and the Arduino has sparked my interest anew. It has been fun to knock the dust off of my old soldering iron and tinker again. I used to use the Z80 in lots of interrupt driven situations and I am eager to see more sophisticated uses for the Arduino/ATtiny2313.

kf2qd

#10
Jan 08, 2012, 02:27 am Last Edit: Jan 15, 2012, 06:24 pm by kf2qd Reason: 1
******************************************************************************************************************************************************
****** This code has a problem... the interrupts don't function the way I wrote it. Can't have 2 interrupt routines on one interrupt...
But if you look farther down I have some cleaner code that does work...
*****************************************************************************************************************************************************
Here's the latest code -
I chose to use 2 interrupts on the direction pin as I could simplify the code, and thus make it run faster.
OOPS... That didn't work to well, only got the second one of the 2...


There are 3 step procedures - 2 are commented out, the active one is for half stepping.
Here it is -
Code: [Select]

/*
Step & Direction Stepper Driver
Pins 9, 10, 11, 12 are tied to transistors
for each of the motor phases.
Pins 2 & 3 are used as interrupts,
Pin 2 as Step and 3 as Direction.
*/

int pin1 =9;
int pin2 = 10;
int pin3 = 11;
int pin4 = 12;
int pinDir = 3;
volatile int ctr;
volatile int dir;
void setup()
{
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(2, INPUT);
 ctr=0;
 dir = 0;
 attachInterrupt(0, Step, RISING);
 attachInterrupt(1, DirPos, RISING);
 attachInterrupt(1, DirNeg, FALLING);
}

void loop()
{
 
}

/* This pattern for simple stepping */  
/*
void Step()
{
if (dir)
{
  ctr-- ;
}
else
{
  ctr++ ;
}
ctr = ctr & 3;

switch (ctr){
case 0:
  digitalWrite(4,HIGH);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);
  break;
case 1:
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);
  break;
case 2:
  digitalWrite(4,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,HIGH);
  digitalWrite(7,LOW);
  break;
case 3:
  digitalWrite(4,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,HIGH);
  break;
}
}
*/
/* use this sequence for wave stepping */  
/*
void Step()
{
if (dir)
{
  ctr-- ;
}
else
{
  ctr++ ;
}
ctr = ctr & 3;

case 0:
  digitalWrite(4,HIGH);
  digitalWrite(5,HIGH);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);
  break;
case 1:
  digitalWrite(4,LOW);
  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,LOW);
  break;
case 2:
  digitalWrite(4,LOW);
  digitalWrite(5,LOW);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);
  break;
case 3:
  digitalWrite(4,HIGH);
  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,HIGH);
  break;
}
}
*/  
/* Use this sequence for half stepping */

void Step()
{
 if (dir)
 {
   ctr-- ;
 }
 else
 {
   ctr++ ;
 }
 ctr = ctr & 7;
 switch (ctr){
 case 0:
   digitalWrite(4,HIGH);
   digitalWrite(5,LOW);
   digitalWrite(6,LOW);
   digitalWrite(7,LOW);
   break;
 case 1:
   digitalWrite(4,HIGH);
   digitalWrite(5,HIGH);
   digitalWrite(6,LOW);
   digitalWrite(7,LOW);
   break;
 case 2:
   digitalWrite(4,LOW);
   digitalWrite(5,HIGH);
   digitalWrite(6,LOW);
   digitalWrite(7,LOW);
   break;
 case 3:
   digitalWrite(4,LOW);
   digitalWrite(5,HIGH);
   digitalWrite(6,HIGH);
   digitalWrite(7,LOW);
   break;
 case 4:
   digitalWrite(4,LOW);
   digitalWrite(5,LOW);
   digitalWrite(6,HIGH);
   digitalWrite(7,LOW);
   break;
 case 5:
   digitalWrite(4,LOW);
   digitalWrite(5,LOW);
   digitalWrite(6,HIGH);
   digitalWrite(7,HIGH);
   break;
 case 6:
   digitalWrite(4,LOW);
   digitalWrite(5,LOW);
   digitalWrite(6,LOW);
   digitalWrite(7,HIGH);
   break;
 case 7:
   digitalWrite(4,HIGH);
   digitalWrite(5,LOW);
   digitalWrite(6,LOW);
   digitalWrite(7,HIGH);
   break;
 }  
}  

void DirPos()
{
   dir = 0;
}
void DirNeg()
{
   dir = -1;
}

kf2qd

#11
Jan 08, 2012, 02:33 am Last Edit: Jan 08, 2012, 02:37 am by kf2qd Reason: 1
I went looking for the necesary pieces to program the ATtiny2313 with the Arduino GUI and found the arduino-tiny-0100-0010 library (http://code.google.com/p/arduino-tiny/) and select downloads near the top. You copy the libraries into the Hardware directory of the Arduino-1.0 install and it adds a number of the ATtiny chips. You then program them using the Arduino as ISP setting. I am gong to order some pieces parts and see what I can do with this code.

Here is the readme file that comes with the package -
----------------------------------------------------------------------------------------------------------
Arduino-Tiny is an open source set of ATtiny "cores" for the Arduino platform.

The Arduino platform currently supports Atmel ATmega processors. There is a need
for the Arduino platform to work with physically smaller DIP package processors.
The intent of this project is fulfill that need. Specifically, our goal is to
provide a core that enables Arduino users to work with the ATtiny 84 (44/24),
ATtiny 85 (45/25), and ATtiny 2313 processors.

For more information about Arduino, see the website at: http://www.arduino.cc/


INSTALLATION

First ensure the Arduino software is correctly installed.

Next...

* Ensure the Arduino IDE is NOT running.

* Download the Arduino-Tiny archive (ZIP-file).

* Locate the Arduino Sketch folder.  This is the folder where the Arduino IDE
 stores Sketches.

* Ensure the "hardware" folder exists under the Arduino Sketch folder.  For
 example, if the Arduino Sketch folder is...

     C:\Projects\Arduino\

 Ensure this folder exists...

     C:\Projects\Arduino\hardware\
     
* Extract the contents of the archive into the "hardware" folder.  For example,
 if the Arduino Sketch folder is...

     C:\Projects\Arduino

 After extracting, the following two files should exist...

     C:\Projects\Arduino\hardware\tiny\boards.txt
     C:\Projects\Arduino\hardware\tiny\bootloaders\attiny84\empty.hex

 And the following folder should contain the Arduino-Tiny core...

     C:\Projects\Arduino\hardware\tiny\cores\tiny\

* Open the "boards.txt" file and change both of the "upload.using" entries to
 the appropriate value for your setup.  Following from the examples above, the
 file would be here...

     C:\Projects\Arduino\hardware\tiny\boards.txt

* Start the Arduino IDE and ensure there are two new boards listed under the
 [Tools] [Board] menu...

     "ATtiny84 @ 8 MHz"
     "ATtiny84 @ 1 MHz"

You are now ready to use Arduino-Tiny!


CREDITS

Arduino is an open source project, supported by many.

The Arduino team is composed of Massimo Banzi, David Cuartielles, Tom Igoe,
Gianluca Martino, and David A. Mellis.

Arduino uses the GNU avr-gcc toolchain, avrdude, avr-libc, and code from
Processing and Wiring.

Arduino-Tiny is based on work by David A. Mellis, René Bohne, R. Wiersma,
Alessandro Saporetti, and Brian Cook.

--------------------------------------------------------------------------------------------

kf2qd

#12
Jan 09, 2012, 07:33 pm Last Edit: Jan 15, 2012, 06:22 pm by kf2qd Reason: 1
I previously had tried to have a single interrupt do 2 things. Didn't work, then I looked at how I had been processing the
Direction interrupt and it hit me - I was going to get either a 1 or a zero from input 3, and I needed a 0 or -1 SO -
 dir = digitalRead(3) would give me 0 or 1, and dir = -digitalRead(3) with minimal effort would give me 0 or -1.

I am getting ready to order a batch of components so, in a week or so, I should have a ATtiny2313 programming
board built to plug into my Arduino board for programming, along with a few other components to play with.

justone

Awhile back I did about the same thing with a 2313. I drove four TIP120's with the four pwm outputs but on the 16bit timer I drove that in 8 bit mode so it was only a matter of building a 4 wide 8bit table for the compare registers. Did it with a tiny24 also (same timer setup).

Pretty simple to get smaller steps - I only did a 1/4 step table. In essence it was just a sine table.

kf2qd

Less than 48 hours and I should have some chips in my hands...

Thinking of direct port output to speed up the output to the driver transistors. Something to study...

Go Up