# PIC16F628A Rotate Left Thru Carry & Loop Around

Discussion in 'Microcontrollers' started by EvilGenius, Sep 25, 2014.

1. ### NorthGuyWell-Known Member

Joined:
Sep 8, 2013
Messages:
1,218
Likes:
206
Location:
Northern Canada
I think I understand what you're doing, although this is an unusual apprach.

Since it doesn't matter in what order values are loaded within the section, you could re-arrange bits so that there would be a similar number of 1s in each value.

For example, instead of b'11111111' and b'00000000' do b'11110000' and b'00001111' or b'10101010' and b'01010101'.

This will produce more even power draw.

2. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
The combined current draw of PortA plus PortB are 200mA. With the shcematics I posted, there are roughly 5mA is alocated to driving each NPN transistor for total of less than 15mA. That leaves 12 other pins among two ports. With resistors of 180 ohms on anodes, the maximum current per each RGB device is 15mA. So 15mA x 12 RGB= 180mA. So total comsumption for 15 pins is just 195mA at maximum peak usage. That is if R,G,B of all 15 modules are turned on at the same time (color white). If we are using R, G, B as 3 primary colors for colorrot then realistically we are using each color 2/3 of the time. Or 2/3 of 15mA x 12 = 120mA average cycle thru each frame. Similarly if we are doing rainbow across 12 channels, on average only two transistors are turned on for total of 10mA. So your total consumption is 120+10mA = 130mA. Way below 200mA chip's maximum operational current. But we are blasing the LED at 33% duty cycle, so your perception of brightness of each LED is close to full brightness.

As for line codes if you look at intensity lines, they are not duplicates within one section. 0000012343210 and also sometimes they are spread out over two ports (A,B). (5 zeros, 7 non-zeros ranging between 1 to 4).

3. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
As I mentioned there are other methods. It will definately confuse you if you go back and forth between the methods. Method2 is that instead of scaning red, green, blue. You do 4 scans from top to bottom with value of intensity for all colors are hit at the same time. Look at last color chart I posted and you see the 4 scans clearly. Your duty cycle drops to 25%. Not bad, but not as bright. Does that really make the code simpler to implement?
Scan1: hits all the peaks at level 4 intensity
Scan2: hits all the points at level 3
Scan3: hits all the points at level 2
Scan4: hits all the points at level 1
--------
Mothod3: Which I was shooting for to do which requires no rotations.
Break the color chart horizontally into 3 sections. 1- from red to green 2- from green to blue 3- from blue to red
Think of the color graph but this time look at the original color graph I posted. You see an x-axis numbers zero to 252 at the bottom and your y-axis (intenity) ranges from o to 84.
Conditional if's 1- x-axis 0 to 84, 2- x-axis 84 to 168, 3- x-axis 168 to 252. Your color formulas (let's say for first section) becomes Yred= 84-x for x= 0 to 84, Ygreen= x, Blue=0
For the next section. Yred=0, Ygreen= 84+(84-x), Yblue= x. and For the final section Yred=x, Ygreen=0, and Yblue= 84+ (168-x). Y-values depict color intensity or number of times each color is called. Your main loop runs x= 252 down to 0, apply each if condition, go to the correct section, run line formular for each color, apply those to R, G, B count in each section.

Last edited: Sep 26, 2014

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

5. ### MosaicWell-Known Member

Joined:
Jun 3, 2010
Messages:
2,568
Likes:
128
Location:
Caribbean

You are driving an LED @ 5mA @ 33% for brightness? Can you share the spec. sheet of the LEDs?

6. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
No Iam driving each LED at 15mA. We are turning one color at a time at 15mA (actually specifically red at 17mA, Green at 14mA, and Blue at 14mA). Build the circuit and you see how bright the LED's are! You are thinking in PWM dimension with low duty cycle. That is the whole concept of this programming. And yes you can do dot correction setup for individual LED either thru hardware or software with a few added program lines to modulate each color at specific count!

7. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
how do you send an email to someone in here. I just took a live video I would like you to see. I don't think I can upload a video directly in here and have to upload it elsewhere and link a URL.

Last edited: Sep 26, 2014
8. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
Here are some photos so you can tell how bright the LED's are! Common anode 5mm RGB frosted lens.

#### Attached Files:

File size:
61.4 KB
Views:
104
File size:
66.7 KB
Views:
98
File size:
64 KB
Views:
115
File size:
61.4 KB
Views:
100
File size:
62.9 KB
Views:
102
File size:
64.6 KB
Views:
105
File size:
65 KB
Views:
98
• ###### IMG_0555.JPG
File size:
63.8 KB
Views:
99
Last edited: Sep 27, 2014
9. ### MosaicWell-Known Member

