Porque no funciona este codigo

Volviendo a lo mismo he reducido mi codigo a un ejemplo simplificado, mas o menos , el caso esque lee de 0 a 9 y de a a e y dependiendo q insertes por la consola suena un sonido u otro, el caso esque una a una no hay problema pero ya cuando pongo todas las canciones en un switch o con ifs ya empiezan los problemas, si quito las canciones largas como la de knighrider o macgyver(era la 8) la cosa mejora pero hasta la cancion 10 si añades de la 10 a la 16 ya simplemente no va, y esque no lo entiendo. Si alguien prueba el codigo borrando todas menos las 7 primeras va perfecto.
Yo no se si son los char q no aguantan tantos caracteres o que, he probado con punteros y sin ellos pero la cosa no va a mejor, me estoy volviendo loco y yo quiero q funcionen todas, estoy por regalar 5€ jaja al q me lo solucione, y si esta cerca le invito a un par e cañas.

#define OCTAVE_OFFSET 0
#define TONE_PIN 6

#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951

int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};


void setup() {

  Serial.begin(9600);

  
}

void loop() 
{

if (Serial.available() > 0) {
		// read the incoming byte:
		char u = Serial.read();
Serial.println(u);
if(u=='1'){
      char *song="Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6";
      play_rtttl(song);
      }
    if(u=='2'){
      char *jk="Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f";
      play_rtttl(jk);
      }
    if(u=='3'){
      char *song3="20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b";
      play_rtttl(song3);
      }
    if(u=='4'){
      char *song4="Blue:d=8,o=5,b=140:a,a#,d,g,a#,c6,f,a,4a#,g,a#,d6,d#6,g,d6,c6,a#,d,g,a#,c6,f,a,4a#,g,a#,d6,d#6,g,d6,c6,a#,d,g,a#,c6,f,a,4a#,g,a#,d6,d#6,g,d6,c6,a#,d,g,a#,a,c,f,2g";
      play_rtttl(song4);
      }
    if(u=='5'){
      char *song5="Canon:d=16,o=6,b=125:8a#.,g.,g#.,8a#.,g.,g#.,a#.,a#.5,c.,d.,d#.,f.,g.,g#.,8g.,d#.,f.,8g.,g.5,g#.5,a#.5,c.,a#.5,g#.5,a#.5,g.5,g#.5,a#.5,8g#.5,c.,a#.5,8g#.5,g.5,f.5,g.5,f.5,d#.5,f.5,g.5,g#.5,a#.5,c.,8g#.5,c.,a#.5,8c.,d.,d#.,a#.5,c.,d.,d#.,f.,g.,g#.,8a#";
      play_rtttl(song5);
      }
    if(u=='6'){
      char *song6="TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5";
      play_rtttl(song6);
      }
    if(u=='7'){
      char *song7="The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6";
      play_rtttl(song7);
      }
    if(u=='8'){
      }
    if(u=='9'){
      char *song9 = "KnightRider:d=4,o=5,b=125:16e,16p,16f,16e,16e,16p,16e,16e,16f,16e,16e,16e,16d#,16e,16e,16e,16e,16p,16f,16e,16e,16p,16f,16e,16f,16e,16e,16e,16d#,16e,16e,16e,16d,16p,16e,16d,16d,16p,16e,16d,16e,16d,16d,16d,16c,16d,16d,16d,16d,16p,16e,16d,16d,16p,16e,16d,16e,16d,16d,16d,16c,16d,16d,16d";
    play_rtttl(song9);
      }
    if(u=='a'){
      char *son10="Fido:d=16,o=6,b=800:f,4p,f,4p,f,4p,f,4p,c,4p,c,4p,c,4p,c,1p,1p,1p,1p";
      play_rtttl(son10);
      }
    if(u=='b'){
      char *son11="Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#";
      play_rtttl(son11);
      }
    if(u=='c'){
      char *son12="Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#";
      play_rtttl(son12);
      }
    if(u=='d'){
      char *son13="LeisureSuit:d=16,o=6,b=56:f.5,f#.5,g.5,g#5,32a#5,f5,g#.5,a#.5,32f5,g#5,32a#5,g#5,8c#.,a#5,32c#,a5,a#.5,c#.,32a5,a#5,32c#,d#,8e,c#.,f.,f.,f.,f.,f,32e,d#,8d,a#.5,e,32f,e,32f,c#,d#.,c#";
      play_rtttl(son13);
      }
}
}
#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here

  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)

  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }

  Serial.print("ddur: "); Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

  Serial.print("doct: "); Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

  Serial.print("bpm: "); Serial.println(bpm, 10);

  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

  Serial.print("wn: "); Serial.println(wholenote, 10);


  // now begin note loop
  while(*p)
  {
    // first, get note duration, if available
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    
    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

    // now get the note
    note = 0;

    switch(*p)
    {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }
  
    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note

     if(note)
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone(TONE_PIN, notes[(scale - 4) * 12 + note]);
      delay(duration);
      noTone(TONE_PIN);
    }
    else
    {
      Serial.print("Pausing: ");
      Serial.println(duration, 10);
      delay(duration);
    }
    
  }
}

