lancaster-university / microbit-dal

http://lancaster-university.github.io/microbit-docs
Other
254 stars 130 forks source link

c++ Servo methods don't work #368

Closed rhubarbdog closed 5 years ago

rhubarbdog commented 6 years ago

hi, I'm new to c++ on the microbit and i am following documentation on this web site.

this program doesn't work, it compiles, but my servo does nothing. I don't have a logic analyser, but the LED i put in the circuit looks to be at full brightness implying no PWM

#include "MicroBit.h"
// compiles but doesn't work
MicroBit uBit;

int main()
{
    int val=1;
    uBit.init();

    uBit.io.P1.setServoPulseUs(20000); // 50hz

    while (1) {
        uBit.io.P0.setDigitalValue(val);
        val=!val;

        uBit.io.P1.setServoValue(0); // this is min

        uBit.sleep(1000);

        uBit.io.P1.setServoValue(200,200); // this is max 200 degree range on my servo
        // or with a 3rd parameter to set the centre default 1.5ms

        uBit.sleep(1000);

        uBit.io.P1.setServoValue(100,200);

        uBit.sleep(1000);
    } 

    release_fiber();
}

where as with the same external circuit I can operate my servo with this code and the LED is at differing brightness for each servo position

#include "MicroBit.h"

MicroBit uBit;

const int Max_Period=2000;
const int Min_Period=500;

int angle(int dwell)
{
    int period;
    int duty;

    period = Max_Period - Min_Period;
    period = Min_Period + (period * dwell / 180);

    duty=((period * 1023) / 20000);

//    printf("%3d , %d \r\n",dwell,duty);

    return duty;
}

int main()
{
    int val=1;
    uBit.init();

    uBit.io.P1.setAnalogValue(0);    
    uBit.io.P1.setAnalogPeriodUs(20000); // 50hz

    while (1) {
        uBit.io.P0.setDigitalValue(val);
        val=!val;

        uBit.io.P1.setAnalogValue(angle(0)); 

        uBit.sleep(1000);

        uBit.io.P1.setAnalogValue(angle(180)); 

        uBit.sleep(1000);

        uBit.io.P1.setAnalogValue(angle(90));

        uBit.sleep(1000);
    } 

    release_fiber();
}
martinwork commented 6 years ago

The second parameter to setServoValue (range) is in microseconds and should be approximately 2000 not 200. You can leave it off to get the default 2000.

setServoValue does a similar job to the angle() function in the second program, but using a center and range rather than min and max. It calls setServoPulseUs to set the pulse in microseconds (called period in the angle function). setServoPulseUs takes care of setting the analogue period to 20ms. An angle value of 200 sent to setServoValue will get clipped to 180.

rhubarbdog commented 6 years ago

i adjusted the first program and removed the second parameter to setServoValue it still wasn't working. i now have it working, the issue is the external circuit setServoValue uses the first circuit where as the setAnalogValue method uses the second circuit. servo01 servo02

finneyj commented 5 years ago

thanks for reporting back @rhubarbdog.

Closing this issue now as it turned out to be a problem with your circuit and not the software.