Go Down

Topic: Arduino and VMUSIC2 (Read 7 times) previous topic - next topic

mbob87

Hey, I'm totally new to Arduino and the VMUSIC module but it sounds like the perfect way to implement the project I'm working on.

All I want is 5 or so inputs (simple buttons) that activate mp3 files on the flash stick.  The inputs can only be activated when it is their turn, which I will indicate with some LEDs.

I would just like to know where  to start with the code for this? I understand the very basics but would not be able to construct the whole code from scratch. Any help would be great!

Thanks, M

p.s does this need an entirely new thread?

Trav

Thank you all for the great information!

I got my VMusic2 hooked up to my Arduino and it worked splendidly. There were a couple commands that didn't work so I read that I needed to upgrade the FW from the v1.12 that came with it.  Easy enough, I loaded the image on a mem stick and upgraded to 3.36. I can read back the FW version and everything looked fine.
   However, now it won't recognize my memmory stick! I tried others and tried reformatting, still no luck. The newer FW isn't more strict than the old is it?  If so, how do I format it to work with the new FW?
   I tried to revert to an older version via the UART interface, but that's proven daunting..
                 Thoughts?            Thank you!

NotQuitePatrician

I'm happy I've been able to get my vmusic2 to work, but I'm not 100% clear how to interface it with an analog sensor...


I was wondering if anyone had experience with arduino and analog sensors and multiple things happening.

I basically need the vmusic constantly playing and the arduino reading the values of an AIRRS sensor. I thought the best way to do this was attachInterrupt but I can't seem to do that since I can't use the interrupt pins.

All I am trying to do is "when someone is thisclose to box, blow air" or I guess "if sensor returns anywhere from x to y, blow air" while the audio plays.

Maybe I'm just unsure how to store or take the comparators. But I think what I'm unsure of is if Arduino can do "while" loops, that's what I thought interrupts were.

I'll happily be pointed to an overlooked tutorial or another forum or notice. Thanks in advance. Some code below:

#define Relay 7 //pin for my relay
int sensorPin=0 //analog pin 0 on arduino
int sensorValue=0 //inital value of the sensor

//boolean old_AIRRS=0;
//boolean handryer_off= true
//int ledPin = 13;                // LED connected to digital pin 13


void setup ()
{
 Serial.begin(9600);
//pinMode(ledPin, OUTPUT);      // sets the digital pin as output
pinMode (Relay, OUTPUT);
//pinMode (AIRRS, INPUT);


digitalWrite (Relay, LOW);  

}

void loop()                     // for 5 seconds
{

 play_music();
{  
  sensorValue = analogRead(sensorPin);

if sensorValue (sensorPin < 300);

digitalWrite(Relay, HIGH);

delay (200);

if sensorValue (sensorPin != 0 && > 200);

digitalWrite (Relay, LOW);
}
void play_music()
{
Serial.print("V3A"); //play all files
Serial.print(13,BYTE);
delay(5000); //wait five seconds
Serial.print("VST"); //stop playing
Serial.print(13,BYTE);
}

}


schristi69

Has anyone else done anything else with getting this to work?  Diagrams on how to hook this up?  Am I better of getting the Efx-Tek controller to use this?

nouse4anick

very nice! i've been thinking of making an mp3 type player that uses a removable hard drive, this looks nice BUT i'm not sure i like how it implements usb drives =/

mbmosher

Hello,

I'd like to use the VMUSIC2 in a project I'm working for, but I need to be able to search the USB .mp3's by ID3 information, like artist or title.  Is this possible with the VMSC commands?  I seem to only be able to find the basics like play, pause, stop, repeat.  I noticed you can get it to output the ID3 info for the currently playing song, but can you search it / play a song based on ID3 info?

Thanks for the help!

b0t

I'm doing  a mp3 player, using vmusic and arduino, with 6 input pressure sensors.

I was able to connect the hardware successfully, managed to interface with it using arduino code.

#define VMUSIC_RX 2  
#define VMUSIC_TX 3  


I'm using Verbatin 2GB pen Drives and i've tried the following formats: FAT32 512b, FAT16 32K, FAT16 64K.
Vmusic don't seem to have a problem reading from any of it.  

As song formats, I'm using several qualitys, >200Kbps at 44,100KHZ.

The problem

The player plays fine for a while, and after a while it stops, sending a Stopped Command Failed,
after what you can't do anything at all, even trying play the same file again it says FileName Invalid.

Can you guys help?

Thanks,

b0t

b0t



