Pages: 1 2 3 [4]   Go Down
Author Topic: Arduino and VMUSIC2  (Read 7348 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you monitored the VMUSIC output directly (either with another device or using the Arduino as a pass-through/manual mode)?  That's why I included my VMUSIC FW info in the post, I've seen it act differently on other FW versions. The FW upgrade files are available on the Veniculum site.
The routine counts on the fact that the VM FW outputs a kind of "keep alive" character every second or so.  If this isn't the case, you can either upgrade the VM FW to the same as mine, or you could take out the timeout check and force it to wait for the command prompt (or make the timeout longer than the file would ever be).
The best solution (IMO) would be to use the same FW as mine so that it has a real timeout/abort in case of any problems. Either way, first step would be characterizing and checking the FW version with direct serial communication. While you're there, verify that it's prompt string is as expected: "D:\>[cr]"
I also see that you switched to the NewSoftwareSerial, that's good as it is much more robust.
        -Trav
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

just a quick question, do i need to connect the CTS pin from the VMusic2 to anything on the arduino?
for now i am just connecting it to ground
the only pin i am connecting to arduino is the RX pin, which is connected to pin 2 on arduino.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grounding the CTS pin is correct.
You have the Rx connected but not the Tx? You need the VM TX connected to the Arduino too, that's how the data comes back in that my routine monitors to detect the end of the MP3 (mySerial.available() & mySerial.read())  You have it defined as pin 3 in your sketch, definitely need to connect it!  smiley
                 -Trav
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok i'll give it a shot
i'm almost done with the circuit board, after its done i will test the vmusic2 again.
EDIT: i tried using the waitForPrompt method in my loop, but it just returned "***Stop Command Timeout"
although, it seemed to stop returning this when the song ended
is it supposed to do this?
or am i putting this in the wrong place?
i tried putting it in one of my buttons, so when it played an 8 second clip it stopped returning "***Stop Command Timeout" after 8 seconds i think.
can you advise me where to put this fucntion?
« Last Edit: December 22, 2010, 04:48:56 am by Keyblader2 » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you control it manually in a serial pass-through mode and check the FW revision as I recommended?
I see one problem, you have errTimeout set to 0 so that when a timeout occurs, ErrCode still remains 0 and doesn't exit the loop, that's why you see multiple timeouts.
From this I'm deducing that the FW on your module doesn't have the keep alive characters.  I can't confirm until you've checked the FW version as I suggested, and/or tried it manually.
I wrote it in a way that would accept a short timeout and return quickly on error (due to the keep alive). Another quick thing you could try (after setting errTimeout to a non zero value) is to call it with a timeout longer than ANY clip you'll want to play. For example, if your longest clip is ~8 second, try calling it with a 10 sec (10000mS) timeout.  It will return immediately when done playing. The downside of this is that is there's a play error, it will wait the full timeout before returning.
It would be best to upgrade to the FW I recommended, but this should get you going for now...
      -Trav
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, thanks for the reply again, i think i know how the function works now.
i'm still mounting the arduino onto a box so i'll take a while to do the code.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry for the late reply, but I finally got it to work.
Thanks for the help Trav, but I'm not sure if I am using the waitForPrompt function correctly.
Nevertheless, it works for me.

Code:
#include <NewSoftSerial.h>
#include <avr/interrupt.h>

#define VMUSIC_RX 3
#define VMUSIC_TX 2

int incomingByte = 0;      // for incoming serial data

//buttons A to Stop
int buttonA = 5;
int buttonB = 7;
int buttonC = 9;
int buttonD = 11;
int buttonStop = 13;

//leds A to Stop
int ledA = 4;
int ledB = 6;
int ledC = 8;
int ledD = 10;
int ledStop = 12;

//locks A to Stop
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

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

//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);

  // 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
    
    //turn off stop button
    digitalWrite(ledStop, LOW);

    //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(10) == 0)
    {
      digitalWrite(ledA, LOW);
      lockA = false;
      digitalWrite(ledStop, HIGH);
    }
  }
  
  if(buttonValueB == HIGH && lockB == false)
  {
    digitalWrite(ledB, HIGH);
    selectTrack(2); // play 2
    lockB = true; // set lock = true to lock it
    
    //turn off stop button
    digitalWrite(ledStop, LOW);

    //turn off other buttons
    digitalWrite(ledA, LOW);
    digitalWrite(ledC, LOW);
    digitalWrite(ledD, LOW);

    //reset locks for other buttons
    lockA = false;
    lockC = false;
    lockD = false;

    if(WaitForPrompt(10) == 0)
    {
      digitalWrite(ledB, LOW);
      lockB = false;
      digitalWrite(ledStop, HIGH);
    }
  }
  
  if(buttonValueC == HIGH && lockC == false)
  {
    digitalWrite(ledC, HIGH);
    selectTrack(3); // play 3
    lockC = true; // set lock = ture to lock it
    
    //turn off stop button
    digitalWrite(ledStop, LOW);

    //turn off other buttons
    digitalWrite(ledA, LOW);
    digitalWrite(ledB, LOW);
    digitalWrite(ledD, LOW);

    //reset locks for other buttons
    lockA = false;
    lockB = false;
    lockD = false;

    if(WaitForPrompt(10) == 0)
    {
      digitalWrite(ledC, LOW);
      lockC = false;
      digitalWrite(ledStop, HIGH);
    }
  }
  
  if(buttonValueD == HIGH && lockD == false)
  {
    digitalWrite(ledD, HIGH);
    selectTrack(4); // play 4
    lockD = true; // set lock = true to lock it
    
    //turn off stop button
    digitalWrite(ledStop, LOW);

    //turn off other buttons
    digitalWrite(ledA, LOW);
    digitalWrite(ledB, LOW);
    digitalWrite(ledC, LOW);

    //reset locks for other buttons
    lockA = false;
    lockB = false;
    lockC = false;

    if(WaitForPrompt(10) == 0)
    {
      digitalWrite(ledD, LOW);
      lockD = false;
      digitalWrite(ledStop, HIGH);
    }
  }
  
  if(buttonValueStop == HIGH /*&& lock == false*/)
  {
    digitalWrite(ledA, LOW);
    digitalWrite(ledB, LOW);
    digitalWrite(ledC, LOW);
    digitalWrite(ledD, LOW);
    digitalWrite(ledStop, HIGH);
    
    //stop playing songs
    mySerial.print("VST");
    mySerial.print(0x0D,BYTE);//send carriage return

    //reset locks
    lockA = false;
    lockB = false;
    lockC = false;
    lockD = false;
  }
}

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

  buttonValueStop = digitalRead(buttonStop);//read the status

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

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

  return(ErrCode);
  
  checkbuttons();
}

void loop() {

  //check the button input
  checkbuttons();  

  WaitForPrompt(10);

}

What the waitForPrompt did for me was when I played any clip of sound, it would keep checking over and over until the clip finished playing before breaking out of the loop.
In order to counter that, I placed my own checkButton function into the waitForPrompt, so that if a button is pressed it would exit the loop.
Logged

Pages: 1 2 3 [4]   Go Up
Jump to: