Maker Pro
Maker Pro

Trouble with tribbles.. erm, timers.

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
OK, a lot of water has passed under the bridge since I replied and I have not had the time to read all that Kris has written (I trust it's right -- he's not often wrong), so some of this may be moot.

Firstly, thanks for taking the time to help me out!

Thanks for the thanks. It makes doing this stuff worthwhile.

No, I won't need you to explain that tutorial Steve. I've re-read that with more understanding as far as C++ goes (thanks to you guys!) and it makes better sense, but I do believe that what he wrote was very misleading..
I'm glad you have it understood. Part of the problem is the language used. As I recall he describes the issue correctly, but it is a rather obscure C++ way of doing almost the same thing two different ways.

He is effectively distinguishing between the following declarations and now they're used:

Code:
int i;
int* j;
int& k;
and then let me add to that

Code:
const int& l;
The last two of these are never (?) seen outside of function headers.

i is an integer, j is a pointer to an integer that must be dereferenced to access the value, k is a pointer that does not need to be dereferenced, and l is a pointer that does not need to be dereferenced, but which can't appear on the LHS.

So i, k, and l can be handled just like a normal integer variable (or constant in the case of l) whereas you need to dereference j.

the declaration style of j allows you to do a traditional pass by reference rather than implementing it as a pass by value of a pointer (C/C++ actually only allow pass by value)

As far as understanding everything else.. Um, well.. not entirely. Steve said both "It depends", "No", and then gave a not answer to my questions.
Sorry about that, I tried to cover all the things that might happen.

My guess is the correct answer was "No", once a while loop starts running it's code it won't stop unless told to do so (weather that means encountering the end of the loop, or a break) or encountering a serious error.
And my point is that if the conditions which terminate the loop (aside from an error or a break) are caused by changes occurring outside the loop (by concurrently running code, a memory mapped IO, etc), then the optimizer may prevent the loop terminating because it won't actually check it.

I'm not sure what he means by optimization entirely.. for a lot of code there's obviously more than one way to accomplish a goal, but how you get there can cost less CPU time or less space in the code and I think that must be to what you're referring?
Essentially the compiler tries to figure out what you're trying to do and it tries to do it in a simpler (typically faster) way.

e.g.

Code:
int i = 10;
int j = 20;
int k = 1;

while (k < (j - i))
{
  k = k + someFunction();
}
would likely be simplified by the compiler to this:

Code:
int i = 10;
int j = 20;
int k = 1;

while (k < 10)
{
  k = k + someFunction();
}
Now that's fine, unless there's an interrupt routine that changes i or j (the compiler should be smart enough to consider whether "someFunction()" could have changed them).

If an interrupt routine could change i, for instance, you would be better declaring i like this:

Code:
volatile int i;
That way the compiler knows that every time it needs to access the value of i it should go and actually read it, not assume it was unchanged since the last time.

I'll be back in a couple days time with more questions as I've been working on my code! I'm at about 1900 lines at this point.. dealing with two matrix simultaneously is a lot of copy&paste work.. I suppose I could write a single function to go through all 11 rows, and 18 columns, but I'm not sure how much CPU time that would actually take recreating what I've done dynamically..

My advice to you is to keep your functions short. 10 to 20 lines is ideal, and maybe a maximum of 50. Declare most of these as "private" unless they're useful external functions.

I did at least add a bunch of comments to ease in my and everyone else headaches though!
Always a good thing!
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
To be quite honest I really doubt I can keep most of the functions that short!

The function I wrote for changing macro key colors is about 81 lines long.
The function I wrote for controlling PWM of the LEDs and color fade functions is 107 lines.
I have 2 other functions that are 12 and 2 lines

There are just too many variables that have to be kept track of to do that! Each key on the keyboard (107) has a set of 9 variables to do with it, and those are mostly arrays (all 3 or 2 elements). I still have to write code for handling how the F~ keys operate while the macro key has been enabled, and I need to write the USB HID communication stuff.. or figure out if there are Atmel chips I can use that make that bit simpler. I need to look into if I need to write code to prevent button bounce as well.
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
To be quite honest I really doubt I can keep most of the functions that short!

The function I wrote for changing macro key colors is about 81 lines long.
The function I wrote for controlling PWM of the LEDs and color fade functions is 107 lines.
I have 2 other functions that are 12 and 2 lines

Post them and let's see what we can do.

Are you familiar with "stepwise refinement"? Often this will lead to sensible definitions of functions.
 

KrisBlueNZ

Sadly passed away in 2015
Nov 28, 2011
8,393
Joined
Nov 28, 2011
Messages
8,393
Are you familiar with "stepwise refinement"? Often this will lead to sensible definitions of functions.
Yes, that's very applicable to this kind of project, when you're really working out how to do things as you go along, because the requirements are pretty complicated but they're also flexible, and the order in which you add features during development (as well as whether any given feature is really needed) is not defined, but flows from the previous development as development progresses.

In situations like this, it's impossible for any normal human being to really see how everything will fit together; it's better to basically use trial and error. Start with something that works, and implements some of the features. Then analyse what you have, where you want to go with it, and how it could be restructured to make it simpler, clearer, or more efficient. Then rinse and repeat.

Part of this analysis involves breaking down long functions, and sections of code that do similar things, into lower-level functions. This is a very good way of making the big picture more obvious and easier to comprehend, which then leads to ideas for restructuring and optimisation. As I said before, the improvements that can come from this approach will often hugely outweigh the extra processing time involved in moving code into functions.

"Stepwise refinement" - a euphemism for "messing around with it" :)
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
"Stepwise refinement" - a euphemism for "messing around with it" :)

Not exactly.

If you have a large task, you first break it down into several steps.

Then you break those steps down.

Then you break those down.

Eventually you have something you can easily code and if you make each of these intermediate steps functions, your code is automatically broken down into easy to understand chunks.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Ah, well.. I was not aware there was a term for it to be honest, but that's essentially what I've done. lol

