Hello Members,
I hope this is the correct forum for this question.
I found the code sample below using timer2 somewhere in the Arduino forums.
I am using an Arduino Uno and a DVR8825 stepper driver chip (from Pololu).
The code below does what it describes - the motor speeds up, slows down, etc.
I would like to use the same concept (setting bits in registers, etc) to do the following:
press button, start the motor (at some selected speed) - motor moves slider until slider hits limit switch.
Motor either reverses, runs for 3 steps (in microstep mode - m0 = 1, m1 =0, m2 = 1) and stops, ready to run in
opposite direction. OR motor stops, reverse direction,starts and runs for 3 steps (in microstep mode - m0 = 1, m1 =0, m2 = 1) and stops, ready to run in opposite direction, runs in opposite direction, hits limit switch, etc.
The motor seems to take the direction change "on the fly" without stopping ok. I have implented the above functionality using the Adafruit MotorShield V2, but would like to use the DVR8825 since it has higer current capability.
I have tried a variation of the code below - moving the OCR2A,B code out of the loop function, and into a
motor run function, but have not figured out how to count steps when set in the 1/32 step mode (slowest for the DVR8825, dependent on the PWM freq, etc.)
Any tips will be helpful. I can attach my bad code if desired.
Thanks,
ewholz
CODE:
/*
Using Timer 2. 1024 prescale, F_CPU/1024 divisor, 50% duty cycle:
[calculated]
base freq OCR2A OCR2B pulse width(ms) pin3 freq(Hz) RPM (@200 steps/rev)
61 255 127 8 61 18
120 129 64 4 120 36
240 64 32 2 240 72
480 32 15 1 489 144
--> 960 15 7 0.5 977 288 <--
| 1920 7 3 0.26 1954 576 |
| |
--> 960 seems to be about the limit of the 28BYG301 <----------
*/
// As currently configured, LOW on the direction pin is CCW.
// HIGH reverses to CW. Default to LOW for start.
int main( void )
{
int direction = 0; // 0 is LOW, 1 is HIGH.
// Setup the outputs: pin 3 for STEP, pin 4 for DIR. Per DVR8825 pinout.
DDRD |= (1 << 3); // Enable pin 3 for OUTPUT to step the DRV8825
DDRD |= (1 << 4); // Enable pin 4 for OUTPUT for step direction.
// Setup Timer2: fast PWM, clear OC2B on compare, 1024 prescale.
TCCR2A |= (1 << WGM20) | (1 << WGM21) | (1 << COM2B1 );
TCCR2B |= (1 << WGM22) | (1 << CS22 ) | (1 << CS21) | (1<< CS20);
while(1)
{
// Speed up.
for( int freq = 61; freq < 961; freq += 10 )
{
OCR2A = ((F_CPU / 1024) / freq) - 1;
OCR2B = ((OCR2A + 1) / 2) - 1;
cheap_delay( 100000 );
}
// Slow down.
for( int freq = 960; freq > 60; freq -= 10 )
{
OCR2A = ((F_CPU / 1024) / freq) - 1;
OCR2B = ((OCR2A + 1) / 2) - 1;
cheap_delay( 100000 );
}
// Reverse direction.
if( direction ) // Direction is HIGH (CW)
{
PORTD &= ~(1 << 4); // Set DIR pin LOW.
direction = 0; // Record for the next pass thru the test loop.
}
else // Direction is LOW (CCW)
{
PORTD |= (1 << 4 ); // Set DIR pin HIGH.
direction = 1; // Record for the next pass thru the test loop.
}
}
}
void cheap_delay( volatile unsigned long count )
{
while( count > 0 ) count--;
}