Code for WTV020SD Sound Card

I started porting code written for the Audio-Sound WTV020SD. The code was written for the Arduino but it seems to work well. I have run out of I/O ports and so can’t implement the chip reset. The code is stubbed out for someone else to mod to their content. You can get the chips on a breakout board off eBay but I used the Sparkfun board for this experiment. The SD card and sound file format are a bit of a hassle. I used a 2GB formatted with the utility from the SD Card Org site. To skip guessing my way through sound sample conversion I used samples from this site.

`
// Class for the sound board. It requires four I/O but I only had 2 left
class Wtv020sd16p {

_resetPin = null;
_clockPin = null;
_dataPin = null;
_busyPin = null;
_busyPinState = 0;

PLAY_PAUSE = 0xFFFE;
STOP = 0xFFFF;
VOLUME_MIN = 0xFFF0;
VOLUME_MAX = 0xFFF7;

constructor(clockPin, dataPin) {
_clockPin = clockPin;
_clockPin.configure(DIGITAL_OUT);
_clockPin.write(1); // Initialize clock high to avoid false reading data
_dataPin = dataPin;
_dataPin.configure(DIGITAL_OUT);
}

function reset() {
server.log(“Reset Sound”);
}

function playVoice(voiceNumber) {
sendCommand(voiceNumber);
server.log("Sync Played Voice " + voiceNumber);
}

function asyncPlayVoice(voiceNumber){
server.log("Async Playing Voice " + voiceNumber);
}

function stopVoice(){
sendCommand(STOP);
server.log(“Stopped Voice”);
}

function pauseVoice(){
sendCommand(PLAY_PAUSE);
server.log(“Paused Voice”);
}

function mute(){
sendCommand(VOLUME_MIN);
server.log(“Muted Voice”);
}

function unmute(){
sendCommand(VOLUME_MAX);
server.log(“Unmuted Voice”);
}

function sendCommand(command){
local iCommand = command.tointeger();
//Start bit Low level pulse.
_clockPin.write(0);
imp.sleep(0.020); // 20 milli seconds

for (local mask = 0x8000; mask > 0; mask = mask >> 1) {
  //Clock low level pulse.
  _clockPin.write(0);
  imp.sleep(0.000050); // 50 micro seconds
  //Write data setup.
  if (iCommand & mask) {
    _dataPin.write(1);
  }
  else {
    _dataPin.write(0);
  }
  
  //Write data hold.
  imp.sleep(0.000050); // 50 micro seconds

  //Clock high level pulse.
  _clockPin.write(1);
  imp.sleep(0.000100); // 100 micro seconds

  if (mask>0x0001){
    //Stop bit high level pulse.
    imp.sleep(0.002); // 2 milli seconds
  }
}
//Busy active high from last data bit latch.
imp.sleep(0.020); // 20 milli seconds

server.log("Sound Command Sent " + command);

}

}
`

Sounds like a good job for P3V3 or C3V0!

Many people are not familiar with the Electric Imp module, but it has 12 total I/O pins.

It looks like you’re bit banging serial data - you could likely simplify this class a fair bit by using on of the SPI busses.