Sie sind auf Seite 1von 4

Techno: Easy Driver With Arduino

View this page in: English


2

Pgina Principal

More

http://xavierstechno.blogspot.com/2012/02/easy-d...

Translate

Turn off for: Catalan

Options

Next Blog

Create Blog

Sign In

Dupla

Feb 22, 2012

Cercar en aquest bloc


Search

Easy Driver With Arduino


Etiquetes: Arduino, CNC, Easy Driver, EasyDriver, Stepper, Stepper Speed

Etiquetes

Part I
(Maximum Stepper Speed)
Go to Part II (Adjust max Stepper Current)
Go to Part III (Sleep an Enable)

3D

Arduino
CNC
Click Here to see and download the design of a PCB implementing this circuit.

Easy

Driver
Fotografia

Links
Processing Programaci

Software
Stepper

Arxiu del bloc


2012 (7)
October (1)
September (3)
June (1)
February (2)
Easy Driver With Arduino
Trheading a function with
parameters in Processing...
2011 (15)
2010 (45)

An important thing to knwo about your stepper, is the maximum speed at witch it can be driven.
To know this, you can follow this LINK;
you need to knwo the specs of your stepper.
For my stepper:
Voltage:
Inductance:
Steps per revolution:
Current:

1 of 4

12v
46+-20% mH
Step Angle = 1.8
0.33 A

then i take 50
360 / 1.8 = 200 Steps/rev
i take 135 mA because with easy
driver you can adjust the maximun current
with the potenciometer
(i will explain this in a future post)

06/23/2015 08:05 PM

Techno: Easy Driver With Arduino

http://xavierstechno.blogspot.com/2012/02/easy-d...

T = 50 * 0.135 * 2 / 12 = 1.125 ms for a single Step


The default configuration of EasyDriver is eighth stepping then:
T = 1.125 / 8 = 0.140 ms = 140 us for a single Step
given this we take a prescaler of 128 for the Timer2 (see coments in the code)
128 / 16000000 = 0.000008 s-1 = 8 us-1

( the frequency of the processor in the


Arduino Uno is 16 MHz)

Timer2 actulizes its counter every 8 us then, 140 / 8 = 17.5


then we have to program the counter for the Timer2 to 18 ( 18 = ceil(17.5) ), because of that we have a success of Timer2 every 18 * 8us = 144 us
and the speed for our stepper will be: 144 us * 1600 Steps/Revolution = 0.2304 s/Revolution
that is 1 / 0.2304 = 4.34 Revolutions / s , wich is an aproximation to the real speed, because there is an extra delay between steps introduced by the code itself ( maybe 20 us extra delay ).

To see this working copy the following code to Arduino IDE, set the proper value for this variables
microSteping
stepsPerRev
l
v
iMax
and run it.
This program also implements acceleration-desacceleration. You can change the amount of acceleration, changing the value of 'accelDuring' variable ( for example it accelerates during 10 steps the run at constant speed
and finaly it desaccelerates during 10 steps ).
If you don't want acceleration set it to 0 ( accepted values are 0 - 255 ).

//http://www.daycounter.com/Calculators/Stepper-Motor-Calculator.phtml
//Rev/sec = V/(L*2*Imax)/(steps/rev) (Imax en A, L en mili Herns) p.e. 12/(46*2*0.33)/200
//T = L*Imax*2/V (T miliSegons/step)
#define DIR_PIN 7
#define STEP_PIN 6
#define sbi(sfr,bit) ( sfr |=
_BV(bit) )
#define cbi(sfr,bit) ( sfr &= ~(_BV(bit)) )
// MS1 MS2 Resolution
// L
L
00 Full step (2 phase)
// H
L
10 Half step
// L
H
01 Quarter step
// H
H
11 Eighth step
//
// per defecte a la easy driver MS1 = MS2 = HIGH

// a l'antiga manera. cbi() i sbi() son funcions obsoletes

float microStepping = 8;
long stepsPerRev = 200;
float l = 50;
float v = 12;
float iMax = 0.135;

//
//
//
//
//
//

Valor establert a la easyDriver ( MS1, MS2 )


caracterstica del motor
= 46 +- 20% (el pitjor dels casos es 55.2) caracterstica del motor
caracterstica del motor
mesurat amb el tester (cal dividir el resultat per 2 (hi ha 2 bobines))
amb la EasyDriver podem controlar iMax abm el potencimetre

float ocr2a;
int ocr2aIni;

// valor de OCR2A ( que depn de la velocitat mxima del Stepper )


