NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Basic Electronics » Stepper Motor Motor Speed Control

July 11, 2012
by Ralphxyz
Ralphxyz's Avatar

Again lets start a new thread dedicated (yeah right) to Stepper Motor Speed Control.

Continued on from my Stepper Motor Programing thread.

Ralph

July 11, 2012
by sask55
sask55's Avatar

Ralph

I don’t have a board set up so I cannot experiment with various delay times on a stepper. It seams to me you said what the range of delay times you have tried. What is the fastest motor speed (shortest delay time) that you have tried?

If you want to use delay times that are relatively short say one or two ms to get high motor speeds, then I think we should consider using the delay_us function, rather then the delay_ms function. If the 65535 microsecond delay does not produce a slow enough motor speed we could deal with that in the code. By using the microsecond delay we could achieve much better control of motor speed at the fast end of the range. My concern is that if you go from a 2ms delay to a 1 ms delay you would double the motor speed, for a 3ms delay to a 2ms delay will be a 50% increase. Those would be huge jumps in the motor speed the user would have very little fine control of the motor speed at the top end of the speed range. By using the us_delay the speed control could be customized to allow for much smaller more linear changes.

We can make the motor speed control in a number of ways. First we should establish what range we would like to be able to cover.

What would be a reasonable range of delay times to set up in the code ie shortest and longest delay periods that we will need?

July 12, 2012
by Ralphxyz
Ralphxyz's Avatar

Hi Darryl, I have use 2ms to 1000ms.

At 1000ms the coils heat up if left on for a couple of minutes but it does work.

That was in Full Step Mode in Half Step Mode there does not appear to be a problem.

I have not thought to much about speed control except that I wanted to do it.

I was going to start with the Nerdkits Temp Sensor project and a potentiometer.

That is very interesting on the speed increase with timing change.

I can definitely see the change between 2ms and 4ms.

I think I am going to have to think about this.

I suppose speed will depend on application it will not be generic code.

Ralph (sorry about all of the first person comments)

July 12, 2012
by sask55
sask55's Avatar

Ralph

I am not at home so don’t have access to software or nerd kit for a couple of days. The potentiometer method should work fine it would be an interesting option.

I will post some code using a method I have used before. It is common on agricultural equipment controls and monitoring systems to use two buttons for user set inputs. I kind of based my system on that kind of model. Basically the longer a person holds down the key the faster the changes occur. It takes a little practice but after a person gets a little experience it is a fast and very precise method to make changes over a very wide range of values. It may not be necessary to have precise stepper motor speed control for many projects but people may adapted this type of method for other input needs.

July 19, 2012
by sask55
sask55's Avatar
 // bi polar motor control
 // for NerdKits with ATmega168
 // by sask55

 #define F_CPU 14745600

 #include <avr/io.h>
  #include <inttypes.h>
 #include <avr/pgmspace.h>
 #include <stdio.h>
 #include <avr/interrupt.h>
 #include "../libnerdkits/delay.h" 
 #include "../libnerdkits/lcd.h"
 #include "../libnerdkits/uart.h"

 // pin Definitions
// output pins to L298N stepper motor controller input connections
    // PB4 -- IN1
    // PB1 -- IN2
    // PB2 -- IN3
    // PB3 -- IN4
// Input pins to momentary push buttons used for motor control
    // PC1 -- Run / Stop button
    // PC2 -- CW /CCW button
    // PC3 -- stepping mode button Full, Half, wave
    // PC4 -- Speed increase button
    // PC5 -- speed decrease button

 //set the stepper motor characteristics and user preferances
#define steps_per_rev 200.0 //  characteristic of the stepper motor,used to estimate motor RPMs.
#define speed_inc_factor  1.0 // incremental change in speed on each single button push,  as % of current speed, more linear then a constant value increment.
#define startup_speed  60.0 // default start up speed  in RPMs .
#define co_pins  (1<<PB4|1<<PB1|1<<PB2|1<<PB3) // set bits for output pins used on PORTB
#define hold_on_stop  0 // User select preferance, maintain holding current when motor is stopped? 0 = no 1= yes
#define MAX_RPM  2000.0 // maximum motor speed in RPMs
#define MIN_RPM   .1 // minimum motor speed in RPMs

