# How to solve this STEPPER motor problem?

Status
Not open for further replies.

#### milan.rajik

##### Banned I have written a Stepper Motor code but it is not working as expected.

My Stepper is a 12V Bi-Polar type. RPM is 360 and step angle is 1.8.

For full 360 rotation I need to step 360 / 1.8 = 200 steps.

In my project I only need to rotate +/- 90, +/- 180.

The motor rotates in these sequence

a) +90 and then -90

b) +90 and then +90 and than -180

c) -90 and then +90

d) -90 and then -90 and then +180

e) +180 and then -180

these sequences (a, b, c, d, e) can occur in any any random way that is...

if a occurs first then a, b, c, d, e can occur again

similarly

if b occurs first then again a, b, c, d, e can occur

The code I have written is given below.

I need 50 steps for 90 and -90 and 100 steps for 180 and -180 degrees.

It works fine for 90 and -90 but not for others.

I am saving the previous step executed in a static variable so that when the RUN_STEPPER() is called another time then previous step is executed again that is

there are 4 pulse sequence

0x10
0x40
0x20
0x80

as I am using upper 4 bits of PORTB

If previous pulse was 0x20 than in the previous step value will be 2 and next function call 0x20 is again executed first and stepper moves either in CW or CCW.

eg: lPreviousStep = 2

In next function call for direction 1 (CW)

lRequiredSteps will be 50 + 2 = 52
52 % 4 = 0

lSteps = lPreviousStep; (lStep will be assigned 2)

loops from 2 to 52 = 50 loops

lCurrStep = lSteps % 4; (loop 1st time, 2 % 4 = 2)

So case 2 of Step_Motor() is executed which is the same step which was executed as the last pulse sequence when RUN_STEPPER() was called previously.

But the code is working erratically. It turns 90 and then -90 and when it turns 180 again the angle is wrong.

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
void Step_Motor(unsigned char pStep) {

unsigned char lStep = 0;

lStep = pStep;

switch(lStep) {
case 0:
STEPPER = (STEPPER & 0x0F) | 0x10;
break;
case 1:
STEPPER = (STEPPER & 0x0F) | 0x40;
break;
case 2:
STEPPER = (STEPPER & 0x0F) | 0x20;
break;
case 3:
STEPPER = (STEPPER & 0x0F) | 0x80;
break;
}

Delay50ms();
}

void RUN_STEPPER(signed int pAngle) {

signed int lAngle = 0;
unsigned char lDir = 0, lCurrStep = 0, lRequiredSteps = 0, lSteps = 0;
static unsigned char lPreviousStep;

lAngle = pAngle;

switch(lAngle) {

case 90:
lRequiredSteps = 50;
lDir = 1;
break;
case -90:
lRequiredSteps = 50;
lDir = 2;
break;
case 180:
lRequiredSteps = 100;
lDir = 1;
break;
case -180:
lRequiredSteps = 100;
lDir = 2;
break;
};

switch(lDir) {

case 1:
lSteps = lPreviousStep;
lRequiredSteps += lPreviousStep;
while(lSteps <= (lRequiredSteps)) {
lCurrStep = lSteps % 4;
Step_Motor(lCurrStep);
++lSteps;
}
break;
case 2:
lRequiredSteps += (lPreviousStep + 2);
while(lRequiredSteps >= (lPreviousStep + 2)) {
lCurrStep = lRequiredSteps % 4;
Step_Motor(lCurrStep);
--lRequiredSteps;
}

break;
};

lPreviousStep = lCurrStep;

}

#### Attachments

##### Full Member level 3 the codes below worked for me, it is written in ccs but you can easily adopt it. it basically gives one step.

Code:
#define STOP   0
#define CW      1
#define CCW    -1

static unsigned char step_dir = STOP;
static byte step_speed= 0;
static byte current_step = 0;
byte const steps[] = {0x10,0x40,0x20,0x80};

void one_step()
{
if((step_speed != 0) && (step_dir != STOP)){
if(step_dir == CW)
current_step = (current_step+1)&(sizeof(steps)-1);
else
current_step = (current_step-1)&(sizeof(steps)-1);

output_d(steps[current_step]);
Delay_Ms(257-step_speed);
}

}

#### milan.rajik

##### Banned Thank you. I will test and reply.

Status
Not open for further replies.