Traje de la calabaza que habla (3 / 6 paso)

Paso 3: El código y archivos Wav

El código es de Adafruit y es respetables partes y ha sido modificado. He añadido un 4 º byte de botón y el sonido. Los bytes de sonido ha cambiado por mi propia y he cambiado los ojos de la ronda a triángulo.

Este Instructable asume que usted ya sabe cómo trabajar con arduino, (código de instalación, biblioteca, etc.)

EL CÓDIGO.

Puede copiar y pegar el siguiente código en el IDE de arduino o haga clic en el archivo.

Cara de calabaza disfraz
Este bosquejo se ha cambiado levemente de la original
Creador como se ve abajo. ¡ Disfrute!
sketch de ejemplo 'wavface' para Adafruit I2C mochilas de LED 8 x 8
y protector de la onda:
//
www.Adafruit.com/products/870 www.adafruit.com/products/1049
www.Adafruit.com/products/871 www.adafruit.com/products/1050
www.Adafruit.com/products/872 www.adafruit.com/products/1051
www.Adafruit.com/products/959 www.adafruit.com/products/1052
www.Adafruit.com/products/94
//
Requiere Adafruit_LEDBackpack, Adafruit_GFX bibliotecas y WaveHC
bibliotecas.
//
Este bosquejo muestra animación sincronizada aproximadamente a pregrabadas
discurso.  Es bastante complejo y puede ser abrumadora para novatos
programadores, que quieran empezar con el ejemplo 'matrix8x8'
y luego 'roboface' antes de trabajar a través de este código.  Además, mucho
de los comentarios relativos a la animación de la cara han sido despojados
aquí por brevedad... Consulte el dibujo de 'roboface' si usted tiene alguna
Preguntas Cómo funciona esa parte.
//
Hardware adicional necesario: sonidos se activan utilizando tres
botones momentánea normalmente abierto conexión a los pines digitales 6, 7, 8
y GND (e.g. www.adafruit.com/products/1009).
//
Adafruit invierte tiempo y recursos que este código de fuente abierto,
por favor apoye Adafruit y hardware de código abierto mediante la compra de
productos de Adafruit.
//
Escrito por P. Burgess por Adafruit Industries, piezas adaptaron de
'PiSpeakHC' bosquejo incluido con la biblioteca de WaveHC.
La licencia BSD, todo el texto anterior debe incluirse en cualquier redistribución.

#include < Arduino.h >
#include < Wire.h >
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include < WaveHC.h >
#include < WaveUtil.h >

Estos archivos WAV deben estar en el nivel raíz de la SD:
Char PROGMEM
wav0 [] = "HALLOW~1.wav",
wav1 [] = "LOOKIN~1.wav",
wav2 [] = "THISPM~1.wav",
wav3 [] = "TRKORTRT.wav", / / añadido esta línea 03/08/13
* wavname [] = {wav0, wav1, wav2, wav3};                                     wav3 añadido a esta línea 03/08/13
PROGMEM hace frecuentes apariciones a lo largo de este código, razón que
la biblioteca de la tarjeta de SD requiere montones de RAM precioso (dejando muy poco a
nuestro propio bosquejo).  PROGMEM nos permite poner datos fijos en la memoria flash de programa,
que es considerablemente más amplio.  Tablas de cadenas son paritcularly desagradable.
Consulte www.arduino.cc/en/Reference/PROGMEM para obtener más información.

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
Archivo FatReader; Este objeto representa el archivo WAV de una frase
Ola WaveHC; Un objeto de simple onda--sólo un sonido se juega a la vez
Macro para poner mensajes de error en memoria flash
#define error(msg) error_P(PSTR(msg))

Porque los dos ojos matrices comparten la misma dirección, sólo cuatro
objetos de la matriz son necesarios para la cinco muestra:
#define MATRIX_EYES 0
#define MATRIX_MOUTH_LEFT 1
#define MATRIX_MOUTH_MIDDLE 2
#define MATRIX_MOUTH_RIGHT 3
Adafruit_8x8matrix matriz [4]; Matriz de objetos Adafruit_8x8matrix