int inc_step(int8_t dir, int8_t step){
step= step + dir;
    if (step<0) {   
        step =7;
        }
    if (step >7){
        step = 0;
        }
        return step;
}

 int main(){
    DDRB |= co_pins; //set pins for output
    PORTC |= (1<<PC1); // turn on internal pull up resistor for PC1
    PORTC |= (1<<PC2); // turn on internal pull up resistor for PC2
    PORTC |= (1<<PC3); // turn on internal pull up resistor for PC3
    PORTC |= (1<<PC4); // turn on internal pull up resistor for PC4
    PORTC |= (1<<PC5); // turn on internal pull up resistor for PC5
    uint8_t steps[8]; // array holds sequence of steps for motor half stepping
    int8_t step =0;  // holds current step in the sequence
    int8_t direct =1;  // 1 is forward and -1 in backward
    int8_t stopped =1;  // -1 is running  and 1 is stopped
    int8_t mode = 0;  // o = full stepping, 1 = wave stepping and 2 = half stepping
    uint32_t tdelay;  // total delay time for each half step, in microseconds, 32 bit to allow for full range of speeds
    uint32_t min_delay; // delay for minimum motor speed, in microseconds
    uint32_t max_delay; // delay for maximum motor speed, in microseconds
    uint16_t millis_delay =0;  // millisecond portion of delay time, 32 bit tdelay is to large for delay_us function so split it up  
    uint16_t micros_delay =0 ;  // microsecond portion of delay time

    uint8_t inc_ct;   // increment counter
    float incf2;    // increment speed adjustment factor
    uint8_t incf;      // increment temperary variable
    double RPM = startup_speed;     // motor speed in RPM.

    steps[0] = ~((1<<PB4) | (1<<PB2)) ;      //  sets step AB 
    steps[1]= ~(1<<PB2);         // sets step B
    steps[2]=  ~((1<<PB1) | (1<<PB2));     //sets step /AB
    steps[3]= ~(1<<PB1);         //sets step/A
    steps[4]= ~((1<<PB1)| (1<<PB3));     // sets step/A/B
    steps[5]= ~(1<<PB3);         //sets step /B
    steps[6]= ~((1<<PB4) | (1<<PB3));     //sets step A/B
    steps[7]= ~(1<<PB4);         //sets stepA

    tdelay = (1000000/((startup_speed/60) * steps_per_rev *2)) ; // set start up delay time  in microseconds, for sartup_speed

    min_delay = (1000000/((MIN_RPM/60) * steps_per_rev *2)) ; // set  delay time  in microseconds for min motor speed allowed
    max_delay = (1000000/((MAX_RPM/60) * steps_per_rev *2)) ; // set  delay time  in microseconds  for max motor speed allowed
    millis_delay = (int)(tdelay/1000);          // calculate millisecond portion of delay time
    micros_delay= tdelay- millis_delay*1000;    // calculate microsecond portion of delay time

    lcd_init();
        lcd_home();
        FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
        //display initial settings
            lcd_line_one();
            lcd_write_string(PSTR("Motor stopped  "));
            lcd_line_two();
            lcd_write_string(PSTR("CW rotation"));  
            lcd_line_three();
            lcd_write_string(PSTR("Full step mode"));       
            lcd_line_four();

            fprintf_P(&lcd_stream,PSTR("Speed= %6.2f-RPMs"), RPM);

    while(1){

    // check CW CCW bUtton display results

        if((PINC & (1<<PC2)) == 0){

                direct = - direct;  // change the motor direction
                lcd_line_two();     //display currnet direction setting
                    if (direct ==1){
                        lcd_write_string(PSTR("CW rotation"));
                    } else{
                        lcd_write_string(PSTR("CCW rotation"));
                }delay_ms(500);  // delay to allow user to react to change and release the button before McU loops.

            }

    //check stepping mode button display results
        if((PINC & (1<<PC3)) ==0){

                mode++;  //change the mode
                if (mode == 3){
                    mode = 0;
                    }
                lcd_line_three(); // display current mode setting
                    switch (mode){
                    case 0:

                        lcd_write_string(PSTR("Full step mode"));
                        break;
                    case 1:

                        lcd_write_string(PSTR("Wave step mode"));
                        break;
                    case 2:

                        lcd_write_string(PSTR("Half step mode"));
                        }
                        delay_ms(500);// delay to allow user to react to change and release the button before McU loops

        }

    // check speed increase button display results
    if ((PINC & (1<<PC4))==0){

            inc_ct=0; // Button hold down counter
            while ((PINC & (1<<PC4)) == 0) {// while button is pushed
                    incf = (inc_ct/6); // speed muliplyer +1 every sixth count of button hold down counter
                    incf2 = (float)(incf+1)*(incf+1);//speed multiplier is squared to get delay factor, increase change rate expenentualy with time. 
                    inc_ct++;

            tdelay = tdelay / (1. +((incf2 * speed_inc_factor)/100));// incremment delay time.

            if (tdelay <= max_delay) { // limit range
            tdelay = max_delay;
            }

            RPM = (1000000/(steps_per_rev *2 * tdelay)*60); // calculate RPMs with new delay
            lcd_line_four();                                    // display RMP setting
            fprintf_P(&lcd_stream,PSTR("Speed= %6.2f-RPMs "), RPM);
            delay_ms(300);  // delay in button hold down count loop to allow user to see and react to changes made. 
            }

         millis_delay = (int)(tdelay/1000); // millisecond portion of total delay time, ie > 1000us.
         micros_delay= tdelay- millis_delay*1000; // microsecond portion of total delay time ie < 1000us.

         }

    // check speed decrease button display results
    if((PINC & (1<<PC5))==0){

            inc_ct=0; 
            while ((PINC & (1<<PC5))==0){
                incf=(inc_ct/6);
                incf2 = (float)((incf+1)*(incf+1));
                inc_ct++;
            tdelay = tdelay * (1. +((incf2 * speed_inc_factor)/100));// incremment delay time.

            if (tdelay >= min_delay) {
            tdelay = min_delay;

            }

            RPM = (1000000/(steps_per_rev *2 * tdelay)*60);
            lcd_line_four();
            fprintf_P(&lcd_stream,PSTR("Speed= %6.2f-RPMs"), RPM);
            delay_ms(300);  // delay in button hold down count loop to allow user to see and react to changes made.

            }
         millis_delay = (int)(tdelay/1000);
         micros_delay= tdelay- millis_delay*1000;

         }

    //check stop run button display results
    if((PINC & (1<<PC1))==0){

                stopped = -stopped;  // motor on/off status
                lcd_line_one();

                if (stopped == -1) {
                lcd_write_string(PSTR("Motor Runnig  ")); // display current off on status
                }else{
                    lcd_write_string(PSTR("Motor stopped "));
                    if (hold_on_stop == 0){     // hold motor coils on in stopped poition??
                    PORTB = (PORTB | (co_pins)) ;
                    }
                    }
                    delay_ms(500);// delay to allow user to react to change and release the button before McU loops

}

if (stopped == -1){

    step = inc_step(direct,step); // change one step position is mottor is running

    delay_ms(millis_delay);   // delay to achieve mottor speed
    delay_us(micros_delay);

            switch (mode){
                case 0: // full stepping mode is selected

                    if (((float)step/2) > (step/2)){  
                    step = inc_step(direct,step) ;// odds numbered step is a wave mode step so skip
                    delay_ms(millis_delay);  // delay to maintain RPM the same as half stepping mode
                    delay_us(micros_delay);
                    } 
                    break;
                case 1: // wave stepping mode is selected

                    if (((float)step/2) == (step/2)){
                    step = inc_step(direct,step);// even numbered step is a full mode step so skip 
                    delay_ms(millis_delay);  // delay to maintain RPM the same as half stepping mode
                    delay_us(micros_delay);
                    break;
                    }
                case 3:

                    break;
                    }

                        PORTB = ((PORTB |co_pins) & steps[step]);// send step output to controller, all modes.

            }

}
}

