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?

Jan 28, 2005
9,030
215

hgmjr

3. SgtWookie Expert

Jul 17, 2007
22,194
1,761
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

File size:
20.7 KB
Views:
61
5. MMcLaren Well-Known Member

Feb 14, 2010
795
128
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.

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
315

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;
21.
22.     configOutputs();
23.     CONFIG_RB0_AS_DIG_INPUT();
24.     configInterrupt();
25.     configBasic(HELLO_MSG);
27.
28.     while(1){
29.
30.         while(!CAN_MSG_AVAILABLE);
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
215
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,194
1,761
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.