En lugar de asignar direcciones de matriz secuencialmente en un bucle, cada
tiene un lugar en esta matriz.  Esto hace más fácil si usted inadvertidamente
instalar una o más matrices en la posición física correcta-
volver a ordenar las direcciones en la tabla y todavía puede hacer referencia a
matrices de índice anterior, ningún otro código o cableado necesita cambiar.
const uint8_t PROGMEM matrixAddr [] = {0x70, 0x71, 0x72, 0x73};

PROGMEM de uint8_t const / / mapas de bits se almacenan en la memoria de programa
[blinkImg] [8] = {/ / ojo cuadros de animación
{B00000001, / / abra completamente el ojo
B00000011,
B00000111,
B00001111,
B00011111,
B00111111,
B01111111,
B11111111},
{B00000000,
B00000001,
B00000011,
B00000111,
B00001111,
B00011111,
B00111111,
B01111111},
{B00000000,
B00000000,
B00000001,
B00000011,
B00000111,
B00001111,
B00011111,
B00111111},
{B00000000,
B00000000,
B00000000,
B00000001,
B00000011,
B00000111,
B00001111,
B00011111},
{B00000000,
B00000000,
B00000000,
B00000000,
B00000001,
B00000011,
B00000111,
B00001111},
{B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000001,
B00000011,
B00000111},
{B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000001,
B00000011},
{B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000001},
{B00000000, / / cerrar completamente el ojo
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000}},
[mouthImg] [24] = {/ / boca de cuadros de animación
{B00000000, B00000000 B00000000, / / posición A la boca
B00000000, B00000000 B00000000,
B01111111, B11111111, B11111110,
B00000000, B00000000 B00000000,
B00000000, B00000000 B00000000,
B00000000, B00000000 B00000000,
B00000000, B00000000 B00000000,
B00000000, B00000000, B00000000},
{B00000000, B00000000 B00000000, / boca posición B
B00000000, B00000000 B00000000,
B00111111, B11111111, B11111100,
B00000111, B00000000, B11100000,
B00000000 B00000000, B11111111,
B00000000, B00000000 B00000000,
B00000000, B00000000 B00000000,
B00000000, B00000000, B00000000},
{B00000000, B00000000 B00000000, / boca de posición C
B00000000, B00000000 B00000000,
B00111111, B11111111, B11111100,
B00001000, B00000000, B00010000,
B00000110, B00000000, B01100000,
B00000001, B11000011, B10000000,
B00000000 B00000000, B00111100,
B00000000, B00000000, B00000000},
{B00000000, B00000000 B00000000, / boca de posición D
B00000000, B00000000 B00000000,
B00111111, B11111111, B11111100,
B00100000, B00000000, B00000100,
B00010000, B00000000, B00001000,
B00001100, B00000000, B00110000,
B00000011, B10000001, B11000000,
B00000000, B01111110, B00000000},
{B00000000, B00000000 B00000000, / / boca de posición E
B00000000 B00000000, B00111100,
B00011111, B11000011, B11111000,
B00000011, B10000001, B11000000,
B00000000 B00000000, B01111110,
B00000000, B00000000 B00000000,
B00000000, B00000000 B00000000,
B00000000, B00000000, B00000000},
{B00000000, B00111100, B00000000, / boca posición F
B00000000 B00000000, B11000011,
B00001111, B00000000, B11110000,
B00000001, B00000000, B10000000,
B00000000 B00000000, B11000011,
B00000000 B00000000, B00111100,
B00000000, B00000000 B00000000,
B00000000, B00000000, B00000000}};

Secuencias de animación correspondiente a cada WAV.  Primer número de
cada par es un índice de mapa de bits de la boca.  Segundo número es la bodega
tiempo (en frames).  final de 255 marcas de la lista.
Aquí no hay ninguna 'magia', el software no es derivando boca
posición del sonido... se determinaron las tablas a mano,
como animadores lo hacen.  Otra explicación aquí:
http://www.idleworm.com/how/ANM/03T/talk1.shtml

PROGMEM de uint8_t const
sec1 [] = {0, 2, 2, 5, 5, 3, 3, 7, / / "Feliz Halloween" / / conectarse a wav 0 arriba
4, 5, 3, 4, 2, 5, 4, 3, 255},


