Debugging Stepper motor control

Discussion in 'The Projects Forum' started by becca23, Apr 10, 2010.

  1. becca23

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    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?
     
  2. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    It would help if we had a schematic of your circuit.

    hgmjr
     
  3. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    It would help even more if you would post your code.

    I think you may be running off the end or beginning of your array.
     
  4. becca23

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    Here's the schematic
     
  5. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    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

    Code ( (Unknown Language)):
    1.  
    2.     uint8 indx = 0;                // current position, 0..7
    3.     uint8 step[] = { 0b00000001,   // half-step patterns
    4.                      0b00000101,   //
    5.                      0b00000100,   //
    6.                      0b00000110,   //
    7.                      0b00000010,   //
    8.                      0b00001010,   //
    9.                      0b00001000,   //
    10.                      0b00001001 }; //
    11.  
    12.     void stepRt()
    13.     { indx++;                      // inc index, 0..7
    14.       indx &= 7;                   // inclusive
    15.       portb = step[indx];          //
    16.     }
    17.  
    18.     void stepLt()
    19.     { indx--;                      // dec index, 0..7
    20.       indx &= 7;                   // inclusive
    21.       portb = step[indx];          //
    22.     }
    23.  
    24.  
     
  6. retched

    AAC Fanatic!

    Dec 5, 2009
    5,201
    312
    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: Apr 10, 2010
  7. becca23

    Thread Starter New Member

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

    Code ( (Unknown Language)):
    1. uint8 coil1Seq[8] =  {1,1,1,0,0,0,0,0};
    2. uint8 coil2Seq[8] =  {0,0,0,0,1,1,1,0};
    3. uint8 coil3Seq[8] =  {1,0,0,0,0,0,1,1};
    4. uint8 coil4Seq[8] =  {0,0,1,1,1,0,0,0};
    5.  
    6.  
    7. uint8 coil1BSeq[8] =  {0,0,0,0,0,1,1,1};
    8. uint8 coil2BSeq[8] =  {0,1,1,1,0,0,0,0};
    9. uint8 coil3BSeq[8] =  {1,1,0,0,0,0,0,1};
    10. uint8 coil4BSeq[8] =  {0,0,0,1,1,1,0,0};
    11.  
    12.  
    13. uint8 currentStep = 0;
    14.  
    15. int main(void){
    16.     int16 valueHi;
    17.     int16 valueLo;
    18.     uint8 id;
    19.     SIMPACKET p;
    20.     uint32 u32_mask= 0x00000000;
    21.  
    22.     configOutputs();
    23.     CONFIG_RB0_AS_DIG_INPUT();
    24.     configInterrupt();
    25.     configBasic(HELLO_MSG);
    26.     setupECAN(u32_mask);    
    27.    
    28.     while(1){
    29.  
    30.         while(!CAN_MSG_AVAILABLE);
    31.         p = receiveCANmessage();
    32.         printf("Received Can message: %ld , %ld\n", p.ID, p.MSG);
    33.         valueLo = (uint16)p.MSG;
    34.    
    35.         if(valueLo > 0){
    36.         //    printf("Driving forwards: %d\n", valueLo);
    37.         driveForwardXSteps(valueLo);                
    38.         }
    39.         else{
    40.         //    printf("Driving backwards: %d \n", valueLo);
    41.             driveBackwardXSteps(valueLo*-1);    
    42.         }
    43.    
    44.     }
    45.     return 0;
    46. }
    47.  
    48. void configOutputs(){
    49.     CONFIG_RB12_AS_DIG_OUTPUT();
    50.     CONFIG_RB13_AS_DIG_OUTPUT();
    51.     CONFIG_RB14_AS_DIG_OUTPUT();
    52.     CONFIG_RB15_AS_DIG_OUTPUT();
    53. }
    54.  
    55. void driveForwardXSteps(int steps){
    56.     int x;
    57.     for(x = currentStep+1; x < steps + currentStep+1; x++){
    58.         _LATB12 = coil1Seq[(x)%8];
    59.         _LATB13 = coil2Seq[(x)%8];
    60.         _LATB14 = coil3Seq[(x)%8];
    61.         _LATB15 = coil4Seq[(x)%8];
    62.  
    63.         DELAY_MS(10);
    64.     }
    65.     currentStep = (x-1)%8;
    66. }
    67.  
    68. void driveBackwardXSteps(uint16 steps){
    69.     uint16 x;
    70.     mod8currentStep(-1);
    71.      mod8currentStep(-1);
    72.     mod8currentStep(-1);
    73.     for(x = 0; x < steps; x++){
    74.         mod8currentStep(-1);
    75.         _LATB12 = coil1Seq[currentStep];
    76.         _LATB13 = coil2Seq[currentStep];
    77.         _LATB14 = coil3Seq[currentStep];
    78.         _LATB15 = coil4Seq[currentStep];
    79.        
    80.         DELAY_MS(10);
    81.     }
    82.    
    83. }
    84. void mod8currentStep(int8 posNeg){
    85.     /* Since %8 with negative numbers doesn't seem to work,
    86.     /  this function provides the functionality for a circular buffer.
    87.     /  
    88.     /  currentStep is a global variable that keeps track of the step that the motor
    89.     /  is on.
    90.     /  posNeg indicates whether the count is increasing or decreasing.
    91.     */
    92.    
    93.     if(currentStep == 7 && posNeg > 0){
    94.         //If the currentStep is 7, and the posNeg value is positive
    95.         //indicating that the count is increasing, we need to loop back around to 0.
    96.         currentStep = 0;
    97.     }else if(currentStep == 0 && posNeg < 0){
    98.         //If the step is 0 and the posNeg is negative, indicating that the count
    99.         //is decreasing, we need to loop back to 7.
    100.         currentStep = 7;
    101.     }else{
    102.         if(posNeg > 0 )
    103.             currentStep++;
    104.         else
    105.             currentStep--;
    106.     }    
    107.  
    108. }
    109.  
     
  8. becca23

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    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.
     
  9. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    What is the part number and manufacturer of your stepper motor just for our reference?

    hgmjr
     
  10. becca23

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    I ordered it from digi-key. It's a portescap 26M048B2U
     
  11. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    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.
     
Loading...