Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Servo motor control...

Status
Not open for further replies.
Hi, its working Ian was right simple but its 180* how to make 360* for robot arm and here is code with ADC but working in one direction not counter clock wise why?

C:
#include <htc.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000
 int ReadADC();
void main()
   {
unsigned long number=0;   
   TRISB=0X00;
TRISA = 0xff ;
   ADCON1=0b10000000;
   ADCON0=0b10000001;//000 = channel 0, (RA0/AN0)
   ADIF=0;
ADIE=1;
   PEIE=1;
   TRISC = 0 ;
   PR2 = 39 ;
   T2CON = 0b00000110 ;   
   CCP1CON = 0b00111100;   
     
   while(1)
     {
   number = ReadADC(0);
CCPR1L=number;


}

   }
int ReadADC(void)
   {
   int ret = 0;
   __delay_ms(20);
   GO_DONE = 1;           // start conversion
     while(GO_DONE);           // wait for conversion
     ret =  (ADRESH & 0x3) << 8;     // get
     ret +=   ADRESL;           // result
   return ret;
   }
 
Last edited:
most servo's wont do 360, they have a mechanical stop inside of them or they would be a motor and not realy a servo????? try shorter or longer pulses to get it to go the other way. ihave totally forgotten servo stuff :( i did loads with servo's last year
 
The servo itself has the limitations.... I have two servo motors in front of me... One is 180 degrees.. (well nearly) and the other is 180 degrees.... The 180 device is positional.... The latter is directional... It rotates with a speed proportional to the PWM.. Left <-- 50% --> Right

 
The servo itself has the limitations.... I have two servo motors in front of me... One is 180 degrees.. (well nearly) and the other is 180 degrees.... The 180 device is positional.... The latter is directional... It rotates with a speed proportional to the PWM.. Left <-- 50% --> Right
Please check my code why servo is not working in another direction it rotates at specific PWM duty cycle in one not opposite and middle, why?
 
Forget the ADC for a while. Give the compare register values manually so that you can find the proper range for your servo.
 
You need to look at your CCPR1L register.... IT CANNOT EXCEED 39..... PR2 is your maximum value

If PR2 is 39 then you must use the two lower bits in the CCP1CON reg and scale your ADC input to suit 0 to 156.
so 78 will be your 50% point... Anything below 78 will be one direction, 0 being fully on.... Anything above 78 will be the other direction with 155 fully on...

So
Code:
ADC_reading /= 6; // should be 6.6 so to get the full adc swing use floats.
CCP1CON |= (ADC_reading & 3) <<4; // Bits 1 and 2
CCPR1L = ADC_reading >>2; //  Bits 3 to 6

This way CCPR1L will not hold more than 39..
 
You need to look at your CCPR1L register.... IT CANNOT EXCEED 39..... PR2 is your maximum value

If PR2 is 39 then you must use the two lower bits in the CCP1CON reg and scale your ADC input to suit 0 to 156.
so 78 will be your 50% point... Anything below 78 will be one direction, 0 being fully on.... Anything above 78 will be the other direction with 155 fully on...
That mean PR2 is also compared for PWM CCP1L register and what is this?
ADC_reading /= 6; / here?

CCP1CON |= (ADC_reading & 3) <<4; // Bits 1 and 2

CCPR1L = ADC_reading >>2; // Bits 3 to 6


 
Last edited:
For a start.. I made a small mistake.... Your maximum value is 159 so your MID position will be 79... not 78.

Look at the datasheet. When PR2 = 39 that is "100111" in binary so in order to use the full 8 bits we use the two lower bits in the CCP1CON register..

10011111 so your maximum count is 159 ( You cannot exceed this or the PWM will just be ON..

we can put 39 in the CCP1RL and 3 in the CCP1CON bits 4 and 5.. For your max PWM .
If we put 18 in the CCP1RL and 3 in the CCP1CON bits 4 and 5. For your midPWM position.

The three lines of code I gave you were to trim the ADC to the maximum allowed by the CCP1RL and CCP1CON registers.... 1023 / 6.4 = 159 .... This takes care of the ADC to PWM difference

The other two lines place the correct values in the two PWM registers....
 
Is this fine now??
But this is also not working....

Code:
#include <htc.h>
__CONFIG(LVP_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
#define _XTAL_FREQ 20000000
int ReadADC();
void main()
    {
unsigned long number=0;  
    TRISB=0X00;
TRISA = 0xff ;
    ADCON1=0b10000000;
    ADCON0=0b10000001;//000 = channel 0, (RA0/AN0)
    ADIF=0;
ADIE=1;
    PEIE=1;
    TRISC = 0 ;
    PR2 = 39 ;
    T2CON = 0b00000101;
    CCP1CON = 0b00111100;                
    
    while(1)
        {
number = ReadADC(0);
number /= 6;
CCP1CON |= (number & 3) <<4; // Bits 1 and 2

CCPR1L = number >>2; // Bits 3 to 6
CCPR1L=number;


}

    }
int ReadADC(void)
    {
    int ret = 0;
    __delay_ms(20);
    GO_DONE = 1;                    // start conversion
      while(GO_DONE);                    // wait for conversion
      ret =  (ADRESH & 0x3) << 8;        // get
      ret +=    ADRESL;                    // result
    return ret;
    }
 
Last edited:
Code:
number = ReadADC(0);
number /= 6;
CCP1CON |= (number & 3) <<4; // Bits 1 and 2

CCPR1L = number >>2; // Bits 3 to 8
//....CCPR1L=number;.... No Incorrect.. You already stored the correct value above.
 
Hi again,

The Servo is rotating in clockwise when ADC is @ Nearly 0v only not counter clockwise and middle also..?
and giving a sound tiiiiiiiii
 
Ok, i have tested without ADC...it is only in clockwise only, why?




Code:
TRISC = 0 ;

  PR2 = 255 ;

  T2CON = 0b00000101;

  CCP1CON = 0b00111100; 

 

  while(1)

  {




CCPR1L=250;// from ~40 to 250
 
That impressed you? I think I'm done with ETO... let the Indians take over with all the lazy nonsense.
Common Mister t...pls guide me ..i have used without ADC also it is working in one direction only.
 
It is working fine with software pwm..
Code:
while(1){
RC1=1;
unsigned int i;
//Move Anti Clockwise direction
for(i=1;i<=100; i++){
RC2=1;

__delay_us(1500); //at centre
RC2=0; 
__delay_ms(20);

}
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top