The Hammer
- Sep 17, 2013
- 164
- Joined
- Sep 17, 2013
- Messages
- 164
Hello there!
I've been working on some code for a 107 key mechanical keyboard with macro key functionality where each key has it's own RGB LED. This means two matrices. One is for the key presses (10 columns input, 11 rows output), and another is for the LEDs. I have been using 3 74HC595 and 3 ULN2803 combined with 3 74HC595 with a separate data line to control the matrix even though it is an 18 column by 18 row matrix (future expandability).
Anyways, I've been writing code for it and while this isn't done yet I would appreciate some input. I know it's rather complex/long, but I've written the basics here so you guys could get the gist here and tell me about if I'm doing anything wrong with these loops I've made?
Maybe there's a way to shorten this code as I have yet to make copies of the massively long if statements in the LED loop?
What are some good ways to call an output on a timer, and where are some good tutorials on Atmel chips and timers?
Before you yell at me, yes, I am aware that I've tried using pins that can't possibly work since the ATTINY861 I'm using doesn't have enough pins for the job. lol Thanks in advance!
I've been working on some code for a 107 key mechanical keyboard with macro key functionality where each key has it's own RGB LED. This means two matrices. One is for the key presses (10 columns input, 11 rows output), and another is for the LEDs. I have been using 3 74HC595 and 3 ULN2803 combined with 3 74HC595 with a separate data line to control the matrix even though it is an 18 column by 18 row matrix (future expandability).
Anyways, I've been writing code for it and while this isn't done yet I would appreciate some input. I know it's rather complex/long, but I've written the basics here so you guys could get the gist here and tell me about if I'm doing anything wrong with these loops I've made?
Maybe there's a way to shorten this code as I have yet to make copies of the massively long if statements in the LED loop?
What are some good ways to call an output on a timer, and where are some good tutorials on Atmel chips and timers?
Before you yell at me, yes, I am aware that I've tried using pins that can't possibly work since the ATTINY861 I'm using doesn't have enough pins for the job. lol Thanks in advance!
Code:
/*
* ATTINY861_20PU_LED_MATRIX.c
*
* Created: 1/25/2014 4:24:47 PM
* Author: The Hammer
*/
#include <avr/io.h>
#include <util/delay.h>
// 74HC595 pins and variables
#define rdata PA0
#define cdata PA1
#define sh_cp PA2
#define st_cp PA3
int row = 0, column = 0, time = 0, state = 0, runout = 0;
int esc = 0, escBC[2], escBPC[2], escGPWM[1], escG[2], escBPWM[1], escB[2], escRPWM[1], escR[2];
int tilda = 0, tildaBC[2], escBPC[2], tildaG[2], tildaB[2], tildaR[2];
int tab = 0, tabBC[2], tabBPC[2], tabG[2], tabB[2], tabR[2];
int caps = 0, capsBC[2], capsBPC[2], capsG[2], capsB[2], capsR[2];
int lshift = 0, lshiftBC[2], lshiftBPC[2], lshiftG[2], lshiftB[2], lshiftR[2];
int lctrl = 0, lctrlBC[2], lctrlBPC[2], lctrlG[2], lctrlB[2], lctrlR[2];
int f1 = 0, f1BC[2], f1BPC[2], f1G[2], f1B[2], f1R[2];
int one = 0, oneBC[2], oneBPC[2], oneG[2], 1B[2], oneR[2];
int q = 0, qBC[2], qBPC[2], qG[2], qB[2], qR[2];
int a = 0, aBC[2], aBPC[2], aG[2], aB[2], aR[2];
// write digital "high" to pin <pn> on port <prt>
//#define DIGIWRITE_H(prt, pn) prt |= (1<<pn)
// write digital "low" to pin <pn> on port <prt>
//#define DIGIWRITE_L(prt, pn) prt &= ~(1<<pn)
int ledstate(int& time, int& state, int& runout)
{
if (state==1)
{
PORTA |= (1<<rdata);
--time;
if (time==0||time==19)
{
runout++;
}
}
else
{
PORTA &= ~(1<<rdata);
--time;
if (time==0||time==19)
{
runout++;
}
}
return(time, state, runout);
}
int main(void)
{
DDRA = (1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3);
PORTA = (0<<PA0)|(0<<PA1)|(0<<PA2)|(0<<PA3);
while(row==0)
{
PORTA |= (1<<0);
esc = PINA0;
if (esc==1)
{
skusb(esc);
}
tilda = PINA1;
if (tilda==1)
{
skusb(tilda);
}
tab = PINA2;
if (tab==1)
{
skusb(tab);
}
caps = PINA3;
if (caps==1)
{
skusb(caps);
}
lshift = PINA4;
if (lshift==1)
{
skusb(lshift);
}
lctrl = PINA5;
if (lctrl==1)
{
skusb(lctrl);
}
f1 = PINA6;
if (f1==1)
{
skusb(f1);
}
one = PINA7;
if (one==1)
{
skusb(one);
}
q = PINA8;
if (q==1)
{
skusb(q);
}
a = PINA9;
if (a==1)
{
skusb(a);
}
PORTA &= ~(1<<0);
row++;
}
while(column==0)
{
if (esc==1)
{
if (escBPC[0] > 0) //if escape is pressed reset fader and set escG to escButtonPressedColor[0]
{
escG[0] = escBPC[0];
escG[1] = 1;
escG[2] = 0;
escGPWM[1] = 1;
}
else
{
escG[0] = 20;
escG[1] = 0;
escG[2] = 0;
escGPWM[1] = 1;
}
}
else
{
if (escG[2]==2) //if esc not pressed and LED has completed duty cycle
{
if (escGPWM[1] < 49) //if fader timer has not run out
{
if (escBPC[0] < escBC[0]) //if escButtonPressColor is smaller than escButtonColor
{
escGPWM[0] = escBC[0] - escBPC[0];
escGPWM[0] /= 49;
escGPWM[0] *= escGPWM[1];
escG[0] = (escBC[0] - escGPWM[0]);
++escGPWM[1];
}
else if (escBPC[0] > escBC[0]) //if escBPC is bigger than escBC perform fade for escG
{
escGPWM[0] = escBPC[0] - escBC[0];
escGPWM[0] /= 49;
escGPWM[0] *= escGPWM[1];
escG[0] = escGPWM[0];
++escGPWM[1];
}
else
{
escG[0] = escBC[0];
escG[1] = 1;
}
}
else
{
escG[0] = escBC[0];
escG[1] = 1;
}
escG[2] = 0;
}
else if (escG[2]==1 && escG[0]==0) //if esc not pressed and LED is done with first stage of duty cycle
{
if (escGPWM[1] > 0)
{
escG[0] = 20 - escGPWM[0];
}
else
{
escG[0] = 20 - escBC[0];
}
escG[1] = 0;
}
else if (escG[2]==0 && escG[0]==0) //if esc not pressed and LED is ready to begin duty cycle
{
escG[0] = escBC[0];
escG[1] = 1;
}
}
ledstate (escG[0], escG[1], escG[2]);
PORTA |= (1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (escB[0], escB[1], escB[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (escR[0], escR[1], escR[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (tildaG[0], tildaG[1], tildaG[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (tildaB[0], tildaB[1], tildaB[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (tildaR[0], tildaR[1], tildaR[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (tabG[0], tabG[1], tabG[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (tabB[0], tabB[1], tabB[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (tabR[0], tabR[1], tabR[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (capsG[0], capsG[1], capsG[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (capsB[0], capsB[1], capsB[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (capsR[0], capsR[1], capsR[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (lshiftG[0], lshiftG[1], lshiftG[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (lshiftB[0], lshiftB[1], lshiftB[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (lshiftR[0], lshiftR[1], lshiftR[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (lctrlG[0], lctrlG[1], lctrlG[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (lctrlB[0], lctrlB[1], lctrlB[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
ledstate (lctrlR[0], lctrlR[1], lctrlR[2]);
PORTA &= ~(1<<cdata);
PORTA |= (1<<sh_cp);
PORTA &= ~(1<<sh_cp);
PORTA |= (1<<st_cp);
PORTA &= ~(1<<st_cp);
column++;
}