PWM current sink capability?

rq3

Senior Member
On a 20M2 Picaxe, why does 0% duty cycle PWM (on pin C.5) not sink as much current as the same pin configured as "low C.5"?

Rip
 

hippy

Technical Support
Staff member
It is not clear how you mean but if you are using "PWM" rather than "PWMOUT" that sets the pin as input when the command completes.
 

rq3

Senior Member
It is not clear how you mean but if you are using "PWM" rather than "PWMOUT" that sets the pin as input when the command completes.
Thanks, hippy. I'm using pwmout. Another quick question? Using the PWM wizard in the latest editor for a 32 KHz, 100% duty cycle output on pin C.5 (chip clock 32 MHz), the result is
"pwmout C.5,249,999", which seems to violate the manual's admonition against using duty cycles greater than 4 times the period?

Rip
 

hippy

Technical Support
Staff member
I think you will have to explain how you mean that pinC.5 doesn't sink as much current using PWMOUT with 0% duty as a LOW C.5 does. Can you explain your set up which determined this, what sort of difference are we talking of ?

The Microchip datasheets don't give full details of the I/O pin interfaces but I would have expected both PWMOUT and normal I/O to go through the same interface drivers; that one would pull the I/O pin down to 0V as much as the other would.

It could be there are some other digital or analogue interfaces enabled in one case but not another but I would not have expected that to have any great or noticeable effect at all.

As for not having duty over four times period that's more a limit on usage. Anything above four times will be the same as four times so not a problem. I believe the actual 100% limit is at four times period plus three which is probably where the 999 comes from.
 

rq3

Senior Member
I think you will have to explain how you mean that pinC.5 doesn't sink as much current using PWMOUT with 0% duty as a LOW C.5 does. Can you explain your set up which determined this, what sort of difference are we talking of ?

The Microchip datasheets don't give full details of the I/O pin interfaces but I would have expected both PWMOUT and normal I/O to go through the same interface drivers; that one would pull the I/O pin down to 0V as much as the other would.

It could be there are some other digital or analogue interfaces enabled in one case but not another but I would not have expected that to have any great or noticeable effect at all.

As for not having duty over four times period that's more a limit on usage. Anything above four times will be the same as four times so not a problem. I believe the actual 100% limit is at four times period plus three which is probably where the 999 comes from.
I have an LED with series resistor. Anode to B.0. Cathode to C.5. If I drive B.0 high, and C.5 low, the LED is distinctly brighter than if I drive C.5 at "pwmout pwmdiv16, C.5, 249, 0" (2 KHz PWM at 0% duty cycle with 32 MHz clock on 20M2).
 

hippy

Technical Support
Staff member
Very odd. I couldn't detect a visible difference in LED brightness when I tested it but a multimeter does show a difference in current drawn through the LED+R. I adjusted the supply voltage to read 10.00mA for HIGH/LOW and using HIGH/PWMOUT that showed 9.98mA, both with HIGH/PWMOUT inside a loop (repeatedly being set ) and set once before entering a do-nothing loop.

The meter is uncalibrated but that suggests a 20uA difference. My first thought was there may be separate, paralleled, pull-down drivers for I/O use and PWMOUT use on the silicon and they are not perfectly matched.

So I tried with the LED+R between +V and C.5, adjusted for 10.00mA for LOW C.5. With PWMOUT no change. So that suggests it's related to the HIGH B.0.

Tried with HIGH B.7 and that changed from 10.00mA with LOW C.5 to 9.99mA with PWMOUT C.5. Around an uncalibrated 10uA drop this time.

That's with things being set outside the do-nothing loop so it is not a result of the program repeatedly updating things, though I believe the firmware does keep internal I/O PORTx and/or TRISx registers updated regularly as recommended by Microchip. The data being re-written won't have changed so it seems to be a feature of the silicon.

It might be worth you undertaking similar tests. A 20uA change would be a far greater percentage if you are running very low current through your LED to start with.
 

BeanieBots

Moderator
Worth putting a 'scope on the output to see if 0% duty really is 0%
Very early 28X2 firmware did not give 100% output for 100% duty!
 

rq3

Senior Member
Worth putting a 'scope on the output to see if 0% duty really is 0%
Very early 28X2 firmware did not give 100% output for 100% duty!
Looks good on the scope with a small routine stepping from 0% to 100% duty cycle.
Experiments continue, along with a close look at the Microchip specs.
Rip
 

rq3

Senior Member
Very odd. I couldn't detect a visible difference in LED brightness when I tested it but a multimeter does show a difference in current drawn through the LED+R. I adjusted the supply voltage to read 10.00mA for HIGH/LOW and using HIGH/PWMOUT that showed 9.98mA, both with HIGH/PWMOUT inside a loop (repeatedly being set ) and set once before entering a do-nothing loop.

