2009-05-20 25 views
6

Si tuviera que programar un microcontrolador (ATMega128) para reproducir un tono real con un altavoz, ¿cómo lo haría?Cómo enviar sonido a un altavoz

¿Necesito usar un convertidor digital/analógico para enviar diferentes valores de amplitud, o es suficiente con los cambios de frecuencia? En cualquier caso, ¿cómo codificaré los valores de frecuencia y amplitud que el hablante necesita recibir? ¿Necesito algún tipo de multiplexación de frecuencia? No estoy hablando simplemente de hacer sonidos simples con el altavoz, como una nota y luego la otra. Quiero tocar una canción real, con todos los instrumentos, voces, etc.

Respuesta

0

Puedes echar un vistazo al open source MP3 player y ver cómo lo hacen. Supongo que necesitarás un convertidor D/A para producir un sonido de una calidad decente.

+0

Interesante proyecto, pero desafortunadamente él "externalizó" la parte de decodificación de sonido a un chip de un tercero: "El otro chip a bordo es un VS1011 de VLSI, Finlandia. Es un chip decodificador .mp3 y .wav, DAC, y un amplificador de auriculares todo en un paquete de 28 pines " Estoy después de hacerlo yo mismo, solo por el bien de aprender :) – palako

6

Asumiendo que tiene un 22,1   kHz 8 bits sin comprimir archivo de onda mono:

1) Franja de formularios de la cabecera
2) Cada 1/22100a segundo:
2.1) Leer 8 bits
2.2) Utilice un DAC para convertirlo en rango de tensión del orador
2.3) Envíalo al altavoz

Esto le dará [22.1   kHz/8 bits/mono] sonido de calidad y es una forma sencilla de reproducir muestras realistas .

Todo ese material de frecuencia es necesario para diferentes sintetizadores. El altavoz de la PC, por ejemplo, es efectivamente un bit. Para tener diferentes amplitudes (que 'ninguno' y 'máximo') pueden ser necesarios algunos trucos como la modulación de ancho de pulso (cambie las frecuencias, como dijo, para que el diafragma del orador tenga efectivamente más posiciones que dos).

Pero no necesita molestarse con eso. Todo lo que necesita hacer es emitir unas 22,100 o 44,200 muestras de sonido por segundo en el altavoz, digamos 8 o 16 bits por muestra para indicar la amplitud.

+0

Muy interesante. Entonces, de su respuesta, estoy asumiendo que un archivo WAV es en realidad una representación muy realista del sonido en sí mismo. Solo se trata de convertir el WAV a la señal analógica que representa. Voy a intentar esto. – palako

+2

La parte de DAC se puede lograr con una escalera (relativamente) simple R-2R. http://en.wikipedia.org/wiki/Resistor_Ladder. – Evansbee

+1

Depende del archivo WAV. El formato WAV en realidad puede contener audio comprimido: la especificación de formato completo está disponible aquí: http://msdn.microsoft.com/en-us/library/ms713497.aspx –

1

Si se siente particularmente creativo, puede construir su propio convertidor digital a analógico utilizando resistor ladder.

0

