2

I'm trying to control a Servo Motor with a PIC18f4550, but before buying one, I'm trying to simulate it on Proteus ISIS, but I'm getting some inconsistencies when setting the angle.

I've tried using a 20ms period and 1ms, 1.167ms, 1.333ms, 1.5ms, 1.667ms or 1.833ms duty cycle and it results in a -69.8° Angle on Proteus MOTOR-PWMSERVO, but using a 2ms duty cycle results in a full 90.0° Angle

#define CONTROL             PORTCbits.RC0
#define BUTTON              PORTCbits.RC1


const Ang_Neg90 =               1.0;
const Ang_Neg60 =               1.167;
const Ang_Neg30 =               1.333;
const Ang_0 =                   1.5;
const Ang_30 =                  1.667;
const Ang_60 =                  1.833;
const Ang_90 =                  2.00;
// ------------------------------------------------- //

void ServoPosition (unsigned float Angle) {
    CONTROL = 1;
    Delay_ms(Angle);
    CONTROL = 0;
    Delay_ms(20 - Angle);
    }
void main(){
while(1){
    ServoPosition(Ang_0);
        if (BUTTON == 1){
            break;
        while(1){
                ServoPosition(Ang_90);
             }
        }
    }
}

I want my program to be able to go from 0 degrees to 90 degrees, but all I'm getting is -69.8 to 90. Any ideas of what I'm getting wrong?

Mike
  • 4,041
  • 6
  • 20
  • 37
  • You want to be able to go from 0 to 90 degrees. Is that a typo? Do you mean the full -90 to 90 range for the servo? – Doug Richardson Sep 01 '19 at 03:15
  • Also, you have an `unsigned float` for `Angle`, which is not valid C. Does this compile for you? – Doug Richardson Sep 01 '19 at 03:18
  • I would also like to see the `Delay_ms` implementation or documentation if you have it. – Doug Richardson Sep 01 '19 at 03:18
  • 1
    As @Mike pointed out in his answer, your const are integers. Avoid using floating points on PICs, There is nothing wrong in using values from 0 to 255 to represent an angle. i.e; 0 <=> -90°, 255 <=> +90°, 127 <=> 0°. The 0 to 255 range being the range of timer, all you need to do is set the compare register to the angle you want mapped to that 0-255 range. In any case, you should ALWAYS state the type of the variable and constants in your programs, to avoid this type of bugs. – Michaël Roy Sep 07 '19 at 04:44

2 Answers2

2

It's hard to tell without seeing your entire setup, so here's a list of things it might be.

Check Simulated Servo Settings

Make sure it's set to the default values.

Server Default Values

Measure your PWM signal with the Oscilloscope Tool

The Hobby Servo Motor sample shows how to use the oscilloscope tool. Hook the oscilloscope up to your pic18f4550 PWM output and measure it to make sure the duty cycle is correct. You're having problems at the low end (trying to reach 1ms) so I suspect the oscilloscope will show your duty cycle is too long.

If you find that your duty cycles are too long, you can try:

  • Subtracting a fudge value to deal with whatever falloff time is present in the simulation. You might have to use different values when you run on real hardware.
  • Using a dedicated PWM module on the pic18f4550. This is probably the best solution since you can just set the PWM registers (assuming this is how it works... I haven't looked closely at the manual) and then let it control the duty cycle for you.

Oscilloscope

Check Voltages

The battery in the Hobby Server was 6V, but 5V also seemed to work. Lower than that and it began to act strange.

Hobby Servo Motor Schematic

Doug Richardson
  • 10,483
  • 6
  • 51
  • 77
1

The type of your constant is wrong:

const Ang_Neg90 =               1.0;

This is a constant of type int with the value 1.

I guess you mean:

const  float Ang_Neg90 =        1.0;

But anyway: If you use the Microchip built in delay function the argument should be of the type unsigned long and you are working with unsigned float.
Try to define your delay times in us (integer not float values!) and use the function __delay_us(...). And be sure to define _XTAL_FREQ correctly.

And as already mentioned: Please remember there don't exist a type unsigned float. float is always unsigned.

Mike
  • 4,041
  • 6
  • 20
  • 37