Cómo instalar ArmBian en Orange Pi PC


Armbian es una distribución ligera basada en Debian o Ubuntu especializada para placas de desarrollo ARM. Compilado desde cero, contando con poderosas herramientas, desarrollo de software, y una comunidad vibrante.Otras placas ARM pueden ser las Raspberry PI, Odroid, Cubieboard… cada una de un fabricante distinto y luchando por hacerse con su espacio

Para instalar Armbian, primero debemos elegir entre un entorno gráfico o linea de comandos pues dependiendo lo que queramos hacer, elegiremos uno u otro sistema. Según la placa tendremos soporte completo con una de cuatro sistemas básicos  Debian Wheezy  (Jessie)  o   Ubuntu Trusty  (Xenial)

Ademas  dentro de esas distribuciones, podemos elegir entre «Legacy» y «Vanilla»,ambos estables y listos para producción, pero se debe elegir en base a nuestras necesidades, ya que su soporte básico es diferente:

  • Legacy: aceleración de vídeo, sistema al que conectar pantallas y otros periféricos, como teclado, ratón…
  • Vanilla: servidores sin monitor o periféricos, que se vayan a controlar remotamente por ssh ( por ejemplo desde el putty)

Más información acerca de Armbian se puede encontrar: Aquí  y se puede encontrar la guía de instalación: Aquí

Ok, ¿qué necesitamos para iniciar este pequeño proyecto?

Hardware necesario:

  1. Orange Pi PC
  2. 5V / 2A con el barril del CC Jack o el cable grueso del USB (utilicé 5V / 1,5A de mi teléfono viejo)
  3. Tarjeta SD – Clase 10!
  4. Teclado y ratón
  5. Cable HDMI
  6. Cable ethernet de LAN
  7. Lector de tarjetas

Software necesario:

  1. Descargar Armbian – Jessie,versión servidor  para el Orange Pi PC   Aquí
  2. Descargar SDFormatter: aqui
  3. Descargar Etcher: Here
  4. Descargar 7-Zip: Aquí
  5. Descargar Putty: aqui