I am posting an example of code that can be used to control bipolar stepper motors. I have tried to put comments in place to help explain how it is set up. There are many ways motor control could be done this is just one way to do it.

To use this code: First change the #define values to match your motor characteristics and your personal preferences.

This code will allow you to

----Turn a motor on and off, and restart at the current step.

----Select the motor direction CW or CCW. There is a 50% chance that the directions will be correct on any setup. If the motor is turning the wrong way from what is displayed on the LCD. Flip or switch the two wire on ONE of the motor coils to correct the LCD display.

----Select what stepping mode you wish the motor to be doing.

----Select the motor speed over a very wide range by holding down the key the incremental rate of change increase with time.

A few notes.

As Ralph has indicated using pin 14 PORTB PB0 as an output pin can sometimes cause problems because this pin when pulled low at start up will put the MCU in program mode. I have moved the IN1 connection to PORT B PB4.

The value of RPMs used in this code is approximant and ideal. I have made no attempt to verify how accurate these values are.

I have used a 32 bit int variable to hold the delay time is microseconds. By using this large variable it is possible to have both a very wide range of speeds and fine control of speed changes.

I have tried a couple of ideas for the delay time increment. The inverse relationship between delay time and motor speed makes it difficult to produce linear changes in speed over a large range. I settled on a using an increment based on a percentage of the current speed rather than a constant value.