(if you can't see the image please check http://rapidshare.com/files/396672649/screen-capture.png)

Keyblader2

Hi.
I'm new to Arduino, but am familiar with C++.
I have noticed the language is similar so the coding isn't really an issue.
However, I need to know if it is possible to get data from the MP3 file through Vmusic2 or Arduino.
For example, I need the length of the song, so that I will know when the song has stopped playing.
I realize normal players like windows media player can already do this, so is it possible to do the same in Arduino?

Trav

You can directly access the files with the File I/O commands. But the best way I've found to detect the MP3 is done playing is by monitoring the Serial port. When the command prompt returns, playing is done.  I used this approach to make a talking clock.
    -Trav

Keyblader2

Sorry about asking again, but how do I specifically get the duration of a song and store it as data?
Can I have a code example for this?
I have tried using the "T time" command but I don't know how it's used.
I need this kind of urgently for my job.
For now I have hooked up a Vmusic2 to an Arduino Mega (Diecimila works too), and then to a PC.
I have managed to play a song with the push of a button.
If it helps, here's the code.
Code: [Select]
/*

This program listens for a signal and plays the video
when the signal is recieved. As there may be multiple
triggers, hence a boolean is implemented and equipped
with a manual timer, it makes sure that only when the
audio has finished playing, can then be a another reading.
*/
#include <SoftwareSerial.h>

#define VMUSIC_RX 3
#define VMUSIC_TX 2

int buttonD = 8;//button used for relay trigger
int buttonValue = 1; //integer storage used for storing the status of the button
int led = 10;
boolean lock = true; // boolean to lock the reading
int count = 0;// manual counter to keep check of the timing

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(VMUSIC_RX, VMUSIC_TX);


void setup() {
 Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps

 // define pin modes for tx, rx, led pins:
 pinMode(VMUSIC_RX, INPUT);
 pinMode(VMUSIC_TX, OUTPUT);

 pinMode(buttonD, INPUT);    // declare pushbutton as input

 digitalWrite(buttonD, LOW);
 pinMode(led, OUTPUT);

 // set the data rate for the SoftwareSerial port
 mySerial.begin(9600);
}

void selectTrack (int trackNumber) {
 switch (trackNumber) {
 case 49:
   
   mySerial.print("VPF 1.mp3"); //play 1.mp3 as in the thumbdrive
   mySerial.print(0x0D,BYTE);// send a carriage return afterwhich

   break;

   //default:
   // if nothing else matches, do the default
   // default is optional
 }

}

void checkbuttons (){

 buttonValue = digitalRead(buttonD);//read the status

 if (buttonValue == HIGH && lock == true){
   digitalWrite(led, HIGH);
   selectTrack(10+39); // play track 49
   lock= false; // set lock = false to lock it
   count = 0;
   delay(50);//must put as a buffer

 }
 else {
   count++; // increment of count
   //Serial.println(count);
   if(count ==  2000) //until it reaches 20000, which the manual timer ends, and the music would have ended too
   {
     count = 0;//reset everything
     lock = true;
     digitalWrite(led, LOW);
   }
 }
}



void loop() {
 checkbuttons();

}



Trav

Do you rally need to know the length/time of the MP3 or do you just need to know when it's done playing? Extracting the time would require parsing the MP3 files to get the bit rate and size. I haven't done this with the VMUSIC/Ard, but there is lots of windows based code available that does this and would require porting to Arduiono.
That's a fair amount of work, but if you really only need to know when playing is complete, you can just monitor the serial port for the command prompt to return (when playing completes). You can call this code immediately after starting playback of an MP3. It will return when playing ends or an error occurs:

Code: [Select]

int WaitForPrompt(int TimeOutMs)
{
 const char strEnd[] = "D:\\>\r"; // = "D:\>[cr]"
 unsigned char strCount = 0, inval = 0, ErrCode = 0;
 unsigned long time;

 do
 {
   time = millis();
   while (!vmSerial.available() && millis() - time < TimeOutMs); //wait for VM serial, check timeout
   if (vmSerial.available())
   {
     inval = vmSerial.read();
     //check for prompt (end)
     if (inval == strEnd[strCount]) strCount++; //matches current pointer
     else
     {
       strCount = 0;
       if (inval == strEnd[strCount]) strCount++; //re-check first char in case of partial match
     }
   }
   else
   {
     ErrCode = errTimeout;
     Serial.println("***Stop Command Timeout");
   }
 }
 while((strCount != sizeof(strEnd)-1) && (!ErrCode)); //loop until match found or error.

 return(ErrCode);
}


Hope this helps!  :)

Trav

I should have mentioned that I usually use a long timeout (4S) since the VM only sends a keep alive every second or so:

 if (WaitForPrompt(4000)) Serial.println("\n***Timeout!");

