Curious PWM/DAC output voltage stability issue - Page 1
Forum section: electronics / projects

author: AlfBaz
author_rank: Super Contributor
timestamp: April 17, 2013, 03:39:38 pm
content: Ok, so I'm playing around with the PWM module on a PIC18f4550. I'm running the PWM output through a 2 pole passive low pass filter.The code on the pic was bare-bones, setup the PWM with the max frequency of around 39kHz to maintain 10bit PWM resolution and an initial duty cycle of around 50% (512)The while loop just had a function call that wrote a variable into the duty cycle register CCPR1L (8bits) and the other 2 bits into CCP1CON bits 4 and 5.The reason I had it continuously writing the duty cycle was so that I could change the variables value with MPLAB's Data Monitor Control Interface (DMCI)I'd the drag the slider, dmci paused the mcu, wrote the new value to the variable and continued execution and a new voltage would appear on the output.The voltage stability seemed pretty good, only jumping around by no more than 10uVI then changed the code so that I could alter the PWM output with a couple of push buttons on the dev board, only this time it would only update the duty cycle registers if a button was pressed and now the voltage stability was an order of magnitude worse, nearly 2mV.Kept the button code but made it update the duty cycle registers on every pass and the variation was 200mVI tried all three permutations several times and the results are repeatable. It seems that the quicker you update the duty cycle regs the more stable the output voltage... Any Ideas as to what's going on here?

author: Rerouter
author_rank: Super Contributor
timestamp: April 18, 2013, 10:34:55 am
content: i would imagine its coming down to what the compiler is doing, what i did on an arduino (its all c) was to have the button in an interrupt, that updated a variable, had an if statement checking that the variable was not 0, and then doing what ever your buttons needed to do, be it adding the button variable to some other, this was i lost only a few 10's of cycles checking the statement, and my loop kept on flying around like normal otherwise,

author: AlfBaz
author_rank: Super Contributor
timestamp: April 18, 2013, 01:38:11 pm
content: Thanks for the reply.That's the first thing I thought to, something in the code but the PWM module operates independently from anything the cpu is doing. Here's a simplified explanation of how it works. There are two registers and a timer. The timer increments and a comparator compares the timer value to the 2 regs. One is the duty cycle reg, when the timer equals the value in it, it sets the PWM output high, when the timer equals the second register (period reg) the output is cleared and the timer reset. This is all done in hardware.It appears that any other code running causes a greater variance in the output voltage. I've moved on to do other parts of the project but want to get back to have a closer look at this.First thing I need to do is work out how the meter is getting and determining the voltage its displaying. The scope shows 300mV of ripple/noise, so seeing the meter with a stable reading down to 10's of microvolts makes me think frequency content in the noise is changing or becoming more random when executing variable code as opposed to 3 or four instructions in a loop.When I get a chance I'll scope the current going into the mcu and see what differences there are under the three scenarios I pointed out.

author: kt315
author_rank: Regular Contributor
timestamp: April 19, 2013, 12:34:57 am
content: I would imagine it depends on what mcu is doing, in particular on its power consumption, which might affect it is VCC voltage, hence the output.If you have not seen this thread, you might find the second part of it interesting:https://www.eevblog.com/forum/projects/general-purpose-power-supply-design-7488/There is some extensive discussion from the big boys on the subject.

author: AlfBaz
author_rank: Super Contributor
timestamp: April 19, 2013, 02:32:59 am
content: Thanks!Will have a look now

author: ve7xen
author_rank: Super Contributor
timestamp: April 19, 2013, 03:10:11 am
content: If you're using the internal RC oscillator (if this chip has one) I suspect it will be very unstable with Vcc. Changing processor activity would change the instantaneous frequency throughout the PWM cycle, which would affect your (absolute) duty cycle. In addition to the output Vcc 'reference' voltage.You could probably use a P-channel MOSFET (or an analogue switch) driven from the PWM output as a driver, possibly connected to a separately regulated or precision reference supply so the internal MCU Vcc fluctuations don't affect the output much. You'll need a stable clock either way though.

author: amspire
author_rank: Super Contributor
timestamp: April 19, 2013, 05:43:14 am
content: Quote from: ve7xen on April 19, 2013, 03:10:11 amBoth these are good ideas. With the Atmega chip, using the internal oscillator or an external crystal in lower power mode did coarse enough modulation on the clock timing to effect the PWM accuracy.Also driving the PWM via another cmos chip - perhaps a 74HC series gate or something faster attached to a very regulated supply or even reference chip output greatly improves the accuracy. I haven't checked the PIC pwm, but the error on the Atmega PWM edges is less then 1nS with the clock in high power mode, and the PWM output is extremely accurate.

author: AlfBaz
author_rank: Super Contributor
timestamp: April 19, 2013, 01:47:29 pm
content: I'm not entirely sure how to go about measuring these edge variations. Was thinking maybe turning persistence on and seeing how thick the edges are following the trigger edgeIt has an external 20MHz crystal oscillator. Internally I have it configured so that it gets divided down to 4MHz which then feeds a 96MHz PLL which is then divided down to 48MHz (48MHz is meant for the USB module which I'm not using at the moment). Had a look at the specs for the PLL and it says its jitter is from -0.25% to +0.25%.Have I got this right... (Ignoring other forms of attenuation) if we take say a 20us period with a 50% duty cycle(10us) with a 5V reference then we get 2.5V out.If the period were to be off by .25% (0.05us) with the on pulse staying at 10us then (10u/19.95u)*5V=2.506V. That's a 6mV variation, so a worse case jitter related variance would be 12mV.As for buffering the PWM output I was more inclined to pick something with slower rise times. The pic's output has rise/fall time of around 10ns.At the moment I'm running some jumper wire from the dev board to a bread board and getting over/under shoots of around a volt. I have managed to dampen them a little but was wondering would reducing the rise/fall time also reduce the over/under shoot?

