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?
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).
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.
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.
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…
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.