4

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

Community
  • 1
  • 1
Lorenzo R.
  • 133
  • 9

2 Answers2

1

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.

Jackie
  • 1,962
  • 1
  • 9
  • 13
  • thank you for the BCM driver link! For now, I just resolved my issue by passing to linux and exploiting the [PiGPIO library](http://abyz.co.uk/rpi/pigpio/), daemon, and python interface. Therefore, I was able to read and generate the PWMs from and to an external source. – Lorenzo R. Nov 03 '16 at 08:57
0

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.

Serve Laurijssen
  • 7,989
  • 4
  • 30
  • 69