Upzip, formato e instalación de Armbian a la tarjeta SD

  • Empezar a descargar Armbian (ver enlaces anteriores) e instalar SDFormatter, Etcher y 7-zip.
    (No estoy explicando cómo instalar esas aplicaciones porque es bastante sencillo.
  • Cuando esto se hace, abra la carpeta donde descargó la imagen de Armbian,
    Esto debe ser nombrado así:
    «Armbian_5.20_Orangepiplus_Debian_jessie_3.4.112_desktop.7z
  • Abra 7-zip y descomprima este archivo en un nuevo directorio para que tenga algo como: «Armbian_5.20_Orangepiplus_Debian_jessie_3.4.112_desktop.img 
  • Conecte su tarjeta SD a su computadora, en este caso utilicé un lector de tarjetas USB
  • Iniciar SDformatter
    • Drive: Seleccione su tarjeta SD ( Compruebe esto! )
    • Vaya a las opciones -> «Ajuste del tamaño del formato» -> YES (El valor predeterminado es «No») -> OK
    • Compruebe nuevamente si la tarjeta SD está seleccionada en la sección «Drive».
    • Haga clic en «Formato»
  • Iniciar Etcher (ejecutar como Administrador!)
    • » Seleccionar imagen » -> Seleccione su unzipt:
      Archivo «Armbian_5.20_Orangepiplus_Debian_jessie_3.4.112_desktop.img»
    • Seleccione » Cambiar » para cambiar su letra de unidad para usted Tarjeta SD
    • Seleccione «Flash!» Y esperar hasta que esto se haga
  • Desconecte su tarjeta SD cuando se haya completado este proceso, use la opción «Quitar hardware y expulsar material de forma segura» en Windows para asegurarse de que está bien

Conecte su Orange Pi PC  y arranque por  primera vez con Armbian

 Ok, ahora es el momento de conectar todos sus dispositivos y cables para iniciar su Orange Pi!
  • Conecte un teclado + mouse a USB
  • Conecte su cable HDMI a su TV  o monitor
  • Conecte el cable LAN al enrutador / conmutador
  • Inserte la tarjeta SD en la ranura de la tarjeta SD
  • Por último, pero no menos importante, conecte el cable de alimentación a su Orange Pi (recuerde que no hay soporte en el Micro USB como fuente de alimentación)
  • ¡Que empiece la diversión!

¿Cómo arrancar?

El primer arranque toma alrededor de 3 minutos y luego se reinicia y tendrá que esperar otro minuto para iniciar sesión. Este retraso se debe a que el sistema actualiza la lista de paquetes y crea SWAP de emergencia de 128Mb en la tarjeta SD.

¿Cómo iniciar sesión?

Ingrese como nombre de usuario » root» en la consola o mediante SSH y use la contraseña » 1234″ . Se le pedirá que cambie esta contraseña en el primer inicio de sesión. A continuación, se le pedirá que cree una cuenta de usuario normal que esté sudo (admin) habilitada.
Incluso te está preguntando si quieres cambiar la resolución de la pantalla, pero para mí está bien en 720P.
Estoy usando la línea de comandos con SSH (masilla) la mayor parte del tiempo.

Su escritorio ya está listo para usar! :

Le mostrará algo como esto: donde como vemos aparece la dirección IP a la que nos podemos conectar por ssh

Inicie Putty y conéctese a la dirección IP de su Orange Pi así (ver captura de pantalla):

Nombre de host (o dirección IP): 192.168.1.48 (sólo mi ejemplo, cambie a su IP)
Puerto 22 (predeterminado)
Y haga clic en «Abrir»

Putty le dará un mensaje de seguridad la primera vez, simplemente haga clic en «Sí».

Ingrese con «root» como nombre de usuario, y su propia contraseña.

Actualizar, establecer una IP estática y deshabilitar raíz para iniciar sesión.

Su Orange Pi debe ejecutar el escritorio y SSH ahora mismo, pero queremos hacer más!

Estos 3 pasos no son obligatorios, pero me gustaría recomendarlo o al menos echarle un vistazo.

  • Actualizar / actualizar su Armbian
    Inicie sesión con Putty en su Orange Pi, y use este comando para actualizar / actualizar su Armbian:
    » Sudo apt-get update«  o simplemente   «apt-get update» si esta logado como root
    Después de esto:
    «Sudo apt-get upgrade -y » o simplemente apt-get upgrade -y  si esta logado como root     .En caso de error puede que tenga   que selecionar la opcion -f , es decir            apt-get -f install
  • Configurar un IP estático
    Quiero tener una dirección IP estática (no DHCP) en mi Orange Pi, así que sé con seguridad que estoy conectando a mi Orange Pi en la misma dirección IP todo el tiempo.
    Inicie sesión con Putty en su Orange Pi y utilice este comando ifconfig  para ver los detalles de su IP actual:

    root@orangepipc:~# ifconfig
    eth0 Link encap:Ethernet HWaddr d2:94:6d:f5:41:56
    inet addr:192.168.1.48 Bcast:192.168.1.255 Mask:255.255.255.0
    inet6 addr: fe80::d094:6dff:fef5:4156/64 Scope:Link
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:20090 errors:0 dropped:0 overruns:0 frame:0
    TX packets:9527 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:24031895 (24.0 MB) TX bytes:757452 (757.4 KB)
    Interrupt:114
    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:16436 Metric:1
    RX packets:1 errors:0 dropped:0 overruns:0 frame:0
    TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:104 (104.0 B) TX bytes:104 (104.0 B)

    root@orangepipc:~#

  • En este caso, quiero usar esta dirección IP 192.168.1.48 como una dirección IP estática, pero usted tiene que comprobar qué dirección IP que desea utilizar en este rango.Tipo:
    «nano / etc / network / interfaces «, el texteditor Nano se abrirá y le mostrará la configuración de red, busque los detalles de «eth0», como esto:

source /etc/network/interfaces.d/*

# Wired adapter #1
allow-hotplug eth0
no-auto-down eth0
iface eth0 inet dhcp
#address 192.168.0.100
#netmask 255.255.255.0
#gateway 192.168.0.1
-nameservers 8.8.8.8 8.8.4.4
# hwaddress ether # if you want to set MAC manually
# pre-up /sbin/ifconfig eth0 mtu 3838 # setting MTU for DHCP, static just: mtu 3838

# Wireless adapter #1
# Armbian ships with network-manager installed by default. To save you time
# and hassles consider using ‘sudo nmtui’ instead of configuring Wi-Fi settings
# manually. The below lines are only meant as an example how configuration could
# be done in an anachronistic way:
#
#allow-hotplug wlan0
#iface wlan0 inet dhcp
#address 192.168.0.100
#netmask 255.255.255.0
#gateway 192.168.0.1
-nameservers 8.8.8.8 8.8.4.4
# wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
# Disable power saving on compatible chipsets (prevents SSH/connection dropouts over WiFi)
-mode Managed
-power off

# Local loopback
auto lo
iface lo inet loopback

  • Ahora necesitamos cambiar la parte » dhcp » a » static «, y llenar todos los detalles de la dirección

    IP.Cambiarlo así:# Wired adapter #1
    allow-hotplug eth0
    no-auto-down eth0
    iface eth0 inet static
    address 192.168.1.48
    netmask 255.255.255.0
    gateway 192.168.0.1
    -nameservers 8.8.8.8 8.8.4.4
    # hwaddress ether # if you want to set MAC manually
    # pre-up /sbin/ifconfig eth0 mtu 3838 # setting MTU for DHCP, static just: mtu 3838# Wireless adapter #1
    # Armbian ships with network-manager installed by default. To save you time
    # and hassles consider using ‘sudo nmtui’ instead of configuring Wi-Fi settings
    # manually. The below lines are only meant as an example how configuration could
    # be done in an anachronistic way:
    #
    #allow-hotplug wlan0
    #iface wlan0 inet dhcp
    #address 192.168.0.100
    #netmask 255.255.255.0
    #gateway 192.168.0.1
    -nameservers 8.8.8.8 8.8.4.4
    # wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
    # Disable power saving on compatible chipsets (prevents SSH/connection dropouts over WiFi)
    -mode Managed
    -power off# Local loopback
    auto lo
    iface lo inet loopback

    Guarde este documento pulsando » ctrl + x «, » Y » y pulse enter ( no cambie el nombre de archivo! )
    Ahora necesitamos reiniciar el servicio de red en Armbian, pero no sé por qué, reiniciando Armbian funciona muy bien aquí. Puede reiniciar tecleando este «reboot».

  • Putty le dará un mensaje » Server inesperadamente cerrado conexión de red «, pero eso no es extraño, que está reiniciando el Orange Pi.
    En putty utilice el botón «Restart ression» para reiniciar la conexión a su Orange Pi.Ahora cambiamos una dirección IP DHCP a una dirección IP estática para » ETH0 «.
  • Desactivar la conexión root de SSH en Armbian
    ¿Por qué debemos desactivar la cuenta de root para el inicio de sesión de SSH? Bastante simple, la seguridad !
    Casi todas las distribuciones de Linux tienen la cuenta «root», así que si alguien quiere hackear / fuerza bruta
    Un servidor Linux que están intentando iniciar sesión con esta cuenta. Al deshabilitar esta cuenta, primero deben encontrar una cuenta de usuario.Para solucionar este problema, debemos editar el archivo » sshd_config «, que es el archivo de configuración principal del servicio sshd. ¡Asegúrese de que su segunda cuenta funcione! Al principio, Armbian le pidió que creara una segunda cuenta de usuario con una contraseña. Cierre sesión en Putty e intente iniciar sesión con esta cuenta. En mi caso creé una cuenta » orangepi «.Tipo:
    » Sudo nano / etc / ssh / sshd_config «Encuentre esta parte: (en Nano puede buscar con «ctrl + w»)
    » PermitRootLogin «Te mostrará:
    # Autenticación:LoginGraceTime 120
    PermitRootLogin sí
    StrictModes síCambie el « PermitRootLogin  » a » PermitRootLogin no »
    Guardar esto golpeando » ctr + x «, Y (es) y pulse enter (no cambie el nombre del archivo!)
    Reinicie SSH escribiendo:
    » Sudo service ssh restart «Cierre la sesión e intente ingresar con «root», si ha cambiado esto correctamente, le dará un error ahora.
    «Acceso denegado».
    Inicia sesión con tu segunda cuenta ahora, en mi caso es «orangepi» y ya está!

Software adicional

Estos son sólo extra como: 

  • GPIO 
    Al igual que la Raspberry Pi (RPI), el Orange Pi (OP o OPI) tiene algunos GPIO para jugar.
    El RPI usa un programa llamado «WiringPi», pero para el Orange Pi tenemos «WiringOP»!
    Se puede encontrar más información: aquí y aquí

    • Ir a su homedirectory
    • Tipo: «clon de git https://github.com/zhaolei/WiringOP.git -b h3»
    • Tipo: «cd WiringOP»
    • Tipo: «sudo chmod + x ./build»
    • Tipo: «sudo ./build»
    • Tipo: «gpio readall» para ver una visión general de todos los puertos GPIO.
  • VNC sobre SSH
    Puedo copiar pasado este sitio web completo, pero toda la información es:Aquí
  • RPI-Monitor
    Puedo copiar pasado este sitio web completo, pero toda la información es:Aquí
  • Webmin 
    Puedo copiar pasado este sitio web completo, pero toda la información es: Aquí

Alarma con estación meteorológica


También decidió utilizar un servidor MQTT para subir esta información en la web por lo que se puede desde cualquier lugar, tener un vistazo a la información meteorológica captada por este prototipo.

Elementos del montaje:

  1. nodeMCU (regulador Micro,  versión 0.9)
  2. Pantalla LCD – 16 x 2
  3. Botones – 3
  4. Sensor de temperatura DHT11
  5. Timbre o zumbador
  6. Placa de prototipos tamaño  mini
  7. Cables de puente
  8. Resistencia de 1000 Ω – 3
  9. Caja de madera para montar todas las cosas dentro.

Asignación de pines y planificación

Bien, así que vamos a hablar acerca de cómo tenía que distribuir los pasadores entre todos los componentes.

La pantalla LCD

La pantalla LCD,  necesita al menos 6 pines de I/O interfaz con el microcontrolador. Puede darse como sigue: Habilitar, register select, D04, D05, D06 D07.

  • Enable – pin I/O digital 0
  • Seleccione Registro – pin I/O digital 1
  • D04 – pin I/O digital 2
  • D05 – pin I/O digital 3
  • D06 – pin I/O digital 4
  • D07 – pin I/O digital 5

Los botones

Hay tres botones que vamos a usar, por lo queo bviamente  necesitaríamos tres pins de I/O digitales,

  • LeftButton – pin I/O digital 6
  • CenterButton – pin I/O digital 7
  • RightButton – pin I/O digital 8

El zumbador

El puede ser conectado al pin I/O digital 9.

El sensor de temperatura DHT11

Este sensor tiene un pin de salida y sigue para el pin de I/O digital 10

 

Ensamblaje

En una caja de madera ser practican agujeros para el lcd  y lo botones y entonces es hora de montar todo dentro de esa caja.

  1. Creo que tenemos que empezar con los botones. Usé un palito de helado estrecho para hacer una base para los botones.
  2. Luego tomar el nodeMCU y las placa de prototipos y pegarloo a la base de la caja con cinta de doble cara.
  3. Entonces conectar los botones a los pines de I/O digitales apropiados.
  4. En tercer lugar, colocar  la pantalla LCD y luego agarrarla bien a la caja con algunas cintas desde el interior. .
  5. Hacer las conexiones de la pantalla LCD.
  6. Luego conectar el timbre o buzzer en el interior de la caja con cinta de doble cara y conectar su terminal positivo al pin digital 9
  7. El sensor DHT11 tiene tres piness: 5v, gnd y la salida. Por lo tanto el pin de salida irá al pin digital 10 de la nodeMCU . 5v y tierra son obvias dónde deben ir.
  8. También para agregar, DHT11 es lo único que se quedará fuera de la caja para detectar la temperatura exterior. .

 

El código

El código qeu ha escrito Techovator0819      es cerca de 450 líneas de longitud. y cuenta  con  algunas bibliotecas importantes que se necesitan para descargar  asi que lo primero es asegúrarse de tener el IDE de Arduino instalado asi como tener los drivers del  esp8266 instaladas también. Si no lo ha hecho, haga clic aquí.

El primer paso antes de ver  el código, es entender la funcionalidad de nuestro dispositivo y el código en consecuencia:

  • Nestro WB(weather box)  accede a internet y recupera la información de tiempo apropiado a través de una llamada a la API.
  • También  tomara  la temperatura del medio ambiente  con un sensor propio y enviara esa información a un corredor de MQTT.
  • También podría mantener alarmas y temporizadores para usted.
  • También es capaz de mostrar hora y fecha.

Todo , esto significa que necesitamos integrar todas estas funciones bajo un título o código.

¿Cuáles son las bibliotecas que necesitamos?

  1. Librería LiquidCrystal . Como estamos usando una pantalla LCD como la principal interfaz entre usted y el NodeMCU, esta biblioteca es indispensable. Paranuestra comodidad, esta biblioteca, por defecto, es una biblioteca integrada en el IDE de Arduino.
  2. Biblioteca de ESP8266WiFi . Esta biblioteca permite el ESP8266 conectar con el Wifi y tener acceso a internet. Esta librería viene en un paquete que debe descargar durante la instalación del ESP8266 en el administrador de la placa.
  3. Biblioteca de ArduinoJson . Cuando se llama a la API, los datos que usted recibirá estaran en formato JSON (JavaScript Object Notation). Así que si quiere convertirlo a un formato utilizable, necesita analizarlo. Y la biblioteca de ArduinoJson lo hace por nosotros.
  4. Biblioteca para el sensor DHT11.
  5. Biblioteca en tiempo de. Para mantener a nuestro tiempo. Las funciones de biblioteca se enumeran aquí.
  6. Biblioteca de TimeAlarms . Se utiliza para que nos establezcan alarmas y temporizadores. Las funciones de biblioteca se enumeran aquí.

Las dos últimas bibliotecas deben utilizarse juntos. Puede usar la biblioteca en tiempo de forma independiente pero no de la biblioteca de TimeAlarms.


La llamada de API

 

 

 

 

 

Lo más importante es una llamada a la API es la API key. Estoy conectando a la página web openweathermap.org para obtener toda la información de tiempo. Así que hay que seguir el procedimiento para abrir una cuenta allí y obtener un API key y es absolutamente gratis. Para llamar a la API key,
El primer paso es conectarse al servidor.

En segundo lugar, usted necesita utilizar su API key en la URL.Usted deberá utilizar el método GET para recuperar los datos de la URL.

Para hacer los datos disponibles en un formato utilizable,necesita para luego almacenar los datos en una cadena.

Los datos que reciba serán en formato JSON. Así que hay que analizarlo.

Y luego, se almacenan la información deseada en algunas variables globales que se pueden utilizar en cualquier lugar en el código.

     El siguiente es un ejemplo de código  para demostrar cómo funciona. Esta parte básicamente declara las bibliotecas utilizadas, crea las variables y objetos de la biblioteca a consultar.

include <ArduinoJson.h>
#include <ESP8266WiFi.h>
String result; 
// la cadena en la que se almacenarán los datos después de la llamada a la API
char servername[]="api.openweathermap.org"; //mombre servidor
String APIKEY = "YOUR_API_KEY"; //el API key
String CityID = "1264527"; //el  ID de la ciudad

//Asignación de sus variables globales para almacenar la información meteorológica recibida
String Description;
String Place;
float Temperature;
float Humidity;
float w;
WiFiClient client; >

Código de configuración básica.

void setup()

{

// Ponga su código de configuración aquí, para ejecutar una vez:
Serial.begin(9600);
WiFi.begin(«your ssid», «your password»);

//empieza  conexion WIFI
while(WiFi.status() != WL_CONNECTED)

{

// espera hasta que se establezca la conexión
Serial.print(«.»);
delay(500);
}
Serial.println(«Connectado!»);
Serial.println(WiFi.localIP());   //imprime direccion  IP
}<

Código para crear una función que obtiene los datos.

void weatherData(){

if (client.connect(servername, 80)) {

// inicia la conexión del cliente, comprueba la conexión
client.println(«GET /data/2.5/weather?id=»+CityID+»&units=metric&APPID=»+APIKEY);

//// llama a la api usando el método get antes de la URL. Nota: La URL utiliza la clave api.
Serial.println(«Server esta accesible»);
client.println();
}
else { //  si el servidor no esta disponible
Serial.println(«fallo de conexion  «); //mensaje de errorsi no esta conectado el cliente
Serial.println();
}
result = «»;

//Hace que la cadena nula de cualquier dato almacenado previamente para almacenar nuevos datos
while (client.available()) { //connected or data available
char c = client.read(); //gets byte from ethernet buffer
result = result+c;
}
Serial.println(result);
result.replace(«[«, » «);

//Estoy enfrentando un error. Sólo para evitarlo, tengo que escribir esto
result.replace(«]», » «);

//y esto tambien.
client.stop(); //para  cliente
Serial.println(«Recieved»);

//Analiza la cadena llamada resultado

StaticJsonBuffer<1024> jbuff;

JsonObject &root = jbuff.parseObject(result);
if (!root.success())
{
Serial.println(«parseObject() failed»);
}

// almacena toda la información deseada en variables temporales.
String location = root[«name»];
float temperature = root[«main»][«temp»];
float humidity = root[«main»][«humidity»];
String description = root[«weather»][«description»];
float wind = root[«wind»][«speed»];

//Transfiere toda la información de las variables temporales a variables globales a las //que puede acceder en cualquier parte del código.
Place = location;
Temperature = temperature;
Humidity = humidity;
w = wind * 3.6;
Description = description;
}

La función de bucle para mostrar todo lo que te quieren en el monitor serie.

void loop() {

weatherData(); //Llama a la función que hemos discutido anteriormente
Serial.println(Temperature);
Serial.println(Place);
Serial.print(«H: «);
Serial.println(Humidity);
Serial.print(w);
Serial.println(» kmph»);
Serial.println(Description);
delay(8000); //retardo de  8 segundos
}

Como vemos  es un ejemplo básico de una llamada a la API y el análisis de datos JSON.

 

MQTT cliente y agente

 

 

 

Como hemos visto en este blog el autor h aoptado  por el frameworl Cayyene de MyDevices para salvar la informacion procedente del sensor DHT11

 

 

 

 

&

 

 

 

 

 

 

Como vemos va  subiendo nuestros datos de los sensores a un corredor de MQTT en internet por lo que podemos ver desde cualquier lugar.
Pesonalmente pienso que el tablero de instrumentos del Cayenne es el más conveniente así queno me sorprende que el autor lo hay usado
Resumidamente esto son los pasos  para usar el servicio
  • En primer lugar, debe crear una cuenta.
  • Después de haber conectado la placa a Cayena se le dirigirá automáticamente a la consola donde se pueden utilizar los widgets personalizados disponibles.
  • Asegúrese de especificar correctamente el canal y corresponden a ese canal para enviar datos en el código.
  • Después de que hayas hecho eso, cree un nuevo proyecto y arrastrar y soltar widgets como de sus dispositivos.
  • El siguiente es un código de ejemplo para que comprendas cómo Protocolo MQTT. También utilizaremos la biblioteca Cayena-MQTT-ESP8266 para hacer las cosas mucho más fácil para nosotros.
    <#include 
    
    char ssid[] = "ssid";
    char wifiPassword[] = "wifiPassword";
    
    char username[] = "MQTT_USERNAME";
    
    char password[] = "MQTT_PASSWORD";
    char clientID[] = "CLIENT_ID";
    
    void setup() {
    
      Serial.begin(9600);
      Cayenne.begin(username, password, clientID, ssid, wifiPassword);
    }
    
    void loop() {
    
     Cayenne.loop(); //this function must be called regularly to keep the connection stable
      float sensorInfo = analogRead(A0);
      Cayenne.virtualWrite(0, sensorInfo); //virtualWrite(channel, data) is function with two parameters. Channel - you want to send the data to and second parameter is the data itself.
    }
  • Después de eso, usted será capaz de enviar y recibir datos sin problemas. Para este , se ha usado sólo dos widgets icono es decir ‘temperatura’ y ‘humedad’.
  • Después de crear una cuenta, haga clic en ‘Add New’.
  • A continuación, haga clic en ‘Dispositivo/Widget’Haga clic en «Traiga su propia cosa», que es en la parte inferior.Una nueva página aparecerá indicando su nombre de usuario MQTT, contraseña y el ID de cliente que son únicas para usted. Estos se aplicarán en el código para identificar el dispositivo.

Estructura del código final

La longitud total del código es alrededor de 550 líneas.

El código está dividido en dos secciones. Una PageDisplay y otra DecMaker (abreviatura de decisiones). Cada vez que usted pulsa cualquier botón, basado en que (derecha o izquierda), la pantalla mostrará esa página. Cuando en página y el centerButton, el código se moverá a la DecMaker. Dentro de la función DecMaker y basado en qué página estaba finalmente abierta, ejecutará las acciones correspondientes. Puede recibir datos meteorológicos, sensores, alarmas y temporizadores.

Las páginas se muestran según los modos. Los modos son cuatro. Pueden ser,

  1. Inicio modo: para obtener los datos meteorológicos y visualizarlos. Así como percibir el entorno.
  2. Modo set timer – establecer temporizadores para usted
  3. Modo de programar la alarma – establecer alarmas para que usted
  4. Panel de control – cuando tu no en cualquiera de los modos, prefiere podría quedarse en el tablero de instrumentos.

A continuación, vamos a hablar sobre el sketch principal 

Paso 9: El código principal

El siguiente es el código principal.

Para descargar el código, haga clic aquí.

LiquidCrystal lcd(16, 5, 4, 0, 2, 14);
#define rightButton 13
#define centerButton 15
#define leftButton 12
#define buzz 3
int page = 1;
byte leftArrow[8]
{ B00000,
 B00010,
 B00110,
 B01110,
 B11110,
 B01110,
 B00110,
 B00010
};
byte rightArrow[8]{
 B00000,
 B01000,
 B01100,
 B01110,
 B01111,
 B01110,
 B01100,
 B01000
};
byte line[8]
 { B00110,
 B00110,
 B00110,
 B00110,
 B00110,
 B00110,
 B00110,
 B00110
};
String result;
char servername[]="api.openweathermap.org";
String APIKEY = "Your Api key";
String CityID = "Your city ID";</p><p>String Description;<br>String Place;
float Temperature;
float Humidity;
float w;
WiFiClient client;
dht DHT;#define pin 1
int set=1; // for configuring the alarm
int a, b, c; // used to denote the hour, minute and second while setting an alarm</p>
char username[] = "MQTT_username";<br>char password[] = "MQTT_password";
char clientID[] = "Client ID";

void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 WiFi.begin("ssid", "password");
 lcd.print("Weather box");
 delay(2000);
 lcd.clear();
 if (WiFi.status() == WL_CONNECTED){
 Cayenne.begin(username, password, clientID);
 lcd.print("Connected!");
 delay(3000);
 lcd.clear();
 Serial.println(WiFi.localIP());
 } else {
 lcd.print("Not conn");
 delay(3500);
 }
 lcd.clear();
 lcd.begin(16, 2);
 lcd.createChar(0, leftArrow);
 lcd.createChar(1, rightArrow);
 lcd.createChar(3, line);
 
 pinMode(rightButton, INPUT);
 pinMode(centerButton, INPUT);
 pinMode(leftButton, INPUT);
 pinMode(buzz, OUTPUT);
 digitalWrite(buzz, LOW);
 
 setTime(15, 12, 50, 25, 5, 17);
 delay(1000);
}
int val = 1;
int x,y; //for setting timer minutes and seconds
int trig; //for coniguring the timer
int counter = 0;
void loop() {
 // put your main code here, to run repeatedly:
 while(val == 1){
 if (digitalRead(leftButton)==HIGH)
 { val = 0;}
 lcd.clear();
 lcd.print(hour());
 lcd.print(":");
 lcd.print(minute());
 lcd.write(byte(3));
 lcd.print("WiFi:");
 if (WiFi.status() == WL_CONNECTED){
 lcd.print("conn"); } 
 else {
 lcd.print("Nconn");} 
 lcd.setCursor(0, 1);
 lcd.write(byte(0));
 lcd.print("Menu");
 lcd.write(byte(3));
 
 if (digitalRead(centerButton)){
 DHT.read11(pin);
 lcd.print("T:");
 int a = DHT.temperature; //converting float to int
 lcd.print(a);
 int b = DHT.humidity; // converting float to int
 lcd.print(" H:");
 lcd.print(b);
 delay(3000);
 }else {
 date();
 }
 counter++;
 if (counter == 60){
 if (WiFi.status()==WL_CONNECTED){
 Cayenne.loop(); 
 DHT.read11(pin); 
 Cayenne.virtualWrite(1, DHT.temperature);
 Cayenne.virtualWrite(2, DHT.humidity); 
 } 
 counter = 0;
 }
 delay(50);
 }
 while (val != 1){
 delay(200);
 pageDisplay();
 if (digitalRead(rightButton)){
 if (page == 4){
 page = page;
 } else {
 page++;
 }
 pageDisplay();
 
 } else if (digitalRead(leftButton)){
 if (page == 1){
 page = page;
 } else {
 page--;
 }
 pageDisplay();
 
 } else if (digitalRead(centerButton)== HIGH){
 decMaker();
 }
 }
}
void pageDisplay()
{ switch(page){
 case 1:
 lcd.clear();
 lcd.setCursor(6, 0);
 lcd.print("Home");
 lcd.setCursor(15, 0);
 lcd.write(byte(1));
 break;
 case 2:
 lcd.clear();
 lcd.write(byte(0));
 lcd.setCursor(3, 0);
 lcd.print("Set Timer");
 lcd.setCursor(15, 0);
 lcd.write(byte(1));
 break;
 case 3: 
 lcd.clear();
 lcd.write(byte(0));
 lcd.setCursor(3, 0);
 lcd.print("Set Alarm");
 lcd.setCursor(15, 0);
 lcd.write(byte(1));
 break;
 case 4:
 lcd.clear();
 lcd.write(byte(0));
 lcd.setCursor(3, 0);
 lcd.print("Dash Board");
 break;
 default:
 lcd.clear();
 lcd.print("Error 002");
 break;
 }
}
void date(){
 lcd.print(day());
 lcd.print(" ");
 int a = month();
 switch(a){
 case 1:
 lcd.print("Jan");
 break;
 case 2:
 lcd.print("Feb");
 break;
 case 3:
 lcd.print("Mar");
 break;
 case 4:
 lcd.print("Apr");
 break;
 case 5:
 lcd.print("May");
 break;
 case 6:
 lcd.print("Jun");
 break;
 case 7:
 lcd.print("Jul");
 break;
 case 8:
 lcd.print("Aug");
 break;
 case 9: 
 lcd.print("Sep");
 break;
 case 10:
 lcd.print("Oct");
 break;
 case 11:
 lcd.print("Nov");
 break;
 case 12:
 lcd.print("Dec");
 break;
 default:
 lcd.print("005");
 }
 if (day()<10){
 lcd.print(" ");
 }
 lcd.print(year());
 }
void decMaker(){
 switch(page){
 case 1:
 lcd.clear();
 lcd.print(". . .");
 weatherData(); 
 lcd.clear();
 while (digitalRead(leftButton) == LOW){
 weatherData();
 digitalRead(leftButton);
 lcd.setCursor(6, 0);
 lcd.print("IST:");
 lcd.setCursor(5, 1);
 lcd.print(hour());
 lcd.print(":");
 lcd.print(minute());
 delay(3000);
 lcd.clear();
 lcd.print("Wthr in ");
 lcd.print(Place);
 lcd.setCursor(0, 1);
 lcd.print("T:");
 lcd.print(Temperature);
 lcd.setCursor(9, 1);
 lcd.print("H:");
 lcd.print(Humidity);
 delay(3000);
 lcd.clear();
 digitalRead(leftButton);
 lcd.print("Wind: ");
 lcd.print(w);
 lcd.print("kmph");
 lcd.setCursor(0, 1);
 lcd.print(Description);
 delay(2000);
 lcd.clear();
 DHT.read11(pin);
 lcd.print("Room: ");
 lcd.setCursor(0, 1);
 lcd.print("T:");
 lcd.print(DHT.temperature);
 lcd.setCursor(9, 1);
 lcd.print("H:");
 lcd.print(DHT.humidity);
 delay(2000);
 lcd.clear();
 }
 lcd.begin(16, 2); // In my case the lcd doesn't work without this. But don't know why.
 break;
 case 2:
 setTimer();
 break;
 case 3:
 setAlarm();
 Serial.print("THREE");
 lcd.begin(16, 2);
 break;
 case 4:
 Serial.print("FOUR");
 val = 1;
 break;
 default:
 Serial.print("not a valid entry");
 lcd.clear();
 lcd.print("error 001");
 break;
 }
}
void weatherData()
{ if (client.connect(servername, 80)) 
{ //starts client connection, checks for connection
 client.println("GET /data/2.5/weather?id="+CityID+"&units=metric&APPID="+APIKEY);
 Serial.println("Server is accessable");
 client.println();
 } 
 else {
 Serial.println("connection failed"); //error message if no client connect
 Serial.println();
 }
 result = "";
 while (client.available()) { //connected or data available
 char c = client.read(); //gets byte from ethernet buffer
 result = result+c;
 }
 result.replace("[", " ");
 result.replace("]", " ");
 client.stop(); //stop client
 Serial.println("Recieved");
 
 StaticJsonBuffer<1024> jbuff;
 JsonObject &root = jbuff.parseObject(result);
 if (!root.success())
 {
 Serial.println("parseObject() failed");
 }
String location = root["name"];
 float temperature = root["main"]["temp"];
 float humidity = root["main"]["humidity"];
 String description = root["weather"]["description"];
 float wind = root["wind"]["speed"];
Place = location;
 Temperature = temperature;
 Humidity = humidity;
 w = wind * 3.6;
 Description = description;
}
void alarm()
{ Serial.println("Alarm activated");
 lcd.clear();
 lcd.print("Wake up, Lazy");
 for (int i = 0; i <= 10; i++){
 digitalWrite(buzz, HIGH);
 delay(80);
 digitalWrite(buzz, LOW);
 delay(80);
 digitalWrite(buzz, HIGH);
 delay(80);
 digitalWrite(buzz, LOW);
 delay(800);
 }
 digitalWrite(buzz, LOW);
 set = 0;
}
void setAlarm(){
 set = 1;
 int pos = 1;
 a, b, c = 0;
 repeat:
 //timeDisplay();
 lcd.clear(); 
 lcd.setCursor(0, 0); 
 lcd.print(a); 
 lcd.print(":");
 lcd.print(b); 
 lcd.print(":");
 lcd.print(c); 
 lcd.setCursor(0, 1);
 if (pos == 1){ lcd.print("hours");}
 else if (pos == 2){ lcd.print("minutes");}
 else if (pos == 3){lcd.print("seconds");}
 delay(200);
 if (digitalRead(leftButton)){//leftButton
 if (pos == 3)
 {pos = 1;}
 else 
 {pos++;}
 } else if (digitalRead(rightButton)){
 switch (pos){
 case 1:
 if (a == 23){ a = 0;}
 else {a++;}
 break;
 case 2:
 if (b == 59){ b = 0;}
 else {b++;}
 break;
 case 3:
 if (c == 59){ c = 0;}
 else {c++;}
 break;
 }
 } else if (digitalRead(centerButton)){
 confirmAlarm();
 } 
 if (set == 0){
 goto endIt;
 }
 goto repeat;
 endIt:
 Serial.println("Alarm executed successfully");
}

void confirmAlarm()
{ lcd.clear();
 Alarm.alarmOnce(a, b, c, alarm);
 up:
 lcd.setCursor(1, 0);
 lcd.print("Alarm Running");
 lcd.setCursor(3, 1);
 lcd.print(hour());
 lcd.print(":");
 lcd.print(minute());
 lcd.print(":");
 lcd.print(second());
 Alarm.delay(200);
 delay(1);
 lcd.clear();
 //timeDisplay();
 Serial.println("...");
 if (set == 0||digitalRead(centerButton)){goto down;}
 goto up;
 down:
 set = 0;
}
void setTimer(){
 int cur = 1;
 x, y = 0;
 trig = 1;
 roof:
 lcd.clear();
 lcd.setCursor(2, 0);
 lcd.print("minutes: ");
 lcd.print(x);
 lcd.setCursor(2, 1);
 lcd.print("seconds: ");
 lcd.print(y);
 if (cur == true){lcd.setCursor(0, 0); lcd.write(byte(1));}
 else {lcd.setCursor(0, 1); lcd.write(byte(1));}
 delay(200);
 if (digitalRead(rightButton)){
 switch(cur){
 case 1:
 if (x == 20){x=0;}
 else {x++;}
 break;
 case 2:
 if (y == 59){y = 0;}
 else {y++;}
 break;
 default: 
 lcd.clear();
 lcd.print("ERROR 003");
 }
 } else if (digitalRead(leftButton)){
 if (cur == 2){cur = 1;}
 else {cur++;}
 }
 if (digitalRead(centerButton)){
 confirmTimer();
 } else {
 goto roof;
 }
 trig = 0;
 lcd.setCursor(0, 0);
 lcd.print("Timer successful");
 delay(2000);
 lcd.clear();
}</p><p>void confirmTimer(){<br> int z;
 z = x*60 + y;
 Alarm.timerOnce(z, timer);
 lcd.clear();
 
 sky:
 Serial.println(".");
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("CountDown Timer");
 lcd.setCursor(7, 1);
 lcd.print(z);
 z--;
 Alarm.delay(999);
 delay(1);
 if (trig == 0||digitalRead(centerButton)==HIGH){goto ground;}
 goto sky;
 ground:
 trig = 0;
 lcd.clear();
}
void timer(){
 Serial.println("Boom, timer is on!! :)");
 lcd.clear();
 lcd.setCursor(3, 0);
 lcd.print("Time's Up!");
 for (int i = 0; i<=10; i++){
 for (int j = 0; j<=3; j++){
 digitalWrite(buzz, HIGH);
 delay(70);
 digitalWrite(buzz, LOW);
 delay(70);
 }
 delay(700);
 }
 trig = 0;
}

Mas información en http://www.instructables.com/id/IoT-Weather-Box-with-Custom-Alarms-Timers/