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.

Servo Motor Push Button

Status
Not open for further replies.

lipming

Newbie level 5
Joined
Mar 23, 2008
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,400
Hi, I'm using MikroC for this project and I have some problem.
I just want to turn the servo motor +90 degree when a button is pushed ( logic 1 ) and when button release ( logic 0) the motor goes back to 0 degree.

Previously I manage to achieve that but the motor in the servo keeps on running because the program is always in a loop. So I decide to modify it. So far no luck at all.

Can some one take a look and tell me whats wrong with my coding? Thanks in advance.






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
unsigned int temp_res; oldstate; i;
 
void main() {
 
    TRISA  = 0xFF;
    TRISD = 0b00000000;
    PORTD= 0b00000000;
 
 
  do
     {
    temp_res = ADC_Read(0);
 
    if (temp_res==0)
     { goto close;
     }
 
   if (temp_res>0)
     { goto open;
     }
 
     }while(1);
 
    open:
     PORTD=0b00000001;
     delay_us(1500);
     PORTD=0b00000000;
     delay_us(1000);
 
    close :
     PORTD=0b00000001;
     delay_us(2000);
     PORTD=0b00000000;
     delay_us(2000);
 
 
 
           }

 
Last edited by a moderator:

Code:
unsigned int temp_res; oldstate; i;

void main() {

TRISA = 0xFF;
TRISD = 0b00000000;
PORTD= 0b00000000;


while(1)
{

//temp_res = ADC_Read(0);     // 
read status of a Pin 

if (temp_res) {open();}
else   {close();}
}
}


void open(void)
{
unsigned int count=0;
while(count<1000)
{
PORTD=0b00000001;
delay_us(1500);
PORTD=0b00000000;
delay_us(1000);
count++;
}
}

void close(void)
{
unsigned int count=0;
while(count<1000)
{
PORTD=0b00000001;
delay_us(2000);
PORTD=0b00000000;
delay_us(2000);
count++;
}
}
 

Hi, thanks for the reply. It gave me a lot of info on the looping.
But I still have some problems.
The ADC is working. In the simulation when I press the button the ADC registry change, but the servo motor keep on rotating to -90 degree which is not in any of the direction I set it.

Any Idea why?

Here is my code again.

Code:
unsigned int temp_res; oldstate; i;

void main() {

TRISA = 0xFF;
TRISB = 0b00000000;
PORTB = 0b00000000;

while(1)
{

temp_res = ADC_Read(0);     //
//read status of a Pin
temp_res = (temp_res >>2);  //throw away the 2 LSB bits


if (temp_res==0)
 {goto open;}
else (temp_res==255);
 {goto close;}
}
}


void open(void)
{
unsigned int count=0;
while(count<1000)
{
PORTB=0b00000001;
delay_us(2000);
PORTB=0b00000000;
delay_us(1000);
count++;
}
}

void close(void)
{
unsigned int count=0;
while(count<1000)
{
PORTB=0b00000001;
delay_us(1500);
PORTB=0b00000000;
delay_us(1000);
count++;
}
}
 

I've reconstruct my idea on the program's flow. Here is the flowchart.
Drawing1.jpg
Objective: Execute the "Open1" and "Close1" once when there are changes in input.
The problem:
1. The program could not response as I wanted. It only execute the " Open1" subroutine when I drop the input to 0V.
2. Even when it execute the "Open1" subroutine, it keeps on looping and seems like the X counter did not prevent it from looping.

Here is my code.
Code:
unsigned int input;x;


void InitMain() {

  input= 0;
  TRISA = 0xFF;                        // configure PORTA pins as input
  PORTB = 0;                          // set PORTC to 0
  TRISB = 0;                          // designate PORTC pins as output
   x=1;
}

void main() {
  InitMain();


   while(1)
   {

     input = ADC_Read(2);
     input = (input>>2);  //throw away the 2 LSB bits

   if (input==0x00)
  {goto open;}
   else
  {goto close;}

  }

open:
{
if  (x==1)
{goto open1;}
else
{goto main;}
}

close:
{
if  (x==0)
{goto close1;}
else
{goto main;}
}


open1:
{
PORTB=0b11111111;
delay_us(1500);
PORTB=0b00000000;
delay_us(1000);
x=0;
goto main;
}

close1:
{
PORTB=0b11111111;
delay_us(2000);
PORTB=0b00000000;
delay_us(2000);
x=1;
goto main;
}

}


Any help would be a great one. Thanks in advance.

- - - Updated - - -

Finally I got it done, haha. I just leave the code here for future reference. Leave me any comments if you think there are should and shouldn't that I've put in the code.
Thanks again!

Code:
unsigned int input;x;


void InitMain() {

  input= 0;
  TRISA = 0xFF;                        // configure PORTA pins as input
  PORTB = 0;                          // set PORTC to 0
  TRISB = 0;                          // designate PORTC pins as output
  PORTC = 0;                          // set PORTC to 0
  TRISC = 0;
   x=1;
}

void open1()
{
PORTB=0b11111111;
delay_us(1500);
PORTB=0b00000000;
delay_us(1000);
x=0;
 return;
}

