PDA

View Full Version : How to make HPWM slower with 16F887?



keithv
- 28th June 2016, 01:07
I want to use an MCU to make an LED get brighter and dimmer (not just blink on and off). Specifically, I want to be able to control the LED in an optocoupler to make various sound effects from a synth module (tremolo, phase shifting, vibrato, and such), so I need it to go a lot slower than the 1221Hz that the 20MHz oscillator of the 16F887 is capable of. I'm not opposed to using an external 4MHz oscillator, but 245Hz is still too fast. Ideally, I'd like to get it to go as slow as 3 or 4 seconds to complete a duty cycle. I've been searching previous posts and it sounds like I need to use an interrupt on TMR1, but I have no idea how to do that.



Dutycycle VAR BYTE
Frequency VAR BYTE


Frequency=1221


main:
For Dutycycle = 255 to 0 Step -1
hpwm 1,Dutycycle,Frequency
Next
for Dutycycle = 0 to 255 step 1
hpwm 1,Dutycycle,Frequency
next
GOTO main


This is what I've got so far. At this point I have to change the code to change the cycle variable. Ideally, I'd use a pot or a button, but I need to get it to be able to go slower than 1221Hz first. Where do I go from here?

HenrikOlsson
- 28th June 2016, 07:50
It's not 100% clear what it is you want to do but I THINK that it's not the PWM frequency you want slower (especially NOT a period of 3-4 seconds because then the LED WILL "blink" and not dim/fade) - it's the time between updating the duty cycle you want to change to increase/decrease the total time it takes for the LED to fade. Again, that's what I THINK you mean - which may be wrong of course.

If you really DO mean you want a PWM period in the region of several seconds then, to be practical, I think you need to do the PWM "manually" using something like a 100Hz interrupt in the background.

Finally, using HPWM like you're doing isn't ideal because it actually "restarts" the CCP module each time the command executes and this creates "glitches" in the outout, This may or may not matter in this case but be aware of it, Another drawback is that it only gives you 8 bit of resolution which can be on the low side for nice smooth LED dimming, especially at the lower end. Again, may or may ot matter.

/Henrik.

keithv
- 28th June 2016, 16:47
It's not 100% clear what it is you want to do but I THINK that it's not the PWM frequency you want slower (especially NOT a period of 3-4 seconds because then the LED WILL "blink" and not dim/fade) - it's the time between updating the duty cycle you want to change to increase/decrease the total time it takes for the LED to fade. Again, that's what I THINK you mean - which may be wrong of course.

If you really DO mean you want a PWM period in the region of several seconds then, to be practical, I think you need to do the PWM "manually" using something like a 100Hz interrupt in the background.

Finally, using HPWM like you're doing isn't ideal because it actually "restarts" the CCP module each time the command executes and this creates "glitches" in the outout, This may or may not matter in this case but be aware of it, Another drawback is that it only gives you 8 bit of resolution which can be on the low side for nice smooth LED dimming, especially at the lower end. Again, may or may ot matter.

/Henrik.

You are correct. I want to make the LED fade from 0% supply voltage to 100% supply voltage and then back down again. Does the 16F887 (or some other PIC) have a the ability to modulate an analog output? Or do I need to use some sort of peripheral device?

HenrikOlsson
- 28th June 2016, 17:28
Then you ARE using the correct peripheral module. I just don't undersand why you think you need (or even WANT) to have the PWM period in the seconds range. The PWM frequency needs to be at least 20-25Hz or you WILL see that the LED is actually blinking.

If you want to slow down the time it takes to fade up/down it is not the PWM frequency you need changing, it's how often you update the dutycycle. Just insert a PAUSE 10 in your FOR-NEXT loop and the fade will take 2.5 seconds.

But again, managing the (E)CCP module "manually" is better for this. There are plenty of examples around for that but by all means, go ahead with HPWM to get started, its drawbacks may not affect you.

/Henrik.

Scampy
- 28th June 2016, 19:07
Ideally, I'd like to get it to go as slow as 3 or 4 seconds to complete a duty cycle.

Henrik, if I read this correctly, I believe that he wants to fade the LED up from 0% to 100% over a 4 second period, rather than have a 4 second frequency, but have to agree the description is a little hard to follow.

