Arduino library for WTV020-SD-16P audio module

xl97:
no need to change them? and they play same 'rate/speed'? awesome!..

glad things finally came together..

good luck!.

There is no need cause the Arduino is not managing WTV clock. Only clock provided from Arduino is to control the commands you send to it.

purgedsoul:

the-rebel-agent:
Why not use .stopVoice method?

Thank you for the reply.

I tried that too.

Even tried using pin change interrupts, thought maybe it just the delay in reading the digitalRead status for the pins.

Basically, what I wanted to achieve, is that whenever a button is pressed, it will interrupt the currently playing sound clip and play the sound clip associated with the button that was pressed (Even if it was the same button).

Here's the code I'm using:
I'm using the pinchangeint library.

/*

Example: Control a WTV020-SD-16P module to play voices from an Arduino board.
Created by Diego J. Arevalo, August 6th, 2012.
Released into the public domain.
*/

#include <Wtv020sd16p.h>
#include <PinChangeInt.h>

int resetPin = 2;  // The pin number of the reset pin.
int clockPin = 3;  // The pin number of the clock pin.
int dataPin = 4;  // The pin number of the data pin.
int busyPin = 5;  // The pin number of the busy pin.

#define BUTTON01  7
#define BUTTON02  8

/*
Create an instance of the Wtv020sd16p class.
1st parameter: Reset pin number.
2nd parameter: Clock pin number.
3rd parameter: Data pin number.
4th parameter: Busy pin number.
*/

Wtv020sd16p wtv020sd16p(resetPin,clockPin,dataPin,busyPin);

void playSound01(){
  wtv020sd16p.stopVoice();
  wtv020sd16p.playVoice(0);
}

void playSound02(){
  wtv020sd16p.stopVoice();
  wtv020sd16p.playVoice(1);

void setup() {
  //Initializes the module.

pinMode(BUTTON01, INPUT);
  digitalWrite(BUTTON01, HIGH);
  PCintPort::attachInterrupt(BUTTON01, &playSound01, RISING);
 
  pinMode(BUTTON02, INPUT);
  digitalWrite(BUTTON02, HIGH);
  PCintPort::attachInterrupt(BUTTON02, &playSound02, RISING);
 
  wtv020sd16p.reset();
}

void loop() {

}

Weird, cause If you check my previous video, that's what I am doing. Music is playing, I hit the trigger and plays a new sound. Even the fire selector plays it own sound. It should be there something wrong in the source code, not in the module.

can you post the code you used on the previous video? So i can try it on my board. I don't want to rule out another SD-Card problem, cause I have already tried several cards, before I got it to make a sound. :0 this thing is pesky with sd-cards. =(

Also, I tried playing a voice and have it loop, well, it can't do gapless loop.

@xl97: your board looks good, do you sell them cause I'm interested.

Shared it on gallery section. Look for v laser gun.

Thanks! Got it. XD This should keep me busy.

Well, it was definitely my code.

Anyone got ideas how to have this play a pseudo-gapless/seamless loop? Or this is just the limitation of this sound module.

Module limitation. It is a 20ms delay.

My module (v1.5) plays sounds only about 0.25sec from each file.
I have used library from this post (synch and asynch playing). SD card is 64MB FAT16.
I have downloaded ad4 and wav-files from this topic. Arduino Forum
Help me.

I had a similar problem with it only playing the first blip of the file. Here's what worked for me.
First, I had to use asyncPlayVoice, then add a delay equal or longer to the length of the file being played. This keeps the busy led on while the file is playing. I don't think I ever got PlayVoice to work, and it wouldn't play a file named 0000, the first one it would play was 0001.

My test program only played one file repeatedly, the delay just kept the loop from repeating and interrupting and restarting playing the file. I think I'll add a millis reading like the blink without delay example so the delay does not stop the program from running anything else waiting for the file to finish playing. This might get messy if there are a lot of files with different lengths. Unfortunately, I just fried my module tonight by absentmindedly hooking it up to 5V! Time to order a few more.

roan861:
My module (v1.5) plays sounds only about 0.25sec from each file.
I have used library from this post (synch and asynch playing). SD card is 64MB FAT16.
I have downloaded ad4 and wav-files from this topic. Arduino Forum
Help me.

It seems to me that your sd card is not supported

DerekD:
I had a similar problem with it only playing the first blip of the file. Here's what worked for me.
First, I had to use asyncPlayVoice, then add a delay equal or longer to the length of the file being played. This keeps the busy led on while the file is playing. I don't think I ever got PlayVoice to work, and it wouldn't play a file named 0000, the first one it would play was 0001.

My test program only played one file repeatedly, the delay just kept the loop from repeating and interrupting and restarting playing the file. I think I'll add a millis reading like the blink without delay example so the delay does not stop the program from running anything else waiting for the file to finish playing. This might get messy if there are a lot of files with different lengths. Unfortunately, I just fried my module tonight by absentmindedly hooking it up to 5V! Time to order a few more.

Syncplay usually works better with long audio files.

For easy testing , load the microSD with sample .AD4 files provided in other links. Make sure to format the uSD to 16bit . Power WTV020 pin 16 & 8. I would just touch pin 9 or pin 13 to ground for playing the file. Touch pin 1 to reset the chip. The audio output is very low power. I used a speaker from a cell phone to pins 4 & 5 and held it really close to my ear to hear it. Once you get some confidence the sound files are working, you can add a LM386 amplifier, or I bought a 12V 15W amp module on ebay for $6. After that can build on more controls functions. I also found the WTV020 cant really do MP3 mode unless you specifically buy it that way. Strangely I can force the WTV020 to operate like MP3 mode by interfacing with TTL gates or dry relay contact for a trigger. Using optocouplers or soliud state relays just didnt cut the cheese.
http://arduino.cc/forum/index.php/topic,115411.0.html more info here

Hello:

I've been playing with rhe sound module i bouught in sparkfun. I've allready been able to make it work with a 2gb sd. As i use an arduino UNO i atached two serial diodes between the arduino and the module. I firstly conected the way i tough i was the correct one but it didn't work.
I made a test making it work as an mp3 and seen that it played sounds i conected the cables "upsidedown". the diagram i'm now using is the one seen in the image. I wanted to ask if this is normal as until what i know the diodes are not in the correct way like this...but is the way it works...if someone has an explanation...

thanks a lot!

You do not use the diodes in the signal lines from the arduino to the RST/Din/Dclk lines. You need them in the vcc+ to the sound module to reduce the voltage to 3.3 vdc.

Even not needing them for the signals i don't think it is a good idea to use 5v signals for a 3.3V working peripheral no? I'm not sure of it as the datasheet of this chip is the worst i've ever seen...there is a lot of information missing there.

Although not needing the diodes for signal i've use the the way shown in the image i posted...and i can't understand the reason for them to work with that polarization...if someone could explain the reason i'll be very pleased

thanks a lot!

Here is my example of a Star Wars Blaster with 8 RGB LEDs, 3 74HC595 shift registers and the WTV020-SD-16P sound card. The sound files are from onesky.

74HC595 shift registers wiring: http://www.arduino.cc/en/Tutorial/ShiftOut

//  Name    : Blaster4                                          //
//  Author  : Norman McGuffey                                   //
//  Date    : 16 Feb 2013                                       //
//  Version : 1.0                                               //
//  Notes   : Code for using 3 74HC595 Shift Registers with     //
//          : 8 - 5mm Superbright CC RGB LEDs on E-11 Blaster   //
//          : Sound using WTV020-SD-16P microSD audio module    //

int resetPin2 = 2;  // Pin D2 connected to WTV20 /Reset (Pin 1)
int clockPin2 = 3;  // Pin D3 connected to WTV20 P04 (clock)(Pin 7)
int dataPin2 = 4;   // Pin D4 connected to WTV20 P05 (data)(Pin 10)
int button1Pin = 6; // Pin D6 connected to Trigger Switch
int button2Pin = 7; // Pin D7 connected to Select Switch
int latchPin = 8;   // Pin D8 connected to ST_CP (PIN 12)of 74HC595
int dataPin = 11;   // Pin D11 connected to DS (PIN 14) of 74HC595
int clockPin = 12;  // Pin D12 connected to SH_CP (PIN 11)of 74HC595
int LEDPin = 13;    // Pin D13 connected to LED
int button1State = 0;
int button2State = 0;
int button2Count = 1;

const unsigned int VOLUME_0 = 0xFFF0;
const unsigned int VOLUME_1 = 0xFFF1;
const unsigned int VOLUME_2 = 0xFFF2;
const unsigned int VOLUME_3 = 0xFFF3;
const unsigned int VOLUME_4 = 0xFFF4;
const unsigned int VOLUME_5 = 0xFFF5;
const unsigned int VOLUME_6 = 0xFFF6;
const unsigned int VOLUME_7 = 0xFFF7;

const unsigned int PLAY_PAUSE = 0xFFFE;
const unsigned int STOP = 0xFFFF;

byte dataRED;
byte dataGREEN;
byte dataBLUE;
int dataArrayRED[] = {1,8,64,0,0,0,0,0,0};
int dataArrayGREEN[] = {0,0,0,2,16,128,0,0,0};
int dataArrayBLUE[] = {0,0,0,0,0,0,4,32,0};


void setup() {
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
  pinMode(resetPin2, OUTPUT);
  pinMode(LEDPin, OUTPUT);
  
  digitalWrite(clockPin2, HIGH);
  digitalWrite(dataPin2, LOW);

  pinMode(latchPin, OUTPUT);
  pinMode(button1Pin, INPUT);
  pinMode(button2Pin, INPUT);
  
  digitalWrite(resetPin2, HIGH);
  delay(100);
  digitalWrite(resetPin2, LOW);
  delay(10);
  digitalWrite(resetPin2, HIGH);
  delay(100);
  delay(500);
  sendCommand(0xFFF6);
 
  digitalWrite(LEDPin, HIGH);
  delay(50);
  digitalWrite(LEDPin, LOW);
  
  Serial.begin(9600);

}

void loop() {

  button2State = digitalRead(button2Pin);
  if (button2State == HIGH) {
    sendCommand(0x000);
    button2Count = button2Count +1;
    if (button2Count > 5) {
      button2Count = 1;
    } 
    for (int x=0; x < button2Count; x++){
       digitalWrite(LEDPin, HIGH);
       delay(100);
       digitalWrite(LEDPin, LOW);
       delay(200); 
    } 
    delay(500);
    }
  
  button1State = digitalRead(button1Pin);
  
  if (button1State == HIGH) {    
   switch (button2Count) {
   case 1:
      { // Color = Red
      sendCommand(0x001);
      int dataArrayRED[] = {1,8,64,0,0,0,0,0,0};
      int dataArrayGREEN[] = {0,0,0,2,16,128,0,0,0};
      int dataArrayBLUE[] = {32,32,32,32,32,32,36,32,0};
      for (int j = 0; j < 9; j++) {
         dataRED = dataArrayRED[j];
         dataGREEN = dataArrayGREEN[j];
         dataBLUE = dataArrayBLUE[j];
         digitalWrite(latchPin, 0);
         shiftOut(dataPin, clockPin, dataBLUE);
         shiftOut(dataPin, clockPin, dataGREEN);   
         shiftOut(dataPin, clockPin, dataRED);
         digitalWrite(latchPin, 1);
         delay(60);}
       break;}
  case 2:
       { // Color = Blue
       sendCommand(0x002);
       int dataArrayRED[] = {4,32,0,0,0,0,0,0,0};
       int dataArrayGREEN[] = {0,0,1,8,64,0,0,0,0};
       int dataArrayBLUE[] = {128,128,128,128,128,130,144,128,0};
       for (int j = 0; j < 9; j++) {
         dataRED = dataArrayRED[j];
         dataGREEN = dataArrayGREEN[j];
         dataBLUE = dataArrayBLUE[j];
         digitalWrite(latchPin, 0);
         shiftOut(dataPin, clockPin, dataBLUE);
         shiftOut(dataPin, clockPin, dataGREEN);   
         shiftOut(dataPin, clockPin, dataRED);
         digitalWrite(latchPin, 1);
         delay(100);}
       break;}
    case 3:
       { // Color = Green
       sendCommand(0x003);
       int dataArrayRED[] = {2,16,128,0,0,0,0,0,0};
       int dataArrayGREEN[] = {0,0,0,4,32,0,0,0,0};
       int dataArrayBLUE[] = {64,64,64,64,64,65,72,64,0}; 
       for (int j = 0; j < 9; j++) {
         dataRED = dataArrayRED[j];
         dataGREEN = dataArrayGREEN[j];
         dataBLUE = dataArrayBLUE[j];
         digitalWrite(latchPin, 0);
         shiftOut(dataPin, clockPin, dataBLUE);
         shiftOut(dataPin, clockPin, dataGREEN);   
         shiftOut(dataPin, clockPin, dataRED);
         digitalWrite(latchPin, 1);
         delay(90);}
       break;}
    case 4:
       { // Color = Purple
       sendCommand(0x004);
       int dataArrayRED[] = {5,40,64,0,0,0,0,0,0};
       int dataArrayGREEN[] = {0,0,1,10,80,128,0,0,0};
       int dataArrayBLUE[] = {160,160,160,160,160,162,180,160,0};
         for (int j = 0; j < 9; j++) {
         dataRED = dataArrayRED[j];
         dataGREEN = dataArrayGREEN[j];
         dataBLUE = dataArrayBLUE[j];
         digitalWrite(latchPin, 0);
         shiftOut(dataPin, clockPin, dataBLUE);
         shiftOut(dataPin, clockPin, dataGREEN);   
         shiftOut(dataPin, clockPin, dataRED);
         digitalWrite(latchPin, 1);
         delay(90);}
       break;}
    case 5:
       { // Color = Orange
       sendCommand(0x005);
       int dataArrayRED[] = {3,24,192,0,0,0,0,0,0};
       int dataArrayGREEN[] = {0,0,0,6,48,128,0,0,0};
       int dataArrayBLUE[] = {96,96,96,96,96,97,108,96,0};
       for (int j = 0; j < 9; j++) {
         dataRED = dataArrayRED[j];
         dataGREEN = dataArrayGREEN[j];
         dataBLUE = dataArrayBLUE[j];
         digitalWrite(latchPin, 0);
         shiftOut(dataPin, clockPin, dataBLUE);
         shiftOut(dataPin, clockPin, dataGREEN);   
         shiftOut(dataPin, clockPin, dataRED);
         digitalWrite(latchPin, 1);
         delay(75);}
       break;}
   }
  }
}

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {

  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);
 
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);
  
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);
    
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }
    digitalWrite(myDataPin, pinState);
    digitalWrite(myClockPin, 1);
    digitalWrite(myDataPin, 0);
  }
    digitalWrite(myClockPin, 0);
}

