[Basics] Curso de Aquila - Día 2


#1

#Códigos Analógicos

En caso de que no hayas leído el tutorial del día 1, te invito a que pases a leerlo.

Espero hayan practicado y entendido los códigos del día anterior, en este día aprenderán sobre la parte analógica

Las señales analógicas son un tipo generado por algún fenómeno electromagnético. Varía en su amplitud y el periodo. Piensa en el sonido; ahora imagina cuán grave, aguda, fuerte, suave puede ser tu propia voz. ¡Ya dominabas las señales analógicas sin saberlo!

En este código se deja ver el PWM en funcionamiento; más adelante explicaré cómo es que funciona el PWM, pero primero quiero que lo veas en acción. Claro que en este ejemplo se ejecutará de manera automática (no necesitarás equipo extra para poder verlo, mas que el Altair).
¡Después trabajarás con un ejemplo que te permite controlarlo!

Algo que queda añadir es que analogWrite a pesar de ser “ANALÓGICA”, no deja de ser una función digital. ¡Carga el siguiente ejemplo, ve cómo funciona y después te explico!

int led = 15; //Led azul
int brightness = 0;
int fadeAmount = 5; //variable de incremento

void setup() {
  pinMode(led, OUTPUT);
}

void loop()
{
  analogWrite(led, brightness);
  brightness = brightness + fadeAmount; // Incrementa (o decrementa de 5 en 5)
  if (brightness == 0 || brightness == 255) //Si llegó a 0 o llegó a 255, entonces..
  {
    fadeAmount = -fadeAmount ; //El incremento (o drecremento) invierte el signo y continua
  }
  delay(30); //Espera 30 milisegundos para evitar que el led sólo parpadee (sería tan rapido que así se vería)
}

El LED se atenúa hasta apagarse y enciende lentamente, ¿no es así? Pues no, de hecho lo que acabas (y posiblemente sigas viendo) es un mera ilusión óptica. No me crees, ¿verdad?
Resulta que al estar moviéndonos en un entornos digital (que funciona únicamente con 0’s y 1’s; o sea, apagado ó prendido; sin puntos intermedios) se debió encontrar una manera de que parezca que está “medio apagado” o “medio prendido” trabajando únicamente con “prendidos” y “apagados”. ¿La solución? El tiempo.
Entre ciclo y ciclo de apagados y encendidos lo que sí podemos controlar es el tiempo que se mantiene en cada uno, así engañando al ojo humano. Fascinante, ¿no?
Para que quede más claro anexo la siguiente imagen.

Ves alguna línea horizontal entre ON y OFF ¿no, verdad? sólo se modula el tiempo entre cada caso.
Como un experimento extra, usando el mismo código o el siguiente, quiero que agites el Altair (si tienes conectada una batería al Altair como se muestra en este tutorial -> http://goo.gl/LKNJHu sería mucho mejor). ¿Logras ver cómo el LED no deja un rastro continuo sino uno punteado sobre el aire? ¡Ahí estás viendo el ancho del pulso en tiempo real!

Ahora, volvamos a un código del día anterior.

void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
  digitalWrite(13, LOW);
  delay(1000); //Tiempo que permanece prendido.
  digitalWrite(13, HIGH);
  delay(1000); //Tiempo que permanece apagado.
}

¡Ah, nuestro viejo amigo, el ejemplo de “Blinking LED”! Mirémoslo con otros ojos esta vez. ¿Qué tal si jugamos con los valores de delay? Intenta reducirlos a valores muy pequeños (ponle 1 a uno y al otro 10, por ejemplo) Juega con los valores. Si no notas mucha diferencia, intenta agitar el Altair como dije antes y dime si varía entre experimentos lo que ves.
Ya que hayas visto los resultados, responde. ¿Ahora me crees que PWM es ilusión óptica?
Para evitar tener que hacer esto de manera manual, se creó esta función que automáticamente calcula el tiempo que requiere estar prendido y apagado para generar la función.
¡No obstante también requiere un Hardware que lo soporte, como el del Altair!

###En el siguiente código se hará uso del “control manual” sobre PWM.
(Aunque, ¡no tan manual como el ejemplo anterior!)

#define LED 15 // Asignamos el LED interno (esta vez es el Azul) a la palabra LED
#define POT A7 //Haremos uso de la Entrada analogica numero 7 (justo en la esquina del Altair, junto a la antena)

