[Solucionado]Estoy bloqueadisimo con la construcción de esta función

Hola a todos,
ojalá alguien me pueda ayudar a resolver esta duda, porqué me esta impidiendo terminar definitivamente el proyecto.
El proyecto trata de lo siguiente:

  • hay 8 controladores, iguales entre ellos, es decir los botones operan igual, pero excluyen al resto de los controladores
  • cada controlador de los 8 tiene 4 botones con cuatro funciones diferentes
  • El boton 1 de cada controlador es para pedir turno, el que lo aprieta antes toma el control del arduino
  • El boton 4 sirve para ejecutar las ordenes indicadas con los otros dos restantes, una vez ejecutadas las ordenes se libera el control otra vez para que todos los controladores puedan intentar acceder a este con su boton 1.
  • Las ordenes se ejecutan en el momento, no se guarda el orden de ejecuciones en memoria
  • Asi que el bucle principal esta esperando todo el rato a que alguien apriete su boton 1

HARDWARE:
El sketch principal , que creo que no es lo importante, escanea el 64 buttons shield de spiekenzelabs:
[list/SpikenzieLabs/Button64Shield.html[/url]

Los 8 botones de la fila 1 de la matriz de 64 son los boton 1 de cada controlador, segun quien aprieta se pasa el numero a la variable de entrada de un SWITCH con 8 casos, evidentemente cada caso es igual solo cambia quien controla.

Hasta aquí bien.

Cada controlador lleva asociado un display dual de dos digitos de 7 segmentos.
Los 8 displays estan incrustados de la siguiente forma:
Los segmentos de los 8 displays estan interconectados en paralelo.
Los anodos comunes (2 por display) estan multiplexados con transistores PNP (los segmentos de los dos digitos estan conectados entre si).
Aqui es donde viene la liada:
Como un arduino uno carece de bastante salidas, le he enchufado un MUX SHIELD II:

Para evitar usar todos los pines, como dice en su guia del usuario, le he hecho un hardwire para que actue solo como shift register,
es decir, todos los pines son salidas digitales, ya que solo lo necesito para poder manejar los displays.

  • La fila I/O 1 no tiene nada conectado, la quiero liberar por liberar el pin que la maneja(pin2) que lo necesito para otra leer los 64 buttons por interrupcion (Lo cual es claramente el primer conflicto)
  • La fila I/O 2 tiene conectados las bases de los 16 transistores necesarios para activar los displays, asi para el display 1, usaria el 1 pin 1 y el pin 2, para el display 2 el pin 3 y el 4 y asi sucesivamente
  • La fila I/O 3 es la que maneja los segmentos de todos los displays, por eso, solo uso los pines del uno al siete, ya que los DP de cada display no son necesarios porqué no hay decimales

En ningun caso va a haber más de un display en marcha simultaneamente, por eso puedo lanzar siempre los valores a los segmentos de todos los displays, pero solo funcionara el que esté activo mediante los pines del MUX SHIELD II I/O2.
Para escribir los numeros de los displays, uso una libreria que se llama sevseg.h la cual la podeis encontrar aquí:
http://playground.arduino.cc/Main/SevenSegmentLibrary
concretamente en el link:
https://docs.google.com/file/d/0Bwrp4uluZCpNdE9oWTY0M3BncTA/edit?usp=sharing

Y aquí viene el maldito problema, cada vez que un usuario tiene el control, está en un case del switch, en el cual se ejecuta una funcion en bucle hasta que el boton 4 de ejecutar es usado y se libera (haciendo un break para salir del switch).
Aquí esta mi función a medias:

int trackSelection (int fwdSong, int revSong, int plAY, int numSong, muxrow, muxD1, muxD0){ 	//vars butskip+, butskip-,butplay, number of song)//mux mapped for sev segm

	numSong=0;																					  //return var
	short trackRef=0;
        SevSeg sevseg;
	sevseg.Begin(1,2,3,[b]muxD[/b]1,[b]muxD2[/b],6,7,8,9,10,11,12,13);									//free pins 2,3 and 					
	sevseg.Brightness(90);
	while(Button!=plAY){                                        								// while play button is not pressed selection is allowed.
		if(Button > 128){                                         								// Example of how to decode the button press
			Button = Button - 128;                                								// A pressd button is the button number + 128  
          
			if((Button== plAY)&&(0<trackRef<100)){												// condition1:Play button pressed + condition2:song must be from 1 to 100) both conditions are obligated.
					
				numSong=trackRef;                           									// if button pressed was this, play selected song
                                delay(10);;
                                break;  									    								// of course get out the loop
				
				}
			   
			else if(Button== fwdSong){  
                    
                                trackRef++;
                                Serial.print(trackRef);
				delay(50);
				sevseg.PrintOutput();	
                                }
              
			else if(Button== revSong){                           	// if button pressed was that, skip- (select song number)
					
				trackRef--;
                                Serial.print(trackRef);
				delay(50);
                                sevseg.PrintOutput();
                
				}  
              
			else{
			        sevseg.PrintOutput();
				delay(10);
				
                                }
                        sevseg.PrintOutput();
				  
			}
		
		else{
        
			Button=(Button, DEC);                					// A released button is from 1 to 64
			
			if((Button== plAY)&&(0<trackRef<100)){					// condition1:Play button pressed + condition2:song must be from 1 to 100) both conditions are obligated.
                
				numSong=trackRef;                           		// if button pressed was this, play selected song
                                delay(10);;
                                break;  									    	// of course get out the loop
				
				}
			   
			else if(Button== fwdSong){  
                    
                                trackRef++;
                                Serial.print(trackRef);
				delay(50);
				sevseg.PrintOutput();	

                                }
              
			else if(Button== revSong){                           // if button pressed was that, skip- (select song number)
					
				trackRef--;
                                Serial.print(trackRef);
				delay(50);
                                sevseg.PrintOutput();
                                
				}  
              
			else{
			        sevseg.PrintOutput();
				delay(10);
				
                              }
				  
			}
    sevseg.PrintOutput();
    }
	trackRef=0;



return numSong;
}

A mi parecer, una vez dentro de esta función gobernada por un bucle while, es cuando deberia crear la instancia del SevSeg, y entonces pasarle los pines en los que tiene que actuar, sabiendo que, todos ellos son del MUX SHIELD. Lo que me bloquea, es que he mirado la libreria del MUX shield, y esta bien explicado como leer y escribir en los pines. Pero lo que me bloquea es que no se como pasar los pines del MUX Shield a la funcion Sev:

//I am using a common anode display, with the digit pins connected
  //from 2-5 and the segment pins connected from 6-13
  sevseg.Begin(1,2,3,4,5,6,7,8,9,10,11,12,13);

El problema reside basicamente en que me estoy liando con la recursividad....

Alguien me puede decir como puedo insertarle los parametros de los pines del MUX shield a sevseg.Begin(); para que los interprete bien y sepa donde va a tener que escribir luego los LOW y HIGH de cada segmento y del digito adecuado?

Solo necesito romper esta barrera psicologica para terminar de incrustar las operaciones y poder hacer los primeros tests.....
....estoy desesperado......

Hola.
Primeramente comentarte que me ha costado bastante entender tu problema. Quizás deberías ser más conciso, porque con la historia de los botones me he vuelto medio loco, y finalmente si no he entendido mal el problema es que no consigues pintar dígitos en los displays conectados al mux. Si estoy en lo correcto, podías haber empezado por ahí y yo no estaría mareado :fearful:. Por cierto, en lo de los botones, si sólo el seleccionado toma control, podías utilizar un solo juego de botones para todos los controladores pero, en fin, no me voy a liar yo también :zipper_mouth_face:
La librería para los displays no te va a funcionar tal como viene, porque está preparada para funcionar con pines directos de arduino. Así que tu punto de partida debe ser la librería del mux, y debes construir tu propia rutina o librería para pintar los dígitos en tus pantallas.
Para minimizar tiempos yo tal vez optaría por escribir los dos dígitos de cada display de una vez. Es decir, en la fila IO3 usaría el doble de pines y en IO2 la mitad (cada uno seleccionaría una pareja de displays). Después, creo que se puede modificar la librería del mux para que trabaje más eficientemente (no la he mirado muy a fondo, pero me ha parecido ver alguna rutina "lenta").

Hola noter,
ante todo, gracias por tomarte tiempo en leer y además en contestar.

noter:
Hola.
Primeramente comentarte que me ha costado bastante entender tu problema. Quizás deberías ser más conciso, porque con la historia de los botones me he vuelto medio loco...

Lo siento, el panico se apoderó de mi, llevo dias programando esto contrareloj para un amigo, es mi primer sketch en arduino, y aunque tengo nociones de programación (me dieron clases de #C hace un par de años en FP), pues veo que me estoy pegando un atracón considerable y empiezo a flaquear y a no saber ver con perspectiva la cosa.

noter:
Por cierto, en lo de los botones, si sólo el seleccionado toma control, podías utilizar un solo juego de botones para todos los controladores pero, en fin, no me voy a liar yo también :zipper_mouth_face:

Te explico, entre todos controlan un mp3Trigger a modo de jukebox, pero mi amigo quiere que los controles esten en la mesa para que la gente desde ahi pueda seleccionar una cancion, mientras nadie seleccione, hay un hilo musical.
Los controladores estan separados fisicamente por metros, he tenido que poner cable apantallado para evitar ruidos y falsos positivos.

La librería para los displays no te va a funcionar tal como viene, porque está preparada para funcionar con pines directos de arduino. Así que tu punto de partida debe ser la librería del mux, y debes construir tu propia rutina o librería para pintar los dígitos en tus pantallas.

Me lo empezaba a suponer, que no habia forma asi como lo intentaba, estaba pensando finalmente en punteros, pero hace tanto que no programo que me liaria aun más.....construir rutinas con funciones puedo, creo, pero ¿hacerme una libreria?
Ya me gustaría a mi saber hacerlas, he leido los tutoriales, y vaya tela...se nota que necesito mas ayuda de los expertos de lo que creia...

La verdad no se si empezar a escribir a lo burro a base de digitalWriteMS();
Necesito buscar la forma rapida de extraer el numero en 2 digitos de siete segmentos e implementar una funcion para mostrar por pantalla eficiente....voy a seguir dandole a la cocorota....

Cualquier cosa que añadas, te la agradezco por adelantado, necesito un faro.

Hola,

Por lo que entendí tienes ocho grupos de 1 controlador+1 display+4 pulsadores
1 pide turno, 4 play y supongo que 2 y 3 anterior y siguiente cancion?
en el display ira saliendo el numero de cancion o indicar ocupado
y el primero que pide turno invalida los otros 7
y mientras esta tocando no admite mas solicitudes
Es correcto?

Hola Marcial,
gracias por interesarte,

....Es correcto?

En un 90%, la verdad es que cada controlador de esos 8 tiene su propio display, y solo se debe poner en marcha si el controlador es el que manda en ese momento, yo lo pienso como si lo que se muestra por pantalla fuese conmutando entre displays segun este el control en un sitio u otro, por lo demás, es correcto.

Editado: me deje un corchete(]) al final del quote y se había quedado un poco de cartón. Ahora se diferencia la cita del resto.

Bueno, de momento se me ha ocurrido que puedo intentar comunicar una placa Mega con el Arduino, dejando la tarea de control de botones y elección de usuario al Arduino UNO y pasandole la carga de los displays a la Mega, además de encargarse de la comunicación serial con el Trigger
Serial RX Tx (UNO<-->MEGA)
Serial1 RxTX(UNO<-->Trigger)

Luego, haciendo un array de instancias de la libreria SevSeg.h, así:

SevSeg sevseg[8]={SevSeg(),SevSeg(),SevSeg(),SevSeg(),SevSeg(),SevSeg(),SevSeg(),SevSeg()};
byte dig0[]={22,24,26,28,30,32,34,36};
byte dig1[]={23,25,27,29,31,33,35,37};
byte sev[] = {43,44,45,46,47,48,49,42};

Si dejo el Mega haciendo sevseg[valor]=PrintOut(); en el loop principal, y hago que los cambios vengan en forma de interrupción, igual es posible....no se.....
El mensaje serial no se puede tratar como una interrupción, no? Eso sería co__nudo....

Una idea:
Divide el problema en partes:
Usa 9 controladores interconectados por serial (si la distancia lo permite)

Escribre un codigo para cada uno de los 8 controladores (todos iguales) de la siguiente manera

lee comunicacion serial
Si en serial hay "ocupado" Ocupado =true
Si en serial hay "Libre" Ocupado =false
si ocupado pintar display asteriscos
si no ocupado
leer pulsadores
gestion display
Si pulsamos play enviar por serial numero de cancion

Y para el noveno:

lee comunicacion serial
si recibimos numero cancion
enviar codigo "ocupado"
tocando =true
si tocando y cancion acaba
envía código "libre"
tocando=false

Edito: Puesto así hasta parece facil :grin:

Hola de nuevo.
Prueba a ver si te pudiera funcionar esta función para pintar un número de dos cifras en el display que selecciones mediante digitalWriteMS en la fila 2. Ten en cuenta que el conexionado es diferente al que proponías tú. Lo tengo hecho de forma que aprovecho la fila 3 completa para poder pintar los dos dígitos a la vez. De forma que con la fila 2 seleccionaríamos un display completo, en lugar de un solo dígito.
Debes cambiar el valor de los #define por los números de pin correspondientes al conexionado del muxer. Esta función debería tratar la fila 3 de una forma mucho más eficiente que si escribiéramos en ella mediante digitalWriteMS segmento por segmento, pues envía los 16 bit de los dos dígitos en una sola pasada (la librería sólo envía un bit por pasada). No obstante, como esto lo hacemos "a espaldas" de la librería, no deberíamos escribir en la fila 3 con digitalWriteMS, pues parte de un valor incorrecto.
Prueba a ver si te hace algo. Recuerda que aparte de llamarla con un número 0-99 como parámetro, deberás también activar el display por el que quieres que salga el número.

// Modifica los valores de estos define:
#define _S2 0
#define _S3 0
#define _OUTMD 0
#define _IO3 0
// Definición de los segmentos de cada dígito 0-9. No sé si serán del todo correctos.
const byte segmento[]={
      B01111110,
      B00110000,
      B01101101,
      B01111001,
      B00110011,
      B01011011,
      B01011111,
      B01110000,
      B01111111,
      B01111011,
      B01001111
};

// FUNCIÓN QUE ESTABLECE EN LA FILA 3 DEL MUX SHIELD LOS SEGMENTOS ADECUADOS PARA UN NÚMERO DE DOS CIFRAS. POSTERIORMENTE A LLAMAR A ESTA FUNCIÓN ESTABLECEREMOS MEDIANTE
// digitalWriteMS EL DISPLAY HACIA EL QUE SE PINTARÁ EL NÚMERO ACTUAL.

void pintaNumero(byte num)
{
      byte salidaSegmentos=0;
      if (num>99) num=99; // si sobrepasamos las dos cifras lo dejamos en 99
      digitalWrite(_S3,LOW);                              //S3 here is LCLK
      digitalWrite(_OUTMD,HIGH);                          //set to output mode
      digitalWrite(_S2,LOW);                  //S2 here is i/o3 _sclk
      salidaSegmentos=segmento[num/10]; // Calculamos el dígito alto
      shiftOut(_IO3, _S2, MSBFIRST, salidaSegmentos);
      salidaSegmentos=segmento[num%10]; // Calculamos el dígito bajo
      shiftOut(_IO3, _S2, MSBFIRST, salidaSegmentos);
      digitalWrite(_S3,HIGH);                     //latch in ALL values
      digitalWrite(_OUTMD,LOW);                   //Exit output mode
}

Gracias a todos por contestar :slight_smile: Me mola mucho que intenteis echar un cable.
OLE VOSOTROS:

Me puse manos a la obra antes de leer lo que deciais, y entonces se me ocurrio usar un arduino Mega de esclavo para I2C,
con el consigo el proposito que quiero:
Os cuelgo el codigo del Arduino UNO MASTER, al cual van cogidos un 64Buttons Shield, un MP3Trigger (de robertsonics) por Serial(RX/TX a 38400) y el Arduino Mega por SCL/SDA.
El Arduino Mega se encarga solo de gestionar los displays con los numeros que le pasa el UNO y con la libreria sevseg.
Codigo UNO/MASTER:

#include <wire.h>
volatile uint8_t Button = 0;// Required for 64 Button Shield (SPI Only)
//byte eXit=18;
byte hilo = 0;
//char incomingChar;
byte incomingByte;
   

void setup(){
	Wire.begin();
        delay(2000);
	Serial.begin(38400);                                // Comunication with MP3TRIGGER or MP3Shield
	delay(2000);
        Wire.begin();
        delay(2000);
	randomSeed(analogRead(A0));		            //Start seeding, random will be different each sequence.
	delay(100);
	hilo=random(1,10);
       Serial.write('p');
       Serial.write(hilo);
      			    //Generating random song to play.
        sendSong(hilo);                                 //we send other byte
        attachInterrupt(0, SPI64B, FALLING);                // Required for 64 Button Shield (SPI Only) is not real SPI communication
	}

void loop(){
byte mesa=0;
byte songPlay=0;
byte track=0;	
while(Button==0){
    if (Serial.available()) {        // lee el byte de entrada:
      byte incomingByte=Serial.read();
      if (incomingByte=='X'){
        sendSong(hilo);
	delay(5);
       }
       else{
         delay(5);
       }
     }
     else{
       delay(5);
     }
   }//////////////////////////////////////////////////////////
  do{
    if(Button > 128){                             // If Button is > 0, then it was pressed or released (SPI only)
    Button = Button - 128;                // A pressd button is the button number + 128
      if (Button<9){
        mesa=Button;
        }
      }
      else{
        Button=(Button, DEC);                	// A released button is from 1 to 64 
        if (0< Button && Button<9){
          mesa=Button;
        }
      }
    }while(mesa==0);					//Scann button until button registered is between 1-8
    sendNumero(mesa, 0);      //  sendMesa(mesa);
	
	//Serial.println(mesa);							// Check if button pressed is button read by the controller.
								//
  Button = 0;										// Security zero avoid problems 
										// Initiate var track to 0 before go through switch menu.
		
 switch(mesa){                  
   
	case 1: //______CASE #1--> Table nº1 gets CONTROL  eXCLUSIVE  BUTTON IDS=[9,17,25]				  |
			
			songPlay=trackSelection(0,9,17,25,track);

																			  
		break;

	case 2: //____________CASE #2--> Table nº2 gets CONTROL____eXCLUSIVE  BUTTON IDS=[10,18,26]__________																	|=			
			songPlay= trackSelection(1,10,18,26,track);
			
		break; 

	case 3: //________CASE #3--> Table nº3 gets CONTROL_______eXCLUSIVE  BUTTON IDS=[11,19,27]_____________
																				songPlay= trackSelection(2,11,19,27,track);
			
		break;																		
	case 4: //__________CASE #4--> Table nº4 gets CONTROL____eXCLUSIVE  BUTTON IDS=[12,20,28]_________		
			songPlay= trackSelection(3,12,20,28,track);
			
	    break;		   

	case 5: //________________CASE #5--> Table nº5 gets CONTROL_____eXCLUSIVE  BUTTON IDS=[13,21,29]		      |
					
		
			songPlay= trackSelection(4,13,21,29,track);
		
		break;	case 6: //__________CASE #6--> Table nº7 gets CONTROL______eXCLUSIVE  BUTTON IDS=[14,22,30]			  |
				
			songPlay= trackSelection(5,14,22,30,track);
			
		break; 

    case 7: //_____________CASE #7--> Table nº7 gets CONTROLS__________eXCLUSIVE  BUTTON IDS=[15,23,31]			  
																				songPlay= trackSelection(6,15,23,31,track);

			
        break;
    case 8: //_______________________CASE #8--> Table nº8 gets CONTROL_______eXCLUSIVE  BUTTON IDS=[16,24,32]			  |
												
			songPlay= trackSelection(7,16,24,32,track);

        break;

	default: //________________CASE RARE—> if arduino gets lost….  
  
  do{ 
    if (Serial.available()) {        // lee el byte de entrada:
      incomingByte=Serial.read();
      if (incomingByte=='X'){
        sendSong(hilo);
	delay(20);
       }
       else{
         delay(20);
       }
     }
     else{
       delay(20);
     }
  }while(incomingByte!='X');
			
        break;
 }

detachInterrupt(0);

  do{
    if (Serial.available() > 0) {
      incomingByte = Serial.read();
      }
    else{
      delay(50);
      }
  }while(incomingByte!='X');
  sendSong(songPlay);
  sendNumero(50,50);
  delay(60000);
  
  do{
    if (Serial.available() > 0) {
      incomingByte = Serial.read();
    }
    else{
      delay(50);
    }
  }while(incomingByte!='X');

attachInterrupt(0, SPI64B, FALLING);		
	
}

Y no se que estoy haciendo mal porque no se oye la canción random inicial para el hilo musical, algo debo de estar haciendo mal.
Grrrrrrrrrr.....

Y aqui va la parte de funciones del UNO/MAster:

/*================================================================================================================================================
=================================================                                            ==========================================================
=================================================       FUNCTIONS                            ==========================================================
=======================================================================================================================================================*/
	


int trackSelection (int super, int fwdSong, int revSong, int plAY, int numSong){ 							// 4 VARIABLES

	numSong=0;																					//return var
	short trackRef=0;																			//counter for mathemathics initialized to 0.
	
	while(Button!=plAY){                                        								// while play button is not pressed selection is allowed.
		if(Button > 128){                                         								// Example of how to decode the button press
		  Button = Button - 128;                                								// A pressd button is the button number + 128
          
		  if((Button== plAY)&& (0<trackRef && trackRef<18)){												// condition1:Play button pressed + condition2:song must be from 1 to 100) both conditions are obligated.
		    numSong=trackRef;                           									// if button pressed was this, play selected song
                    delay(10);
                    break;  									    								// of course get out the loo
                    }
			   
		  else if(Button== fwdSong){  
                     trackRef++;
                     if (trackRef>17){
                       trackRef=1;
                       }
                     //Serial.print(trackRef);
                     sendNumero(super,trackRef);
                          delay(20);		
                    }
                    
                  else if(Button== revSong){                           	// if button pressed was that, skip- (select song number)
		    trackRef--;
                    if (trackRef<1){
                       trackRef=17;
                     }
                    //Serial.print(trackRef);
                    sendNumero(super,trackRef);
                   
		    delay(20);
                    }
  
               
	          else{
                    //Serial.print(trackRef);
                    if (trackRef<1){
                       trackRef=17;
                        }
                    else if(trackRef>17){
                        trackRef=1;
                        }
                    sendNumero(super,trackRef);
                  
		    delay(15);
		    }
				  
	        }
		
		else{//////////////////////////////////////////////////////////////////////////////////////////////////////////
  
                  Button=(Button, DEC);                					// A released button is from 1 to 64
		  if((Button== plAY) && (0<trackRef && trackRef<18)){					// condition1:Play button pressed + condition2:song must be from 1 to 100) both conditions are obligated.
                    numSong=trackRef;                            		// if button pressed was this, play selected song
                    delay(10);
                    break;  									    	// of course get out the loop
		    }//***********

	          else if(Button== fwdSong){  //***********
                    trackRef++;
                    if(trackRef>17){
                      trackRef=1;
                      }
                    sendNumero(super,trackRef);
                    
                    //Serial.print(trackRef);
		    delay(20);
		    }                  //***********v

                  else if(Button== revSong){//***********                           // if button pressed was that, skip- (select song number)
		    trackRef--;
                    if (trackRef<1){
                       trackRef=17;
                      }
                    sendNumero(super,trackRef);
                    
                    //Serial.print(trackRef);
		    delay(20);
                    }        //***********    
                  else{    //***********
                    if (trackRef<1){
                     trackRef=17;
                      }   //---------------
                    else if(trackRef>17){
                      trackRef=1;
                      }   //---------------
                    sendNumero(super,trackRef);
                    
                    Serial.print(trackRef);
		    delay(15);	
                  }//***********
		}//////////////////////////////////////////////////////////////////////////////////////////////////////////
  
        }
trackRef=0;
return numSong;
}

/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\
///////////////////////						////////////////////////////////////
/######################		Communication Functions	##################################/
//\\\\\\\\\\\\\\\\\\\\\\				        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
/##################################################################################################_*/

void sendSong(byte cancion){
                                                      //Master Send DATA
  Serial.write('p');                                    // we send 1byte
  Serial.write(cancion);
} 


void sendNumero(byte x, byte y){
  Wire.beginTransmission(2);                           //Master Send DATA
  Wire.write(x);
  Wire.write(y);  // we send 1byte
  //Wire.write(false);
  Wire.endTransmission();
} 


//*******************************************************************************************************************
// Required for 64 Button Shield (SPI Only)			                           Functions & Subroutines
//*******************************************************************************************************************
//
// This void is called if the Interrupt 0 is triggered (digital pin 2).
//

void SPI64B()
{
  Button = 0;
  
  volatile uint8_t  val  = 0;
  volatile uint8_t  clk  = 0;
  
  #define  DataInPin   3
  #define  ClkPin      4

  clk = digitalRead(ClkPin);
  while(clk == LOW)
  {
    clk = digitalRead(ClkPin);
  }

  for(volatile int i =0; i<8;i++)
  {   
    val = digitalRead(DataInPin);
    clk = digitalRead(ClkPin); 
    
    while(clk == HIGH)
    {
      clk = digitalRead(ClkPin);
    }

    if(val == HIGH)
    {
      Button = Button +1;
    }
    
    if(i != 7)
    {
      Button = Button << 1;
    }
    else
    {
      break;
    }

    clk = digitalRead(ClkPin);
    
    while(clk == LOW)
    {
      clk = digitalRead(ClkPin);
    }

  }
}    // End  of SPI64B void
// -------------------------------------------------------------------------------------------------------------

ya he visto el fallo,
y creo que lo he corregido,
ahora el problema esta en la función trackSelection, el problema está en que cuando le doy a un pulsador, al hacer el release, el valor no vuelve a 0, entonces se queda guardado en button.
Como hay que elegir entre 17 canciones, hay unos limitadores tal que si es mayor a 17 o menor a 0 pasan respectivamente a 1 y 17 para que no sigan computando infinitamente.
El problema es que al no volver a 0, muchas veces por segundo sigue apretado el boton de incremento o decremento, haciendo muchos ciclos de bucle.
Por lo demás parece que funciona todo.

Bueno, hay otro problema, una vez enchufado todo, si no le doy al boton del reset en el arduino UNO, no funciona, Eso no lo entiendo.