PIC16F628A Rotate Left Thru Carry & Loop Around

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

1. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
I call peak of triangles resolution. I should be careful how I label them.
Increasing color depth is not the solution of smoothing out the color morphing as it originally appeared. I noticed when I charted all the color bits for 8 bit resolution, I was not gaining anything. I just had to deal with more zeros which means less overall brightness. The key here is to lower the color depth and increase transitions between frames with care taken to modulate fast enough not to get flickering going from one frame to the next.
Which is exactly what I did with a great success. I have lowered the triangle peaks to 3 bit brightness instead of 4 and increased number of frames from 4 to 12. To place 12 colors across 12 channels and loop them around will take 12 frames with 12 transitions with total of 12 sections (3colorsx12frames/3 duplicates). It is awesome looking! I am about to wrap up the code shortly and post. This also improved the color spread between 3 primary colors across 12 channels. Colors are more evenly spread and they are brighter. Now that I discovered how to transition from one frame to the next, I can work on transitioning from one entire entry color set to the next and also shift colors in and out like a shift register. (stand-alone device!)

2. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
I have been reverting back to 4-bit resolution for best results. I mapped the bits one more time for 4 frames, 12 sections. Then I added the bits for Red, Green and Blue individually and then graphed those points. You are not going to believe what I discovered! The 3 sets of triangles converted to 3 sine waves phase shifted by 120 degrees. Sum=Integral so it makes sense that sum of triangles is a sine wave. I am thinking Differentiation and Integration. (method1)
Setting that aside and looking at it from a Trigonometry point of view, the waves are sine waves with center point lifted by 6 points, amplitude of 6 points, and frequency of 1. Phase change each sine by 120 degrees and you have the entire graph mapped. Someone must have already discovered this I am pretty sure. But I have not seen it yet.
Why is this a big deal? Imagine you have a variable called Phi (angle) that goes from 0 to 360 degrees. While angle is changing, you take sine of it (theoratically) multiply it by 6, add 6 to it, and you have your first sine wave. Do the same with the other two sine waves and instead of using Phi, we use Phi+120, and Phi+240, do all these sine waves at the same time.
To recap we are color shifting by an angle (Circular format) and modulating it. (Circular Bit Amplitude Modulation- "CBAM") This will change everything in color mapping. I have to think about this a bit now.

File size:
534.2 KB
Views:
87
3. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
As promised below is the code for ColorRot-3Bit:
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
errorlevel    -305

