Arduino Forum

Using Arduino => Motors, Mechanics, and Power => Topic started by: kf2qd on Dec 27, 2011, 11:58 pm

Title: Arduino chip as Stepper Controller
Post by: kf2qd on Dec 27, 2011, 11:58 pm
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
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Dec 29, 2011, 11:40 pm
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;
 }  
}
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Dec 30, 2011, 03:26 am
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;
 }
}
Title: Re: Arduino chip as Stepper Controller
Post by: gharryh on Dec 30, 2011, 10:02 am
And how do you hook it up to a computer? I dont see any IO going on.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Dec 30, 2011, 09:20 pm
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.
Title: Re: Arduino chip as Stepper Controller
Post by: gharryh on Dec 31, 2011, 12:36 pm
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?
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 01, 2012, 02:39 am
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.
Title: Re: Arduino chip as Stepper Controller
Post by: gharryh on Jan 01, 2012, 11:35 am
So you have ONLY 4 transistors. In all my circuitry i am using the example given here:
http://vimeo.com/6972843 (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.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 02, 2012, 06:09 am
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...
Title: Re: Arduino chip as Stepper Controller
Post by: celem on Jan 05, 2012, 08:38 pm
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.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 08, 2012, 02:27 am
******************************************************************************************************************************************************
****** 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;
}
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 08, 2012, 02:33 am
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.

--------------------------------------------------------------------------------------------
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 09, 2012, 07:33 pm
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.
Title: Re: Arduino chip as Stepper Controller
Post by: justone on Jan 09, 2012, 08:45 pm
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.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 15, 2012, 04:28 am
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...
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 15, 2012, 06:19 pm
Okay - Now I've done it :D...

Got looking for Direct Port I/O and found a part of the Arduino documentation that doesn't seem to have a direct link.
Here's the link - http://arduino.cc/en/Reference/PortManipulation (http://arduino.cc/en/Reference/PortManipulation)
It explains some of the problems and some of the uses. In a general Arduino project you might not want to use this approach as there are a few pitfalls that the Arduino IDE hides from you, and that is not always a bad thing. As i intend to use this in a dedicated chip it should cause me no problems.

Port B on the Arduino/ATMege328 is pins 8, 9, 10, 11, 12, 13, with the 2 remaining pins used by the crystal/resonator
DDRB is the Data Direction Register. Assigning 1 to a bit makes it an output, 0 makes it an input.
PORTB is the predefined variable that lets you read or write port B.
PORTB = B0001 turns on pin 8 and turns off pin 9, 10 & 11.

I also used pre-initialized arrays to set up the step patterns.

Down to 1232 bytes.

Here's the last version of the code -
Code: [Select]

/*
Step & Direction Stepper Driver
Pins 8, 9, 10, 11 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.
*/
// the following 3 arrays contain the bit patterns to drive the transistors to in turn drive each of the phases of the stepper
int patSimple[] = {B0011,B0010, B0100, B1000, B0001, B0010, B0100, B1000};
int patWave[] = {B0011, B0110, B1100, B1001, B0011, B0110, B1100, B1001};
int patHalf[] = {B0001, B0011, B0010, B0110, B0100, B1100, B1000, B1001};
int pinDir = 3;
volatile int ctr;
volatile int dir;
void setup()
{
  DDRB = B1111 ;  // this enables Port B Bits 0 - 3, Arduino I/O 8, 9, 10, 11 as outputs
  pinMode(pinDir, INPUT);
  ctr=0;
  dir = 0;
  attachInterrupt(0, Step, RISING);  // Depending on the application FALLING might be a better choice.
  attachInterrupt(1, Direction, CHANGE);
}

void loop()
{
// Nothing to see here... 
}