It was difficult, but I've more or less got the code written for the LEDs, and registering key presses. There are some minor tweaks I'd like to make to the fader functions for when the macro state is switched to fade those colors (and I have to change the variable type where I do a divide function in the fader stuff that's likely going to produce not whole numbers and then round it to a whole number..), add the code to possibly randomize button press colors and/or button colors, and I've devised a method for changing the color states without needing to reprogram the micro controller.. I think.. I'm about to inquire with the almighty Google about the possibility of saving variables in non-volatile memory.. if there is a way to..

Code:
/*
 * ATTINY861_20PU_LED_MATRIX.c
 *
 * Created: 1/25/2014 4:24:47 PM
 *  Author: The Hammer
 */ 


#include <avr/io.h>
// 74HC595 PWM and key variables
int row = 0, column = 0;
int esc = 0, escBC[3]={0, 20, 0}, escBPC[3]={0, 0, 20}, escGfade[2]={49, 0}, escG[3]={0, 0, 0}, escBfade[2]={49, 0}, escB[3]={0, 0, 0}, escRfade[2]={49, 0}, escR[3]={0, 0, 0};
int tilda = 0, tildaBC[3]={0, 20, 0}, tildaBPC[3]={0, 0, 20}, tildaGfade[2]={49, 0}, tildaG[3]={0, 0, 0}, tildaBfade[2]={49, 0}, tildaB[3]={0, 0, 0}, tildaRfade[2]={49, 0}, tildaR[3]={0, 0, 0};
int tab = 0, tabBC[3]={0, 20, 0}, tabBPC[3]={0, 0, 20}, tabGfade[2]={49, 0}, tabG[3]={0, 0, 0}, tabBfade[2]={49, 0}, tabB[3]={0, 0, 0}, tabRfade[2]={49, 0}, tabR[3]={0, 0, 0};
int caps = 0, capsBC[3]={0, 20, 0}, capsBPC[3]={0, 0, 20}, capsGfade[2]={49, 0}, capsG[3]={0, 0, 0}, capsBfade[2]={49, 0}, capsB[3]={0, 0, 0}, capsRfade[2]={49, 0}, capsR[3]={0, 0, 0};
int lshift = 0, lshiftBC[3]={0, 20, 0}, lshiftBPC[3]={0, 0, 20}, lshiftGfade[2]={49, 0}, lshiftG[3]={0, 0, 0}, lshiftBfade[2]={49, 0}, lshiftB[3]={0, 0, 0}, lshiftRfade[2]={49, 0}, lshiftR[3]={0, 0, 0};
int lctrl = 0, lctrlBC[3]={0, 20, 0}, lctrlBPC[3]={0, 0, 20}, lctrlGfade[2]={49, 0}, lctrlG[3]={0, 0, 0}, lctrlBfade[2]={49, 0}, lctrlB[3]={0, 0, 0}, lctrlRfade[2]={49, 0}, lctrlR[3]={0, 0, 0};
int f1 = 0, f1BC[3]={0, 20, 0}, f1BPC[3]={0, 0, 20}, f1Gfade[2]={49, 0}, f1G[3]={0, 0, 0}, f1Bfade[2]={49, 0}, f1B[3]={0, 0, 0}, f1Rfade[2]={49, 0}, f1R[3]={0, 0, 0};
int one = 0, oneBC[3]={0, 20, 0}, oneBPC[3]={0, 0, 20}, oneGfade[2]={49, 0}, oneG[3]={0, 0, 0}, oneBfade[2]={49, 0}, oneB[3]={0, 0, 0}, oneRfade[2]={49, 0}, oneR[3]={0, 0, 0};
int q = 0, qBC[3]={0, 20, 0}, qBPC[3]={0, 0, 20}, qGfade[2]={49, 0}, qG[3]={0, 0, 0}, qBfade[2]={49, 0}, qB[3]={0, 0, 0}, qRfade[2]={49, 0}, qR[3]={0, 0, 0};
int a = 0, aBC[3]={0, 20, 0}, aBPC[3]={0, 0, 20}, aGfade[2]={49, 0}, aG[3]={0, 0, 0}, aBfade[2]={49, 0}, aB[3]={0, 0, 0}, aRfade[2]={49, 0}, aR[3]={0, 0, 0};
int z = 0, zBC[3]={0, 20, 0}, zBPC[3]={0, 0, 20}, zGfade[2]={49, 0}, zG[3]={0, 0, 0}, zBfade[2]={49, 0}, zB[3]={0, 0, 0}, zRfade[2]={49, 0}, zR[3]={0, 0, 0};
int lspecial = 0, lspecialBC[3]={0, 20, 0}, lspecialBPC[3]={0, 0, 20}, lspecialGfade[2]={49, 0}, lspecialG[3]={0, 0, 0}, lspecialBfade[2]={49, 0}, lspecialB[3]={0, 0, 0}, lspecialRfade[2]={49, 0}, lspecialR[3]={0, 0, 0};
int f2 = 0, f2BC[3]={0, 20, 0}, f2BPC[3]={0, 0, 20}, f2Gfade[2]={49, 0}, f2G[3]={0, 0, 0}, f2Bfade[2]={49, 0}, f2B[3]={0, 0, 0}, f2Rfade[2]={49, 0}, f2R[3]={0, 0, 0};
int two = 0, twoBC[3]={0, 20, 0}, twoBPC[3]={0, 0, 20}, twoGfade[2]={49, 0}, twoG[3]={0, 0, 0}, twoBfade[2]={49, 0}, twoB[3]={0, 0, 0}, twoRfade[2]={49, 0}, twoR[3]={0, 0, 0};
int w = 0, wBC[3]={0, 20, 0}, wBPC[3]={0, 0, 20}, wGfade[2]={49, 0}, wG[3]={0, 0, 0}, wBfade[2]={49, 0}, wB[3]={0, 0, 0}, wRfade[2]={49, 0}, wR[3]={0, 0, 0};
int s = 0, sBC[3]={0, 20, 0}, sBPC[3]={0, 0, 20}, sGfade[2]={49, 0}, sG[3]={0, 0, 0}, sBfade[2]={49, 0}, sB[3]={0, 0, 0}, sRfade[2]={49, 0}, sR[3]={0, 0, 0};
int x = 0, xBC[3]={0, 20, 0}, xBPC[3]={0, 0, 20}, xGfade[2]={49, 0}, xG[3]={0, 0, 0}, xBfade[2]={49, 0}, xB[3]={0, 0, 0}, xRfade[2]={49, 0}, xR[3]={0, 0, 0};
int lalt = 0, laltBC[3]={0, 20, 0}, laltBPC[3]={0, 0, 20}, laltGfade[2]={49, 0}, laltG[3]={0, 0, 0}, laltBfade[2]={49, 0}, laltB[3]={0, 0, 0}, laltRfade[2]={49, 0}, laltR[3]={0, 0, 0};
int f3 = 0, f3BC[3]={0, 20, 0}, f3BPC[3]={0, 0, 20}, f3Gfade[2]={49, 0}, f3G[3]={0, 0, 0}, f3Bfade[2]={49, 0}, f3B[3]={0, 0, 0}, f3Rfade[2]={49, 0}, f3R[3]={0, 0, 0};
int three = 0, threeBC[3]={0, 20, 0}, threeBPC[3]={0, 0, 20}, threeGfade[2]={49, 0}, threeG[3]={0, 0, 0}, threeBfade[2]={49, 0}, threeB[3]={0, 0, 0}, threeRfade[2]={49, 0}, threeR[3]={0, 0, 0};
int e = 0, eBC[3]={0, 20, 0}, eBPC[3]={0, 0, 20}, eGfade[2]={49, 0}, eG[3]={0, 0, 0}, eBfade[2]={49, 0}, eB[3]={0, 0, 0}, eRfade[2]={49, 0}, eR[3]={0, 0, 0};
int d = 0, dBC[3]={0, 20, 0}, dBPC[3]={0, 0, 20}, dGfade[2]={49, 0}, dG[3]={0, 0, 0}, dBfade[2]={49, 0}, dB[3]={0, 0, 0}, dRfade[2]={49, 0}, dR[3]={0, 0, 0};
int c = 0, cBC[3]={0, 20, 0}, cBPC[3]={0, 0, 20}, cGfade[2]={49, 0}, cG[3]={0, 0, 0}, cBfade[2]={49, 0}, cB[3]={0, 0, 0}, cRfade[2]={49, 0}, cR[3]={0, 0, 0};
int v = 0, vBC[3]={0, 20, 0}, vBPC[3]={0, 0, 20}, vGfade[2]={49, 0}, vG[3]={0, 0, 0}, vBfade[2]={49, 0}, vB[3]={0, 0, 0}, vRfade[2]={49, 0}, vR[3]={0, 0, 0};
int f4 = 0, f4BC[3]={0, 20, 0}, f4BPC[3]={0, 0, 20}, f4Gfade[2]={49, 0}, f4G[3]={0, 0, 0}, f4Bfade[2]={49, 0}, f4B[3]={0, 0, 0}, f4Rfade[2]={49, 0}, f4R[3]={0, 0, 0};
int four = 0, fourBC[3]={0, 20, 0}, fourBPC[3]={0, 0, 20}, fourGfade[2]={49, 0}, fourG[3]={0, 0, 0}, fourBfade[2]={49, 0}, fourB[3]={0, 0, 0}, fourRfade[2]={49, 0}, fourR[3]={0, 0, 0};
int r = 0, rBC[3]={0, 20, 0}, rBPC[3]={0, 0, 20}, rGfade[2]={49, 0}, rG[3]={0, 0, 0}, rBfade[2]={49, 0}, rB[3]={0, 0, 0}, rRfade[2]={49, 0}, rR[3]={0, 0, 0};
int f = 0, fBC[3]={0, 20, 0}, fBPC[3]={0, 0, 20}, fGfade[2]={49, 0}, fG[3]={0, 0, 0}, fBfade[2]={49, 0}, fB[3]={0, 0, 0}, fRfade[2]={49, 0}, fR[3]={0, 0, 0};
int b = 0, bBC[3]={0, 20, 0}, bBPC[3]={0, 0, 20}, bGfade[2]={49, 0}, bG[3]={0, 0, 0}, bBfade[2]={49, 0}, bB[3]={0, 0, 0}, bRfade[2]={49, 0}, bR[3]={0, 0, 0};
int space = 0, spaceBC[3]={0, 20, 0}, spaceBPC[3]={0, 0, 20}, spaceGfade[2]={49, 0}, spaceG[3]={0, 0, 0}, spaceBfade[2]={49, 0}, spaceB[3]={0, 0, 0}, spaceRfade[2]={49, 0}, spaceR[3]={0, 0, 0};
int five = 0, fiveBC[3]={0, 20, 0}, fiveBPC[3]={0, 0, 20}, fiveGfade[2]={49, 0}, fiveG[3]={0, 0, 0}, fiveBfade[2]={49, 0}, fiveB[3]={0, 0, 0}, fiveRfade[2]={49, 0}, fiveR[3]={0, 0, 0};
int six = 0, sixBC[3]={0, 20, 0}, sixBPC[3]={0, 0, 20}, sixGfade[2]={49, 0}, sixG[3]={0, 0, 0}, sixBfade[2]={49, 0}, sixB[3]={0, 0, 0}, sixRfade[2]={49, 0}, sixR[3]={0, 0, 0};
int y = 0, yBC[3]={0, 20, 0}, yBPC[3]={0, 0, 20}, yGfade[2]={49, 0}, yG[3]={0, 0, 0}, yBfade[2]={49, 0}, yB[3]={0, 0, 0}, yRfade[2]={49, 0}, yR[3]={0, 0, 0};
int t = 0, tBC[3]={0, 20, 0}, tBPC[3]={0, 0, 20}, tGfade[2]={49, 0}, tG[3]={0, 0, 0}, tBfade[2]={49, 0}, tB[3]={0, 0, 0}, tRfade[2]={49, 0}, tR[3]={0, 0, 0};
int h = 0, hBC[3]={0, 20, 0}, hBPC[3]={0, 0, 20}, hGfade[2]={49, 0}, hG[3]={0, 0, 0}, hBfade[2]={49, 0}, hB[3]={0, 0, 0}, hRfade[2]={49, 0}, hR[3]={0, 0, 0};
int g = 0, gBC[3]={0, 20, 0}, gBPC[3]={0, 0, 20}, gGfade[2]={49, 0}, gG[3]={0, 0, 0}, gBfade[2]={49, 0}, gB[3]={0, 0, 0}, gRfade[2]={49, 0}, gR[3]={0, 0, 0};
int f5 = 0, f5BC[3]={0, 20, 0}, f5BPC[3]={0, 0, 20}, f5Gfade[2]={49, 0}, f5G[3]={0, 0, 0}, f5Bfade[2]={49, 0}, f5B[3]={0, 0, 0}, f5Rfade[2]={49, 0}, f5R[3]={0, 0, 0};
int seven = 0, sevenBC[3]={0, 20, 0}, sevenBPC[3]={0, 0, 20}, sevenGfade[2]={49, 0}, sevenG[3]={0, 0, 0}, sevenBfade[2]={49, 0}, sevenB[3]={0, 0, 0}, sevenRfade[2]={49, 0}, sevenR[3]={0, 0, 0};
int u = 0, uBC[3]={0, 20, 0}, uBPC[3]={0, 0, 20}, uGfade[2]={49, 0}, uG[3]={0, 0, 0}, uBfade[2]={49, 0}, uB[3]={0, 0, 0}, uRfade[2]={49, 0}, uR[3]={0, 0, 0};
int i = 0, iBC[3]={0, 20, 0}, iBPC[3]={0, 0, 20}, iGfade[2]={49, 0}, iG[3]={0, 0, 0}, iBfade[2]={49, 0}, iB[3]={0, 0, 0}, iRfade[2]={49, 0}, iR[3]={0, 0, 0};
int j = 0, jBC[3]={0, 20, 0}, jBPC[3]={0, 0, 20}, jGfade[2]={49, 0}, jG[3]={0, 0, 0}, jBfade[2]={49, 0}, jB[3]={0, 0, 0}, jRfade[2]={49, 0}, jR[3]={0, 0, 0};
int n = 0, nBC[3]={0, 20, 0}, nBPC[3]={0, 0, 20}, nGfade[2]={49, 0}, nG[3]={0, 0, 0}, nBfade[2]={49, 0}, nB[3]={0, 0, 0}, nRfade[2]={49, 0}, nR[3]={0, 0, 0};
int f6 = 0, f6BC[3]={0, 20, 0}, f6BPC[3]={0, 0, 20}, f6Gfade[2]={49, 0}, f6G[3]={0, 0, 0}, f6Bfade[2]={49, 0}, f6B[3]={0, 0, 0}, f6Rfade[2]={49, 0}, f6R[3]={0, 0, 0};
int eight = 0, eightBC[3]={0, 20, 0}, eightBPC[3]={0, 0, 20}, eightGfade[2]={49, 0}, eightG[3]={0, 0, 0}, eightBfade[2]={49, 0}, eightB[3]={0, 0, 0}, eightRfade[2]={49, 0}, eightR[3]={0, 0, 0};
int nine = 0, nineBC[3]={0, 20, 0}, nineBPC[3]={0, 0, 20}, nineGfade[2]={49, 0}, nineG[3]={0, 0, 0}, nineBfade[2]={49, 0}, nineB[3]={0, 0, 0}, nineRfade[2]={49, 0}, nineR[3]={0, 0, 0};
int o = 0, oBC[3]={0, 20, 0}, oBPC[3]={0, 0, 20}, oGfade[2]={49, 0}, oG[3]={0, 0, 0}, oBfade[2]={49, 0}, oB[3]={0, 0, 0}, oRfade[2]={49, 0}, oR[3]={0, 0, 0};
int k = 0, kBC[3]={0, 20, 0}, kBPC[3]={0, 0, 20}, kGfade[2]={49, 0}, kG[3]={0, 0, 0}, kBfade[2]={49, 0}, kB[3]={0, 0, 0}, kRfade[2]={49, 0}, kR[3]={0, 0, 0};
int m = 0, mBC[3]={0, 20, 0}, mBPC[3]={0, 0, 20}, mGfade[2]={49, 0}, mG[3]={0, 0, 0}, mBfade[2]={49, 0}, mB[3]={0, 0, 0}, mRfade[2]={49, 0}, mR[3]={0, 0, 0};
int f7 = 0, f7BC[3]={0, 20, 0}, f7BPC[3]={0, 0, 20}, f7Gfade[2]={49, 0}, f7G[3]={0, 0, 0}, f7Bfade[2]={49, 0}, f7B[3]={0, 0, 0}, f7Rfade[2]={49, 0}, f7R[3]={0, 0, 0};
int zero = 0, zeroBC[3]={0, 20, 0}, zeroBPC[3]={0, 0, 20}, zeroGfade[2]={49, 0}, zeroG[3]={0, 0, 0}, zeroBfade[2]={49, 0}, zeroB[3]={0, 0, 0}, zeroRfade[2]={49, 0}, zeroR[3]={0, 0, 0};
int p = 0, pBC[3]={0, 20, 0}, pBPC[3]={0, 0, 20}, pGfade[2]={49, 0}, pG[3]={0, 0, 0}, pBfade[2]={49, 0}, pB[3]={0, 0, 0}, pRfade[2]={49, 0}, pR[3]={0, 0, 0};
int l = 0, lBC[3]={0, 20, 0}, lBPC[3]={0, 0, 20}, lGfade[2]={49, 0}, lG[3]={0, 0, 0}, lBfade[2]={49, 0}, lB[3]={0, 0, 0}, lRfade[2]={49, 0}, lR[3]={0, 0, 0};
int comma = 0, commaBC[3]={0, 20, 0}, commaBPC[3]={0, 0, 20}, commaGfade[2]={49, 0}, commaG[3]={0, 0, 0}, commaBfade[2]={49, 0}, commaB[3]={0, 0, 0}, commaRfade[2]={49, 0}, commaR[3]={0, 0, 0};
int ralt = 0, raltBC[3]={0, 20, 0}, raltBPC[3]={0, 0, 20}, raltGfade[2]={49, 0}, raltG[3]={0, 0, 0}, raltBfade[2]={49, 0}, raltB[3]={0, 0, 0}, raltRfade[2]={49, 0}, raltR[3]={0, 0, 0};
int f8 = 0, f8BC[3]={0, 20, 0}, f8BPC[3]={0, 0, 20}, f8Gfade[2]={49, 0}, f8G[3]={0, 0, 0}, f8Bfade[2]={49, 0}, f8B[3]={0, 0, 0}, f8Rfade[2]={49, 0}, f8R[3]={0, 0, 0};
int minus = 0, minusBC[3]={0, 20, 0}, minusBPC[3]={0, 0, 20}, minusGfade[2]={49, 0}, minusG[3]={0, 0, 0}, minusBfade[2]={49, 0}, minusB[3]={0, 0, 0}, minusRfade[2]={49, 0}, minusR[3]={0, 0, 0};
int lsqbracket = 0, lsqbracketBC[3]={0, 20, 0}, lsqbracketBPC[3]={0, 0, 20}, lsqbracketGfade[2]={49, 0}, lsqbracketG[3]={0, 0, 0}, lsqbracketBfade[2]={49, 0}, lsqbracketB[3]={0, 0, 0}, lsqbracketRfade[2]={49, 0}, lsqbracketR[3]={0, 0, 0};
int semicolon = 0, semicolonBC[3]={0, 20, 0}, semicolonBPC[3]={0, 0, 20}, semicolonGfade[2]={49, 0}, semicolonG[3]={0, 0, 0}, semicolonBfade[2]={49, 0}, semicolonB[3]={0, 0, 0}, semicolonRfade[2]={49, 0}, semicolonR[3]={0, 0, 0};
int period = 0, periodBC[3]={0, 20, 0}, periodBPC[3]={0, 0, 20}, periodGfade[2]={49, 0}, periodG[3]={0, 0, 0}, periodBfade[2]={49, 0}, periodB[3]={0, 0, 0}, periodRfade[2]={49, 0}, periodR[3]={0, 0, 0};
int rspecial = 0, rspecialBC[3]={0, 20, 0}, rspecialBPC[3]={0, 0, 20}, rspecialGfade[2]={49, 0}, rspecialG[3]={0, 0, 0}, rspecialBfade[2]={49, 0}, rspecialB[3]={0, 0, 0}, rspecialRfade[2]={49, 0}, rspecialR[3]={0, 0, 0};
int f9 = 0, f9BC[3]={0, 20, 0}, f9BPC[3]={0, 0, 20}, f9Gfade[2]={49, 0}, f9G[3]={0, 0, 0}, f9Bfade[2]={49, 0}, f9B[3]={0, 0, 0}, f9Rfade[2]={49, 0}, f9R[3]={0, 0, 0};
int equals = 0, equalsBC[3]={0, 20, 0}, equalsBPC[3]={0, 0, 20}, equalsGfade[2]={49, 0}, equalsG[3]={0, 0, 0}, equalsBfade[2]={49, 0}, equalsB[3]={0, 0, 0}, equalsRfade[2]={49, 0}, equalsR[3]={0, 0, 0};
int rsqbracket = 0, rsqbracketBC[3]={0, 20, 0}, rsqbracketBPC[3]={0, 0, 20}, rsqbracketGfade[2]={49, 0}, rsqbracketG[3]={0, 0, 0}, rsqbracketBfade[2]={49, 0}, rsqbracketB[3]={0, 0, 0}, rsqbracketRfade[2]={49, 0}, rsqbracketR[3]={0, 0, 0};
int apostrophe = 0, apostropheBC[3]={0, 20, 0}, apostropheBPC[3]={0, 0, 20}, apostropheGfade[2]={49, 0}, apostropheG[3]={0, 0, 0}, apostropheBfade[2]={49, 0}, apostropheB[3]={0, 0, 0}, apostropheRfade[2]={49, 0}, apostropheR[3]={0, 0, 0};
int fslash = 0, fslashBC[3]={0, 20, 0}, fslashBPC[3]={0, 0, 20}, fslashGfade[2]={49, 0}, fslashG[3]={0, 0, 0}, fslashBfade[2]={49, 0}, fslashB[3]={0, 0, 0}, fslashRfade[2]={49, 0}, fslashR[3]={0, 0, 0};
int menu = 0, menuBC[3]={0, 20, 0}, menuBPC[3]={0, 0, 20}, menuGfade[2]={49, 0}, menuG[3]={0, 0, 0}, menuBfade[2]={49, 0}, menuB[3]={0, 0, 0}, menuRfade[2]={49, 0}, menuR[3]={0, 0, 0};
int f10 = 0, f10BC[3]={0, 20, 0}, f10BPC[3]={0, 0, 20}, f10Gfade[2]={49, 0}, f10G[3]={0, 0, 0}, f10Bfade[2]={49, 0}, f10B[3]={0, 0, 0}, f10Rfade[2]={49, 0}, f10R[3]={0, 0, 0};
int backspace = 0, backspaceBC[3]={0, 20, 0}, backspaceBPC[3]={0, 0, 20}, backspaceGfade[2]={49, 0}, backspaceG[3]={0, 0, 0}, backspaceBfade[2]={49, 0}, backspaceB[3]={0, 0, 0}, backspaceRfade[2]={49, 0}, backspaceR[3]={0, 0, 0};
int bslash = 0, bslashBC[3]={0, 20, 0}, bslashBPC[3]={0, 0, 20}, bslashGfade[2]={49, 0}, bslashG[3]={0, 0, 0}, bslashBfade[2]={49, 0}, bslashB[3]={0, 0, 0}, bslashRfade[2]={49, 0}, bslashR[3]={0, 0, 0};
int enter = 0, enterBC[3]={0, 20, 0}, enterBPC[3]={0, 0, 20}, enterGfade[2]={49, 0}, enterG[3]={0, 0, 0}, enterBfade[2]={49, 0}, enterB[3]={0, 0, 0}, enterRfade[2]={49, 0}, enterR[3]={0, 0, 0};
int rshift = 0, rshiftBC[3]={0, 20, 0}, rshiftBPC[3]={0, 0, 20}, rshiftGfade[2]={49, 0}, rshiftG[3]={0, 0, 0}, rshiftBfade[2]={49, 0}, rshiftB[3]={0, 0, 0}, rshiftRfade[2]={49, 0}, rshiftR[3]={0, 0, 0};
int rctrl = 0, rctrlBC[3]={0, 20, 0}, rctrlBPC[3]={0, 0, 20}, rctrlGfade[2]={49, 0}, rctrlG[3]={0, 0, 0}, rctrlBfade[2]={49, 0}, rctrlB[3]={0, 0, 0}, rctrlRfade[2]={49, 0}, rctrlR[3]={0, 0, 0};
int f11 = 0, f11BC[3]={0, 20, 0}, f11BPC[3]={0, 0, 20}, f11Gfade[2]={49, 0}, f11G[3]={0, 0, 0}, f11Bfade[2]={49, 0}, f11B[3]={0, 0, 0}, f11Rfade[2]={49, 0}, f11R[3]={0, 0, 0};
int f12 = 0, f12BC[3]={0, 20, 0}, f12BPC[3]={0, 0, 20}, f12Gfade[2]={49, 0}, f12G[3]={0, 0, 0}, f12Bfade[2]={49, 0}, f12B[3]={0, 0, 0}, f12Rfade[2]={49, 0}, f12R[3]={0, 0, 0};
int up = 0, upBC[3]={0, 20, 0}, upBPC[3]={0, 0, 20}, upGfade[2]={49, 0}, upG[3]={0, 0, 0}, upBfade[2]={49, 0}, upB[3]={0, 0, 0}, upRfade[2]={49, 0}, upR[3]={0, 0, 0};
int down = 0, downBC[3]={0, 20, 0}, downBPC[3]={0, 0, 20}, downGfade[2]={49, 0}, downG[3]={0, 0, 0}, downBfade[2]={49, 0}, downB[3]={0, 0, 0}, downRfade[2]={49, 0}, downR[3]={0, 0, 0};
int right = 0, rightBC[3]={0, 20, 0}, rightBPC[3]={0, 0, 20}, rightGfade[2]={49, 0}, rightG[3]={0, 0, 0}, rightBfade[2]={49, 0}, rightB[3]={0, 0, 0}, rightRfade[2]={49, 0}, rightR[3]={0, 0, 0};
int left = 0, leftBC[3]={0, 20, 0}, leftBPC[3]={0, 0, 20}, leftGfade[2]={49, 0}, leftG[3]={0, 0, 0}, leftBfade[2]={49, 0}, leftB[3]={0, 0, 0}, leftRfade[2]={49, 0}, leftR[3]={0, 0, 0};
int insert = 0, insertBC[3]={0, 20, 0}, insertBPC[3]={0, 0, 20}, insertGfade[2]={49, 0}, insertG[3]={0, 0, 0}, insertBfade[2]={49, 0}, insertB[3]={0, 0, 0}, insertRfade[2]={49, 0}, insertR[3]={0, 0, 0};
int home = 0, homeBC[3]={0, 20, 0}, homeBPC[3]={0, 0, 20}, homeGfade[2]={49, 0}, homeG[3]={0, 0, 0}, homeBfade[2]={49, 0}, homeB[3]={0, 0, 0}, homeRfade[2]={49, 0}, homeR[3]={0, 0, 0};
int pageup = 0, pageupBC[3]={0, 20, 0}, pageupBPC[3]={0, 0, 20}, pageupGfade[2]={49, 0}, pageupG[3]={0, 0, 0}, pageupBfade[2]={49, 0}, pageupB[3]={0, 0, 0}, pageupRfade[2]={49, 0}, pageupR[3]={0, 0, 0};
int dlt = 0, dltBC[3]={0, 20, 0}, dltBPC[3]={0, 0, 20}, dltGfade[2]={49, 0}, dltG[3]={0, 0, 0}, dltBfade[2]={49, 0}, dltB[3]={0, 0, 0}, dltRfade[2]={49, 0}, dltR[3]={0, 0, 0};
int end = 0, endBC[3]={0, 20, 0}, endBPC[3]={0, 0, 20}, endGfade[2]={49, 0}, endG[3]={0, 0, 0}, endBfade[2]={49, 0}, endB[3]={0, 0, 0}, endRfade[2]={49, 0}, endR[3]={0, 0, 0};
int pagedown = 0, pagedownBC[3]={0, 20, 0}, pagedownBPC[3]={0, 0, 20}, pagedownGfade[2]={49, 0}, pagedownG[3]={0, 0, 0}, pagedownBfade[2]={49, 0}, pagedownB[3]={0, 0, 0}, pagedownRfade[2]={49, 0}, pagedownR[3]={0, 0, 0};
int macro = 0, macroS = 0, macroS1BC[3]={20, 0, 0},macroS2BC[3]={20, 20, 20}, macroBC[3]={0, 20, 0}, macroBPC[3]={0, 0, 20}, macroGfade[2]={49, 0}, macroG[3]={0, 0, 0}, macroBfade[2]={49, 0}, macroB[3]={0, 0, 0}, macroRfade[2]={49, 0}, macroR[3]={0, 0, 0}, macroFKBPCV[39]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int numlock = 0, numlockBC[3]={0, 20, 0}, numlockBPC[3]={0, 0, 20}, numlockGfade[2]={49, 0}, numlockG[3]={0, 0, 0}, numlockBfade[2]={49, 0}, numlockB[3]={0, 0, 0}, numlockRfade[2]={49, 0}, numlockR[3]={0, 0, 0};
int num7 = 0, num7BC[3]={0, 20, 0}, num7BPC[3]={0, 0, 20}, num7Gfade[2]={49, 0}, num7G[3]={0, 0, 0}, num7Bfade[2]={49, 0}, num7B[3]={0, 0, 0}, num7Rfade[2]={49, 0}, num7R[3]={0, 0, 0};
int num4 = 0, num4BC[3]={0, 20, 0}, num4BPC[3]={0, 0, 20}, num4Gfade[2]={49, 0}, num4G[3]={0, 0, 0}, num4Bfade[2]={49, 0}, num4B[3]={0, 0, 0}, num4Rfade[2]={49, 0}, num4R[3]={0, 0, 0};
int num1 = 0, num1BC[3]={0, 20, 0}, num1BPC[3]={0, 0, 20}, num1Gfade[2]={49, 0}, num1G[3]={0, 0, 0}, num1Bfade[2]={49, 0}, num1B[3]={0, 0, 0}, num1Rfade[2]={49, 0}, num1R[3]={0, 0, 0};
int num0 = 0, num0BC[3]={0, 20, 0}, num0BPC[3]={0, 0, 20}, num0Gfade[2]={49, 0}, num0G[3]={0, 0, 0}, num0Bfade[2]={49, 0}, num0B[3]={0, 0, 0}, num0Rfade[2]={49, 0}, num0R[3]={0, 0, 0};
int bright = 0, brightBC[3]={0, 20, 0}, brightBPC[3]={0, 0, 20}, brightGfade[2]={49, 0}, brightG[3]={0, 0, 0}, brightBfade[2]={49, 0}, brightB[3]={0, 0, 0}, brightRfade[2]={49, 0}, brightR[3]={0, 0, 0};
int numfslash = 0, numfslashBC[3]={0, 20, 0}, numfslashBPC[3]={0, 0, 20}, numfslashGfade[2]={49, 0}, numfslashG[3]={0, 0, 0}, numfslashBfade[2]={49, 0}, numfslashB[3]={0, 0, 0}, numfslashRfade[2]={49, 0}, numfslashR[3]={0, 0, 0};
int num8 = 0, num8BC[3]={0, 20, 0}, num8BPC[3]={0, 0, 20}, num8Gfade[2]={49, 0}, num8G[3]={0, 0, 0}, num8Bfade[2]={49, 0}, num8B[3]={0, 0, 0}, num8Rfade[2]={49, 0}, num8R[3]={0, 0, 0};
int num5 = 0, num5BC[3]={0, 20, 0}, num5BPC[3]={0, 0, 20}, num5Gfade[2]={49, 0}, num5G[3]={0, 0, 0}, num5Bfade[2]={49, 0}, num5B[3]={0, 0, 0}, num5Rfade[2]={49, 0}, num5R[3]={0, 0, 0};
int num2 = 0, num2BC[3]={0, 20, 0}, num2BPC[3]={0, 0, 20}, num2Gfade[2]={49, 0}, num2G[3]={0, 0, 0}, num2Bfade[2]={49, 0}, num2B[3]={0, 0, 0}, num2Rfade[2]={49, 0}, num2R[3]={0, 0, 0};
int numperiod = 0, numperiodBC[3]={0, 20, 0}, numperiodBPC[3]={0, 0, 20}, numperiodGfade[2]={49, 0}, numperiodG[3]={0, 0, 0}, numperiodBfade[2]={49, 0}, numperiodB[3]={0, 0, 0}, numperiodRfade[2]={49, 0}, numperiodR[3]={0, 0, 0};
int mute = 0, muteBC[3]={0, 20, 0}, muteBPC[3]={0, 0, 20}, muteGfade[2]={49, 0}, muteG[3]={0, 0, 0}, muteBfade[2]={49, 0}, muteB[3]={0, 0, 0}, muteRfade[2]={49, 0}, muteR[3]={0, 0, 0};
int asterisk = 0, asteriskBC[3]={0, 20, 0}, asteriskBPC[3]={0, 0, 20}, asteriskGfade[2]={49, 0}, asteriskG[3]={0, 0, 0}, asteriskBfade[2]={49, 0}, asteriskB[3]={0, 0, 0}, asteriskRfade[2]={49, 0}, asteriskR[3]={0, 0, 0};
int num9 = 0, num9BC[3]={0, 20, 0}, num9BPC[3]={0, 0, 20}, num9Gfade[2]={49, 0}, num9G[3]={0, 0, 0}, num9Bfade[2]={49, 0}, num9B[3]={0, 0, 0}, num9Rfade[2]={49, 0}, num9R[3]={0, 0, 0};
int num6 = 0, num6BC[3]={0, 20, 0}, num6BPC[3]={0, 0, 20}, num6Gfade[2]={49, 0}, num6G[3]={0, 0, 0}, num6Bfade[2]={49, 0}, num6B[3]={0, 0, 0}, num6Rfade[2]={49, 0}, num6R[3]={0, 0, 0};
int num3 = 0, num3BC[3]={0, 20, 0}, num3BPC[3]={0, 0, 20}, num3Gfade[2]={49, 0}, num3G[3]={0, 0, 0}, num3Bfade[2]={49, 0}, num3B[3]={0, 0, 0}, num3Rfade[2]={49, 0}, num3R[3]={0, 0, 0};
int numenter = 0, numenterBC[3]={0, 20, 0}, numenterBPC[3]={0, 0, 20}, numenterGfade[2]={49, 0}, numenterG[3]={0, 0, 0}, numenterBfade[2]={49, 0}, numenterB[3]={0, 0, 0}, numenterRfade[2]={49, 0}, numenterR[3]={0, 0, 0};
int prtscrn = 0, prtscrnBC[3]={0, 20, 0}, prtscrnBPC[3]={0, 0, 20}, prtscrnGfade[2]={49, 0}, prtscrnG[3]={0, 0, 0}, prtscrnBfade[2]={49, 0}, prtscrnB[3]={0, 0, 0}, prtscrnRfade[2]={49, 0}, prtscrnR[3]={0, 0, 0};
int scrolllock = 0, scrolllockBC[3]={0, 20, 0}, scrolllockBPC[3]={0, 0, 20}, scrolllockGfade[2]={49, 0}, scrolllockG[3]={0, 0, 0}, scrolllockBfade[2]={49, 0}, scrolllockB[3]={0, 0, 0}, scrolllockRfade[2]={49, 0}, scrolllockR[3]={0, 0, 0};
int pause = 0, pauseBC[3]={0, 20, 0}, pauseBPC[3]={0, 0, 20}, pauseGfade[2]={49, 0}, pauseG[3]={0, 0, 0}, pauseBfade[2]={49, 0}, pauseB[3]={0, 0, 0}, pauseRfade[2]={49, 0}, pauseR[3]={0, 0, 0};
int numminus = 0, numminusBC[3]={0, 20, 0}, numminusBPC[3]={0, 0, 20}, numminusGfade[2]={49, 0}, numminusG[3]={0, 0, 0}, numminusBfade[2]={49, 0}, numminusB[3]={0, 0, 0}, numminusRfade[2]={49, 0}, numminusR[3]={0, 0, 0};
int plus = 0, plusBC[3]={0, 20, 0}, plusBPC[3]={0, 0, 20}, plusGfade[2]={49, 0}, plusG[3]={0, 0, 0}, plusBfade[2]={49, 0}, plusB[3]={0, 0, 0}, plusRfade[2]={49, 0}, plusR[3]={0, 0, 0};
void sh_cp(int cdata);
void st_cp();
int fader_state(int key, int keyBC, int keyBPC, int* keyCfadestep, int* keyCfadetime, int* keyCtime, int* keyCstate, int* keyCdcs);
void sh_cp(int cdata)	//input rdata and cdata states into the 74HC595 chips, if cdata is 1 make cdata state high then low 
{
	if (cdata == 0)	//if cdata is 0 pulse clock pin
	{
		PORTA |= (1<<PA2);	//set clock pin high
		PORTA &= ~(1<<PA2);	//set clock pin low
	}	//end if (cdata == 0)
	else
	{
		PORTA |= (1<<PA1);	//set cdata pin high
		PORTA |= (1<<PA2);	//set clock pin high
		PORTA &= ~(1<<PA2);	//set clock pin low
		PORTA &= ~(1<<PA1);	//set cdata pin high
	}
}	//end sh_cp() function
void st_cp()	//latch all 74HC595 states
{
	PORTA |= (1<<PA3);	//set latch pin high
	PORTA &= ~(1<<PA3);	//set latch pin low
}	//end st_cp() function
int fader_state(int key, int keyBC, int keyBPC, int* keyCfadestep, int* keyCfadetime, int* keyCtime, int* keyCstate, int* keyCdcs) //key fader and LED color function
{
	if (key==1)	//if key is pressed
	{
		if (keyBPC > 0)	//if keyButtonPressColor is on
		{
			*keyCtime = keyBPC;	//reset fader and key duty cycle to beginning state of keyButtonPressColor
			*keyCstate = 1;
			*keyCdcs = 0;
			*keyCfadestep = 1;
		}	//end if (keyBPC > 0)
		else
		{
			*keyCtime = 20;	//reset fader to off state and reset key duty cycle
			*keyCstate = 0;
			*keyCdcs = 0;
			*keyCfadestep = 49;
		}	//end else
	}	//end if (key==1)
	else
	{
		if (*keyCdcs==2) //if LED has completed duty cycle
		{
			if (*keyCfadestep < 49)	//if fader timer has not run out
			{
				if (keyBPC < keyBC)	//if keyButtonPressColor is smaller than keyButtonColor
				{
					*keyCfadetime = keyBC - keyBPC;	//math to figure out time on in duty cycle
					*keyCfadetime /= 49;
					*keyCfadetime *= *keyCfadestep;
					*keyCfadetime = keyBC - *keyCfadetime;
					*keyCtime = *keyCfadetime;
				}	//end if (keyBPC < keyBC)
				else if (keyBPC > keyBC)	//if keyButtonPressColor is bigger than keyButtonColor
				{
					*keyCfadetime = keyBPC - keyBC;	//math to figure out time on in duty cycle
					*keyCfadetime /= 49;
					*keyCfadetime *= *keyCfadestep;
					*keyCtime = *keyCfadetime;
				}	//end else if (keyBPC > keyBC)
				else
				{
					*keyCtime = keyBC;	//if keyButtonPressColor and keyButtonColor are the same put keyButtonColor in effect
					*keyCstate = 1;
					*keyCfadestep = 48;
				}	//end else
				++*keyCfadestep;
			}	//end if (*keyCfadestep < 49)
			else
			{
				if (keyBC > 0)	//if keyButtonColor is on
				{
					*keyCtime = keyBC;	//make keyColortime state of keyButtonColor and keyCstate 1
					*keyCstate = 1;
				}	//end if (keyBC > 0)
				else
				{
					*keyCtime = 20;	//make keyColortime full duty cycle and keyCstate to 0
					*keyCstate = 0;
				}	//end else
			}	//end else
			*keyCdcs = 0;	//make keyCdutycyclestate 0 to start new duty cycle
		}	//end if (*keyCdcs==2)
		else if (*keyCdcs==1 && *keyCtime==0)	//if LED is done with first stage of duty cycle
		{
			if (*keyCfadestep < 49)	//if keyColorfadestep is below 49
				*keyCtime = 20 - *keyCfadetime;	//math for time left until end of duty cycle
			else
				*keyCtime = 20 - keyBC;	//math for time left until end of duty cycle
			*keyCstate = 0;//make key finish second stage of duty cycle off
		}
		else if (*keyCdcs==0 && *keyCtime==0)	//if LED is ready to begin first duty cycle
		{
			if (keyBC > 0)	//if keyButtonColor is on
			{
				*keyCtime = keyBC;	//make keyColortime state of keyButtonColor and keyCstate 1
				*keyCstate = 1;
			}	//end if (keyBC > 0)
			else
			{
				*keyCtime = 20;	//make keyColortime full duty cycle and keyCstate to 0
				*keyCstate = 0;
			}	//end else
		}	//end else if (*keyCdcs==0 && *keyCtime==0)
	}	//end else
	if (*keyCstate==1)	//if keyColorstate is 1
	{
		PORTA |= (1<<PA0);	//rdata on
		--*keyCtime;	//increment keyColortime
		if (*keyCtime==0||*keyCtime==19)	//if keyColortime is 0 or 19
		{
			++*keyCdcs;	//increment keyColordutycyclestate
		}	//end if (*keyCtime==0||*keyCtime==19)
	}	//if (*keyCstate==1)
	else
	{
		PORTA &= ~(1<<PA0);	//rdata off
		--*keyCtime;	//increment keyColortime
		if (*keyCtime==0||*keyCtime==19)	//if keyColortime is 0 or 19
		{
			++*keyCdcs;	//increment keyColordutycyclestate
		}	//end if (*keyCtime==0||*keyCtime==19)
	}	//else
}	//end fader_state() function
int main(void)
{
	DDRA = (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
	PORTA = (0<<PA0)|(0<<PA1)|(0<<PA2)|(0<<PA3);
	while(1)
	{
		if (row==0)
		{
			PORTA |= (1<<0);
			esc = PINA0;
			tilda = PINA1;
			tab = PINA2;
			caps = PINA3;
			lshift = PINA4;
			lctrl = PINA5;
			f1 = PINA6;
			one = PINA7;
			q = PINA8;
			a = PINA9;
			PORTA &= ~(1<<0);
			row++;
		}
		else if (row==1)
		{
			PORTA |= (1<<1);
			z = PINA0;
			lspecial = PINA1;
			f2 = PINA2;
			two = PINA3;
			w = PINA4;
			s = PINA5;
			x = PINA6;
			lalt = PINA7;
			f3 = PINA8;
			three = PINA9;
			PORTA &= ~(1<<1);
			row++;
		}
		else if (row==2)
		{
			PORTA |= (1<<2);
			e = PINA0;
			d = PINA1;
			c = PINA2;
			v = PINA3;
			f4 = PINA4;
			four = PINA5;
			r = PINA6;
			f = PINA7;
			b = PINA8;
			space = PINA9;
			PORTA &= ~(1<<2);
			row++;
		}
		else if (row==3)
		{
			PORTA |= (1<<3);
			five = PINA0;
			six = PINA1;
			y = PINA2;
			t = PINA3;
			h = PINA4;
			g = PINA5;
			f5 = PINA6;
			seven = PINA7;
			u = PINA8;
			i = PINA9;
			PORTA &= ~(1<<3);
			row++;
		}
		else if (row==4)
		{
			PORTA |= (1<<4);
			j = PINA0;
			n = PINA1;
			f6 = PINA2;
			eight = PINA3;
			nine = PINA4;
			o = PINA5;
			k = PINA6;
			m = PINA7;
			f7 = PINA8;
			zero = PINA9;
			PORTA &= ~(1<<4);
			row++;
		}
		else if (row==5)
		{
			PORTA |= (1<<5);
			p = PINA0;
			l = PINA1;
			comma = PINA2;
			ralt = PINA3;
			f8 = PINA4;
			minus = PINA5;
			lsqbracket = PINA6;
			semicolon = PINA7;
			period = PINA8;
			rspecial = PINA9;
			PORTA &= ~(1<<5);
			row++;
		}
		else if (row==6)
		{
			PORTA |= (1<<6);
			f9 = PINA0;
			equals = PINA1;
			rsqbracket = PINA2;
			apostrophe = PINA3;
			fslash = PINA4;
			menu = PINA5;
			f10 = PINA6;
			backspace = PINA7;
			bslash = PINA8;
			enter = PINA9;
			PORTA &= ~(1<<6);
			row++;
		}
		else if (row==7)
		{
			PORTA |= (1<<7);
			rshift = PINA0;
			rctrl = PINA1;
			f11 = PINA2;
			f12 = PINA3;
			up = PINA4;
			down = PINA5;
			right = PINA6;
			left = PINA7;
			insert = PINA8;
			home = PINA9;
			PORTA &= ~(1<<7);
			row++;
		}
		else if (row==8)
		{
			PORTA |= (1<<8);
			pageup = PINA0;
			dlt = PINA1;
			end = PINA2;
			pagedown = PINA3;
			macro = PINA4;
			numlock = PINA5;
			num7 = PINA6;
			num4 = PINA7;
			num1 = PINA8;
			num0 = PINA9;
			PORTA &= ~(1<<8);
			row++;
		}
		else if (row==9)
		{
			PORTA |= (1<<9);
			bright = PINA0;
			numfslash = PINA1;
			num8 = PINA2;
			num5 = PINA3;
			num2 = PINA4;
			numperiod = PINA5;
			mute = PINA6;
			asterisk = PINA7;
			num9 = PINA8;
			num6 = PINA9;
			PORTA &= ~(1<<9);
			row++;
		}
		else if (row==10)
		{
			PORTA |= (1<<10);
			num3 = PINA0;
			numenter = PINA1;
			prtscrn = PINA2;
			scrolllock = PINA3;
			pause = PINA4;
			numminus = PINA5;
			plus = PINA6;
			PORTA &= ~(1<<10);
			row = 0;
		}
		if (column==0)
		{
			fader_state(esc, escBC[0], escBPC[0], &escGfade[0], &escGfade[1], &escG[0], &escG[1], &escG[2]);	//the fader state function sets the rdata pin for this clock cycle
			sh_cp(1);	//the sh_cp function sets the state of cdata low if sent 0, and high if 1 as well as setting the clock pin
			fader_state(esc, escBC[1], escBPC[1], &escBfade[0], &escBfade[1], &escB[0], &escB[1], &escB[2]);
			sh_cp(0);
			fader_state(esc, escBC[2], escBPC[2], &escRfade[0], &escRfade[1], &escR[0], &escR[1], &escR[2]);
			sh_cp(0);
			fader_state(tilda, tildaBC[0], tildaBPC[0], &tildaGfade[0], &tildaGfade[1], &tildaG[0], &tildaG[1], &tildaG[2]);
			sh_cp(0);
			fader_state(tilda, tildaBC[1], tildaBPC[1], &tildaBfade[0], &tildaBfade[1], &tildaB[0], &tildaB[1], &tildaB[2]);
			sh_cp(0);
			fader_state(tilda, tildaBC[2], tildaBPC[2], &tildaRfade[0], &tildaRfade[1], &tildaR[0], &tildaR[1], &tildaR[2]);
			sh_cp(0);
			fader_state(tab, tabBC[0], tabBPC[0], &tabGfade[0], &tabGfade[1], &tabG[0], &tabG[1], &tabG[2]);
			sh_cp(0);
			fader_state(tab, tabBC[1], tabBPC[1], &tabBfade[0], &tabBfade[1], &tabB[0], &tabB[1], &tabB[2]);
			sh_cp(0);
			fader_state(tab, tabBC[2], tabBPC[2], &tabRfade[0], &tabRfade[1], &tabR[0], &tabR[1], &tabR[2]);
			sh_cp(0);
			fader_state(caps, capsBC[0], capsBPC[0], &capsGfade[0], &capsGfade[1], &capsG[0], &capsG[1], &capsG[2]);
			sh_cp(0);
			fader_state(caps, capsBC[1], capsBPC[1], &capsBfade[0], &capsBfade[1], &capsB[0], &capsB[1], &capsB[2]);
			sh_cp(0);
			fader_state(caps, capsBC[2], capsBPC[2], &capsRfade[0], &capsRfade[1], &capsR[0], &capsR[1], &capsR[2]);
			sh_cp(0);
			fader_state(lshift, lshiftBC[0], lshiftBPC[0], &lshiftGfade[0], &lshiftGfade[1], &lshiftG[0], &lshiftG[1], &lshiftG[2]);
			sh_cp(0);
			fader_state(lshift, lshiftBC[1], lshiftBPC[1], &lshiftBfade[0], &lshiftBfade[1], &lshiftB[0], &lshiftB[1], &lshiftB[2]);
			sh_cp(0);
			fader_state(lshift, lshiftBC[2], lshiftBPC[2], &lshiftRfade[0], &lshiftRfade[1], &lshiftR[0], &lshiftR[1], &lshiftR[2]);
			sh_cp(0);
			fader_state(lctrl, lctrlBC[0], lctrlBPC[0], &lctrlGfade[0], &lctrlGfade[1], &lctrlG[0], &lctrlG[1], &lctrlG[2]);
			sh_cp(0);
			fader_state(lctrl, lctrlBC[1], lctrlBPC[1], &lctrlBfade[0], &lctrlBfade[1], &lctrlB[0], &lctrlB[1], &lctrlB[2]);
			sh_cp(0);
			fader_state(lctrl, lctrlBC[2], lctrlBPC[2], &lctrlRfade[0], &lctrlRfade[1], &lctrlR[0], &lctrlR[1], &lctrlR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==0)
		else if (column==1)
		{
			fader_state(f1, f1BC[0], f1BPC[0], &f1Gfade[0], &f1Gfade[1], &f1G[0], &f1G[1], &f1G[2]);
			sh_cp(0);
			fader_state(f1, f1BC[1], f1BPC[1], &f1Bfade[0], &f1Bfade[1], &f1B[0], &f1B[1], &f1B[2]);
			sh_cp(1);
			fader_state(f1, f1BC[2], f1BPC[2], &f1Rfade[0], &f1Rfade[1], &f1R[0], &f1R[1], &f1R[2]);
			sh_cp(0);
			fader_state(one, oneBC[0], oneBPC[0], &oneGfade[0], &oneGfade[1], &oneG[0], &oneG[1], &oneG[2]);
			sh_cp(0);
			fader_state(one, oneBC[1], oneBPC[1], &oneBfade[0], &oneBfade[1], &oneB[0], &oneB[1], &oneB[2]);
			sh_cp(0);
			fader_state(one, oneBC[2], oneBPC[2], &oneRfade[0], &oneRfade[1], &oneR[0], &oneR[1], &oneR[2]);
			sh_cp(0);
			fader_state(q, qBC[0], qBPC[0], &qGfade[0], &qGfade[1], &qG[0], &qG[1], &qG[2]);
			sh_cp(0);
			fader_state(q, qBC[1], qBPC[1], &qBfade[0], &qBfade[1], &qB[0], &qB[1], &qB[2]);
			sh_cp(0);
			fader_state(q, qBC[2], qBPC[2], &qRfade[0], &qRfade[1], &qR[0], &qR[1], &qR[2]);
			sh_cp(0);
			fader_state(a, aBC[0], aBPC[0], &aGfade[0], &aGfade[1], &aG[0], &aG[1], &aG[2]);
			sh_cp(0);
			fader_state(a, aBC[1], aBPC[1], &aBfade[0], &aBfade[1], &aB[0], &aB[1], &aB[2]);
			sh_cp(0);
			fader_state(a, aBC[2], aBPC[2], &aRfade[0], &aRfade[1], &aR[0], &aR[1], &aR[2]);
			sh_cp(0);
			fader_state(z, zBC[0], zBPC[0], &zGfade[0], &zGfade[1], &zG[0], &zG[1], &zG[2]);
			sh_cp(0);
			fader_state(z, zBC[1], zBPC[1], &zBfade[0], &zBfade[1], &zB[0], &zB[1], &zB[2]);
			sh_cp(0);
			fader_state(z, zBC[2], zBPC[2], &zRfade[0], &zRfade[1], &zR[0], &zR[1], &zR[2]);
			sh_cp(0);
			fader_state(lspecial, lspecialBC[0], lspecialBPC[0], &lspecialGfade[0], &lspecialGfade[1], &lspecialG[0], &lspecialG[1], &lspecialG[2]);
			sh_cp(0);
			fader_state(lspecial, lspecialBC[1], lspecialBPC[1], &lspecialBfade[0], &lspecialBfade[1], &lspecialB[0], &lspecialB[1], &lspecialB[2]);
			sh_cp(0);
			fader_state(lspecial, lspecialBC[2], lspecialBPC[2], &lspecialRfade[0], &lspecialRfade[1], &lspecialR[0], &lspecialR[1], &lspecialR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==1)
		else if (column==2)
		{
			fader_state(f2, f2BC[0], f2BPC[0], &f2Gfade[0], &f2Gfade[1], &f2G[0], &f2G[1], &f2G[2]);
			sh_cp(0);
			fader_state(f2, f2BC[1], f2BPC[1], &f2Bfade[0], &f2Bfade[1], &f2B[0], &f2B[1], &f2B[2]);
			sh_cp(0);
			fader_state(f2, f2BC[2], f2BPC[2], &f2Rfade[0], &f2Rfade[1], &f2R[0], &f2R[1], &f2R[2]);
			sh_cp(1);
			fader_state(two, twoBC[0], twoBPC[0], &twoGfade[0], &twoGfade[1], &twoG[0], &twoG[1], &twoG[2]);
			sh_cp(0);
			fader_state(two, twoBC[1], twoBPC[1], &twoBfade[0], &twoBfade[1], &twoB[0], &twoB[1], &twoB[2]);
			sh_cp(0);
			fader_state(two, twoBC[2], twoBPC[2], &twoRfade[0], &twoRfade[1], &twoR[0], &twoR[1], &twoR[2]);
			sh_cp(0);
			fader_state(w, wBC[0], wBPC[0], &wGfade[0], &wGfade[1], &wG[0], &wG[1], &wG[2]);
			sh_cp(0);
			fader_state(w, wBC[1], wBPC[1], &wBfade[0], &wBfade[1], &wB[0], &wB[1], &wB[2]);
			sh_cp(0);
			fader_state(w, wBC[2], wBPC[2], &wRfade[0], &wRfade[1], &wR[0], &wR[1], &wR[2]);
			sh_cp(0);
			fader_state(s, sBC[0], sBPC[0], &sGfade[0], &sGfade[1], &sG[0], &sG[1], &sG[2]);
			sh_cp(0);
			fader_state(s, sBC[1], sBPC[1], &sBfade[0], &sBfade[1], &sB[0], &sB[1], &sB[2]);
			sh_cp(0);
			fader_state(s, sBC[2], sBPC[2], &sRfade[0], &sRfade[1], &sR[0], &sR[1], &sR[2]);
			sh_cp(0);
			fader_state(x, xBC[0], xBPC[0], &xGfade[0], &xGfade[1], &xG[0], &xG[1], &xG[2]);
			sh_cp(0);
			fader_state(x, xBC[1], xBPC[1], &xBfade[0], &xBfade[1], &xB[0], &xB[1], &xB[2]);
			sh_cp(0);
			fader_state(x, xBC[2], xBPC[2], &xRfade[0], &xRfade[1], &xR[0], &xR[1], &xR[2]);
			sh_cp(0);
			fader_state(lalt, laltBC[0], laltBPC[0], &laltGfade[0], &laltGfade[1], &laltG[0], &laltG[1], &laltG[2]);
			sh_cp(0);
			fader_state(lalt, laltBC[1], laltBPC[1], &laltBfade[0], &laltBfade[1], &laltB[0], &laltB[1], &laltB[2]);
			sh_cp(0);
			fader_state(lalt, laltBC[2], laltBPC[2], &laltRfade[0], &laltRfade[1], &laltR[0], &laltR[1], &laltR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==2)
		else if (column==3)
		{
			fader_state(f3, f3BC[0], f3BPC[0], &f3Gfade[0], &f3Gfade[1], &f3G[0], &f3G[1], &f3G[2]);
			sh_cp(0);
			fader_state(f3, f3BC[1], f3BPC[1], &f3Bfade[0], &f3Bfade[1], &f3B[0], &f3B[1], &f3B[2]);
			sh_cp(0);
			fader_state(f3, f3BC[2], f3BPC[2], &f3Rfade[0], &f3Rfade[1], &f3R[0], &f3R[1], &f3R[2]);
			sh_cp(0);
			fader_state(three, threeBC[0], threeBPC[0], &threeGfade[0], &threeGfade[1], &threeG[0], &threeG[1], &threeG[2]);
			sh_cp(1);
			fader_state(three, threeBC[1], threeBPC[1], &threeBfade[0], &threeBfade[1], &threeB[0], &threeB[1], &threeB[2]);
			sh_cp(0);
			fader_state(three, threeBC[2], threeBPC[2], &threeRfade[0], &threeRfade[1], &threeR[0], &threeR[1], &threeR[2]);
			sh_cp(0);
			fader_state(e, eBC[0], eBPC[0], &eGfade[0], &eGfade[1], &eG[0], &eG[1], &eG[2]);
			sh_cp(0);
			fader_state(e, eBC[1], eBPC[1], &eBfade[0], &eBfade[1], &eB[0], &eB[1], &eB[2]);
			sh_cp(0);
			fader_state(e, eBC[2], eBPC[2], &eRfade[0], &eRfade[1], &eR[0], &eR[1], &eR[2]);
			sh_cp(0);
			fader_state(d, dBC[0], dBPC[0], &dGfade[0], &dGfade[1], &dG[0], &dG[1], &dG[2]);
			sh_cp(0);
			fader_state(d, dBC[1], dBPC[1], &dBfade[0], &dBfade[1], &dB[0], &dB[1], &dB[2]);
			sh_cp(0);
			fader_state(d, dBC[2], dBPC[2], &dRfade[0], &dRfade[1], &dR[0], &dR[1], &dR[2]);
			sh_cp(0);
			fader_state(c, cBC[0], cBPC[0], &cGfade[0], &cGfade[1], &cG[0], &cG[1], &cG[2]);
			sh_cp(0);
			fader_state(c, cBC[1], cBPC[1], &cBfade[0], &cBfade[1], &cB[0], &cB[1], &cB[2]);
			sh_cp(0);
			fader_state(c, cBC[2], cBPC[2], &cRfade[0], &cRfade[1], &cR[0], &cR[1], &cR[2]);
			sh_cp(0);
			fader_state(v, vBC[0], vBPC[0], &vGfade[0], &vGfade[1], &vG[0], &vG[1], &vG[2]);
			sh_cp(0);
			fader_state(v, vBC[1], vBPC[1], &vBfade[0], &vBfade[1], &vB[0], &vB[1], &vB[2]);
			sh_cp(0);
			fader_state(v, vBC[2], vBPC[2], &vRfade[0], &vRfade[1], &vR[0], &vR[1], &vR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==3)
		else if (column==4)
		{
			fader_state(f, fBC[0], fBPC[0], &fGfade[0], &fGfade[1], &fG[0], &fG[1], &fG[2]);
			sh_cp(0);
			fader_state(f, fBC[1], fBPC[1], &fBfade[0], &fBfade[1], &fB[0], &fB[1], &fB[2]);
			sh_cp(0);
			fader_state(f, fBC[2], fBPC[2], &fRfade[0], &fRfade[1], &fR[0], &fR[1], &fR[2]);
			sh_cp(0);
			fader_state(four, fourBC[0], fourBPC[0], &fourGfade[0], &fourGfade[1], &fourG[0], &fourG[1], &fourG[2]);
			sh_cp(0);
			fader_state(four, fourBC[1], fourBPC[1], &fourBfade[0], &fourBfade[1], &fourB[0], &fourB[1], &fourB[2]);
			sh_cp(1);
			fader_state(four, fourBC[2], fourBPC[2], &fourRfade[0], &fourRfade[1], &fourR[0], &fourR[1], &fourR[2]);
			sh_cp(0);
			fader_state(r, rBC[0], rBPC[0], &rGfade[0], &rGfade[1], &rG[0], &rG[1], &rG[2]);
			sh_cp(0);
			fader_state(r, rBC[1], rBPC[1], &rBfade[0], &rBfade[1], &rB[0], &rB[1], &rB[2]);
			sh_cp(0);
			fader_state(r, rBC[2], rBPC[2], &rRfade[0], &rRfade[1], &rR[0], &rR[1], &rR[2]);
			sh_cp(0);
			fader_state(f, fBC[0], fBPC[0], &fGfade[0], &fGfade[1], &fG[0], &fG[1], &fG[2]);
			sh_cp(0);
			fader_state(f, fBC[1], fBPC[1], &fBfade[0], &fBfade[1], &fB[0], &fB[1], &fB[2]);
			sh_cp(0);
			fader_state(f, fBC[2], fBPC[2], &fRfade[0], &fRfade[1], &fR[0], &fR[1], &fR[2]);
			sh_cp(0);
			fader_state(b, bBC[0], bBPC[0], &bGfade[0], &bGfade[1], &bG[0], &bG[1], &bG[2]);
			sh_cp(0);
			fader_state(b, bBC[1], bBPC[1], &bBfade[0], &bBfade[1], &bB[0], &bB[1], &bB[2]);
			sh_cp(0);
			fader_state(b, bBC[2], bBPC[2], &bRfade[0], &bRfade[1], &bR[0], &bR[1], &bR[2]);
			sh_cp(0);
			fader_state(space, spaceBC[0], spaceBPC[0], &spaceGfade[0], &spaceGfade[1], &spaceG[0], &spaceG[1], &spaceG[2]);
			sh_cp(0);
			fader_state(space, spaceBC[1], spaceBPC[1], &spaceBfade[0], &spaceBfade[1], &spaceB[0], &spaceB[1], &spaceB[2]);
			sh_cp(0);
			fader_state(space, spaceBC[2], spaceBPC[2], &spaceRfade[0], &spaceRfade[1], &spaceR[0], &spaceR[1], &spaceR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==4)
		else if (column==5)
		{
			fader_state(five, fiveBC[0], fiveBPC[0], &fiveGfade[0], &fiveGfade[1], &fiveG[0], &fiveG[1], &fiveG[2]);
			sh_cp(0);
			fader_state(five, fiveBC[1], fiveBPC[1], &fiveBfade[0], &fiveBfade[1], &fiveB[0], &fiveB[1], &fiveB[2]);
			sh_cp(0);
			fader_state(five, fiveBC[2], fiveBPC[2], &fiveRfade[0], &fiveRfade[1], &fiveR[0], &fiveR[1], &fiveR[2]);
			sh_cp(0);
			fader_state(six, sixBC[0], sixBPC[0], &sixGfade[0], &sixGfade[1], &sixG[0], &sixG[1], &sixG[2]);
			sh_cp(0);
			fader_state(six, sixBC[1], sixBPC[1], &sixBfade[0], &sixBfade[1], &sixB[0], &sixB[1], &sixB[2]);
			sh_cp(0);
			fader_state(six, sixBC[2], sixBPC[2], &sixRfade[0], &sixRfade[1], &sixR[0], &sixR[1], &sixR[2]);
			sh_cp(1);
			fader_state(t, tBC[0], tBPC[0], &tGfade[0], &tGfade[1], &tG[0], &tG[1], &tG[2]);
			sh_cp(0);
			fader_state(t, tBC[1], tBPC[1], &tBfade[0], &tBfade[1], &tB[0], &tB[1], &tB[2]);
			sh_cp(0);
			fader_state(t, tBC[2], tBPC[2], &tRfade[0], &tRfade[1], &tR[0], &tR[1], &tR[2]);
			sh_cp(0);
			fader_state(y, yBC[0], yBPC[0], &yGfade[0], &yGfade[1], &yG[0], &yG[1], &yG[2]);
			sh_cp(0);
			fader_state(y, yBC[1], yBPC[1], &yBfade[0], &yBfade[1], &yB[0], &yB[1], &yB[2]);
			sh_cp(0);
			fader_state(y, yBC[2], yBPC[2], &yRfade[0], &yRfade[1], &yR[0], &yR[1], &yR[2]);
			sh_cp(0);
			fader_state(g, gBC[0], gBPC[0], &gGfade[0], &gGfade[1], &gG[0], &gG[1], &gG[2]);
			sh_cp(0);
			fader_state(g, gBC[1], gBPC[1], &gBfade[0], &gBfade[1], &gB[0], &gB[1], &gB[2]);
			sh_cp(0);
			fader_state(g, gBC[2], gBPC[2], &gRfade[0], &gRfade[1], &gR[0], &gR[1], &gR[2]);
			sh_cp(0);
			fader_state(h, hBC[0], hBPC[0], &hGfade[0], &hGfade[1], &hG[0], &hG[1], &hG[2]);
			sh_cp(0);
			fader_state(h, hBC[1], hBPC[1], &hBfade[0], &hBfade[1], &hB[0], &hB[1], &hB[2]);
			sh_cp(0);
			fader_state(h, hBC[2], hBPC[2], &hRfade[0], &hRfade[1], &hR[0], &hR[1], &hR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==5)
		else if (column==6)
		{
			fader_state(f, fBC[0], fBPC[0], &fGfade[0], &fGfade[1], &fG[0], &fG[1], &fG[2]);
			sh_cp(0);
			fader_state(f, fBC[1], fBPC[1], &fBfade[0], &fBfade[1], &fB[0], &fB[1], &fB[2]);
			sh_cp(0);
			fader_state(f, fBC[2], fBPC[2], &fRfade[0], &fRfade[1], &fR[0], &fR[1], &fR[2]);
			sh_cp(0);
			fader_state(seven, sevenBC[0], sevenBPC[0], &sevenGfade[0], &sevenGfade[1], &sevenG[0], &sevenG[1], &sevenG[2]);
			sh_cp(0);
			fader_state(seven, sevenBC[1], sevenBPC[1], &sevenBfade[0], &sevenBfade[1], &sevenB[0], &sevenB[1], &sevenB[2]);
			sh_cp(0);
			fader_state(seven, sevenBC[2], sevenBPC[2], &sevenRfade[0], &sevenRfade[1], &sevenR[0], &sevenR[1], &sevenR[2]);
			sh_cp(0);
			fader_state(u, uBC[0], uBPC[0], &uGfade[0], &uGfade[1], &uG[0], &uG[1], &uG[2]);
			sh_cp(1);
			fader_state(u, uBC[1], uBPC[1], &uBfade[0], &uBfade[1], &uB[0], &uB[1], &uB[2]);
			sh_cp(0);
			fader_state(u, uBC[2], uBPC[2], &uRfade[0], &uRfade[1], &uR[0], &uR[1], &uR[2]);
			sh_cp(0);
			fader_state(i, iBC[0], iBPC[0], &iGfade[0], &iGfade[1], &iG[0], &iG[1], &iG[2]);
			sh_cp(0);
			fader_state(i, iBC[1], iBPC[1], &iBfade[0], &iBfade[1], &iB[0], &iB[1], &iB[2]);
			sh_cp(0);
			fader_state(i, iBC[2], iBPC[2], &iRfade[0], &iRfade[1], &iR[0], &iR[1], &iR[2]);
			sh_cp(0);
			fader_state(j, jBC[0], jBPC[0], &jGfade[0], &jGfade[1], &jG[0], &jG[1], &jG[2]);
			sh_cp(0);
			fader_state(j, jBC[1], jBPC[1], &jBfade[0], &jBfade[1], &jB[0], &jB[1], &jB[2]);
			sh_cp(0);
			fader_state(j, jBC[2], jBPC[2], &jRfade[0], &jRfade[1], &jR[0], &jR[1], &jR[2]);
			sh_cp(0);
			fader_state(n, nBC[0], nBPC[0], &nGfade[0], &nGfade[1], &nG[0], &nG[1], &nG[2]);
			sh_cp(0);
			fader_state(n, nBC[1], nBPC[1], &nBfade[0], &nBfade[1], &nB[0], &nB[1], &nB[2]);
			sh_cp(0);
			fader_state(n, nBC[2], nBPC[2], &nRfade[0], &nRfade[1], &nR[0], &nR[1], &nR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==6)
		else if (column==7)
		{
			fader_state(f6, f6BC[0], f6BPC[0], &f6Gfade[0], &f6Gfade[1], &f6G[0], &f6G[1], &f6G[2]);
			sh_cp(0);
			fader_state(f6, f6BC[1], f6BPC[1], &f6Bfade[0], &f6Bfade[1], &f6B[0], &f6B[1], &f6B[2]);
			sh_cp(0);
			fader_state(f6, f6BC[2], f6BPC[2], &f6Rfade[0], &f6Rfade[1], &f6R[0], &f6R[1], &f6R[2]);
			sh_cp(0);
			fader_state(eight, eightBC[0], eightBPC[0], &eightGfade[0], &eightGfade[1], &eightG[0], &eightG[1], &eightG[2]);
			sh_cp(0);
			fader_state(eight, eightBC[1], eightBPC[1], &eightBfade[0], &eightBfade[1], &eightB[0], &eightB[1], &eightB[2]);
			sh_cp(0);
			fader_state(eight, eightBC[2], eightBPC[2], &eightRfade[0], &eightRfade[1], &eightR[0], &eightR[1], &eightR[2]);
			sh_cp(0);
			fader_state(nine, nineBC[0], nineBPC[0], &nineGfade[0], &nineGfade[1], &nineG[0], &nineG[1], &nineG[2]);
			sh_cp(0);
			fader_state(nine, nineBC[1], nineBPC[1], &nineBfade[0], &nineBfade[1], &nineB[0], &nineB[1], &nineB[2]);
			sh_cp(1);
			fader_state(nine, nineBC[2], nineBPC[2], &nineRfade[0], &nineRfade[1], &nineR[0], &nineR[1], &nineR[2]);
			sh_cp(0);
			fader_state(o, oBC[0], oBPC[0], &oGfade[0], &oGfade[1], &oG[0], &oG[1], &oG[2]);
			sh_cp(0);
			fader_state(o, oBC[1], oBPC[1], &oBfade[0], &oBfade[1], &oB[0], &oB[1], &oB[2]);
			sh_cp(0);
			fader_state(o, oBC[2], oBPC[2], &oRfade[0], &oRfade[1], &oR[0], &oR[1], &oR[2]);
			sh_cp(0);
			fader_state(k, kBC[0], kBPC[0], &kGfade[0], &kGfade[1], &kG[0], &kG[1], &kG[2]);
			sh_cp(0);
			fader_state(k, kBC[1], kBPC[1], &kBfade[0], &kBfade[1], &kB[0], &kB[1], &kB[2]);
			sh_cp(0);
			fader_state(k, kBC[2], kBPC[2], &kRfade[0], &kRfade[1], &kR[0], &kR[1], &kR[2]);
			sh_cp(0);
			fader_state(m, mBC[0], mBPC[0], &mGfade[0], &mGfade[1], &mG[0], &mG[1], &mG[2]);
			sh_cp(0);
			fader_state(m, mBC[1], mBPC[1], &mBfade[0], &mBfade[1], &mB[0], &mB[1], &mB[2]);
			sh_cp(0);
			fader_state(m, mBC[2], mBPC[2], &mRfade[0], &mRfade[1], &mR[0], &mR[1], &mR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==7)
		else if (column==8)
		{
			fader_state(f7, f7BC[0], f7BPC[0], &f7Gfade[0], &f7Gfade[1], &f7G[0], &f7G[1], &f7G[2]);
			sh_cp(0);
			fader_state(f7, f7BC[1], f7BPC[1], &f7Bfade[0], &f7Bfade[1], &f7B[0], &f7B[1], &f7B[2]);
			sh_cp(0);
			fader_state(f7, f7BC[2], f7BPC[2], &f7Rfade[0], &f7Rfade[1], &f7R[0], &f7R[1], &f7R[2]);
			sh_cp(0);
			fader_state(zero, zeroBC[0], zeroBPC[0], &zeroGfade[0], &zeroGfade[1], &zeroG[0], &zeroG[1], &zeroG[2]);
			sh_cp(0);
			fader_state(zero, zeroBC[1], zeroBPC[1], &zeroBfade[0], &zeroBfade[1], &zeroB[0], &zeroB[1], &zeroB[2]);
			sh_cp(0);
			fader_state(zero, zeroBC[2], zeroBPC[2], &zeroRfade[0], &zeroRfade[1], &zeroR[0], &zeroR[1], &zeroR[2]);
			sh_cp(0);
			fader_state(p, pBC[0], pBPC[0], &pGfade[0], &pGfade[1], &pG[0], &pG[1], &pG[2]);
			sh_cp(0);
			fader_state(p, pBC[1], pBPC[1], &pBfade[0], &pBfade[1], &pB[0], &pB[1], &pB[2]);
			sh_cp(0);
			fader_state(p, pBC[2], pBPC[2], &pRfade[0], &pRfade[1], &pR[0], &pR[1], &pR[2]);
			sh_cp(1);
			fader_state(l, lBC[0], lBPC[0], &lGfade[0], &lGfade[1], &lG[0], &lG[1], &lG[2]);
			sh_cp(0);
			fader_state(l, lBC[1], lBPC[1], &lBfade[0], &lBfade[1], &lB[0], &lB[1], &lB[2]);
			sh_cp(0);
			fader_state(l, lBC[2], lBPC[2], &lRfade[0], &lRfade[1], &lR[0], &lR[1], &lR[2]);
			sh_cp(0);
			fader_state(comma, commaBC[0], commaBPC[0], &commaGfade[0], &commaGfade[1], &commaG[0], &commaG[1], &commaG[2]);
			sh_cp(0);
			fader_state(comma, commaBC[1], commaBPC[1], &commaBfade[0], &commaBfade[1], &commaB[0], &commaB[1], &commaB[2]);
			sh_cp(0);
			fader_state(comma, commaBC[2], commaBPC[2], &commaRfade[0], &commaRfade[1], &commaR[0], &commaR[1], &commaR[2]);
			sh_cp(0);
			fader_state(ralt, raltBC[0], raltBPC[0], &raltGfade[0], &raltGfade[1], &raltG[0], &raltG[1], &raltG[2]);
			sh_cp(0);
			fader_state(ralt, raltBC[1], raltBPC[1], &raltBfade[0], &raltBfade[1], &raltB[0], &raltB[1], &raltB[2]);
			sh_cp(0);
			fader_state(ralt, raltBC[2], raltBPC[2], &raltRfade[0], &raltRfade[1], &raltR[0], &raltR[1], &raltR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==8)
		else if (column==9)
		{
			fader_state(f8, f8BC[0], f8BPC[0], &f8Gfade[0], &f8Gfade[1], &f8G[0], &f8G[1], &f8G[2]);
			sh_cp(0);
			fader_state(f8, f8BC[1], f8BPC[1], &f8Bfade[0], &f8Bfade[1], &f8B[0], &f8B[1], &f8B[2]);
			sh_cp(0);
			fader_state(f8, f8BC[2], f8BPC[2], &f8Rfade[0], &f8Rfade[1], &f8R[0], &f8R[1], &f8R[2]);
			sh_cp(0);
			fader_state(minus, minusBC[0], minusBPC[0], &minusGfade[0], &minusGfade[1], &minusG[0], &minusG[1], &minusG[2]);
			sh_cp(0);
			fader_state(minus, minusBC[1], minusBPC[1], &minusBfade[0], &minusBfade[1], &minusB[0], &minusB[1], &minusB[2]);
			sh_cp(0);
			fader_state(minus, minusBC[2], minusBPC[2], &minusRfade[0], &minusRfade[1], &minusR[0], &minusR[1], &minusR[2]);
			sh_cp(0);
			fader_state(lsqbracket, lsqbracketBC[0], lsqbracketBPC[0], &lsqbracketGfade[0], &lsqbracketGfade[1], &lsqbracketG[0], &lsqbracketG[1], &lsqbracketG[2]);
			sh_cp(0);
			fader_state(lsqbracket, lsqbracketBC[1], lsqbracketBPC[1], &lsqbracketBfade[0], &lsqbracketBfade[1], &lsqbracketB[0], &lsqbracketB[1], &lsqbracketB[2]);
			sh_cp(0);
			fader_state(lsqbracket, lsqbracketBC[2], lsqbracketBPC[2], &lsqbracketRfade[0], &lsqbracketRfade[1], &lsqbracketR[0], &lsqbracketR[1], &lsqbracketR[2]);
			sh_cp(0);
			fader_state(semicolon, semicolonBC[0], semicolonBPC[0], &semicolonGfade[0], &semicolonGfade[1], &semicolonG[0], &semicolonG[1], &semicolonG[2]);
			sh_cp(1);
			fader_state(semicolon, semicolonBC[1], semicolonBPC[1], &semicolonBfade[0], &semicolonBfade[1], &semicolonB[0], &semicolonB[1], &semicolonB[2]);
			sh_cp(0);
			fader_state(semicolon, semicolonBC[2], semicolonBPC[2], &semicolonRfade[0], &semicolonRfade[1], &semicolonR[0], &semicolonR[1], &semicolonR[2]);
			sh_cp(0);
			fader_state(period, periodBC[0], periodBPC[0], &periodGfade[0], &periodGfade[1], &periodG[0], &periodG[1], &periodG[2]);
			sh_cp(0);
			fader_state(period, periodBC[1], periodBPC[1], &periodBfade[0], &periodBfade[1], &periodB[0], &periodB[1], &periodB[2]);
			sh_cp(0);
			fader_state(period, periodBC[2], periodBPC[2], &periodRfade[0], &periodRfade[1], &periodR[0], &periodR[1], &periodR[2]);
			sh_cp(0);
			fader_state(rspecial, rspecialBC[0], rspecialBPC[0], &rspecialGfade[0], &rspecialGfade[1], &rspecialG[0], &rspecialG[1], &rspecialG[2]);
			sh_cp(0);
			fader_state(rspecial, rspecialBC[1], rspecialBPC[1], &rspecialBfade[0], &rspecialBfade[1], &rspecialB[0], &rspecialB[1], &rspecialB[2]);
			sh_cp(0);
			fader_state(rspecial, rspecialBC[2], rspecialBPC[2], &rspecialRfade[0], &rspecialRfade[1], &rspecialR[0], &rspecialR[1], &rspecialR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==9)
		else if (column==10)
		{
			fader_state(f9, f9BC[0], f9BPC[0], &f9Gfade[0], &f9Gfade[1], &f9G[0], &f9G[1], &f9G[2]);
			sh_cp(0);
			fader_state(f9, f9BC[1], f9BPC[1], &f9Bfade[0], &f9Bfade[1], &f9B[0], &f9B[1], &f9B[2]);
			sh_cp(0);
			fader_state(f9, f9BC[2], f9BPC[2], &f9Rfade[0], &f9Rfade[1], &f9R[0], &f9R[1], &f9R[2]);
			sh_cp(0);
			fader_state(equals, equalsBC[0], equalsBPC[0], &equalsGfade[0], &equalsGfade[1], &equalsG[0], &equalsG[1], &equalsG[2]);
			sh_cp(0);
			fader_state(equals, equalsBC[1], equalsBPC[1], &equalsBfade[0], &equalsBfade[1], &equalsB[0], &equalsB[1], &equalsB[2]);
			sh_cp(0);
			fader_state(equals, equalsBC[2], equalsBPC[2], &equalsRfade[0], &equalsRfade[1], &equalsR[0], &equalsR[1], &equalsR[2]);
			sh_cp(0);
			fader_state(rsqbracket, rsqbracketBC[0], rsqbracketBPC[0], &rsqbracketGfade[0], &rsqbracketGfade[1], &rsqbracketG[0], &rsqbracketG[1], &rsqbracketG[2]);
			sh_cp(0);
			fader_state(rsqbracket, rsqbracketBC[1], rsqbracketBPC[1], &rsqbracketBfade[0], &rsqbracketBfade[1], &rsqbracketB[0], &rsqbracketB[1], &rsqbracketB[2]);
			sh_cp(0);
			fader_state(rsqbracket, rsqbracketBC[2], rsqbracketBPC[2], &rsqbracketRfade[0], &rsqbracketRfade[1], &rsqbracketR[0], &rsqbracketR[1], &rsqbracketR[2]);
			sh_cp(0);
			fader_state(apostrophe, apostropheBC[0], apostropheBPC[0], &apostropheGfade[0], &apostropheGfade[1], &apostropheG[0], &apostropheG[1], &apostropheG[2]);
			sh_cp(0);
			fader_state(apostrophe, apostropheBC[1], apostropheBPC[1], &apostropheBfade[0], &apostropheBfade[1], &apostropheB[0], &apostropheB[1], &apostropheB[2]);
			sh_cp(1);
			fader_state(apostrophe, apostropheBC[2], apostropheBPC[2], &apostropheRfade[0], &apostropheRfade[1], &apostropheR[0], &apostropheR[1], &apostropheR[2]);
			sh_cp(0);
			fader_state(fslash, fslashBC[0], fslashBPC[0], &fslashGfade[0], &fslashGfade[1], &fslashG[0], &fslashG[1], &fslashG[2]);
			sh_cp(0);
			fader_state(fslash, fslashBC[1], fslashBPC[1], &fslashBfade[0], &fslashBfade[1], &fslashB[0], &fslashB[1], &fslashB[2]);
			sh_cp(0);
			fader_state(fslash, fslashBC[2], fslashBPC[2], &fslashRfade[0], &fslashRfade[1], &fslashR[0], &fslashR[1], &fslashR[2]);
			sh_cp(0);
			fader_state(menu, menuBC[0], menuBPC[0], &menuGfade[0], &menuGfade[1], &menuG[0], &menuG[1], &menuG[2]);
			sh_cp(0);
			fader_state(menu, menuBC[1], menuBPC[1], &menuBfade[0], &menuBfade[1], &menuB[0], &menuB[1], &menuB[2]);
			sh_cp(0);
			fader_state(menu, menuBC[2], menuBPC[2], &menuRfade[0], &menuRfade[1], &menuR[0], &menuR[1], &menuR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==10)
		else if (column==11)
		{
			fader_state(f10, f10BC[0], f10BPC[0], &f10Gfade[0], &f10Gfade[1], &f10G[0], &f10G[1], &f10G[2]);
			sh_cp(0);
			fader_state(f10, f10BC[1], f10BPC[1], &f10Bfade[0], &f10Bfade[1], &f10B[0], &f10B[1], &f10B[2]);
			sh_cp(0);
			fader_state(f10, f10BC[2], f10BPC[2], &f10Rfade[0], &f10Rfade[1], &f10R[0], &f10R[1], &f10R[2]);
			sh_cp(0);
			fader_state(backspace, backspaceBC[0], backspaceBPC[0], &backspaceGfade[0], &backspaceGfade[1], &backspaceG[0], &backspaceG[1], &backspaceG[2]);
			sh_cp(0);
			fader_state(backspace, backspaceBC[1], backspaceBPC[1], &backspaceBfade[0], &backspaceBfade[1], &backspaceB[0], &backspaceB[1], &backspaceB[2]);
			sh_cp(0);
			fader_state(backspace, backspaceBC[2], backspaceBPC[2], &backspaceRfade[0], &backspaceRfade[1], &backspaceR[0], &backspaceR[1], &backspaceR[2]);
			sh_cp(0);
			fader_state(bslash, bslashBC[0], bslashBPC[0], &bslashGfade[0], &bslashGfade[1], &bslashG[0], &bslashG[1], &bslashG[2]);
			sh_cp(0);
			fader_state(bslash, bslashBC[1], bslashBPC[1], &bslashBfade[0], &bslashBfade[1], &bslashB[0], &bslashB[1], &bslashB[2]);
			sh_cp(0);
			fader_state(bslash, bslashBC[2], bslashBPC[2], &bslashRfade[0], &bslashRfade[1], &bslashR[0], &bslashR[1], &bslashR[2]);
			sh_cp(0);
			fader_state(enter, enterBC[0], enterBPC[0], &enterGfade[0], &enterGfade[1], &enterG[0], &enterG[1], &enterG[2]);
			sh_cp(0);
			fader_state(enter, enterBC[1], enterBPC[1], &enterBfade[0], &enterBfade[1], &enterB[0], &enterB[1], &enterB[2]);
			sh_cp(0);
			fader_state(enter, enterBC[2], enterBPC[2], &enterRfade[0], &enterRfade[1], &enterR[0], &enterR[1], &enterR[2]);
			sh_cp(1);
			fader_state(rshift, rshiftBC[0], rshiftBPC[0], &rshiftGfade[0], &rshiftGfade[1], &rshiftG[0], &rshiftG[1], &rshiftG[2]);
			sh_cp(0);
			fader_state(rshift, rshiftBC[1], rshiftBPC[1], &rshiftBfade[0], &rshiftBfade[1], &rshiftB[0], &rshiftB[1], &rshiftB[2]);
			sh_cp(0);
			fader_state(rshift, rshiftBC[2], rshiftBPC[2], &rshiftRfade[0], &rshiftRfade[1], &rshiftR[0], &rshiftR[1], &rshiftR[2]);
			sh_cp(0);
			fader_state(rctrl, rctrlBC[0], rctrlBPC[0], &rctrlGfade[0], &rctrlGfade[1], &rctrlG[0], &rctrlG[1], &rctrlG[2]);
			sh_cp(0);
			fader_state(rctrl, rctrlBC[1], rctrlBPC[1], &rctrlBfade[0], &rctrlBfade[1], &rctrlB[0], &rctrlB[1], &rctrlB[2]);
			sh_cp(0);
			fader_state(rctrl, rctrlBC[2], rctrlBPC[2], &rctrlRfade[0], &rctrlRfade[1], &rctrlR[0], &rctrlR[1], &rctrlR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==11)
		else if (column==12)
		{
			fader_state(f11, f11BC[0], f11BPC[0], &f11Gfade[0], &f11Gfade[1], &f11G[0], &f11G[1], &f11G[2]);
			sh_cp(0);
			fader_state(f11, f11BC[1], f11BPC[1], &f11Bfade[0], &f11Bfade[1], &f11B[0], &f11B[1], &f11B[2]);
			sh_cp(0);
			fader_state(f11, f11BC[2], f11BPC[2], &f11Rfade[0], &f11Rfade[1], &f11R[0], &f11R[1], &f11R[2]);
			sh_cp(0);
			fader_state(f12, f12BC[0], f12BPC[0], &f12Gfade[0], &f12Gfade[1], &f12G[0], &f12G[1], &f12G[2]);
			sh_cp(0);
			fader_state(f12, f12BC[1], f12BPC[1], &f12Bfade[0], &f12Bfade[1], &f12B[0], &f12B[1], &f12B[2]);
			sh_cp(0);
			fader_state(f12, f12BC[2], f12BPC[2], &f12Rfade[0], &f12Rfade[1], &f12R[0], &f12R[1], &f12R[2]);
			sh_cp(0);
			fader_state(left, leftBC[0], leftBPC[0], &leftGfade[0], &leftGfade[1], &leftG[0], &leftG[1], &leftG[2]);
			sh_cp(0);
			fader_state(left, leftBC[1], leftBPC[1], &leftBfade[0], &leftBfade[1], &leftB[0], &leftB[1], &leftB[2]);
			sh_cp(0);
			fader_state(left, leftBC[2], leftBPC[2], &leftRfade[0], &leftRfade[1], &leftR[0], &leftR[1], &leftR[2]);
			sh_cp(0);
			fader_state(up, upBC[0], upBPC[0], &upGfade[0], &upGfade[1], &upG[0], &upG[1], &upG[2]);
			sh_cp(0);
			fader_state(up, upBC[1], upBPC[1], &upBfade[0], &upBfade[1], &upB[0], &upB[1], &upB[2]);
			sh_cp(0);
			fader_state(up, upBC[2], upBPC[2], &upRfade[0], &upRfade[1], &upR[0], &upR[1], &upR[2]);
			sh_cp(0);
			fader_state(down, downBC[0], downBPC[0], &downGfade[0], &downGfade[1], &downG[0], &downG[1], &downG[2]);
			sh_cp(1);
			fader_state(down, downBC[1], downBPC[1], &downBfade[0], &downBfade[1], &downB[0], &downB[1], &downB[2]);
			sh_cp(0);
			fader_state(down, downBC[2], downBPC[2], &downRfade[0], &downRfade[1], &downR[0], &downR[1], &downR[2]);
			sh_cp(0);
			fader_state(right, rightBC[0], rightBPC[0], &rightGfade[0], &rightGfade[1], &rightG[0], &rightG[1], &rightG[2]);
			sh_cp(0);
			fader_state(right, rightBC[1], rightBPC[1], &rightBfade[0], &rightBfade[1], &rightB[0], &rightB[1], &rightB[2]);
			sh_cp(0);
			fader_state(right, rightBC[2], rightBPC[2], &rightRfade[0], &rightRfade[1], &rightR[0], &rightR[1], &rightR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==12)
		else if (column==13)
		{
			fader_state(insert, insertBC[0], insertBPC[0], &insertGfade[0], &insertGfade[1], &insertG[0], &insertG[1], &insertG[2]);
			sh_cp(0);
			fader_state(insert, insertBC[1], insertBPC[1], &insertBfade[0], &insertBfade[1], &insertB[0], &insertB[1], &insertB[2]);
			sh_cp(0);
			fader_state(insert, insertBC[2], insertBPC[2], &insertRfade[0], &insertRfade[1], &insertR[0], &insertR[1], &insertR[2]);
			sh_cp(0);
			fader_state(dlt, dltBC[0], dltBPC[0], &dltGfade[0], &dltGfade[1], &dltG[0], &dltG[1], &dltG[2]);
			sh_cp(0);
			fader_state(dlt, dltBC[1], dltBPC[1], &dltBfade[0], &dltBfade[1], &dltB[0], &dltB[1], &dltB[2]);
			sh_cp(0);
			fader_state(dlt, dltBC[2], dltBPC[2], &dltRfade[0], &dltRfade[1], &dltR[0], &dltR[1], &dltR[2]);
			sh_cp(0);
			fader_state(home, homeBC[0], homeBPC[0], &homeGfade[0], &homeGfade[1], &homeG[0], &homeG[1], &homeG[2]);
			sh_cp(0);
			fader_state(home, homeBC[1], homeBPC[1], &homeBfade[0], &homeBfade[1], &homeB[0], &homeB[1], &homeB[2]);
			sh_cp(0);
			fader_state(home, homeBC[2], homeBPC[2], &homeRfade[0], &homeRfade[1], &homeR[0], &homeR[1], &homeR[2]);
			sh_cp(0);
			fader_state(end, endBC[0], endBPC[0], &endGfade[0], &endGfade[1], &endG[0], &endG[1], &endG[2]);
			sh_cp(0);
			fader_state(end, endBC[1], endBPC[1], &endBfade[0], &endBfade[1], &endB[0], &endB[1], &endB[2]);
			sh_cp(0);
			fader_state(end, endBC[2], endBPC[2], &endRfade[0], &endRfade[1], &endR[0], &endR[1], &endR[2]);
			sh_cp(0);
			fader_state(pageup, pageupBC[0], pageupBPC[0], &pageupGfade[0], &pageupGfade[1], &pageupG[0], &pageupG[1], &pageupG[2]);
			sh_cp(0);
			fader_state(pageup, pageupBC[1], pageupBPC[1], &pageupBfade[0], &pageupBfade[1], &pageupB[0], &pageupB[1], &pageupB[2]);
			sh_cp(1);
			fader_state(pageup, pageupBC[2], pageupBPC[2], &pageupRfade[0], &pageupRfade[1], &pageupR[0], &pageupR[1], &pageupR[2]);
			sh_cp(0);
			fader_state(pagedown, pagedownBC[0], pagedownBPC[0], &pagedownGfade[0], &pagedownGfade[1], &pagedownG[0], &pagedownG[1], &pagedownG[2]);
			sh_cp(0);
			fader_state(pagedown, pagedownBC[1], pagedownBPC[1], &pagedownBfade[0], &pagedownBfade[1], &pagedownB[0], &pagedownB[1], &pagedownB[2]);
			sh_cp(0);
			fader_state(pagedown, pagedownBC[2], pagedownBPC[2], &pagedownRfade[0], &pagedownRfade[1], &pagedownR[0], &pagedownR[1], &pagedownR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==13)
		if (macro == 1)	//if macro key is pressed
		{
			++macroS;	//incriment macroState
			if (macroS==1)	//if macroState is 1
			{
				macroFKBPCV[0] = f1BPC[0];	//store f1-f12+macro ButtonPressColor in macroFunctionButtonPressColorValue
				macroFKBPCV[1] = f1BPC[1];
				macroFKBPCV[2] = f1BPC[2];
				macroFKBPCV[3] = f2BPC[0];
				macroFKBPCV[4] = f2BPC[1];
				macroFKBPCV[5] = f2BPC[2];
				macroFKBPCV[6] = f3BPC[0];
				macroFKBPCV[7] = f3BPC[1];
				macroFKBPCV[8] = f3BPC[2];
				macroFKBPCV[9] = f4BPC[0];
				macroFKBPCV[10] = f4BPC[1];
				macroFKBPCV[11] = f4BPC[2];
				macroFKBPCV[12] = f5BPC[0];
				macroFKBPCV[13] = f5BPC[1];
				macroFKBPCV[14] = f5BPC[2];
				macroFKBPCV[15] = f6BPC[0];
				macroFKBPCV[16] = f6BPC[1];
				macroFKBPCV[17] = f6BPC[2];
				macroFKBPCV[18] = f7BPC[0];
				macroFKBPCV[19] = f7BPC[1];
				macroFKBPCV[20] = f7BPC[2];
				macroFKBPCV[21] = f8BPC[0];
				macroFKBPCV[22] = f8BPC[1];
				macroFKBPCV[23] = f8BPC[2];
				macroFKBPCV[24] = f9BPC[0];
				macroFKBPCV[25] = f9BPC[1];
				macroFKBPCV[26] = f9BPC[2];
				macroFKBPCV[27] = f10BPC[0];
				macroFKBPCV[28] = f10BPC[1];
				macroFKBPCV[29] = f10BPC[2];
				macroFKBPCV[30] = f11BPC[0];
				macroFKBPCV[31] = f11BPC[1];
				macroFKBPCV[32] = f11BPC[2];
				macroFKBPCV[33] = f12BPC[0];
				macroFKBPCV[34] = f12BPC[1];
				macroFKBPCV[35] = f12BPC[2];
				macroFKBPCV[36] = macroBPC[0];
				macroFKBPCV[37] = macroBPC[1];
				macroFKBPCV[38] = macroBPC[2];
				f1BPC[0] = f1BC[0];	//set f1-f12+macro ButtonPressColor to f1-f12+macro ButtonColor
				f1BPC[1] = f1BC[1];
				f1BPC[2] = f1BC[2];
				f2BPC[0] = f2BC[0];
				f2BPC[1] = f2BC[1];
				f2BPC[2] = f2BC[2];
				f3BPC[0] = f3BC[0];
				f3BPC[1] = f3BC[1];
				f3BPC[2] = f3BC[2];
				f4BPC[0] = f4BC[0];
				f4BPC[1] = f4BC[1];
				f4BPC[2] = f4BC[2];
				f5BPC[0] = f5BC[0];
				f5BPC[1] = f5BC[1];
				f5BPC[2] = f5BC[2];
				f6BPC[0] = f6BC[0];
				f6BPC[1] = f6BC[1];
				f6BPC[2] = f6BC[2];
				f7BPC[0] = f7BC[0];
				f7BPC[1] = f7BC[1];
				f7BPC[2] = f7BC[2];
				f8BPC[0] = f8BC[0];
				f8BPC[1] = f8BC[1];
				f8BPC[2] = f8BC[2];
				f9BPC[0] = f9BC[0];
				f9BPC[1] = f9BC[1];
				f9BPC[2] = f9BC[2];
				f10BPC[0] = f10BC[0];
				f10BPC[1] = f10BC[1];
				f10BPC[2] = f10BC[2];
				f11BPC[0] = f11BC[0];
				f11BPC[1] = f11BC[1];
				f11BPC[2] = f11BC[2];
				f12BPC[0] = f12BC[0];
				f12BPC[1] = f12BC[1];
				f12BPC[2] = f12BC[2];
				macroBPC[0] = macroBC[0];
				macroBPC[1] = macroBC[1];
				macroBPC[2] = macroBC[2];
				f1BC[0] = macroS1BC[0];	//set f1-f12+macro ButtonColor to macroState1ButtonColor
				f1BC[1] = macroS1BC[1];
				f1BC[2] = macroS1BC[2];
				f2BC[0] = macroS1BC[0];
				f2BC[1] = macroS1BC[1];
				f2BC[2] = macroS1BC[2];
				f3BC[0] = macroS1BC[0];
				f3BC[1] = macroS1BC[1];
				f3BC[2] = macroS1BC[2];
				f4BC[0] = macroS1BC[0];
				f4BC[1] = macroS1BC[1];
				f4BC[2] = macroS1BC[2];
				f5BC[0] = macroS1BC[0];
				f5BC[1] = macroS1BC[1];
				f5BC[2] = macroS1BC[2];
				f6BC[0] = macroS1BC[0];
				f6BC[1] = macroS1BC[1];
				f6BC[2] = macroS1BC[2];
				f7BC[0] = macroS1BC[0];
				f7BC[1] = macroS1BC[1];
				f7BC[2] = macroS1BC[2];
				f8BC[0] = macroS1BC[0];
				f8BC[1] = macroS1BC[1];
				f8BC[2] = macroS1BC[2];
				f9BC[0] = macroS1BC[0];
				f9BC[1] = macroS1BC[1];
				f9BC[2] = macroS1BC[2];
				f10BC[0] = macroS1BC[0];
				f10BC[1] = macroS1BC[1];
				f10BC[2] = macroS1BC[2];
				f11BC[0] = macroS1BC[0];
				f11BC[1] = macroS1BC[1];
				f11BC[2] = macroS1BC[2];
				f12BC[0] = macroS1BC[0];
				f12BC[1] = macroS1BC[1];
				f12BC[2] = macroS1BC[2];
				macroBC[0] = macroS1BC[0];
				macroBC[1] = macroS1BC[1];
				macroBC[2] = macroS1BC[2];
			}	//end if(macroS==1)
			else if (macroS==2)	//if macroState is  2
			{
				f1BC[0] = macroS2BC[0];	//set f1-f12+macro ButtonColor to macroState2ButtonColor
				f1BC[1] = macroS2BC[1];
				f1BC[2] = macroS2BC[2];
				f2BC[0] = macroS2BC[0];
				f2BC[1] = macroS2BC[1];
				f2BC[2] = macroS2BC[2];
				f3BC[0] = macroS2BC[0];
				f3BC[1] = macroS2BC[1];
				f3BC[2] = macroS2BC[2];
				f4BC[0] = macroS2BC[0];
				f4BC[1] = macroS2BC[1];
				f4BC[2] = macroS2BC[2];
				f5BC[0] = macroS2BC[0];
				f5BC[1] = macroS2BC[1];
				f5BC[2] = macroS2BC[2];
				f6BC[0] = macroS2BC[0];
				f6BC[1] = macroS2BC[1];
				f6BC[2] = macroS2BC[2];
				f7BC[0] = macroS2BC[0];
				f7BC[1] = macroS2BC[1];
				f7BC[2] = macroS2BC[2];
				f8BC[0] = macroS2BC[0];
				f8BC[1] = macroS2BC[1];
				f8BC[2] = macroS2BC[2];
				f9BC[0] = macroS2BC[0];
				f9BC[1] = macroS2BC[1];
				f9BC[2] = macroS2BC[2];
				f10BC[0] = macroS2BC[0];
				f10BC[1] = macroS2BC[1];
				f10BC[2] = macroS2BC[2];
				f11BC[0] = macroS2BC[0];
				f11BC[1] = macroS2BC[1];
				f11BC[2] = macroS2BC[2];
				f12BC[0] = macroS2BC[0];
				f12BC[1] = macroS2BC[1];
				f12BC[2] = macroS2BC[2];
				macroBC[0] = macroS2BC[0];
				macroBC[1] = macroS2BC[1];
				macroBC[2] = macroS2BC[2];
			}	//end if(macroS==2)
			else
			{
				f1BC[0] = f1BPC[0];	//set f1-f12+macro ButtonColor to f1-f12+macro ButtonPressColor
				f1BC[1] = f1BPC[1];
				f1BC[2] = f1BPC[2];
				f2BC[0] = f2BPC[0];
				f2BC[1] = f2BPC[1];
				f2BC[2] = f2BPC[2];
				f3BC[0] = f3BPC[0];
				f3BC[1] = f3BPC[1];
				f3BC[2] = f3BPC[2];
				f4BC[0] = f4BPC[0];
				f4BC[1] = f4BPC[1];
				f4BC[2] = f4BPC[2];
				f5BC[0] = f5BPC[0];
				f5BC[1] = f5BPC[1];
				f5BC[2] = f5BPC[2];
				f6BC[0] = f6BPC[0];
				f6BC[1] = f6BPC[1];
				f6BC[2] = f6BPC[2];
				f7BC[0] = f7BPC[0];
				f7BC[1] = f7BPC[1];
				f7BC[2] = f7BPC[2];
				f8BC[0] = f8BPC[0];
				f8BC[1] = f8BPC[1];
				f8BC[2] = f8BPC[2];
				f9BC[0] = f9BPC[0];
				f9BC[1] = f9BPC[1];
				f9BC[2] = f9BPC[2];
				f10BC[0] = f10BPC[0];
				f10BC[1] = f10BPC[1];
				f10BC[2] = f10BPC[2];
				f11BC[0] = f11BPC[0];
				f11BC[1] = f11BPC[1];
				f11BC[2] = f11BPC[2];
				f12BC[0] = f12BPC[0];
				f12BC[1] = f12BPC[1];
				f12BC[2] = f12BPC[2];
				macroBC[0] = macroBPC[0];
				macroBC[1] = macroBPC[1];
				macroBC[2] = macroBPC[2];
				f1BPC[0] = macroFKBPCV[0];	//set f1-f12+macro ButtonPressColor to macroFunctionKeyPressColorValue
				f1BPC[1] = macroFKBPCV[1];
				f1BPC[2] = macroFKBPCV[2];
				f2BPC[0] = macroFKBPCV[3];
				f2BPC[1] = macroFKBPCV[4];
				f2BPC[2] = macroFKBPCV[5];
				f3BPC[0] = macroFKBPCV[6];
				f3BPC[1] = macroFKBPCV[7];
				f3BPC[2] = macroFKBPCV[8];
				f4BPC[0] = macroFKBPCV[9];
				f4BPC[1] = macroFKBPCV[10];
				f4BPC[2] = macroFKBPCV[11];
				f5BPC[0] = macroFKBPCV[12];
				f5BPC[1] = macroFKBPCV[13];
				f5BPC[2] = macroFKBPCV[14];
				f6BPC[0] = macroFKBPCV[15];
				f6BPC[1] = macroFKBPCV[16];
				f6BPC[2] = macroFKBPCV[17];
				f7BPC[0] = macroFKBPCV[18];
				f7BPC[1] = macroFKBPCV[19];
				f7BPC[2] = macroFKBPCV[20];
				f8BPC[0] = macroFKBPCV[21];
				f8BPC[1] = macroFKBPCV[22];
				f8BPC[2] = macroFKBPCV[23];
				f9BPC[0] = macroFKBPCV[24];
				f9BPC[1] = macroFKBPCV[25];
				f9BPC[2] = macroFKBPCV[26];
				f10BPC[0] = macroFKBPCV[27];
				f10BPC[1] = macroFKBPCV[28];
				f10BPC[2] = macroFKBPCV[29];
				f11BPC[0] = macroFKBPCV[30];
				f11BPC[1] = macroFKBPCV[31];
				f11BPC[2] = macroFKBPCV[32];
				f12BPC[0] = macroFKBPCV[33];
				f12BPC[1] = macroFKBPCV[34];
				f12BPC[2] = macroFKBPCV[35];
				macroBPC[0] = macroFKBPCV[36];
				macroBPC[1] = macroFKBPCV[37];
				macroBPC[2] = macroFKBPCV[38];
				macroS = 0;
			}	//end else
		}	//end if(macro==1)
		else if (column==14)
		{
			fader_state(macro, macroBC[0], macroBPC[0], &macroGfade[0], &macroGfade[1], &macroG[0], &macroG[1], &macroG[2]);
			sh_cp(0);
			fader_state(macro, macroBC[1], macroBPC[1], &macroBfade[0], &macroBfade[1], &macroB[0], &macroB[1], &macroB[2]);
			sh_cp(0);
			fader_state(macro, macroBC[2], macroBPC[2], &macroRfade[0], &macroRfade[1], &macroR[0], &macroR[1], &macroR[2]);
			sh_cp(0);
			fader_state(numlock, numlockBC[0], numlockBPC[0], &numlockGfade[0], &numlockGfade[1], &numlockG[0], &numlockG[1], &numlockG[2]);
			sh_cp(0);
			fader_state(numlock, numlockBC[1], numlockBPC[1], &numlockBfade[0], &numlockBfade[1], &numlockB[0], &numlockB[1], &numlockB[2]);
			sh_cp(0);
			fader_state(numlock, numlockBC[2], numlockBPC[2], &numlockRfade[0], &numlockRfade[1], &numlockR[0], &numlockR[1], &numlockR[2]);
			sh_cp(0);
			fader_state(num7, num7BC[0], num7BPC[0], &num7Gfade[0], &num7Gfade[1], &num7G[0], &num7G[1], &num7G[2]);
			sh_cp(0);
			fader_state(num7, num7BC[1], num7BPC[1], &num7Bfade[0], &num7Bfade[1], &num7B[0], &num7B[1], &num7B[2]);
			sh_cp(0);
			fader_state(num7, num7BC[2], num7BPC[2], &num7Rfade[0], &num7Rfade[1], &num7R[0], &num7R[1], &num7R[2]);
			sh_cp(0);
			fader_state(num4, num4BC[0], num4BPC[0], &num4Gfade[0], &num4Gfade[1], &num4G[0], &num4G[1], &num4G[2]);
			sh_cp(0);
			fader_state(num4, num4BC[1], num4BPC[1], &num4Bfade[0], &num4Bfade[1], &num4B[0], &num4B[1], &num4B[2]);
			sh_cp(0);
			fader_state(num4, num4BC[2], num4BPC[2], &num4Rfade[0], &num4Rfade[1], &num4R[0], &num4R[1], &num4R[2]);
			sh_cp(0);
			fader_state(num1, num1BC[0], num1BPC[0], &num1Gfade[0], &num1Gfade[1], &num1G[0], &num1G[1], &num1G[2]);
			sh_cp(0);
			fader_state(num1, num1BC[1], num1BPC[1], &num1Bfade[0], &num1Bfade[1], &num1B[0], &num1B[1], &num1B[2]);
			sh_cp(0);
			fader_state(num1, num1BC[2], num1BPC[2], &num1Rfade[0], &num1Rfade[1], &num1R[0], &num1R[1], &num1R[2]);
			sh_cp(1);
			fader_state(num0, num0BC[0], num0BPC[0], &num0Gfade[0], &num0Gfade[1], &num0G[0], &num0G[1], &num0G[2]);
			sh_cp(0);
			fader_state(num0, num0BC[1], num0BPC[1], &num0Bfade[0], &num0Bfade[1], &num0B[0], &num0B[1], &num0B[2]);
			sh_cp(0);
			fader_state(num0, num0BC[2], num0BPC[2], &num0Rfade[0], &num0Rfade[1], &num0R[0], &num0R[1], &num0R[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==14)
		else if (column==15)
		{
			fader_state(bright, brightBC[0], brightBPC[0], &brightGfade[0], &brightGfade[1], &brightG[0], &brightG[1], &brightG[2]);
			sh_cp(0);
			fader_state(bright, brightBC[1], brightBPC[1], &brightBfade[0], &brightBfade[1], &brightB[0], &brightB[1], &brightB[2]);
			sh_cp(0);
			fader_state(bright, brightBC[2], brightBPC[2], &brightRfade[0], &brightRfade[1], &brightR[0], &brightR[1], &brightR[2]);
			sh_cp(0);
			fader_state(numfslash, numfslashBC[0], numfslashBPC[0], &numfslashGfade[0], &numfslashGfade[1], &numfslashG[0], &numfslashG[1], &numfslashG[2]);
			sh_cp(0);
			fader_state(numfslash, numfslashBC[1], numfslashBPC[1], &numfslashBfade[0], &numfslashBfade[1], &numfslashB[0], &numfslashB[1], &numfslashB[2]);
			sh_cp(0);
			fader_state(numfslash, numfslashBC[2], numfslashBPC[2], &numfslashRfade[0], &numfslashRfade[1], &numfslashR[0], &numfslashR[1], &numfslashR[2]);
			sh_cp(0);
			fader_state(num8, num8BC[0], num8BPC[0], &num8Gfade[0], &num8Gfade[1], &num8G[0], &num8G[1], &num8G[2]);
			sh_cp(0);
			fader_state(num8, num8BC[1], num8BPC[1], &num8Bfade[0], &num8Bfade[1], &num8B[0], &num8B[1], &num8B[2]);
			sh_cp(0);
			fader_state(num8, num8BC[2], num8BPC[2], &num8Rfade[0], &num8Rfade[1], &num8R[0], &num8R[1], &num8R[2]);
			sh_cp(0);
			fader_state(num5, num5BC[0], num5BPC[0], &num5Gfade[0], &num5Gfade[1], &num5G[0], &num5G[1], &num5G[2]);
			sh_cp(0);
			fader_state(num5, num5BC[1], num5BPC[1], &num5Bfade[0], &num5Bfade[1], &num5B[0], &num5B[1], &num5B[2]);
			sh_cp(0);
			fader_state(num5, num5BC[2], num5BPC[2], &num5Rfade[0], &num5Rfade[1], &num5R[0], &num5R[1], &num5R[2]);
			sh_cp(0);
			fader_state(num2, num2BC[0], num2BPC[0], &num2Gfade[0], &num2Gfade[1], &num2G[0], &num2G[1], &num2G[2]);
			sh_cp(0);
			fader_state(num2, num2BC[1], num2BPC[1], &num2Bfade[0], &num2Bfade[1], &num2B[0], &num2B[1], &num2B[2]);
			sh_cp(0);
			fader_state(num2, num2BC[2], num2BPC[2], &num2Rfade[0], &num2Rfade[1], &num2R[0], &num2R[1], &num2R[2]);
			sh_cp(0);
			fader_state(numperiod, numperiodBC[0], numperiodBPC[0], &numperiodGfade[0], &numperiodGfade[1], &numperiodG[0], &numperiodG[1], &numperiodG[2]);
			sh_cp(1);
			fader_state(numperiod, numperiodBC[1], numperiodBPC[1], &numperiodBfade[0], &numperiodBfade[1], &numperiodB[0], &numperiodB[1], &numperiodB[2]);
			sh_cp(0);
			fader_state(numperiod, numperiodBC[2], numperiodBPC[2], &numperiodRfade[0], &numperiodRfade[1], &numperiodR[0], &numperiodR[1], &numperiodR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==15)
		else if (column==16)
		{
			fader_state(mute, muteBC[0], muteBPC[0], &muteGfade[0], &muteGfade[1], &muteG[0], &muteG[1], &muteG[2]);
			sh_cp(0);
			fader_state(mute, muteBC[1], muteBPC[1], &muteBfade[0], &muteBfade[1], &muteB[0], &muteB[1], &muteB[2]);
			sh_cp(0);
			fader_state(mute, muteBC[2], muteBPC[2], &muteRfade[0], &muteRfade[1], &muteR[0], &muteR[1], &muteR[2]);
			sh_cp(0);
			fader_state(asterisk, asteriskBC[0], asteriskBPC[0], &asteriskGfade[0], &asteriskGfade[1], &asteriskG[0], &asteriskG[1], &asteriskG[2]);
			sh_cp(0);
			fader_state(asterisk, asteriskBC[1], asteriskBPC[1], &asteriskBfade[0], &asteriskBfade[1], &asteriskB[0], &asteriskB[1], &asteriskB[2]);
			sh_cp(0);
			fader_state(asterisk, asteriskBC[2], asteriskBPC[2], &asteriskRfade[0], &asteriskRfade[1], &asteriskR[0], &asteriskR[1], &asteriskR[2]);
			sh_cp(0);
			fader_state(num9, num9BC[0], num9BPC[0], &num9Gfade[0], &num9Gfade[1], &num9G[0], &num9G[1], &num9G[2]);
			sh_cp(0);
			fader_state(num9, num9BC[1], num9BPC[1], &num9Bfade[0], &num9Bfade[1], &num9B[0], &num9B[1], &num9B[2]);
			sh_cp(0);
			fader_state(num9, num9BC[2], num9BPC[2], &num9Rfade[0], &num9Rfade[1], &num9R[0], &num9R[1], &num9R[2]);
			sh_cp(0);
			fader_state(num6, num6BC[0], num6BPC[0], &num6Gfade[0], &num6Gfade[1], &num6G[0], &num6G[1], &num6G[2]);
			sh_cp(0);
			fader_state(num6, num6BC[1], num6BPC[1], &num6Bfade[0], &num6Bfade[1], &num6B[0], &num6B[1], &num6B[2]);
			sh_cp(0);
			fader_state(num6, num6BC[2], num6BPC[2], &num6Rfade[0], &num6Rfade[1], &num6R[0], &num6R[1], &num6R[2]);
			sh_cp(0);
			fader_state(num3, num3BC[0], num3BPC[0], &num3Gfade[0], &num3Gfade[1], &num3G[0], &num3G[1], &num3G[2]);
			sh_cp(0);
			fader_state(num3, num3BC[1], num3BPC[1], &num3Bfade[0], &num3Bfade[1], &num3B[0], &num3B[1], &num3B[2]);
			sh_cp(0);
			fader_state(num3, num3BC[2], num3BPC[2], &num3Rfade[0], &num3Rfade[1], &num3R[0], &num3R[1], &num3R[2]);
			sh_cp(0);
			fader_state(numenter, numenterBC[0], numenterBPC[0], &numenterGfade[0], &numenterGfade[1], &numenterG[0], &numenterG[1], &numenterG[2]);
			sh_cp(0);
			fader_state(numenter, numenterBC[1], numenterBPC[1], &numenterBfade[0], &numenterBfade[1], &numenterB[0], &numenterB[1], &numenterB[2]);
			sh_cp(1);
			fader_state(numenter, numenterBC[2], numenterBPC[2], &numenterRfade[0], &numenterRfade[1], &numenterR[0], &numenterR[1], &numenterR[2]);
			sh_cp(0);
			st_cp();
			column++;
		}	//end else if (column==16)
		else if (column==17)
		{
			fader_state(prtscrn, prtscrnBC[0], prtscrnBPC[0], &prtscrnGfade[0], &prtscrnGfade[1], &prtscrnG[0], &prtscrnG[1], &prtscrnG[2]);
			sh_cp(0);
			fader_state(prtscrn, prtscrnBC[1], prtscrnBPC[1], &prtscrnBfade[0], &prtscrnBfade[1], &prtscrnB[0], &prtscrnB[1], &prtscrnB[2]);
			sh_cp(0);
			fader_state(prtscrn, prtscrnBC[2], prtscrnBPC[2], &prtscrnRfade[0], &prtscrnRfade[1], &prtscrnR[0], &prtscrnR[1], &prtscrnR[2]);
			sh_cp(0);
			fader_state(scrolllock, scrolllockBC[0], scrolllockBPC[0], &scrolllockGfade[0], &scrolllockGfade[1], &scrolllockG[0], &scrolllockG[1], &scrolllockG[2]);
			sh_cp(0);
			fader_state(scrolllock, scrolllockBC[1], scrolllockBPC[1], &scrolllockBfade[0], &scrolllockBfade[1], &scrolllockB[0], &scrolllockB[1], &scrolllockB[2]);
			sh_cp(0);
			fader_state(scrolllock, scrolllockBC[2], scrolllockBPC[2], &scrolllockRfade[0], &scrolllockRfade[1], &scrolllockR[0], &scrolllockR[1], &scrolllockR[2]);
			sh_cp(0);
			fader_state(pause, pauseBC[0], pauseBPC[0], &pauseGfade[0], &pauseGfade[1], &pauseG[0], &pauseG[1], &pauseG[2]);
			sh_cp(0);
			fader_state(pause, pauseBC[1], pauseBPC[1], &pauseBfade[0], &pauseBfade[1], &pauseB[0], &pauseB[1], &pauseB[2]);
			sh_cp(0);
			fader_state(pause, pauseBC[2], pauseBPC[2], &pauseRfade[0], &pauseRfade[1], &pauseR[0], &pauseR[1], &pauseR[2]);
			sh_cp(0);
			fader_state(numminus, numminusBC[0], numminusBPC[0], &numminusGfade[0], &numminusGfade[1], &numminusG[0], &numminusG[1], &numminusG[2]);
			sh_cp(0);
			fader_state(numminus, numminusBC[1], numminusBPC[1], &numminusBfade[0], &numminusBfade[1], &numminusB[0], &numminusB[1], &numminusB[2]);
			sh_cp(0);
			fader_state(numminus, numminusBC[2], numminusBPC[2], &numminusRfade[0], &numminusRfade[1], &numminusR[0], &numminusR[1], &numminusR[2]);
			sh_cp(0);
			fader_state(plus, plusBC[0], plusBPC[0], &plusGfade[0], &plusGfade[1], &plusG[0], &plusG[1], &plusG[2]);
			sh_cp(0);
			fader_state(plus, plusBC[1], plusBPC[1], &plusBfade[0], &plusBfade[1], &plusB[0], &plusB[1], &plusB[2]);
			sh_cp(0);
			fader_state(plus, plusBC[2], plusBPC[2], &plusRfade[0], &plusRfade[1], &plusR[0], &plusR[1], &plusR[2]);
			sh_cp(0);
			PORTA &= ~(1<<PA0);	//sets rdata to low since there are no more keys to fill up the remainder of the 18 LED slots and the remainder of the 24 total 74HC595 pins low
			sh_cp(0);
			sh_cp(0);
			sh_cp(1);
			sh_cp(0);
			sh_cp(0);
			sh_cp(0);
			sh_cp(0);
			sh_cp(0);
			sh_cp(0);
			st_cp();
			column = 0;	//restart at the beginning of column loop
		}	//end else if (column==17)
	}	//end while(1)
}	//end main
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
I slimmed this down to 1416 lines of code after I cleaned up all the necessary copypasta. I added a lot of comments so you guys won't be driven completely mad, although I didn't necessarily follow any guide to proper commenting.. I understand what I mean, and that's good enough for me.

As you can see though.. each key has at least 9 variables, 8 of which are arrays with 2 or 3 elements. 22 variables, at least, per key, of which there are 107.. so, 2354 variables just for the keys. There's some others in there too.
 
Last edited:

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
OK, here's a partial reworking of your code.

Code:
/*
 * ATTINY861_20PU_LED_MATRIX.c
 *
 * Created: 1/25/2014 4:24:47 PM
 *  Author: The Hammer
 *
 * Modified: 2/23/2014 13:00:00 PM
 *  Author: (*Steve*)
 */ 

#include <avr/io.h>

// Structure for what looks like intensity and fade values
class CColFade {
  int time;
  int state;
  int dcs;
  int fadeStep;
  int fadeTime;
  
  void CColFade();
};

// initialize to default values
void CColFade::CColFade()
: time(0)
, state (0)
, dcs (0)
, fadeStep (49)
, fadeTime (0)
{
};

// Don't know what these things are, but they sure need a stuct, and maybe a class
class CKey {
  int pressed;
  int BC[3];
  int BPC[3];
  CColFade col[3]; // G, B, R
  
  void CKey();
}

// Extra initialization for default values of these things
void CKey::CKey()
: pressed(0)
, BC({0, 20, 0})
, BPC({0, 0, 20})
{
}

// 74HC595 PWM and key variables
int row = 0, column = 0;

// things were defined like this:
// int lshift = 0, lshiftBC[3]={0, 20, 0}, lshiftBPC[3]={0, 0, 20}, lshiftGfade[2]={49, 0}, lshiftG[3]={0, 0, 0}, lshiftBfade[2]={49, 0}, lshiftB[3]={0, 0, 0}, lshiftRfade[2]={49, 0}, lshiftR[3]={0, 0, 0};

CKey keys[10,14]; // there is a array of keys (10 rows * 14 columns)

void sh_cp(int cdata);

void st_cp();

int fader_state(int key, int keyBC, int keyBPC, int* keyCfadestep, int* keyCfadetime, int* keyCtime, int* keyCstate, int* keyCdcs);

void sh_cp(int cdata)    //input rdata and cdata states into the 74HC595 chips, if cdata is 1 make cdata state high then low 
{
    if (cdata == 0)    //if cdata is 0 pulse clock pin
    {
        PORTA |= (1<<PA2);    //set clock pin high
        PORTA &= ~(1<<PA2);    //set clock pin low
    }    //end if (cdata == 0)
    else
    {
        PORTA |= (1<<PA1);    //set cdata pin high
        PORTA |= (1<<PA2);    //set clock pin high
        PORTA &= ~(1<<PA2);    //set clock pin low
        PORTA &= ~(1<<PA1);    //set cdata pin high
    }
}    //end sh_cp() function

void st_cp()    //latch all 74HC595 states
{
    PORTA |= (1<<PA3);    //set latch pin high
    PORTA &= ~(1<<PA3);    //set latch pin low
}    //end st_cp() function

// 
void fs_LED_duty_complete(int BPC, int BC, CColFade& CF)
{
    if (CF.fadeStep < 49)    //if fader timer has not run out
    {
        fs_fader_running(BPC, BC, CF);
        if (BPC < BC)    //if keyButtonPressColor is smaller than keyButtonColor
        {
            CF.fadeTime = BC - BPC;    //math to figure out time on in duty cycle
            CF.fadeTime /= 49;
            CF.fadeTime *= CF.fadeStep;
            CF.fadeTime = BC - CF.fadeTime;
            CF.time = CF.fadeTime;
        }    //end if (keyBPC < keyBC)
        else if (BPC > BC)    //if keyButtonPressColor is bigger than keyButtonColor
        {
            CF.fadeTime = BPC - BC;    //math to figure out time on in duty cycle
            CF.fadeTime /= 49;
            CF.fadeTime *= CF.fadeStep;
            CF.time = int CF.fadetime;
        }    //end else if (keyBPC > keyBC)
        else
        {
            CF.time = keyBC;    //if keyButtonPressColor and keyButtonColor are the same put keyButtonColor in effect
            CF.state = 1;
            CF.fadestep = 48;
        }    //end else
        ++CF.fadestep;
    }    //end if (*keyCfadestep < 49)
    else
    {
        if (BC > 0)    //if keyButtonColor is on
        {
            CF.time = BC;    //make keyColortime state of keyButtonColor and keyCstate 1
            CF.state = 1;
        }    //end if (keyBC > 0)
        else
        {
            CF.time = 20;    //make keyColortime full duty cycle and keyCstate to 0
            CF.state = 0;
        }    //end else
    }    //end else
    CF.dcs = 0;    //make keyCdutycyclestate 0 to start new duty cycle
}

// in fader state when key ios pressed
void fs_keypress(int BPC, CColFade& CF)
{
    if (BPC > 0)    //if keyButtonPressColor is on
    {
        CF.time = BPC;    //reset fader and key duty cycle to beginning state of keyButtonPressColor
        CF.state = 1;
        CF.dcs = 0;
        CF.fadeStep = 1;
    }    //end if (keyBPC > 0)
    else
    {
        CF.time = 20;    //reset fader and key duty cycle to beginning state of keyButtonPressColor
        CF.state = 0;
        CF.dcs = 0;
        CF.fadeStep = 49;
    }    //end else
}

//was: int fader_state(int key, int keyBC, int keyBPC, int* keyCfadestep, int* keyCfadetime, int* keyCtime, int* keyCstate, int* keyCdcs) //key fader and LED color function
// called like this: fader_state(esc, escBC[0], escBPC[0], &escGfade[0], &escGfade[1], &escG[0], &escG[1], &escG[2]);    //the fader state function sets the rdata pin for this clock cycle
int fader_state(CKey& keyData, int col) //key fader and LED color function
{
        CColFade CF& = keyData.ColFade[col]; // the colour we're interested in
        int BPC& = keyData.BPC[col];
        int BC& = keyData.BC[col];
        
    if (keyData.pressed == 1)    //if key is pressed
    {
                fs_keypress(BPC, CF);
    }    //end if (key==1)
    else
    {
        if (CF.dcs == 2) //if LED has completed duty cycle
        {
                        fs_LED_duty_complete(BPC, BC, CF);
        }    //end if (*keyCdcs==2)
        else if ((CF.dcs == 1) && (CF.time == 0))    //if LED is done with first stage of duty cycle
        {
            if (CF.fadeStep < 49)    //if keyColorfadestep is below 49
                CF.time = 20 - CF.fadeTime;    //math for time left until end of duty cycle
            else
                CF.time = 20 - BC;    //math for time left until end of duty cycle
            CF.state = 0;//make key finish second stage of duty cycle off
        }
        else if ((CF.dcs == 0) && (CF.time == 0))    //if LED is ready to begin first duty cycle
        {
            if (BC > 0)    //if keyButtonColor is on
            {
                CF.time = BC;    //make keyColortime state of keyButtonColor and keyCstate 1
                CF.state = 1;
            }    //end if (keyBC > 0)
            else
            {
                CF.time = 20;    //make keyColortime full duty cycle and keyCstate to 0
                CF.state = 0;
            }    //end else
        }    //end else if (*keyCdcs==0 && *keyCtime==0)
    }    //end else
    if (CF.state==1)    //if keyColorstate is 1
    {
        PORTA |= (1<<PA0);    //rdata on
        --CF.time;    //increment keyColortime
        if ((CF.time == 0)||(CF.time == 19))    //if keyColortime is 0 or 19
        {
            ++CF.dcs;    //increment keyColordutycyclestate
        }    //end if (*keyCtime==0||*keyCtime==19)
    }    //if (*keyCstate==1)
    else
    {
        PORTA &= ~(1<<PA0);    //rdata off
        --CF.time;    //increment keyColortime
        if ((CF.time == 0)||(CF.time == 19))    //if keyColortime is 0 or 19
        {
            ++CF.dcs;    //increment keyColordutycyclestate
        }    //end if (*keyCtime==0||*keyCtime==19)
    }    //else
}    //end fader_state() function

void GetRowData()
{
    for (int row = 0; row < 10; row++)
    {
        PORTA |= (1<<row);
        key[row,0] = PINA0;
        key[row,1] = PINA1;
        key[row,2] = PINA2;
        key[row,3] = PINA3;
        key[row,4] = PINA4;
        key[row,5] = PINA5;
        key[row,6] = PINA6;
        key[row,7] = PINA7;
        key[row,8] = PINA8;
        key[row,9] = PINA9;

        PORTA &= ~(1<<row);
    }
}

void SendFaderStates()
{
    int bits = 0;

    for (int column = 0; column < 14; column++)
    {
        for (int row = 0; row < 10); row++)
        {
               for (int colour = 0, colour < 3; colour++)
               {
                     fader_state(Key[row, column], colour);
                if (bits == 0)
                {
                      sh_cp(1);
                      bits = 18;
                  }
                  else
                  {
                        sh_cp(0);
                        bits--;
                    }
                }
            }
        st_cp();
    }
}

int main(void)
{
    DDRA = (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
    PORTA = (0<<PA0)|(0<<PA1)|(0<<PA2)|(0<<PA3);
    while(1)
    {

        GetRowData();

                SendFaderStates();

        if (macro == 1)    //if macro key is pressed
        {
            ++macroS;    //incriment macroState
            if (macroS==1)    //if macroState is 1
            {
                macroFKBPCV[0] = f1BPC[0];    //store f1-f12+macro ButtonPressColor in macroFunctionButtonPressColorValue
                macroFKBPCV[1] = f1BPC[1];
                macroFKBPCV[2] = f1BPC[2];
                macroFKBPCV[3] = f2BPC[0];
                macroFKBPCV[4] = f2BPC[1];
                macroFKBPCV[5] = f2BPC[2];
                macroFKBPCV[6] = f3BPC[0];
                macroFKBPCV[7] = f3BPC[1];
                macroFKBPCV[8] = f3BPC[2];
                macroFKBPCV[9] = f4BPC[0];
                macroFKBPCV[10] = f4BPC[1];
                macroFKBPCV[11] = f4BPC[2];
                macroFKBPCV[12] = f5BPC[0];
                macroFKBPCV[13] = f5BPC[1];
                macroFKBPCV[14] = f5BPC[2];
                macroFKBPCV[15] = f6BPC[0];
                macroFKBPCV[16] = f6BPC[1];
                macroFKBPCV[17] = f6BPC[2];
                macroFKBPCV[18] = f7BPC[0];
                macroFKBPCV[19] = f7BPC[1];
                macroFKBPCV[20] = f7BPC[2];
                macroFKBPCV[21] = f8BPC[0];
                macroFKBPCV[22] = f8BPC[1];
                macroFKBPCV[23] = f8BPC[2];
                macroFKBPCV[24] = f9BPC[0];
                macroFKBPCV[25] = f9BPC[1];
                macroFKBPCV[26] = f9BPC[2];
                macroFKBPCV[27] = f10BPC[0];
                macroFKBPCV[28] = f10BPC[1];
                macroFKBPCV[29] = f10BPC[2];
                macroFKBPCV[30] = f11BPC[0];
                macroFKBPCV[31] = f11BPC[1];
                macroFKBPCV[32] = f11BPC[2];
                macroFKBPCV[33] = f12BPC[0];
                macroFKBPCV[34] = f12BPC[1];
                macroFKBPCV[35] = f12BPC[2];
                macroFKBPCV[36] = macroBPC[0];
                macroFKBPCV[37] = macroBPC[1];
                macroFKBPCV[38] = macroBPC[2];
                f1BPC[0] = f1BC[0];    //set f1-f12+macro ButtonPressColor to f1-f12+macro ButtonColor
                f1BPC[1] = f1BC[1];
                f1BPC[2] = f1BC[2];
                f2BPC[0] = f2BC[0];
                f2BPC[1] = f2BC[1];
                f2BPC[2] = f2BC[2];
                f3BPC[0] = f3BC[0];
                f3BPC[1] = f3BC[1];
                f3BPC[2] = f3BC[2];
                f4BPC[0] = f4BC[0];
                f4BPC[1] = f4BC[1];
                f4BPC[2] = f4BC[2];
                f5BPC[0] = f5BC[0];
                f5BPC[1] = f5BC[1];
                f5BPC[2] = f5BC[2];
                f6BPC[0] = f6BC[0];
                f6BPC[1] = f6BC[1];
                f6BPC[2] = f6BC[2];
                f7BPC[0] = f7BC[0];
                f7BPC[1] = f7BC[1];
                f7BPC[2] = f7BC[2];
                f8BPC[0] = f8BC[0];
                f8BPC[1] = f8BC[1];
                f8BPC[2] = f8BC[2];
                f9BPC[0] = f9BC[0];
                f9BPC[1] = f9BC[1];
                f9BPC[2] = f9BC[2];
                f10BPC[0] = f10BC[0];
                f10BPC[1] = f10BC[1];
                f10BPC[2] = f10BC[2];
                f11BPC[0] = f11BC[0];
                f11BPC[1] = f11BC[1];
                f11BPC[2] = f11BC[2];
                f12BPC[0] = f12BC[0];
                f12BPC[1] = f12BC[1];
                f12BPC[2] = f12BC[2];
                macroBPC[0] = macroBC[0];
                macroBPC[1] = macroBC[1];
                macroBPC[2] = macroBC[2];
                f1BC[0] = macroS1BC[0];    //set f1-f12+macro ButtonColor to macroState1ButtonColor
                f1BC[1] = macroS1BC[1];
                f1BC[2] = macroS1BC[2];
                f2BC[0] = macroS1BC[0];
                f2BC[1] = macroS1BC[1];
                f2BC[2] = macroS1BC[2];
                f3BC[0] = macroS1BC[0];
                f3BC[1] = macroS1BC[1];
                f3BC[2] = macroS1BC[2];
                f4BC[0] = macroS1BC[0];
                f4BC[1] = macroS1BC[1];
                f4BC[2] = macroS1BC[2];
                f5BC[0] = macroS1BC[0];
                f5BC[1] = macroS1BC[1];
                f5BC[2] = macroS1BC[2];
                f6BC[0] = macroS1BC[0];
                f6BC[1] = macroS1BC[1];
                f6BC[2] = macroS1BC[2];
                f7BC[0] = macroS1BC[0];
                f7BC[1] = macroS1BC[1];
                f7BC[2] = macroS1BC[2];
                f8BC[0] = macroS1BC[0];
                f8BC[1] = macroS1BC[1];
                f8BC[2] = macroS1BC[2];
                f9BC[0] = macroS1BC[0];
                f9BC[1] = macroS1BC[1];
                f9BC[2] = macroS1BC[2];
                f10BC[0] = macroS1BC[0];
                f10BC[1] = macroS1BC[1];
                f10BC[2] = macroS1BC[2];
                f11BC[0] = macroS1BC[0];
                f11BC[1] = macroS1BC[1];
                f11BC[2] = macroS1BC[2];
                f12BC[0] = macroS1BC[0];
                f12BC[1] = macroS1BC[1];
                f12BC[2] = macroS1BC[2];
                macroBC[0] = macroS1BC[0];
                macroBC[1] = macroS1BC[1];
                macroBC[2] = macroS1BC[2];
            }    //end if(macroS==1)
            else if (macroS==2)    //if macroState is  2
            {
                f1BC[0] = macroS2BC[0];    //set f1-f12+macro ButtonColor to macroState2ButtonColor
                f1BC[1] = macroS2BC[1];
                f1BC[2] = macroS2BC[2];
                f2BC[0] = macroS2BC[0];
                f2BC[1] = macroS2BC[1];
                f2BC[2] = macroS2BC[2];
                f3BC[0] = macroS2BC[0];
                f3BC[1] = macroS2BC[1];
                f3BC[2] = macroS2BC[2];
                f4BC[0] = macroS2BC[0];
                f4BC[1] = macroS2BC[1];
                f4BC[2] = macroS2BC[2];
                f5BC[0] = macroS2BC[0];
                f5BC[1] = macroS2BC[1];
                f5BC[2] = macroS2BC[2];
                f6BC[0] = macroS2BC[0];
                f6BC[1] = macroS2BC[1];
                f6BC[2] = macroS2BC[2];
                f7BC[0] = macroS2BC[0];
                f7BC[1] = macroS2BC[1];
                f7BC[2] = macroS2BC[2];
                f8BC[0] = macroS2BC[0];
                f8BC[1] = macroS2BC[1];
                f8BC[2] = macroS2BC[2];
                f9BC[0] = macroS2BC[0];
                f9BC[1] = macroS2BC[1];
                f9BC[2] = macroS2BC[2];
                f10BC[0] = macroS2BC[0];
                f10BC[1] = macroS2BC[1];
                f10BC[2] = macroS2BC[2];
                f11BC[0] = macroS2BC[0];
                f11BC[1] = macroS2BC[1];
                f11BC[2] = macroS2BC[2];
                f12BC[0] = macroS2BC[0];
                f12BC[1] = macroS2BC[1];
                f12BC[2] = macroS2BC[2];
                macroBC[0] = macroS2BC[0];
                macroBC[1] = macroS2BC[1];
                macroBC[2] = macroS2BC[2];
            }    //end if(macroS==2)
            else
            {
                f1BC[0] = f1BPC[0];    //set f1-f12+macro ButtonColor to f1-f12+macro ButtonPressColor
                f1BC[1] = f1BPC[1];
                f1BC[2] = f1BPC[2];
                f2BC[0] = f2BPC[0];
                f2BC[1] = f2BPC[1];
                f2BC[2] = f2BPC[2];
                f3BC[0] = f3BPC[0];
                f3BC[1] = f3BPC[1];
                f3BC[2] = f3BPC[2];
                f4BC[0] = f4BPC[0];
                f4BC[1] = f4BPC[1];
                f4BC[2] = f4BPC[2];
                f5BC[0] = f5BPC[0];
                f5BC[1] = f5BPC[1];
                f5BC[2] = f5BPC[2];
                f6BC[0] = f6BPC[0];
                f6BC[1] = f6BPC[1];
                f6BC[2] = f6BPC[2];
                f7BC[0] = f7BPC[0];
                f7BC[1] = f7BPC[1];
                f7BC[2] = f7BPC[2];
                f8BC[0] = f8BPC[0];
                f8BC[1] = f8BPC[1];
                f8BC[2] = f8BPC[2];
                f9BC[0] = f9BPC[0];
                f9BC[1] = f9BPC[1];
                f9BC[2] = f9BPC[2];
                f10BC[0] = f10BPC[0];
                f10BC[1] = f10BPC[1];
                f10BC[2] = f10BPC[2];
                f11BC[0] = f11BPC[0];
                f11BC[1] = f11BPC[1];
                f11BC[2] = f11BPC[2];
                f12BC[0] = f12BPC[0];
                f12BC[1] = f12BPC[1];
                f12BC[2] = f12BPC[2];
                macroBC[0] = macroBPC[0];
                macroBC[1] = macroBPC[1];
                macroBC[2] = macroBPC[2];
                f1BPC[0] = macroFKBPCV[0];    //set f1-f12+macro ButtonPressColor to macroFunctionKeyPressColorValue
                f1BPC[1] = macroFKBPCV[1];
                f1BPC[2] = macroFKBPCV[2];
                f2BPC[0] = macroFKBPCV[3];
                f2BPC[1] = macroFKBPCV[4];
                f2BPC[2] = macroFKBPCV[5];
                f3BPC[0] = macroFKBPCV[6];
                f3BPC[1] = macroFKBPCV[7];
                f3BPC[2] = macroFKBPCV[8];
                f4BPC[0] = macroFKBPCV[9];
                f4BPC[1] = macroFKBPCV[10];
                f4BPC[2] = macroFKBPCV[11];
                f5BPC[0] = macroFKBPCV[12];
                f5BPC[1] = macroFKBPCV[13];
                f5BPC[2] = macroFKBPCV[14];
                f6BPC[0] = macroFKBPCV[15];
                f6BPC[1] = macroFKBPCV[16];
                f6BPC[2] = macroFKBPCV[17];
                f7BPC[0] = macroFKBPCV[18];
                f7BPC[1] = macroFKBPCV[19];
                f7BPC[2] = macroFKBPCV[20];
                f8BPC[0] = macroFKBPCV[21];
                f8BPC[1] = macroFKBPCV[22];
                f8BPC[2] = macroFKBPCV[23];
                f9BPC[0] = macroFKBPCV[24];
                f9BPC[1] = macroFKBPCV[25];
                f9BPC[2] = macroFKBPCV[26];
                f10BPC[0] = macroFKBPCV[27];
                f10BPC[1] = macroFKBPCV[28];
                f10BPC[2] = macroFKBPCV[29];
                f11BPC[0] = macroFKBPCV[30];
                f11BPC[1] = macroFKBPCV[31];
                f11BPC[2] = macroFKBPCV[32];
                f12BPC[0] = macroFKBPCV[33];
                f12BPC[1] = macroFKBPCV[34];
                f12BPC[2] = macroFKBPCV[35];
                macroBPC[0] = macroFKBPCV[36];
                macroBPC[1] = macroFKBPCV[37];
                macroBPC[2] = macroFKBPCV[38];
                macroS = 0;
            }    //end else
        }    //end if(macro==1)
        else if (column==14)
        {
            fader_state(macro, macroBC[0], macroBPC[0], &macroGfade[0], &macroGfade[1], &macroG[0], &macroG[1], &macroG[2]);
            sh_cp(0);
            fader_state(macro, macroBC[1], macroBPC[1], &macroBfade[0], &macroBfade[1], &macroB[0], &macroB[1], &macroB[2]);
            sh_cp(0);
            fader_state(macro, macroBC[2], macroBPC[2], &macroRfade[0], &macroRfade[1], &macroR[0], &macroR[1], &macroR[2]);
            sh_cp(0);
            fader_state(numlock, numlockBC[0], numlockBPC[0], &numlockGfade[0], &numlockGfade[1], &numlockG[0], &numlockG[1], &numlockG[2]);
            sh_cp(0);
            fader_state(numlock, numlockBC[1], numlockBPC[1], &numlockBfade[0], &numlockBfade[1], &numlockB[0], &numlockB[1], &numlockB[2]);
            sh_cp(0);
            fader_state(numlock, numlockBC[2], numlockBPC[2], &numlockRfade[0], &numlockRfade[1], &numlockR[0], &numlockR[1], &numlockR[2]);
            sh_cp(0);
            fader_state(num7, num7BC[0], num7BPC[0], &num7Gfade[0], &num7Gfade[1], &num7G[0], &num7G[1], &num7G[2]);
            sh_cp(0);
            fader_state(num7, num7BC[1], num7BPC[1], &num7Bfade[0], &num7Bfade[1], &num7B[0], &num7B[1], &num7B[2]);
            sh_cp(0);
            fader_state(num7, num7BC[2], num7BPC[2], &num7Rfade[0], &num7Rfade[1], &num7R[0], &num7R[1], &num7R[2]);
            sh_cp(0);
            fader_state(num4, num4BC[0], num4BPC[0], &num4Gfade[0], &num4Gfade[1], &num4G[0], &num4G[1], &num4G[2]);
            sh_cp(0);
            fader_state(num4, num4BC[1], num4BPC[1], &num4Bfade[0], &num4Bfade[1], &num4B[0], &num4B[1], &num4B[2]);
            sh_cp(0);
            fader_state(num4, num4BC[2], num4BPC[2], &num4Rfade[0], &num4Rfade[1], &num4R[0], &num4R[1], &num4R[2]);
            sh_cp(0);
            fader_state(num1, num1BC[0], num1BPC[0], &num1Gfade[0], &num1Gfade[1], &num1G[0], &num1G[1], &num1G[2]);
            sh_cp(0);
            fader_state(num1, num1BC[1], num1BPC[1], &num1Bfade[0], &num1Bfade[1], &num1B[0], &num1B[1], &num1B[2]);
            sh_cp(0);
            fader_state(num1, num1BC[2], num1BPC[2], &num1Rfade[0], &num1Rfade[1], &num1R[0], &num1R[1], &num1R[2]);
            sh_cp(1);
            fader_state(num0, num0BC[0], num0BPC[0], &num0Gfade[0], &num0Gfade[1], &num0G[0], &num0G[1], &num0G[2]);
            sh_cp(0);
            fader_state(num0, num0BC[1], num0BPC[1], &num0Bfade[0], &num0Bfade[1], &num0B[0], &num0B[1], &num0B[2]);
            sh_cp(0);
            fader_state(num0, num0BC[2], num0BPC[2], &num0Rfade[0], &num0Rfade[1], &num0R[0], &num0R[1], &num0R[2]);
            sh_cp(0);
            st_cp();
            column++;
        }    //end else if (column==14)
        else if (column==15)
        {
            fader_state(bright, brightBC[0], brightBPC[0], &brightGfade[0], &brightGfade[1], &brightG[0], &brightG[1], &brightG[2]);
            sh_cp(0);
            fader_state(bright, brightBC[1], brightBPC[1], &brightBfade[0], &brightBfade[1], &brightB[0], &brightB[1], &brightB[2]);
            sh_cp(0);
            fader_state(bright, brightBC[2], brightBPC[2], &brightRfade[0], &brightRfade[1], &brightR[0], &brightR[1], &brightR[2]);
            sh_cp(0);
            fader_state(numfslash, numfslashBC[0], numfslashBPC[0], &numfslashGfade[0], &numfslashGfade[1], &numfslashG[0], &numfslashG[1], &numfslashG[2]);
            sh_cp(0);
            fader_state(numfslash, numfslashBC[1], numfslashBPC[1], &numfslashBfade[0], &numfslashBfade[1], &numfslashB[0], &numfslashB[1], &numfslashB[2]);
            sh_cp(0);
            fader_state(numfslash, numfslashBC[2], numfslashBPC[2], &numfslashRfade[0], &numfslashRfade[1], &numfslashR[0], &numfslashR[1], &numfslashR[2]);
            sh_cp(0);
            fader_state(num8, num8BC[0], num8BPC[0], &num8Gfade[0], &num8Gfade[1], &num8G[0], &num8G[1], &num8G[2]);
            sh_cp(0);
            fader_state(num8, num8BC[1], num8BPC[1], &num8Bfade[0], &num8Bfade[1], &num8B[0], &num8B[1], &num8B[2]);
            sh_cp(0);
            fader_state(num8, num8BC[2], num8BPC[2], &num8Rfade[0], &num8Rfade[1], &num8R[0], &num8R[1], &num8R[2]);
            sh_cp(0);
            fader_state(num5, num5BC[0], num5BPC[0], &num5Gfade[0], &num5Gfade[1], &num5G[0], &num5G[1], &num5G[2]);
            sh_cp(0);
            fader_state(num5, num5BC[1], num5BPC[1], &num5Bfade[0], &num5Bfade[1], &num5B[0], &num5B[1], &num5B[2]);
            sh_cp(0);
            fader_state(num5, num5BC[2], num5BPC[2], &num5Rfade[0], &num5Rfade[1], &num5R[0], &num5R[1], &num5R[2]);
            sh_cp(0);
            fader_state(num2, num2BC[0], num2BPC[0], &num2Gfade[0], &num2Gfade[1], &num2G[0], &num2G[1], &num2G[2]);
            sh_cp(0);
            fader_state(num2, num2BC[1], num2BPC[1], &num2Bfade[0], &num2Bfade[1], &num2B[0], &num2B[1], &num2B[2]);
            sh_cp(0);
            fader_state(num2, num2BC[2], num2BPC[2], &num2Rfade[0], &num2Rfade[1], &num2R[0], &num2R[1], &num2R[2]);
            sh_cp(0);
            fader_state(numperiod, numperiodBC[0], numperiodBPC[0], &numperiodGfade[0], &numperiodGfade[1], &numperiodG[0], &numperiodG[1], &numperiodG[2]);
            sh_cp(1);
            fader_state(numperiod, numperiodBC[1], numperiodBPC[1], &numperiodBfade[0], &numperiodBfade[1], &numperiodB[0], &numperiodB[1], &numperiodB[2]);
            sh_cp(0);
            fader_state(numperiod, numperiodBC[2], numperiodBPC[2], &numperiodRfade[0], &numperiodRfade[1], &numperiodR[0], &numperiodR[1], &numperiodR[2]);
            sh_cp(0);
            st_cp();
            column++;
        }    //end else if (column==15)
        else if (column==16)
        {
            fader_state(mute, muteBC[0], muteBPC[0], &muteGfade[0], &muteGfade[1], &muteG[0], &muteG[1], &muteG[2]);
            sh_cp(0);
            fader_state(mute, muteBC[1], muteBPC[1], &muteBfade[0], &muteBfade[1], &muteB[0], &muteB[1], &muteB[2]);
            sh_cp(0);
            fader_state(mute, muteBC[2], muteBPC[2], &muteRfade[0], &muteRfade[1], &muteR[0], &muteR[1], &muteR[2]);
            sh_cp(0);
            fader_state(asterisk, asteriskBC[0], asteriskBPC[0], &asteriskGfade[0], &asteriskGfade[1], &asteriskG[0], &asteriskG[1], &asteriskG[2]);
            sh_cp(0);
            fader_state(asterisk, asteriskBC[1], asteriskBPC[1], &asteriskBfade[0], &asteriskBfade[1], &asteriskB[0], &asteriskB[1], &asteriskB[2]);
            sh_cp(0);
            fader_state(asterisk, asteriskBC[2], asteriskBPC[2], &asteriskRfade[0], &asteriskRfade[1], &asteriskR[0], &asteriskR[1], &asteriskR[2]);
            sh_cp(0);
            fader_state(num9, num9BC[0], num9BPC[0], &num9Gfade[0], &num9Gfade[1], &num9G[0], &num9G[1], &num9G[2]);
            sh_cp(0);
            fader_state(num9, num9BC[1], num9BPC[1], &num9Bfade[0], &num9Bfade[1], &num9B[0], &num9B[1], &num9B[2]);
            sh_cp(0);
            fader_state(num9, num9BC[2], num9BPC[2], &num9Rfade[0], &num9Rfade[1], &num9R[0], &num9R[1], &num9R[2]);
            sh_cp(0);
            fader_state(num6, num6BC[0], num6BPC[0], &num6Gfade[0], &num6Gfade[1], &num6G[0], &num6G[1], &num6G[2]);
            sh_cp(0);
            fader_state(num6, num6BC[1], num6BPC[1], &num6Bfade[0], &num6Bfade[1], &num6B[0], &num6B[1], &num6B[2]);
            sh_cp(0);
            fader_state(num6, num6BC[2], num6BPC[2], &num6Rfade[0], &num6Rfade[1], &num6R[0], &num6R[1], &num6R[2]);
            sh_cp(0);
            fader_state(num3, num3BC[0], num3BPC[0], &num3Gfade[0], &num3Gfade[1], &num3G[0], &num3G[1], &num3G[2]);
            sh_cp(0);
            fader_state(num3, num3BC[1], num3BPC[1], &num3Bfade[0], &num3Bfade[1], &num3B[0], &num3B[1], &num3B[2]);
            sh_cp(0);
            fader_state(num3, num3BC[2], num3BPC[2], &num3Rfade[0], &num3Rfade[1], &num3R[0], &num3R[1], &num3R[2]);
            sh_cp(0);
            fader_state(numenter, numenterBC[0], numenterBPC[0], &numenterGfade[0], &numenterGfade[1], &numenterG[0], &numenterG[1], &numenterG[2]);
            sh_cp(0);
            fader_state(numenter, numenterBC[1], numenterBPC[1], &numenterBfade[0], &numenterBfade[1], &numenterB[0], &numenterB[1], &numenterB[2]);
            sh_cp(1);
            fader_state(numenter, numenterBC[2], numenterBPC[2], &numenterRfade[0], &numenterRfade[1], &numenterR[0], &numenterR[1], &numenterR[2]);
            sh_cp(0);
            st_cp();
            column++;
        }    //end else if (column==16)
        else if (column==17)
        {
            fader_state(prtscrn, prtscrnBC[0], prtscrnBPC[0], &prtscrnGfade[0], &prtscrnGfade[1], &prtscrnG[0], &prtscrnG[1], &prtscrnG[2]);
            sh_cp(0);
            fader_state(prtscrn, prtscrnBC[1], prtscrnBPC[1], &prtscrnBfade[0], &prtscrnBfade[1], &prtscrnB[0], &prtscrnB[1], &prtscrnB[2]);
            sh_cp(0);
            fader_state(prtscrn, prtscrnBC[2], prtscrnBPC[2], &prtscrnRfade[0], &prtscrnRfade[1], &prtscrnR[0], &prtscrnR[1], &prtscrnR[2]);
            sh_cp(0);
            fader_state(scrolllock, scrolllockBC[0], scrolllockBPC[0], &scrolllockGfade[0], &scrolllockGfade[1], &scrolllockG[0], &scrolllockG[1], &scrolllockG[2]);
            sh_cp(0);
            fader_state(scrolllock, scrolllockBC[1], scrolllockBPC[1], &scrolllockBfade[0], &scrolllockBfade[1], &scrolllockB[0], &scrolllockB[1], &scrolllockB[2]);
            sh_cp(0);
            fader_state(scrolllock, scrolllockBC[2], scrolllockBPC[2], &scrolllockRfade[0], &scrolllockRfade[1], &scrolllockR[0], &scrolllockR[1], &scrolllockR[2]);
            sh_cp(0);
            fader_state(pause, pauseBC[0], pauseBPC[0], &pauseGfade[0], &pauseGfade[1], &pauseG[0], &pauseG[1], &pauseG[2]);
            sh_cp(0);
            fader_state(pause, pauseBC[1], pauseBPC[1], &pauseBfade[0], &pauseBfade[1], &pauseB[0], &pauseB[1], &pauseB[2]);
            sh_cp(0);
            fader_state(pause, pauseBC[2], pauseBPC[2], &pauseRfade[0], &pauseRfade[1], &pauseR[0], &pauseR[1], &pauseR[2]);
            sh_cp(0);
            fader_state(numminus, numminusBC[0], numminusBPC[0], &numminusGfade[0], &numminusGfade[1], &numminusG[0], &numminusG[1], &numminusG[2]);
            sh_cp(0);
            fader_state(numminus, numminusBC[1], numminusBPC[1], &numminusBfade[0], &numminusBfade[1], &numminusB[0], &numminusB[1], &numminusB[2]);
            sh_cp(0);
            fader_state(numminus, numminusBC[2], numminusBPC[2], &numminusRfade[0], &numminusRfade[1], &numminusR[0], &numminusR[1], &numminusR[2]);
            sh_cp(0);
            fader_state(plus, plusBC[0], plusBPC[0], &plusGfade[0], &plusGfade[1], &plusG[0], &plusG[1], &plusG[2]);
            sh_cp(0);
            fader_state(plus, plusBC[1], plusBPC[1], &plusBfade[0], &plusBfade[1], &plusB[0], &plusB[1], &plusB[2]);
            sh_cp(0);
            fader_state(plus, plusBC[2], plusBPC[2], &plusRfade[0], &plusRfade[1], &plusR[0], &plusR[1], &plusR[2]);
            sh_cp(0);
            PORTA &= ~(1<<PA0);    //sets rdata to low since there are no more keys to fill up the remainder of the 18 LED slots and the remainder of the 24 total 74HC595 pins low
            sh_cp(0);
            sh_cp(0);
            sh_cp(1);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            st_cp();
            column = 0;    //restart at the beginning of column loop
        }    //end else if (column==17)
    }    //end while(1)
}    //end main

The important things are:

1) use appropriate data structures
2) Create functions to handle discrete chunks of functionality

The biggest thing I've done in your code is to declare an array of keys so they can be accessed by index rather than by name. I've also stopped using arrays where it makes no good sense.

I also noticed that your code to read the rows seemed incorrect, but maybe I just don't understand.

Don't assume my refactoring of your code is correct -- I'm sure it's not -- but see if there's anything you can glean from it to make your code simpler.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
There were 11 rows (10 keys to be registered in each, aside from the 11th row) and 18 columns (18 LEDs in each, aside from the 18th column) in total. I think you got tripped up when you got to the if(macro==1) statement right before the 15th column (where the macro key LEDs are set) and didn't read past it to column 15-18. Can't really say it's your fault considering how much code I had written. lol

I don't think I understand what you've done here, but I'm learning. I don't understand much about classes and the functions you wrote for them I don't get either. Google will guide me.

What I wrote for reading the rows is completely incorrect as far as the actual pins go. I don't have a microcontroller with enough GPIO selected yet to program appropriately for the keys since it requires 21 GPIO to register the keypresses (another 4 for the LEDs, and 2 for USB HID communication), and just put A0-A9 in there as placeholders. I've only got a total of 16 GPIO on the MCU I've currently got for testing purposes. Eventually, I will swap those out.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
As far as the code goes there were a couple variables you said you weren't sure about. The BC variables were button color arrays, so it was setup like this: keyBC={Green0-20, Blue0-20, Red0-20}, and BPC was Button Press Color in the same design. Any key had a completely separate normal button color, and when pressed could change to any other color and fade back to the normal button color state. I'm still recognizing what you did, but it looks like with the way you wrote the variables out that each key wouldn't be able to have it's own unique button color and button press color.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
So much of what you've done is something I had an inclination I might be able to do, but hadn't even begun thinking about it seriously! Very brilliant on quite a bit of it. Some of the values were wrong, but that's because my code was a mess. lol

I'm confused by why you've made function fs_keypress(), and fs_LED_duty_complete() though?! It's going to have to run that code every time that the if statements are true. It seems it's just added text to the program as far as I can see, but maybe in my novice ways I don't understand. Does it somehow translate to less overhead since it doesn't have to skip over as much code passing that particular if statement??

Also, these for statements won't work exactly. At least I don't think so. Each time that an st_cp is called I was hoping to put onto a timer without hanging up the rest of the code being that it will be stuck in a for loop.
 
Last edited:

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
I'm confused by why you've made function fs_keypress(), and fs_LED_duty_complete() though?! It's going to have to run that code every time that the if statements are true.

Those exist purely to simplify the code and to make it more readable. The functions themselves are short and understandable without being trivial, and they have a distinct purpose. When you read the code calling them you can concentrate on the activity at a particular level of abstraction and delve deeper if you need to.

It makes the code easier to read by a human, and that makes it easier to understand, modify, debug, etc.

The source code is made for people to read. Not to make it easy for compilers. The compiler may determine that the function is called only in one place and create inline code. Even if it doesn't, unless your code is extremely time critical, the overhead will be minor.

It seems it's just added text to the program as far as I can see, but maybe in my novice ways I don't understand. Does it somehow translate to less overhead since it doesn't have to skip over as much code passing that particular if statement??

The less overhead is inside your head when you come to read the code again.

Properly done, with each function limited in size to a page, or what can be seen on the screen all at once, you can look at it and grasp what it does. It is an aid to your understanding.

Also, these for statements won't work exactly. At least I don't think so. Each time that an st_cp is called I was hoping to put onto a timer without hanging up the rest of the code being that it will be stuck in a for loop.

I think you need to carefully think out how you want your code to operate. I don't know and your original code wasn't helping me.

Abstracting the code so that you have a collection of keys, and then dealing with those keys in the same manner where possible will make things a lot clearer. Originally I had to look through a lot of code before I noticed that all those variables were pretty much the same and that they were all initialised to the same values. Then it took time before I say that some really were handled differently (and that's where I stopped)

Tackling a program like this I would think something like:

1) I have a heap of keys
2) I need to set them to initial values.
3) I need to scan them
4) I need to change values based on which one is pressed, and how long it has been since others were pressed
5) I need to "display" the results (LED colours)

from that I would start with:

Code:
// class to hold all of my keys
class CKeys {
  int x; // just a dummy.  I don't know what will go here
}

CKeys keys; // my keys

void setInitialValues(CKeys& keys)\
{
  // nothing here yet
}

// initialization
void init()
{
  setInitialValues(keys);
}

void scan(CKeys& keys)\
{
  // nothing here yet
}

void process(CKeys& keys)\
{
  // nothing here yet
}

void display(CKeys& keys)\
{
  // nothing here yet
}

// main loop
void main()
{
  scan(keys);     // scan the key values
  process(keys);  // change values based on what is pressed etc.
  display(keys);  // update the LED display
}

At this point I have the framework. I might note that I have only a single key structure, so there is no need to pass it as a parameter, and I may realise ther is more initialization required (setting IO pins, initializing the display, etc.) so let's presume I add that.

The next step is to realise that the keys are an array of x rows of y columns (but not what a key itself actually is)

Code:
#define KEY_ROWS 10
#define KEY_COLS 14

// class to hold all of my keys
class CKeys {
  int x[KEY_ROWS,KEY_COLS]; // just a dummy.  I don't know what will go here
}

CKeys keys; // my keys

void setInitialKeyValues();
{
  for(int x = 0; x < KEY_ROWS; x++) // for each row
  {
    for (int y = 0; y < KEY_COLS; y++) // for each column
    {
      // nothing here yet (initialise key at [x,y])
    }
  }
}

void initIO()
{
  // initialize IO pins, and anything else
}

void displayKeys();
{
  for(int x = 0; x < KEY_ROWS; x++) // for each row
  {
    for (int y = 0; y < KEY_COLS; y++) // for each column
    {
      // nothing here yet (display key at [x,y])
    }
  }
}

// initialization
void init()
{
  initIO();
  setInitialKeyValues();
  displayKeys(); // set all keys to default display
}

void scanKeys();
{
  for(int x = 0; x < KEY_ROWS; x++) // for each row
  {
    for (int y = 0; y < KEY_COLS; y++) // for each column
    {
      // nothing here yet (scan key at [x,y])
    }
  }
}

void processKeys();
{
  for(int x = 0; x < KEY_ROWS; x++) // for each row
  {
    for (int y = 0; y < KEY_COLS; y++) // for each column
    {
      // nothing here yet (process key at [x,y])
    }
  }
}

// main loop
void main()
{
  scanKeys();     // scan the key values
  processKeys();  // change values based on what is pressed etc.
  displayKeys();  // update the LED display
}

So now I have the core of the code.

The next thing is that I need to read the keys column by column, not row by row, and that I need to do certain initialization at the beginning of each column

Code:
void initiateKeyRead()
{
  // do what is required to set up for a read (is there anything?)
}

void requestKeyboardColumn(int y)
{
  // do what is required to read column y
}

void readKeyboardColumn(y)
{
  // set value for key[0,y];
  // set value for key[1,y];
  // set value for key[2,y];
  // ...
  // set value for key[KEY_ROWS-1,y];
}

void scanKeys();
{
  initiateKeyRead();

  for (int y = 0; y < KEY_COLS; y++) // for each column
  {
    // do IO stuff to set up hardware for the yth column
    requestKeyboardColumn(y);

    // read a column (this can't be done in a loop)
    readKeyboardColumn(y);
  }
}

And then you've probably got to a point where you can write actual code for some of these.

If they turn out to be a simple 1 or 2 line thing (requestKeyboardColumn(y) might be), then you can remove the procedure and place the code directly into the routine which called it (or maybe you don't).

What you'll end up with is code that can be followed at every level. If it runs sufficiently fast in the memory you have available, you might leave it. If not, you might look for places you can speed up the code or where you can hint to the compiler how to do that.

This is *a* way of doing stepwise refinement. Normally some of this work is figured out on paper beforehand, but if you're going direct to code it is a method which will yeild code that is not a couple of huge functions that cannot be mentally grasped all at once.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Code:
/*
 * ATTINY861_20PU_LED_MATRIX.c
 *
 * Created: 1/25/2014 4:24:47 PM
 *  Author: The Hammer
 *
 * Modified: 2/23/2014 13:00:00 PM
 *  Author: (*Steve*)
 */ 

#include <avr/io.h>

// Structure for what looks like intensity and fade values
class CColFade {
  int time;
  int state;
  int dcs;
  int fadeStep;
  int fadeTime;
  
  void CColFade();
};

// initialize to default values
void CColFade::CColFade()
: time(0)
, state (0)
, dcs (0)
, fadeStep (49)
, fadeTime (0)
{
};

// Don't know what these things are, but they sure need a stuct, and maybe a class
class CKey {
  int pressed;
  int BC[3];
  int BPC[3];
  CColFade col[3]; // G, B, R
  
  void CKey();
}

// Extra initialization for default values of these things
void CKey::CKey()
: pressed(0)
, BC({0, 20, 0})
, BPC({0, 0, 20})
{
}

// 74HC595 PWM and key variables
int row = 0, column = 0;

// things were defined like this:
// int lshift = 0, lshiftBC[3]={0, 20, 0}, lshiftBPC[3]={0, 0, 20}, lshiftGfade[2]={49, 0}, lshiftG[3]={0, 0, 0}, lshiftBfade[2]={49, 0}, lshiftB[3]={0, 0, 0}, lshiftRfade[2]={49, 0}, lshiftR[3]={0, 0, 0};

CKey keys[10,14]; // there is a array of keys (10 rows * 14 columns)

void sh_cp(int cdata);

void st_cp();

int fader_state(int key, int keyBC, int keyBPC, int* keyCfadestep, int* keyCfadetime, int* keyCtime, int* keyCstate, int* keyCdcs);

void sh_cp(int cdata)    //input rdata and cdata states into the 74HC595 chips, if cdata is 1 make cdata state high then low 
{
    if (cdata == 0)    //if cdata is 0 pulse clock pin
    {
        PORTA |= (1<<PA2);    //set clock pin high
        PORTA &= ~(1<<PA2);    //set clock pin low
    }    //end if (cdata == 0)
    else
    {
        PORTA |= (1<<PA1);    //set cdata pin high
        PORTA |= (1<<PA2);    //set clock pin high
        PORTA &= ~(1<<PA2);    //set clock pin low
        PORTA &= ~(1<<PA1);    //set cdata pin high
    }
}    //end sh_cp() function

void st_cp()    //latch all 74HC595 states
{
    PORTA |= (1<<PA3);    //set latch pin high
    PORTA &= ~(1<<PA3);    //set latch pin low
}    //end st_cp() function

// 
void fs_LED_duty_complete(int BPC, int BC, CColFade& CF)
{
    if (CF.fadeStep < 49)    //if fader timer has not run out
    {
        fs_fader_running(BPC, BC, CF);
        if (BPC < BC)    //if keyButtonPressColor is smaller than keyButtonColor
        {
            CF.fadeTime = BC - BPC;    //math to figure out time on in duty cycle
            CF.fadeTime /= 49;
            CF.fadeTime *= CF.fadeStep;
            CF.fadeTime = BC - CF.fadeTime;
            CF.time = CF.fadeTime;
        }    //end if (keyBPC < keyBC)
        else if (BPC > BC)    //if keyButtonPressColor is bigger than keyButtonColor
        {
            CF.fadeTime = BPC - BC;    //math to figure out time on in duty cycle
            CF.fadeTime /= 49;
            CF.fadeTime *= CF.fadeStep;
            CF.time = int CF.fadetime;
        }    //end else if (keyBPC > keyBC)
        else
        {
            CF.time = keyBC;    //if keyButtonPressColor and keyButtonColor are the same put keyButtonColor in effect
            CF.state = 1;
            CF.fadestep = 48;
        }    //end else
        ++CF.fadestep;
    }    //end if (*keyCfadestep < 49)
    else
    {
        if (BC > 0)    //if keyButtonColor is on
        {
            CF.time = BC;    //make keyColortime state of keyButtonColor and keyCstate 1
            CF.state = 1;
        }    //end if (keyBC > 0)
        else
        {
            CF.time = 20;    //make keyColortime full duty cycle and keyCstate to 0
            CF.state = 0;
        }    //end else
    }    //end else
    CF.dcs = 0;    //make keyCdutycyclestate 0 to start new duty cycle
}

// in fader state when key ios pressed
void fs_keypress(int BPC, CColFade& CF)
{
    if (BPC > 0)    //if keyButtonPressColor is on
    {
        CF.time = BPC;    //reset fader and key duty cycle to beginning state of keyButtonPressColor
        CF.state = 1;
        CF.dcs = 0;
        CF.fadeStep = 1;
    }    //end if (keyBPC > 0)
    else
    {
        CF.time = 20;    //reset fader and key duty cycle to beginning state of keyButtonPressColor
        CF.state = 0;
        CF.dcs = 0;
        CF.fadeStep = 49;
    }    //end else
}

//was: int fader_state(int key, int keyBC, int keyBPC, int* keyCfadestep, int* keyCfadetime, int* keyCtime, int* keyCstate, int* keyCdcs) //key fader and LED color function
// called like this: fader_state(esc, escBC[0], escBPC[0], &escGfade[0], &escGfade[1], &escG[0], &escG[1], &escG[2]);    //the fader state function sets the rdata pin for this clock cycle
int fader_state(CKey& keyData, int col) //key fader and LED color function
{
        CColFade CF& = keyData.ColFade[col]; // the colour we're interested in
        int BPC& = keyData.BPC[col];
        int BC& = keyData.BC[col];
        
    if (keyData.pressed == 1)    //if key is pressed
    {
                fs_keypress(BPC, CF);
    }    //end if (key==1)
    else
    {
        if (CF.dcs == 2) //if LED has completed duty cycle
        {
                        fs_LED_duty_complete(BPC, BC, CF);
        }    //end if (*keyCdcs==2)
        else if ((CF.dcs == 1) && (CF.time == 0))    //if LED is done with first stage of duty cycle
        {
            if (CF.fadeStep < 49)    //if keyColorfadestep is below 49
                CF.time = 20 - CF.fadeTime;    //math for time left until end of duty cycle
            else
                CF.time = 20 - BC;    //math for time left until end of duty cycle
            CF.state = 0;//make key finish second stage of duty cycle off
        }
        else if ((CF.dcs == 0) && (CF.time == 0))    //if LED is ready to begin first duty cycle
        {
            if (BC > 0)    //if keyButtonColor is on
            {
                CF.time = BC;    //make keyColortime state of keyButtonColor and keyCstate 1
                CF.state = 1;
            }    //end if (keyBC > 0)
            else
            {
                CF.time = 20;    //make keyColortime full duty cycle and keyCstate to 0
                CF.state = 0;
            }    //end else
        }    //end else if (*keyCdcs==0 && *keyCtime==0)
    }    //end else
    if (CF.state==1)    //if keyColorstate is 1
    {
        PORTA |= (1<<PA0);    //rdata on
        --CF.time;    //increment keyColortime
        if ((CF.time == 0)||(CF.time == 19))    //if keyColortime is 0 or 19
        {
            ++CF.dcs;    //increment keyColordutycyclestate
        }    //end if (*keyCtime==0||*keyCtime==19)
    }    //if (*keyCstate==1)
    else
    {
        PORTA &= ~(1<<PA0);    //rdata off
        --CF.time;    //increment keyColortime
        if ((CF.time == 0)||(CF.time == 19))    //if keyColortime is 0 or 19
        {
            ++CF.dcs;    //increment keyColordutycyclestate
        }    //end if (*keyCtime==0||*keyCtime==19)
    }    //else
}    //end fader_state() function

void GetRowData()
{
    for (int row = 0; row < 10; row++)
    {
        PORTA |= (1<<row);
        key[row,0] = PINA0;
        key[row,1] = PINA1;
        key[row,2] = PINA2;
        key[row,3] = PINA3;
        key[row,4] = PINA4;
        key[row,5] = PINA5;
        key[row,6] = PINA6;
        key[row,7] = PINA7;
        key[row,8] = PINA8;
        key[row,9] = PINA9;

        PORTA &= ~(1<<row);
    }
}

void SendFaderStates()
{
    int bits = 0;

    for (int column = 0; column < 14; column++)
    {
        for (int row = 0; row < 10); row++)
        {
               for (int colour = 0, colour < 3; colour++)
               {
                     fader_state(Key[row, column], colour);
                if (bits == 0)
                {
                      sh_cp(1);
                      bits = 18;
                  }
                  else
                  {
                        sh_cp(0);
                        bits--;
                    }
                }
            }
        st_cp();
    }
}

int main(void)
{
    DDRA = (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
    PORTA = (0<<PA0)|(0<<PA1)|(0<<PA2)|(0<<PA3);
    while(1)
    {

        GetRowData();

                SendFaderStates();

        if (macro == 1)    //if macro key is pressed
        {
            ++macroS;    //incriment macroState
            if (macroS==1)    //if macroState is 1
            {
                macroFKBPCV[0] = f1BPC[0];    //store f1-f12+macro ButtonPressColor in macroFunctionButtonPressColorValue
                macroFKBPCV[1] = f1BPC[1];
                macroFKBPCV[2] = f1BPC[2];
                macroFKBPCV[3] = f2BPC[0];
                macroFKBPCV[4] = f2BPC[1];
                macroFKBPCV[5] = f2BPC[2];
                macroFKBPCV[6] = f3BPC[0];
                macroFKBPCV[7] = f3BPC[1];
                macroFKBPCV[8] = f3BPC[2];
                macroFKBPCV[9] = f4BPC[0];
                macroFKBPCV[10] = f4BPC[1];
                macroFKBPCV[11] = f4BPC[2];
                macroFKBPCV[12] = f5BPC[0];
                macroFKBPCV[13] = f5BPC[1];
                macroFKBPCV[14] = f5BPC[2];
                macroFKBPCV[15] = f6BPC[0];
                macroFKBPCV[16] = f6BPC[1];
                macroFKBPCV[17] = f6BPC[2];
                macroFKBPCV[18] = f7BPC[0];
                macroFKBPCV[19] = f7BPC[1];
                macroFKBPCV[20] = f7BPC[2];
                macroFKBPCV[21] = f8BPC[0];
                macroFKBPCV[22] = f8BPC[1];
                macroFKBPCV[23] = f8BPC[2];
                macroFKBPCV[24] = f9BPC[0];
                macroFKBPCV[25] = f9BPC[1];
                macroFKBPCV[26] = f9BPC[2];
                macroFKBPCV[27] = f10BPC[0];
                macroFKBPCV[28] = f10BPC[1];
                macroFKBPCV[29] = f10BPC[2];
                macroFKBPCV[30] = f11BPC[0];
                macroFKBPCV[31] = f11BPC[1];
                macroFKBPCV[32] = f11BPC[2];
                macroFKBPCV[33] = f12BPC[0];
                macroFKBPCV[34] = f12BPC[1];
                macroFKBPCV[35] = f12BPC[2];
                macroFKBPCV[36] = macroBPC[0];
                macroFKBPCV[37] = macroBPC[1];
                macroFKBPCV[38] = macroBPC[2];
                f1BPC[0] = f1BC[0];    //set f1-f12+macro ButtonPressColor to f1-f12+macro ButtonColor
                f1BPC[1] = f1BC[1];
                f1BPC[2] = f1BC[2];
                f2BPC[0] = f2BC[0];
                f2BPC[1] = f2BC[1];
                f2BPC[2] = f2BC[2];
                f3BPC[0] = f3BC[0];
                f3BPC[1] = f3BC[1];
                f3BPC[2] = f3BC[2];
                f4BPC[0] = f4BC[0];
                f4BPC[1] = f4BC[1];
                f4BPC[2] = f4BC[2];
                f5BPC[0] = f5BC[0];
                f5BPC[1] = f5BC[1];
                f5BPC[2] = f5BC[2];
                f6BPC[0] = f6BC[0];
                f6BPC[1] = f6BC[1];
                f6BPC[2] = f6BC[2];
                f7BPC[0] = f7BC[0];
                f7BPC[1] = f7BC[1];
                f7BPC[2] = f7BC[2];
                f8BPC[0] = f8BC[0];
                f8BPC[1] = f8BC[1];
                f8BPC[2] = f8BC[2];
                f9BPC[0] = f9BC[0];
                f9BPC[1] = f9BC[1];
                f9BPC[2] = f9BC[2];
                f10BPC[0] = f10BC[0];
                f10BPC[1] = f10BC[1];
                f10BPC[2] = f10BC[2];
                f11BPC[0] = f11BC[0];
                f11BPC[1] = f11BC[1];
                f11BPC[2] = f11BC[2];
                f12BPC[0] = f12BC[0];
                f12BPC[1] = f12BC[1];
                f12BPC[2] = f12BC[2];
                macroBPC[0] = macroBC[0];
                macroBPC[1] = macroBC[1];
                macroBPC[2] = macroBC[2];
                f1BC[0] = macroS1BC[0];    //set f1-f12+macro ButtonColor to macroState1ButtonColor
                f1BC[1] = macroS1BC[1];
                f1BC[2] = macroS1BC[2];
                f2BC[0] = macroS1BC[0];
                f2BC[1] = macroS1BC[1];
                f2BC[2] = macroS1BC[2];
                f3BC[0] = macroS1BC[0];
                f3BC[1] = macroS1BC[1];
                f3BC[2] = macroS1BC[2];
                f4BC[0] = macroS1BC[0];
                f4BC[1] = macroS1BC[1];
                f4BC[2] = macroS1BC[2];
                f5BC[0] = macroS1BC[0];
                f5BC[1] = macroS1BC[1];
                f5BC[2] = macroS1BC[2];
                f6BC[0] = macroS1BC[0];
                f6BC[1] = macroS1BC[1];
                f6BC[2] = macroS1BC[2];
                f7BC[0] = macroS1BC[0];
                f7BC[1] = macroS1BC[1];
                f7BC[2] = macroS1BC[2];
                f8BC[0] = macroS1BC[0];
                f8BC[1] = macroS1BC[1];
                f8BC[2] = macroS1BC[2];
                f9BC[0] = macroS1BC[0];
                f9BC[1] = macroS1BC[1];
                f9BC[2] = macroS1BC[2];
                f10BC[0] = macroS1BC[0];
                f10BC[1] = macroS1BC[1];
                f10BC[2] = macroS1BC[2];
                f11BC[0] = macroS1BC[0];
                f11BC[1] = macroS1BC[1];
                f11BC[2] = macroS1BC[2];
                f12BC[0] = macroS1BC[0];
                f12BC[1] = macroS1BC[1];
                f12BC[2] = macroS1BC[2];
                macroBC[0] = macroS1BC[0];
                macroBC[1] = macroS1BC[1];
                macroBC[2] = macroS1BC[2];
            }    //end if(macroS==1)
            else if (macroS==2)    //if macroState is  2
            {
                f1BC[0] = macroS2BC[0];    //set f1-f12+macro ButtonColor to macroState2ButtonColor
                f1BC[1] = macroS2BC[1];
                f1BC[2] = macroS2BC[2];
                f2BC[0] = macroS2BC[0];
                f2BC[1] = macroS2BC[1];
                f2BC[2] = macroS2BC[2];
                f3BC[0] = macroS2BC[0];
                f3BC[1] = macroS2BC[1];
                f3BC[2] = macroS2BC[2];
                f4BC[0] = macroS2BC[0];
                f4BC[1] = macroS2BC[1];
                f4BC[2] = macroS2BC[2];
                f5BC[0] = macroS2BC[0];
                f5BC[1] = macroS2BC[1];
                f5BC[2] = macroS2BC[2];
                f6BC[0] = macroS2BC[0];
                f6BC[1] = macroS2BC[1];
                f6BC[2] = macroS2BC[2];
                f7BC[0] = macroS2BC[0];
                f7BC[1] = macroS2BC[1];
                f7BC[2] = macroS2BC[2];
                f8BC[0] = macroS2BC[0];
                f8BC[1] = macroS2BC[1];
                f8BC[2] = macroS2BC[2];
                f9BC[0] = macroS2BC[0];
                f9BC[1] = macroS2BC[1];
                f9BC[2] = macroS2BC[2];
                f10BC[0] = macroS2BC[0];
                f10BC[1] = macroS2BC[1];
                f10BC[2] = macroS2BC[2];
                f11BC[0] = macroS2BC[0];
                f11BC[1] = macroS2BC[1];
                f11BC[2] = macroS2BC[2];
                f12BC[0] = macroS2BC[0];
                f12BC[1] = macroS2BC[1];
                f12BC[2] = macroS2BC[2];
                macroBC[0] = macroS2BC[0];
                macroBC[1] = macroS2BC[1];
                macroBC[2] = macroS2BC[2];
            }    //end if(macroS==2)
            else
            {
                f1BC[0] = f1BPC[0];    //set f1-f12+macro ButtonColor to f1-f12+macro ButtonPressColor
                f1BC[1] = f1BPC[1];
                f1BC[2] = f1BPC[2];
                f2BC[0] = f2BPC[0];
                f2BC[1] = f2BPC[1];
                f2BC[2] = f2BPC[2];
                f3BC[0] = f3BPC[0];
                f3BC[1] = f3BPC[1];
                f3BC[2] = f3BPC[2];
                f4BC[0] = f4BPC[0];
                f4BC[1] = f4BPC[1];
                f4BC[2] = f4BPC[2];
                f5BC[0] = f5BPC[0];
                f5BC[1] = f5BPC[1];
                f5BC[2] = f5BPC[2];
                f6BC[0] = f6BPC[0];
                f6BC[1] = f6BPC[1];
                f6BC[2] = f6BPC[2];
                f7BC[0] = f7BPC[0];
                f7BC[1] = f7BPC[1];
                f7BC[2] = f7BPC[2];
                f8BC[0] = f8BPC[0];
                f8BC[1] = f8BPC[1];
                f8BC[2] = f8BPC[2];
                f9BC[0] = f9BPC[0];
                f9BC[1] = f9BPC[1];
                f9BC[2] = f9BPC[2];
                f10BC[0] = f10BPC[0];
                f10BC[1] = f10BPC[1];
                f10BC[2] = f10BPC[2];
                f11BC[0] = f11BPC[0];
                f11BC[1] = f11BPC[1];
                f11BC[2] = f11BPC[2];
                f12BC[0] = f12BPC[0];
                f12BC[1] = f12BPC[1];
                f12BC[2] = f12BPC[2];
                macroBC[0] = macroBPC[0];
                macroBC[1] = macroBPC[1];
                macroBC[2] = macroBPC[2];
                f1BPC[0] = macroFKBPCV[0];    //set f1-f12+macro ButtonPressColor to macroFunctionKeyPressColorValue
                f1BPC[1] = macroFKBPCV[1];
                f1BPC[2] = macroFKBPCV[2];
                f2BPC[0] = macroFKBPCV[3];
                f2BPC[1] = macroFKBPCV[4];
                f2BPC[2] = macroFKBPCV[5];
                f3BPC[0] = macroFKBPCV[6];
                f3BPC[1] = macroFKBPCV[7];
                f3BPC[2] = macroFKBPCV[8];
                f4BPC[0] = macroFKBPCV[9];
                f4BPC[1] = macroFKBPCV[10];
                f4BPC[2] = macroFKBPCV[11];
                f5BPC[0] = macroFKBPCV[12];
                f5BPC[1] = macroFKBPCV[13];
                f5BPC[2] = macroFKBPCV[14];
                f6BPC[0] = macroFKBPCV[15];
                f6BPC[1] = macroFKBPCV[16];
                f6BPC[2] = macroFKBPCV[17];
                f7BPC[0] = macroFKBPCV[18];
                f7BPC[1] = macroFKBPCV[19];
                f7BPC[2] = macroFKBPCV[20];
                f8BPC[0] = macroFKBPCV[21];
                f8BPC[1] = macroFKBPCV[22];
                f8BPC[2] = macroFKBPCV[23];
                f9BPC[0] = macroFKBPCV[24];
                f9BPC[1] = macroFKBPCV[25];
                f9BPC[2] = macroFKBPCV[26];
                f10BPC[0] = macroFKBPCV[27];
                f10BPC[1] = macroFKBPCV[28];
                f10BPC[2] = macroFKBPCV[29];
                f11BPC[0] = macroFKBPCV[30];
                f11BPC[1] = macroFKBPCV[31];
                f11BPC[2] = macroFKBPCV[32];
                f12BPC[0] = macroFKBPCV[33];
                f12BPC[1] = macroFKBPCV[34];
                f12BPC[2] = macroFKBPCV[35];
                macroBPC[0] = macroFKBPCV[36];
                macroBPC[1] = macroFKBPCV[37];
                macroBPC[2] = macroFKBPCV[38];
                macroS = 0;
            }    //end else
        }    //end if(macro==1)
        else if (column==14)
        {
            fader_state(macro, macroBC[0], macroBPC[0], &macroGfade[0], &macroGfade[1], &macroG[0], &macroG[1], &macroG[2]);
            sh_cp(0);
            fader_state(macro, macroBC[1], macroBPC[1], &macroBfade[0], &macroBfade[1], &macroB[0], &macroB[1], &macroB[2]);
            sh_cp(0);
            fader_state(macro, macroBC[2], macroBPC[2], &macroRfade[0], &macroRfade[1], &macroR[0], &macroR[1], &macroR[2]);
            sh_cp(0);
            fader_state(numlock, numlockBC[0], numlockBPC[0], &numlockGfade[0], &numlockGfade[1], &numlockG[0], &numlockG[1], &numlockG[2]);
            sh_cp(0);
            fader_state(numlock, numlockBC[1], numlockBPC[1], &numlockBfade[0], &numlockBfade[1], &numlockB[0], &numlockB[1], &numlockB[2]);
            sh_cp(0);
            fader_state(numlock, numlockBC[2], numlockBPC[2], &numlockRfade[0], &numlockRfade[1], &numlockR[0], &numlockR[1], &numlockR[2]);
            sh_cp(0);
            fader_state(num7, num7BC[0], num7BPC[0], &num7Gfade[0], &num7Gfade[1], &num7G[0], &num7G[1], &num7G[2]);
            sh_cp(0);
            fader_state(num7, num7BC[1], num7BPC[1], &num7Bfade[0], &num7Bfade[1], &num7B[0], &num7B[1], &num7B[2]);
            sh_cp(0);
            fader_state(num7, num7BC[2], num7BPC[2], &num7Rfade[0], &num7Rfade[1], &num7R[0], &num7R[1], &num7R[2]);
            sh_cp(0);
            fader_state(num4, num4BC[0], num4BPC[0], &num4Gfade[0], &num4Gfade[1], &num4G[0], &num4G[1], &num4G[2]);
            sh_cp(0);
            fader_state(num4, num4BC[1], num4BPC[1], &num4Bfade[0], &num4Bfade[1], &num4B[0], &num4B[1], &num4B[2]);
            sh_cp(0);
            fader_state(num4, num4BC[2], num4BPC[2], &num4Rfade[0], &num4Rfade[1], &num4R[0], &num4R[1], &num4R[2]);
            sh_cp(0);
            fader_state(num1, num1BC[0], num1BPC[0], &num1Gfade[0], &num1Gfade[1], &num1G[0], &num1G[1], &num1G[2]);
            sh_cp(0);
            fader_state(num1, num1BC[1], num1BPC[1], &num1Bfade[0], &num1Bfade[1], &num1B[0], &num1B[1], &num1B[2]);
            sh_cp(0);
            fader_state(num1, num1BC[2], num1BPC[2], &num1Rfade[0], &num1Rfade[1], &num1R[0], &num1R[1], &num1R[2]);
            sh_cp(1);
            fader_state(num0, num0BC[0], num0BPC[0], &num0Gfade[0], &num0Gfade[1], &num0G[0], &num0G[1], &num0G[2]);
            sh_cp(0);
            fader_state(num0, num0BC[1], num0BPC[1], &num0Bfade[0], &num0Bfade[1], &num0B[0], &num0B[1], &num0B[2]);
            sh_cp(0);
            fader_state(num0, num0BC[2], num0BPC[2], &num0Rfade[0], &num0Rfade[1], &num0R[0], &num0R[1], &num0R[2]);
            sh_cp(0);
            st_cp();
            column++;
        }    //end else if (column==14)
        else if (column==15)
        {
            fader_state(bright, brightBC[0], brightBPC[0], &brightGfade[0], &brightGfade[1], &brightG[0], &brightG[1], &brightG[2]);
            sh_cp(0);
            fader_state(bright, brightBC[1], brightBPC[1], &brightBfade[0], &brightBfade[1], &brightB[0], &brightB[1], &brightB[2]);
            sh_cp(0);
            fader_state(bright, brightBC[2], brightBPC[2], &brightRfade[0], &brightRfade[1], &brightR[0], &brightR[1], &brightR[2]);
            sh_cp(0);
            fader_state(numfslash, numfslashBC[0], numfslashBPC[0], &numfslashGfade[0], &numfslashGfade[1], &numfslashG[0], &numfslashG[1], &numfslashG[2]);
            sh_cp(0);
            fader_state(numfslash, numfslashBC[1], numfslashBPC[1], &numfslashBfade[0], &numfslashBfade[1], &numfslashB[0], &numfslashB[1], &numfslashB[2]);
            sh_cp(0);
            fader_state(numfslash, numfslashBC[2], numfslashBPC[2], &numfslashRfade[0], &numfslashRfade[1], &numfslashR[0], &numfslashR[1], &numfslashR[2]);
            sh_cp(0);
            fader_state(num8, num8BC[0], num8BPC[0], &num8Gfade[0], &num8Gfade[1], &num8G[0], &num8G[1], &num8G[2]);
            sh_cp(0);
            fader_state(num8, num8BC[1], num8BPC[1], &num8Bfade[0], &num8Bfade[1], &num8B[0], &num8B[1], &num8B[2]);
            sh_cp(0);
            fader_state(num8, num8BC[2], num8BPC[2], &num8Rfade[0], &num8Rfade[1], &num8R[0], &num8R[1], &num8R[2]);
            sh_cp(0);
            fader_state(num5, num5BC[0], num5BPC[0], &num5Gfade[0], &num5Gfade[1], &num5G[0], &num5G[1], &num5G[2]);
            sh_cp(0);
            fader_state(num5, num5BC[1], num5BPC[1], &num5Bfade[0], &num5Bfade[1], &num5B[0], &num5B[1], &num5B[2]);
            sh_cp(0);
            fader_state(num5, num5BC[2], num5BPC[2], &num5Rfade[0], &num5Rfade[1], &num5R[0], &num5R[1], &num5R[2]);
            sh_cp(0);
            fader_state(num2, num2BC[0], num2BPC[0], &num2Gfade[0], &num2Gfade[1], &num2G[0], &num2G[1], &num2G[2]);
            sh_cp(0);
            fader_state(num2, num2BC[1], num2BPC[1], &num2Bfade[0], &num2Bfade[1], &num2B[0], &num2B[1], &num2B[2]);
            sh_cp(0);
            fader_state(num2, num2BC[2], num2BPC[2], &num2Rfade[0], &num2Rfade[1], &num2R[0], &num2R[1], &num2R[2]);
            sh_cp(0);
            fader_state(numperiod, numperiodBC[0], numperiodBPC[0], &numperiodGfade[0], &numperiodGfade[1], &numperiodG[0], &numperiodG[1], &numperiodG[2]);
            sh_cp(1);
            fader_state(numperiod, numperiodBC[1], numperiodBPC[1], &numperiodBfade[0], &numperiodBfade[1], &numperiodB[0], &numperiodB[1], &numperiodB[2]);
            sh_cp(0);
            fader_state(numperiod, numperiodBC[2], numperiodBPC[2], &numperiodRfade[0], &numperiodRfade[1], &numperiodR[0], &numperiodR[1], &numperiodR[2]);
            sh_cp(0);
            st_cp();
            column++;
        }    //end else if (column==15)
        else if (column==16)
        {
            fader_state(mute, muteBC[0], muteBPC[0], &muteGfade[0], &muteGfade[1], &muteG[0], &muteG[1], &muteG[2]);
            sh_cp(0);
            fader_state(mute, muteBC[1], muteBPC[1], &muteBfade[0], &muteBfade[1], &muteB[0], &muteB[1], &muteB[2]);
            sh_cp(0);
            fader_state(mute, muteBC[2], muteBPC[2], &muteRfade[0], &muteRfade[1], &muteR[0], &muteR[1], &muteR[2]);
            sh_cp(0);
            fader_state(asterisk, asteriskBC[0], asteriskBPC[0], &asteriskGfade[0], &asteriskGfade[1], &asteriskG[0], &asteriskG[1], &asteriskG[2]);
            sh_cp(0);
            fader_state(asterisk, asteriskBC[1], asteriskBPC[1], &asteriskBfade[0], &asteriskBfade[1], &asteriskB[0], &asteriskB[1], &asteriskB[2]);
            sh_cp(0);
            fader_state(asterisk, asteriskBC[2], asteriskBPC[2], &asteriskRfade[0], &asteriskRfade[1], &asteriskR[0], &asteriskR[1], &asteriskR[2]);
            sh_cp(0);
            fader_state(num9, num9BC[0], num9BPC[0], &num9Gfade[0], &num9Gfade[1], &num9G[0], &num9G[1], &num9G[2]);
            sh_cp(0);
            fader_state(num9, num9BC[1], num9BPC[1], &num9Bfade[0], &num9Bfade[1], &num9B[0], &num9B[1], &num9B[2]);
            sh_cp(0);
            fader_state(num9, num9BC[2], num9BPC[2], &num9Rfade[0], &num9Rfade[1], &num9R[0], &num9R[1], &num9R[2]);
            sh_cp(0);
            fader_state(num6, num6BC[0], num6BPC[0], &num6Gfade[0], &num6Gfade[1], &num6G[0], &num6G[1], &num6G[2]);
            sh_cp(0);
            fader_state(num6, num6BC[1], num6BPC[1], &num6Bfade[0], &num6Bfade[1], &num6B[0], &num6B[1], &num6B[2]);
            sh_cp(0);
            fader_state(num6, num6BC[2], num6BPC[2], &num6Rfade[0], &num6Rfade[1], &num6R[0], &num6R[1], &num6R[2]);
            sh_cp(0);
            fader_state(num3, num3BC[0], num3BPC[0], &num3Gfade[0], &num3Gfade[1], &num3G[0], &num3G[1], &num3G[2]);
            sh_cp(0);
            fader_state(num3, num3BC[1], num3BPC[1], &num3Bfade[0], &num3Bfade[1], &num3B[0], &num3B[1], &num3B[2]);
            sh_cp(0);
            fader_state(num3, num3BC[2], num3BPC[2], &num3Rfade[0], &num3Rfade[1], &num3R[0], &num3R[1], &num3R[2]);
            sh_cp(0);
            fader_state(numenter, numenterBC[0], numenterBPC[0], &numenterGfade[0], &numenterGfade[1], &numenterG[0], &numenterG[1], &numenterG[2]);
            sh_cp(0);
            fader_state(numenter, numenterBC[1], numenterBPC[1], &numenterBfade[0], &numenterBfade[1], &numenterB[0], &numenterB[1], &numenterB[2]);
            sh_cp(1);
            fader_state(numenter, numenterBC[2], numenterBPC[2], &numenterRfade[0], &numenterRfade[1], &numenterR[0], &numenterR[1], &numenterR[2]);
            sh_cp(0);
            st_cp();
            column++;
        }    //end else if (column==16)
        else if (column==17)
        {
            fader_state(prtscrn, prtscrnBC[0], prtscrnBPC[0], &prtscrnGfade[0], &prtscrnGfade[1], &prtscrnG[0], &prtscrnG[1], &prtscrnG[2]);
            sh_cp(0);
            fader_state(prtscrn, prtscrnBC[1], prtscrnBPC[1], &prtscrnBfade[0], &prtscrnBfade[1], &prtscrnB[0], &prtscrnB[1], &prtscrnB[2]);
            sh_cp(0);
            fader_state(prtscrn, prtscrnBC[2], prtscrnBPC[2], &prtscrnRfade[0], &prtscrnRfade[1], &prtscrnR[0], &prtscrnR[1], &prtscrnR[2]);
            sh_cp(0);
            fader_state(scrolllock, scrolllockBC[0], scrolllockBPC[0], &scrolllockGfade[0], &scrolllockGfade[1], &scrolllockG[0], &scrolllockG[1], &scrolllockG[2]);
            sh_cp(0);
            fader_state(scrolllock, scrolllockBC[1], scrolllockBPC[1], &scrolllockBfade[0], &scrolllockBfade[1], &scrolllockB[0], &scrolllockB[1], &scrolllockB[2]);
            sh_cp(0);
            fader_state(scrolllock, scrolllockBC[2], scrolllockBPC[2], &scrolllockRfade[0], &scrolllockRfade[1], &scrolllockR[0], &scrolllockR[1], &scrolllockR[2]);
            sh_cp(0);
            fader_state(pause, pauseBC[0], pauseBPC[0], &pauseGfade[0], &pauseGfade[1], &pauseG[0], &pauseG[1], &pauseG[2]);
            sh_cp(0);
            fader_state(pause, pauseBC[1], pauseBPC[1], &pauseBfade[0], &pauseBfade[1], &pauseB[0], &pauseB[1], &pauseB[2]);
            sh_cp(0);
            fader_state(pause, pauseBC[2], pauseBPC[2], &pauseRfade[0], &pauseRfade[1], &pauseR[0], &pauseR[1], &pauseR[2]);
            sh_cp(0);
            fader_state(numminus, numminusBC[0], numminusBPC[0], &numminusGfade[0], &numminusGfade[1], &numminusG[0], &numminusG[1], &numminusG[2]);
            sh_cp(0);
            fader_state(numminus, numminusBC[1], numminusBPC[1], &numminusBfade[0], &numminusBfade[1], &numminusB[0], &numminusB[1], &numminusB[2]);
            sh_cp(0);
            fader_state(numminus, numminusBC[2], numminusBPC[2], &numminusRfade[0], &numminusRfade[1], &numminusR[0], &numminusR[1], &numminusR[2]);
            sh_cp(0);
            fader_state(plus, plusBC[0], plusBPC[0], &plusGfade[0], &plusGfade[1], &plusG[0], &plusG[1], &plusG[2]);
            sh_cp(0);
            fader_state(plus, plusBC[1], plusBPC[1], &plusBfade[0], &plusBfade[1], &plusB[0], &plusB[1], &plusB[2]);
            sh_cp(0);
            fader_state(plus, plusBC[2], plusBPC[2], &plusRfade[0], &plusRfade[1], &plusR[0], &plusR[1], &plusR[2]);
            sh_cp(0);
            PORTA &= ~(1<<PA0);    //sets rdata to low since there are no more keys to fill up the remainder of the 18 LED slots and the remainder of the 24 total 74HC595 pins low
            sh_cp(0);
            sh_cp(0);
            sh_cp(1);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            sh_cp(0);
            st_cp();
            column = 0;    //restart at the beginning of column loop
        }    //end else if (column==17)
    }    //end while(1)
}    //end main
Could you possibly help me understand how you worked this though?

I'm just grasping classes, and I'm very, very confused by what you did to define all the key variables, and how you called to the fader_state() function I don't understand at all..

It looks like the key variables are all private and therefore won't be able to be accessed by the rest of the code!? To be honest I'm not even sure how all those classes are supposed to work together although I figure the basic principle was to create the pressed, BP, and BPC variables in KeyC and add 3 copies of time, state, dcs, fadeStep, and fadeTime to that.. but how the hell are you even referencing those later in the program??? How would you even call to say the blue time left in the duty cycle on the escape key?? esc.esc[2].time might work for referencing that later in the program??

Code:
// Structure for what looks like intensity and fade values
class CColFade {
  int time;
  int state;
  int dcs;
  int fadeStep;
  int fadeTime;
  
  void CColFade();
};

// initialize to default values
void CColFade::CColFade()
: time(0)
, state (0)
, dcs (0)
, fadeStep (49)
, fadeTime (0)
{
};

// Don't know what these things are, but they sure need a stuct, and maybe a class
class CKey {
  int pressed;
  int BC[3];
  int BPC[3];
  CColFade col[3]; // G, B, R
  
  void CKey();
}

// Extra initialization for default values of these things
void CKey::CKey()
: pressed(0)
, BC({0, 20, 0})
, BPC({0, 0, 20})
{
}

Then I'm really not sure how the variables "Key[row, column], color" get passed to the fader_state() since you seem to have declared "fader_state(CKey& keyData, int col)" but the 3D array should have been passed as a single variable to another 3D array, shouldn't it have? Does it split up to be 3 variables then?

You finally managed to give me a headache. :confused: lol
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
I should mention I think I fixed the issues about waiting for the timer to be correct, and incorrect amounts of variables places..

Code:
void SetLEDStates()
{
	if (timerC>=Ctime && column < 17)
	{
		for (int row = 0; row < 6); row++)
		{
			for (int color = 0, color < 3; color++)
			{
				LEDFaderandState(Key[row, column], color);
				if ((((row+1)*3)-3)+(color+1))==(column+1))
					sh_cp(1);
				else
					sh_cp(0);
			}
		}
	++column;
	st_cp();
	}
	else if (timerC>=Ctime)
	{
		for (int row = 0; row < 6); row++)
		{
			for (int color = 0, color < 3; color++)
			{
				LEDFaderandState(Key[row, column], color);
				if ((((row+1)*3)-3)+(color+1))==(column+1))
					sh_cp(1);
				else
					sh_cp(0);
			}
		}
		column = 0;
		st_cp();
	}
}
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
Could you possibly help me understand how you worked this though?

I went through about three or four refactorings to get that.

I don't have time to explain right now, I'll try to find some time later :)
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
I went through about three or four refactorings to get that.

I don't have time to explain right now, I'll try to find some time later :)

I don't mean how you got that code! I mean how it's supposed to work. Apparently I'm more of a novice than even I thought with programming since these classes and structures I suppose are common knowledge for projects involving loads of variables.. When you have time though, thanks!
 
Last edited:

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
What you defined originally was a heap of separate variables for each key.

What I did was define a single object that was a key. Inside that I defined an array of other objects which were duplicated (R, G, and B values).

So the object as used here is just a collection of variables. Actually it's a lot more than that, and I would probably go on to make some of your functionality into methods of the class, but let's walk before we run :)

If I define a class like this:

Code:
class CDemo {
  int i;
  int j;
}
then I am defining a new type that I can use to define a variable.

Code:
CDemo foo;
declares a new variable called foo of type CDemo.

Now we can do stuff like this:

Code:
  foo.i = 10;
  foo.j = foo.i + 100;
But classes can do a lot more.

One of the simple things is that they can have automatic initialization.

Code:
class CDemo {
  int i;
  int j;

  void CDemo();
}

void CDemo::CDemo()
: i (10)
, j (110)
{
}
This initialises i to 10 and j to 110 when a variable of this type is declared.

You may have done similar things with integers like this:

Code:
int i = 10;
Note that the syntax used here actually initialises the object without running any code (or might do). There is another way that looks more familiar:

Code:
class CDemo {
  int i;
  int j;

  void CDemo();
}

void CDemo::CDemo()
{
  i = 10;
  j = 110;
}
This is slightly less efficient in some cases, but allows you to do things that the previous form does not.

Also note the special name of the function. It is actually a method of the class, and it's definition requires that you tell the compiler where it belongs. So it's

void CDemo::CDemo()

CDemo is the name of the class.
:: is what goes between the class and the method name
CDemo is the method name.

Note that in this case the method name is the same as the class name. This means it is a constructor that is automatically called when an instance of a class (essentially a variable of this type) is created. (Created and declared mean different things, but at the level of this code you can think of them as functionally equivalent).

So I used a constructor to set the initial values of all of your keys.

I also used another class within the key class, and they have their own constructor. Classes can be nested and the initialization works the same way.

Now I have bundled all the key data into a single variable (and later I made that into an array).

So we need to pass the entire class to a function rather than the stack of variables. In my case I passed the key and an ID to tell it whether it should look at the R, G, or B value inside.

Clearly we need to change the contents of the class, so I passed it by reference. I used a way that is effectively the same as passing a pointer, but it doesn't require all those nasty "*"s.

Code:
void function test(CDemo &x)

causes x to have the same address in memory as the parameter passed to it. In effect it passes a pointer to the function and this is automatically dereferenced whenever you refer to x.

So within that function we can refer to x.i and x.j.

Alternatively, we could have defined a function like:

Code:
void function test(CDemo *x)

You've used that method in tyour code. If you had done that, you would need to refer to *x.i and *x.y, or (and this is a special case classes and structs) x->i, and x->y.

Another thing I did inside your code was to create variables to reference elements of an array etc.

So instead of continually refering to x.i, I could declare:

Code:
int &i = x.i;

and then just refer to i.

This is very useful where you need to refer to an element of an array inside a class, inside another array, pointed to by a pointer... Instead of the compiler having to do that long lookup every time, and instead of you having to understand what that string of stuff is (and that it is the same all the time), you declare it and then use it. Your code looks a lot cleaner.

However beware. look at this code:

Code:
  int i[10];
  int j = 3;

  int k = i[j];

  j = 5;

At the conclusion of this, what does k represent? Is it the 4th or the 6th element of the array? It's the 4th. k was fixed to the 4th element when the declaration happened and it won't chance if j later changes.

hopefully some of this verbiage is useful to you.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Sorry, it took a while to piece everything together that you were saying. I think that mostly sorts it out. A lot of the reason I didn't understand stuff properly was because of two typos that were in your code that I was just assuming were correct. I was losing my mind trying to figure out how things were being referenced!

Tell me if I'm wrong, but I think I found other problems too. I think that the classes are going to create all those variables as private, and therefore inaccessible by other functions, correct?

I have no idea where the 10x14 idea came from, so changed some functions to reflect that. I don't think that the 3D array is a good idea since there are two matrix of different size that need to access the key variables. I tried fixing that stuff, but first, based on what you've just told me I want to know if this seems correct:

Code:
int column = 0, EEPROM = 0;
struct KeyColorStruct {	//initializes then calls KeyColorStruct() to set duty cycle and fader variables (each set of variables called 3 times, one per color)
	int dctime;
	int dcLEDstate;
	int dcstate;
	int fadestep;
	int fadetime;
	void KeyColorStruct();
};
void KeyColorStruct::KeyColorStruct()
: dctime (0)
, dcLEDstate (0)
, dcstate (0)
, fadestep (49)
, fadetime (0)
{
}
struct KeyStruct {
	int pressed;
	int BC[3];
	int BPC[3];
	KeyColorStruct color[3]; // G, B, R
	void KeyStruct();
}esc, tilda, tab, caps, lshift, lctrl, f1, one, q, a, z, lspecial, f2, two, w, s, x, lalt, f3, three, e, d, c, v, f4, four, r, f, b, space, five, six, y, t, h, g, f5, seven, u, i, j, n, f6, eight, nine, o, k, m, f7, zero, p, l, comma, ralt, f8, minus, lsqbracket, semicolon, period, rspecial, f9, equals, rsqbracket, apostrophe, fslash, menu, f10, backspace, bslash, enter, rshift, rctrl, f11, f12, up, down, right, left, insert, home, pageup, dlt, end, pagedown, macro, numlock, num7, num4, num1, num0, bright, numfslash, num8, num5, num2, numperiod, mute, asterisk, num9, num6, num3, numenter, prtnscrn, scrolllock, pause, numminus, plus;
void KeyStruct::KeyStruct()
{
	pressed = 0;
	char key = FindKey(EEPROM);
	BC[0] = (key)EEPROM.BC[0];
	BC[1] = (key)EEPROM.BC[1];
	BC[2] = (key)EEPROM.BC[2];
	BPC[0] = (key)EEPROM.BPC[0];
	BPC[1] = (key)EEPROM.BPC[1];
	BPC[2] = (key)EEPROM.BPC[2];
	EEPROM++;
}
char FindKey(char numtokey)
{
	switch (numtokey)
	{
		case 1:
			numtokey = "esc";
			break;
		case 2:
			numtokey = "tilda";
			break;
		case 3:
			numtokey = "tab";
			break;
		case 4:
			numtokey = "caps";
			break;
		case 5:
			numtokey = "lshift";
			break;
		case 6:
			numtokey = "lctrl";
			break;
	}
	return numtokey;
}

In this code will esc.BC[1] wind up initializing as the same value as escEEPROM.BC[1]? If I was to make a new variable equal to a color's fade step in main() could I do it by int "escbluefadestep = esc.color[1].fadestep;"?
 
Last edited:

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Jan 21, 2010
25,510
Joined
Jan 21, 2010
Messages
25,510
Sorry, it took a while to piece everything together that you were saying. I think that mostly sorts it out. A lot of the reason I didn't understand stuff properly was because of two typos that were in your code that I was just assuming were correct. I was losing my mind trying to figure out how things were being referenced!

Only 2! Amazing :)

Tell me if I'm wrong, but I think I found other problems too. I think that the classes are going to create all those variables as private, and therefore inaccessible by other functions, correct?

Yeah, originally I was thinking structs, but the arduino environment doesn't play nice with them always. Yes, a public: would be a good idea (correct data hiding would be even better, but that's another story)

I have no idea where the 10x14 idea came from

Your original code didn't make it easy to find out. It was a guess.

but there *is* an array, your use of row and column variables makes that plain.

I think the last column is only partially implemented, so you may have to deal with that.

I don't think that the 3D array is a good idea

3D array?

Code:
struct KeyStruct {
    int pressed;
    int BC[3];
    int BPC[3];
    KeyColorStruct color[3]; // G, B, R
    void KeyStruct();
}esc, tilda, tab, caps, lshift, lctrl, f1, one, q, a, z, lspecial, f2, two, w, s, x, lalt, f3, three, e, d, c, v, f4, four, r, f, b, space, five, six, y, t, h, g, f5, seven, u, i, j, n, f6, eight, nine, o, k, m, f7, zero, p, l, comma, ralt, f8, minus, lsqbracket, semicolon, period, rspecial, f9, equals, rsqbracket, apostrophe, fslash, menu, f10, backspace, bslash, enter, rshift, rctrl, f11, f12, up, down, right, left, insert, home, pageup, dlt, end, pagedown, macro, numlock, num7, num4, num1, num0, bright, numfslash, num8, num5, num2, numperiod, mute, asterisk, num9, num6, num3, numenter, prtnscrn, scrolllock, pause, numminus, plus;

This is the main thing I'd want to get rid of.

Everything else is just fluff.

Is there a reason to treat keys differently? If there is, it was highly obscured in you original code.

Code:
void KeyStruct::KeyStruct()
{
    pressed = 0;
    char key = FindKey(EEPROM);
    BC[0] = (key)EEPROM.BC[0];
    BC[1] = (key)EEPROM.BC[1];
    BC[2] = (key)EEPROM.BC[2];
    BPC[0] = (key)EEPROM.BPC[0];
    BPC[1] = (key)EEPROM.BPC[1];
    BPC[2] = (key)EEPROM.BPC[2];
    EEPROM++;
}
In this code will esc.BC[1] wind up initializing as the same value as esc.BCEEPROM[1]? If I was to make a new variable equal to a color's fade step in main() could I do it by int "escbluefadestep = esc.color[1].fadestep;"?

The way you have written that constructor is bad because you can never know what order the constructor will be called in. It may be left to right along a list of variables, right to left, or it might decide to call them in a different order and maybe not call some at all!

If you need each key to be initialised by a particular address in the eeprom, then you should initialise them a different way (or at least initialise the parts that come from the eeprom.
 

The Hammer

Sep 17, 2013
164
Joined
Sep 17, 2013
Messages
164
Only 2! Amazing :)



Yeah, originally I was thinking structs, but the arduino environment doesn't play nice with them always. Yes, a public: would be a good idea (correct data hiding would be even better, but that's another story)
Definitely starting to agree with you on a VERY serious level. With all the variable names you and me have put into this thing that are similar I can see how it can get confusing.. lol
Your original code didn't make it easy to find out. It was a guess.

but there *is* an array, your use of row and column variables makes that plain.

I think the last column is only partially implemented, so you may have to deal with that.



3D array?
Yup, huge long lists of things in that original set of code. I don't think I could be dropped into anyone else's code and pick it up 1/3 as good as you.. look at how long it's taking me to catch up with your alterations to what I've written. lol

I tried compiling it for the ATTINY861 I've got, and it was overfilling the memory by about 22,000 bytes. 0.o

Erm, my turn for more typos. I had meant 2D, and by 2D I mean multidimensional arrays and I slept 3 hours last night. XD
This is the main thing I'd want to get rid of.

Everything else is just fluff.

Is there a reason to treat keys differently? If there is, it was highly obscured in you original code.
I'd like to get rid of the naming convention as well, but there's two problems:
1. There's not really a good way to store an 18x18 matrix and a 10x11 matrix in a multidimensional array that works easily with both matrix that I can see. I also don't see another good way to store them aside from making a plain array for the 107 keys.
2. Eventually, I guess I'm going to have to put those keys written out in the code somewhere being that they will need to be sent over USB anyway. I think it may save text space writing them out from the beginning and reusing the conventions I've set up for figuring out what key I'm actually using.

So, it was obscured in the fact that I'm not done writing all the parts that need to happen in the code. So far on the docket I've got:
writing an interrupt routine to save all the current user changeable values to EEPROM on power failure/reading from the EEPROM when the variables initialize,
writing code to change brightness of the entire keyboard to 3/3-2/3-1/3-off,
writing a function that on specific key presses you can change key variables,
and dealing with the HID USB stuff.
There's some other things I was considering doing such as random key colors/key pressed colors/random fading effects, changing the time the fade takes (1 second as of now), and maybe a startup routine similar to this:
!
The way you have written that constructor is bad because you can never know what order the constructor will be called in. It may be left to right along a list of variables, right to left, or it might decide to call them in a different order and maybe not call some at all!

If you need each key to be initialised by a particular address in the eeprom, then you should initialise them a different way (or at least initialise the parts that come from the eeprom.
Wait, huh? Why doesn't a constructor just call it in order the same as a regular function? What if I made it a regular function?
 
Last edited:
Top