Saltar al contenido principal
LibreTexts Español

14.1: Introducción

  • Page ID
    83177
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    Este ejercicio combina gran parte del trabajo anterior, a saber, detectar entrada digital, crear salida digital, cronometrar, etc. Un nuevo elemento importante es producir voltajes de salida analógicos sin recurrir a esquemas de modulación por ancho de pulso. Una vez terminado, tendremos un generador de formas de onda de baja frecuencia en funcionamiento con al menos tres formas de onda para elegir (seno, cuadrado y rampa con más formas de onda posibles) y frecuencia ajustable. La calidad del seno será al menos tan buena como la de los generadores típicos de función analógica (THD medido < 1%). Un ejercicio de esta magnitud cubrirá mucho terreno y tomará considerablemente más tiempo resolver problemas de software y cablear el hardware correspondiente. Un enfoque metódico del problema será invaluable.

    Empecemos con el concepto central de la síntesis digital directa. En lugar de usar osciladores analógicos, podemos hacer formas de onda alimentando valores de datos apropiados a un convertidor digital a analógico (DAC). Podemos obtener estos valores digitalizando una señal analógica o mediante cómputos. Cualquiera que sea la fuente de los datos, podemos almacenarlos en una matriz y enviarlos uno a la vez a un DAC. Una vez que llegamos al final de la matriz, volvemos al principio de la matriz y repetimos el proceso. Esta matriz generalmente se llama tabla de ondas. Teóricamente, dada una tabla lo suficientemente grande podemos reproducir cualquier ola que deseemos. La pregunta obvia entonces es ¿qué tan grande es lo suficientemente grande? Simplemente esto dependerá de la complejidad de la onda, la precisión deseada y otras consideraciones prácticas. Para algo así como una onda sinusoidal, se pueden obtener resultados de calidad razonables con unos cientos de valores de 8 bits. Para una calidad muy alta, se pueden usar unos pocos miles de valores de datos de 16 bits.

    Ante algo tan simple como una onda sinusoidal, surge la pregunta de por qué incluso nos molestamos con una tabla de ondas. Después de todo, podríamos calcular cada punto de datos directamente usando la función sin (). Si bien esto probablemente ahorraría algo de memoria (el código computacional ocupando menos espacio que la tabla de ondas), sería demasiado lento. El cálculo directo de datos de 8 bits usando la función sin () en el Arduino Uno requiere aproximadamente 140 microsegundos por punto de datos. Si la tabla de ondas contuviera solo 100 puntos esto conduciría a un periodo de 14 milisegundos, o una frecuencia máxima de solo 71 hercios. Por el contrario, acceder a los datos de una tabla precalculada y escribirlos en un puerto de salida toma una fracción de un microsegundo. Incluso con una tabla más grande podríamos lograr frecuencias de salida en el rango de kilohercios.

    Entonces, ¿cómo llenamos la mesa? Primero, por razones prácticas, las tablas de ondas suelen ser una potencia de dos en tamaño. 256 elementos es un tamaño agradable porque podemos usar un char sin signo para el índice y simplemente incrementarlo continuamente. Una vez que llegue a 255, el siguiente incremento provocará un desbordamiento y el valor vuelve a cero, eliminando así la necesidad de una prueba de límite. Si bien es posible calcular la tabla de ondas en la función setup (), eso consumirá algo de memoria. Es mejor hacerlo por separado. Aunque podríamos tomar una calculadora y producir los valores manualmente uno por uno, sería mucho más rápido escribir un pequeño programa que cree un simple archivo de texto. Luego podemos copiar y pegar esto en el programa C. Python es una buena opción para tal tarea de programación.


    This page titled 14.1: Introducción is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.