// valor inicial de OCR2A donada l'acceleraci

int accelDuring = 10;

// Accelera i desaccelera durant 10 Steps

int downCounter = accelDuring;


int upCounter = accelDuring;
int accelDelta;

//
//
//
//

long stepsLeft = 0;
boolean running = false;

// nombre d'Steps que manque per acabar


// motor is running?

void setup() {
unsigned int usDelay;

// temps d'espera entre Steps en us

el nombre d'Steps que falten fins acabar la desacceleraci


el nombre d'Steps que falten fins acabar l'acceleraci
valor en que varia OCR2A durant l'acceleraci
( p.e. si ha de pasar de 255 a 19 en 10 steps decremeta de 23 en 23 i comea a 249 )

Serial.begin(115200);
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
usDelay = l * 2000 * iMax / v / microStepping;
ocr2a = ceil((float)usDelay / 8.0);

// temps d'espera entre steps en microsegons ( T= L*Imax*2/V (T miliSegons/step) )


// l'enter mes proper donat l'interval del Timer2 ( 8 us )

Serial.println(ocr2a);
if(accelDuring > 0){
accelDelta = (255 - int(ocr2a) ) / accelDuring;

// OCR2A pasar del enter mes proper a 255 fins a ocr2a


// el valor que hem calculat per la velocitat mxima

Serial.println(accelDelta);
if(accelDelta<=0){
if(ocr2a < 255){
accelDelta =1;
ocr2aIni = 255;
accelDuring = 255 - ocr2a;
}else{
accelDelta = 0;
accelDuring = 0;
ocr2aIni = ocr2a;
}
}else
ocr2aIni = ocr2a + accelDelta * accelDuring;
}else
ocr2aIni = ocr2a;

// la durada de l'acceleraci no pot ser tan gran com esperem

// durada mxima de l'acceleraci permesa


// ocr2a = 255, no hi pot haver acceleraci

// acceleraci segons la definici


// calcula el OCR2A inicial donada l'acceleraci
// no hi ha acceleraci

Serial.println(ocr2aIni);
setTimer2(ocr2aIni);
Serial.print("Inter Step Delay: ");
Serial.print(usDelay);
Serial.println(" us");
Serial.print("Max Speed: ");
Serial.print( 60000000.0 / ((float)stepsPerRev * microStepping * (usDelay)) );
Serial.println(" RPM");

2 of 4

06/23/2015 08:05 PM

Techno: Easy Driver With Arduino

http://xavierstechno.blogspot.com/2012/02/easy-d...

Serial.print("Max Speed Real: ");


Serial.print( 60000000.0 / ((float)stepsPerRev * microStepping * ((int( ceil( (float)usDelay / 8.0 ) ))*8)) );
}////

long nVoltes = 1;
long nSteps = nVoltes * stepsPerRev * microStepping;

void loop(){
if(!running){
delay(1000);
driveStepper(nSteps);
nSteps = -nSteps;
}
}////

void driveStepper(long lnSteps){


int dir = (lnSteps > 0)? HIGH:LOW;
digitalWrite(DIR_PIN,dir);
lnSteps = abs(lnSteps);
OCR2A = ocr2aIni;
upCounter = accelDuring;
downCounter = accelDuring;
running = true;
stepsLeft = lnSteps;
}////

// reinicialitza el contador (permet acceleraci)