cblock    0x20
copyPORTA
copyPORTB
FrameCount
LoopCount
Color1
Color2
Color3
Col1
Col2
Col3
endc
#define        bank0    bcf        STATUS,RP0
#define        bank1    bsf        STATUS,RP0
RESET_VECTOR    org        0x000
;--------------------------------------------------------------
Rainbow    macro    Col1,Col2,Col3
movlw    Col1
movwf    Color1
movlw    Col2
movwf    Color2
movlw    Col3
movwf    Color3
call        MainFrames
endm
;--------------------------------------------------------------
START
movlw    b'00000111'            ;Set all ports as outputs
movwf    CMCON                ;Disable comparators
bank1
clrf    TRISA
clrf    TRISB
bank0
;----------------------------------------------------------------------
Sequence
call        MegaColor
goto    Sequence
;----------------------------------------------------------------------
MegaColor
Rainbow    b'00010000',b'01000000',b'10000000'
Rainbow    b'00010000',b'01010000',b'01000000'
Rainbow    b'00010000',b'00010000',b'01010000'
Rainbow    b'00010000',b'01000000',b'01000000'
Rainbow    b'00010000',b'10000000',b'00010000'
Rainbow    b'00010000',b'00010000',b'10000000'
Rainbow    b'00010000',b'10010000',b'10000000'
Rainbow    b'00010000',b'10010000',b'10010000'
Rainbow    b'00010000',b'00010000',b'10010000'
Rainbow    b'01010000',b'01010000',b'00010000'
Rainbow    b'01010000',b'01010000',b'01000000'
Rainbow    b'01010000',b'01010000',b'11000000'
Rainbow    b'01010000',b'01010000',b'10000000'
Rainbow    b'01010000',b'01010000',b'10010000'
Rainbow    b'01010000',b'10010000',b'11000000'
Rainbow    b'01010000',b'01000000',b'11000000'
Rainbow    b'01010000',b'10010000',b'10010000'
Rainbow    b'01010000',b'11010000',b'00010000'
Rainbow    b'01010000',b'11010000',b'01000000'
Rainbow    b'01010000',b'11010000',b'10000000'
Rainbow    b'01000000',b'11010000',b'10000000'
Rainbow    b'01000000',b'10000000',b'10000000'
Rainbow    b'01000000',b'01000000',b'10000000'
Rainbow    b'01000000',b'11000000',b'10000000'
Rainbow    b'01000000',b'11000000',b'11000000'
Rainbow    b'01000000',b'11010000',b'11000000'
Rainbow    b'01000000',b'10010000',b'10010000'
Rainbow    b'01000000',b'01000000',b'01010000'
Rainbow    b'01000000',b'01000000',b'11000000'
Rainbow    b'01000000',b'01000000',b'10010000'
Rainbow    b'10000000',b'10010000',b'00010000'
Rainbow    b'10000000',b'10010000',b'10010000'
Rainbow    b'10000000',b'11010000',b'00010000'
Rainbow    b'10000000',b'11000000',b'11000000'
Rainbow    b'10000000',b'11010000',b'10010000'
Rainbow    b'10010000',b'10010000',b'11010000'
Rainbow    b'10010000',b'01010000',b'11010000'
Rainbow    b'10010000',b'10010000',b'01000000'
Rainbow    b'10010000',b'10010000',b'11000000'
Rainbow    b'10010000',b'11010000',b'11000000'
Rainbow    b'00010000',b'00000000',b'00000000'
Rainbow    b'01010000',b'00000000',b'00000000'
Rainbow    b'01000000',b'00000000',b'00000000'
Rainbow    b'11000000',b'00000000',b'00000000'
Rainbow    b'10000000',b'00000000',b'00000000'
Rainbow    b'10010000',b'00000000',b'00000000'
;
return
;----------------------------------
MainFrames
movlw  d'255'
movwf    FrameCount
FC1
call        Frame12
call        Frame12
decfsz    FrameCount
goto    FC1
;
movlw  d'255'
movwf    FrameCount
FC2
call        Frame12
call        Frame11
decfsz    FrameCount
goto    FC2
;
movlw  d'255'
movwf    FrameCount
FC3
call        Frame11
call        Frame11
decfsz    FrameCount
goto    FC3
;
movlw  d'255'
movwf    FrameCount
FC4
call        Frame11
call        Frame10
decfsz    FrameCount
goto    FC4
;
movlw  d'255'
movwf    FrameCount
FC5
call        Frame10
call        Frame10
decfsz    FrameCount
goto    FC5
;
movlw  d'255'
movwf    FrameCount
FC6
call        Frame10
call        Frame9
decfsz    FrameCount
goto    FC6
;
movlw  d'255'
movwf    FrameCount
FC7
call        Frame9
call        Frame9
decfsz    FrameCount
goto    FC7
;
movlw  d'255'
movwf    FrameCount
FC8
call        Frame9
call        Frame8
decfsz    FrameCount
goto    FC8
;
movlw  d'255'
movwf    FrameCount
FC9
call        Frame8
call        Frame8
decfsz    FrameCount
goto    FC9
;
movlw  d'255'
movwf    FrameCount
FC10
call        Frame8
call        Frame7
decfsz    FrameCount
goto    FC10
;
movlw  d'255'
movwf    FrameCount
FC11
call        Frame7
call        Frame7
decfsz    FrameCount
goto    FC11
;
movlw  d'255'
movwf    FrameCount
FC12
call        Frame7
call        Frame6
decfsz    FrameCount
goto    FC12
;
movlw  d'255'
movwf    FrameCount
FC13
call        Frame6
call        Frame6
decfsz    FrameCount
goto    FC13
;
movlw  d'255'
movwf    FrameCount
FC14
call        Frame6
call        Frame5
decfsz    FrameCount
goto    FC14
;
movlw  d'255'
movwf    FrameCount
FC15
call        Frame5
call        Frame5
decfsz    FrameCount
goto    FC15
;
movlw  d'255'
movwf    FrameCount
FC16
call        Frame5
call        Frame4
decfsz    FrameCount
goto    FC16
;
movlw  d'255'
movwf    FrameCount
FC17
call        Frame4
call        Frame4
decfsz    FrameCount
goto    FC17
;
movlw  d'255'
movwf    FrameCount
FC18
call        Frame4
call        Frame3
decfsz    FrameCount
goto    FC18
;
movlw  d'255'
movwf    FrameCount
FC19
call        Frame3
call        Frame3
decfsz    FrameCount
goto    FC19
;
movlw  d'255'
movwf    FrameCount
FC20
call        Frame3
call        Frame2
decfsz    FrameCount
goto    FC20
;
movlw  d'255'
movwf    FrameCount
FC21
call        Frame2
call        Frame2
decfsz    FrameCount
goto    FC21
;
movlw  d'255'
movwf    FrameCount
FC22
call        Frame2
call        Frame1
decfsz    FrameCount
goto    FC22
;
movlw  d'255'
movwf    FrameCount
FC23
call        Frame1
call        Frame1
decfsz    FrameCount
goto    FC23
;
movlw  d'255'
movwf    FrameCount
FC24
call        Frame1
call        Frame12
decfsz    FrameCount
goto    FC24
;
return
;----------------------------------
Frame1
call        C1
call        Sec1
call        C2
call        Sec2
call        C3
call        Sec3
return
;---------------------------------------------
Frame2
call        C1
call        Sec4
call        C2
call        Sec5
call        C3
call        Sec6
return
;---------------------------------------------
Frame3
call        C1
call        Sec7
call        C2
call        Sec8
call        C3
call        Sec9
return
;---------------------------------------------
Frame4
call        C1
call        Sec10
call        C2
call        Sec11
call        C3
call        Sec12
return
;---------------------------------------------
Frame5
call        C3
call        Sec1
call        C1
call        Sec2
call        C2
call        Sec3
return
;---------------------------------------------
Frame6
call        C3
call        Sec4
call        C1
call        Sec5
call        C2
call        Sec6
return
;---------------------------------------------
Frame7
call        C3
call        Sec7
call        C1
call        Sec8
call        C2
call        Sec9
return
;---------------------------------------------
Frame8
call        C3
call        Sec10
call        C1
call        Sec11
call        C2
call        Sec12
return
;---------------------------------------------
Frame9
call        C2
call        Sec1
call        C3
call        Sec2
call        C1
call        Sec3
return
;---------------------------------------------
Frame10
call        C2
call        Sec4
call        C3
call        Sec5
call        C1
call        Sec6
return
;---------------------------------------------
Frame11
call        C2
call        Sec7
call        C3
call        Sec8
call        C1
call        Sec9
return
;---------------------------------------------
Frame12
call        C2
call        Sec10
call        C3
call        Sec11
call        C1
call        Sec12
return
;---------------------------------------------
Sec1
movlw    b'00001111'
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
return
;---------------------------------------------
Sec2
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
return
;---------------------------------------------
Sec3
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
return
;---------------------------------------------
Sec4
movlw    b'00011111'
movwf    copyPORTB
movlw    b'00001100'
call        Output
movlw    b'00001111'
movwf    copyPORTB
movlw    b'00001000'
call        Output
movlw    b'00000111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec5
movlw    b'11111100'
movwf    copyPORTB
movlw    b'00000001'
call        Output
movlw    b'11111000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'01110000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec6
movlw    b'11000001'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'10000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000111'
call        Output
return
;---------------------------------------------
Sec7
movlw    b'00111111'
movwf    copyPORTB
movlw    b'00001000'
call        Output
movlw    b'00011111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00001110'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec8
movlw    b'11111000'
movwf    copyPORTB
movlw    b'00000011'
call        Output
movlw    b'11110000'
movwf    copyPORTB
movlw    b'00000001'
call        Output
movlw    b'11100000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec9
movlw    b'10000011'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000001'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001110'
call        Output
return
;---------------------------------------------
Sec10
movlw    b'01111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00111110'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00011100'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec11
movlw    b'11110000'
movwf    copyPORTB
movlw    b'00000111'
call        Output
movlw    b'11100000'
movwf    copyPORTB
movlw    b'00000011'
call        Output
movlw    b'11000000'
movwf    copyPORTB
movlw    b'00000001'
call        Output
return
;---------------------------------------------
Sec12
movlw    b'00000111'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000011'
movwf    copyPORTB
movlw    b'00001110'
call        Output
movlw    b'00000001'
movwf    copyPORTB
movlw    b'00001100'
call        Output
return
;---------------------------------------------
C1            movfw    Color1
movwf    copyPORTA
return
;---------------------------------------------
C2            movfw    Color2
movwf    copyPORTA
return
;---------------------------------------------
C3            movfw    Color3
movwf    copyPORTA
return
;---------------------------------------------
movwf    PORTA
movfw    copyPORTB
movwf    PORTB
return
;---------------------------------------------
end

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

5. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida

If intention of the design is changed to color wave then hardware can easily be modified to make the firmware much simpler. Also many more RGB modules can be driven with less number of pins. Color Wave: An FX that places 12 colors across 12 channels with equal spacing and fading, then rotates colors around. In example of 12 RGB, RGB9 and RGB5 follow RGB1. So if RGB1 goes Red, RGB5 becomes Green and RGB9 becomes Blue. Similarly when RGB1 goes to Yellow, RGB5 goes to Aqua and RGB9 goes to Maganta. You will lose control of individual colors but you still have the smooth morphing between channels and colors are spread out evenly (almost perfect even). Hardware: Very similar to ColorRot with couple of major differences. R,G,B of first 4 RGB LEDs are tied together, same with RGB5-8 and RGB9-12. Then R1 is tied to G5, G1 tied to B5, and B1 is tied to R5. The wires get shifted. (R1G1B1-G5B5R5-B9R9G9)
To control 12 RGB now you need 3 pins for RGB and 4 pins for common anode for total of 7 pins used (instead of 15 pins). You can expand on this to have 12 pins common plus RGB (15 pins used) and control a whopping 36 RGB LED's. Another words a PIC16F628A can control 36 RGB led modules! With 36 RGB, the firmware is identical to ColorRot-12 but you can drive 3 times more LED's! More to come if there is an interest.