According to its data sheet the L298N motor controller chip has the capability to make use of current sensing resistors to allow the chip to limit current to the motor coils. Control boards like the one Ralph has, do not have any provision designed into them to allow the user to make use of that capability on the chip. Without that capability the speed range and torque produced by the motor will be limited.

As the speed of the motor is increased the inductance of the motor coils becomes more relevant. At high controller speeds the motor will eventually stall or not have sufficient torque to move any load.

At low controller speeds the motor coils may overheat do to continues high current flow.

If a project requires a broader motor speed range and more torque at higher motor speeds. I would consider abandoning the motor control board and acquiring a L298N chip., A couple of resistors properly sized to limit the current to match my stepper motor coil rating. Some fast diodes to be used as flyback current diodes. A higher voltage power supply that is rated with a capacity of at least twice the motor coil rating, By building or buying a circuit with current control it is likely you will get much better motor performance.

A major consideration of controlling a motor this way is that the MCU is spending most of its time doing delays and is therefore not available to do much else. Controlling one motor at a time is about all that can be done using this approach. In fact when the motor is turning very slowly the MCU does not check the status of the buttons very often even using the input buttons is affected by the delays.

I hope that some of this is of some help or at least interesting.

Darryl

July 19, 2012
by live4the1
live4the1's Avatar

I've noticed that you have steps_per_rev at 200. Since my motor is set at 7.5 degrees per step would I put 48 instead of 200 and if in half-step mode, would it actually be 96 steps per revolution?

July 19, 2012
by Ralphxyz
Ralphxyz's Avatar

or at least interesting

Yeah right hopefully someone will find this interesting (ME, ME, ME).

Can't wait to try it, I need some good rainy days the weather has finally cooled off so I need to be working on my outside project.

Ralph

July 19, 2012
by sask55
sask55's Avatar

live4the1

Yes 48. will replace 200.0 if your motor has 7.5 degree steps.

The decimal point should be included as in some cases it indicates to the compiler to treat the number as a floating point number not an integer type.

Yes there would be 96 half steps per rev for half stepping mode. This is handled in the code by doubling the value of step_per_rev and then skipping the output part of every second step for half and full stepping modes but still doing the delay to maintain the same speed. The user does not have to change anything when selecting different modes.