void close1()
{
PORTB=0b11111111;
delay_us(1000);
PORTB=0b00000000;
delay_us(1000);
x=1;
 return;
}

void open()
{
if  (x==1)
open1();
 else
 return;

}

void close()
{
if  (x==0)
close1();
  else
 return;

}


void main() {
  InitMain();

  while(1)
 {
     input = ADC_Read(2);
     input = (input>>2);  //throw away the 2 LSB bits

   if (input==0x00)
   open();
   else
  close();
  }



}
 

Hi lipming,
if you wanna turn your axis a number of degrees you should use a stepper motor, not a servo motor, unless you know exactly the speed of your servo motor

- - - Updated - - -

Hi lipming,
if you wanna turn your axis a number of degrees you should use a stepper motor, not a servo motor, unless you know exactly the speed of your servo motor

- - - Updated - - -

when a button is pushed ( logic 1 ) and when button release ( logic 0)
why you use ADC ?
just a digital input can do the work !
 

ya, for the ADC, I am planing to put on an Infrared Sensor. and i have the servo motor ready available, I guess i would try stepper motor next time.

Oh and when I essemble the hardware. The servo motor does not turn 90 degree even though the pulses that I set it in the range.
What is the problem? faulty servo motor or coding error again? the simulation in Proteus indicates that it would turn to 90 degree but the actual thing just doesn't reach that. Another thing is that the turning of the servo motor is not consistent. Sometimes it turns more, sometimes it turn less.

any idea anyone?
 

There are numerous variations of RC servo motors and just as many duty cycle "ranges."

You may have to fine tune the actual duty cycle to yield the desired angle of rotational.

Do you have a datasheet for your particular servo motor?

After examining your code, your timing doesn't appear to be correct.

Almost all RC servo motors operate with a PWM frequency of 50Hz or a PWM period of 20ms.

Therefore, your loops should add up to 20ms total.

Example Simple PWM Servo Motor Control:

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//==========================================================================
//  Project             : Sample code for control single servo motors using delays
//                        This project is using 16F84A with 4MHz
//                        Has been try succesfully using GWS S03N STD
//                        
//                        Please make sure the hardware is compatible with this code
//
//  Project description : This source code is used to control a servo motor.
//                    Servo motor will continuosly turn from one position to another position 
//                    Lib func __delay_us() and __delay_ms() is use to generate the pulse width. 
//                      The delay timing is independent of crystal but_XTAL_FREQ must be set correctly.
//                        
//  
//  Author          : BigDogGuru
//  Date                : April 2011
//==========================================================================
// 
//  include
//==========================================================================
#include "config.h"
#include "delays.h"
#include <htc.h>                    // this sample code is using 16F84A !!
                                
//  configuration
//==========================================================================
 __CONFIG ( 0x3FF2 );               // configuration for the  16F84A
                                            
//  define
//==========================================================================
#define servo   RB5                 // servo set RB5
 
 
 
 
 
//  function                        (every function must have a function prototype)
//==========================================================================
 
//  none
//
//  main function                   (main fucntion of the program)
//==========================================================================
void main(void)
{
    unsigned int i;
    
    //set IO port for servo pin 
    TRISB = 0b00000000;         //servo motor is RB1
    PORTB = 0b00000000;         //clear port B
 
                                //servo will loop infinity
    while(1)                    //from one position to another position
    {
        //*******************************************************
        //
        //Delay determine the servo motors position
        //Try change the value for different position 
        //
        //Value in __delay_xs() function is unsigned long
        //Calculate the timing correctly or servo damage could result!!
        //
        //******************************************************
        
        for(i=0;i<50;i++)       //continues pulse for 50 times
        {
            servo=1;            //set servo pin high
            delay_us(900);  //delay 0.7ms
        
            servo=0;            //set servo pin low
            delay_us(19100);    //delay 19.3ms
        }
        
        //  _                   _                  _
        // | |                 | |                | |
        // | |                 | |                | |               ~~50 times              
        // | |_________________| |________________| |____________________
        // 0.7ms    19ms      0.7ms      19ms     0.7ms   19ms
        // |                   |
        // |<-------20ms------>|
        
        for(i=0;i<50;i++)       //continues pulse for 50 times
        {
            servo=1;            //set servo pin high
            delay_us(1500); //delay 1.8ms   
                                
                                
            servo=0;            //set servo pin low
            delay_us(18500);    //delay 18.2ms
                                
        }
 
 
 
        for(i=0;i<50;i++)       //continues pulse for 50 times
        {
            servo=1;            //set servo pin high
            delay_us(2000); //delay 1.8ms   
                                
                                
            servo=0;            //set servo pin low
            delay_us(18000);    //delay 18.2ms
                                
        }   
            
        //  ___                 ___                 ___
        // |   |               |   |               |   |
        // |   |               |   |               |   |              ~~50 times       
        // |   |_______________|   |_______________|   |____________________
        //  2ms       18ms      2ms      18ms       2ms     18ms
        // |                   |
        // |<-------20ms------>|
    }
        
}
    
//subroutines
//============================================================================  
//
// none




BigDog
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top