Show Posts
Pages: [1]
1  Using Arduino / Programming Questions / Re: Using Metro to Play Multiple Speakers at Once on: May 14, 2013, 09:32:31 pm
Thanks tobyb121!
2  Using Arduino / Programming Questions / Re: Using Metro to Play Multiple Speakers at Once on: May 08, 2013, 02:05:47 pm
@Paul

Quote
For which you need to provide a link. It is not a core library, so you can not assume that we are all familiar with it.

Sorry about that. Here's the link to the website that has the library:  http://playground.arduino.cc/Code/Metro

Quote
You'd need to look at the library code, and see what resources/technique it is using.

I have looked at the cpp file and have noticed that it uses the millis() method. I have a feeling that using more than 2 ports causes the millis() function to not work as intended. I later had the Arduino output the value of millis() during each iteration of the loop. It kept on displaying small values like 49 or 56, then staying at about 57. Is this a problem?

@tobyb121

Quote
I don't think you can open more than 1 file with the SD library like that, I may be wrong as I haven't used it for a little while, but I'm pretty sure I remember that it can only handle one open file at a time.

I double checked that and it can open up multiple files at a time. Are you suggesting that there could be a shortage of memory?
3  Using Arduino / Programming Questions / Using Metro to Play Multiple Speakers at Once on: May 07, 2013, 06:11:22 pm
Hi! I'm still new to the Arduino world. I'm trying to have my Arduino play music by reading textfiles. However, I am running into an issue. BTW, I am using an Arduino Mega 2560.

When I try to run this code, the Arduino plays only the 1st note for each file. This is correct. However, it stops right afterwards. It should play through the WHOLE song for each speaker. I happened to get this to work with 2 speakers in a different version of the program. However, I cannot get this to work with 3 or more speakers.

I have been using the Metro library in order to have durations for all kinds of notes (including rests). However, when I removed the Metro.reset() portion of the code, the whole song played through (although not at the correct durations). Is there a limit to how many Metros can run at the same time? If so, what can I do to fix this? Thanks in advance! smiley

This is my code, BTW:

Code:
#include <Metro.h>
#include <SD.h>
#include <String.h>
#include <Tone.h>

File root;

const int arr[7][27] = {
  {
    26, 28, 29, 52, 55, 58, 104, 110, 117, 208, 220, 233, 415, 440, 466, 831, 880, 932,  1661, 1760, 1865, 3322, 3520, 3729, 0,    0,    0    }
  ,
  {
    29, 31, 33, 58, 62, 65, 117, 123, 131, 233, 247, 262, 466, 494, 523, 932, 988, 1047, 1865, 1976, 2093, 3729, 3951, 4186, 0,    0,    0    }
  ,
  {
    0,  16, 17, 31, 33, 35, 62,  65,  69,  123, 131, 139, 247, 262, 277, 494, 523, 554,  988,  1047, 1109, 1976, 2093, 2217, 3951, 4186, 4435    }
  ,
  {
    17, 18, 19, 35, 37, 39, 69,  73,  78,  139, 147, 156, 277, 294, 311, 554, 587, 622,  1109, 1175, 1245, 2217, 2349, 2489, 4435, 4699, 4978    }
  ,
  {
    19, 21, 22, 39, 41, 44, 78,  82,  87,  156, 165, 175, 311, 330, 349, 622, 659, 698,  1245, 1319, 1397, 2489, 2637, 2794, 4978, 0,    0    }
  ,
  {
    21, 22, 23, 41, 44, 46, 82,  87,  93,  165, 175, 185, 330, 349, 370, 659, 698, 740,  1319, 1397, 1480, 2637, 2794, 2960, 0,    0,    0    }
  ,
  {
    23, 25, 26, 46, 49, 52, 93,  98,  104, 185, 196, 208, 370, 392, 415, 740, 784, 831,  1480, 1568, 1661, 2960, 3136, 3322, 0,    0,    0    }
};
//Rows are as follows: A B C D E F G
//Columns are 0F, 0N, 0S, 1F, 1N, 1S, etc.
void readFile(File f, int t, int numba);//Gets the pitch and duration of each note
int getTempo(File f, int i);//Gets the tempo of
int translation(String s);

