How to make HPWM slower with 16F887?


Closed Thread
Results 1 to 19 of 19
  1. #1

    Default How to make HPWM slower with 16F887?

    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.

    Code:
    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?

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Quote Originally Posted by HenrikOlsson View Post
    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?

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  5. #5
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Quote Originally Posted by keithv View Post
    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.

  6. #6
    Join Date
    Jan 2011
    Location
    Sydney, Australia
    Posts
    166


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Quote Originally Posted by HenrikOlsson View Post
    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

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Quote Originally Posted by Scampy View Post
    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.

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  9. #9
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  10. #10
    Join Date
    May 2013
    Location
    australia
    Posts
    2,386


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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


    Code:
    '****************************************************************
    '*  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
    Warning I'm not a teacher

  11. #11
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Richard, I can't help but notice your table only goes to 511. That's half of the available pwm pulse width.
    Dave Purola,
    N8NTA
    EN82fn

  12. #12
    Join Date
    May 2013
    Location
    australia
    Posts
    2,386


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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
    Warning I'm not a teacher

  13. #13


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Thanks so much for the help. I'll give this a try.

  14. #14
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  15. #15
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  16. #16


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    Quote Originally Posted by CuriousOne View Post
    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.

  17. #17
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  18. #18
    Join Date
    Feb 2013
    Posts
    1,078


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

  19. #19
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: How to make HPWM slower with 16F887?

    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.

Similar Threads

  1. Can't make RA1 a digital Input on (10 out of 20) 16F887.
    By paulgrut in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 11th October 2013, 06:53
  2. USB HID is slower than often using PIC18f2550
    By Ahmadabuomar in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 16th November 2010, 14:05
  3. Mibam at 20mhz runs slower than at 4 mhz
    By Homerclese in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 31st October 2010, 18:41
  4. Code running 19 times slower than intended
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 15th April 2010, 12:20
  5. Servo Slower?
    By actionplus in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 4th September 2004, 13:56

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts