Duino with FW 2.1.0.60000
I use PWM to control the switching of a MOSFET for a boost converter, and also to manage the charge on a capacitor (via an optocoupler) to vary the output of a voltage regulator. To do this, I keep the pulse width at, say, 30uS, and vary the frequency (I always do it this way). There is also A/D feedback to sample the output voltage so it can be intelligently controlled by varying the frequency.
The problem is that when I set the frequency (controller.SetDesiredFrequency()), and also adjust the pulse width to keep it at 30uS (pwm.SetActiveDutyCyclePercentage()), the PWM outputs an additional pulse. This causes a noticeable jump in the voltage (see picture), and the voltage feedback value is inaccurate (unless I delay a while, which slows everything down).
Hereās a scope shot which shows the problem.
Has anyone else noticed this? I could not find anything about it in the forums. I can do a workaround, but it would be far better to have a smooth transition.
Below this is the test code Iām using. The Duino buttons control the frequency. (This is only test code, without the feedback. The final version will be rather more sophisticated.)
static void pwmtest()
{
var gpio = GpioController.GetDefault();
var appButton = gpio.OpenPin(SC20100.GpioPin.PB7);
appButton.SetDriveMode(GpioPinDriveMode.InputPullUp);
var ldrButton = gpio.OpenPin(SC20100.GpioPin.PE3);
ldrButton.SetDriveMode(GpioPinDriveMode.InputPullUp);
var controller = PwmController.FromName(SC20100.Timer.Pwm.Controller3.Id);
var pwm = controller.OpenChannel(SC20100.Timer.Pwm.Controller3.PB0);
// keep pulse width fixed and vary the frequency to control the voltage
double step = 1;
double freq = 1;
double pulseWidth = 30e-6; // 30 microseconds fixed pulse width
double period = 1 / freq;
double dutyCyclePercentage = pulseWidth / period;
controller.SetDesiredFrequency(freq);
pwm.SetActiveDutyCyclePercentage(dutyCyclePercentage);
pwm.Start();
double change = 1;
while (true) {
if (appButton.Read() == GpioPinValue.Low) {
if (freq >= 80000)
continue;
change = step;
}
if (ldrButton.Read() == GpioPinValue.Low) {
if (freq <= 0)
continue;
change = -step;
}
if (change != 0) {
freq += change;
change = 0;
if (freq <= 0) {
pwm.SetActiveDutyCyclePercentage(0);
}
else {
// keep the pulse width the same for all frequencies
period = 1 / freq;
dutyCyclePercentage = pulseWidth / period;
Debug.Assert(dutyCyclePercentage <= 1.0);
controller.SetDesiredFrequency(freq);
pwm.SetActiveDutyCyclePercentage(dutyCyclePercentage);
Debug.WriteLine(freq.ToString());
}
}
Thread.Sleep(20);
}
}