void setTimer2(int lusDelay) {


//http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
// The ATmega328P has three timers known as Timer 0, Timer 1, and Timer 2
// Each timer has two output compare registers
// Each of the timers has a prescaler that generates the timer clock by dividing
//
the system clock by a prescale factor such as 1, 8, 64, 256, or 1024
//
Note that Timer 2 has a different set of prescale values from the other timers
// The Arduino has a system clock of 16MHz and the timer clock frequency will be
//
the system clock frequency divided by the prescale factor
// The timers can also generate interrupts on overflow and/or match against either output compare register
//
// TCCRnA and TCCRnB. The Timer/Counter Control Registers hold the main control bits
//
for the timer. (Note that TCCRnA and TCCRnB do not correspond to the outputs A and B.)
// TCCRnA and TCCRnB hold several groups of bits:
//
Waveform Generation Mode bits (WGM): these control the overall mode of the timer.
//
(These bits are split between TCCRnA and TCCRnB.)
//
Clock Select bits (CS): these control the clock prescaler
//
Compare Match Output A Mode bits (COMnA): these enable/disable/invert output A
//
Compare Match Output B Mode bits (COMnB): these enable/disable/invert output B
//
// OCRnA and OCRnB. The Output Compare Registers set the levels at which outputs A and B will be affected
//
// TIMSK2 Timer2 Interrupt Mask Register
//
OCIE2B: Timer2 Output Compare Match B Interrupt Enable
//
OCIE2A: Timer2 Output Compare Match A Interrupt Enable
//
TOIE2: Timer2 Overflow Interrupt Enable
//
// Timer 1 is a 16-bit timer and has additional modes. Timer 2 has different prescaler values
//
// The Arduino uses Timer 0 internally for the millis() and delay() functions
// OC0A pin 6
OC0B pin 5
// OC1A pin 9
OC1B pin 10
// OC2A pin 11
OC2B pin 3
cli();

// plana 10. Bit 7 Clear interrupts

cbi(TCCR2A, COM2A0 );
cbi(TCCR2A, COM2A1 );

// plana 158. Table 17-2. Normal port operation, OC0A disconnected.


// 00 deconecta el pin A del timer2

cbi(TCCR2A, WGM20
sbi(TCCR2A, WGM21
cbi(TCCR2B, WGM22

);
);
);

// TCCR2A Regitre A de control del timer 2


// plana 160 i 149. Clear Timer on Compare
// WGM2 = 010 ==> mode of operation Clear Timer on Compare (CTC)
// The counter value TCNT2 increases until TCNT2 == OCR2A,
// and then counter (TCNT2) is cleared
// repeteix el cilce 0 --> valor ( valor clocks )

sbi(TCCR2B, CS22
cbi(TCCR2B, CS21
sbi(TCCR2B, CS20

);
);
);

// TCCR2B Regitre B de control del timer 2


// Plana 162
// CS2 = 101 prescaler = 128 ==> 128/16.000.000 = 0.000008 s-1 = 8us-1
// mxim temps que es pot contar = 8 * 255 = 2040 us

sbi(TIMSK2, OCIE2A

);

cbi(ASSR, AS2);

// Timer2 Output Compare Match A Interrupt Enable. plana 163


// AS2
//
//
//
//

= 0 clocked from the I/O clock


plana 164. Asynchronous Status Register
When AS2 is written to zero, Timer/Counter2 is clocked from the I/O clock, clkI/O.
When AS2 is written to one, Timer/Counter2 is clocked from a crystal Oscillator
connected to the Timer Oscillator 1 (TOSC1) pin.

OCR2A = lusDelay;

//

TCNT2 = 0;

// reset Timer2 counter

sei();
}////

void stopTimer2() {
cbi(TIMSK2, OCIE2A
}////

si p.e. OCR2A = 21 --> 21*0.000008 = 168us-1

. cridem la funcio un cop cada 168 us. plana 162

// Enable Interrupts

);

ISR(TIMER2_COMPA_vect) {

// Timer2 Output Compare Match A Interrupt Disable. plana 163

// Timer2 Output Compare Match A Interrupt


// definici dels vectors a Arduino\hardware\tools\avr\avr\include\iom328p.h
// definitions for ATmega328P

if(stepsLeft > 0){

3 of 4

06/23/2015 08:05 PM

Techno: Easy Driver With Arduino

downCounter--;
OCR2A += accelDelta;
}
else if(upCounter >0){
upCounter--;
OCR2A -= accelDelta;
}
digitalWrite(STEP_PIN, HIGH);
digitalWrite(STEP_PIN, LOW);

stepsLeft--;
}
else
running = false;
}////

http://xavierstechno.blogspot.com/2012/02/easy-d...

// incrementa el temps entre Steps en CS22:0 us (el proper Step es produir 8 us mes tard)
// ha d'accelerar
// decrementa el temps entre Steps en CS22:0 us (el proper Step es produir 8 us abans)
//
//
//
//
//
//
//
//
//
//

envia el pols a la EasyDriver per avanar 1 Step


A low-to-high transition on the STEP input sequences the translator
and advances the motor one increment.
Minimum STEP Pulse Width 1.0 s (plana 7 de 'A3967.pdf')
la intruccio NOP triga 1 Clock ( 0,0625 us = 62.5 ns ) per tant
la instrucci digitalWrite ha de trigar ms de 16 Clocks
mirar el codi a 'wiring_digital.c'
segons els forums 'digitalWrite()' sembla trigar entre 6 i 9 us
depenent de si el port es PWM o no
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230286016

// para el motor

Links to this post


Create a Link

Newer Post

Home

Older Post

Powered by Blogger.

4 of 4

06/23/2015 08:05 PM

Das könnte Ihnen auch gefallen