Sec2 [] = {0, 1, 3, 5, 1, 5, 4, 2, / / "Hay, ¿qué está mirando?"        conectado a wav 1 sobre
3, 2, 1, 2, 4, 4, 1, 3,
4, 2, 255}
sec3 [] = {0, 1, 1, 2, 3, 6, 2, 5, / / "que tiene dos pulgares y quiere dulces, esta calabaza" / conectado a wav 2 arriba
0, 1, 4, 4, 5, 2, 1, 5,
3, 6, 1, 4, 5, 3, 4, 2,
3, 6, 4, 2, 255},

seq4 [] = {3, 2, 2, 5, 5, 3, 3, 7, / / «Trick Or Treat"/ / conectarse a wav 3 anterior
4, 5, 255}

* anim [] = {sec1, Sec2, sec3, seq4};                                      seq 4 aquí ha añadido 03/08/13

uint8_t
[blinkIndex] PROGMEM = {1, 2, 3, 4, 3, 2, 1}, / / parpadear de secuencia de mapa de bits
blinkCountdown = 100, / / cuenta regresiva para el próximo parpadeo (en marcos)
gazeCountdown = 75, / / cuenta regresiva al próximo movimiento ocular
gazeFrames = 50, / / duración del movimiento de ojo (más pequeño = más rápido)
mouthPos = 0, / / número de boca de la imagen actual
mouthCountdown = 10 / / cuenta regresiva para la próxima boca cambio
newPos = 255, / boca nueva posición para el marco actual
* seq, / / actualmente está reproduciendo la secuencia de animación
IDX, / / corriente serie índice dentro de la secuencia de animación
prevBtn = 99, / botón pulsado en última iteración loop() #
btnCount = 0;   Número de iteraciones que se ha celebrado el mismo botón
int8_t
eyeX = 3, ojosos = 3, / / corriente ojo posición
newX = 3, newY = 3, / / ojo siguiente posición
dX = 0, dY = 0;   Distancia desde antes de la nueva posición

void setup() {}

Serial.Begin(9600);

PgmPrintln "(cara de WAV");

if(!Card.init()) error ("tarjeta init. no se pudo!");
if(!Vol.init(Card)) error ("no hay partición!");
if(!root.openRoot(vol)) error ("no pudo abrir dir");
PgmPrintln ("archivos encontrados:");
root.LS();

Semilla generador de números aleatorios de una entrada analógica no utilizada:
randomSeed(analogRead(A0));

Instanciar e inicializar cada objeto de matriz:
para (uint8_t i = 0; i < 4; i ++) {}
matriz [i] = Adafruit_8x8matrix();
matriz [i] .begin (pgm_read_byte (y matrixAddr[i]));
}

Habilitar las resistencias pull-up en cuatro (cambiado a cuatro) botón entradas.
Otro extremo de cada botón y se conecta a tierra.
para (uint8_t i = 6; i < = 9; i ++) {//i < = 8 a 9 8/3/13
pinMode (, entrada);
digitalWrite (i, alto); Activar subida
}
}

void loop() {}

uint8_t.

Empate del globo ocular en estado actual de la blinkyness (ningún alumno).
Matrix[MATRIX_EYES].Clear();
matriz [MATRIX_EYES] .drawBitmap (0, 0,
[blinkImg
¿(blinkCountdown < sizeof(blinkIndex))?      ¿Actualmente parpadea?
pgm_read_byte (& blinkIndex[blinkCountdown]): / / sí, ver # de mapa de bits
0 / / no, mostrar mapas de bits 0
], 8, 8, LED_ON);
Contador de centelleo de decremento.  En fin, fijar la hora al azar siguiente parpadeo.
Si (--blinkCountdown == 0) blinkCountdown = random (5, 180);

Si (--gazeCountdown < = gazeFrames) {}
Los ojos están en movimiento - dibujar la pupila en posición provisional
(.fillRect) matriz [MATRIX_EYES]
newX - (dX * gazeCountdown / gazeFrames),
newY - (dY * gazeCountdown / gazeFrames),
2, 2, LED_OFF);
¿if(gazecountdown == 0) {/ / último capítulo?
eyeX = newX; eyeY = newY; Sí.  Lo nuevo es viejo, entonces...
{/ / Selección de posiciones al azar hasta que uno está dentro del círculo del ojo
newX = random(7); newY = random(7);
dX = newX - 3;  dY = newY - 3;
} mientras que ((dX * dX + dY * dY) > = 10);      Gracias Pitágoras
dX = newX - eyeX;             Distancia horizontal para mover
dY = newY - eyeY;             Distancia vertical para mover
gazeFrames = random (3, 15);           Duración del movimiento de ojo
gazeCountdown = random (gazeFrames, 120); Cuenta al final del siguiente movimiento
}
} else {}
No en movimiento dibujar aún--pupila en posición estática actual
matriz [MATRIX_EYES] .fillRect (eyeX, ojosos, 2, 2, LED_OFF);
}