author: ve7xen
author_rank: Super Contributor
timestamp: April 19, 2013, 07:09:21 pm
content: Quote from: AlfBaz on April 19, 2013, 01:47:29 pmShould work well as long as your PWM setting is constant. I'd keep all your code except the line that actually sets the duty cycle register and set for a sensible duty cycle you can use to measure this way.QuoteThis seems like it's fairly likely to be unstable on the short term, especially if you're using an internal oscillator with external crystal. I'd try hooking up an external clock from a function generator or such and disable the PLL and see if your output improves. I suspect it will, though it's possible your error is dominated by the supply voltage change itself right now.QuoteLooks about right to me.QuoteI think the goal of fast rise times is to reduce the influence of rise time on the output accuracy. I suspect rise time varies a bit with voltage/temp so the faster the rise time, the less those effects will have an influence on the final output. Remember ideal PWM has an instantaneous change from 0 to V+, so any slew time introduces error. Variable slew time introduces variable errors. And the longer you're slewing, the more error you have to deal with. It will produce a constant offset you can calibrate out because it occurs exactly once per cycle, but variability over time/temp/voltage would affect your calibration. I'm not so sure about over/undershoot but I suspect the implications are similar to those for rise/fall time.The main reason of using an external buffer for the PWM though is so you can have a separate supply for the PWM high level that is more stable than what you can get out of the microcontroller. Use a precision reference and you can generate arbitrary voltages with good absolute accuracy. That wouldn't be possible if using the micro's outputs directly.

author: AlfBaz
author_rank: Super Contributor
timestamp: April 20, 2013, 09:54:22 am
content: Thanks for the comments ve7xenThis project is going to need some A2D channels and I want some accuracy in the readings as they will be feedback for the PWM outputs. As such I will implement a decent voltage reference, I have a couple of brand new LM399's that have been sitting around for years and plan to utilise one of them. I hadn't thought to use this ref voltage as the supply for the PWM module but I will now, thanksAs for the rise times, I can't help but think they're giving me "signal integrity" issues... I'm getting two rather large "bumps" in my final DC voltage that coincide with the PWM transitions and so far have only been able to diminish them but I would like to get rid of them altogether.I haven't studied or given this a great deal of thought just yet but my initial thoughts are that the faster the rise time the greater the drive strength (or lower dynamic impedance) which means it's more capable of driving capacitive loads (such as me trying to filter it)... This problem may disappear or at least be easier to deal with once I move away from the setup I have at the moment with a dev board sending the pwm signal through the board with plenty of stubs (different board options),through a header, and a long bit of wire plugged into a bread board.

author: amspire
author_rank: Super Contributor
timestamp: April 20, 2013, 01:16:18 pm
content: The fact your circuit includes a PLL adds another instability factor. My biggest concern is that the VCO in the PLL can be modulated slightly by digital transitions on the micro pins. This can particularly be so if the micro is doing other tasks at the same time as the PWM. One way to get an idea of the jitter is to use a delayed trigger on the scope with a fixed PWM output. Trigger of a rising edge and look at the jitter on a rising edge after a delay of, say, 10 PWM cycles. More if your scope can do it.The rising and falling edges should be fairly fast - probably 10nS is good. Make sure the resistor on the output of the CMOS PWM output device is big compared to the channel resistance of the cmos device. This means at least 10K and perhaps 100K before the first capacitor. This also means that after the two filter stage, you need a very low offset current and low drift opamp. An opamp configered as a unity gain buffer is good, as you can use the opamp output to drive a guard ring around the non-inverting input, the filter resistors, and the non-grounded ends of the capacitor terminals.

author: JoeAAI
author_rank: Newbie
timestamp: April 27, 2013, 01:23:17 am
content: I'm working with the same chip now... and just recently had a situation where two timer interrupts occurred at the same time (when the timers aligned) this caused a frequency jitter on an SPI bus... your situation makes me wonder if your buttons are using input interrupts and if this is causing a slight pause in your PWM frequency... I would expect this would be visible on a scope of your PWM output if so.

author: AlfBaz
author_rank: Super Contributor
timestamp: April 27, 2013, 02:16:43 am
content: Hi Joe,I've left that for a moment and am messing around with a stable reference voltage to pulse width modulate and use as the adc's ref.I didn't use interrupts for the buttons, I was just polling them and the inputs were on a different port to the PWM output just to make sure there was no interference during the Read Modify Write cycle.I was working on the assumption that the PWM module, and possibly all other timer based modules worked independently to the cpu core. So far I have yet to find information to contradict this assumption.As pointed out by amspire and ve7xen, there were several problems with my quick test. Core activity could be causing fluctuations in internal voltages due to more current switching activity whilst the cpu is carrying out operations, effecting the VCO. The jitter I managed to measure turned out to be about 2-3ns but the noise and ripple on the voltage ceiling for the PWM was pretty terrible as the PWM output was being used without buffering.Also there was massive overshoot on both rising and falling transitions due to the layout of the dev board I'm using. Parallel termination at the receiver/buffer was not working because the current consumption required for it to be effective was to high so I will employ series termination at the pins output by cutting the trace and soldering a resistor at the PWM pin.I'll post updates as if I get it right