July 21, 2012
by sask55
sask55's Avatar

I have looked over the code that I posted.

Although the code does work as it was posted, I see a number of strange things that are not necessary or correct. I have attempted to clean up and remove a bit of the confusing bits of code, here and there, that I have noticed. Most of these errors originated as a result of cut and paste operations, or me changing my approach without changing all the lines affected.

I think this code may be a little clearer.

 // bi polar motor control
 // for NerdKits with ATmega168
 // by sask55

#define F_CPU 14745600

#include <avr/io.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "../libnerdkits/delay.h" 
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

// pin Definitions
// output pins to L298N stepper motor controller input connections
    // PB4 -- IN1
    // PB1 -- IN2
    // PB2 -- IN3
    // PB3 -- IN4
// Input pins to momentary push buttons used for motor control
    // PC1 -- Run / Stop button
    // PC2 -- CW /CCW button
    // PC3 -- stepping mode button Full, Half, wave
    // PC4 -- Speed increase button
    // PC5 -- speed decrease button

//set the stepper motor characteristics and user preferances
#define steps_per_rev 200.0 //  characteristic of the stepper motor,used to estimate motor RPMs.
#define speed_inc_factor  1.0 // incremental change in speed on each single button push,  as % of current speed, more linear then a constant value increment.
#define startup_speed  60.0 // default start up speed  in RPMs .
#define co_pins  (1<<PB4|1<<PB1|1<<PB2|1<<PB3) // set bits for output pins used on PORTB
#define hold_on_stop  0 // User select preferance, maintain holding current when motor is stopped? 0 = no 1= yes
#define MAX_RPM  2000.0 // maximum motor speed in RPMs
#define MIN_RPM   .1 // minimum motor speed in RPMs

