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:
- nodeMCU (regulador Micro, versión 0.9)
- Pantalla LCD - 16 x 2
- Botones - 3
- Sensor de temperatura DHT11
- Timbre o zumbador
- Placa de prototipos tamaño mini
- Cables de puente
- Resistencia de 1000 Ω - 3
- 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.
- Creo que tenemos que empezar con los botones. Usé un palito de helado estrecho para hacer una base para los botones.
- Luego tomar el nodeMCU y las placa de prototipos y pegarloo a la base de la caja con cinta de doble cara.
- Entonces conectar los botones a los pines de I/O digitales apropiados.
- En tercer lugar, colocar la pantalla LCD y luego agarrarla bien a la caja con algunas cintas desde el interior. .
- Hacer las conexiones de la pantalla LCD.
- 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
- 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.
- 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.
¿Cuáles son las bibliotecas que necesitamos?
- 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.
- 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.
- 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.
- Biblioteca para el sensor DHT11.
- Biblioteca en tiempo de. Para mantener a nuestro tiempo. Las funciones de biblioteca se enumeran aquí.
- Biblioteca de TimeAlarms . Se utiliza para que nos establezcan alarmas y temporizadores. Las funciones de biblioteca se enumeran aquí.
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
}<
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;
}
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,
- Inicio modo: para obtener los datos meteorológicos y visualizarlos. Así como percibir el entorno.
- Modo set timer - establecer temporizadores para usted
- Modo de programar la alarma - establecer alarmas para que usted
- Panel de control - cuando tu no en cualquiera de los modos, prefiere podría quedarse en el tablero de instrumentos.
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; }Esta entrada fue publicada en alarma, Alarma Ventana, Arduino, Cayenne, controlar dispositivo desde internet, desarrollo de aplicaciones, Electronica General, UTILIDADES ORDENADORES y etiquetada como alarma casera avanzada, alarma con display del tiempo, alarma con iot, el tiempo en tu ciudad, sensor iot.