[Basics] Curso de Aquila - Día 3


#1

En caso de que hayas llegado a esta parte por accidente, te pongo el link del día 2, para que lo leas y luego procedas a esta 3ra y última parte del curso de la plataforma Aquila Día 2.-> Link

Antes de seguir adelante, date una vuelta por este thread en el foto. Es la guía de instalación (según sistema operativo) del Software de Aquila. -> Link

#Aquila

Es importante que sepas que el Altair no se comunica con otros Altair vía WiFi o vía Bluetooh, de hecho, usa otro protocolo dentro de la misma frecuencia que el WiFi (2.4GHz). Siendo el WiFi 802.11(b/g/n), el Altair, por otro lado usa el protocolo 802.15.4 es por eso que se requiere un Altair en modo Bridge, porque tu computadora por si sola, sólo tiene una antena para el protocolo de WiFi. Necesitamos una antena que hable y escuche bajo el mismo protocolo que los otros Altair, y qué mejor que otro Altair para eso. (:

Una ventaja más de este protocolo es que está optimizado para dispositivos de bajo consumo.

Bien, ya sabes cómo funciona su magia inalámbrica ahora habrá 3 conceptos que deberás conocer para poder dominar de manera correcta todo a lo que Aquila y Altair respecta.

  • Acciones: Es todo lo que puede hacer el dispositivo (y que de hecho, puedes ejecutar de manera manual desde la interfaz web).

  • Eventos: Es todo lo que le puede ocurrir al dispositivo.

  • Interacciones: Es lo que determina qué Acción ocurre después de que acaba de ocurrir un Evento según tu los encadenes en el Hub.

Desde el Hub (interfaz web) podrás; como mencioné anteriormente:

  • Ejecutar las acciones de los Altair conectados en red (siempre y cuando tengan acciones).

  • Puedes ejecutarlo desde una PC (y sí, deberá estar encendida mientras tienes el servidor levantado) o bien, desde un Raspberry Pi (en caso de que tengas alguno).

  • Otra cualidad, es que el Hub ¡es accesible desde cualquier computadora, tablet e incluso smartphone!

Muy bien, hasta ahora ya debes de ser capaz de iniciar el servidor desde tu computadora, según aprendiste en el thread donde menciona la instalación y manera de arranque, así como los conceptos básicos del entorno.

Entrando en materia, comenzaremos a hacer código.

#Acciones

  • Definición; esto va antes del setup
bool miAccion (uint8_t param, bool gotParam)
{
//Hacer algo
}
  • Inscripción; esto va dentro del setup
Aquila.addAction("Nombre de accion", miAccion);

#Eventos

  • Definición; va antes del setup.
Event miEvento;
  • Inscripción; va dentro del setup.
miEvento = Aquila.addEvent ("Nombre de evento");
  • Detonante; esto va dentro de tu lógica, cuando quieras que el Altair avise que acaba de pasar sobre ese evento.
Aquila.emit (miEvento);

Puede que esto se ve algo espantoso, pero recuerda que incluso si usabas Arduino estas son funciones exclusivas de Altair. Más adelante haremos juntos códigos de ejemplo para que te familiarices, no te ofusques.

Primero que nada, teniendo el servidor levantado deberás acceder al Hub accediendo desde un navegador a:

  • http:// ip del servidor:8080
    (Para acceder al hub desde la misma máquina que lo está coriendo es: http://localhost:8080)

Login por defecto:

  • Usuario: Admin
  • Pass: Admin

Ahora, es momento de cargar un Altair con el código de Bridge; se verá espantoso, pero no te preocupes, nuestros ingenieros se encargaron de dejarlo listo para que sólo debas cargarlo al Altair (y nada más :wink: ).

Este código lo encuentras en:

Archivo > Ejemplos > AquilaBridge > AltairBridge

Ahora, mantén conectado el Altair a la PC (O al Raspberry Pi).

Es momento de iniciar el servidor.

Linux y OSX: Ejecutar aquila-server desde una terminal.
En caso de que te pierdas a la hora de iniciar el Servidor, te dejo una Mini guía que muestra desde el momento de instalación.

Windows: Inicio > Aquila Server > Launch Aquila Server.

###Toma en cuenta que yo ya tenía instalado el IDE de Arduino, así que opté por no instalarlo.

###Simplemente busca en Inicio > Todos los Programas > Aquila Tools…

###Y así se debería ver ya que inicie el servidor :slight_smile:

Para los siguientes códigos vas a necesitar 2 Altair, claro que uno lo acabas de configurar para ser el Bridge. El otro será al que le subas estos códigos.

#include <Wire.h>
#include <Aquila.h> //De ahora en adelante, deberas incluir esta libreria, si no
//nada de las funciones de aquila van a funcionar

#define LED 13

//Declaracion de acciones

//bool *nombre_de_funcion* (nunca omitas lo de aqui dentro)
bool turnOff(uint8_t param, bool gotParam)
{
  digitalWrite(LED, HIGH);
}

bool turnOn(uint8_t param, bool gotParam)
{
    digitalWrite(LED, LOW);
}

void setup()
{
  pinMode(LED, OUTPUT);
  
  
  // Este bloque no debes de omitirlo nunca, ninguna parten de él.
  Aquila.begin();
  Aquila.setClass("mx.makerlab.blink");
  Aquila.setName("Blink"); //El texto en comillas es como aparece el Altair en el HUB
  
  //Implementacion de Acciones
  Aquila.addAction("Off", turnOff);
  Aquila.addAction("On", turnOn);
  
  //Esta linea tampoco debes de omitirla nunca.
  Aquila.sendClass(BROADCAST);
}

void loop()
{
//Esta linea es otra que no debes ni omitir ni posponerla
//Dicho de otra forma, trata de no usar la funcion delay en tus codigos
  Aquila.loop();
}

Así se verá cuando subas el código y mires en el HUB tu altair.

Quiero que analices el siguiente código, voy a poner el mínimo de comentarios.

#include <Wire.h>
#include <Mesh.h>
#include <AquilaProtocol.h> // Libreria necesaria

#define LED 13 // LED interno rojo

bool turnOff(uint8_t param, bool gotParam)
{
  digitalWrite(LED, HIGH); // HIGH es OFF para LED interno
}

bool turnOn(uint8_t param, bool gotParam)
{
  if(gotParam)
  {
    analogWrite(LED, param);
  }
  else
  {
    digitalWrite(LED, LOW);
  }
}

void setup()
{
  pinMode(LED, OUTPUT);
  
  Mesh.begin();
  Aquila.begin();
  Aquila.setClass("mx.makerlab.fade");
  Aquila.setName("Fade"); //Nombre como aparece en el hub
  
  Aquila.addAction("Off", turnOff);
  Aquila.addAction("Turn On with intensity", turnOn);
  
 Mesh.announce(HUB);
}

void loop()
{
  Mesh.loop();
  Aquila.loop();
}


¿Cambio algo con respecto al código del blinking LED?
¿Notaste el analogWrite que en empleó en la función de encendido?
Igual, ¿viste que el valor de entrada para el analogWrite era un tal “param”?

Resulta que esos valores que van al declarar la función funcionan directamente con el Hub; te habrás dado cuenta que en él hay un slider horizontal en el Altair conectado. Ese slider envía el PARAM y no es algo que controles directamente desde el Altair. ¡Lo mismo que con el ejemplo del potenciómetro en el tutorial pasado, pero a distancia!

  • bool turnOn (uint8_t param, bool gotParam)

Y lo que dice ahí es “Esta función me va a devolver si se hizo o no (al ser bool); esta función va a recibir un parámetro entero; Hay parámetro? Sí o no”

De hecho, uint8_t es una manera de ahorrar memoria, ya que int separa 16 bits por default y es desperdiciar memoria. Hacerlo de 8 bits, lo limita a números de 0 a 255 (¡justamente los que usamos aquí!)

#include <Wire.h>
#include <Mesh.h>
#include <AquilaProtocol.h>

#define LEDR 13
#define LEDG 14
#define LEDB 15

// Acciones
bool setR(uint8_t param, bool gotParam)
{
  if(gotParam)
  {
     analogWrite(LEDR, 255 - param); // Para que el slider funcione "como deberia" se invierte el valor que reciba, luciendo asi..
  }
}

bool setG(uint8_t param, bool gotParam)
{
  if(gotParam)
  {
    analogWrite(LEDG, 255 - param);
  }
}

bool setB(uint8_t param, bool gotParam)
{
  if(gotParam)
  {
    analogWrite(LEDB, 255 - param);
  }
}

void setup()
{
  // Setting up LEDs
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);
  
  Mesh.begin();
  Aquila.begin();
  Aquila.setClass("mx.makerlab.rgb");
  Aquila.setName("RGB");
  
  Aquila.addAction("Red", setR); // Haciendo esto se podran controlar los 3 LED
  Aquila.addAction("Green", setG); //de manera individual
  Aquila.addAction("Blue", setB); // Asi como sus intensidades
  
  Mesh.announce(HUB);
}

void loop()
{
  Mesh.loop();
  Aquila.loop();
}

Para este siguiente código aplicaremos todo el conocimiento visto en ejemplos anteriores.
Haremos que un botón en un Altair provoque que un segundo Altair se encienda. Ten en cuenta que para poder hacerlo se van a necesitar 3 Altair (1 bridge, 1 emisor, 1 receptor) Sin embargo sólo necesitarás 1 pushbutton. (Y suficientes cables o baterías para alimentar al emisor y receptor; ¡recuerda que el del servidor no se debe desconectar!)

#include <Wire.h>
#include <Mesh.h>
#include <AquilaProtocol.h>


// Boton interno del Altair
#define BUTTON 33

// Este evento sera emitido cada que el boton sea presionado
Event buttonPressed;

bool buttonLastState = HIGH; 

bool buttonIsPressed() //No es una funcion de Aquila, es una funcion habitual
{
  bool actualState = digitalRead(BUTTON);
  
  if(actualState == LOW && buttonLastState == HIGH) //Si el boton esta presionado y anteriormente estaba sin presionar entonces..
  {
    buttonLastState = LOW; //Su ultima posicion fue "presionado".
    return true;
  }
  else if(actualState == HIGH) //Si no esta presionado entonces..
  {
    buttonLastState = HIGH; //Su ultimo estado es "no presionado".
  }
  
  return false;
}

void setup()
{
  pinMode(BUTTON, INPUT);
  
  Mesh.begin();
  Aquila.begin();
  Aquila.setClass("mx.makerlab.button");
  Aquila.setName("Button");
  
  
  //Aqui se registra el evento
  buttonPressed = Aquila.addEvent("Button Pressed"); //Este texto entre comillas sale en la ventana de Interracciones, al abrir el menu despues de seleccionar el primer Altair
  
  
  // Si no haces esto, el Altair nunca va a avisar a la RED que esta conectado y listo para transmitir, por eso es importante no olvidarla.
  Mesh.announce(HUB);
}

void loop()
{
  //Con esta, todo el tiempo esta leyendo algun cambio en la red, digamos que se le envia alguna accion, por eso tiene que esta revisando muy frecuentemente el info del hub.
  Mesh.loop();
  Aquila.loop();
 
  if(buttonIsPressed()) // Se va a la funcion booleana de arriba y lee la informacion del boton..
  {
    Aquila.emit(buttonPressed); // ¿Recuerdas esto? En vez de que vaya el tipico "digitalWrite.." ponemos que mande esa info mejor al Hub; alla luego veremos que hacer con ella.
    // Este Altair lo unico que hace es emitir, por eso su funcion no tiene un gotparam,
    //porque ni es una accion, sino un evento lo que queremos hacer aqui.
  }
}

Y al otro Altair puedes ponerle el código del Blinking LED que hicimos aquí (el primer ejemplo).

Ahora, encadenar los Eventos con Acciones es de lo más fácil e intuitivo.

Algo así verás cuando entres al HUB. Verás inmediatemente los dispositivos conectados a la red.
Del lado izquierdo, verás en la columna “Interacciones”, accede a ella. Y le darás click a “Agregar Interacción”, es el botón morado del lado derecho.

##Seguido, verás algo así. Encadena “Button” a “Blink”

Ya que le des en aceptar, deberás ver las interacciones así. Mostrando el resumen de cada nueva interacción.

Bueno, ya tienes todo el conocimiento necesario para poder comenzar a desarrollar los prototipos que se te ocurran. Ten en cuenta que si necesitas ayuda, nuestra comunidad puede ayudar a resolver tus dudas o buscando en Internet (claro que quizá en vez de buscarlo como Altair", deberías comenzar buscando como Arduino).

No obstante las mejores creaciones las haces tú. Nunca lo olvides, nunca dejes de practicar, que eso es lo que te hace un mejor programador y desarrollador!

¿Qué tal te sientes ahora? Tal vez sientas que puedes devorarte al mundo con tus prototipos. ¡Y estoy seguro de que lo lograrás!

¡Ahora ve al IDE a mostrar quién manda aquí!


[Complemento] Acciones y Eventos
Cómo NO usar delay
#2

Hola tengo un problema al conectar mis dos aquilas el del botton y el del led no me aparecen el la interfaz de aquila, A que se debe esto?

y probe el codigo del botton que tienes en el post y me sale un error de compilación con este mensaje
"Opciones de compilación cambiadas, reconstruyendo todo
RoomLights.ino:2:18: fatal error: Mesh.h: No such file or directory
compilation terminated.
Error de compilación·"

No se cual sea el problema ya hace poco actualice mi aquila a la version mas actual


#3

Hola @Sonmed, Acabo de probar el código del botón aqui posteado y me compiló bien, ese error me suena a que algo esta mal instalado, o no seleccionaste la placa Altair en el IDE de Arduino.

¿Sobre que sistema operativo estas trabajando? si es windows, intenta reinstalando con en instalador de aquí: http://www.aquila.io/es/downloads

Mantenme informado para que pueda seguir ayudándote.

Saludos.


#4

Hola amigos, tengo un problema en el primer ejemplo usando el hub, sube correcto el programa del bridge, sin embargo cuando quiero subir el segundo código al segundo altair, me sale el error que dice "C:\Users\Juan\Documents\Burgauss\Cursos\AQUILA\DIA_2_E1\DIA_2_E1.ino:2:81: fatal error: Aquila.h: No such file or directory

#include <Aquila.h> //De ahora en adelante, deberas incluir esta libreria, si no
compilation terminated.

Utilizando biblioteca Wire en carpeta: C:\Users\Juan\AppData\Local\Arduino15\packages\makerlab\hardware\avr\0.2.5\libraries\Wire (legacy)
exit status 1
Error compilación en tarjeta Altair."

como procedo? tengo la placa revB


#5

Hola @Burgauss, aparentemente este tutorial ya quedó desactualizado, el código debería ser algo así (no lo he probado):

#include <Wire.h>
#include <Mesh.h>
#include <AquilaProtocol.h>

#define LED 13

//Declaracion de acciones

//bool *nombre_de_funcion* (nunca omitas lo de aqui dentro)
bool turnOff(uint8_t param, bool gotParam)
{
  digitalWrite(LED, HIGH);
}

bool turnOn(uint8_t param, bool gotParam)
{
    digitalWrite(LED, LOW);
}

void setup()
{
  pinMode(LED, OUTPUT);
  
  
  // Este bloque no debes de omitirlo nunca, ninguna parten de él.
  Mesh.begin();
  Aquila.begin();
  Aquila.setClass("mx.makerlab.blink");
  Aquila.setName("Blink"); //El texto en comillas es como aparece el Altair en el HUB
  
  //Implementacion de Acciones
  Aquila.addAction("Off", turnOff);
  Aquila.addAction("On", turnOn);
  
  //Esta linea tampoco debes de omitirla nunca.
  Mesh.announce(HUB);
}

void loop()
{
//Esta linea es otra que no debes ni omitir ni posponerla
//Dicho de otra forma, trata de no usar la funcion delay en tus codigos
  Mesh.loop();
  Aquila.loop();
}