PWM output from Raptor stops when pulse parameters changed

I’m using a PWM output from the CPU to send step pulses to a stepper motor controller. (I know that isn’t a sensible long-term approach).
I have a sequencer class running its own thread that controls a sequence of operations. My intention was to change the speed of the motor over the course of the sequence. However, I find that changing the speed causes the PWM output to stop (at zero volts; I’ve observed this with both a logic analyser and a voltmeter, including with the motor inactive). If I run the sequence without changing the speed, all is well.
I’ve tried lots of combinations but, for the moment at least, I’m unable to change the speed without stopping the PWM output altogether. Once the output has ‘stopped’, it seems a full reset is required to start it again.

I’m connecting to the PWM output using a Breadboard_X1. .NetMF 4.2. There are lots of apparently-out-of-date examples for this sort of thing, so to be clear, this is how I initialize the PWM output:


I've tried different pins and minimizing the application, but I've been unable to find a solution.

Anyone know of an explanation?

I should have mentioned: the output stops after a small but random number of speed changes - say between 3 and 15.

You did not mention what board you are using. But, the following is from the release notes for the premium library of the current r4.2 release(not beta).

• Setting PWM frequency will corrupt Duty Cycle. To fix, a user must then set Duty Cycle. See https://netmf.codeplex.com/workitem/1749 for more information.

I thought the best way to make it clear which board I’m using was to put it in the title…

I’m not sure of the relevance of the work item you cited. I’m using Gadgeteer assembly version 2.42 and the Microsoft assemblies are all version 4.2. BUT I’m using Gadgeteer.Interfaces.PWMOutput, not a Microsoft class - is this a wrapper around the MS class? Should I be using Microsoft.SPOT.Hardware.PWM instead? If so, how do I work out which CPU pin is connected to my Gadgeteer socket?

Also, I’ve tried both the Set(int frequency, double dutyCycle) and SetPulse(uint period_ns, uint highTime_ns) methods to vary the frequency. I’ve also tried setting the Active property to false while adjusting the settings - still seeing the failure.

Thanks for the reply!

@ philAtkin - Could you post a small program that reproduces the issue?

Hi John.
My description of this issue may have been misleading, as are its symptoms…

The following fails reliably:

        private void ProgramStarted()
        {
            var pulse = breadBoard_X1.SetupPWMOutput(Gadgeteer.Socket.Pin.Eight);
            for (int i = 1; i <= 10; ++i)
            {
                pulse.Set(i*100, 0.5);
                Thread.Sleep(100);
            }
        }

The [em]way[/em] it fails may be interesting. After rebooting the device (power connection restored or Reset button pressed), the pin goes to 3.5V during initialization, then starts pulsing, then (at some point) drops to zero. Once the failure has occurred, the pin stays at zero volts even if it’s restarted from the debugger. Only a hard reset will restore any sort of function to the PWM pin.

HTH, Phil

Do you have any other boards you can test this on?

No, unfortunately not.
Have you tried to repro there?
Phil

We have been able to reproduce the issue. We’ll let you know when we have more information.

A partial, temporary, workaround: If I use the regular NETMF PWM class and do not start and stop it (changing only the frequency and duty cycle as needed), it lasts much longer until dropping to 0V.

Thanks for looking at this.
Being a ‘newbie’ in this context, I don’t know how to ‘use the regular NETMF PWM class’. Could you provide a code snippet that’s equivalent to my example, please?

Also, could you indicate whether ‘much longer’ means milliseconds, seconds, hours, days…

Thanks, Phil

Something like (you’ll want to find the proper PWMChannel for your use):


using Microsoft.SPOT.Hardware;

var pwm = new PWM(Cpu.PWMChannel.PWM_0, 500, 0.5, false);
pwm.Start();
pwm.Frequency = 501;
pwm.DutyCycle = 0.5;

Just changing those last two properties, and adding 1Hz every 250ms, I am currently at 14,260Hz, so about an hour so far. It may still fail so we are still looking into the issue. Make sure to keep https://netmf.codeplex.com/workitem/1749 in mind when you are changing the frequency and duty cycle.

Sorry - my problem is precisely that I “want to find the proper PWMChannel for [my] use”. How do I find out which channel is equivalent to breadBoard_X1.SetupPWMOutput(Gadgeteer.Socket.Pin.Eight)?

The quickest way in a Gadgeteer context is probably: Gadgeteer.Socket.GetSocket(18, true, null, null).PWM8; That’ll return the PWM channel on pin 8 on socket 18 which is PWMChannel.PWM_1 in this case.

Thanks, but where is the documentation that tells how to do this in general?

We are still working on getting the documentation up for things like that. But for now, you can find that information via the method in code I gave you which makes it more generic or you can look at the actual mainboard source. For the Raptor for example, you can find all the socket definitions here: http://gadgeteer.codeplex.com/SourceControl/latest#Main/Mainboards/GHIElectronics/FEZRaptor/Software/FEZRaptor/FEZRaptor_42/FEZRaptor_42.cs