Botones de exploración de 6, 7, 8, 9 en busca de la primera tecla... agregó #9 8/3/13
para (i = 0; (< 4) & & (digitalRead(i+6) == HIGH); i++);                                  (< 3 cambiado a 4 8/3/13

¿if(i < 4) {/ / nada presionado?  ¡ Sí!                                 (< 3 cambiado a 4 8/3/13
¿if(i == prevbtn) {/ / igual que la última vez que lo comprobamos?  Buena!
Si (++ btnCount == 4) {/ / 3 pases para 'debounce' botón de entrada / / == cambió de 3 a 4
playfile ((char *) pgm_read_word(&wavname[i])); Inicio WAV
Ver animación secuencia # correspondiente a este WAV...
Seq = (uint8_t *) pgm_read_word(&anim[i]);
IDX = 0; Comenzar en el primer byte de datos
newPos = pgm_read_byte (& seq[idx++]); Posición inicial de la boca
mouthCountdown = pgm_read_byte (& seq[idx++]); Tiempo para la posición de espera
}
} else btnCount = 0; Otra tecla que antes - Inicio cuenta sobre
prevBtn = i;
} else prevBtn = 99;   Ningún botón pulsado

¿Si (newPos! = 255) {/ / es la boca en movimiento?
Si (--mouthCountdown == 0) {/ / cuenta regresiva marcos a la siguiente posición
newPos = pgm_read_byte (& seq[idx++]); Nueva posición de la boca
¿if(newpos == 255) {/ / el final de la lista?
mouthPos = 0;     Sí, ponga la boca en posición neutra
} else {}
mouthPos = newPos; Set boca a nueva posición
mouthCountdown = pgm_read_byte (& seq[idx++]); Tiempo de espera de lectura
}
}
} else mouthPos = 0; Boca no en movimiento, ponga en posición neutra

drawMouth(mouthImg[mouthPos]);

Actualizar todas las matrices en una sola pasada rápida
para (uint8_t i = 0; i < 4; i ++) matrix[i].writeDisplay();

Delay(20);
}

Dibujar la imagen de la boca a través de tres pantallas adyacentes
void drawMouth (uint8_t const * img) {}
para (uint8_t i = 0; i < 3; i ++) {}
matriz [MATRIX_MOUTH_LEFT + i].clear();
matriz [MATRIX_MOUTH_LEFT +] .drawBitmap (i * -8, 0, img, 24, 8, LED_ON);
}
}

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
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);
}

Abrir y empezar a reproducir un archivo WAV
void playfile (const char * nombre) {}
char nombre [13]; 8.3 + NUL

wave.stop() de if(Wave.IsPlaying); Detener cualquier WAV de reproduciendo actualmente

strcpy_P (nombre de archivo, nombre); Nombre de la copia de la PROGMEM en la RAM

Si (! file.open (raíz, nombre de archivo)) {}
PgmPrint ("no puede abrir archivo");
Serial.Print(FileName);
retorno;
}
{if(!Wave.Create(File))}
PgmPrintln ("no un válido WAV");
retorno;
}
Wave.Play();
}

Artículos Relacionados

Libro que habla de Steampunked

Libro que habla de Steampunked

Hi todo el mundoHa pasado mucho tiempo desde que escribí mi última instructable. Yo tenía mucho que ver con asuntos familiares.Pero ahora un nuevo proyecto está listo para ser presentado aquí. Se llama el "steampunked-hablar-libro".Este divertid
Bote de basura que habla

Bote de basura que habla

En el parque temático holandés ' de Efteling ' tienen una papelera parlante llamado Holle Bolle Gijs para más de 50 años! Para cumplir esto, hice una versión en casa de Gijs. Gijs está hecho de papel maché, cartón y acrílico pintura. Para la electrón
La mano de espíritu egipcio que habla

La mano de espíritu egipcio que habla