int tempo1 = 0, tempo2 = 0, tempo3 = 0, tempo4 = 0, tempo5 = 0; //Self explanatory.
double duration = 0;//Self explanatory.
int pitch = 0;//Self explanatory.
int pitch2 = 0;
int duration2 = 0;
int pitch3 = 0;
int duration3 = 0;
Tone tone1; //Used as an easy reference to a speaker in a port.
Tone tone2;
Tone tone3;

Metro m1 = Metro(0);//This is the special "stopwatch" variable for tone1.
Metro m2 = Metro(0);
Metro m3 = Metro(0);

void setup()
{  
  Serial.begin(9600);//Begins the serial at a rate of 9600 bauds.
  pinMode(53, OUTPUT);//Sets port 10 as the output port (I THINK).
  SD.begin(53);//Used for SD cards and the like. Bother with it.
  tone1.begin(8);//Needed to start the tone variable.
  tone2.begin(9);
  tone3.begin(7);
  root = SD.open("/boss/"); // Just use "/" if you don't want to go to a specific folder....
  File temp = root.openNextFile();//Starts it on the 1st file.
  File temp2 = root.openNextFile();
  File temp3 = root.openNextFile();
  //int i = 0;//Used for
  if(temp)
  Serial.println("File 1 works");
  else
  Serial.println("File 1 doesn't work");
  if(temp2)
  Serial.println("File 2 works");
  else
  Serial.println("File 2 doesn't work");
  if(temp3)
  Serial.println("File 3 works");
  else
  Serial.println("File 3 doesn't work");
  if(temp || temp2 || temp3)
  {
  int seekPos = 0, seekPos2 = 0, seekPos3 = 0;
  if(temp)
  {
    seekPos = getTempo(temp, 0);
    temp.seek(seekPos);
  }
  if(temp2)
  {
    seekPos2 = getTempo(temp2, 1);
    temp2.seek(seekPos2);
  }
  if(temp3)
  {
    seekPos3 = getTempo(temp3, 2);
    temp3.seek(seekPos3);
  }
  while(temp.available() || temp2.available() || temp3.available())
  {
    if(m1.check() && temp.available())
    {
      readFile(temp, tempo1, 0);
      tone1.play(pitch, duration);
      m1.interval(duration); //An Issue is here I think
      m1.reset();
    }
    if(m2.check() && temp2.available())
    {
      readFile(temp2, tempo2, 1);
      tone2.play(pitch2, duration2);
      m2.interval(duration2); //An Issue is here I think
      m2.reset();
    }
    if(m3.check() && temp3.available())
    {
      readFile(temp3, tempo3, 2);
      tone3.play(pitch3, duration3);
      m3.interval(duration3); //An Issue is here I think
      m3.reset();
    }
  }  
  }
  Serial.println("Completed");
}

void loop()
{
  
}

