Go Down

Topic: Porque no funciona este codigo (Read 2 times) previous topic - next topic

greenlanternx

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

riscking

#16
Jun 24, 2011, 10:29 pm Last Edit: Jun 24, 2011, 11:23 pm by riscking Reason: 1
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.

greenlanternx


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

riscking

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

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="";
    }

greenlanternx

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

riscking

#20
Jun 27, 2011, 01:00 am Last Edit: Jun 28, 2011, 12:46 am by riscking Reason: 1
Creo que he encontrado la solucion al problema y no precisamente delante del Pc sino en la playa xDD, un colega q habia trabajado con microcontroladores me ha preguntado sobre mi proyecto y le he explicado los problemas q tenia con la Ram y me ha dicho porque no guardo las canciones en la memoria flash ya q no se van a manipular, y he investigado un poco y parece q puede ser la solución, he hecho unas pequeñas pruebas y la cosa pinta bien, en esta dire explica como usar PROGMEM.
http://arduino.cc/estemp/Reference/PROGMEM

P.D. Lo he probado con 25 canciones y va genial, por fin he podido conseguirlo!!!!

greenlanternx

bueno, el donde te haya llegado la inspiracion no es importante, muchas veces a mi me han llegado mientras voy en el bus o mientras estoy en el supermercado XD
podrias postear las lineas que tuviste que cambiar para implementar progmem

riscking

Ya que me pusiste tu codigo entero, lo he modificado y  quedaria así, lo he probado y aparentemente funciona sin errores, espero que te sirva, un saludo.

Code: [Select]
#include <Tone.h>
#include <stdlib.h>
#include <avr/pgmspace.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
};
prog_char string_0[] PROGMEM = "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";   // "String 0" etc. son strings a guardar.
prog_char string_1[] PROGMEM = "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";
prog_char string_2[] PROGMEM = "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";
prog_char string_3[] PROGMEM = "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";
PROGMEM const char *string_table[] =
{   
  string_0,
  string_1,
  string_2,
  string_3
};
char *p; 
char song[700]; //del tamaño de la cadena mas grande
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(6);
 
  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));
      switch (atoi(this_char)) {
    case 1:{
      strcpy_P(song, (char*)pgm_read_word(&(string_table[0])));
      p=song;
      break;}
    case 2:{
      strcpy_P(song, (char*)pgm_read_word(&(string_table[1])));
      p= song;
    break;}
    case 3:{
      strcpy_P(song, (char*)pgm_read_word(&(string_table[2])));
    p=song; 
    break;}
    case 4:{
      strcpy_P(song, (char*)pgm_read_word(&(string_table[3])));
    p=song; 
    break;}
   
  }
      //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);
}

Go Up