I should also mention that the serial output has changed in different FW versions of the VM, here's what I'm currently using with the above code:
(fwv command)
MAIN 03.65VMSC1F
RPRG 1.00R

Keyblader2

#43
Dec 14, 2010, 05:21 am Last Edit: Dec 14, 2010, 06:07 am by Keyblader2 Reason: 1
Thanks for the reply.
I clarified with a colleague and I think I only need to check if the MP3 file has stopped playing, which is what you have provided here.
I will test out the code and report back with results.
[edit]EDIT: Oh no, it seems like I am using an older version of Adruino (0018) that doesn't have Serial.available. Is there any way to get around this or do I have to download the newest version?
EDIT: I tried using Arduino 0021 and the same message is shown.

'class SoftwareSerial' has no member named 'available'

I renamed the vmSerial in your code to mySerial since it's what I'm using, and this message appeared.

EDIT AGAIN: I think my colleague solved the problem, the available() function isn't in SoftwareSerial but in Serial.

Here's my latest version of the code, which seems to compile just fine.
Code: [Select]
/*

This program listens for a signal and plays the video
when the signal is recieved. As there may be multiple
triggers, hence a boolean is implemented and equipped
with a manual timer, it makes sure that only when the
audio has finished playing, can then be a another reading.
*/
#include <SoftwareSerial.h>

#define VMUSIC_RX 3
#define VMUSIC_TX 2

int buttonD = 8;//button used for relay trigger
int buttonValue = 1; //integer storage used for storing the status of the button
int led = 10;
boolean lock = true; // boolean to lock the reading
int count = 0;// manual counter to keep check of the timing

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(VMUSIC_RX, VMUSIC_TX);


void setup() {
 Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps

 // define pin modes for tx, rx, led pins:
 pinMode(VMUSIC_RX, INPUT);
 pinMode(VMUSIC_TX, OUTPUT);

 pinMode(buttonD, INPUT);    // declare pushbutton as input

 digitalWrite(buttonD, LOW);
 pinMode(led, OUTPUT);

 // set the data rate for the SoftwareSerial port
 mySerial.begin(9600);
}

void selectTrack (int trackNumber) {
 switch (trackNumber) {
 case 49:

   mySerial.print("VPF 1.mp3"); //play 1.mp3 as in the thumbdrive
   mySerial.print(0x0D,BYTE);// send a carriage return afterwhich
   delay(100);
   mySerial.print("T");

   break;

   //default:
   // if nothing else matches, do the default
   // default is optional
 }

}

void checkbuttons (){

 buttonValue = digitalRead(buttonD);//read the status

 if (buttonValue == HIGH && lock == true){
   digitalWrite(led, HIGH);
   selectTrack(10+39); // play track 49
   lock= false; // set lock = false to lock it
   count = 0;
   delay(50);//must put as a buffer

 }
 else {
   count++; // increment of count
   //Serial.println(count);
   if(count ==  2000) //until it reaches 20000, which the manual timer ends, and the music would have ended too
   {
     count = 0;//reset everything
     lock = true;
     digitalWrite(led, LOW);
   }
 }
}

int WaitForPrompt(int TimeOutMs)
{
 const char strEnd[] = "D:\\>\r"; // = "D:\>[cr]"
 unsigned char strCount = 0, inval = 0, ErrCode = 0;
 unsigned long time;

 do
 {
   time = millis();
   while (!Serial.available() && millis() - time < TimeOutMs); //wait for VM serial, check timeout
   if (Serial.available())
   {
     inval = Serial.read();
     //check for prompt (end)
     if (inval == strEnd[strCount]) strCount++; //matches current pointer
     else
     {
       strCount = 0;
       if (inval == strEnd[strCount]) strCount++; //re-check first char in case of partial match
     }
   }
   else
   {
     //ErrCode = errTimeout;
     ErrCode = 1;
       Serial.println("***Stop Command Timeout");
   }
 }
 while((strCount != sizeof(strEnd)-1) && (!ErrCode)); //loop until match found or error.

 return(ErrCode);
}

void loop() {
 //checkbuttons();
   mySerial.print("VPF 1.mp3"); //play 1.mp3 as in the thumbdrive
   mySerial.print(0x0D,BYTE);// send a carriage return afterwhich
   delay(100);
   mySerial.print("T time");
   char incoming = mySerial.read();
   Serial.print(incoming);
}


[/edit]

Keyblader2

Code: [Select]
//#include <SoftwareSerial.h>
#include <NewSoftSerial.h>
#include <avr/interrupt.h>

//#define VMUSIC_RX 3
//#define VMUSIC_TX 2
//#define VMUSIC_CTS 5