Aussie Barry
- 29th June 2016, 00:40
The PWM frequency needs to be at least 20-25Hz or you WILL see that the LED is actually blinking.


Hi Henrik,

I agree with your comment however it should be noted that a lot of people can still see the LED blinking at these rates. In fact, a small percentage of the population can still see LEDs blinking at 100Hz and higher!

Cheers
Barry

keithv
- 29th June 2016, 17:57
Henrik, if I read this correctly, I believe that he wants to fade the LED up from 0% to 100% over a 4 second period, rather than have a 4 second frequency, but have to agree the description is a little hard to follow.

Right. I want to make the LED slowly and very smoothly get brighter and dimmer. I do not want it to blink on and off. If there is a better way to do this than PWM or HPWM then please tell me.

HenrikOlsson
- 30th June 2016, 06:05
Using a PIC there's no better way than using the (E)CCP module in PWM-mode - no.

Using the HPWM command to "drive" the (E)CCP module in PWM-mode may not be ideal as have been described but it will work as a starting point. If you want to drive the ECCP module manually there's another thread active right now which discusses just that and there's a lot of info burried in the forum.

And, as have been said a couple of times now, you DON'T want to make the PWM output "slower", you want to slow down the rest of the program. It's not the PWM frequency that determines the "dimming speed" it's how often you update the dutycycle.

/Henrik.

Scampy
- 30th June 2016, 08:14
Basically you need a frequency fast enough so that the eye doesn't detect it, and a smooth ramp up / down in duty cycle over a 4 minute period.

The problem is that with just 255 steps between 0% and 100% you will notice the stepping in brightness at low levels, such as when the value is in single figures. For smooth dimming you need 4096 steps. One solution would be to use an PCA9685 chip which has 16 PWM outputs, each with 4096 steps, and is controlled via I2C bus.

richard
- 30th June 2016, 14:27
The problem is that with just 255 steps between 0% and 100% you will notice the stepping in brightness at low levels

most pics have 10 bit pwm and if used the "stepping" effect is negligible , why not to use the 1024 steps


here is a simple demo with the led on portc.5 "stepping" at low levels even when gamma corrected

the led on portc.3 is as smooth as silk



'************************************************* ***************
'* Name : fader.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 6/30/2016 *
'* Version : 1.0 *
'* Notes : pic16f1825 *
'* : *
'************************************************* ***************


#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG


DEFINE OSC 32



goto overpwm

my_pwm:
;100 step 1.35 gamma curve
@ dW 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
@ dW 1, 1, 1, 1, 1, 1, 2, 2, 2, 2
@ dW 2, 2, 2, 2, 2, 3, 3, 3, 3, 3
@ dW 3, 4, 4, 4, 4, 5, 5, 5, 6, 6
@ dW 6, 7, 7, 8, 8, 9, 9, 10, 11, 11
@ dW 12, 13, 14, 15, 16, 17, 18, 20, 21, 23
@ dW 24, 26, 28, 30, 33, 35, 38, 41, 44, 47
@ dW 51, 55, 59, 64, 69, 74, 80, 86, 93,101
@ dW 109,118,128,138,150,162,176,190,206,224
@ dW 243,263,286,310,337,366,398,433,471,511



ASM
;---[Returns the Address of a Label as a Word]------------------------------
GetAddress macro Label, Wout
CHK?RP Wout
movlw low Label ; get low byte
movwf Wout
; movlw High Label ; get high byte MPLAB 8.53 killed high
movlw Label >> 8 ; get high byte
movwf Wout + 1
endm
endasm
overpwm:

OSCCON=$70
ANSELA=0
ANSELC=0
paddress var word
pw var word
pl var byte
pl2 var word
inc var word
t2con=5
TRISA = %111110
TRISC = %11010011 ' set PORTC I/O
led1 var portc.3 ; 10 bit straight pwm
led2 var portc.5 ; 10 bit 100 step gamma corrected pwm


@ GetAddress _my_pwm,_paddress
pl2 =0
pl=100

main:
inc=1
while pl
pl=pl-1
gosub setpwm
pause 50
wend
inc=-1
while pl < 99
pl=pl+1
gosub setpwm
pause 50
wend
goto main

