In a nutshell, I am trying to change the voice of toys to a different language.
There are many toys I am hoping to change, but I am looking to re-purpose the:
Battery pack (often 3x AA batteries)
Built-in speaker
Inputs (buttons, switches)
I have a project which uses a prop shield LC, using the on board memory and audio outputs. I have imported duff's snooze library and Frank B's MP3 example. I have also lowered the clock speed to 24mHz. The aim is to have a longer lasting setup that can play audio files based on pin inputs. The project is outlined here.
I can get the code to work just fine playing files and pulling data from the prop shield while plugged into the USB, however once I unplug the usb and attach my power source (3x AA batteries in series) the teensy is unresponsive.
I was wondering if anyone has any ideas on how to proceed to use my power source of 3xAA batteries.
I have been looking at regulators, but again, the aim is to have a lot of standby time and be able to wake up and play an audio file simply, and I can't see anything that might be very efficient.
Any help greatly appreciated!
There are many toys I am hoping to change, but I am looking to re-purpose the:
Battery pack (often 3x AA batteries)
Built-in speaker
Inputs (buttons, switches)
I have a project which uses a prop shield LC, using the on board memory and audio outputs. I have imported duff's snooze library and Frank B's MP3 example. I have also lowered the clock speed to 24mHz. The aim is to have a longer lasting setup that can play audio files based on pin inputs. The project is outlined here.
I can get the code to work just fine playing files and pulling data from the prop shield while plugged into the USB, however once I unplug the usb and attach my power source (3x AA batteries in series) the teensy is unresponsive.
I was wondering if anyone has any ideas on how to proceed to use my power source of 3xAA batteries.
I have been looking at regulators, but again, the aim is to have a lot of standby time and be able to wake up and play an audio file simply, and I can't see anything that might be very efficient.
Any help greatly appreciated!
Code:
// Simple MP3 file player example
//
// https://forum.pjrc.com/threads/27059-MP3-Player-Lib-with-example?p=101537&viewfull=1#post101537
//
// Requires the prop-shield and Teensy 3.2 or 3.1
// This example code is in the public domain.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <play_sd_mp3.h> // https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib
#include <Bounce2.h>
#include <Snooze.h>
#include <SnoozeBlock.h>
#define PINTER_DELAY 2000
#define HIBERNATE_DELAY 300000
#define PROP_AMP_ENABLE 5
#define FLASH_CHIP_SELECT 6
//#define FLASH_CHIP_SELECT 21 // Arduino 101 built-in SPI Flash
// GUItool: begin automatically generated code
//AudioPlaySdWav playSdWav1; //xy=154,422
AudioPlaySdMp3 playMp31; //xy=154,422
AudioMixer4 mixer1; //xy=327,432
AudioOutputAnalog dac1; //xy=502,412
AudioConnection patchCord1(playMp31, 0, mixer1, 0);
AudioConnection patchCord2(playMp31, 1, mixer1, 1);
AudioConnection patchCord3(mixer1, dac1);
// GUItool: end automatically generated code
const char *sounds[] = {
"achest.mp3",
"afoot.mp3",
"ear.mp3",
"lfoot.mp3",
"rhand.mp3",
"hand.mp3"
};
bool buttons[33]; // create a symbol for every button
Bounce buttonsB[33]; // debounce handler for each button not excluded.
//
uint8_t exclude_buttons[] = { 6, 7, 10, 11, 12, 13 }; // exclude pins that may be required for communication or other
uint8_t switch_buttons[] = { 23, 24 };
// button 0 -> 33
void initButtonStates() {
for ( uint8_t i = 0; i < 33; i++ ) {
buttons[i] = false;
}
}
bool isSwitch(uint8_t b) {
uint8_t n = sizeof(switch_buttons);
for ( uint8_t i = 0; i < n; i++ ) {
if ( b == switch_buttons[i] ) {
return(true);
}
}
return(false);
}
bool excludedButton(uint8_t b) {
uint8_t n = sizeof(exclude_buttons);
for ( uint8_t i = 0; i < n; i++ ) {
if ( b == exclude_buttons[i] ) {
return(true);
}
}
return(false);
}
void setupBouncers(void) {
for ( uint8_t i = 0; i < 33; i++ ) {
if ( !excludedButton(i) ) {
buttonsB[i].attach( i , INPUT_PULLUP ); //setup the bounce instance for the current button
buttonsB[i].interval(10); // interval in ms
}
}
}
void buttonUpdates(void) {
// Update all the button objects
for ( uint8_t i = 0; i < 33; i++ ) {
if ( !excludedButton(i) ) {
buttonsB[i].update();
}
}
}
bool buttonSense(void) {
//
buttonUpdates();
//
bool hasActivity = false;
for ( uint8_t i = 0; i < 33; i++ ) {
if ( !excludedButton(i) ) {
bool bstate = ( buttonsB[i].read() == 0 );
bool bfell = buttonsB[i].fell();
if ( isSwitch(i) ) {
buttons[i] = bstate;
} else {
buttons[i] = bstate && bfell;
}
hasActivity = hasActivity || bstate;
}
}
//
return(hasActivity);
}
SnoozeDigital digital;
// install drivers to a SnoozeBlock
SnoozeBlock config(digital);
uint8_t wakeupPins[] = { 2, 4, 6, 7, 9, 10, 11, 13, 16, 21, 22, 26, 30, 33 };
void initWakeupPins(void) {
uint8_t n = sizeof(wakeupPins);
for ( uint8_t i = 0; i < n; i++ ) {
if ( !excludedButton(wakeupPins[i]) ) {
pinMode(wakeupPins[i], INPUT_PULLUP);
digital.pinMode(wakeupPins[i], INPUT_PULLUP, FALLING); // pin, mode, type
}
}
}
void setAmpliferState(bool ampEnableState) {
if ( ampEnableState ) {
digitalWrite(PROP_AMP_ENABLE, HIGH); // Enable Amplifier
} else {
digitalWrite(PROP_AMP_ENABLE, LOW); // Disable Amplifier
}
}
void init_amplifier(void) {
//Start Amplifier
pinMode(PROP_AMP_ENABLE, OUTPUT);
setAmpliferState(true);
}
void setup() {
//
// Configure the pushbutton pins for pullups.
// Each button should connect from the pin to GND.
initButtonStates();
setupBouncers();
//
initWakeupPins();
//
pinMode(LED_BUILTIN, OUTPUT);
//Serial.begin(9600);
while (!Serial);
AudioMemory(8); //4
delay(2000);
Serial.println("start...");
// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1) {
Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}
}
//Set Volume
mixer1.gain(0, 0.5);
mixer1.gain(1, 0.5);
init_amplifier();
Serial.println("ready...");
}
void playFile(const char *filename)
{
SerialFlashFile ff = SerialFlash.open(filename);
Serial.print("Playing file: ");
Serial.println(filename);
uint32_t sz = ff.size();
uint32_t pos = ff.getFlashAddress();
// Start playing the file. This sketch continues to
// run while the file plays.
playMp31.play(pos,sz);
// Simply wait for the file to finish playing.
/*
while (playMp31.isPlaying()) {
yield();
}
*/
}
// JUST A LITTLE CHANGE: Just put in the buttons on this one. But. It looks like the whole thing will delay until the file is done playing.
// That means the buttons should be useless until the sound is done.
// One way to fix that is to quit using the call to yield() above. Eliminate the loop.
// Again, the stops might have to be uncommented.
elapsedMillis gt_activityTimeout = 0;
bool activityTimeout(void) {
if ( gt_activityTimeout > HIBERNATE_DELAY ) {
return(true);
}
return(false);
}
void actvityRefreshTimer(void) {
gt_activityTimeout = 0;
}
void actvityWakeup() {
delay(PINTER_DELAY);
actvityRefreshTimer();
}
void triggerAwake(void) {
if ( !playMp31.isPlaying() ) {
if ( activityTimeout() ) {
digitalWrite(LED_BUILTIN, LOW);
Serial.println("going to sleep...");
setAmpliferState(false);
delay(100);
//Snooze.sleep( config );
Serial.print(gt_activityTimeout);
Serial.print(" ");
elapsedMillis timeout = 0;
Serial.println(gt_activityTimeout);
// bounce needs to call update longer than the debounce time = 5ms,
// which is set in constructor.
while (timeout < 10) buttonUpdates();
//
Snooze.hibernate( config );
//Snooze.sleep( config );
//
actvityWakeup();
setAmpliferState(true);
Serial.println("Woke up");
digitalWrite(LED_BUILTIN, HIGH);
}
// actually never really returns.
} else {
actvityRefreshTimer();
}
}
void loop() {
//
triggerAwake(); // block on sleeping so does not have to be boolean
if ( buttonSense() ) {
actvityRefreshTimer();
if ( buttons[0]) {
playFile(sounds[0]);
} else if ( buttons[1]) {
playFile(sounds[1]);
} else if ( buttons[2]) {
playFile(sounds[2]);
} else if ( buttons[3]) {
playFile(sounds[3]);
} else if ( buttons[4]) {
playFile(sounds[4]);
} else if ( buttons[5]) {
playFile(sounds[5]);
} else {
// no selections
}
}
//
}