Last edited: Oct 10, 2014
6. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Introduction of a new program called "ColorStream". This is a 4-bit resolution color streaming. New color enters at the right side and gets morphed into existing colors and then shifted to the left (without loop around). It would have been too easy to just push the colors in one after the other. But in this code we actually incorporate the new color into the previous code by transitioning it (morphing it) into the old colors. Here is an example of what the code does: Grabs 3 initial colors, We used black, black, black. Then shift Red in. So the first step on 12 channels we have: Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Red1. Where Red1 designates the lowest brightness of Red, while Red4 depicts highest brightness. Following the shift-morph logic our next step will be: Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Blk, Red1, Red2 and so on until Red4 is reached to the far right. Then the next color is shifted in with a morph. So we have: Blk, Blk, Blk, Blk, Blk, Blk, Blk, Red1, Red2, Red3, Red4, Yellow1. We continue this entering new color, morphing, and shifting all the way to the end of our data (look up table for example).
This code will come in handy (with a bit of modification and added synchronizer) to receive 8-bit color data from an EEPROM for a continous streaming. Here is the code:
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
errorlevel    -305

cblock    0x20
copyPORTA                ;Declare variables used in the program
copyPORTB
FrameCount
LoopCount
Color1
Color2
Color3
Col1
Col2
Col3
Speed
endc
#define        bank0    bcf        STATUS,RP0
#define        bank1    bsf        STATUS,RP0
RESET_VECTOR    org        0x000
;--------------------------------------------------------------
Rainbow    macro    Col1,Col2,Col3
movlw    Col1
movwf    Color1
movlw    Col2
movwf    Color2
movlw    Col3
movwf    Color3
call        MainFrames
endm
;--------------------------------------------------------------
START
movlw    b'00000111'            ;Set all ports as outputs
movwf    CMCON                ;Disable comparators
bank1
clrf    TRISA
clrf    TRISB
bank0
clrf        copyPORTA
;----------------------------------------------------------------------
movlw    d'35'
movwf    Speed
Rainbow    b'00000000',b'00000000',b'00000000'
Rainbow    b'00000000',b'00000000',b'00010000'
Rainbow    b'00000000',b'00010000',b'01010000'
Sequence
Rainbow    b'00010000',b'01010000',b'01000000'
Rainbow    b'01010000',b'01000000',b'11000000'
Rainbow    b'01000000',b'11000000',b'10000000'
Rainbow    b'11000000',b'10000000',b'10010000'
Rainbow    b'10000000',b'10010000',b'00010000'
Rainbow    b'10010000',b'00010000',b'01010000'
goto    Sequence
;----------------------------------------------------------------------
MainFrames
movfw    Speed
movwf    LoopCount
LC1
call        Frame1
decfsz    LoopCount,F
goto    LC1
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC2
call        Frame2
decfsz    LoopCount,F
goto    LC2
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC3
call        Frame3
decfsz    LoopCount,F
goto    LC3
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC4
call        Frame4
decfsz    LoopCount,F
goto    LC4
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC5
call        Frame5
decfsz    LoopCount,F
goto    LC5
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC6
call        Frame6
decfsz    LoopCount,F
goto    LC6
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC7
call        Frame7
decfsz    LoopCount,F
goto    LC7
;-----------------------------------------------
movfw    Speed
movwf    LoopCount
LC8
call        Frame8
decfsz    LoopCount,F
goto    LC8
;
return
;-----------------------------------------------
Frame1
movfw        Speed
movwf        FrameCount
FC1
call        C1
call        Sec1
call        C2
call        Sec2
call        C3
call        Sec3
decfsz    FrameCount,F
goto    FC1
return
;---------------------------------------------
Frame2
movfw        Speed
movwf        FrameCount
FC2
call        C1
call        Sec4
call        C2
call        Sec5
call        C3
call        Sec6
decfsz    FrameCount,F
goto    FC2
return
;---------------------------------------------
Frame3
movfw        Speed
movwf        FrameCount
FC3
call        C1
call        Sec7
call        C2
call        Sec8
call        C3
call        Sec9
decfsz    FrameCount,F
goto    FC3
return
;---------------------------------------------
Frame4
movfw        Speed
movwf        FrameCount
FC4
call        C1
call        Sec10
call        C2
call        Sec11
call        C3
call        Sec12
decfsz    FrameCount,F
goto    FC4
return
;---------------------------------------------
Frame5
movfw        Speed
movwf        FrameCount
FC5
call        C1
call        Sec13
call        C2
call        Sec14
call        C3
call        Sec15
decfsz    FrameCount,F
goto    FC5
return
;---------------------------------------------
Frame6
movfw        Speed
movwf        FrameCount
FC6
call        C1
call        Sec16
call        C2
call        Sec17
call        C3
call        Sec18
decfsz    FrameCount,F
goto    FC6
return
;---------------------------------------------
Frame7
movfw        Speed
movwf        FrameCount
FC7
call        C1
call        Sec19
call        C2
call        Sec20
call        C3
call        Sec21
decfsz    FrameCount,F
goto    FC7
return
;---------------------------------------------
Frame8
movfw        Speed
movwf        FrameCount
FC8
call        C1
call        Sec22
call        C2
call        Sec23
call        C3
call        Sec24
decfsz    FrameCount,F
goto    FC8
return
;---------------------------------------------
Sec1
movlw    b'11110000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11100000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'10000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
return
;---------------------------------------------
Sec2
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'01111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00011111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec3
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec4
movlw    b'11100000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'10000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
return
;---------------------------------------------
Sec5
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000001'
call        Output
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'01111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec6
movlw    b'00000001'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec7
movlw    b'11000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'10000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001110'
call        Output
return
;---------------------------------------------
Sec8
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000011'
call        Output
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000001'
call        Output
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'01111110'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec9
movlw    b'00000011'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000001'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec10
movlw    b'10000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001110'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001100'
call        Output
return
;---------------------------------------------
Sec11
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000111'
call        Output
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00000011'
call        Output
movlw    b'11111110'
movwf    copyPORTB
movlw    b'00000001'
call        Output
movlw    b'11111100'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec12
movlw    b'00000111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000011'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000001'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec13
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001110'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001100'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001000'
call        Output
return
;---------------------------------------------
Sec14
movlw    b'11111111'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11111110'
movwf    copyPORTB
movlw    b'00000111'
call        Output
movlw    b'11111100'
movwf    copyPORTB
movlw    b'00000011'
call        Output
movlw    b'11111000'
movwf    copyPORTB
movlw    b'00000001'
call        Output
return
;---------------------------------------------
Sec15
movlw    b'00001111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000011'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000001'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec16
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001110'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001100'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec17
movlw    b'11111110'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11111100'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11111000'
movwf    copyPORTB
movlw    b'00000111'
call        Output
movlw    b'11110000'
movwf    copyPORTB
movlw    b'00000011'
call        Output
return
;---------------------------------------------
Sec18
movlw    b'00011111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00001111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000011'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec19
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001100'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec20
movlw    b'11111100'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11111000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11110000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11100000'
movwf    copyPORTB
movlw    b'00000111'
call        Output
return
;---------------------------------------------
Sec21
movlw    b'00111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00011111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00001111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec22
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00001000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00000000'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
Sec23
movlw    b'11111000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11110000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11100000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
movlw    b'11000000'
movwf    copyPORTB
movlw    b'00001111'
call        Output
return
;---------------------------------------------
Sec24
movlw    b'01111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00111111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00011111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
movlw    b'00001111'
movwf    copyPORTB
movlw    b'00000000'
call        Output
return
;---------------------------------------------
C1            movfw    Color1
movwf    copyPORTA
return
;---------------------------------------------
C2            movfw    Color2
movwf    copyPORTA
return
;---------------------------------------------
C3            movfw    Color3
movwf    copyPORTA
return
;---------------------------------------------
movwf    PORTA
movfw    copyPORTB
movwf    PORTB
return
;---------------------------------------------
end

7. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
So far we have created a family of FX for 12 channel RGB:
ColorMorph: All 12 channels together shift color from Red thru colors of rainbow back to Red.
Fix3Color: Produced 12 fix colors across 12 RGB with morphing in between (static colors with no movement)
ColorRot: 12 Colors are produced on 12 channels with morph in between and then rotated with a loop around
ColorStream: 12 colors are produced on 12 channels with morph in between, new color is entered to the right, morphed in, and then shifted to the left. Last color drops off with no loop around.

8. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Since the topic of original post started with rotate bits. I will go back to the original concept of generation of 12 colors across 12 channels and rotating them (ColorRot).
Given:
User enters 3 primary colors (Choose: R, RG, G, GB, B, BR, W, BLK)
Color Resolution:3 bits
Required data lines to create one frame: 9 lines (9 lines of 12-bit long)
It takes 4 frames to go from primary color1 to primary color2
It takes 3 colorsets across 4 frames to complete one complete rotation of colors across 12 channels. i.e.: Once 4 frames are completed primary color 1 and 2 switch places and so on. Hence only 4 frames are needed, then rotate primary colors and do 4 frames again. Rotate primary colors one last time and repeat 4 frames. (example: when LED1=Red, LED5=Green, LED9=Blue, do 4 frames to shift LED1 from Red to Green and that shifts LED5-12 automatically). You will need 4 more frames for LED1 to go from Green to Blue, and another 4 frames to go from Blue to Red. That is 3 times doing 4 frames with primary colors rotated.
Implementations:
Create 9 lines:

L1: 1110-0000-1111 (to be placed in A3-A0 and B7-B0)
L2: 1100-0000-0111
L3: 1000-0000-0011
L4: 0000-1111-1110
L5: 0000-0111-1100
L6: 0000-0011-1000
L7: 1111-1110-0000
L8: 0111-1100-0000
L9: 0011-1000-0000
Create 3 Colorsets:
Read user given 3 primary colors and place them in Color1,Color2,Color3
Colorset1: C1,C2,C3 (place Color1 in C1, Color2 in C2, Color3 in C3)
Colorset2: C2,C3,C1 (Place Color1 in C2, Color2 in C3, Color3 in C1)
Colorset3: C3,C1,C2 (place Color1 in C3, Color2 in C1, Color3 in C2)
Create 4 Frames:
Frame1
Place C1 in A7-A4
Put L1 in A3-A0 and B7-B0 -> Output
Put L2 -> Output
Put L3 -> Output
Place C2 in A7-A4
Put L4 -> Output
Put L5 -> Output
Put L6 -> Output
Place C3 in A7-A4
Put L7 -> Output
Put L8 -> Output
Put L9 -> Output
--------------
Frame2
Place C1 in A7-A4
Rotate L1 -> Output
Rotate L2 -> Output
Rotate L3 -> Output
Place C2 in A7-A4
Rotate L4 -> Output
Rotate L5 -> Output
Rotate L6 -> Output
Place C3 in A7-A4
Rotate L7 -> Output
Rotate L8 -> Output
Rotate L9 -> Output
-------------
Frame 3 and 4 are similar to Frame 2 with lines rotated
----------------------------------
Program:
Call Colorset1: C1, C2, C3
Call Frame1
Call Frame2
Call Frame3
Call Frame4
Call Colorset2: C2, C3, C1
Call Frame1
Call Frame2
Call Frame3
Call Frame4
Call Colorset3: C3, C1, C2
Call Frame1
Call Frame2
Call Frame3
Call Frame4
End

Challenges I have had so far: During the time I shift bits and rotate primary colors the color rotation gets paused. (stop and go) I have to find a way to rotate bits faster and time the frame to frame transitions such that it takes equal amount of time as rotations. I could use some suggestions....

9. NorthGuyWell-Known Member

Joined:
Sep 8, 2013
Messages:
1,218
Likes:
206
Location:
To get a stable time base, you need a timer interrupt. Set your LEDs first thing after the interrupt is called. If you want to switch at 60Hz x 3 channels x 32 (5 bit) resolution = about 6kHz - one interrupt every 170 us - not very challenging speed. Then you can run any stuff between iterrupts without distubing the time base.

10. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Thanks North. I will work on that when I have some time.

11. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Here is the code for ColorRotate modified, cleaned up and commented.
Thanks to all for great feedbacks. Special thanks to Mike-K8LH for his contributions.