No tiene suficiente espacio en el ATMega128 para hacer algo demasiado elegante. La forma más fácil de conectar el altavoz (pequeña 2" o menos) se realiza a través de una resistencia. Verifique la capacidad de absorción de corriente de la salida y calcular R consecuencia.

---------------------- +V 
    | 
    \ 
    /R 
    \ 
    /   ---------- 
    |    | 
    | ------  | 
    ----| |-----| Microcontroller 
     / \  | 
     -------- | 
     Speaker --------- 

Por lo que respecta a los tonos que producen, conmutación básica de la salida producirá crapolla de sonido de stylaphone básico. Puede usar la modulación de ancho de pulso para producir aproximaciones de cualquier sonido analógico (demasiado complejo para entrar aquí y el AtMega probablemente no tendrá suficiente calada o almacenamiento). Este fue el método utilizado para hacer controladores de audio para PC sin tarjeta de sonido (solo el altavoz incorporado) en los buenos tiempos ...

2

Hoy en día, es fácil y barato reproducir archivos MP3 desde un microcontrolador de 8 bits. vice (una tarjeta SD, por ejemplo) y un chipset de MP3. Vea esto article por ejemplo. Puede encontrar muchos más en avrfreaks. Allí también puedes encontrar artículos para reproducir sonidos sin un chip externo.

Puede reproducir sonidos básicos con Pulse-width modulation (PWM), pero para una canción real necesitaría un DAC. He visto proyectos que reproducían archivos MP3 utilizando solo un DAC y un software, pero involucraban a los microcontroladores ARM más potentes.

0

Si está usando un Arduino, puede comprar el WaveShield de Lady Ada por $ 22 usd. Lady Ada ofrece muchos Arduino goodies vale la pena comprar. Algunos ejemplos son GPS, Ethernet y protectores de pasos/servos.

+0

No uso un arduino para este proyecto, solo el ATMega, ya que estoy interesado en implementarlo realmente, no en el resultado final. Pero mantengo ese sitio marcado para mis proyectos arduino, ¡gracias! – palako

4

He intentado algo similar. Primero, NO tendrá suficiente memoria en el microcontrolador para almacenar una canción real. Necesitará memoria externa para manejar eso. Eso significa usar una interfaz SPI para flash externo o EEPROM o algo así. SD también es bueno, creo que es una interfaz de estilo SPI. Existe un código para que los ATMegas se conecten a las tarjetas SD.

El segundo gran problema es obtener los datos en un formato adecuado. La forma en que lo haría es usar pulse-width modulation (PWM) para crear los niveles de voltaje variables. Creo que tienes un PWM de 16 bits en ese microcontrolador para que puedas tener una fidelidad de 16 bits en tu sonido. Si tiene problemas de espacio, puede usar PWM de 8 bits. Por lo tanto, sus datos de sonido deben estar en PCM de 8 o 16 bits, siendo 0x0000 el valor más bajo y 0xFFFF el más alto. Si desea música de alta fidelidad, tendrá que tener una frecuencia de muestreo de 44   KHz para obtener todos los buenos armónicos y demás. Creo que esto es PCM, lo mismo que se llama en la PC.

Entonces tendrá todos estos valores: durante cinco minutos de música tendrá 5 * 60 * 44000 = 13,200,000 valores de 16 bits que son 211,200,000 bits (211 megabits, 26.4 megabytes). Esos son sus requisitos de almacenamiento para los datos sin procesar. El MP3 es una posibilidad: hay chips externos para eso, pero aún tendrás grandes requisitos de espacio.

Por lo tanto, cada 1/44000a de segundo actualizará un valor en un registro PWM. Su frecuencia de PWM tendrá que ser mayor en 4 o 5, es decir, 5 ciclos de PWM por valor.

Ese es su algoritmo general - actualice los valores en un registro PWM y déjelo ir hasta el final. Necesitará al menos un filtro en la salida - limite las frecuencias al rango audible de 20KHz (más si es un audiófilo). Un filtro RC funcionará, pero yo elegiría un filtro activo PORQUE si está utilizando PWM, su rango de salida será de 0 a 5 V, generalmente con un voltaje promedio de aproximadamente 2.5V. Los altavoces no les gusta los niveles de CC, solo señales. Pretty ondas sinusoidales que tienen un voltaje medio de 0. Por lo tanto, su filtro activo tendrá que ajustar los niveles de voltaje y utilizar suministros duales para proporcionar voltajes negativos. También puede amplificar la señal para el gran bombeo de graves. Simplemente no apague sus parlantes.

MP3 es probablemente una mejor alternativa a PCM. Hay chips por ahí: http://www.sparkfun.com/commerce/product_info.php?products_id=8892

Eso es, sin embargo, un microcontrolador completo. Y ya tienes uno. Pero enfrentémoslo: el ATMega no va a hacer MP3 por sí mismo pronto, sin importar cómo lo animes.

Parece que el protector de ondas mencionado anteriormente básicamente hace esto: usa una tarjeta SD para el almacenamiento de PCM y un amplificador externo para el sonido. ¡Buena suerte!

+0

El enlace Sparkfun parece estar roto. –

2

Un método para generar un tono constante es Direct Digital Synthesis. Necesitarás un DAC, ya sea un chip dedicado o una escalera de resistencia.

Configura un contador para desbordamiento en la frecuencia que desea generar, y en cada tic del contador lo usa para indexar una tabla de ondas y obtener un valor de salida para su DAC.

He escrito un par de diferentes técnicas de generación de tonos para el Arduino aquí en New Noises From MidiVox. El código de actualización DAC es específico de MidiVox (y Adafruit WaveShield) MCP4921, pero la generación de onda sinusoidal debe ser generalmente aplicable.Intenté mantener el código en general general para ATmegas, pero hay un par de Arduino-ismos que se arrastraron.

Pegado de esa publicación, aquí hay un código para reproducir un tono de 440Hz en un Arduino con un MCP4921 en el bus SPI:

uint16_t sample = 0; 

/* incr = freq * (2^16/15625) 
* So for 440Hz, incr = 1845 */ 
uint16_t incr = 1845; 

/* oscillator position */ 
uint16_t pos = 0; 

const uint8_t sine[] = { 
    0x80, 0x83, 0x86, 0x89, 0x8C, 0x8F, 0x92, 0x95, 0x98, 0x9B, 0x9E, 0xA2, 
    0xA5, 0xA7, 0xAA, 0xAD, 0xB0, 0xB3, 0xB6, 0xB9, 0xBC, 0xBE, 0xC1, 0xC4, 
    0xC6, 0xC9, 0xCB, 0xCE, 0xD0, 0xD3, 0xD5, 0xD7, 0xDA, 0xDC, 0xDE, 0xE0, 
    0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEE, 0xF0, 0xF1, 0xF3, 0xF4, 
    0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 
    0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 
    0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF1, 
    0xF0, 0xEE, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 
    0xDA, 0xD7, 0xD5, 0xD3, 0xD0, 0xCE, 0xCB, 0xC9, 0xC6, 0xC4, 0xC1, 0xBE, 
    0xBC, 0xB9, 0xB6, 0xB3, 0xB0, 0xAD, 0xAA, 0xA7, 0xA5, 0xA2, 0x9E, 0x9B, 
    0x98, 0x95, 0x92, 0x8F, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 
    0x74, 0x71, 0x6E, 0x6B, 0x68, 0x65, 0x62, 0x5E, 0x5B, 0x59, 0x56, 0x53, 
    0x50, 0x4D, 0x4A, 0x47, 0x44, 0x42, 0x3F, 0x3C, 0x3A, 0x37, 0x35, 0x32, 
    0x30, 0x2D, 0x2B, 0x29, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18, 
    0x16, 0x15, 0x13, 0x12, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x08, 0x07, 
    0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 
    0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 
    0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x12, 0x13, 0x15, 
    0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29, 0x2B, 0x2D, 
    0x30, 0x32, 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x42, 0x44, 0x47, 0x4A, 0x4D, 
    0x50, 0x53, 0x56, 0x59, 0x5B, 0x5E, 0x62, 0x65, 0x68, 0x6B, 0x6E, 0x71, 
    0x74, 0x77, 0x7A, 0x7D 
}; 

void setup() { 
    cli(); 

    /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz, 
     this gives a timer interrupt at 15625Hz. */ 
    TIMSK2 = (1 << OCIE2A); 
    OCR2A = 127; 

    /* clear/reset timer on match */ 
    TCCR2A = 1<<WGM21 | 0<<WGM20; /* CTC mode, reset on match */ 
    TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20; /* clk, /8 prescaler */ 

    SPCR = 0x50; 
    SPSR = 0x01; 
    DDRB |= 0x2E; 
    PORTB |= (1<<1); 

    sei(); 
} 

ISR(TIMER2_COMPA_vect) { 
    /* OCR2A has been cleared, per TCCR2A above */ 
    OCR2A = 127; 

    pos += incr; 

    /* shift left a couple of bits for more volume */ 
    sample = sine[highByte(pos)] << 2; 

    PORTB &= ~(1<<1); 

    /* buffered, 1x gain, active mode */ 
    SPDR = highByte(sample) | 0x70; 
    while (!(SPSR & (1<<SPIF))); 

    SPDR = lowByte(sample); 
    while (!(SPSR & (1<<SPIF))); 

    PORTB |= (1<<1); 
} 

void loop() { 
} 

el Clou síntesis digital directa es que es muy fácil de jugar múltiples tonos juntos (por adición) o mezclarlas en volúmenes deseados (multiplicando por el volumen antes de añadir).

He encontrado que un Arduino puede reproducir unos 30 tonos simultáneamente con este método. Mi aplicación particular es para Hammond organ simulation, y eso también puede ser útil para la lectura.

Cuestiones relacionadas