aquí es algo que hice hace unos años para una fiesta de Halloween de Cub Scout.  Los niños entran en una habitación tenuemente iluminada y se sientan en un semicírculo alrededor de una pequeña mesa que tiene una vieja caja supuestamente encontrada en
Cómo hacer una cabeza de Origami que habla

Cómo hacer una cabeza de Origami que habla

traído a usted de la empresa AHP, presentamos la cabeza hablando de Origami. O como nos gusta llamarlos, húmedo/Clammantha. Altamente le sugerimos hacer algunas con sus hijos y toda tu familia.-AH-HPPaso 1: Agarrar una tarjeta Agarrar una tarjeta nor
Cartulina K-9 controlado de Radio, que habla

Cartulina K-9 controlado de Radio, que habla

Doctor Who ha tenido muchos compañeros en los años, y cuando fans Haz preguntados "¿quién es tu favorito compañero Dr Who?", generalmente va escuchar respuestas como Rose Tyler, Sarah Jane Smith, el capitán jack Harkness, Leela y Jamie McCrimmon
Calabaza que talla las sierras

Calabaza que talla las sierras

tan! ¿Quiere patear la calabaza tallado juego encima de una muesca y probar su mano en uno de los complejos patrones de lujo? Bien por ti! ¡ Es fácil! Pero más allá de la meta de este Instructable. Una cosa que absolutamente necesita, sin embargo, es
OpenTrashCan: Una Internet inteligente con bote de basura que habla

OpenTrashCan: Una Internet inteligente con bote de basura que habla

OpenTrashCan se conecta a tu red wifi y le envía un correo electrónico cuando su totalidad, te habla e incluso puede ser controlado desde la App de OpenTrashCan para los teléfonos Android. Verlo en acción aquí:¿ Quiere comprar uno? Regístrate en la l
Caps Lock clave broma que habla

Caps Lock clave broma que habla

¿Conoces a alguien tipos con el Caps Lock en? ¿Cómo quieres modificar su teclado para que grita en ellos cuando pulse la tecla de Caps Lock? En este proyecto voy a mostrarle cómo hacerlo. Todo lo que tienes que hacer es un pequeño módulo de sonido de
Automatizado de cráneo que habla

Automatizado de cráneo que habla

Este instructable le mostrará cómo agregar un movimiento de la mandíbula a una calavera, calabaza u otros prop de vacaciones. Usé esta para hacer mi charla 3 eje cráneo en mi caldero de fluencia cuando un detector de movimiento. Este circuito no requ
Horneado y el pan de calabaza que hace (VIDEO)

Horneado y el pan de calabaza que hace (VIDEO)

este pan hace un gran regalo. El video es de unos 13 minutos de duración.Haga clic aquí para ver las fotosPan de calabazaAdaptado de muffins de calabaza de Smitten Kitchen(ingredientes secos)1 taza de harina para todo uso1/2 taza de harina de trigo i
Cabeza de Robot Animatronic que habla

Cabeza de Robot Animatronic que habla

(Robot concurso entrada categoría = 18 +)Este instructable es un parlante animatronic robot cabeza construí, que llamo Robot jefe 2.  Para tener una idea de la funcionalidad del Robot jefe 2, haga clic en el siguiente video corto o puede copiar y peg
Cráneo que habla

Cráneo que habla

Este cráneo habla dice lo que usted quiere (grabación un mensaje) yempieza a hablar cuando la cámara ve un color determinado (programar el color).Un Arduino convierte discurso (sobre la marcha) a movimientos de servo para la mandíbula. Una cámara de
Una vida de tamaño cabeza humanoide que habla

Una vida de tamaño cabeza humanoide que habla

Utilizando piezas de "off the shelf" para hacer una cabeza humana tamaño natural que se mueve de manera realista y se puede hacer para mover la boca sincronizada con sonido, o incluso manualmente mediante una palanca de mando. Total hardware cos
Monitor de ritmo cardíaco de Arduino que habla

Monitor de ritmo cardíaco de Arduino que habla

Mi pareja y yo quería hacer monitor de ritmo cardiaco que más que medir el pulso del usuario. Nuestras conversaciones de monitor de ritmo cardíaco. Cada botón hace una descripción verbal de su funcionalidad y hace que las medidas visibles en la panta