setpwm:
readcode paddress+pl ,pw
CCPR1L = PW>>2;
ccp1con=12|((PW&3)<<4); led2
pl2 =pl2 +inc
if pl2 >1023 then pl2 =0
CCPR2L = Pl2>>2; led1
ccp2con=12|((Pl2&3)<<4);
return

Dave
- 1st July 2016, 14:20
Richard, I can't help but notice your table only goes to 511. That's half of the available pwm pulse width.

richard
- 1st July 2016, 15:01
I can't help but notice your table only goes to 511. That's half of the available pwm pulse width.

that's correct dave.
The point was to demonstrate that its possible to eliminate the visible brightness steps that are most evident at the dimmest fading levels. The steps are quite visible at the lowest 20 or so pulse widths wether its gamma corrected at full 10 bit resolution or linear at 8 bit resolution .
100 steps was all that's necessary to prove the point , it can be done

the missing 10 steps


100
481


101
522


102
568


103
617


104
671


105
729


106
793


107
863


108
940


109
1023

keithv
- 6th July 2016, 00:44
Thanks so much for the help. I'll give this a try.

Art
- 10th July 2016, 04:24
If it helps for a musical instrument you can connect an old AM radio tuning capacitor across one of the crystal capacitors or across the crystal itself,
and bend the note a little. Of course you don’t have programatic control over that manual knob, but you do have infinite resolution over a range.

CuriousOne
- 10th July 2016, 13:05
If you want to do portamento - "sliding notes" using HPWM and Picbasic pro, you should do it with ASM, because, PBP on each HPWM statement, resets and restarts PWM generator, which sounds additional bzzzzzzzz, while doing portamento.

If you really want to go deep into music with PIC, you should try LT8500 IC - this is 48 channel 12 bit PWM generator with fine adjustments - you can have impressive 48 voice polyphony, or say 24 voice with 2 operators per channel, or 12 with 4 operators and so on.

keithv
- 11th July 2016, 18:03
If you want to do portamento - "sliding notes" using HPWM and Picbasic pro, you should do it with ASM, because, PBP on each HPWM statement, resets and restarts PWM generator, which sounds additional bzzzzzzzz, while doing portamento.

If you really want to go deep into music with PIC, you should try LT8500 IC - this is 48 channel 12 bit PWM generator with fine adjustments - you can have impressive 48 voice polyphony, or say 24 voice with 2 operators per channel, or 12 with 4 operators and so on.

That's a good idea. I didn't realize there was such a device. I found the TLC5973 which has only 3 channels, which would suit my needs just fine. Not sure how well it works with PIC, but I'm sure if I look around I'll find something similar that works with SPI or I2C.

HenrikOlsson
- 11th July 2016, 18:47
This thread is confusing. You say you want to fade the intensity of a LED and that you need to control the "fade speed". You confuse "fade speed" with PWM frequency which we've tried to explain has nothing to do with it. Then comes the ideas of using external chips, and not that the LT8500 isn't a cool chip (thanks for pointing it out!) and totally capable of dimming a LED but why on earth would you use a $6, 48 channel PWM chip in an "impossible" to breadboard 56pin QFN package, when the CCP module in the PIC you've already got is totally capable of doing what oyu want as long as you can live with 10bit resolution.

If 12bit is really needed then the TCL5973 is much more suitable. Or you can get a PIC capable of higher resolution PWM, like the 12F1571 which will do up to 16bit resolution on up to 3 channels. At 16bits though I think the frequency is getting on the low side but at 12bits you should be totally workable. Nope, HPWM won't work with it.

/Henrik.

CuriousOne
- 12th July 2016, 21:19
PWM frequency, not duty cycle, has do something with fading smoothness - lower the frequency, higher the smoothness is, but flicker is more noticeable. With higher frequency, flicker is almost gone, but fading will be more ugly.

HenrikOlsson
- 12th July 2016, 21:48
Yes with the smoothness (ie the resolution or number of available dutycycles) but not with the TIME it takes to fade the LED*
You can get a fairly high (certainly high enough to not notice any flickering) while maintaining full (10bit) resolution of the CCP module. Going below that point gives you nothing in terms of smoothness.

Of course, if have a fixed delay of 10ms between duty cycles updates and then change the frequency enough to get from 8 to 10bits without changing the delay it WILL take longer to to do a full fade but THAT's pretty obvious.

/Henrik.