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

289 lines
6.3 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 57600
#define BAUD_SOFT 9600
byte int_counter = 0;
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[13] = "";
const int remap[16] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
boolean count = true;
byte command = 0;
byte lastread;
byte estado = 0;
byte estado_ant = 0;
long previousMillis = 0; // will store last time LED was updated
long interval = 1000;
boolean flag_link = 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
//makemagic();
//makemagic();
//makemagic();
if(Serial.available() >= 2){
if(!count){ // If the last command has finished executing, read in the next command and reset the command flag
command = Serial.read();
count = 1;
}
// if( Serial.available())
if( (command > 200) && (command <= 216) && count )
{
level[command-200] = Serial.read()*16;
count = 0;
}
else
count = 0;
}
#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);
// set the data rate for the NewSoftSerial port
mySerial.begin(BAUD_SOFT);
startup();
}
void loop()
{
makemagic();
unsigned long currentMillis = millis();
if(Serial.available() >= 2){
if(!count){ // If the last command has finished executing, read in the next command and reset the command flag
command = Serial.read();
count = 1;
}
// if( Serial.available())
if( (command > 200) && (command <= 216) && count )
{
level[command-200] = Serial.read()*16;
count = 0;
}
else
count = 0;
}
for (int i=0 ; i<5 ; i++){ // limite a tres botones + 1 final de carrera (valor max estado = 31)
if (digitalRead(sensor[i]))
estado = (0x01<<i) | estado;
else
estado = (~(0x01<<i)) & estado;
}
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
Serial.print(estado);
}
if (estado != estado_ant)
{
Serial.print(estado);
estado_ant = estado;
}
}
byte rfid_read()
{
byte i = 0;
byte val = 0;
byte code[6];
byte checksum = 0;
byte bytesread = 0;
byte tempbyte = 0;
byte check = 0;
if(mySerial.available() > 0) {
if((val = mySerial.read()) == 2) { // check for header
bytesread = 0;
while (bytesread < 12) { // read 10 digit code + 2 digit checksum
if( mySerial.available() > 0) {
val = mySerial.read();
if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) { // if header or stop bytes before the 10 digit reading
break; // stop reading
}
RFID[bytesread] = val;
//makemagic();
bytesread++; // ready to read next digit
}
}
// Output to Serial:
if (bytesread == 12) { // if 12 digit read is complete
check = 1;
bytesread = 0;
}
}
}
return(check);
}