int inc_step(int8_t dir, int8_t step){ //step number increment function , accepts  current  direction and step number return next step number 
step= step + dir;               // increment step number, up or down one step depending on value of dir.
    if (step<0) {               // for CcW rotation step after step 1 is step 7 
        step =7;
        }
    if (step >7){               // for CW rotation step after step 7 is step 1
        step = 0;
        }
        return step;
}

 int main(){
    DDRB |= co_pins; //set pins for output
    PORTC |= (1<<PC1); // turn on internal pull up resistor for PC1
    PORTC |= (1<<PC2); // turn on internal pull up resistor for PC2
    PORTC |= (1<<PC3); // turn on internal pull up resistor for PC3
    PORTC |= (1<<PC4); // turn on internal pull up resistor for PC4
    PORTC |= (1<<PC5); // turn on internal pull up resistor for PC5
    uint8_t steps[8]; // array holds sequence of steps for motor half stepping
    int8_t step =0;  // holds current step in the sequence
    int8_t direct =1;  // 1 is forward and -1 in backward
    int8_t stopped =1;  // -1 is running  and 1 is stopped
    int8_t mode = 0;  // o = full stepping, 1 = wave stepping and 2 = half stepping
    uint32_t tdelay;  // total delay time for each half step, in microseconds, 32 bit to allow for full range of speeds
    uint32_t min_delay; // delay for minimum motor speed, in microseconds
    uint32_t max_delay; // delay for maximum motor speed, in microseconds
    uint16_t millis_delay =0;  // millisecond portion of delay time, 32 bit tdelay is to large for delay_us function so split it up  
    uint16_t micros_delay =0 ;  // microsecond portion of delay time

    uint8_t inc_ct;   // increment counter
    uint8_t incf2;    // increment speed adjustment factor
    uint8_t incf;      // increment temperary variable
    float RPM = startup_speed;     // motor speed in RPM.

    steps[0] = ~((1<<PB4) | (1<<PB2)) ;      //  sets step AB, all bit high except for PB4 and PB2
    steps[1]= ~(1<<PB2);         // sets step B
    steps[2]=  ~((1<<PB1) | (1<<PB2));     //sets step /AB
    steps[3]= ~(1<<PB1);         //sets step/A
    steps[4]= ~((1<<PB1)| (1<<PB3));     // sets step/A/B
    steps[5]= ~(1<<PB3);         //sets step /B
    steps[6]= ~((1<<PB4) | (1<<PB3));     //sets step A/B
    steps[7]= ~(1<<PB4);         //sets stepA

    tdelay = (1000000/((startup_speed/60) * steps_per_rev *2)) ; // set start up delay time  in microseconds, for sartup_speed

    min_delay = (1000000/((MIN_RPM/60) * steps_per_rev *2)) ; // set  delay time  in microseconds for min motor speed allowed
    max_delay = (1000000/((MAX_RPM/60) * steps_per_rev *2)) ; // set  delay time  in microseconds  for max motor speed allowed
    millis_delay = (int)(tdelay/1000);          // calculate millisecond portion of delay time
    micros_delay= tdelay- millis_delay*1000;    // calculate microsecond portion of delay time

    lcd_init();
        lcd_home();
        FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
        //display initial settings
            lcd_line_one();
            lcd_write_string(PSTR("Motor stopped  "));
            lcd_line_two();
            lcd_write_string(PSTR("CW rotation"));  
            lcd_line_three();
            lcd_write_string(PSTR("Full step mode"));       
            lcd_line_four();

            fprintf_P(&lcd_stream,PSTR("Speed= %6.2f-RPMs"), RPM);

    while(1){

    // check CW CCW bUtton  and display results if button is pushed

        if((PINC & (1<<PC2)) == 0){  
            direct = - direct;  // change the motor direction
            lcd_line_two();     //display currnet direction setting
            if (direct ==1){
                lcd_write_string(PSTR("CW rotation"));
            } else{
                lcd_write_string(PSTR("CCW rotation"));
            }delay_ms(500);  // delay to allow user to react to change and release the button before McU loops. 
        }

    //check stepping mode button and  display results if button is pushed

        if((PINC & (1<<PC3)) ==0){
            mode++;  //change the mode
            if (mode == 3){
                mode = 0;
                }
            lcd_line_three(); // display current mode setting
                switch (mode){
                    case 0:
                        lcd_write_string(PSTR("Full step mode"));
                    break;
                    case 1:
                        lcd_write_string(PSTR("Wave step mode"));
                    break;
                    case 2:
                        lcd_write_string(PSTR("Half step mode"));
                    }
                delay_ms(500);// delay to allow user to react to change and release the button before McU loops
            }

    // check speed increase button and display results if button is pushed

    if ((PINC & (1<<PC4))==0){
        inc_ct=0; // Button hold down counter
        while ((PINC & (1<<PC4)) == 0) {// while button is pushed
            incf = (inc_ct/6); // speed muliplyer +1 every sixth count of button hold down counter
            incf2 = (incf+1)*(incf+1);//speed multiplier is squared to get delay factor, increase change rate expenentualy with time. 
            inc_ct++;
            tdelay = tdelay / (1. +((incf2 * speed_inc_factor)/100));// incremment delay time.

            if (tdelay <= max_delay) { // limit range
            tdelay = max_delay;
            }

            RPM = (1000000/(steps_per_rev *2 * tdelay)*60); // calculate RPMs with new delay
            lcd_line_four();                                    // display RMP setting
            fprintf_P(&lcd_stream,PSTR("Speed= %6.2f-RPMs "), RPM);
            delay_ms(300);  // delay in button hold down count loop to allow user to see and react to changes made. 
        }

        millis_delay = (int)(tdelay/1000); // millisecond portion of total delay time, ie > 1000us.
        micros_delay= tdelay- millis_delay*1000; // microsecond portion of total delay time ie < 1000us.

    }

    // check speed decrease button and display results if button is pushed

    if((PINC & (1<<PC5))==0){
        inc_ct=0; 
        while ((PINC & (1<<PC5))==0){
            incf=(inc_ct/6);
            incf2 = ((incf+1)*(incf+1));
            inc_ct++;
            tdelay = tdelay * (1. +((incf2 * speed_inc_factor)/100));// incremment delay time.

            if (tdelay >= min_delay) {
            tdelay = min_delay;
            }

            RPM = (1000000/(steps_per_rev *2 * tdelay)*60);
            lcd_line_four();
            fprintf_P(&lcd_stream,PSTR("Speed= %6.2f-RPMs"), RPM);
            delay_ms(300);  // delay in button hold down count loop to allow user to see and react to changes made.

        }
        millis_delay = (int)(tdelay/1000);
        micros_delay= tdelay- millis_delay*1000;

    }

    //check stop run button display and display results if button is pushed

    if((PINC & (1<<PC1))==0){
        stopped = -stopped;  // motor on/off status
        lcd_line_one();
        if (stopped == -1) {
            lcd_write_string(PSTR("Motor Runnig  ")); // display current off on status
        }else{
            lcd_write_string(PSTR("Motor stopped "));
            if (hold_on_stop == 0){     // hold motor coils on in stopped poition??
                PORTB = (PORTB | (co_pins)) ;  //set all controller pins high controller out will be all low. coils off. 
            }
        }
        delay_ms(500);// delay to allow user to react to change and release the button before McU loops

    }

if (stopped == -1){  // is the mottor running?

    step = inc_step(direct,step); // change one step position if motor is running

    delay_ms(millis_delay);   // delay to achieve motor speed
    delay_us(micros_delay);

    switch (mode){
        case 0: // full stepping mode is selected
            if (((float)step/2) > (step/2)){  
                step = inc_step(direct,step) ;// odds numbered step is a wave mode step so skip
                delay_ms(millis_delay);  // delay to maintain RPM the same as half stepping mode
                delay_us(micros_delay);
            } 
            break;
        case 1: // wave stepping mode is selected
            if (((float)step/2) == (step/2)){
                step = inc_step(direct,step);// even numbered step is a full mode step so skip 
                delay_ms(millis_delay);  // delay to maintain RPM the same as half stepping mode
                delay_us(micros_delay);
            }
            break;

    }

    PORTB = ((PORTB |co_pins) & steps[step]);// send step output to controller, all modes.

}

 }
 }

