Continue to Site

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.

  • 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.

BoostC Charlieplexed PWM 32

Status
Not open for further replies.
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.
 
I like to know is your project LEDs moving like night rider effect?
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]

Do you have an idea how to do a knight rider effect on direct IO port without using charliplexing.
Yes I do.
 
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.
 
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:
I'm doing PWM in ISR.I'm using 16F88 4Mhz.8 LEDs are connected to PORTB via resisters thats it.

Code:
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:
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.
 
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:
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?
 
Hi Suraj,

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

Mike

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?
 

Attachments

  • Knight for Mike to correct.asm
    4 KB · Views: 241
  • Knight Mike.png
    Knight Mike.png
    5.1 KB · Views: 253
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:
;
;  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:
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:
No need to clear the shadow variable when you're shifting 8 new bits into it each interrupt, yes, no?
 
Last edited:
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?
 
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:
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:
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)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top