Saltar al contenido principal
LibreTexts Español

14.2: Parte Uno — Un generador de seno simple

  • Page ID
    83168
  • \( \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}}\)

    Aquí hay un programa corto de Python que creará una tabla sinusoidal para nosotros. Cada punto de datos es un carácter sin signo, por lo que van desde un mínimo de 0 hasta un máximo de 255 con un desplazamiento de CC efectivo de 128. Esto funcionará perfectamente con un sencillo DAC unipolar de 8 bits.

    # Python 3.3 wavetable creator for C language data array using unsigned bytes
    # 256 entry wave table, amplitude range is 0-255
    # Note: Rename array as needed
    
    import math
    
    fn = input("Enter name of the wavetable file to be created: ")
    fil = open( fn, "w+" )
    fil.write( "unsigned char sinetable[256]={" )
    
    for x in range( 256 ):
    
        # each data point is 1/256th of a cycle, peak value is 127
        f = 127.0 * math.sin( 6.28319 * x / 256.0 )
    
        # turn into an integer and add DC offset
        v = int( round( f, 0 ) ) + 128
    
        # guarantee no out-of-bounds values just in case
        if v > 255:
            v = 255
        if v < 0:
            v = 0
    
        if x < 255:
            fil.write( str(v) + ", " )
        else:
            fil.write( str(v) + "};" )
    
    fil.close()
    

    Para generar la tabla sinusoidal simplemente ejecutamos este programa, ingresamos un nombre de archivo apropiado cuando se le solicite, y literalmente esperar un segundo para que se procese. Luego abrimos el archivo resultante con un editor de texto y pegamos el contenido en el editor Arduino. Podemos usar este programa como plantilla para generar otras tablas de olas según sea necesario.

    Ahora que tenemos los datos de onda, ¿qué tipo de circuitos usaremos para el DAC? Obviamente, podemos usar un DAC de 8 bits listo para usar pero también podemos lograr resultados factibles mediante el uso de una simple red de escalera R-2R como se muestra en la Figura\(\PageIndex{1}\). R podría estar alrededor de 10 k haciendo\(\Omega\) así 2R 20 k\(\Omega\). Si bien la tolerancia de resistencia y las fluctuaciones de voltaje de salida del puerto agregarán algo de no linealidad, los resultados para datos de 8 bits son lo suficientemente buenos por ahora.

    Elija un valor apropiado para R y construya la red de escalera. Conecte las brocas al puerto D del Arduino Uno. El puerto D corresponde a los pines 0 (LSB) a 7 (MSB). La conexión de Salida Analógica debe ser monitoreada con un osciloscopio.

    clipboard_e9498bd8cb5c18567e024694c6699e53b.png

    Figura\(\PageIndex{1}\): Escalera R-2R

    El código para generar la onda sinusoidal es bastante sencillo, de hecho en realidad es bastante escaso. La mayor parte del espacio es ocupado por la matriz de datos. Aquí está la primera versión:

    unsigned char sinetable[256]={128, 131, 134, 137, 140, 144, 147, 150, 153, 
    156, 159, 162, 165, 168, 171, 174, 177, 179, 182, 185, 188, 191, 193, 196, 
    199, 201, 204, 206, 209, 211, 213, 216, 218, 220, 222, 224, 226, 228, 230, 
    232, 234, 235, 237, 239, 240, 241, 243, 244, 245, 246, 248, 249, 250, 250, 
    251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 254, 
    254, 254, 253, 253, 252, 251, 250, 250, 249, 248, 246, 245, 244, 243, 241, 
    240, 239, 237, 235, 234, 232, 230, 228, 226, 224, 222, 220, 218, 216, 213, 
    211, 209, 206, 204, 201, 199, 196, 193, 191, 188, 185, 182, 179, 177, 174, 
    171, 168, 165, 162, 159, 156, 153, 150, 147, 144, 140, 137, 134, 131, 128, 
    125, 122, 119, 116, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 77, 
    74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40, 38, 36, 34, 32, 30, 
    28, 26, 24, 22, 21, 19, 17, 16, 15, 13, 12, 11, 10, 8, 7, 6, 6, 5, 4, 3, 3, 
    2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 10, 11, 12, 
    13, 15, 16, 17, 19, 21, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 43, 45, 47, 
    50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77, 79, 82, 85, 88, 91, 94, 97, 100, 
    103, 106, 109, 112, 116, 119, 122, 125};
    
    void setup()
    {
          // set all of port D for output
          DDRD = 0xff;
    }
    void loop()
    {
          unsigned char u=0;
          unsigned char *p;
    
          p = sinetable;
    
          // loop forever
          while( 1 )
          {
                // set data and wait one sample period
                PORTD = p[u++];
                delayMicroseconds(100);
          }
    }
    

    El código primero establece todo el puerto D en modo de salida. La función loop () consiste en un bucle while () que nunca termina. Curiosamente, loop () no loop en absoluto, solo se ingresa una vez. El contenido de la función loop () podría colocarse fácilmente en la función setup () pero se colocan aquí simplemente como un medio para separar visualmente el código de inicialización del código de bucle.

    Se utiliza un puntero para identificar el inicio de la tabla de ondas. Estrictamente hablando esto no es necesario aquí ya que bien podríamos usar sinetable []. El motivo de esto se hará evidente en un momento. El primer valor de la matriz de tabla de ondas se copia al puerto D. La red de escalera transforma las ocho combinaciones de 0 voltios/5 voltios en una sola tensión. Observe la eficiencia de la escritura única en el puerto cuando se compara con la función orientada a bits digitalWrite () examinada anteriormente. Intentar escribir un solo bit a la vez crearía un completo desorden ya que los diversos bits no cambiarían todos juntos, sino que crearía siete valores incorrectos que conducen al valor correcto una vez que se hayan escrito los ocho bits. En cualquier caso, después de escribir el valor, el programa hace una pausa de 100 microsegundos. Este es el periodo muestral. Después de la pausa, el siguiente valor de matriz se copia en el puerto y el proceso se repite. Ignorando la sobrecarga de bucle y acceso/escritura, una sola pasada de la tabla requiere 256 entradas por 100 microsegundos cada una, o 25.6 milisegundos. Esta es una frecuencia de salida de aproximadamente 39 Hz.

    Ingresa el código, compila y transfiérelo al tablero. Conecte un osciloscopio a la conexión de salida analógica. Debería ver una onda sinusoidal de 39 Hz bastante agradable de aproximadamente 5 voltios pico a pico montando en una compensación de 2.5 voltios CC. Amplíe la base de tiempo para inspeccionar la ola. Los escalones individuales de la escalera R-2R deben ser evidentes. Además, el tiempo de 100 microsegundos por paso debería ser obvio.

    Podemos aumentar o disminuir la frecuencia ajustando el valor alimentado a la función delayMicroseconds (). Pruebe un valor más alto y vea lo que obtiene. 10 microsegundos deberían producir una frecuencia de aproximadamente 390 Hz. Usando esta frecuencia, mida el THD residual de la forma de onda. Con resistencias típicas del 5%, la distorsión armónica total probablemente será inferior al 1%. Una parte de esto se debe a la varianza de las resistencias, así como a que los voltajes de salida del pin del puerto no son todos idénticos.

    Se puede generar una forma de onda diferente y agregarse al programa. El único cambio al cuerpo del programa sería cambiar a lo que hace referencia el puntero p. Por ejemplo, podrías copiar y pegar la tabla sinusoidal, cambiar algunos de los valores por cantidades extremas para que sean obvios a la vista, y luego cambiar el nombre a algo así como wackysinetable []. Finalmente, cambia la referencia del puntero a p=wackysinetable; Prueba esto. Si está disponible, podría considerar conectar la salida a un amplificador pequeño y auriculares y escuchar la onda recién alterada. ¡Por qué, son horas de diversión para hacer! Llama a tu cónyuge/bf/gf/así, consigue a los niños o hermanos, agarra a los vecinos y da rienda suelta al perro; todos estarán de acuerdo en que es mucho mejor que ver otro programa de juegos tontos, series de “reality” o evangelista de televisión.


    This page titled 14.2: Parte Uno — Un generador de seno simple 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.