Darryl

July 24, 2012
by Ralphxyz
Ralphxyz's Avatar

Hey Darryl, you have the buttons going to ground correct?

I tried your code, it compiles fine but I am getting nothing with button press.

The motor does not run!

None of LEDs light also.

Ralph

July 24, 2012
by sask55
sask55's Avatar

Ralph

That seams strange it is working here.

Are you seeing the four lines of messages on the LCD screen as expected ?

“Motor stopped “ should be in line one.

Yes the buttons go to ground, five buttons should be on the MCU pins 24,25,26,27,28

I am not sure what is going on. We will have to try to isolate the problem by eliminating one thing at a time.

Darryl

July 25, 2012
by Ralphxyz
Ralphxyz's Avatar

I do not have a LCD, I would add one but I use Rick's I2C LED and so I'll have to make adjustments to see the LCD.

I was sure the buttons went to ground but wanted to make sure, thanks.

I do not have a lot of time but I'll try to sort this out.

Of course I'll will be looking at my wiring and running some previously working code to make sure everything is "still" wired up correctly.

Funny how things can change with the previously working breadboard and controller pushed aside while I was working on a different breadboard.

Ralph

July 25, 2012
by sask55
sask55's Avatar

Ralph

With no LCD the only button that you will notice anything happening is the start/stop on the PC1 pin. All the buttons should still work if the motor is stopped but there is no way you will be able to tell they are working until you start the motor. The way the code is written the motor will always pause while any button is pushed. When a button is pushed the change made by the button push is displayed on the LCD. After the button is released there is a short delay and motor will resume, using the change. If you hold a button down you will end up repeatedly changing the parameter that that button controls. i.e. the button on PC1 will switch between the motor being off and on about twice each second until the button is released

Post a Reply

Please log in to post a reply.

Did you know that many systems in nature can be described by a first order response? Learn more...