Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to solve this STEPPER motor problem?

Status
Not open for further replies.

milan.rajik

Banned
Advanced Member level 5
Joined
Apr 1, 2013
Messages
2,524
Helped
540
Reputation
1,078
Reaction score
524
Trophy points
1,393
Visit site
Activity points
0
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

  • stepper.png
    stepper.png
    39.5 KB · Views: 84
  • Stepper.rar
    16.8 KB · Views: 72

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);
  }

}
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top