Mi hijo es un gran fan de los Simpsons (y supongo, soy yo). He creado como un regalo para él para la Navidad.
Lo que tenemos aquí es la caja de almuerzo de los Simpson que, cuando se presiona el interruptor rojo, jugarán al azar uno de 413 archivos wav que se almacenan en la tarjeta SD que se utiliza por el waveshield Adafruit.
Sigue un video de ella en uso.
Los materiales utilizados son:
-Arduino UNO
-Adafruit onda Shield Kit v1.1
-2GB SD card
-Caja de almuerzo Simpsons - de Amazon.com
-2 baterías de 9 voltios y 2 sostenedores - radio shack
-3 LEDs
-un altavoz de 8 ohm
-un interruptor DPDT
-un par de condensadores, resistencias y un LM386 chip para un pequeño amplificador, el sonido del protector de la onda no es lo suficientemente alto para el altavoz.
-Algunos cables
También usé un lector de tarjetas SD y un programa llamado Switch-it a descomprimir los archivos wav.
Pasos:
1. comprar un Arduino Uno - muchas fuentes para esto - aproximadamente $25,00
2. comprar un Kit de Adafruit Waveshield - cerca de las 22.00.
Esto debe ser montado y las instrucciones están aquí:
http://www.Ladyada.net/make/waveshield/make.html
(Estos son fáciles de seguir las instrucciones con muchas buenas fotos)
3. comprar una tarjeta SD de 2gb para ser utilizado en el protector de la onda
4. hice una búsqueda en internet para: "Simpson wav" y encontré un par de sitios que tenía una buena colección de fragmentos de archivo de wav de los Simpsons. Pude (con ayuda de mi hijo) Descargar más de 400 archivos y guardarlos en la tarjeta SD.
-Nota el protector de la onda no como archivos comprimidos así que algunos de los archivos necesarios para ser descomprimido que hice usando un software freeware llamado "Switch-it".
5. desde la salida de sonido del protector de la onda está muy bien para auriculares pero no era lo bastante fuerte como para que el altavoz, he enviado la salida del protector de la onda a un pequeño amplificador LM386 que construí utilizando las instrucciones siguientes.
http://www.rason.org/projects/icamps/icamps.htm
6. Añadido LEDs para indicar que está encendido (lado del interruptor) y para indicar cuándo es aceptable solicitar un nuevo archivo.
(Nota: he añadido una función que cuando se presiona el interruptor rojo cuando el LED verde está parpadeando, toda la onda se reproducirá archivos)
7. otras observaciones:
-básicamente el código espera a que el interruptor rojo ser presionado.
a continuación, genera un randow número entre 1 y 413 (el número de archivos). Entonces lee a través de los archivos de onda e incrementa un contador hasta que se alcance el número aleatorio. Luego juega con ese archivo. Esto significa que el número de archivos es difícil codificado en el código. Probablemente hay alguna manera que la figura de código cuántos archivos hay.
-a veces no puede reproducir un archivo creo que es porque también no le gusta archivos estéreo.
8. el código:
-copiados de diversas fuentes y lo indicado en el código. En concreto, empecé con el código que está en el sitio de Adafruit y modificado según sea necesario.
/*
trata de reproducir un archivo wav al azar cada vez que se pulse el botón
V2 intentando añadir botón y otro código
V2 funciona bien
V3 - añadir capacidad de reproducir todas las canciones manteniendo el botón pulsado durante el parpadeo
*/
#include
#include
Tarjeta SdReader; Este objeto contiene la información de la tarjeta
FatVolume vol; Contiene la información de la partición en la tarjeta
FatReader raíz; Esto contiene la información para el directorio de raíz de volúmenes
Ola WaveHC; Este es el único objeto (audio) de la onda, puesto que sólo jugaremos uno a la vez
dirLevel de uint8_t; aplicar sangría a nivel de nombres de archivo/dir (para prettyIndent)
dirBuf de dir_t; buffer para directorio lecturas
#define DEBOUNCE 5 / botón debouncer
const int buttonPin = 8; el número de pin pulsador
int buttonState = 0; variable para lectura del estado del pulsador
para el juego de rsndom
largo randNumber;
ct largo = 0;
necesarios para la reproducción de todas
playAll int = 0;
int numPress = 0; variable para lectura del estado del pulsador
xx int = 0;
firstTime mucho = 1;
hay que cambiar esto para igual numberr de archivos wav en tarjeta sd
numWavs largo = 413;
const int ledPin = 7; el número de los pines del LED
Va a cambiar las variables:
int ledState = alto; ledState permite configurar el LED
/*
* Definir macro para mensajes de error en memoria flash
*/
#define error(msg) error_P(PSTR(msg))
Definiciones de la función (definimos aquí, pero el código está a continuación)
juego vacío (FatReader & dir);
Esta práctica función devolverá el número de bytes actualmente libres en RAM, ideal para depuración!
int freeRam(void)
{
extern int __bss_end;
extern int * __brkval;
int free_memory;
Si ((int) __brkval == 0) {}
free_memory = ((int) & free_memory)-((int) & __bss_end);
}
Else {}
free_memory = ((int) & free_memory)-((int) __brkval);
}
volver free_memory;
}
//////////////////////////////////// SETUP
void setup() {}
Serial.Begin(9600); Biblioteca Serial a 9600 bps para la depuración
Si la clavija de entrada analógica 0 es análogo al azar,
ruido hará que la llamada a randomSeed() para generar
número de semillas diferentes cada vez que se ejecuta el bosquejo.
randomSeed() entonces se baraja la función aleatorizada.
randomSeed(analogRead(3));
inicializar el perno pulsador como entrada:
pinMode (buttonPin, entrada);
configurar el pin digital como salida:
pinMode (ledPin, salida);
digitalWrite(ledPin,HIGH);
putstring_nl ("\nWave test!"); decir que nos despertamos!
putstring ("memoria RAM libre:"); Esto puede ayudar con la depuración, es malo quedarse sin RAM
Serial.println(FreeRam());
Si (! card.init()) {//play con spi de 8 MHz (por defecto más rápido!)
error ("tarjeta init. no se pudo!"); Algo salió mal, permite imprimir por qué
}
permiten optimizar la lectura - algunas tarjetas pueden tiempo de espera. Desactivar si tienes problemas
card.partialBlockRead(true);
Ahora buscaremos una partición FAT!
parte de uint8_t;
para (parte = 0; parte < 5; parte ++) {/ / tenemos hasta 5 ranuras en
Si (vol.init (tarjeta, parte))
rotura; encontró uno, permite la libertad bajo fianza
}
Si (parte == 5) {/ / si terminamos por no encontrar uno :(
error ("No válida partición FAT!"); Algo salió mal, permite imprimir por qué
}
Permite decir que el usuario lo que encontramos
putstring ("partición de uso");
Serial.Print (parte, DEC);
putstring (", el tipo es grasa");
Serial.println(Vol.fatType(), DEC); ¿FAT16 o FAT32?
Intente abrir el directorio raíz
Si (! {root.openRoot(vol))}
error ("no puede abrir raíz dir!"); Algo salió mal,
}
¡ UF! Llegamos pasado las partes difíciles.
putstring_nl ("archivos encontrados (* = fragmentadas):");
Imprima todos los archivos en los directorios.
root.LS(LS_R | LS_FLAG_FRAGMENTED);
digitalWrite(ledPin,HIGH);
}
//////////////////////////////////// LOOP
void loop() {}
corto bucle durante 3 segundos la primera vez sólo
Si pulsa el botón más de una vez, [Coloque todas las ondas p
Serial.println (firstTime);
Delay(1000);
Si (firstTime == 1) {}
hacer
{
digitalWrite(ledPin,HIGH);
Delay(250);
digitalWrite(ledPin,LOW);
Delay(250);
numPress = digitalRead(buttonPin);
Si (numPress == HIGH) {}
playAll ++;
firstTime ++;
}
XX ++;
Serial.println (xx);
} y (xx < 10);
firstTime ++;
}
Serial.println (firstTime);
Serial.println (playAll);
Delay(1000);
leer el estado del pulsador valor:
buttonState = digitalRead(buttonPin);
digitalWrite(ledPin,HIGH);
comprobar si el pulsador está presionado.
Si es así, el buttonState es alta:
Si (buttonState == HIGH) {}
CT = 0;
reproducir un archivo wav es decir continuar con el código
digitalWrite(ledPin,LOW);
imprimir un número aleatorio de 1 a 60
randNumber = al azar (1, numWavs);
Serial.println(randNumber);
Delay(50);
root.Rewind();
Play(root);
}
Else {}
no hacer nada
}
}
/////////////////////////////////// HELPERS
/*
* imprimir mensaje de error y detener la
*/
void error_P (const char * str) {}
PgmPrint ("Error:");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/*
* imprimir mensaje de error y detener si error E/S SD, ideal para depuración!
*/
void sdErrorCheck(void) {}
Si (! card.errorCode()) retorno;
PgmPrint ("\r\nSD I/O error:");
Serial.Print(Card.ErrorCode(), hexagonal);
PgmPrint (",");
Serial.println(Card.errorData(), hexagonal);
while(1);
}
/*
* jugar a recursivamente - con desbordamiento de pila posible si subdirectorios anidados demasiado
*/
juego vacío {} (FatReader y dir)
Archivo FatReader;
mientras (dir.readDir(dirBuf) > 0) {/ / leer cada archivo en el directorio uno a la vez
Saltar si no un subdirectorio y no una. Archivo WAV
if (!. DIR_IS_SUBDIR(dirBuf)
& & strncmp_P ((char *) & dirBuf.name[8], PSTR("WAV"), 3)) {}
continuar;
}
Serial.println(); limpiar una nueva línea
para (uint8_t i = 0; i < dirLevel; i ++) {}
Serial.Write(' '); Esto es para prettyIndent, poner espacios en el frente
}
Si (! file.open (vol, dirBuf)) {/ / abrir el archivo en el directorio
error ("file.open fallado"); algo salió mal
}
Si (file.isDir()) {/ / comprobar si abrimos un nuevo directorio
putstring ("Subdir:");
printEntryName(dirBuf);
Serial.println();
dirLevel += 2; Añadir más espacios
reproducir archivos en el subdirectorio
Play(File); recursiva!
dirLevel-= 2;
}
Else {}
¡ Ajá! se encontró un archivo que no es un directorio
putstring ("jugando");
printEntryName(dirBuf); imprimir
¿Si (! wave.create(file)) {/ / la figura, es un WAV correcto?
putstring ("no un válido WAV"); OK saltarlo
} else {}
Serial.println();
¡ Hurra es un WAV correcto!
TC ++;
Serial.println(randNumber);
Serial.println(CT);
Aquí es donde tenemos el archivo
Quiero sin embargo solamente el un archivo wav que es seleccionado por el número aleatorio
Si ((randNumber == ct) || (playAll > 1)) {
Wave.Play();
hacer algo de ruido!
uint8_t n = 0;
mientras (wave.isplaying) {/ / reproducción ocurre en interrupciones, por lo que imprimimos puntos en tiempo real
putstring(".");
Si (! () ++ n % 32))Serial.println();
Delay(100);
}
digitalWrite(ledPin,HIGH);
}
sdErrorCheck(); ¿todo OK?
Si (wave.errors)Serial.println(wave.errors); ola errores de descodificación
}
}
}
}