Wednesday, May 15, 2013

Play WAV files from SD card with Wise Clock 3/4 board

The video below shows another hack for Wise Clock 3/4, playing a WAV file directly (not using extra hardware) from SD card, with the help of the TMRpcm library.



The TMRpcm software uses the standard SD library (coming with Arduino IDE 1.0 and later) to read WAV files from SD card. To output the audio while buffering the content of the SD file, TMRpcm uses ISR triggered by internal timer. The buzzer/speaker can be connected only to certain pins of the processor. For ATmega1284/ATmega644 (used in Wise Clock 3/4), these pins are D3, D4, D12, D13, D14 and D15, as shown in the definition below (from sanguino core file pins_arduino.c).





















From the perspective of TMRpcm library, the buzzer in Wise Clock 4 is connected to the "wrong" pins, D22 and D23, which are not eligible for this trick. I chose to connect another speaker to pin D13, but that's already taken by the display (CS, pin 1). So I had to cut the trace from D13 to the display, and connect pin 1 of the display to D18 (another choice was D19, the only other available I/O left).

From now on it's only software.
  • modify this line in HT1632.cpp:
    #define HT1632_CS 18 //  Chip Select (pin 1 of display connector)
  • add line
     #define SPEAKER_PIN1  13


Then follow from step 4 of this previous post.

Unfortunately, this will not work with Wise Clock 4 software as is, and the main reason is the timer interrupts used by TMRpcm library, which disrupt the "SPI-like" commands for the display.

The video above may seem like another Wise Clock "app", but it is just a "cheating" sketch running standalone, shown below.


#include "Arduino.h"
#include "Wire.h"
#include "DS3231.h"
#include "HT1632.h"
#include "AlarmClock.h"
#include "WiseClock.h"
#include "SD.h"
#include "TMRpcm.h"
#define SD_ChipSelectPin   4
#define AudioPin          13  // must be PWM pin

TMRpcm tmrpcm;

//**********************
void setup()
{
  Serial.begin(9600);

  // disable JTAG (to use pin D18);
  uint8_t tmp = 1<
  MCUCR = tmp;
  MCUCR = tmp;

  ht1632_setup();

  SD.begin(SD_ChipSelectPin);
  tmrpcm.speakerPin = AudioPin;
}

//*********************
void loop()
{
  alarmClock.isAlarmEnabled = true;
  alarmClock.getTimeFromRTC();

  Serial.print("Time is: ");
  Serial.print(alarmClock.hour, DEC);
  Serial.print(":");
  Serial.print(alarmClock.minute, DEC);
  Serial.print(":");
  Serial.println(alarmClock.second, DEC);
  
  if (!tmrpcm.isPlaying())
  {
    ht1632_putTinyString(0, 0, "Playing", RED);
    wiseClock.displayTime(8, false);
    tmrpcm.play("dancing.wav");
  }
  delay(2000);
}

The display is statically updated once, before the WAV file starts playing.

It would probably be possible to update the display between playing short WAV files (with interrupts disabled right after each file is played). But that may open a door to other set of problems, since the display is practically frozen for the duration of the file playing. On the other hand, the I2C (through Wire library) works just fine (that's because I2C is hardware driven), so getting the current time from RTC while playing music is not an issue.

Conclusion
Although in theory would be possible to integrate TMRpcm library in the Wise Clock software (to play WAV files from SD card while the clock functionality is not affected), in practice that would take a lot of programming effort. A much easier and cheaper way to include audio into Wise Clock 4 (hardware and software) would be through the use of serially controlled audio-playback specialized modules, like this one (or maybe even the radio/MP3 module I reviewed here, if I ever find it in my pile of stuff).

2 comments:

  1. Replies
    1. :)
      That was the only WAV file I could find, on an old hard drive.

      Delete