Attached Files:

• A12 Color Rotate 4-Bit Res.pdf
File size:
542 KB
Views:
203
Last edited: Oct 17, 2014
12. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Working on 18 RGB version now. 9 shared data bits, 2 sets of RGB. Hardware design is completed, will work on the code time permitting.

13. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
I tried to create a 12-bit variable and rotate it. But during assembly processor gave me an error message indicating that the string was too long and it chopped it down to the least significant 8 bits. Is there a trick to creating a 12-bit variable (may be in declaration) or PIC16F628A can not handle a "word" variable?
Regards,
Rom

Follow up post: I do not believe it is possible with PIC16F628A to generate 16-bit (or 12-bit) variables and cobnstantly rotate them. I kow W-register can hold a "Word" (16-bit number) and do something with it. But I have not find any examples that show these values can be passed on to a 16-bit variable. Until additional discoveries, I broke up each data-line into two 8-bit variables and named them High and Low. See next post for details.

Last edited: Oct 28, 2014
14. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Here is the code for A12-ColorRotate with Rotate Left Function. It is not the most efficient way to implement color rotate, nor the color transitions are as smooth as one would like. Nevertheless, the code works beautifully.
Concept: Firmware generates 12 data lines which hold the color triangles. Then these data lines are rotated and appropriate color-bits are added at the right time and displayed.
Implementation: User provides 3 colors. Code grabs these 3 colors and place them in Color1, COlor2, Color3 each a 4-bit number (with upper 4-MSB used). Every 4 data lines gets one color to cover all 3 colors over 12 lines. Then these data lines are rotated and colors added once again and display. As before each frame contains the data lines for 12 RGB LEDs multiplex RGB. 12 Frames (12 rotatations) will cover rotation of colors from RGB1 thru RGB12. Then next set of colors are selected from user provided table.

File size:
63.1 KB
Views:
156
15. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Here is one more method of Rotate Left Bits for ColorRotate. This time brightness is implemented on RGB and not on data lines (A3-A0 & B7-B0). To get 12 desired colors across 12 RGB, we simply mix different ratio of each primary color. Red=4 times red, Orange=3 times red, 1 time green, and so on.
As before user provides 3 colors. Colors are placed in 3 variables. We Initialize data line (0000-0000, 0000-0001) corresponding to (LHigh, LLow).
We cross fire B0 with color1, rotate data line (now 0000-0000 0000-0010), implement color2. Every 4 rotations we rotate the colors from color1 to color2, color2 to color3, color3 to color1 to capture 12 colors. (3 sets of 4 rotations, 4 colors) The final trick is once you complete a frame to rotate the bits one extra time. This allows color1 to fall on 0000-0000, 0000-0010 (instead of 0000-0000, 0000-0001) and then rotation continues. So from one frame to the next the entire data line mapping is turn left one, creating the color motion. This code is a lot simpler and more efficient. Colors are much brighter and fading is smoother.

File size:
59.3 KB
Views:
143
16. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Quick tip (trick) to increase color saturation of one color over the other (color correction) when morphing: Let's say you have implemented your color mapping and you noticed on your RGB LEDs color red is weaker than green and blue. Hence your color wheel is shifted more towards green and blue. i.e.: Yellow is more greenish, and magenta is more purplish.
To correct this, change the order of color bits to be pushed out last. For example above when doing 1 red, 3 green. set your greens first then red at the end. For color yellow, do two greens first, then 2 reds. You can make this correction going from red to green, greeen to blue, and blue to red transitions. It makes a noticable difference!
Another tip when color matching your RGB LED's: Before soldering your LED's, build a quick jig on a protype board and test your LED's 2 by 2 to find out the best resistor values. Focus on colors: Yellow first (equal red & green), then on Magenta (equal red and blue) and finally white (red + green +blue). You might have to do several adjustment going thru these colors sets. Once you have the perfect combination then write down what values of resistors you calculated and build your circuit. You will find out that RGB LED's have different color rendering from one to another even within the same "bin". To do your fine tuning of the final colors use trick one by rearranging color bits in your firmware. Happy Coloring.

Last edited: Oct 31, 2014
17. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
To wrap up this post I started this project with a color graph of the desired output of LED's. Then proceeded putting together the concept of general code. Once that was done, I broke down the project in hardware and software in steps and implemented subroutines and macros to shorten the code and put everything together. Here are a few challenges I went thru and learned by experimenting, calculating, and experimenting again:
1- The challenge in multi RGB color decoding is that we are trying to force a 3D effect into a 2D programing then display it back in 3D. We have color choice (RGB), Brightness, and Port Pins as our dimensions. I found out the most efficient way to do this is to scan all Reds, Greens and Blues in 3 passes. Combine brightness with data bits as your first dimension and your second dimension is your color sets. The codes are written for an array of input colors. One can simplify the codes if only a sinple RGB is used.
2- The challenge for circuit design and calculating available current for each RGB: The best tackle is first calculate how much current your microcontroller can put out since we are direct driving (for PIC16F628A max combined two ports output current is 200mA). Then figure out how much current your NPN transistors need to fully turn on (Base current x current gain = Max Emitter current sinking ability). Most standard transistors require turn-on base voltage of 2V with approximate base current of 5mA (with conservative gain of 50). Now 200mA minus (3x5mA=15mA) for transistors and you have 185mA available current to source the anodes of 12 RGB (approx. 15mA per RGB). But remember we are scanning R, G, then B. So at each given time we have 15mA available for each individual color (R,G,B) on all 12 RGB LEDs! (15x12=180mA, with 5mA to spare)
3- Now we know how much current is available to each RGB. One method of supplying currents to each RGB is to have individual resistors for each color on each LED before you tie them together. To cut down on parts and to simplify the PCB layout, I elected to do this differently. I used two resistors instead of 3 and I placed them stratigically on Anode and Red. This makes the calculations a bit more challenging since you have different Vf and If for colors. To make the matters worse to balance the colors you will need to compensate for brightness of R,G,B to give you a great color mix. On most RGB+ : Common Anode with frusted lens (better than clear lens) you will discover that red is the weakest color. So where do we start?!
I had to solve two equations (one for red and one for GB). Let's tackle Red first. We know at full brightness Red uses 20mA at 1.9V. But we only have 15mA available. We do a quick approximation: 1.9x15/20=1.43V,......So at 15mA Red will have a voltage of 1.43V across it. Hold this number.
For G & B typically, at 20mA we have Vf of 3.3V, but we only have 15mA. Again with approximation we calculate that at 15mA, we have 2.5V across G & B. To compensate for color mixing, you will find out that you need to run G & B at 90% of that voltage (& current) corresponding to 2.3V across G & B at current of 13.8mA. The anode resistor then will have 2.7V across it with 15mA thru it. So Resist for anode is 180 ohms. Now the juction of anodes of RGB have a voltage of 2.3 and Red uses 1.43V at 15mA. So series Resist for Red will have the value of (2.3-1.43)/15mA=58 ohms (you can use 56 ohms standard or use 51 since we have some playroom in our overhead current). Again as a reminder each manufacturer has specific color rendering and brightness. Not to mention color may vary from batch to batch during manufacturing. In conclusiong you might have to adjust the resistor values once again to get your desired mix and color balance. As a tip if you think you need to reduce the brightness of GB by increasing Anode resistor by 10 ohms, only increase it by 5 ohms and reduce Red series resistor by 5 ohms. The entire circuit uses 200mA at 5v for total of 1W. If you leave this circuit on 24 hours, 365 days, your annual electric usage is about \$12 (\$1/month). I recommend experimenting with the codes in this post as it will provide you with an insight of color coding. Your challenge is to simplify the codes and make them more efficient. Cheers.

Last edited: Jan 3, 2015
18. EvilGeniusMember

Joined:
Jan 8, 2008
Messages:
334
Likes:
6
Location:
Florida
Additional Developement Regarding Color Mixing and RGB Balancing:
While one can alway do color balancing thru firmware or trial and error with hardware, I was able to create a way to balance RGB via formulas and an Excell sheet which anyone can put together with a bit of study. This process involved looking at individual chromographic characteristic of each color LED (x,y,z), view angel, individual lumen-intensities, and quantity of each color used in a module to obtain a pure white color. These variables along with individual LED Vf and If were entered into the spreadsheet. By adjusting number of each color used, spreadsheet calculates total X,Y,Z along with total MCD, Lumens, Currents thru each group of color (say 5 red, 3 green, 3 blue), required series resistor, total current and total wattage for individual module. Once all colors are balanced X,Y,Z become precisely (or very close to) 0.333, 0333, 0.334 which is pure white. This step will save tremendous amount of time in prototyping, increases overall efficiency of each module and provide the user with an excellent color mixing. This also allows user to use different type of LED's for different RGB module configurations. (Example 5mm 20 degree spots, 5mm 120 degree Strawhat flood, or 5050 RGB strips)