Debugging Stepper motor control

Thread Starter

becca23

Joined Apr 10, 2010
5
I need some help with debugging a unipolar stepper motor I am using a PIC24 and a ULN2003A chip to drive the motor. It seems to have no problem moving forward, but only twitches when I attempt to go backward.

This is the half-step sequence I am using:
uint8 coil1Seq[8] = {1,1,1,0,0,0,0,0};
uint8 coil2Seq[8] = {0,0,0,0,1,1,1,0};
uint8 coil3Seq[8] = {1,0,0,0,0,0,1,1};
uint8 coil4Seq[8] = {0,0,1,1,1,0,0,0};

The logic I am using is to move a certain number of steps, a for loop increments through this array and assigns these values to the pins. To go backwards, it decrements from the last position it was in the array. Is this correct?
 

MMcLaren

Joined Feb 14, 2010
861
That symptom is very similar to what I got when one of my motor lines was connected in the wrong order.

If it helps, here's a excerpt from a half-step example program I did long ago. I don't mean to imply that it's better then yours. It's just different.

Good luck with your project.

Regards, Mike

Rich (BB code):
    uint8 indx = 0;                // current position, 0..7
    uint8 step[] = { 0b00000001,   // half-step patterns
                     0b00000101,   //
                     0b00000100,   //
                     0b00000110,   //
                     0b00000010,   //
                     0b00001010,   //
                     0b00001000,   //
                     0b00001001 }; //

    void stepRt()
    { indx++;                      // inc index, 0..7
      indx &= 7;                   // inclusive
      portb = step[indx];          //
    }

    void stepLt()
    { indx--;                      // dec index, 0..7
      indx &= 7;                   // inclusive
      portb = step[indx];          //
    }
 

retched

Joined Dec 5, 2009
5,207
When you post your code, use the ]code[ tags, It will help us help you..

As the Sarge said, I also suspect you may need to pad your array. That will only be know once we see the code, but it is an often seen problem.

[ed]
Stepped on you mike. sorry
[/ed]
 
Last edited:

Thread Starter

becca23

Joined Apr 10, 2010
5
Here's the code, hopefully it's not too confusing.

Rich (BB code):
uint8 coil1Seq[8] =  {1,1,1,0,0,0,0,0};
uint8 coil2Seq[8] =  {0,0,0,0,1,1,1,0};
uint8 coil3Seq[8] =  {1,0,0,0,0,0,1,1};
uint8 coil4Seq[8] =  {0,0,1,1,1,0,0,0};


uint8 coil1BSeq[8] =  {0,0,0,0,0,1,1,1};
uint8 coil2BSeq[8] =  {0,1,1,1,0,0,0,0};
uint8 coil3BSeq[8] =  {1,1,0,0,0,0,0,1};
uint8 coil4BSeq[8] =  {0,0,0,1,1,1,0,0};


uint8 currentStep = 0;

int main(void){
    int16 valueHi;
    int16 valueLo;
    uint8 id;
    SIMPACKET p;
    uint32 u32_mask= 0x00000000;

    configOutputs();
    CONFIG_RB0_AS_DIG_INPUT();
    configInterrupt();
    configBasic(HELLO_MSG);
    setupECAN(u32_mask);    
    
    while(1){

        while(!CAN_MSG_AVAILABLE);
        p = receiveCANmessage();
        printf("Received Can message: %ld , %ld\n", p.ID, p.MSG);
        valueLo = (uint16)p.MSG;
    
        if(valueLo > 0){
        //    printf("Driving forwards: %d\n", valueLo);
        driveForwardXSteps(valueLo);                
        }
        else{
        //    printf("Driving backwards: %d \n", valueLo);
            driveBackwardXSteps(valueLo*-1);    
        }
    
    }
    return 0;
}

void configOutputs(){
    CONFIG_RB12_AS_DIG_OUTPUT();
    CONFIG_RB13_AS_DIG_OUTPUT();
    CONFIG_RB14_AS_DIG_OUTPUT();
    CONFIG_RB15_AS_DIG_OUTPUT();
}

void driveForwardXSteps(int steps){
    int x;
    for(x = currentStep+1; x < steps + currentStep+1; x++){
        _LATB12 = coil1Seq[(x)%8];
        _LATB13 = coil2Seq[(x)%8];
        _LATB14 = coil3Seq[(x)%8];
        _LATB15 = coil4Seq[(x)%8];

        DELAY_MS(10);
    }
    currentStep = (x-1)%8;
}

void driveBackwardXSteps(uint16 steps){
    uint16 x;
    mod8currentStep(-1);
     mod8currentStep(-1);
    mod8currentStep(-1);
    for(x = 0; x < steps; x++){
        mod8currentStep(-1);
        _LATB12 = coil1Seq[currentStep];
        _LATB13 = coil2Seq[currentStep];
        _LATB14 = coil3Seq[currentStep];
        _LATB15 = coil4Seq[currentStep];
        
        DELAY_MS(10);
    }
    
}
void mod8currentStep(int8 posNeg){
    /* Since %8 with negative numbers doesn't seem to work,
    /  this function provides the functionality for a circular buffer.
    /  
    /  currentStep is a global variable that keeps track of the step that the motor
    /  is on. 
    /  posNeg indicates whether the count is increasing or decreasing.
    */
    
    if(currentStep == 7 && posNeg > 0){
        //If the currentStep is 7, and the posNeg value is positive
        //indicating that the count is increasing, we need to loop back around to 0.
        currentStep = 0;
    }else if(currentStep == 0 && posNeg < 0){
        //If the step is 0 and the posNeg is negative, indicating that the count
        //is decreasing, we need to loop back to 7.
        currentStep = 7;
    }else{
        if(posNeg > 0 )
            currentStep++;
        else
            currentStep--;
    }    

}
 

Thread Starter

becca23

Joined Apr 10, 2010
5
Matt, if I'm reading your code right, we're both using the same sequence, mine just starts on a different index.

As far as the wiring, I was wondering this too. I used a multimeter to narrow down that the black and brown wires go together, and the orange and yellow go together. I've tried switching the black and brown, and then the orange and yellow, but that really only seems to affect which direction it screws up in. And I'm assuming if I switch both sets, it will just act the same way as when I started.
 

SgtWookie

Joined Jul 17, 2007
22,230
Becca,
I suggest that you take Mike up on his kind offer of that section of code; his array uses 1/4 the memory space as your array does, the stepRt()/stepLt() functions are "bulletproof", and the code is much more easily understood.

I wrote some routines several years ago in a Basic language that are virtually identical to Mike's code.

I think your problem is occurring in the function "void mod8currentStep(int8 posNeg)".

Keep in mind that stepper motors have "ballistics"; if you are stepping them slowly, you don't have to worry much about starting and stopping them suddenly. However, if you want to run them at close to their maximum step rate, you will have to slowly accelerate them from a stop up to their max step rate, and then slow them down as you approach the terminal count.

A 10mS step is 100 steps/second. While you are debugging things, try increasing your time between steps to 30mS-50mS per step, and add a 100mS "nap" between changing directions.
 
Top