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.

Control the servo motor using PIC16f877a

Status
Not open for further replies.

erfan.khalilian69

Member level 4
Joined
Feb 7, 2011
Messages
71
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,288
Location
Kualalampur
Activity points
1,916
Hi everyone can anyone help me over this project
actually its simple job to rotate the servo motor 90 degree CW and then 90 degree CCW.
I want to use push button for example if button 1 pressed then servo rotates 90 degree CW and if button 2 pressed servo rotates 90 degree CCW (back to first position)
plz help me over this
thanks
 

exactly what type of motor is it and how is it interfaced?
how will you measure the 90degrees?
 

exactly what type of motor is it and how is it interfaced?
how will you measure the 90degrees?

HI thanks for replayin mr horace
its normal servo motor (small servo motor for hobby kit C36R )
actually it does not matter how long it rotates but according to data sheet a 1.5 ms pulse will make the motor turn to the 90 degree position (neutral position).
the main part is how to rotate the motor CW and then rotate back to the first position CCW , I need some codes

---------- Post added at 16:07 ---------- Previous post was at 16:04 ----------

and about interfacing I dun want to interface yet I just want to rotate it some degree for example if button1 pressed servo rotates 90 degree CW and if button 2 pressed servo rotates 90 degree CCW (back to the first position) using C language in pic and hitech compiler
thanks
 

actually I have read these two pdf but I have doubt on my programming
I mean should I just right like this ?

if (BUTTON1 != 0)
{
RC3 = 1;


__delay_ms(1.5); // delay for 2 milliseconds
CLRWDT();



__delay_ms(18.5); // delay for 2 milliseconds
CLRWDT();

}


?????????
 

but if want to use one button :
I mean if the button one pressed servo motor rotates 90 degree CW and stop then after 45 seconds it rotates 90 degree CCW (back to the same position)???
 

reading the manual it looks like you send a 1.5mSec pulse to move the servo 90degrees and repeat it every 20mSec to maintain position. once you stop it returns to the netural position
probably something along the lines of
Code:
if (BUTTON1 != 0)
  for(i=0;i<45*5; i++)   // for 45 seconds
 {
     RC3 = 1;
     __delay_ms(1.5); // delay for 2 milliseconds
    CLRWDT();
     RC3 = 0;
     __delay_ms(18.5);   
     CLRWDT();
 }
 
thanks alot
i will try this command thank u very much

---------- Post added at 18:03 ---------- Previous post was at 17:59 ----------

but I have a question does it affect to the rest of program , i mean 45 seconds delay?
do i need put this command into void main of program or use while?
let me put my code here then tell me that where should i put these commands (for servo motor )

here is my all program : (this program is for showing temperature and light intensity on the LCD (16*2) thanks alot
 
Last edited:

I have tried your program but the thing is it gets error about the for loop , the error said undefined symbol something like this ?
actually how can I build 45 sec delay ? in this program which I have downloaded from Cytron website they defined the function for delay. here is the code for delay function

void delay(unsigned short i);// at above the program


//==================subroutine DELAY==========================
void delay(unsigned short i)
{
for(;i>0;i--);
}


and the thing is I think the program should be like this ? right?

if (BUTTON1 != 0)

RC3 = 1;
delay(1.5); // delay for 1.5 milliseconds /// now servo rotate 90 degree
//pause for 45 seconds
for(i=0;i<45*5; i++) // for 45 seconds
RC3 = 0; // back to the previous position
delay(18.5)

????????????????
it should be like this or not ?

plz help
 

the problem with a simple delay loop is you need to know the system clock frequency and instruction timing
see the following
PIC 16 Delay Tutorial by Vasily Koudymov

I would use a timer interrupt to get accurate timing

don't forget the {} arond the control loop
Code:
if (BUTTON1 != 0)
  for(i=0;i<45*5; i++)   // for 45 seconds
 {
     RC3 = 1;
     __delay_ms(1.5); // delay for 2 milliseconds
    CLRWDT();
     RC3 = 0;
     __delay_ms(18.5);   
     CLRWDT();
 }
 
Last edited:
thanks for replaying.
actually it gives me error so I modified the program as below :
//==============FUNCTION PTOTOTYPE=========================
void delay(unsigned short i);
void pause (unsigned short e);
//=======================main======================= ======
if (button != 0)


{
servo = 1;

delay(1.5);

pause(1); // stop for 45 seconds


servo = 0;
delay(18.5);

}

//==================subroutine DELAY==========================
void delay(unsigned short i)
{
for(;i>0;i--);
}
//=================subrouting Pause===========================
void pause (unsigned short e)


{
for(e=0;e<45*5; e++); // for 45 seconds

}


so do you think now it will working well ?
for 45 seconds I wrote the function as your command and named it pause then I wrote pause whenever I want this 45 seconds . is it righte?
 

Ideally if you are using a servo you should providing the position pulse continuously to the signal line, othewise noise on the signal could case the servo to change position.

If I was doing this in assemble I would handle the entire routine with interrupts. A button press would activate a change interrupt, move the servo and then set up the 45sec timer.
 

yeap
thanks for replaying , you mean the program has problem now ?
can you tell me where exactly should i modify ??????
 

now I got how to rotate the motor , I just need delay for 45 seconds , because i want to stop the motor for 45 seconds but I dun know how :((
any suggestion , does anybody have the codes for long delay ?
 

if you wish to have time intervals like 1.5mSec you need to interrupt 0.1mSec intervals then count 15 interrupts
the following code interrupts every 0.1mSec intervals using a PIC16F917 on a Microchip PICDEM mechatronics board with an 8MHz clock
Code:
volatile int tenthMillSecCounter=0;               // incremented every 10mSec

// Timer 0 is programmed to interrupt every 0.1mSeconds
//  T0 clock is FOSC/4 = 200000
//  with 1:2 prescaler decrements 2000000/2 times / second
//  to get an interrupt every  0.1 mSec the calculation for TMR0 overflow from 0xFF to 0 is
//    count = 255 - 1000000/10000 = 255 - 100
//    i.e. for 0.1mSec counter is
#define tenthMillSec 155
static void interrupt isr(void)
{
    if (T0IF)                           // A TMR0 interupt occurred
    {
        TMR0=tenthMillSec;                // increment counters every .1 mSec
        tenthMillSecCounter++;
    }
    T0IF=0;                             // clear TMR0 interrupt flag
}

// delay for count tenths of a second
void tenthMilliSecondDelay(int count)
{
    tenthMillSecCounter=0;                         // zero counter
    while( tenthMillSecCounter  < count) ;    // wait
}
        
        
// initalise clock, set port A for digital input, set up timer 0, etc
void systemInitialise(void)
{
        OSCCON=0x70;             // Fosc use oscillator 8MHz
        ANSEL=0;                 // set digital inputs
        OPTION=0x80;             // TMR0 RATE 1:2
        TMR0=tenthMillSec;       // initialise timer 0 counter
        T0IE = 1;                // enable interrupt on TMR0 overflow from 0xFF to 0
        GIE = 1;                 // Global interrupt enable
 }

the main() program then looks somthing like
Code:
systemInitialise();
if (BUTTON1 != 0)
  for(i=0;i<45*5; i++)   // for 45 seconds
     {
      RC3 = 1;
      tenthMilliSecondDelay(15); // delay for 1.5 milliseconds
      CLRWDT();
      RC3 = 0;
      tenthMilliSecondDelay(185);   
      CLRWDT();
     }
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top