void Step()
{
  if (dir)
  {
    ctr-- ;
  }
  else
  {
    ctr++ ;
  }
  ctr = ctr & 7;
// 2 of the following 3 lines must be commented.
//  PORTB = patsimple[ctr];  // Simple Stepping
//  PORTB = patWave[ctr];    // Wave Stepping
     PORTB = patHalf[ctr];      // Half Stepping


void Direction()
{
    dir = -digitalRead(pinDir);    // Direction is 0 (zero) or -1 (minus one)
}

Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 19, 2012, 06:24 pm
Got my chips and parts on Monday and Tuesday night I put together a board for programming ATMega328 and ATTiny2313 chips. I didn't order any 120Ohm resistors so I had to wait til yesterday to test it out.

Used AVRDude to program the chips and had to add a section to the avrdude.conf file for the ATMega328 as it only had the ATMEga328P. I could have added the -F argument to the command string, but it was just as easy to add a section for the 328. Copied the whole 328P section and made 3 changes - in the 2 locations where 328P appeared I erased the P and I changed the System Descriptor bytes (avrdude reports what it finds if it doesn't agree) from 1E 95 0F to 1E 95 14 and everything worked. Took the chip out of the programming socket and swapped it for the chip in my Arduino board and loaded it with Blink.

I also put one of my ATTiny2313 chips in the and used the Arduino IDE to load the code to the 2313 and it seems to have loaded just fine. Have to hook up a circuit and test out the chip. Will probably be Sunday night before I get the chance as I have too much in my schedule between now and then.

I will post a picture of my programmer board and a schematic the first of the week.
Title: Re: Arduino chip as Stepper Controller
Post by: BetterSense on Jan 19, 2012, 09:58 pm
Just so you know, you are on the right track. I drive a unipolar stepper using 1/16 step microstepping driving 4 TIP110s's from PORTB and C of my ATMEGA168 using 8-bit fast PWM. You can either store the sine wave values in an array or in a table/switch statement.

IMPORTANT: this works for me because 1. I use ~5kHz PWM, not the standard arduino 500Hz PWM and 2. I only need to rotate slowly.

To microstep using PWM you have to use a PWM frequency several times higher than the fastest microstepping rate you anticipate. This means that at the standard Arduino PWM rate of ~500Hz you will only be able to meaningfully microstep at about 100Hz--even that is only 5 PWM cycles per microstep--which at full step for a 1.8* motor is only 30RPM and for 1/8 microstepping (1600steps/rev) you will only be able to meaningfully microstep at 1/4RPM. Which might be fine if you are making a rotisserie; I only need 10RPM myself.

To be able to output small microsteps at high microstepping rates, you have to crank up the PWM frequency; this is basic sampling theory.  There is no problem in principle; commercial microstepping drivers run their PWM at about 30kHz, but I assume we would run into trouble with our discrete TIPs and have to write very tight code (maybe assembly) to use PWM rates that high. I don't know, but I do know that my 5kHz is going fine.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 21, 2012, 02:47 am
Well it works. (almost didn't, hooked the chip up upside down and generated a little heat...) plugged the chip in and hooked up to my led drivers and it works.

Got a few things to take care of before I can play with it too much so ... The first of the week i should have a stepper driver working.

So - It is really rather easy to hook up an ATTiny2313 to an Arduino programmed as an ISP and load the code into the 2313. I did have to use version 0.22 of the Arduino Environment to have teh ArduinoISP work properly, but I stumbled across that little piece of info somewhere along the way.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 23, 2012, 06:48 pm
Worked on the board for my first driver. Got it mostly soldered up and got to thinking that I would have to change the bleeder resistor as 56Ohms wold draw too much current from the 328, so I will have to pull them and get some resistors in the 120 to 220 range. Oh well, minor setback.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jan 31, 2012, 09:24 pm
Got to playing with assembly language - took my code size from 1200 bytes to 86 bytes.

Out of necesity, Arduino adds a lot of overhead to interrupt routines. Saves all the registers and such, but it would take a lot more power to analyze the code and reduce that overhead. Writing in assembler means I had to do the optimizing and I am responsible for what can go wrong...

I am using AVRStudio 4 to write and test the code (has a simulator built in)(even has a disassembler that will load the hex files and list them )
I recommend AVR Studio 4 over 5 as 5 is just to S-L-O-W...

Here's what the code looks like in assembler.
Code: [Select]

.NoList
.INCLUDE "tn2313Adef.inc" ; Header for ATTINY2313A
.List
; ============================================
;   R E G I S T E R   D E F I N I T I O N S
; ============================================
.DEF Conf = R16 ; Multipurpose register
.DEF StepCt = R17
.DEF StepMask = R18
.DEF Direction = R19
.DEF PortBHold = R20
.DEF PortDHold = R21
.DEF PortDMask = R22
.DEF SeqBase = R23
; ============================================
;   R E S E T   A N D   I N T   V E C T O R S
; ============================================
.CSEG
.ORG $0000
rjmp Main ; Reset vector
rjmp Step ; Int vector 1
rjmp Dir ; Int vector 2
reti ; Int vector 3
reti ; Int vector 4
reti ; Int vector 5
reti ; Int vector 6
reti ; Int vector 7
; ============================================
;     I N T E R R U P T   S E R V I C E S
; ============================================
Step: add StepCt,Direction
     and StepCt,StepMask
     mov ZL,SeqBase
 add ZL,StepCt
 Lpm PortBHold,Z
 out PORTB,PortBHold
 reti
Dir:  ldi PortDMask,8
     in  PortDHold,PIND
     and PortDHold,PortDMask
     breq SinNeg
 ldi Direction ,1
     rjmp DirEx
SinNeg:  ldi Direction ,-1
DirEx:reti
; ============================================
;     M A I N    P R O G R A M    I N I T
; ============================================
Main:
; Init stack
ldi Conf, LOW(RAMEND) ; Init LSB stack
out SPL,Conf
; Init Port A
ldi Conf,0 ; Direction Port A
out DDRA,Conf
; Init Port B
ldi Conf,(1<<DDB0)|(1<<DDB1)|(1<<DDB2)|(1<<DDB3) ; Direction Port B
out DDRB,Conf
; [Add all other init routines here]
ldi Conf,(1<<SE)|(0<<ISC00)|(1<<ISC01)|(1<<ISC10)|(0<<ISC11) ; enable sleep
out MCUCR,Conf
ldi StepCt,0
ldi StepMask,7
ldi Direction,1
ldi SeqBase, StepSeq
add SeqBase,SeqBase
sei
; ============================================
;         P R O G R A M    L O O P
; ============================================
Loop:
rjmp loop ; go back to loop

StepSeq: .DB 1,3,2,6,4,12,8,9,0,0
; End of source code

Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Feb 07, 2012, 12:21 am
Finally can say I have an ATMel chip - the ATtiny2313 functioning as a stepper driver.
I got it working in Arduino, the assembler version still has some strange behavious (and the assembler version of the code is hareder to troubleshoot in hardware. In the Simulator it works just fine, but in hardware.....

Here's the Arduino version.
By my count it will run in excess of 140RPM  running in Half Step mode when driven by a simple Arduino program.

Code: [Select]
/*
Step & Direction Stepper Driver
Pins 8, 9, 10, 11 are tied to transistors
for each of the motor phases.
Pins 2 is used as interruptfor the steps
and 3 is the Direction.
*/
// the following 3 arrays contain the bit patterns to drive the transistors
// to in turn drive each of the phases of the stepper
int patSimple[] = {
  B0011,B0010, B0100, B1000, B0001, B0010, B0100, B1000};
int patWave[]   = {
  B0011, B0110, B1100, B1001, B0011, B0110, B1100, B1001};
int patHalf[]   = {
  B0001, B0011, B0010, B0110, B0100, B1100, B1000, B1001};
int pinDir = 5;
volatile int ctr;
volatile int dir;

void setup()
{
  DDRB = B1111 ;  // this enables Port B Bits 0 - 3, Arduino I/O 8, 9, 10, 11 as outputs
  pinMode(pinDir, INPUT);
  ctr=0;
  dir = 0;
  attachInterrupt(0, Step, FALLING);  // Depending on the application FALLING might be a better choice.

}

void loop()
{
  // Nothing to see here... 
}

void Step()
{
  if (digitalRead(5))
  {
    ctr++ ;
  }
  else
  {
    ctr-- ;
  }
  ctr = ctr & 7;
  // 2 of the following 3 lines must be commented.
  // PORTB = patsimple[ctr];  // Simple Stepping
  // PORTB = patWave[ctr];    // Wave Stepping
  PORTB = patHalf[ctr];      // Half Stepping



And I was testing it with code that looks like this in my Arduino-
Code: [Select]
int steps;

void setup() {               
  // initialize the digital pin as an output.
  // Pin 13 has an LED connected on most Arduino boards:
  pinMode(2, OUTPUT);     
  pinMode(3, OUTPUT);   
  digitalWrite(3,HIGH); 
}

void loop() {
  for (steps=0;steps<400;steps++)
  {
    digitalWrite(2, HIGH);   // set the LED on
    digitalWrite(2, LOW);    // set the LED off
    delay(1);              // wait for a second
  }
}


Still want to crack the assembly code...
Title: Re: Arduino chip as Stepper Controller
Post by: sloppyjava on Feb 07, 2012, 03:00 am
Hi, I am experimenting with the code you posted ( Reply #15 on: January 15, 2012, 05:19:57 PM ) with 4 IRF530's, an Arduino Uno, a small unipolar stepper and solder-less board and It works really well with EMC2 linux.  My goal is to drive a homebrew CNC router table with the above components.  I have very little (NO) experience with port manipulation and am somewhat apprehensive about adding another axis to the code, as I recall reading that I could bugger up the TX RX ports?  does the UNO have enough ports available to control 3 axes? I would still be happy with 2!  In any case, great work on this elegant code so far!
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Feb 07, 2012, 11:09 am
I am using the ATtiny2313 for this application. It has a few extra pins, It turns out I need 1 interrupt pin, 1 input and 4 outputs. I would also like to add 1 more input as an enable  and possibly a Ready output. The problem with trying to run more than one stepper in this application is the Interrupt inputs. Because of priority of interrupts the second interrupt would get missed if it occurred at the time as the first.

Look into some ATtiny2313 chips and use the Arduino as the programmer. That circuit is abut as inexpensive and simple as an Arduino circuit can be. If yuwant more info to use that approach I can point you to the few pieces you need to put together to do that.
Title: Re: Arduino chip as Stepper Controller
Post by: sloppyjava on Feb 07, 2012, 04:29 pm
That would be great.  I was wondering about the ability to program with the arduino and swap the IC out to a PCB, so that sounds like it could work for me.  Any resources you can point me to would be greatly appreciated.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Feb 07, 2012, 08:52 pm
To program a chip I use Arduino-0.22 to load the ArduinoISP sketch on my Arduino Uno board. I made a small board that has 2 sockets, a 20 pin that could be used to program 20 and 8 pin chips and a 28 pin socket that I use to program 328's (like the Uno).  Search for Arduino as ISP as there is a lot of info out there that exlains the process and the wiring. My little board has 6 wires between the boards to program the chip and a 120 Ohm resistor between the Reset and +5 on the Arduino Uno. To program an Arduino sketch using the ArduinoISP there is a selection on the ArduinoIDE File menu to write the sketch usin Arduino as ISP.


I use the Arduino-0.22 IDE as there was a change in something in Arduino-1.0 and the ArduinoISP only works at 9600 baud instead of 19200 which causes a problem.

Here's a picture (poor) of my ISP board to use with the Uno.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Feb 15, 2012, 04:00 am
I got it working -

Figured out what was lacking in my assembly code and now it works.

Code: [Select]

.NoList
.INCLUDE "tn2313Adef.inc" ; Header for ATTINY2313A
.List
; ============================================
;   R E G I S T E R   D E F I N I T I O N S
; ============================================
.DEF Conf = R16 ; Multipurpose register
.DEF StepCt = R17
.DEF StepMask = R18
.DEF Direction = R19
.DEF PortBHold = R20
.DEF PortDHold = R21
.DEF PortDMask8 = R22
.DEF SeqBase = R24
; ============================================
;       S R A M   D E F I N I T I O N S
; ============================================
.DSEG
.ORG  0X0060
; ============================================
;   R E S E T   A N D   I N T   V E C T O R S
; ============================================
.CSEG
.ORG $0000
rjmp Main ; Reset vector
rjmp Step ; Int vector 1
reti ; Int vector 2
reti ; Int vector 3
reti ; Int vector 4
reti ; Int vector 5
reti ; Int vector 6
reti ; Int vector 7
; ============================================
;     I N T E R R U P T   S E R V I C E S
; ============================================
Step:   in  PortDHold,PIND
; look at only PD#, the Direction input
        and PortDHold,PortDMask8
; if PD3 High, Add Direct to StepCt, if PD3 Low Subtract Direction
        breq SinNeg
        add StepCt,Direction
        rjmp Next
SinNeg: sub StepCt,Direction
; limit StepCt to range from 0 to 7 (-1 becomes 7)
Next:   and StepCt,StepMask
; use Z as a pointer to the StepSequence table
        mov ZL,SeqBase
; StepCt is teh offset into the table
add ZL,StepCt
; transfer the next bit pattern from ProgMem to PortBHold, R20
Lpm PortBHold,Z
out PortB,PortBHold
reti
; ============================================
;     M A I N    P R O G R A M    I N I T
; ============================================
Main:
; Init stack
ldi Conf, LOW(RAMEND) ; Init LSB stack
out SPL,Conf
; Init Port A
ldi Conf,0 ; Direction Port A
out DDRA,Conf
; Init Port B
ldi Conf,(1<<DDB0)|(1<<DDB1)|(1<<DDB2)|(1<<DDB3) ; Direction Port B
out DDRB,Conf
; Set ISC00 to 0 and ISC01 to 1, Falling Edge INT0 Interrupt
ldi Conf,(0<<ISC00)|(1<<ISC01)
out MCUCR,Conf
; Set INTO , Bit 6 of GIMSK to Enable INT0
ldi Conf,(1<<int0)
out GIMSK, Conf
; Initialize StepCt, R17
ldi StepCt,0
; Initailize StepMask, R18
ldi StepMask,7
;Initialize Direction, R19
ldi Direction,1
; Initialize SeqBase to point to 8 bit address of StepSeq
ldi SeqBase, StepSeq
add SeqBase,SeqBase
; Initialize PortDMask8, R22, to mask only PD3 of port D
        ldi PortDMask8,8
        ldi ZH,0   
sei
; ============================================
;         P R O G R A M    L O O P
; ============================================
Loop:  rjmp loop ; go back to loop
; bit patterns for output to the Stepper Drive Bits.
StepSeq: .DB 1,3,2,6,4,12,8,9,0,0
; End of source code
Title: Re: Arduino chip as Stepper Controller
Post by: jsearles on Jun 28, 2012, 02:56 pm
This was one of the best reads on Arduino stepper logic thata I have seen.  You are to be commended and I thank you very much. 

It's a pity that it seemed to drop so abruptly,

Do you have any final specs on the speed of your assembly code version?

Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jun 28, 2012, 09:43 pm
Got into a few other projects so I have not paid much attention to it for a while. I was able to get hold of a Hardinge UM milling machine and that took some time to get cleaned and moved into my shop. I have a Harbor Freight Mini Mill that I want to convert to CNC along with a 10:1 gearbox that I want to use as an indexer on that mill. Living down here in South Texas my year is backwards from folks that live farther north. Here it get too hot to work in an un-airconditioned garage so most of my projects out there take place from September to May whereas when I lived up in Indiana the projects took place from April to October when it was warm enough to work out in the shop.

I have mounted 2 2313 on a perf board along with the 8 MOSFETs and actually had it running - ~140 rpm using my Arduino as the step generator. As that was written in the Arduino IDE I suspect that I can get quite a bit more speed using MACH3 or GRBL.

What's the timing for 12 instructions and an interrupt on an ATtiny running at 8Mhz? According to how I interpret the info from AVRStudio the interrupt shold process in ~2.25mSec.
Title: Re: Arduino chip as Stepper Controller
Post by: flop777 on Jul 01, 2012, 09:42 am

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?

yeah very interesting...
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Jul 02, 2012, 08:19 pm
I used the Arduino to test my idea and then migrated the code over to the ATtiny2313. A stepper driver takes the problem of controlling the motor away from your main processor - be it an Arduino or a PC running Mach3. The chip is programmed so it has 2 inputs - Step & Direction, and 4 outputs - Pahses 1 - 4. Those outputs drive 4 MOSFETs which are then connected to the 4 phases of the stepper. Very similar to some other stepper controllers that are available - the PIC Stepper is one that I chose to emulate. Instead of the PICStepper I have the AVRStepper...

And by using a stepper driver my Arduino can control 4 steppers instead of just 2. Or I can hook those steppers to my PC and control them using Mach3, or to some other device.
Title: Re: Arduino chip as Stepper Controller
Post by: sbright33 on Dec 07, 2012, 05:56 pm
4 is impressive!  With my code I can control 3 at once.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Dec 07, 2012, 07:28 pm
Distributed processing. And by using the 2313's for controllers they can be placed away from the main arduino meaning things can be mounted more conveniently.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Mar 18, 2013, 10:25 pm
Sort of a bump to the thread.

I have some perforated circuit board material coming - Vectorboard #169P44WEC1 which is copper clad on 1 side with .042 holes spaced every 0.1". Saves having to drill my sample boards. I have generated a board layout using AutoCAD and will be spending the next couple days drawing the resist pattern on the board and then etching it with Radio Shack Ferric Chloride etchant. Have spent that last couple weeks going over the design and that helped me spot an error in the schematic. I sort of had a schematic, but this was a project where the schematic followed the breadboard build and I found out I had drawn it  with the signals to the wrong pins... Oh well, slide them over and the schematic matches the working parts...

Salvaged some terminals and now I just have to get the materials in hand to try it out.
Title: Re: Arduino chip as Stepper Controller
Post by: patternp on Apr 01, 2013, 01:30 am
Is the Vectorboard #169P44WEC1 copper "all continuous," i.e. no precut pads on them?  It's really just a whole plane of copper with holes, and you can still etch on them?

How did it work out for you?

I'm looking for something similar, but there aren't many of these so when I read the product description, I'm not sure it's what I think it is.

Thanks!
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Apr 01, 2013, 06:32 pm

Is the Vectorboard #169P44WEC1 copper "all continuous," i.e. no precut pads on them?  It's really just a whole plane of copper with holes, and you can still etch on them?

How did it work out for you?

I'm looking for something similar, but there aren't many of these so when I read the product description, I'm not sure it's what I think it is.

Thanks!



This version of the board has copper on just 1 side. There is also a version that ends with C2 that has copper on both sides.

I have a couple pictures on my phone of the boards I made. I drew the resist pattern with a Sharpie and it worked well. I make 2 boards with a minimum of copper removed with the bulk of the board being a ground plane. The other 2 I removed any unneeded copper.  Both versions seem to work just fine. Will try to upload the pictures tonight.
Title: Re: Arduino chip as Stepper Controller
Post by: patternp on Apr 04, 2013, 07:53 pm
Thanks for info on C2 version of board.

Looking forward to seeing the photos, if you get a chance to post them :-)
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Apr 05, 2013, 04:11 am
Here's a top view of the assembled board.

The 5 pins across the top are, from right to left, Motor 1, Motor2, Motor Common, Motor 3, Motor 4.

The 7 down the side, from top to bottom, Motor+, Motor-, Logic+, Logic-, Logic Common, Direction, Step.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Apr 05, 2013, 04:21 am
This one doesn't zoom too well, but it shows the backside, one with minimal copper removed.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Apr 05, 2013, 04:26 am
Here are a couple boards I made that have minimal copper left.
Title: Re: Arduino chip as Stepper Controller
Post by: kf2qd on Apr 05, 2013, 04:34 am
Here's a couple of board layouts from the copper side. They don't zoom well either.