Joined:
Jun 3, 2010
Messages:
2,568
Likes:
128
Location:
Caribbean
I suppose you could share a dropbox link for larger files.

10. ### Mike - K8LHWell-Known Member

Joined:
Jan 22, 2005
Messages:
3,637
Likes:
109
Location:
Michigan, USA
Thank you for simplifying your "colormorph" code down to a level that I could study.

I have a few concerns about the "colormorph" example. I understand why you need delays in order to slow down the morph but placing your delays in the Output routine affects your minimum PWM duty cycle "step" time and refresh rate. With the delay in your example, a duty cycle "step" is ~79-usecs and 255 of these steps make up a full PWM period of ~20-msecs (50-Hz refresh rate). The reason you experience flicker when you try to increase the delay is because the additional delay increases the PWM period and decreases the refresh rate.

Don't increase "step" time to accomplish your morph delay. Instead, try to implement the shortest "step" time (highest refresh rate) possible and implement your delay by repeating the entire 255 step PWM period at the same color level for the number of times required to achieve your delay. For example, your "colormorph" code uses a ~79 usec step to stretch out the PWM period to ~20 msecs in order to provide a color morph spanning 5 seconds. I believe it would be better to use a ~4-usec duty cycle "step" which results in a ~1024-usec period (~1-kHz) and then simply repeat that PWM period 20 times to achieve your 20-msec delay. In this case, you can maintain any particular color level for 10-msecs, 20-msecs, or 100-msecs, without affecting refresh rate which will remain at ~1-kHz (no flicker).

Code (text):
;
;  untested example
;
radix   dec
Morph
clrf    step            ;
movlw   1               ;
morphit
movwf   duty            ; set duty cycle
movlw   20000/1029      ; display each level for ~20-msecs
movwf   speed           ; (time spent at a single pwm level)
pwmstep
movf    color2,W        ; pwm period ~1029-us (971-Hz)
movwf   PORTA           ;
incf    step,F          ;
decfsz  duty,F          ;
goto    \$-2             ;
movf    color1,W        ;
movwf   PORTA           ;
decf    duty,F          ;
incfsz  step,F          ;
goto    \$-2             ;

decfsz  Speed,F         ;
goto    pwmstep         ;

incfsz  duty,W          ; fully morphed? yes, skip, else
goto    morphit         ; do next duty cycle iteration
return                  ;

A duty cycle "step" of 79-usecs is rather coarse. You may want to experiment with smaller steps. My work with single color LEDs showed remarkable differences in light intensity between steps at the low end when using duty cycle steps as small as 250-nsecs with a 1500-usec period (1/6000 duty cycle steps).

Good luck on your project.

Cheerful regards, Mike

11. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
Thanks Mike. I tested it with your changes and it works. I removed "Speed" from "Output"
If I want to slow the morphing down what number do I change? 20000?
I like to create a variable and bring it to the top of the program so that user can easily change it without diging for it in the code.

12. ### NorthGuyWell-Known Member

Joined:
Sep 8, 2013
Messages:
1,218
Likes:
206
Location:
Northern Canada
Since the "Morph" is using 100% duty and "Rot" only 33%, does Morph look much brighter than the Rot?

13. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
North after Mosaic asked the question yesterday, I looked the brightness of two closely. ColorMorph is visually brighter (If I was to guess about 25% or so). Logic says 1/3 of the modulation would yield 33%. But looking at the ColorRot (pictures above), they don't look like 33% but more like 50% full brightness. At 15mA 33% brightness should be much dimmer, but it is not. I am pretty sure I am not over driving the LED's nor the PIC, because my PIC is cold to the touch and my anodes feed directly from PIC!
It could also have something to do with logaritmic brightness of LED when it reaches above certain duty cycle that difference between 33% and 50% is not significant.

14. ### Mike - K8LHWell-Known Member

Joined:
Jan 22, 2005
Messages:
3,637
Likes:
109
Location:
Michigan, USA
Nice looking PCB. Got any extras?

15. ### NorthGuyWell-Known Member

Joined:
Sep 8, 2013
Messages:
1,218
Likes:
206
Location:
Northern Canada
It's difficult to compare brightness when you cannot look at them at the same time. You can light different LEDs with different duty to see how this affect brightness.

16. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
Homemade. One sided copper. Here is copper and silk. Board is 3 inch round.

File size:
24.4 KB
Views:
100
File size:
30.9 KB
Views:
105
File size:
419.5 KB
Views:
106
File size:
321.4 KB
Views:
104
17. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
I did look at them side by side. I have two boards made for this purpose.
That said I have bought LED's from USA, Canada, and China (majority China), and even same product from same manufacturer could have much variations in colors and brightness. (Different bins)
When I buy LED I buy them in larger numbers and ask the manufacturer to use the same bin. Sometimes I am successful in getting uniform products and sometimes I am not. These batch of RGB and another batch of superflux I bought online were superb. Have you seen the new 15,000 Lumens RGB modules. LOL they are insane!

18. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
Code (text):

list p=16F628A
#include <p16F628A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _LVP_OFF
errorlevel -302 ; supress banksel warning messages during assembly
errorlevel -311 ; supress HIGH operator warning messages during assembly
cblock 0x20
copyPORTA ;Declare variables used in the program
copyPORTB
FrameCount
LoopCount
Color1
Color2
Color3
endc
#define bank0 bcf STATUS,RP0
#define bank1 bsf STATUS,RP0
RESET_VECTOR org 0x000
START
movlw b'00000111' ;Set all ports as outputs
movwf CMCON ;Disable comparators
bank1
clrf TRISA
clrf TRISB
bank0
;-----------------------------------------------------------------------------------
;  Main Program and Subroutines
;-----------------------------------------------------------------------------------
Sequence
call MegaColor
goto Sequence
;---------------------------------------------
MegaColor
movlw b'00010000'
movwf Color1
movlw b'01000000'
movwf Color2
movlw b'10000000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'01000000'
movwf Color2
movlw b'10000000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'01000000'
movwf Color2
movlw b'10000000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'11010000'
movwf Color2
movlw b'10010000'
movwf Color3
call Rainbow
;
movlw b'01010000'
movwf Color1
movlw b'00010000'
movwf Color2
movlw b'01010000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'01010000'
movwf Color2
movlw b'00010000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'01010000'
movwf Color2
movlw b'10010000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'01010000'
movwf Color2
movlw b'01000000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'01000000'
movwf Color2
movlw b'10000000'
movwf Color3
call Rainbow
;
movlw b'10010000'
movwf Color1
movlw b'11010000'
movwf Color2
movlw b'01000000'
movwf Color3
call Rainbow
;
movlw b'10000000'
movwf Color1
movlw b'11010000'
movwf Color2
movlw b'00010000'
movwf Color3
call Rainbow
;
movlw b'00010000'
movwf Color1
movlw b'11010000'
movwf Color2
movlw b'01000000'
movwf Color3
call Rainbow
;
movlw b'01000000'
movwf Color1
movlw b'11010000'
movwf Color2
movlw b'10000000'
movwf Color3
call Rainbow
;
return
;----------------------------------
Rainbow
call Frame1
Return
;--------------------------------------------------------------
Frame1 ;Each section modulates R,G,B
movlw d'160'
movwf FrameCount
FR1 call C1
call Sec1 ;Individual sections are shared by R, G,B calls
call C2
call Sec2
call C3
call Sec3
decfsz FrameCount,F
goto FR1
return
;--------------------------------------------------------------
Sec1
movlw d'100'
movwf LoopCount
loop1
movlw b'00001111' ;Values for Anodes (common) placed in B0-B7 & A0-A3
movwf copyPORTB
movlw b'00001110'
call Output
movlw b'00000111'
movwf copyPORTB
movlw b'00001100'
call Output
movlw b'00000011'
movwf copyPORTB
movlw b'00001000'
call Output
movlw b'00000001'
movwf copyPORTB
movlw b'00000000'
call Output
decfsz LoopCount,F
goto loop1
return
;---------------------------------------------
Sec2
movlw d'100'
movwf LoopCount
loop2
movlw b'11111110'
movwf copyPORTB
movlw b'00000000'
call Output
movlw b'01111100'
movwf copyPORTB
movlw b'00000000'
call Output
movlw b'00111000'
movwf copyPORTB
movlw b'00000000'
call Output
movlw b'00010000'
movwf copyPORTB
movlw b'00000000'
call Output
decfsz LoopCount,F
goto loop2
return
;---------------------------------------------
Sec3
movlw d'100'
movwf LoopCount
loop3
movlw b'11100000'
movwf copyPORTB
movlw b'00001111'
call Output
movlw b'11000000'
movwf copyPORTB
movlw b'00000111'
call Output
movlw b'10000000'
movwf copyPORTB
movlw b'00000011'
call Output
movlw b'00000000'
movwf copyPORTB
movlw b'00000001'
call Output
decfsz LoopCount,F
goto loop3
return
;-----------------------------------------------------------------------------------------
C1
movfw Color1 ;Sets the colors used in 3 chan, R,G,B
movwf copyPORTA ;Individual color for each section is stored
return   ;in copyPORTA and added to anode bits (A0-A3)at "OUTPUT" call
;---------------------------------------------
C2
movfw Color3
movwf copyPORTA
return
;---------------------------------------------
C3
movfw Color2
movwf copyPORTA
return
;---------------------------------------------
Output
addwf copyPORTA,0 ;content of w from SEC# is added to copyPORTA which has color (Ex: 10000000 = Blue)
movwf PORTA ;the result of addition is placed in w and then transfered to PORTA directly
movfw copyPORTB
movwf PORTB
return
;---------------------------------------------
end

