Lab_interaccio/2011/Bisbe/led_rele_fades/led_rele_fades.pde

384 lines
11 KiB
Plaintext
Raw Permalink Normal View History

2025-02-25 21:29:42 +01:00
//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() {
//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, 0, 255, 255, 0, 0 );
ledFade(0, 0, 255, 0, 255, 0 );
ledFade(0, 0, 255, 0, 0, 255 );
//ledFade(0, 10, 15, 0, 255, 0 );
// ledFade(50, 0, 3, 0, 0, 255 );
//ledFade(0, 10, 1, 255, 0, 0 );
for(int i=0; i<2; i++)
{
ledOn(10, 255, 0, 0, 255 );
ledOn(10, 255, 0, 255, 0 );
ledOn(10, 255, 0, 0, 255 );
ledOn(10, 255, 255, 0, 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 inc, byte canal, byte rojo, byte verde, byte azul ) // tiempo de delay, incremento, canal, r, g , b
{
int i;
byte p_start[32];
byte p_end[3];
byte ch1 = canal & 0x01; // 0, 1
byte ch2 = (canal>>1) & 0x01; // 2
byte ch3 = (canal>>2) & 0x01; // 4
byte ch4 = (canal>>3) & 0x01; // 8
byte ch5 = (canal>>4) & 0x01; // 16
byte ch6 = (canal>>5) & 0x01; // 32
byte ch7 = (canal>>6) & 0x01; // 64
byte 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;
}
if(inc)
i+=inc;
else
i++;
if(i > 255)
i = 255;
if(tiempo)
delayMicroseconds(tiempo);
}
}