void blinkAll_3Bytes(int n, int d) {
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
  delay(200);
  for (int x = 0; x < n; x++) {
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 1);
    digitalWrite(latchPin, 1);
    delay(50);
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    digitalWrite(latchPin, 1);
    delay(200);
  }
}
void sendCommand(int addr)
{
  digitalWrite(clockPin2, LOW);
  delay(2);
  for (int i=15; i>=0; i--)
  { 
    delayMicroseconds(200);
    if((addr>>i)&0x0001 >0)
      {
        digitalWrite(dataPin2, HIGH);
       }
    else
       {
         digitalWrite(dataPin2, LOW);
       }
    delayMicroseconds(200);
    digitalWrite(clockPin2, HIGH);
    delayMicroseconds(200);
    
    if(i>0)
    digitalWrite(dataPin2, LOW);
    else
    digitalWrite(dataPin2, HIGH);
    delayMicroseconds(200);
    
    if(i>0)
    digitalWrite(clockPin2, LOW);
    else
    digitalWrite(clockPin2, HIGH);
  }
  delay(30); 
}

chathuranga:
Hi the-rebel-agent,

Hats off for sharing your experience :slight_smile:

I am going to play with the same module but decided to ask and get the pin diagram confirmed. I found the following application circuit for this device.

I believe the following is the way of identifying the pins. Can you please confirm? :slight_smile:

/Chathuranga

Yes, the way of identifying the pins is right----waytronic -Jasmine. Manufacturer of WTV020-SD module

chathuranga:
Nice Stuff :slight_smile:

I will add my findings etc when I continue with my experiments. I am about to start :slight_smile:

The Datasheet says the maximum supported size of the Card is 1GB. Is that so or could you be able to use a card with higher capacity? I cannot imagine a reason of limiting the size at 1 GB because generally the address spaces are larger than that.. :~

acctually it can support 2 GB,we have tested 2GB TF card,same use with 1GB TF card.some times manual will have something wrong,and we will revise them when we discover them.and welcome every one to help us point out them.

foxbau:
I just got from China a board : V1.5 / 2012.01.12", and "5v / 3.3v

The only successfully way to format my Nokia mirco SD 512 MB
was win / cmd(Admin) / diskpart .
( http://www.chip.de/bildergalerie/Windows-To-Go-So-laeuft-Windows-8-auf-USB-Sticks-und-Festplatten-Galerie_54926063.html)

Up to now I run the board stand alone.
OK Files:

  • 000X.ad4
  • 000x.wav freq 12.000 Mono and -1dB

It is possible to run MP3 im stand alone modus ?

WTV020-SD module only can play WAV and AD4 file

djole_ru:
Hello!
I have a question!
How to manually change modes on vtv020-sd-16p,all ekys are on/off(loop),key 5 group of voice...
Thanks!!!

I want to ask which control mode module do you use?for example ,If you buy 2-wire series mode can not us key 5 group of voice,control mode is fixed when we program main chip,and you need tell supplier what you want,i think they will give you correct control mode module.