The meter is uncalibrated but that suggests a 20uA difference. My first thought was there may be separate, paralleled, pull-down drivers for I/O use and PWMOUT use on the silicon and they are not perfectly matched.

So I tried with the LED+R between +V and C.5, adjusted for 10.00mA for LOW C.5. With PWMOUT no change. So that suggests it's related to the HIGH B.0.

Tried with HIGH B.7 and that changed from 10.00mA with LOW C.5 to 9.99mA with PWMOUT C.5. Around an uncalibrated 10uA drop this time.

That's with things being set outside the do-nothing loop so it is not a result of the program repeatedly updating things, though I believe the firmware does keep internal I/O PORTx and/or TRISx registers updated regularly as recommended by Microchip. The data being re-written won't have changed so it seems to be a feature of the silicon.

It might be worth you undertaking similar tests. A 20uA change would be a far greater percentage if you are running very low current through your LED to start with.
Hippy, is there a list of "blocking commands" for pwmout? My understanding was that pwmout is a silicon "hardware" function, and that it would run continuously in the background once enabled. What I think I'm seeing is that it can be over-ridden (and the duty cycle modified) with things like dirsC and outpinsC?

Rip
 

hippy

Technical Support
Staff member
PWMOUT is a silicon function. Post your test code with details of exactly what it is doing that it shouldn't be doing and we can take a look at that.
 

inglewoodpete

Senior Member
What hippy didn't say is that there are no blocking commands that will stop PWMOut (unless you count the 'Sleep' or 'End' commands).
 

hippy

Technical Support
Staff member
Sorry, missed that bit out!

There are commands which can affect PWMOUT output; reissuing PWMOUT commands, turning PWMOUT off, and there can be changes to the output when the operating frequency is changed, or when the operating frequency drops to 4MHz during some commands which require that speed to operate.

There should not otherwise be anything else which actually blocks the PWMOUT or alters the frequency or duty, and interacting with pins or ports should not (AFAIAA) affect the PWMOUT.

It is however possible there may be some unintended or unexpected interactions we have not witnessed ourselves which no one else has previously experienced or reported.

We really need examples of the code which demonstrates an issue experienced to determine if it is an actual issue, a misunderstanding or something else. That avoids having to waste time checking things which are working as expected and allows us to focus on what might not be working as expected.
 

rq3

Senior Member
PWMOUT is a silicon function. Post your test code with details of exactly what it is doing that it shouldn't be doing and we can take a look at that.
Here you are, hippy, with thanks! The first part (test) works as expected. The second part (led) does not achieve full brightness even when the duty cycle is 0 (maximum brightness).

Code:
#PICAXE20M2                        ;compiler directive
    setfreq m32                    ;set internal clock to 32 MHz
    pwmout pwmdiv16,C.5,249,0        ;set pin C.5 for PWM at 2 KHz with a minimum duty cycle (max brightness)
    pause 1000                    ;pause 0.125 second to settle
    
test:                            ;make label "test" for the LED and PWM brightness autotest routine 
    for w1=990 to 0 step -5            ;assign a range to variable w1 (min to max brightness)
        pwmduty C.5,w1            ;make w1 the PWM duty cycle to increase brightness
    for b0=0 to 9                ;assign a range of 10 outputs as LED drivers
        high b0                ;turn the first LED on
            pause 8            ;pause 1 millisecond
            next b0            ;select the next LED
            next w1            ;select the next duty cycle
    for w1=0 to 990 step 5            ;repeat to dim
        pwmduty C.5,w1
    for b0=0 to 9
        high b0
            pause 8
            next b0
            next w1
        
led:                            ;make label "led" for the auto-brightness control routine
    pwmduty C.5,1023                ;force C.5 high to reverse bias LED for photodiode measurement
    dirsC=%01101011                ;make C.2, C.4, and C.7 inputs to avoid clock noise on C.4
    for s_w1=0 to 31                ;set up for ADC averaging
    readadc10 B.0,s_w2            ;read the LED anode photovoltage at B.0 into word variable s_w2
        s_w3=s_w3+s_w2/2            ;average the two ADC words and re-assign to s_w3
        next s_w1
        s_w3=1022-s_w3 max 990 min 0    ;invert photodiode response and set brightness limits
    pwmduty C.5,s_w3                ;set brightness
                        
angle:                                 ;make label "angle" 
    outpinsB=%00000000            ;turn all PortB pins off                        
    outpinsC=%00000000            ;turn all PortC pins off

led10:
    high C.1
        goto led
 

rq3

Senior Member
It is however possible there may be some unintended or unexpected interactions we have not witnessed ourselves which no one else has previously experienced or reported.
One other odd point. In the "led" section of my code, the "pwmduty C.5, 1023" line is intended to drive the output high. This applies reverse bias to an LED used to sense ambient lighting. The odd point is that any duty cycle of 100% should work, but doesn't. The photodiode response of the LED is wildly different (and noisy, almost random) unless the duty cycle is "over" 100%.

Rip
 

hippy

Technical Support
Staff member
s_w3 = 1022 - s_w3

Not sure that will be doing what is expected when s_w3 is 1023 as it could be.

The bigger problem is that you are using very specific hardware which will not be easy to replicate to verify what results are seen.

It's also not easy to understand what your code is actually doing or attempting to achieve. A circuit might help in that respect.

When you say the photodiode response is not consistent at 100%; what value are you using as 100% ? That could be the issue that 100% is period times four plus three.
 

rq3

Senior Member
s_w3 = 1022 - s_w3

Not sure that will be doing what is expected when s_w3 is 1023 as it could be.

The bigger problem is that you are using very specific hardware which will not be easy to replicate to verify what results are seen.

It's also not easy to understand what your code is actually doing or attempting to achieve. A circuit might help in that respect.

When you say the photodiode response is not consistent at 100%; what value are you using as 100% ? That could be the issue that 100% is period times four plus three.
Theoretically it could, yes, but the ADC value never exceeds 1022 (and no, I don't know why. LED drop?) Feel free to change it, the end result (maximum brightness) will only change by a count of one.

Picaxe20M2.jpg

C.5 is PWM at 2 KHz. Ignore the "test" section of the code, which just makes the display do sexy things. C.5 is then set to 100% duty cycle (C.5 is high, in other words) to reverse bias the LED on B.0. An ADC measurement is then made at B.0 to get the photodiode voltage from the LED. This part works fine. Sertxd of the ADC value from B.0 varies smoothly from dark to bright illumination of the LED on pin B.0.

The ADC value is then used to vary the duty cycle of C.5 while pin C.1 is high. The LED on C.1 should then vary in brightness according to the illumination on the B.0 LED. This is a very old technique, and indeed works very well. BUT, the LED does not get to full brightness (full being defined as no PWM at all, i.e.; pwmoff, C.5 low, and C.1 high).


Per the code, I'm currently using 1023, which is WAY past 100%. I originally used the 100% duty cycle value from the editor wizard. An earlier revision of Editor 6 gave higher values for 100%, which is how I stumbled on this odd effect.
 

hippy

Technical Support
Staff member
BUT, the LED does not get to full brightness (full being defined as no PWM at all, i.e.; pwmoff, C.5 low, and C.1 high).
Is this not simply the original problem, rather than an issue of manipulating 'pin' and 'dir' variables ? Perhaps I'm not following something.

Not reaching full brightness is rather abstract; compared against what to start with, and it could simply be because when you are reverse biasing the photodiode you are not driving the LED, so it won't ever have the full brightness it could have.

In fact, thinking on that, there are no pauses in the loop so the the time the LED is on for is nowhere near 'most of the time', regardless of what the duty is.

There are also some potential issues which relate to how an actual PWM output changes when the duty is changed which may be playing a part in things, especially with a rather slow PWM frequency, but I would say it is the lack of pauses which is the main problem. I don't think there is any inherent problem with the PWM nor with drive capability of pins.
 

BeanieBots

Moderator
Whilst I agree with hippy that it looks as if your code is not doing what you expect, the fact that you say it looks OK on a 'scope suggests otherwise.
If I were in the same position, I would crank the PICAXE clock right back and check again.
It might be that your 'scope did not trigger on a small output glitch or some other reason for missing a time issue rather than a level issue.
Also, I would simplify the code to bare minimum and if possible, reduce the hardware (ideally to a single load resistor + DVM) and try to repeat the issue with a known repeatable configuration.
That way, it will be much easier to get to root cause and others can reproduce the same setup.
 

Technical

Technical Support
Staff member
Within the LED loop you have this:

pwmduty C.5,1023

Therefore the total effective pwmduty within that LED loop as a whole can simply never average to 0, no matter what value s_w3 becomes. In reality this will have the effect of making the LED look different.
 

rq3

Senior Member
!0%

Within the LED loop you have this:

pwmduty C.5,1023

Therefore the total effective pwmduty within that LED loop as a whole can simply never average to 0, no matter what value s_w3 becomes. In reality this will have the effect of making the LED look different.
Technical, thanks for the slap. When I trigger the scope on the "high" pwmduty signal, of course I can now see that I'm effectively modulating my modulation, yielding about 10% rather than 0%. Moving the dimming process out of the measurement loop completely solved the issue. Many thanks!
Rip
 
Top