void readFile(File f, int t, int numba)
{
  int k = 0, iteration = 0;
  String s = "";
  while(f.available() && iteration < 2)
  {
    String s = "";
    boolean b = true;
    while(b && f.available())
    {
      char c = f.read();
      if((c >  '/' && c < ':') || (c > '@' && c < 'H') || (c > '`' && c < 'h') || c == 'r' || c == '.' && c != '\n')
      {
        s+= c;
      }
      else if(c == ' ')
      {
       b = false;
       Serial.println(s);
      }
    }
    if(s != NULL && s.length() >= 1)
    {
        if(iteration%2 == 0)
          {
            if(numba == 0)
            pitch = translation(s);          
            else if(numba == 1)
            pitch2 = translation(s);
            else if(numba == 2)
            pitch3 = translation(s);
          }
        else
        {
          char buf[s.length()+1];
          s.toCharArray(buf,sizeof(buf));
          double WVal=atof(buf);
          double v = (((WVal)/4.0) * (245000.0/(t)));      
          if(numba == 0)
          duration = v;      
          else if(numba == 1)
          duration2 = v;
          else if(numba == 2)
          duration3 = v;
          k++;
        }
        iteration++;
    }
  }  
}
int translation(String s)
{
  int row = 0, column = 0, modifier = 0;
  char a = s.charAt(0), b = s.charAt(1);
  if('a' == tolower(a))
    row = 0;
  else if('b' == tolower(a))
    row = 1;
  else if('c' == tolower(a))
    row = 2;
  else if('d' == tolower(a))
    row = 3;
  else if('e' == tolower(a))
    row = 4;
  else if('f' == tolower(a))
    row = 5;
  else if('g' == tolower(a))
    row = 6;
  else
    return 0;
  if(s.length() == 2)
  {
    modifier = 1;
    if('0' ==  b)
      column = 0;
    else if('1' ==  b)
      column = 1;
    else if('2' ==  b)
      column = 2;
    else if('3' ==  b)
      column = 3;
    else if('4' ==  b)
      column = 4;
    else if('5' ==  b)
      column = 5;
    else if('6' ==  b)
      column = 6;
    else if('7' ==  b)
      column = 7;
    else if('8' ==  b)
      column = 8;
    else
      return 0;
  }
  else if(s.length() == 3)
  {
    char c = s.charAt(2);
    if('f' == tolower(b))
      modifier = 0;
    else if('n' == tolower(b))
      modifier = 1;
    else if('s' == tolower(b))
      modifier = 2;
    else
      return 0;
    if('0' ==  c)
      column = 0;
    else if('1' ==  c)
      column = 1;
    else if('2' ==  c)
      column = 2;
    else if('3' ==  c)
      column = 3;
    else if('4' ==  c)
      column = 4;
    else if('5' ==  c)
      column = 5;
    else if('6' ==  c)
      column = 6;
    else if('7' ==  c)
      column = 7;
    else if('8' ==  c)
      column = 8;
    else
      return 0;
  }
  else
    return 0;
  if(row > 6 || row < 0 || ((3*column) + modifier) > 26 || ((3*column) + modifier) < 0)
    return 0;
  return arr[row][(3*column) + modifier];
}
int getTempo(File f, int i)
{
  String s = "";
  char c;
  boolean b = true;
  while(f.available() && b)
  {
    char c = f.read();
    if(c != ((char) 10) && c != ((char) 32))
    {
      s+= c;
    }
    else
      b = false;
  }
  s.toLowerCase();
  if(s.equals("tempo:"))
  {
    int t = f.position();
    s = NULL;
    b = true;
    while(f.available() && b)
    {
      char c = f.read();
      if(c != ((char) 10) && c != ((char) 32))
      {
        s+= c;
      }
      else
        b = false;
    }
    int k = s.toInt();
    switch(i)
    {
       case 0:
       {
        tempo1 = k;
        break;
       }
      case 1:
       {
        tempo2 = k;
        break;
       }
      case 2:
       {
        tempo3 = k;
        break;
       }
      case 3:
       {
        tempo4 = k;
        break;
       }
      case 4:
       {
        tempo5 = k;
        break;
       }  
    }
    return f.position();
  }
  else
    return 0;
}
4  Using Arduino / Storage / Re: SD Shield Issues for Arduino Mega (works with Arduino Uno) on: May 07, 2013, 05:18:58 pm
You're a LIFE SAVER!!! Thanks a LOT!!!!  smiley-grin

This helps me a TON in my Mentorship class! Without you, I'd be stuck with having to use the Uno in order to play music. And the Uno only allowed me to use 2 ports. And you know how songs sound better with multiple parts anyways. smiley-wink

Once again, THANKS!! smiley-grin
5  Using Arduino / Storage / Re: SD Card Shield configuration on Arduino mega 2560 REV3? on: May 07, 2013, 05:05:18 pm
Is there a difference between 11-50 and 11 > 50? If so, how does one wire 11 > 50 as opposed to 11-50?
6  Using Arduino / Storage / Re: SD Shield Issues for Arduino Mega (works with Arduino Uno) on: May 07, 2013, 04:32:14 pm
I tried doing that right now and it still shows that the two files couldn't be opened. Do I need to bend the pins? Also, do I need to change the port number to 53 (I changed both output and SD.begin() to ports 53)?
7  Using Arduino / Storage / SD Shield Issues for Arduino Mega (works with Arduino Uno) on: May 07, 2013, 04:05:26 pm
I am having trouble having my Arduino Mega 2560 read text files from the SD Shield. My SD Shield is functional on an Arduino Uno R3 Plus, however. I also installed the driver for the Mega and have tested it with non-SD card related programs and it works fine. Does the SD shield plug into the Mega differently? Am I using the wrong ports?

I chose to buy an Arduino Mega 2560 in order to use more ports simultaneously. I desire to have my Arduino play music by reading text files located on an SD card. The Uno only allowed me to play up to two files at once as only 2 ports could be used at once. So, that's why I bought the Mega 2560.