Here is the introduction of another code called: A12-Fix3Color
This may help clarify how ColorRot works. Fix3Color: Fix Static 3 colors faded into each other across 12 channels. (Same Circuit Layout, PIC, and Pin-out).
Basically this code is one Frame of ColorRot. Remember 12 Frames made the entire movie (ColorRot) which rotates 12 colors across 12 channels. In this case it is only 1 Frame so there is no movement, yet you have smooth color fading between 3 initial colors given in the begining of the program Fix3Color. Here is how it works:
Sequence: It is just a simple loop to have the program run over and over infinately. This calls the color generation subroutine called MegaColor. In MegaColor, user gives program 3 primary colors. (again you have the same selection of colors to choose from: R, RG, G, GB, B, BR, W, BLK). Colors are placed in 3 holders called C1, C2, C3. Program uses these colors to morph in between. When one complete cycle is completed, program comes back to MegaColor and picks another set of 3 colors and runs the program again. MegaColor calls on main routine called Rainbow. Rainbow calls on the Frame1. Frame1: Consists of 3 main Sections for 3 colors (C1, C2, C3). If primary colors used are Red, Green, Blue, then you have colors of rainbow across 12 channels. What does "call C1" do? It places the first color in copyPORTA (upper 4 bits). 1011-xxxx which is A7,A6, 0, A4-oooo. 4 right bits are used in the program and are set to zero at this point. At a later point we are adding the color to PortA and along with PortB we send them out to Output for display. We are still in the Frame1 subroutine; so we called on the C1 and placed it in Color1 then we tell it to go to Section1. In here data bits for PortB and PortA are set. Remember colors are in upper 4 bits of PortA. So we have 4 lower bits of PortA and 8 bits of PortB to place our data in which drives the anodes of RGB. While A7, A6, A4 sink the Cathodes thru transistors and run RGB. Section1: Consists of 4 sets [of two lines (PortA and PortB addresses) and an Output call]. 4 sets of lines create resolution or brightness of individual pins. Repeat bit 4 times (4 times "1" in each pin on each line) down the text and you have maximum brightness. Each time we give a value to PortA and PortB, we call the Output. We do this so rapidly that program sees the 4 lines as one unit average brightness across 12 channels. Output: Remember we placed our color in upper 4-bit of Color1 (as an example). Now we simply add the color to the individual data for PortA and push it out (data for PortA is read into W before Output call and then added to color in the Output routine). We read the data from PortB and push it out as well and now we have lit the appropriate LED and its associated color.
Another way of looking at it: we scan color1 across 12 channels, then scan color2 across 12 channels, then scan color3 across 12 channels. We do this so rapdily that we see each pin having a specific color mix and intensity. This creates a beautiful and smooth transition.

#### Attached Files:

• ###### 12 CHANNEL RGB COLOR MORPH 12 PORTS.jpg
File size:
59.9 KB
Views:
111
Last edited: Sep 29, 2014
19. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
If you were to flatten out the code and give each pin intensity values of 0-4 then this is what it looks like which mimics the color chart:
Frame1
Sec1 PortA: 0001-3210 PortB: 0000-1234 (Color Red)
Sec2 PortA: 0100-0000 PortB: 1234-3210 (Color Green)
Sec3 PortA: 1000-1234 PortB: 3210-0000 (Color Blue)

You ask why 4 as intensity: Given 3 primary colors, there are 4 steps between each primary color. 3 primary x 4 = 12 colors across 12 RGB.
By setting the numbers of steps moving to the left, each color rises by the same number of steps.
Want to zoom in on a section of the color graph: Choose your 3 colors accordingly.
Let's say we want to zoom in colors between Red to Green. Set your primary colors: C1= Red, C2=Yellow, C3=Green.
Yes with this program you can zoom, fade, strobe, morph, set dot corrections as needed with a few extra lines of code.

Last edited: Sep 28, 2014
20. ### MosaicWell-Known Member

Joined:
Jun 3, 2010
Messages:
2,568
Likes:
128
Location:
Caribbean
Perhaps a flowchart is easier to follow. Reading details doesn't show structure as a flow chart or state diagram.

21. ### EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
323
Likes:
6
Location:
Florida
I don't think flowchart will tell you a lot more than said above. But here it is:

File size:
479.6 KB
Views:
150