Saltar al contenido principal
LibreTexts Español

6.3: Codificación

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

    Ordinariamente, todo el código estará contenido dentro de un solo archivo. Cuando creas un nuevo proyecto, o “sketch” en Arduino, se creará un nuevo directorio para ello. A diferencia de los archivos fuente del lenguaje C ordinario, los bocetos de Arduino utilizan una extensión “.ino” en lugar de “.c”. Además, no se utiliza el punto de entrada normal main (). En esencia, el sistema Arduino ya ha escrito main () para ti y se ve algo así:

    void main()
    {
          init();
    
          setup();
    
          while(1)
                loop();
    }
    

    La primera llamada a la función es donde ocurren diversas inicializaciones del sistema como la asignación y preajuste de temporizadores, el sistema ADC, etc. Esto ya ha sido escrito para usted. Las otras dos llamadas, setup () y loop (), son para que escribas. setup () es tu propia función de inicialización (es decir, cosas que necesitas hacer solo una vez al inicio) y loop () es la porción a la que se llamará repetidamente. Por lo que normalmente comienzas a codificar con algo que se parece a la primera figura, arriba.

    Uno de los problemas con la programación integrada es que no tienes una consola para entrada y salida a través de scanf () y printf (). Normalmente, un programa embebido no los necesitará pero son muy útiles a la hora de depurar un programa. Sin printf (), ¿cómo puedes insertar puntos de prueba en tu código para verificar progreso, valores, etc? Una técnica es simplemente flashear un LED en puntos específicos del programa. Las placas Arduino incluyen un pequeño LED en uno de los puertos para este propósito. Si bien esto es útil, es limitado, por lo que una segunda y más poderosa técnica implica la comunicación bidireccional con la computadora host. En el Arduino, esto se hace a través de la biblioteca Serial. El IDE incluye un monitor serie bajo el menú de herramientas. Al seleccionar esto, se abrirá una pequeña ventana. Se puede utilizar para enviar datos a la placa o enviar datos de la placa de nuevo a la computadora host.

    Veamos un ejemplo de comunicación a través del Monitor Serial. Primero, consideremos escribir datos desde el tablero de nuevo al host. Aquí tienes un programa “Hola Mundo”.

    void setup()
    {
          Serial.begin(9600);
    }
    
    void loop()
    {
          Serial.print("Hello World\n");
          delay( 1000 );   
    }
    

    En la función de configuración abrimos la biblioteca serial y establecemos la velocidad de comunicación a 9600 baudios (velocidad más o menos estándar para el Arduino) usando la función serial.begin (). Hay una función serial.end () complementaria si decide que necesita los pines de puerto particulares que se utilizan para la comunicación en serie para otros fines más adelante. Tenga en cuenta que todas las llamadas a funciones en esta biblioteca comenzarán con el nombre de la biblioteca. Las funciones loop () escriben nuestro mensaje usando serial.print () y luego espera aproximadamente un segundo usando la función delay (), cuyo argumento se mide en milisegundos. Una vez hecho esto, el flujo del programa vuelve a main (). Por supuesto, main () simplemente se repite en la función loop () por lo que vuelve a llamarla. Nuestro mensaje se imprime por segunda vez, tercera vez y así sucesivamente.

    Ingresa el bit de código anterior, compila y descárgalo al destino. Una vez hecho esto, abre el Monitor Serial y mira la salida. Cada segundo deberías ver el mensaje “Hola Mundo” impreso de nuevo. Eso es todo lo que hace el programa controlador. Aquí no es demasiado útil por sí solo, pero el poder de imprimir artículos de vuelta al anfitrión será muy útil una vez que nos pongamos en marcha.

    Acostúmbrate a usar la documentación en línea. Dos buenos lugares para comenzar son la página de referencia en http://arduino.cc/en/Reference/HomePage y la página Tutorial en http://arduino.cc/en/Tutorial/HomePage La página de referencia incluye información sobre todos los operadores y funciones integradas en el sistema Arduino. El Tutorial da información sobre conceptos e ideas de programación. Por ejemplo, aquí hay una copia de la documentación en línea de la función.print ():

    6.3.1: Serial.print ()

    Descripción

    Imprime los datos en el puerto serie como texto ASCII legible por humanos. Este comando puede tomar muchas formas. Los números se imprimen usando un carácter ASCII para cada dígito. Los flotadores se imprimen de manera similar como dígitos ASCII, por defecto con dos decimales. Los bytes se envían como un solo carácter. Los caracteres y las cadenas se envían tal cual. Por ejemplo:

    • Serial.print (78) da “78"
    • Serial.print (1.23456) da “1.23"
    • Serial.print ('N') da “N”
    • Serial.print (“Hola mundo.”) da “Hola mundo”.

    Un segundo parámetro opcional especifica la base (formato) a usar; los valores permitidos son BIN (binario o base 2), OCT (octal o base 8), DEC (decimal o base 10), HEX (hexadecimal o base 16). Para los números de coma flotante, este parámetro especifica el número de decimales a utilizar. Por ejemplo:

    • Serial.print (78, BIN) da “1001110"
    • Serial.print (78, OCT) da “116"
    • Serial.print (78, DEC) da “78"
    • Serial.print (78, HEX) da “4E”
    • Serial.println (1.23456, 0) da “1"
    • Serial.println (1.23456, 2) da “1.23"
    • Serial.println (1.23456, 4) da “1.2346"

    Puede pasar cadenas basadas en memoria flash a serial.print () envolviéndolas con F (). Por ejemplo:

    • Serial.print (F (“Hola Mundo”))

    Para enviar un solo byte, utilice serial.write ().

    Sintaxis

    Serial.Imprimir (val)
    Serial.Imprimir (val, formato)

    Parámetros

    val: el valor a imprimir - cualquier tipo de datos

    format: especifica la base numérica (para tipos de datos integrales) o el número de posiciones decimales (para tipos de coma flotante)

    Devoluciones

    size_t (long): print () devuelve el número de bytes escritos, aunque leer ese número es opcional

    /**** fin del material de referencia copiado ****/

    Lo bueno de esta función es el segundo argumento opcional que permite especificar información de formato. La capacidad de imprimir valores en hexadecimal y binario es particularmente útil, por ejemplo, al examinar campos de bits. Modifique su programa para que aparezca de la siguiente manera, compile, descargue y ejecútelo:

    void setup()
    {
          int i = 27; // try different values for this
    
          Serial.begin(9600);
    
          // println is just print with an added newline character
          Serial.println(i, DEC);
          Serial.println(i, BIN);
          Serial.println(i, HEX);
    }
    
    void loop()
    {
          // nothing to do here  
    }
    

    Menos común pero aún útil de vez en cuando cuando la depuración es la capacidad de pasar valores al programa en ejecución. La ventana Serial Monitor incluye un pequeño campo de entrada de datos en la parte superior con un botón Enviar asociado. Las funciones Serial de mayor interés son Serial.Available (), Serial.parseFloat () y Serial.parseInt ():

    6.3.2: Serial.Disponible ()

    Descripción

    Obtenga el número de bytes (caracteres) disponibles para leer desde el puerto serie. Se trata de datos que ya han llegado y almacenados en el búfer de recepción serie (que contiene 64 bytes). available () hereda de la clase de utilidad Stream.

    Sintaxis

    Serial.Disponible ()

    Parámetros

    ninguno

    Devoluciones

    el número de bytes disponibles para leer

    6.3.3: Serial.parseFloat ()

    Descripción

    Serial.parseFloat () devuelve el primer número válido de punto flotante del búfer Serial. Los caracteres que no son dígitos (o el signo menos) se omiten. parseFloat () termina con el primer carácter que no es un número de punto flotante.

    Serial.parseFloat () hereda de la clase de utilidad Stream.

    Sintaxis

    Serial.parsefloat ()

    Parámetros

    ninguno

    Devoluciones

    flotar

    /**** fin del material de referencia copiado ****/

    Serial.parseInt () es similar a Serial.parseFloat () pero devuelve un entero en lugar de un valor de punto flotante. Las dos funciones de análisis examinan la cadena de entrada y comienzan descartando caracteres no numéricos. Una vez que se encuentra un numeral, continúa mirando los caracteres en la cadena hasta que se encuentra otro no numeral. Luego traduce los bytes numéricos ASCII en un único valor entero (o float, según sea el caso). Tenga en cuenta que es posible enviar múltiples valores al mismo tiempo.

    Aquí hay un ejemplo de cómo podrían usarse para crear un convertidor decimal a hexadecimal. Ingrese el siguiente pedazo de código, compile y descárguelo.

    int i1, i2; // globals to hold the data
    
    void setup()
    {
          Serial.begin(9600);    
    }
    
    void loop()
    {
    
          // Anything in the buffer?
          if (Serial.available() > 0)
          {
                i1 = Serial.parseInt();
                i2 = Serial.parseInt();
    
                // Echo back what you got, but in hex
                Serial.println("In hex, that is: ");
    
                Serial.println(i1, HEX);
                Serial.println(i2, HEX);
            }
    }
    

    Una vez que se haya descargado el programa, abra el Monitor de serie e ingrese 10 27 en el cuadro de texto en la parte superior y luego presione el botón Enviar junto a él (también podría presionar la tecla Enter en su teclado). El resultado debe ser:

    In hex, that is:
    A
    1B
    

    También puedes probar otros valores. Si ingresa solo un valor, i2 volverá como 0. Si ingresa varios valores, seguirán múltiples devoluciones. Pruébalos a ambos antes de continuar.

    Si ingresas un valor negativo, sucederá algo interesante. Intenta escribir -1 -2. ¿Qué ves y por qué?

    Ahora que tienes algunos conocimientos básicos del IDE y cómo realizar una depuración simple de texto, podemos pasar a examinar cómo leer y escribir en circuitos externos.


    This page titled 6.3: Codificació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.