int valor = 0;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(POT, INPUT);
}

void loop()
{
  valor = analogRead(POT); //El altair estara muestreando todo el tiempo lo que el potenciometro indique que marca (desde 0 hasta 1023; 1024 valores)
  valor = map(valor, 0, 1023, 0, 255); //Aqui "traducimos" los valores del 0 al 1023 escritos en la variable "valor" y los reescalamos hacia 256 (8 bits) que permite el LED del Altair
  analogWrite(LED, valor); //Simplemente se escribe el valor adaptado para ser escrito en el LED
}

La conexión es bastante sencilla (ten en cuenta que dependiendo de la polaridad que le des al potenciómetro, afectará en el sentido en el que deberás girar la perilla, nada más. Nada se va a quemar. :wink:
(Aquí la explican la función MAP en caso de que tengas duda http://goo.gl/k0ViGY )

###En este siguiente ejemplo se muestra como también se puede controlar todo esto con un fotoresistor.
En si el código es idéntico, salvo que requerimos valores de 8 bits y el foto resistor nos devuelve desde 300 hasta 1023. Por eso, haremos uso de nuevo de la función “map”.

#define LED 15 //Led Azul
#define LDR A7 //Foto resistor en el Analogo 7

int valor = 0;

void setup()
{
  pinMode(LED, OUTPUT);
  pinMode(LDR, INPUT);
}

void loop()
{
  valor = analogRead(LDR); //Similar al ejemplo del potenciómetro
  valor = map(valor,300, 1023, 0, 255); //Adaptamos sus valores posibles (Hasta el tope de analógico (1024)
  analogWrite(LED, valor); //Y lo convertimos a 256  (8 bits)
}

###Ahora, para pasar al siguiente tema, comenzaremos con un ejemplo sencillo del monitor Serial.

Resulta que muchas veces es más práctico leer los valores que devuelve el Altair en pantalla, o para interactuar directamente con él. (No necesitaras ya nada para este ejemplo, sólo el Altair)

void setup()
{
  Serial.begin(9600); //Inicia el monitor serial a una velocidad de 9600 baudios (esta sera tu tasa de refresco)
}

void loop()
{
  if (Serial.available()) //A veces el monitor serial puede estaro ocupado haciendo otras cosas, solo es una mendida preventiva para evitar perdidas de informacion
  {
    char a = Serial.read(); //Lee todo lo que escribas en el recuadro de texto del monitor serial
    
    Serial.println(a); //Re escribe todo lo que hayas escrito en el recuadro.
    //Ojo que se esta usando "println" y no "print" solamente, la diferencia es que println
    //"Incluye" ya un \n despues de cada linea que teclees, ademas, se esta trabajando con
    //una variable del tipo caracter (char) entonces solo almacenara letra por letra y
    //con println las ira separando en renglones distintos
    //Intenta teclear tu nombre o alguna palabra y ve lo que ocurre!
  }
}

Más adelante se hará más uso de la función del monitor Serial, sólo era necesario que te explicara cómo funciona a grandes rasgos.

Y por último, por haber estado leyendo hasta aquí, te enseñaré una función secreta del Altair! ¡La función de medir la temperatura! (claro que usa la función del monitor serial, ¡para que apliques ese conocimiento fresco!)
No necesitarás nada para hacer este último ejemplo, sólo el Altair

#include <AltairTemperature.h>

void setup()
{
  Serial.begin(9600); //Inicia el monitor serial a 9600 baudios
}

void loop()
{
  float temp = getTempC(); //Lee la funcion getTempC y la almacena en una variable con decimales
  Serial.println(temp); //Imprime la variable temp y lo que tenga almacenado
  delay(500); //Espera medio segundo para evitar que se sature el monitor serial y para tener lecturas diferentes (o habra muchisimas repetidas)
}

Ahora ¿se te ocurren más prototipos para desarrollar? No olvides anotar todas tus ideas para llevarlas acabo! (Igual, no olvides preguntar!)

Esto concluye el día dos del Curso de Aquila.
En el siguiente Día te daré una introducción a la plataforma Aquila. Espero que hasta ahora todo esté quedando claro y te la estés pasando bien.
Una vez terminando el curso seré todo oídos para cualquier duda que tengas. :blush:


[Basics] Curso de Aquila - Día 3
Recursos para Aquila (Documentación, código, etc.)