#define VMUSIC_RX 3
#define VMUSIC_TX 2
//#define VMUSIC_CTS 5

int incomingByte = 0;      // for incoming serial data

int buttonA = 5;
int buttonB = 6;
int buttonC = 7;
int buttonD = 8;//button used for relay trigger
int buttonStop = 4;

int ledA = 10;
int ledB = 11;
int ledC = 12;
int ledD = 13;//led used for display output
int ledStop = 9;

boolean lockA = false; // boolean to lock the reading for buttonA
boolean lockB = false; // boolean to lock the reading for buttonB
boolean lockC = false; // boolean to lock the reading for buttonC
boolean lockD = false; // boolean to lock the reading for buttonD
boolean lockStop = false; // boolean to lock the reading for buttonStop

int count = 0;// manual counter to keep check of the timing

int buttonValueA = 1;
int buttonValueB = 1;
int buttonValueC = 1;
int buttonValueD = 1; //integer storage used for storing the status of the button
int buttonValueStop = 1;

//// set up a new serial port
//SoftwareSerial mySerial =  SoftwareSerial(VMUSIC_RX, VMUSIC_TX);

//NSS serial port test
NewSoftSerial mySerial = NewSoftSerial(VMUSIC_RX, VMUSIC_TX);

void setup() {
 Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps

 // define pin modes for tx, rx, led pins:
 pinMode(VMUSIC_RX, INPUT);
 pinMode(VMUSIC_TX, OUTPUT);
 //pinMode(VMUSIC_CTS, OUTPUT);
 pinMode(buttonA, INPUT);    // declare pushbutton as input
 pinMode(buttonB, INPUT);    // declare pushbutton as input
 pinMode(buttonC, INPUT);    // declare pushbutton as input
 pinMode(buttonD, INPUT);    // declare pushbutton as input
 pinMode(buttonStop, INPUT);
 
 digitalWrite(buttonA, LOW);
 digitalWrite(buttonB, LOW);
 digitalWrite(buttonC, LOW);
 digitalWrite(buttonD, LOW);
 digitalWrite(buttonStop, LOW);
 
 pinMode(ledA, OUTPUT);
 pinMode(ledB, OUTPUT);
 pinMode(ledC, OUTPUT);
 pinMode(ledD, OUTPUT);
 pinMode(ledStop, OUTPUT);
 
 //This will allow softwareSerial to process incoming automatically:
 //attachInterrupt(0, readSoftwareSerial, LOW);
 
 //Tells VMUSIC that hardware is connected:
 //digitalWrite(VMUSIC_CTS, LOW);  

 // set the data rate for the SoftwareSerial port
 mySerial.begin(9600);
 
}

void selectTrack (int trackNumber)
{
 switch (trackNumber)
 {
   case 1:

   mySerial.print("VPF 1.mp3"); //play 1.mp3 as in the thumbdrive
   mySerial.print(0x0D,BYTE);// send a carriage return afterwhich
   
   break;
   
   case 2:
   
   mySerial.print("VPF 2.mp3");//play 2.mp3
   mySerial.print(0x0D,BYTE);//send carriage return
   
   break;
   
   case 3:
   
   mySerial.print("VPF 3.mp3");//play 3.mp3
   mySerial.print(0x0D,BYTE);//send carriage return
   
   break;
   
   case 4:
   
   mySerial.print("VPF 4.mp3");//play 4.mp3
   mySerial.print(0x0D,BYTE);//send carriage return
   
   break;

   //default:
   // if nothing else matches, do the default
   // default is optional
 }

}

