4
votes

I'd like to get Frequency and Duty Cycle of two PWM signals (i.e. PWM inputs) and set them for another one (i.e. PWM output) depending on inputs. These PWM signals have a Duty Cycle of 50%, while their Frequency range is from 1kHz to 20kHz.

I checked the web a bit, and I found the Microsoft IoT Lightning Library (i.e. Bus Providers) from Windows 10 IoT Core. This library seems to be what I need, even with the PWM Consumer example!
However, while I was testing my first example based on PWM Consumer one, I noticed that PWM Controller frequency range is limited from 40Hz to 1kHz. Hence, the first issue: the frequency range seems not supported.
Moreover, while PWM Controller property "ActualFrequency" returns the frequency setted via "SetDesiredFrequencyMethod", PWMPin objects provides only information about current Duty Cycle.

Hence, I googled looking for some answer and I found this question which confuses me even more than the two previous issues.

Do you know if it is possible and how to use MS-IoT Lightning Library to set/get PWM signals from 1kHz to 20kHz on a Raspberry Pi2?

Here, few rows of code from the example:

    public async void Run(IBackgroundTaskInstance taskInstance)
    {
        if (!LightningProvider.IsLightningEnabled)
        {
            // Lightning provider is required for this sample
            return;
        }

        var deferral = taskInstance.GetDeferral();

        // Use the PAC9685 PWM provider, LightningPCA9685PwmControllerProvider
        pwmController = (await PwmController.GetControllersAsync(LightningPwmProvider.GetPwmProvider()))[0];
        motorPin = pwmController.OpenPin(0);
        secondMotorPin = pwmController.OpenPin(1);

        //// To use the software PWM provider, LightningSoftwarePwmControllerProvider, with GPIO pins 5 and 6, 
        //// uncomment the following lines and comment the ones above
        //pwmController = (await PwmController.GetControllersAsync(LightningPwmProvider.GetPwmProvider()))[1];
        //motorPin = pwmController.OpenPin(5);
        //secondMotorPin = pwmController.OpenPin(6);

        pwmController.SetDesiredFrequency(50);
        motorPin.SetActiveDutyCyclePercentage(RestingPulseLegnth);
        motorPin.Start();
        secondMotorPin.SetActiveDutyCyclePercentage(RestingPulseLegnth);
        secondMotorPin.Start();

        timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, TimeSpan.FromMilliseconds(500));
    }

    private void Timer_Tick(ThreadPoolTimer timer)
    {
        iteration++;
        if (iteration % 3 == 0)
        {
            currentPulseLength = ClockwisePulseLength;
            secondPulseLength = CounterClockwisePulseLegnth;
        }
        else if (iteration % 3 == 1)
        {
            currentPulseLength = CounterClockwisePulseLegnth;
            secondPulseLength = ClockwisePulseLength;
        }
        else
        {
            currentPulseLength = 0;
            secondPulseLength = 0;
        }

        double desiredPercentage = currentPulseLength / (1000.0 / pwmController.ActualFrequency);
        motorPin.SetActiveDutyCyclePercentage(desiredPercentage);

        double secondDesiredPercentage = secondPulseLength / (1000.0 / pwmController.ActualFrequency);
        secondMotorPin.SetActiveDutyCyclePercentage(secondDesiredPercentage);
    }

All the best, Lorenzo

2

2 Answers

1
votes

The IoT lightning framework seems to have software limitation on the PWM controller output frequency, see to this file.

Not sure if this will work, but what is worth a shot is make a clone of lightning repository, modify the Max/MinFrequency constants, build the project, and reference it directly in your source project, instead of referencing the nuget package.

I'm looking forward this approach being tested with a scope.

Alternatively, instead of using the Lightning driver, use the default inbox driver, the pwm device driver for which can be found in here, try to see if you can use a higher frequency above 1kHz.

0
votes

Raspberry PI is not a real-time system (it has cache and branch prediction) so it cannot process PWM signals just like that. It just cannot measure microsecond timings accurately when an instruction causes a cache refresh or too many if statements fail their prediction. Microsoft IoT Lightning gives arduino as example which IS real-time.