Lab_interaccio/2011/Picasso/Picasso.pde
2025-02-25 21:29:42 +01:00

297 lines
7.2 KiB
Plaintext

#include <NewSoftSerial.h>
NewSoftSerial mySerial(3, 8);
//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
#define BAUD 9600
#define BAUD_SOFT 9600
// For interrupt timing; needed only to do intermediate clock speeds
/* Divide interrupt frequency by a factor of FREQ. It is preferable to keep
FREQ as small as possible, and control the frequency of the interrupts
using the hardware clock. Setting it to 1 disables this entirely, which,
if it works, is ideal; this should be the same as commenting out the
"#define FREQ" statement entirely.
*/
#define FREQ 1 // How many interrupts occur before the serial commands are read
#if FREQ > 1
byte int_counter = 0;
#endif
const int sensor[6] = {14,15,16,17,18,19};
long level[16] = {
4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,4095, 4095, 4095, 4095,4095, 4095, 4095, 4095};
char RFID_temp[30] = { 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};
char RFID[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int remap[16] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
byte ready = true;
byte command = 0;
byte lastread;
byte estado = 0;
byte estado_ant = 0;
byte count=0;
//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
if(Serial.available()){
if(ready){ // If the last command has finished executing, read in the next command and reset the command flag
command = Serial.read();
ready = false;
}
switch (command >> 4) { //Execute the appropriate command, but only if we have received enough bytes to complete it. We might one day add "partial completion" for long command strings.
case 1: // set colour
if( Serial.available()) {
level[command&0x0F] = Serial.read()*16;
ready=true;
}
break;
case 2: // led_on
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
case 3: // led_off
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
case 4: // led_row1
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
case 5: // led_col1
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
case 8: //frame
if( Serial.available() > 7 ) {
lastread = Serial.read();
lastread = Serial.read();
lastread = Serial.read();
lastread = Serial.read();
lastread = Serial.read();
lastread = Serial.read();
lastread = Serial.read();
lastread = Serial.read();
ready = true;
}
break;
case 9: //clear
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
case 12:
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
case 13:
if( Serial.available() ) {
lastread = Serial.read();
ready = true;
}
break;
default:
break;
}
}
#if FREQ > 1
}
#endif //FREQ
}
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 < 16; ++x){
level[x] = 0;
makemagic();
}
}
void setup()
{
for (int i=0; i <= 5; i++){
pinMode(sensor[i], INPUT);
}
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
/* Setup the timer interrupt
Settings for TCCR2B: (remember, interrupts occur every 255 cycles)
000 = Clock stopped
001 = No prescaling (16MHz)
010 = 1/8 (2MHz)
011 = 1/32 (500kHz)
100 = 1/64 (250kHz)
101 = 1/128 (125kHz)
110 = 1/256 (62.5khZ)
111 = 1/1024 (15.625kHz)
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 = 0<<CS22 | 1<<CS21 | 1<<CS20;
//Timer2 Overflow Interrupt Enable
TIMSK2 = 1<<TOIE2;
//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);
Serial.begin(BAUD);
Serial.println("Picasso");
// set the data rate for the NewSoftSerial port
mySerial.begin(BAUD_SOFT);
startup();
}
void loop()
{
makemagic();
/* REHACER!!!!
if (mySerial.available()) {
RFID_temp[count]=mySerial.read();
if (count == 16)
{
count=0;
if (RFID_temp[0]=0x02)
{
for (int i=0; i <= 11; i++) RFID[i]=RFID_temp[i+1];
Serial.print(RFID);
}
}
count++;
}
*/
for (int i=0; i <= 5; i++){
if (digitalRead(sensor[i]))
{
estado=(0x01<<i)|estado;
}
else
{
estado=(~(0x01<<i))&estado;
}
}
if (estado!=estado_ant)
{
//Serial.print(RFID);
//Serial.print(estado);
}
estado_ant=estado;
}