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.

PIC16F628A Rotate Left Thru Carry & Loop Around

Status
Not open for further replies.
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.
 
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.
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).
 
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:
You are driving an LED @ 5mA @ 33% for brightness? Can you share the spec. sheet of the LEDs?
 
You are driving an LED @ 5mA @ 33% for brightness? Can you share the spec. sheet of the LEDs?
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!
 
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:
Here are some photos so you can tell how bright the LED's are! Common anode 5mm RGB frosted lens.
 

Attachments

  • IMG_0539.JPG
    IMG_0539.JPG
    61.4 KB · Views: 213
  • IMG_0545.JPG
    IMG_0545.JPG
    66.7 KB · Views: 220
  • IMG_0547.JPG
    IMG_0547.JPG
    64 KB · Views: 229
  • IMG_0548.JPG
    IMG_0548.JPG
    61.4 KB · Views: 202
  • IMG_0549.JPG
    IMG_0549.JPG
    62.9 KB · Views: 215
  • IMG_0551.JPG
    IMG_0551.JPG
    64.6 KB · Views: 218
  • IMG_0554.JPG
    IMG_0554.JPG
    65 KB · Views: 205
  • IMG_0555.JPG
    IMG_0555.JPG
    63.8 KB · Views: 203
Last edited:
Mike let me know if you understand colormorph first. I walk you thru colorrot.
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:
;
;  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
 
Thank you for simplifying your "colormorph" code down to a level that I could study.
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.
 
Since the "Morph" is using 100% duty and "Rot" only 33%, does Morph look much brighter than the Rot?
 
Since the "Morph" is using 100% duty and "Rot" only 33%, does Morph look much brighter than the Rot?
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.
 
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.
 

Attachments

  • AURORA 12 MINI Round Copper.pdf
    24.4 KB · Views: 212
  • AURORA 12 MINI Round Silk.pdf
    30.9 KB · Views: 232
  • 1.jpg
    1.jpg
    419.5 KB · Views: 220
  • 1.jpg
    1.jpg
    321.4 KB · Views: 231
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.
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!
 
Code:
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.
 

Attachments

  • 12 CHANNEL RGB COLOR MORPH 12 PORTS.jpg
    12 CHANNEL RGB COLOR MORPH 12 PORTS.jpg
    59.9 KB · Views: 219
Last edited:
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:
Perhaps a flowchart is easier to follow. Reading details doesn't show structure as a flow chart or state diagram.
 
Perhaps a flowchart is easier to follow. Reading details doesn't show structure as a flow chart or state diagram.
I don't think flowchart will tell you a lot more than said above. But here it is:
 

Attachments

  • A12-Fix3Color-Flowchart.jpg
    A12-Fix3Color-Flowchart.jpg
    479.6 KB · Views: 272
Status
Not open for further replies.

Latest threads

Back
Top