422 lines
12 KiB
Plaintext
422 lines
12 KiB
Plaintext
//TLC5940NT pin definitions
|
|
#define VPRG 2
|
|
#define SIN 11
|
|
#define SCLK 13
|
|
#define XLAT 4
|
|
#define BLANK 5
|
|
#define DCPRG 6
|
|
#define GSCLK 7
|
|
#define MISO 12
|
|
#define SS 10
|
|
|
|
|
|
unsigned long currentMillis, previousMillis;
|
|
int ledState;
|
|
|
|
int level[32] = {
|
|
4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,4095, 4095, 4095, 4095,4095, 4095, 4095, 4095,
|
|
4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,4095, 4095, 4095, 4095,4095, 4095, 4095, 4095};
|
|
|
|
|
|
byte rele[6] = {
|
|
14, 15, 16, 17, 18, 19};
|
|
|
|
|
|
const byte remap[32] = {
|
|
1,2,3,4,5,6,7,8,9,10,11,12,23,24,25,26,27,28,17,18,19,20,21,22,0,0,0,0,0,0,0,0};
|
|
|
|
|
|
#define FREQ 12 // How many interrupts occur before the serial commands are read
|
|
#if FREQ > 1
|
|
byte int_counter = 0;
|
|
#endif
|
|
|
|
|
|
char spi_transfer(volatile byte data)
|
|
{
|
|
SPDR = data; // Start the transmission
|
|
while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission
|
|
{
|
|
};
|
|
return SPDR; // return the received byte
|
|
}
|
|
|
|
void makemagic(){
|
|
setGreys();
|
|
feedPorts();
|
|
}
|
|
|
|
void feedPorts() {
|
|
// Clock for TLC5940's PWM
|
|
digitalWrite(BLANK, HIGH);
|
|
digitalWrite(BLANK, LOW); //=all outputs ON, start PWM cycle
|
|
for (int i=0; i<4096; i++) {
|
|
pulseGSCLK();
|
|
}
|
|
}
|
|
|
|
void pulseGSCLK() {
|
|
//ultra fast pulse trick, using digitalWrite caused flickering
|
|
PORTD |= 0x80 ; // bring pin 7 high, but don't touch any of the other pins in PORTB
|
|
//16 nanosecs is the min pulse width for the 5940, but no pause seems needed here
|
|
PORTD &= 0x7F; // bring pin 7 low without touching the other pins in PORTB
|
|
}
|
|
|
|
void setGreys() {
|
|
digitalWrite(BLANK, HIGH);
|
|
digitalWrite(XLAT,LOW);
|
|
for(int i = 15; i>=0; i--){
|
|
spi_transfer( (level[2*i+1] & 0x0FF0) >> 4 );
|
|
spi_transfer( ((level[2*i+1] & 0xF) << 4) | ((level[2*i] & 0x0F00) >> 8) );
|
|
spi_transfer( level[2*i] & 0xFF);
|
|
}
|
|
digitalWrite(XLAT,HIGH);
|
|
digitalWrite(XLAT,LOW);
|
|
digitalWrite(BLANK, LOW);
|
|
}
|
|
|
|
|
|
void startup(){
|
|
for(byte x = 0; x < 31; ++x){
|
|
level[x] = 4095;
|
|
//makemagic();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//The timer interrupt routine, which periodically interprets the serial commands
|
|
ISR(TIMER2_OVF_vect) {
|
|
sei(); //Reenable global interrupts, otherwise serial commands will get dropped
|
|
#if FREQ > 1
|
|
if(++int_counter == FREQ){ // Only do this once every FREQ-th interrupt
|
|
int_counter = 0;
|
|
#endif //FREQ
|
|
|
|
makemagic();
|
|
makemagic();
|
|
makemagic();
|
|
makemagic();
|
|
|
|
#if FREQ > 1
|
|
}
|
|
#endif //FREQ
|
|
//sei();
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
|
pinMode(VPRG, OUTPUT);
|
|
pinMode(SIN, OUTPUT);
|
|
pinMode(SCLK, OUTPUT);
|
|
pinMode(XLAT, OUTPUT);
|
|
pinMode(BLANK, OUTPUT);
|
|
pinMode(DCPRG, OUTPUT);
|
|
pinMode(GSCLK, OUTPUT);
|
|
pinMode(MISO, INPUT);
|
|
pinMode(SS,OUTPUT);
|
|
digitalWrite(SS,HIGH); //disable device
|
|
digitalWrite(SIN, LOW);
|
|
digitalWrite(SCLK, LOW);
|
|
digitalWrite(XLAT, LOW);
|
|
digitalWrite(VPRG, LOW);
|
|
digitalWrite(BLANK, HIGH);
|
|
digitalWrite(GSCLK, HIGH);
|
|
digitalWrite(DCPRG, LOW); // USE EEPROM DC register if LOW
|
|
|
|
Serial.begin(9600);
|
|
/*
|
|
010 (2MHz) with FREQ set to 10 or less seem to work reasonably well
|
|
Trying to use 011 (500kHz), to eliminate the if statement needed for FREQ
|
|
Might even work as slow as 100 (250kHz).
|
|
*/
|
|
TCCR2A = 0;
|
|
TCCR2B = 1<<CS22 | 0<<CS21 | 0<<CS20;
|
|
|
|
//Timer2 Overflow Interrupt Enable
|
|
TIMSK2 = 1<<TOIE2;
|
|
delay(10);
|
|
|
|
//Setup the Hardware SPI registers
|
|
// SPCR = 01010000
|
|
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
|
|
//sample on leading edge of clk,system clock/4 (fastest)
|
|
byte clr;
|
|
SPCR = (1<<SPE)|(1<<MSTR);
|
|
clr=SPSR;
|
|
clr=SPDR;
|
|
delay(10);
|
|
|
|
for(byte i = 0; i < 6; ++i) pinMode(rele[i], OUTPUT);
|
|
for(byte i = 0; i < 6; ++i) digitalWrite(rele[i], LOW);
|
|
startup();
|
|
|
|
}
|
|
|
|
int ch = 9; // canal base del RGB
|
|
|
|
void loop() {
|
|
|
|
//makemagic();
|
|
unsigned long currentMillis = millis();
|
|
|
|
|
|
ledOn(100, 255, 0, 0, 255 );
|
|
ledOn(100, 255, 0, 255, 0 );
|
|
ledOn(100, 255, 0, 0, 255 );
|
|
ledOn(100, 255, 0, 255, 0 );
|
|
|
|
|
|
releOn(1000, 63);
|
|
releOn(0, 0);
|
|
|
|
ledFade(0, 255, 255, 0, 0 );
|
|
ledFade(0, 255, 0, 0, 255 );
|
|
ledFade(0, 255, 0, 255, 0 );
|
|
}
|
|
|
|
|
|
//void rele(int bpm, int step1, int step2, int step3, int step4, int step5, int step6, int step7, int step8, int step9, int step10, int step11, int step12, int step13, int step14, int step15, int step16 )
|
|
void releOn(int tiempo, int estado )
|
|
{
|
|
int ch1 = estado & 0x01; // 0, 1
|
|
int ch2 = (estado>>1) & 0x01; // 2
|
|
int ch3 = (estado>>2) & 0x01; // 4
|
|
int ch4 = (estado>>3) & 0x01; // 8
|
|
int ch5 = (estado>>4) & 0x01; // 16
|
|
int ch6 = (estado>>5) & 0x01; // 32
|
|
digitalWrite(rele[0],ch1);
|
|
digitalWrite(rele[1],ch2);
|
|
digitalWrite(rele[2],ch3);
|
|
digitalWrite(rele[3],ch4);
|
|
digitalWrite(rele[4],ch5);
|
|
digitalWrite(rele[5],ch6);
|
|
|
|
delay(tiempo);
|
|
|
|
}
|
|
|
|
void ledOn(int tiempo, int canal, int rojo, int verde, int azul )
|
|
{
|
|
int ch1 = canal & 0x01; // 0, 1
|
|
int ch2 = (canal>>1) & 0x01; // 2
|
|
int ch3 = (canal>>2) & 0x01; // 4
|
|
int ch4 = (canal>>3) & 0x01; // 8
|
|
int ch5 = (canal>>4) & 0x01; // 16
|
|
int ch6 = (canal>>5) & 0x01; // 32
|
|
int ch7 = (canal>>6) & 0x01; // 64
|
|
int ch8 = (canal>>7) & 0x01; // 128
|
|
|
|
|
|
if(ch1)
|
|
{
|
|
level[remap[0]] = rojo*16;
|
|
level[remap[1]] = verde*16;
|
|
level[remap[2]] = azul*16;
|
|
}
|
|
if(ch2)
|
|
{
|
|
level[remap[3]] = rojo*16;
|
|
level[remap[4]] = verde*16;
|
|
level[remap[5]] = azul*16;
|
|
}
|
|
if(ch3)
|
|
{
|
|
level[remap[6]] = rojo*16;
|
|
level[remap[7]] = verde*16;
|
|
level[remap[8]] = azul*16;
|
|
}
|
|
if(ch4)
|
|
{
|
|
level[remap[9]] = rojo*16;
|
|
level[remap[10]] = verde*16;
|
|
level[remap[11]] = azul*16;
|
|
}
|
|
if(ch5)
|
|
{
|
|
level[remap[12]] = rojo*16;
|
|
level[remap[13]] = verde*16;
|
|
level[remap[14]] = azul*16;
|
|
}
|
|
if(ch6)
|
|
{
|
|
level[remap[15]] = rojo*16;
|
|
level[remap[16]] = verde*16;
|
|
level[remap[17]] = azul*16;
|
|
}
|
|
if(ch7)
|
|
{
|
|
level[remap[18]] = rojo*16;
|
|
level[remap[19]] = verde*16;
|
|
level[remap[20]] = azul*16;
|
|
}
|
|
if(ch8)
|
|
{
|
|
level[remap[21]] = rojo*16;
|
|
level[remap[22]] = verde*16;
|
|
level[remap[23]] = azul*16;
|
|
}
|
|
|
|
|
|
delay(tiempo);
|
|
|
|
}
|
|
|
|
void ledFade(int tiempo, int canal, int rojo, int verde, int azul )
|
|
{
|
|
|
|
byte i;
|
|
byte p_start[32];
|
|
byte p_end[3];
|
|
|
|
int ch1 = canal & 0x01; // 0, 1
|
|
int ch2 = (canal>>1) & 0x01; // 2
|
|
int ch3 = (canal>>2) & 0x01; // 4
|
|
int ch4 = (canal>>3) & 0x01; // 8
|
|
int ch5 = (canal>>4) & 0x01; // 16
|
|
int ch6 = (canal>>5) & 0x01; // 32
|
|
int ch7 = (canal>>6) & 0x01; // 64
|
|
int ch8 = (canal>>7) & 0x01; // 128
|
|
|
|
p_start[0] = level[remap[0]]/16 ;
|
|
p_start[1] = level[remap[1]]/16 ;
|
|
p_start[2] = level[remap[2]]/16 ;
|
|
p_start[3] = level[remap[3]]/16 ;
|
|
p_start[4] = level[remap[4]]/16 ;
|
|
p_start[5] = level[remap[5]]/16 ;
|
|
p_start[6] = level[remap[6]]/16 ;
|
|
p_start[7] = level[remap[7]]/16 ;
|
|
p_start[8] = level[remap[8]]/16 ;
|
|
p_start[9] = level[remap[9]]/16 ;
|
|
p_start[10] = level[remap[10]]/16 ;
|
|
p_start[11] = level[remap[11]]/16 ;
|
|
p_start[12] = level[remap[12]]/16 ;
|
|
p_start[13] = level[remap[13]]/16 ;
|
|
p_start[14] = level[remap[14]]/16 ;
|
|
p_start[15] = level[remap[15]]/16 ;
|
|
p_start[16] = level[remap[16]]/16 ;
|
|
p_start[17] = level[remap[17]]/16 ;
|
|
p_start[18] = level[remap[18]]/16 ;
|
|
p_start[19] = level[remap[19]]/16 ;
|
|
p_start[20] = level[remap[20]]/16 ;
|
|
p_start[21] = level[remap[21]]/16 ;
|
|
p_start[22] = level[remap[22]]/16 ;
|
|
p_start[23] = level[remap[23]]/16 ;
|
|
p_start[24] = level[remap[24]]/16 ;
|
|
p_start[25] = level[remap[25]]/16 ;
|
|
p_start[26] = level[remap[26]]/16 ;
|
|
p_start[27] = level[remap[27]]/16 ;
|
|
p_start[28] = level[remap[28]]/16 ;
|
|
|
|
p_end[0] = rojo;
|
|
p_end[1] = verde;
|
|
p_end[2] = azul;
|
|
|
|
i = 0;
|
|
while (i < 255) {
|
|
if(ch1)
|
|
{
|
|
level[remap[0]] = (( (p_end[0] - p_start[0]) / 254) * i + p_start[0])*16;
|
|
level[remap[1]] = (( (p_end[1] - p_start[1]) / 254) * i + p_start[1])*16;
|
|
level[remap[2]] = (( (p_end[2] - p_start[2]) / 254) * i + p_start[2])*16;
|
|
}
|
|
if(ch2)
|
|
{
|
|
level[remap[3]] = (( (p_end[0] - p_start[3]) / 254) * i + p_start[3])*16;
|
|
level[remap[4]] = (( (p_end[1] - p_start[4]) / 254) * i + p_start[4])*16;
|
|
level[remap[5]] = (( (p_end[2] - p_start[5]) / 254) * i + p_start[5])*16;
|
|
}
|
|
if(ch3)
|
|
{
|
|
level[remap[6]] = (( (p_end[0] - p_start[6]) / 254) * i + p_start[6])*16;
|
|
level[remap[7]] = (( (p_end[1] - p_start[7]) / 254) * i + p_start[7])*16;
|
|
level[remap[8]] = (( (p_end[2] - p_start[8]) / 254) * i + p_start[8])*16;
|
|
}
|
|
if(ch4)
|
|
{
|
|
level[remap[9]] = (( (p_end[0] - p_start[9]) / 254) * i + p_start[9])*16;
|
|
level[remap[10]] = (( (p_end[1] - p_start[10]) / 254) * i + p_start[10])*16;
|
|
level[remap[11]] = (( (p_end[2] - p_start[11]) / 254) * i + p_start[11])*16;
|
|
}
|
|
if(ch5)
|
|
{
|
|
level[remap[12]] = (( (p_end[0] - p_start[12]) / 254) * i + p_start[12])*16;
|
|
level[remap[13]] = (( (p_end[1] - p_start[13]) / 254) * i + p_start[13])*16;
|
|
level[remap[14]] = (( (p_end[2] - p_start[14]) / 254) * i + p_start[14])*16;
|
|
}
|
|
if(ch6)
|
|
{
|
|
level[remap[15]] = (( (p_end[0] - p_start[15]) / 254) * i + p_start[15])*16;
|
|
level[remap[16]] = (( (p_end[1] - p_start[16]) / 254) * i + p_start[16])*16;
|
|
level[remap[17]] = (( (p_end[2] - p_start[17]) / 254) * i + p_start[17])*16;
|
|
}
|
|
if(ch7)
|
|
{
|
|
level[remap[18]] = (( (p_end[0] - p_start[18]) / 254) * i + p_start[18])*16;
|
|
level[remap[19]] = (( (p_end[1] - p_start[19]) / 254) * i + p_start[19])*16;
|
|
level[remap[20]] = (( (p_end[2] - p_start[20]) / 254) * i + p_start[20])*16;
|
|
}
|
|
if(ch8)
|
|
{
|
|
level[remap[21]] = (( (p_end[0] - p_start[21]) / 254) * i + p_start[21])*16;
|
|
level[remap[22]] = (( (p_end[1] - p_start[22]) / 254) * i + p_start[22])*16;
|
|
level[remap[23]] = (( (p_end[2] - p_start[23]) / 254) * i + p_start[23])*16;
|
|
}
|
|
|
|
i++;
|
|
if(tiempo)
|
|
delayMicroseconds(tiempo);
|
|
}
|
|
|
|
/*
|
|
while (i < 256) {
|
|
|
|
level[remap[canal*3]] = ( (p_end[0] - p_start[0]) / 254) * i *16 + p_start[0];
|
|
level[remap[canal*3+1]] = ( (p_end[1] - p_start[1]) / 254 * i )*16 + p_start[1] ;
|
|
level[remap[canal*3+2]] = ( (p_end[2] - p_start[2]) / 254 * i )*16 + p_start[2] ;
|
|
i++;
|
|
//Serial.println(level[remap[canal*3]]);
|
|
//Serial.println(level[remap[canal*3+1]]);
|
|
// Serial.println(level[remap[canal*3+2]]);
|
|
// Serial.println();
|
|
}
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
void fadeTo(byte r, byte g, byte b) {
|
|
byte i;
|
|
byte p_start[3];
|
|
byte p_end[3];
|
|
|
|
p_start[0] = curr_rgb[0];
|
|
p_start[1] = curr_rgb[1];
|
|
p_start[2] = curr_rgb[2];
|
|
|
|
p_end[0] = r;
|
|
p_end[1] = g;
|
|
p_end[2] = b;
|
|
|
|
i = 0;
|
|
|
|
while (i < 255) {
|
|
|
|
curr_rgb[0] = (p_end[0] - p_start[0]) / 254 * i + p_start[0];
|
|
curr_rgb[1] = (p_end[1] - p_start[1]) / 254 * i + p_start[1];
|
|
curr_rgb[2] = (p_end[2] - p_start[2]) / 254 * i + p_start[2];
|
|
|
|
setDmxChannel(1, curr_rgb[0]);
|
|
setDmxChannel(2, curr_rgb[1]);
|
|
setDmxChannel(3, curr_rgb[2]);
|
|
processDmx();
|
|
i++;
|
|
}
|
|
|
|
}
|
|
*/
|
|
|
|
|