Hola,
en la primera declaración de song creas un puntero a una cadena de 693+1 caracteres (bytes). Para copiar otro valor en esa cadena puedes usar

strcpy(song, "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6");

teniendo cuidado de que lo que copias no sea mayor que la primera cadena.
Si sabes cuál es la longitud de la cadena más larga, puedes definir una variable global como
char song[700]; // suponiendo que esta sea la longitud máxima y luego copias lo que te interese en ella con strcpy()

MacGyver:d=4,o=6,b=150:8b4,8e5,8a5,8b5,a5,8e5,8b4,8p,8e5,8a5,8b5,8a5,8e5,b4,8p,8e5,8a5,8b5,a5,8e5,8b4,8p,8a5,8d,8c,8d,8c,8b5,8a5,8b4,8e5,8a5,8b5,a5,8e5,8b4,8p,8e5,8a5,8b5,8a5,8e5,b4,8p,8e5,8a5,8b5,a5,8e5,8b4,8p,8a5,8d,8c,8d,8c,8b5,8a5,b5,8p,2b5,8p,b5,8p,a5,d.,b5,8p,2b5,8p,8b5,8p,2a5,p,8c,8c,8c,8c,8c,8c,2b5,16p,8f#5,8a5,8p,2g5,8p,8c,8c,8p,b5,8a5,8b5,8a5,8g5,8p,e,2a5,16p,8c,8c,8p,2b5,8p,8f#5,8a5,8p,2g5,8p,8c,8c,8p,4b5,8a5,8b5,8a5,8g5,8p,4e,2a5,2b5,32p,8c,8b5,8a5,c,8b5,8a5,8d,8c,8b5,d,8c,8b5,e,8d,8e,f#,b5,g,8p,f#,f,b5,8g,8e,8b5,8f#,8d,8a5,8e,8c,8g5,8d,8b5,8g5,8c,8e5,8b5,8d5,8c,8b5,8a5,8g5,a#5,a5,8g,8g5,8d,8g5,8d#,8d#5,8a#5,8a5,8g5,8g4,8d5,8g4,8d#5,8g4,8a#4,8a4,8g4,8g4,8g4,8g4,8g4,8g4,8g4";

Perdona por ser tan torpon, como haces para hacer la melodía con arduino.

Saludos.

Cuando pueda pruebo a ver si me sale como dices, flico ahora esque tengo el codigo todo mezclado, a ver si te encentro la pagina de donde saque que estaba muy bien, la verdad q me costo encontrar un codigo al q se le pueden añadir mas de una cancion, yo la verdad las canciones no las hago, la musica no es mi campo y con todas las notas q hay como para componer.
Nos vemos.

xDD le doy a enviar y lo encuentro, el codigo de este foro, va de maravilla.

No consigo hacer lo basico con un switch o con if para selecionar la cancion que quiero y no entiendo el problema si son la capacidad de los char o que , el caso esque una a una funcion y en conjunto no, en la consolas empiezan a aparecer cosas q no deberian como si se desbordase y no se por donde, y porque solas funcionan.

Hola,
creo que el parseo de la cadena que contiene la melodía está bien.
Yo en tu lugar probaría primero con una sola melodía, cortita, sin seleccionar nada con if() o switch()

con una solo melodia va perfecto el problema es al darle la capacidad de selecionar q se desborda o algo y no entiendo la razon, gracias.

Hola,
cada vez que se ejecuta loop() estás creando una cadena (memoria ocupada) que luego no se libera. Crea una variable global a

char song[333]; // o la longitud que haga falta para la cadena más larga

Y luego utiliza esa variable para copiar las melodías

if(u=='1'){
strcpy(song, "Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6";
      play_rtttl(song);
      }
    if(u=='2'){
     strcpy(song, "Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f";
      play_rtttl(jk);
      }
etc.

También podrías definir un puntero global char *psong, y usar malloc() cada vez que vayas a copiar una cadena; y liberar luego con free()

De todas formas, no sé para qué usas esa variable, podrías hacer directamente

play_rtttl("Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6");

Hola curro92, con la primera opcion q me has dado me pasa lo mismo y poniendo play_rtttl( la cancion ); tambien tengo el mismo problema, no entiendo nada xDD.
Queda probar lo del malloc y free pero no encuentro mucha informacion al respecto.

poniendo esto antes del loop que es lo q ponen en todos sitios me da un error q no entiendo "expected constructor, destructor, or type conversion before '=' token
"

char *song;
song = (char )malloc(3sizeof(char)); // se sopne que reservas el espacio de 3 char para song q yo creo q no deberia haber problemas.

Lo he intentado asi:

int stringLength = strlen("The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6");
p = (char*)malloc(stringLength * sizeof(char));
strcpy( song,"The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6");
play_rtttl(song);
free(p);

Pero sigo teniendo problemas, estoy empezando a darlo por imposible.

Hola,
no sé si esto tendrá importancia en tu caso, pero cuando se hace malloc() para una cadena char, hay que poner un carácter de más, para el '\0' final de cadena:

int stringLength = strlen("The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6");
p = (char*)malloc(stringLength * sizeof(char) + 1);

Curro92 si paso la cancion asi: play_rtttl("Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6");

no me debería saturar la memoria no? el caso es que si lo hace, el problema no sera el char *p de la funcion o algo??
Un saludo.

yo ya hice algo parecido, lo que hice fue crear un array con 35 o 37 tonos diferentes, y por medio del teclado le ingreso el numero de la cancion que quiero reproducir y un enter, si hay alguna sonando en ese momento, la detiene y corre la seleccionada, si alguna llega al final la reproduccion se detiene, hasta que ingresa algun numero valido:

#include <Tone.h>
#include <stdlib.h>
Tone tone1;
#define OCTAVE_OFFSET 0
int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};

char *song[] = {"The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6",
"Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6",
"Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f",
"20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b",
"Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6",
"StarWars:d=4,o=5,b=45:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6",
"A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#",
"Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6",
"Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#",
"MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d",
"BadTouch:d=8,o=5,b=125:4f,f,d#,4f,f,f,f,16f,16f,f,f,f,f,f,f,4d#,d#,d,4d#,d#,d#,c#,16c#,16c#,c#,c#,c#,c#,c#,16c#",
"Mario:d=16,o=6,b=100:32p,e,e,p,e,p,c,e,p,g,8p.,g5,8p.,c,8p,g5,8p,e5,8p,a5,p,b5,p,a#5,a5,p,g5,e,g,a,p,f,g,p,e,p,c,d,b5,4p,g,f#,f,d#,p,e,p,g#5,a5,c,p,a5,c,d,8p,8d#,p,d,8p,8c",
"MrRoboto:d=32,o=6,b=50:p,b.5,8a5,d.,8c#,a.5,8g5,p,d.,d.,d.,16e,p,d.,d.,d.,d.,e.",
"HareHare:d=8,o=5,b=164:g,a,g,a,4a,a,4a,a,4g,f,g,2a,a,4a,a,4a,a,4a#,a,a#,4c.6,c,c6,4a#,a,4f.,c6,c6,4a#,a,4f.,c6,c6,4a#,g#,4g,4f,2g"};
char *p;
bool reproducir=false,nuevo=false;
byte default_dur = 4;
byte default_oct = 6;
int bpm = 63;
int num;
long wholenote;
long duration;
byte note;
byte scale;

#include <PS2Keyboard.h>

const int DataPin = 8;
const int IRQpin =  2;
String comando;
PS2Keyboard keyboard;


void setup(void)
{
  Serial.begin(9600);
  tone1.begin(9);
  
  pinMode(13, OUTPUT);
  keyboard.begin(DataPin, IRQpin);
}

#define isdigit(n) (n >= '0' && n <= '9')
void inicializar_tono()
{
  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }
  Serial.print("ddur: "); Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

  Serial.print("doct: "); Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

  Serial.print("bpm: "); Serial.println(bpm, 10);
  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

  Serial.print("wn: "); Serial.println(wholenote, 10);
}

void sonar(){
num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    
    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

    // now get the note
    note = 0;

    switch(*p)
    {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }
  
    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note

    if(note)
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
    {
      Serial.print("Pausing: ");
      Serial.println(duration, 10);
      delay(duration);
    }
}
void play_rtttl()
{
  // Absolutely no error checking in here

  

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)
  if (nuevo){
    inicializar_tono();
    nuevo=false;
  }
  
  // now begin note loop
  if(*p)
  {
    // first, get note duration, if available
    sonar();
    
  }else{reproducir=false;}
}

void loop(void)
{
  digitalWrite(13, HIGH);
  if (reproducir){play_rtttl();}
  if (keyboard.available()) {
    
    // read the next key
    char c = keyboard.read();
    
    // check for some of the special keys
    if (c == PS2_ENTER) {
      Serial.println(comando);
      char this_char[comando.length() + 1];
      comando.toCharArray(this_char, sizeof(this_char));
      p=song[atoi(this_char)];
      nuevo=true;
      reproducir=true;
      comando="";
    } else if (c == PS2_TAB) {
      Serial.print("[Tab]");
    } else if (c == PS2_ESC) {
      Serial.print("[ESC]");
    } else if (c == PS2_PAGEDOWN) {
      Serial.print("[PgDn]");
    } else if (c == PS2_PAGEUP) {
      Serial.print("[PgUp]");
    } else if (c == PS2_LEFTARROW) {
      Serial.print("[Left]");
    } else if (c == PS2_RIGHTARROW) {
      Serial.print("[Right]");
    } else if (c == PS2_UPARROW) {
      Serial.print("[Up]");
    } else if (c == PS2_DOWNARROW) {
      Serial.print("[Down]");
    } else if (c == PS2_DELETE) {
      Serial.print("[Del]");
    } else {
      
      // otherwise, just print all normal characters
      Serial.print(c);
      comando.concat(c);
    }
  }
  digitalWrite(13, LOW);
  //delay(500);
}

aclaro que el codigo es una combinacion entre el ejemplo que hay en el sitio de la libreria tone, y el ejemplo de la ultima version de la libreria keyboard
saludos

Greenlanternx, gracias por contestar estoy intentando amoldar tu codigo al mio y he puesto q lea por la consola lo que metas por teclado, de momento no consigo que funcione y esque no me queda muy claro lo hace el string comando, de todas formas el arduino te permite meter 37 tonos en el array?? yo q con 7 ya tengo problemas serios y esque seria justo lo que quiero.

void loop(void)
{
  digitalWrite(7, HIGH);
  if (reproducir){play_rtttl();}
  if (Serial.available() > 0) {
    
    // read the next key
    char c =  Serial.read();
    
    // check for some of the special keys
    if (c == 'd') {
      Serial.println(comando);
      char this_char[comando.length() + 1];
      comando.toCharArray(this_char, sizeof(this_char));
      p=song[atoi(this_char)];
      nuevo=true;
      //reproducir=true;
      comando="";
    } else if (c == '1') {
      Serial.print("1");
    } else if (c == '2') {
      Serial.print("2");
    } else if (c == '3') {
      Serial.print("3");
    } else if (c == '4') {
      Serial.print("4");
    } else if (c == '5') {
      Serial.print("5");
    } else if (c =='6') {
      Serial.print("6");
    } else if (c == '7') {
      Serial.print("7");
    } else if (c == '8') {
      Serial.print("8");
    } else if (c == '9') {
      Serial.print("9");
    } else {
      
      // otherwise, just print all normal characters
      Serial.print(c);
      comando.concat(c);
    }
  }
  digitalWrite(7, LOW);
  //delay(500);
}

He puesto mi version con un array y si me hincho a poner canciones en el array song se me llena la ram y ya la cosa no pinta bien, yo lo estoy probando en el atmega328p.

comando lo que hace es almacenar cada uno de los caracteres que entran por el teclado, y al detectarse un enter, se convierte en integer y se utiliza como indice para el array( que si te fijas bien cuando hago la lectura de la cancion uso otra variable a la que le cargo el contenido correspondiente del array) tras eso limpio comando, el asunto es como ingresas tus comandos, por que lo que veo es que estas leyendo todas las entradas del serial como un char, y creo que te seria mas practico leerlas como un string (por teclado para la cancion 17 yo debia ingresar 1 7 [ENTER] , en cambio por serial deberias ingresar 17 {supongo estaras usando el serial monitor del IDE})ademas veo que tu codigo no va a ingresar nunca los numeros ni la 'd' al comando (en tu codigo la d estaria tomando el lugar del [ENTER] de teclado de mi codigo)

nota: mi codigo lo probe solo en el arduino mega 1280

Hola greenlanternx, tenia curiosidad por probar lo del PS2 Keyboard y la verdad ta chulo, he hecho una plaquita adaptadora con un adaptador de una placa de portatil viejo y va de fábula, luego he probado tu codigo y definitivamente en el nano o el duemilanove solo entran entre 7 y 9 canciones dependiendo de su longitud, ya mas da errores, asique tendre q conformarme con ese numero, una pena almenos q demos con alguna solucion. Yo con string no he trabajado practicamente nunca pero no se podria guardar todas las canciones en uno separados pongamos por un $ y cuando haya que copiar y volcar a un char*??, es una idea que se me acaba de ocurrir pero no se muy bien como hacerlo, voy a ir mirando.

riscking:
Hola greenlanternx, tenia curiosidad por probar lo del PS2 Keyboard y la verdad ta chulo, he hecho una plaquita adaptadora con un adaptador de una placa de portatil viejo y va de fábula, luego he probado tu codigo y definitivamente en el nano o el duemilanove solo entran entre 7 y 9 canciones dependiendo de su longitud, ya mas da errores, asique tendre q conformarme con ese numero, una pena almenos q demos con alguna solucion. Yo con string no he trabajado practicamente nunca pero no se podria guardar todas las canciones en uno separados pongamos por un $ y cuando haya que copiar y volcar a un char*??, es una idea que se me acaba de ocurrir pero no se muy bien como hacerlo, voy a ir mirando.

si te fijas lo que hice fue almacenar en un array de char* , en string lo unico que maneje fue el comando de teclado, hay un pequeño truco para no usar tanta memoria, lo cual seria por medio de un case comparar el valor de la variable comando, y en cada alternativa asignar directamente la cancion, asi podrias tener mas canciones pero el codigo te saldra mucho mas extenso

Estoy intentandolo asi, pero el resultado es igual o peor, por longitud de codigo no hay problema lo q me satura en la ram.

if (keyboard.available()) {
    
    // read the next key
    char c = keyboard.read();
    // check for some of the special keys
    if (c == PS2_ENTER) {
      Serial.println(comando);
      char this_char[comando.length() + 1];
      comando.toCharArray(this_char, sizeof(this_char));
      switch (atoi(this_char)) {
    case 1:{
      char* song={"Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6"};
      p=song;
      break;}
    case 2:{
      char* song={"A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#"};
      p= song;
    break;}
    case 3:{
      char* song={"StarWars:d=4,o=5,b=45:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6"};
    p=song;  
    break;}
    case 4:{
      char* song={"Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6"};
    p=song;  
    break;}
    case 5:{
      char* song={"HareHare:d=8,o=5,b=164:g,a,g,a,4a,a,4a,a,4g,f,g,2a,a,4a,a,4a,a,4a#,a,a#,4c.6,c,c6,4a#,a,4f.,c6,c6,4a#,a,4f.,c6,c6,4a#,g#,4g,4f,2g"};
    p=song;  
    break;}
    case 6:{
      char* song={"MrRoboto:d=32,o=6,b=50:p,b.5,8a5,d.,8c#,a.5,8g5,p,d.,d.,d.,16e,p,d.,d.,d.,d.,e."};
      p=song; 
      break;}
    case 7:{
      char* song={"MissionImp:d=16,o=6,b=95:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#,g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f,32p,a#5,g5,2e,d#,8d"};
      p=song; 
      break;}
    case 8:{
      char* song={"Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#"};
      p=song; 
      break; } 
    
  }
      //p=song[atoi(this_char)];
      nuevo=true;
      reproducir=true;
      comando="";
    }

.... la lectura de datos la haces desde teclado o desde el serie? intenta con un solo tono y ve que sucede