1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

BoostC Charlieplexed PWM 32

Discussion in 'Microcontrollers' started by Mike - K8LH, Jun 25, 2008.

  1. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike, K8LH.

    I like to know is your project LEDs moving like night rider effect?

    Do you have an idea how to do a knight rider effect on direct IO port without using charliplexing.
     
  2. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    The animation demo' in Main is not really the "night rider" effect. This is what it looks like;

    [embed]http://www.youtube.com/v/AgQTBKcg2D4&hl=en&fs=1[/embed]

    Yes I do.
     
  3. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Wow thats very nice.Thats what I want to do exactly.Thats really nice Mike.

    I need to do the same thing but with direct IO port.You have a long tail.I don't need that much.I'm planing to do with something like 4 brightness level moving from right to left.

    If you have an idea please share with me.I have been working hard with a code but my code is flickering.Thats the problem.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld

    For 4 brightness levels is it ok 64 levels?From Where can I start?
     
  6. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    What do you have now (schematic & code)?
     
  7. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi I have code but its not smoothly functioning.That idea also came one from your past thread :)

    I'll show my code.
     
    Last edited: Feb 17, 2009
  8. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    I'm doing PWM in ISR.I'm using 16F88 4Mhz.8 LEDs are connected to PORTB via resisters thats it.

    Code (text):

    ISR_Enter   ;Context save
            ;interrupt on 256uS

            ;256X64=16384
            ;61Hz PWM frequency
            bcf INTCON,T0IF     ;clear TimerO int flag

    Check_Duty  ;
            movf    Duty,W      ;              
            xorwf   LED0,W      ;Brightness variable               
            skpnz                          
            bcf Shadow,0                   
            movf    Duty,W                     
            xorwf   LED1,W      ;Brightness variable               
            skpnz                      
            bcf Shadow,1               
            movf    Duty,W                     
            xorwf   LED2,W      ;Brightness variable           
            skpnz                          
            bcf Shadow,2
            movf    Duty,W                     
            xorwf   LED3,W      ;Brightness variable               
            skpnz                      
            bcf Shadow,3

            movf    Shadow,W    ;update PORTB      
            movwf   PORTB

            incf    Duty,F      ;update Duty
            btfss   Duty,6      ;64 levels??
            goto    Exit_ISR
            clrf    Duty
            movf    S_Shadow,W  ;pre load the mask LED's   
            movwf   Shadow_B
           
    Exit_ISR    ;restore Context

            retfie
     
    Last edited: Feb 17, 2009
  9. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    You should probably tell us what you mean by "not smoothly functioning".

    When animating LEDs, you will often see some glitchy visual artifacts if you don't sync' the LED updates to your 61 Hz (16 msec) refresh rate. So you might want to limit the LED PWM values to the range of 0..62 and then only update the LED array when the Duty variable == 63.
     
  10. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike. I want to know what’s the secret behind this synchronizing.

    Not smoothness means LEDs are moving with a slight blinking , this not the refresh rate problem my PWM frequency is 61Hz also I changed the PWM frequency to 78Hz.but the problem still occurs.

    I did like you mentioned adjusted 0-62 brightness variables & when it comes 63 I update into PORTB & clear the duty to zero. PWM frequency is 61Hz.

    Same did after adjusting the PWM frequency to 78Hz.updated the PORTB when duty reaches 63 & clear the duty to zero.
     
    Last edited: Mar 12, 2009
  11. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike I have a problem when to shift the next led sequences (I mean the time).

    In the ISR I'm counting 256 (interrupt rate) X 20 = 5120 uS.

    5120 X 10 = 51200mS = 50mS

    So every 50mS I'm setting a flag bit in the ISR.And I'm reading that flag bit in the main & making a shift.

    The problem is when the flag bit sets (50ms) do I need to reload the brightness variables & duty variable to minimize the flicker?
     
  12. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    Hi Suraj,

    It's difficult to help you with your problem without schematic and well commented code.

    Mike
     
  13. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike thanks for your concern.I have attached my code.Can you tell is it ok or what changes do I have to do?What method do you use if you are doing a knight rider on direct I/O port?
     

    Attached Files:

  14. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    Hi Suraj,

    Now I see what you're doin'. Thanks.

    I think your problem is that you're counting pwm "steps" rather than complete "frames" for your LED array update timing. Your update timing delays need to be in increments of your 12.8 msec frame rate which means you can update your LED array with new PWM values only up to the frame rate which is 78.125 times per second.

    I would use duty_cycle == 0 for synchronizing LED array updates as shown in the following example and I think I would use a faster refresh rate to allow finer update intervals. Here's an example ISR using 100 pwm "steps" and 50 usec interrupt intervals for a 200 Hz refresh rate and a 5 msec frame rate;

    Code (text):
    ;
    ;  50 usec (100 cycle) interrupts, approx 50% ISR "overhead"
    ;
    ;  100 pwm "steps", 200 Hz refresh rate, 5 msec frame rate
    ;
            org     0x0004

            radix   dec
    isr
            movwf   w_isr           ; save W-reg                      |B?
            swapf   STATUS,W        ; don't change STATUS bits        |B?
            movwf   s_isr           ; save STATUS reg                 |B?
            clrf    STATUS          ; bank 0                          |B0
            movf    PCLATH,W        ; get PCLATH                      |B0
            movwf   p_isr           ; save PCLATH                     |B0
            clrf    PCLATH          ; page 0                          |B0
    ;
    ;  reload Timer 0 for 50 usec interrupts (8 Mhz, prescaler 1)
    ;  for a 200 Hz refresh rate and a 5 msec frame rate
    ;
            movlw   -100+2          ; 100 500-nsec ticks = 50 usecs   |B0
            addwf   TMR0,F          ; add to free running TMR0 reg    |B0
            bcf     INTCON,TMR0IF   ; clear Timer O interrupt flag    |B0
    ;
    ;  do a 1/100th pwm 'step', 25 cycles (isochronous)
    ;
            movf    led+0,W         ; led0 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led0 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+1,W         ; led1 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led1 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+2,W         ; led2 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led2 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+3,W         ; led3 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led3 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+4,W         ; led4 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led4 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+5,W         ; led5 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led5 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+6,W         ; led6 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led6 => dcy                 |B0
            rrf     shadow,F        ;                                 |B0
            movf    led+7,W         ; led7 pwm value, 0..99           |B0
            subwf   dcy,W           ; C = led7 => dcy                 |B0
            rrf     shadow,W        ; W = led 'step' output           |B0
    ;       xorlw   0xFF            ; for active hi outputs           |B0
            movwf   PORTB           ; update LEDs                     |B0
    ;
    ;  bump duty cycle, 5 cycles (isochronous)
    ;
            incf    dcy,F           ; dcy++, 0..99 inclusive          |B0
            movf    dcy,W           ;                                 |B0
            xorlw   100             ; end of 5 msec frame?            |B0
            skpnz                   ; no, skip, else                  |B0
            clrf    dcy             ; reset duty cycle counter        |B0
    ;
    ;  restore context, 8 cycles (isochronous)
    ;
    isr_xit
            movf    p_isr,W         ;                                 |B0
            movwf   PCLATH          ; restore PCLATH                  |B0
            swapf   s_isr,W         ;                                 |B0
            movwf   STATUS          ; restore STATUS                  |B0
            swapf   w_isr,f         ; don't screw up STATUS           |B0
            swapf   w_isr,W         ; restore WREG                    |B0
            retfie                  ; return from interrupt           |B0
    ;
     
    Now write a macro to help you visualize the patterns you want and use a simple delay subroutine that counts 5 msec frames and returns when duty_cycle == 0 and it's safe to update the LED array without visual artifacts;

    Code (text):
    pos_01  setled  00,00,00,00,99,70,40,20
            movlw   60/5            ;
            call    delay5          ; wait 60 msecs
            setled  00,00,00,99,70,40,20,05
            movlw   60/5            ;
            call    delay5          ; wait 60 msecs
            setled  00,00,99,70,40,20,05,00
            movlw   60/5            ;
            call    delay5          ; wait 60 msecs
            ......

    ;
    ;  delay WREG * 5 msec "frames", returns during step 0
    ;
    delay5
            movwf   x5msec          ; save x5 msec delay value        |B0
    wait0   movf    dcy,W           ; end-of-frame, dcy == 0?         |B0
            bnz     wait0           ; no, branch (wait), else         |B0
            decf    x5msec,F        ; x5 msec timer timed out?        |B0
            skpnz                   ; no, skip, else                  |B0
            return                  ; timed out so return             |B0
    waitx   movf    dcy,W           ; wait for non-zero dcy value     |B0
            bnz     wait0           ; branch, wait for next frame     |B0
            goto    waitx           ; else, wait for non-zero dcy     |B0
    ;
     
     
    Last edited: Mar 24, 2009
  15. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike, K8LH what a code thats a nice method I'll use your method.

    Thanks for the big support :)
     
  16. Gayan Soyza

    Gayan Soyza Active Member

    Joined:
    Oct 23, 2006
    Messages:
    1,821
    Likes:
    19
    Location:
    Colombo
    I’d clear that “shadow” variable on every interrupt.

    Also I’ll subtract the “dcy” register from “led+X” variables 
     
  17. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    No need to clear the shadow variable when you're shifting 8 new bits into it each interrupt, yes, no?
     
    Last edited: Mar 25, 2009
  18. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike I studied your program its very clever.I have a problem.I'm using 4Mhz not 8Mhz.

    I adjusted your program Is this settings ok?

    XT = 4Mhz
    Interrupts = 100uS
    Levels = 100
    Frame Rate = 10000uS = 10mS
    PWM Frequency = 100Mhz

    Whats the advantage using higher PWM frequency Mike? Is 60 PWM frequency do you recommend?
     
  19. Mike - K8LH

    Mike - K8LH Well-Known Member

    Joined:
    Jan 22, 2005
    Messages:
    3,637
    Likes:
    109
    Location:
    Michigan, USA
    Hi Suraj,

    Those settings look fine and a 100 Hz refresh rate should be fine.

    The only advantage for using a higher refresh rate is that you would be able to update the LED array at shorter intervals. You can update the array at 5 msec intervals with the 200 Hz rate or update the array at 10 msec intervals with the 100 Hz rate.

    Did you test your modified program?

    Mike
     
    Last edited: Mar 25, 2009
  20. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike, K8LH I've completed the code now I have to make it & see.I'll tell you the progress.

    When I extend the pwm levels like (200 levels) the PWM frequency drops down like 50Hz.Is this good?Will it get unsmoother?
     
    Last edited: Mar 25, 2009
  21. Suraj143

    Suraj143 Active Member

    Joined:
    Jan 11, 2007
    Messages:
    1,564
    Likes:
    2
    Location:
    South Mald Isld
    Hi Mike, K8LH last night I checked on a real hardware your code worked perfectly.You need to uncomment that (xorlw 0ffh) after that it worked.I'm really really happy now.Thanks again for the support.

    Can I use the maximum brightness value 100 instead of 99?

    Now everything is ok reloading the LED variables I'm doing with a lengthy way.I like to use your method using a macro.

    Can I use "Setled 00,00,99,66,20,12,04,01" to load the brightnesses?Or do I have to write a macro to load them?(I never used macros)
     

Share This Page