This is my code, BTW. It works on the Uno, but not the Mega.
Code:
#include <Metro.h>
#include <SD.h>
#include <String.h>
#include <Tone.h>

File root;//Used as the directory

const int arr[7][27] = {
  {
    26, 28, 29, 52, 55, 58, 104, 110, 117, 208, 220, 233, 415, 440, 466, 831, 880, 932,  1661, 1760, 1865, 3322, 3520, 3729, 0,    0,    0    }
  ,
  {
    29, 31, 33, 58, 62, 65, 117, 123, 131, 233, 247, 262, 466, 494, 523, 932, 988, 1047, 1865, 1976, 2093, 3729, 3951, 4186, 0,    0,    0    }
  ,
  {
    0,  16, 17, 31, 33, 35, 62,  65,  69,  123, 131, 139, 247, 262, 277, 494, 523, 554,  988,  1047, 1109, 1976, 2093, 2217, 3951, 4186, 4435    }
  ,
  {
    17, 18, 19, 35, 37, 39, 69,  73,  78,  139, 147, 156, 277, 294, 311, 554, 587, 622,  1109, 1175, 1245, 2217, 2349, 2489, 4435, 4699, 4978    }
  ,
  {
    19, 21, 22, 39, 41, 44, 78,  82,  87,  156, 165, 175, 311, 330, 349, 622, 659, 698,  1245, 1319, 1397, 2489, 2637, 2794, 4978, 0,    0    }
  ,
  {
    21, 22, 23, 41, 44, 46, 82,  87,  93,  165, 175, 185, 330, 349, 370, 659, 698, 740,  1319, 1397, 1480, 2637, 2794, 2960, 0,    0,    0    }
  ,
  {
    23, 25, 26, 46, 49, 52, 93,  98,  104, 185, 196, 208, 370, 392, 415, 740, 784, 831,  1480, 1568, 1661, 2960, 3136, 3322, 0,    0,    0    }
};
//Rows are as follows: A B C D E F G
//Columns are 0F, 0N, 0S, 1F, 1N, 1S, etc.
void readFile(File f, int t, int numba);
int getTempo(File f, int i);
int translation(String s);

int tempo1 = 0, tempo2 = 0, tempo3 = 0, tempo4 = 0, tempo5 = 0;
double duration = 0;
int pitch = 0;
int pitch2 = 0;
int duration2 = 0;
Tone tone1;
Tone tone2;

Metro m1 = Metro(0);
Metro m2 = Metro(0);

void setup()

  Serial.begin(9600);//Begins the serial at a rate of 9600 bauds.
  pinMode(10, OUTPUT);//Sets port 10 as the output port.
  SD.begin(10);//Used for SD cards and the like.
  tone1.begin(8);//Needed to start the tone variable.
  tone2.begin(9);
  root = SD.open("/ALttP/"); // Just use "/" if you don't want to go to a specific folder....
  File temp = root.openNextFile();//Starts it on the 1st file.
  File temp2 = root.openNextFile();
  //int i = 0;//Used for
  if(temp)
  Serial.println("File 1 works");
  else
  Serial.println("File 1 doesn't work");
  if(temp2)
  Serial.println("File 2 works");
  else
  Serial.println("File 2 doesn't work");
  if(temp && temp2)
  {
  int seekPos = 0, seekPos2 = 0;
  seekPos = getTempo(temp, 0);
  seekPos2 = getTempo(temp2, 1);
//  countFile(temp, i);
  temp.seek(seekPos);
  temp2.seek(seekPos2);
  while(temp.available() || temp2.available())
  {
    if(m1.check() && temp.available())
    {
    readFile(temp, tempo1, 0);
    tone1.play(pitch, duration);
    m1.interval(duration);
    m1.reset();
    }
    if(m2.check() && temp2.available())
    {
    readFile(temp2, tempo2, 1);
    tone2.play(pitch2, duration2);
    m2.interval(duration2);
    m2.reset();
    }
  } 
  }
  Serial.println("Completed");
}
void loop()
{
//  Serial.println("Yay!");
}

/*void countFile(File f, int i)
{
  int count = 0;
  while(f.available())
  {
    char c = f.read();
    if(c == ((char) 32))
    {
      count++;
    }
  }
  count++;
  if(i == 0)
  {
    limit1 = count/2;
  }
  else if(i == 1)
  {
    limit2 = count/2;   
  }
  else if(i == 2)
  {
    limit3 = count/2;   
  }
  else if(i == 3)
  {
    limit4 = count/2;   
  }
  else if(i == 4)
  {
    limit5 = count/2;   
  }
}*/

void readFile(File f, int t, int numba)
{
  int k = 0, iteration = 0;
//  int song[500], duration[500];
  String s = "";
  while(f.available() && iteration < 2)
  {
    String s = "";
    boolean b = true;
    while(b && f.available())
    {
      char c = f.read();
      if((c >  '/' && c < ':') || (c > '@' && c < 'H') || (c > '`' && c < 'h') || c == 'r' || c == '.' && c != '\n')
      {
        s+= c;
      }
      else if(c == ' ')
      {
       b = false;
       Serial.println(s);
      }
    }
    if(s != NULL && s.length() >= 1)
    {
        if(iteration%2 == 0)
          {
            if(numba == 0)
            pitch = translation(s);         
            else if(numba == 1)
            pitch2 = translation(s);
          }
        else
        {
          char buf[s.length()+1];
          s.toCharArray(buf,sizeof(buf));
          double WVal=atof(buf);
          double v = (((WVal)/4.0) * (245000.0/(t)));       
          Serial.println(v);
          if(numba == 0)
          duration = v;     
          else if(numba == 1)
          duration2 = v;
          k++;
        }
        iteration++;
    }
  } 
}
int translation(String s)
{
  int row = 0, column = 0, modifier = 0;
  char a = s.charAt(0), b = s.charAt(1);
  if('a' == tolower(a))
    row = 0;
  else if('b' == tolower(a))
    row = 1;
  else if('c' == tolower(a))
    row = 2;
  else if('d' == tolower(a))
    row = 3;
  else if('e' == tolower(a))
    row = 4;
  else if('f' == tolower(a))
    row = 5;
  else if('g' == tolower(a))
    row = 6;
  else
    return 0;
  if(s.length() == 2)
  {
    modifier = 1;
    if('0' ==  b)
      column = 0;
    else if('1' ==  b)
      column = 1;
    else if('2' ==  b)
      column = 2;
    else if('3' ==  b)
      column = 3;
    else if('4' ==  b)
      column = 4;
    else if('5' ==  b)
      column = 5;
    else if('6' ==  b)
      column = 6;
    else if('7' ==  b)
      column = 7;
    else if('8' ==  b)
      column = 8;
    else
      return 0;
  }
  else if(s.length() == 3)
  {
    char c = s.charAt(2);
    if('f' == tolower(b))
      modifier = 0;
    else if('n' == tolower(b))
      modifier = 1;
    else if('s' == tolower(b))
      modifier = 2;
    else
      return 0;
    if('0' ==  c)
      column = 0;
    else if('1' ==  c)
      column = 1;
    else if('2' ==  c)
      column = 2;
    else if('3' ==  c)
      column = 3;
    else if('4' ==  c)
      column = 4;
    else if('5' ==  c)
      column = 5;
    else if('6' ==  c)
      column = 6;
    else if('7' ==  c)
      column = 7;
    else if('8' ==  c)
      column = 8;
    else
      return 0;
  }
  else
    return 0;
  if(row > 6 || row < 0 || ((3*column) + modifier) > 26 || ((3*column) + modifier) < 0)
    return 0;
  return arr[row][(3*column) + modifier];
}
int getTempo(File f, int i)
{
  String s = "";
  char c;
  boolean b = true;
  while(f.available() && b)
  {
    char c = f.read();
    if(c != ((char) 10) && c != ((char) 32))
    {
      s+= c;
    }
    else
      b = false;
  }
  s.toLowerCase();
  if(s.equals("tempo:"))
  {
    int t = f.position();
    s = NULL;
    b = true;
    while(f.available() && b)
    {
      char c = f.read();
      if(c != ((char) 10) && c != ((char) 32))
      {
        s+= c;
      }
      else
        b = false;
    }
    int k = s.toInt();
    switch(i)
    {
       case 0:
       {
        tempo1 = k;
        break;
       }
      case 1:
       {
        tempo2 = k;
        break;
       }
      case 2:
       {
        tempo3 = k;
        break;
       }
      case 3:
       {
        tempo4 = k;
        break;
       }
      case 4:
       {
        tempo5 = k;
        break;
       } 
    }
    return f.position();
  }
  else
    return 0;
}
Pages: [1]