void checkbuttons (){

 buttonValueA = digitalRead(buttonA);//read the status
 buttonValueB = digitalRead(buttonB);//read the status
 buttonValueC = digitalRead(buttonC);//read the status
 buttonValueD = digitalRead(buttonD);//read the status
 buttonValueStop = digitalRead(buttonStop);//read the status
 
 if(buttonValueA == HIGH && lockA == false)
 {
   digitalWrite(ledA, HIGH);
   selectTrack(1); // play 1
   lockA = true; // set lock = true to lock it
   count = 0;
   //delay(50);//must put as a buffer
   digitalWrite(ledStop, LOW);//turn off stop button
   
   //turn off other buttons
   digitalWrite(ledB, LOW);
   digitalWrite(ledC, LOW);
   digitalWrite(ledD, LOW);
       
   //reset locks for other buttons
   lockB = false;
   lockC = false;
   lockD = false;
   
   if (WaitForPrompt(4000)) Serial.println("\n***Timeout!");//trying out checking for playback stop
 }
 else if(buttonValueB == HIGH && lockB == false)
 {
   digitalWrite(ledB, HIGH);
   selectTrack(2); // play 2
   lockB = true; // set lock = true to lock it
   count = 0;
   //delay(50);//must put as a buffer
   digitalWrite(ledStop, LOW);//turn off stop button
   
   digitalWrite(ledA, LOW);//turn off other buttons
   digitalWrite(ledC, LOW);
   digitalWrite(ledD, LOW);
       
   lockA = false;//reset locks for other buttons
   lockC = false;
   lockD = false;
 }
 else if(buttonValueC == HIGH && lockC == false)
 {
   digitalWrite(ledC, HIGH);
   selectTrack(3); // play 3
   lockC = true; // set lock = ture to lock it
   count = 0;
   //delay(50);//must put as a buffer
   digitalWrite(ledStop, LOW);//turn off stop button
   
   digitalWrite(ledA, LOW);//turn off other buttons
   digitalWrite(ledB, LOW);
   digitalWrite(ledD, LOW);
       
   lockA = false;//reset locks for other buttons
   lockB = false;
   lockD = false;
 }
 else if(buttonValueD == HIGH && lockD == false)
 {
   digitalWrite(ledD, HIGH);
   selectTrack(4); // play 4
   lockD = true; // set lock = true to lock it
   count = 0;
   //delay(50);//must put as a buffer
   digitalWrite(ledStop, LOW);//turn off stop button
   
   digitalWrite(ledA, LOW);//turn off other buttons
   digitalWrite(ledB, LOW);
   digitalWrite(ledC, LOW);
       
   lockA = false;//reset locks for other buttons
   lockB = false;
   lockC = false;
 }
 else if(buttonValueStop == HIGH /*&& lock == false*/)
 {
   digitalWrite(ledA, LOW);
   digitalWrite(ledB, LOW);
   digitalWrite(ledC, LOW);
   digitalWrite(ledD, LOW);
   digitalWrite(ledStop, HIGH);
   mySerial.print("VST");
   mySerial.print(0x0D,BYTE);//send carriage return
   //digitalWrite(ledStop, LOW);
   //lockStop = true; // set lock = false to lock it
   count = 0;
   
   lockA = false;//reset locks
   lockB = false;
   lockC = false;
   lockD = false;
     
   delay(50);//must put as a buffer
 }
//  else
//  {
//    count++; // increment of count
//    //Serial.println(count);
//    if(count ==  2000) //until it reaches 20000, which the manual timer ends, and the music would have ended too
//    {
//      count = 0;//reset everything
//      lockA = false;
//      lockB = false;
//      lockC = false;
//      lockD = false;
//      //lockStop = false;
//      digitalWrite(ledA, LOW);
//      digitalWrite(ledB, LOW);
//      digitalWrite(ledC, LOW);
//      digitalWrite(ledD, LOW);
//      digitalWrite(ledStop, LOW);
//    }
//  }
}

int WaitForPrompt(int TimeOutMs)
{
 const char strEnd[] = "D:\\>\r"; // = "D:\>[cr]"
 unsigned char strCount = 0, inval = 0, ErrCode = 0, errTimeout = 0;
 unsigned long time;

 do
 {
   time = millis();
   while (!mySerial.available() && millis() - time < TimeOutMs); //wait for VM serial, check timeout
   if (mySerial.available())
   {
     inval = mySerial.read();
     //check for prompt (end)
     if (inval == strEnd[strCount]) strCount++; //matches current pointer
     else
     {
       strCount = 0;
       if (inval == strEnd[strCount]) strCount++; //re-check first char in case of partial match
     }
   }
   else
   {
     ErrCode = errTimeout;

     Serial.println("***Stop Command Timeout");
   }
 }
 while((strCount != sizeof(strEnd)-1) && (!ErrCode)); //loop until match found or error.

 return(ErrCode);
}

//void readSoftwareSerial(){
// noInterrupts();
// digitalWrite(led, HIGH);
// char incoming = mySerial.read();
// Serial.print(incoming);
// digitalWrite(led, LOW);
// interrupts();
//}

void loop() {
     checkbuttons();
}


ok, here's my current code
what it's supposed to do, is detect input from 5 different buttons
4 of them will each play one song
the 5th one will be the stop button
now, my buttons work perfectly
but when i try to use the waitForPrompt function by Trav, it will get stuck in an endless loop and keep printing "***Stop Command Timeout"
as you can see in buttonA, i tried to use
if (WaitForPrompt(4000)) Serial.println("\n***Timeout!");
but it just makes the button stuck in an endless loop
can anyone give me some help?
i'm so close to the answer :(

Go Up