Tutorial 2: Escribiendo y utilizando una función personalizada

Versión 5

    Introducción

     

     

     

    El cuerpo humano puede actuar cómo un capacitor natural. ¿Has utilizado  alguna vez un dispositivo con pantalla táctil? Cuando se combina con un  aislante, como el vidrio que está cubierto con un conductor transparente, la  interfaz de la pantalla táctil responde al tacto mediante el uso de la  capacitancia del cuerpo.

     

    En nuestro cuerpo tenemos pequeñas cargas eléctricas que, entre otras  cosas, nos dan la capacidad de procesar el mundo que nos rodea. Por ejemplo, mientras  estás leyendo esto, miles de impulsos eléctricos están enviándose a tu cerebro,  diciéndole que procese estas palabras que estás leyendo.

     

    En esta lección, tu cuerpo físico será parte de tu programa. Vamos a usar  un sensor táctil capacitivo como un interruptor ON/OFF. Una vez que el sensor envíe  un estado alto, se encenderá un LED y activará un micrófono. Los sonidos que el  micrófono recoja serán responsables de controlar la cantidad de brillo de otro  LED. Entenderás cómo usar los pines de Modulación por Ancho de Pulso (PWM, "Pulse Width Modulation") para  sacar una señal analógica que proporcione el rango necesario para la variar el  brillo del LED.

     

    Serás introducido a la escritura y el uso de una función personalizada, así  como a algunos lineamientos comunes de programación.

     

     

    Equipo Requerido

     

     

     

    Entradas Avanzadas

     

    El  circuito que construirás tendrá dos entradas (para el micrófono y para el  capacitor táctil), y dos salidas (dos LEDs). Antes de cablear todo, veamos los  tipos de entradas que usaremos.

    Micrófono


    Nuestro  micrófono es considerado una entrada analógica. Esto quiere decir que tomará  valores del mundo físico y los convertirá en valores leíbles que utilizaremos  en nuestro programa.

    Sensor táctil capacitivo


    Nuestro sensor es considerado una entrada digital. Lo que significa que los  únicos valores de entrada que se interpretarán son estados ALTO y BAJO  (verdadero/falso, 0/1).

    Es importante comprender las diferencias entre los dos  tipos de entradas. La tarjeta Intel® Galileo tiene 6 entradas analógicas,  etiquetadas desde la A0 hasta la A5. Los pines analógicos son únicamente de  entrada. Estos pines analógicos convierten las señales de voltaje de entrada (0  a 5V) en valores enteros entre 0 y 1023. En el código, leemos y escribimos  valores analógicos usando las funciones analógicas.

     

    // Declare and assign "val" to the incoming value from pin A0 (ranging between 0-1023)

    int val = analogRead(A0);

    // Writes incoming values from A0 (ranging between 0-255, after mapping the value)

    analogWrite(13, val);

    Para más detallles sobre cómo y cuándo usar las funciones analógicas, consulte la guía de referencia:

    arduino.cc/en/Reference/analogRead

    arduino.cc/en/Reference/analogWrite

     

    ¿Por qué hay una función llamada "analogWrite"? ¿Qué vamos a escribir?

    Aquí es donde utilizaremos los pines de Modulación por Ancho de Pulso (PWM). En la siguiente sección repasaremos cómo funciona la PWM y cómo y cuándo utilizarla.

     

    Probando los valores de entrada

     

    Paso 1: Energiza la placa de pruebas

    Conecta dos cables a los pines de 5V y GND de la tarjeta Galileo respectivamente. Conecta los otros dos extremos de estos cables a las líneas verticales de la placa de pruebas, marcadas con +,-, las cuales representan Energía (PWR) y Tierra (GND). Esto proporcionará  energía a las líneas verticales de la placa de pruebas para que puedas conectar otros módulos.

     

    Paso 2: Conecta el micrófono

    Conecta dos cables desde los pines de energía y tierra del micrófono hacia su respectiva línea vertical de la placa de pruebas. Conecta el cable restante del micrófono a una línea de la parte interior de la placa de pruebas. A continuación, conecta un cable desde la misma línea y hacia el pin A0 de la tarjeta Galileo.

     

    Paso 3: Conecta el sensor táctil

    Conecta las entradas de energía y tierra del sensor táctil (tal como lo hiciste con los cables del micrófono. Después conecta el otro extremo de los cables a las correspondientes líneas de energía y tierra de la placa de pruebas. Conecte el cable final a una línea de la parte interior de la placa de pruebas. Debe de ser una línea diferente que la del micrófono. Finalmente conecta el último cable desde la misma línea y hasta el pin 2 de la placa Galileo.

     

    Carga el siguiente sketch. Abre el monitor serial para ver que está pasando:

     

    // Declare and assign two variables that represent the pins we use for the sensors

    /* NOTE: Putting the word "const" in front of a variable declaration tell the compiler that this variable cannot be updated by the program. http://arduino.cc/en/Reference/Const */

    const int touch = 2;

    const int sound = A0;

    void setup(){

      Serial.begin(57600);

      // Set the pin mode for the touch sensor.

      pinMode(touch, INPUT);

      // NOTE: Since the sound sensor is an Analog input, we do not need to set a pin mode.

    }

    void loop(){

      // Declare and assign two variables that represent the input reading from the sensors

      int touch_input = digitalRead(touch);

      int sound_input = analogRead(sound);

      // Print the values to the serial monitor

      Serial.print("sound: ");

      Serial.println(sound_input);

      Serial.print("touch: ");

    Serial.println(touch_input);

    Serial.println("");

      // Wait 10 milliseconds before the next reading

      delay(10);

    }



    Modulación por Ancho de Pulso (PWM)

     

     

    Como la mayoría de los Arduinos, hay 14 pines digitales disponibles. Aunque pueden parecer todas iguales, vamos a echar un vistazo más a detalle de los pines 3, 5, 6, 9, 10 y 11. A un lado de los números que identifican los pines, hay un símbolo ~. Esto significa que estos pines pueden simular una salida analógica, permitiendo la capacidad de regresar valores entre 5 y 0V. Si recuerdas la lección anterior, los pines digitales solamente pueden dar y recibir valores ALTO y BAJO (nada entre medio).

     

    Dicho esto, estos pines especiales, los que están marcados con ~, son programables usando PWM como un medio para obtener resultados analógicos utilizando una interfaz digital. Con esta función especial, vamos a controlar el brillo de un LED.

     

    Agregando LEDs

     

    Paso 1: Configura la energía para el LED

    Conecta el cátodo (terminal corta) del LED al negativo (línea vertical azul). Conecta el ánodo (terminal larga) del LED a una sección de la parte central de la placa de pruebas.

     

    Paso 2: Añadir resistencias

    Al igual que en la lección anterior, usaremos un resistor de 220 Ohms. Conecta un lado del resistor a la misma línea donde está conectado el ánodo del LED. Conecta el otro extremo del resistor a la misma línea pero de la otra mitad de la placa de pruebas.

     

    Paso 3: Conecta al pin 4

    Conecta un cable desde la línea donde conectaste el resistor al  pin 4. Cuando este pin sea configurado con un estado ALTO, está señal irá a través del resistor, al ánodo, encenderá el LED, y después irá a tierra.

     

    Paso 4: Conecta al pin 9

    Sigue de nuevo los pasos del 1 al 3, excepto que esta vez conecta el cable al pin 9. Como se mencionó anteriormente, éste es un pin especial, denotado por ~. Este símbolo representa Modulación por Ancho de Pulso, permitiéndonos obtener valores entre 0 y 255 (algo que los pines puramente digitales no pueden hacer).

     

    Vamos a probar el desvanecimiento de un LED. Abre el sketch de ejemplo que se encuentra en el menú del software de Arduino: Archivo > Ejemplos > 03.Analog > Fading


    Ya que estamos utilizando el pin 9 en nuestro (que tiene PWM), este sketch variará el brillo del LED conectado a este pin.

     

    No hay más que escribir código dentro de las funciones loop y setup. Vamos a profundizar y comenzar a escribir nuestras propias funciones.

     

     

    Escribiendo una función personalizada

     

    Hasta este punto, hemos estado escribiendo código dentro de las funciones setup y loop. Esto está perfectamente bien. Pero, ¿qué pasa si tu programa tiene mucha lógica compleja?, ¿Cómo organizarás tu código?

    Hay un arte en la programación y comienza con saber dónde colocar tu código.

     

    Muchas veces, la codificación puede causar problemas. Si alguna vez has leído código abierto, es posible que te encuentres con un código que:

     

    • No tenga comentarios: Incluir comentarios te ayuda a ti y a otros a comprender lo que está pasando.
    • La lógica no esté organizada: Organizar tu código en fragmentos lógicos ayuda a la depuración y el mantenimiento del código.
    • Los nombres son engañosos: Los nombres de las variables y las funciones deberían describir adecuadamente lo que intentan de hacer.
    • Inteligencia sobre claridad: El código debería poder ser leído con facilidad. Trata de no encriptar lo que estas tratando de lograr.

     

    Los programas en cualquier lenguaje pueden ser escritos y organizados de acuerdo a lo que el programador considere conveniente. Esto está bien si tú eres el único que leerá tu código. Sin embargo, si estás trabajando en un equipo, es importante proporcionar algunas indicaciones que todos deberán seguir. Un día, el código que tú escribas necesitará ser actualizado y leído por otras personas. Escribir código organizado y tener buenas prácticas comunes de codificación te ayudará a ti y a tus compañeros ingenieros a escribir código bello.

     

    Para obtener consejos sobre cómo mejorar tu estilo de codificación, echa un vistazo a la guía de estilo de codificación en C++ de Google:

    google-styleguide.googlecode.com/svn/trunk/cppguide.xml

     

    Hay dos tipos de funciones:

    • Las que ejecutan instrucciones y no regresan ningún valor (tipo void)
    • Las que ejecutan instrucciones y regresan un valor (tipos int, float, double)

     

    Puedes ver más tipos en la sección "Data Types" en la página de referencia de Arduino:

    http://arduino.cc/en/Reference/HomePage

     

    Tipos de funciones

     

    Tipo void:


    void sayHello(){

      Serial.println("Hello!");

    }


    Tipo entero:

     

    int theAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything(){

      return 42;

    }


    Podemos asignar el valor de las funciones para que devuelvan algo a alguna variable:

     

    int myAnswer = theAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything();


    Digamos que quisiéramos hacer una función un poco más útil. Podemos utilizar  parámetros de función para transferirle datos que tendrán un impacto en el resultado de la función. Por ejemplo:

     

    int add(int x, int y){

      return x + y;

    }


    Llamaremos a esta función, pasándole los parámetros personalizados de este modo:

     

    int numbersAdded = add(2, 2); // The variable numbersAdded is equal to 4


    Hay varias maneras en las que puedes escribir una función. Todo depende de lo que quieres que haga. Una buena forma para comenzar a escribir una función personalizada es definir la signatura de la función.

     

    Signatura de una función

     

    Antes de escribir el código de una función, es mejor determinar qué estas tratando de lograr.

    • ¿Regresará algún valor?
    • ¿Cuantos parámetros le vamos a transferir (si existen)?
    • ¿Cuál es el propósito de la función?

     

    Pretendamos que estás escribiendo un programa que devuelve un mensaje personalizado al monitor serial. Este mensaje hará comentarios sobre el clima (que podría basarse en un sensor de temperatura, por ejemplo).

    Aún no sabes exactamente cómo luce el código dentro de la función, pero sabes lo que quieres que haga:

    • Tomar dos parámetros para concatenarlos (o unirlos).
    • Tomar un número del tipo double que se anexará al mensaje.
    • No regresará ningún valor.
    • Mostrará en el monitor serial algo como "It is 30 degrees outside".

     

    La signatura podría lucir algo como esto:

     

    void myMessage(String msg1, String msg2, double deg){}

    Llamar a la función sería algo como:

    // Degrees here would be a predefined variable based on a temperature sensor reading.

    myMessage("It is", degrees, "outside");


    Desafío

    ¿Cómo escribirías el código para completar la tarea de la función?

     

     

    Usando una función personalizada

     

    Como ya hemos construido nuestro circuito (dos LEDs, un micrófono, un sensor táctil capacitivo), veamos en acción una función personalizada.

     

    Antes de cargar el siguiente sketch a tu tarjeta Galileo, leé el código y trata de averiguar lo que está pasando:

     

    // Declare variables that represent pin numbers where the sensors/leds will be plugged in to.

    int mic_ready_LED = 4;

    int mic_fade_LED = 9; // PWM

    int touch = 2;

    int sound = A0;

     

    void setup(){

      Serial.begin(57600);    

      pinMode(touch, INPUT);

      // Set the pin mode for the LED's to output

      pinMode(mic_ready_LED, OUTPUT);

      pinMode(mic_fade_LED, OUTPUT);

    }

     

    void loop(){

      // Save the value of the incoming value from the touch sensor

      int touch_input = digitalRead(touch);

      // Read Touch sensor signal

      if(touch_input == HIGH) {

        digitalWrite(mic_ready_LED, HIGH);

      }

      else{

        // if Touch sensor is LOW, then turn off the led

        digitalWrite(mic_ready_LED, LOW);

      }

      // Pass the value of the touch input to the micListen function.

      micListen(touch_input);

      delay(10);

    }


    void micListen(boolean touch_val){

      if(touch_val == HIGH){

        Serial.println(analogRead(sound));

        analogWrite(mic_fade_LED, analogRead(sound) );

      }

      else {

        analogWrite(mic_fade_LED, LOW );

      }

    }


    Recuerda abrir el monitor serial. Ya que estamos usando un baud rate de 57600, en el menú desplegable en la esquina inferior derecha del monitor debe reflejar esto.

     

     

    En resumen

     

    Nuestros cuerpos, en cierto sentido, funcionan con electricidad. Mediante el uso de un sensor táctil capacitivo, somos capaces de utilizar la capacitancia eléctrica de nuestro cuerpo para activar el uso del micrófono.

     

    Al usar los pines de PWM, denotados por el símbolo ~ en seguida del número del pin, somos capaces de simular un pin analógico de salida utilizando los pines especiales PWM de la tarjeta Galileo. Esto nos da la capacidad de tener valores a la salida entre 0 a 5V, representados por números en el rango de 0 a 255. Usando estos valores, podemos ajustar el brillo del LED.

     

    Escribir código puede causar problemas. Empleando funciones puede ayudar a que tu código sea fácilmente leíble por otros desarrolladores. El uso de prácticas comunes y guías te ayuda a ti y a tu equipo a escribir y entender código eficiente.

     

    Escribir signaturas de las funciones antes de escribir el código para la función es un buen primer paso para determinar lo que quieres lograr. Una vez que se establece la signatura, escribir el código será más fácil.

     

    Desafíos

    • ¿Cómo modificarías el código en el último sketch para mejorar su legibilidad?
    • ¿Cuándo y por qué usarías una función del tipo void?
    • ¿Y si quisieras que el micrófono se apagara cuando el capacitor reciba una entrada ALTA?
    • ¿Cómo actualizarías el código para hacer eso?
    • En lugar de utilizar una declaración if/else, ¿cómo usarías otra estructura de control para obtener los mismos resultados? Vea "Estructuras de control" aquí: arduino.cc/en/Reference/HomePage