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/

Electrónica de una CNC


Cada  vez se  nos pone mas sencillo    interactuar con  el mundo físico , no solo desde el punto de vista  de complejidad, sino también debido a  la  simplicidad  conseguida gracias a  la elevada miniaturización, lo cual  que  se suele traducir en precios muy bajos y diseños sencillos, especialmente  en la parte de la electrónica necesaria.

Como ejemplo usando Arduino se pueden construir muchos tipos de proyectos CNC  gracias al ingenio de muchas personas  así como la ayuda de  la electrónica necesaria  que puede condensarse   simplemente en este escudo   con el que se   pueden  controlar  por medio de un Arduino   3 motores paso a paso gracias a que los propios  módulos de controladores pueden  insertarse en cada zócalo  proporcionando así  la capacidad al eje motor de impulsión 3 motores  paso a paso (X, Y y Z).

cnc_shield_v3_2

En este escudo  para Arduino,  los motores paso a paso se pueden conectar con conectores molex de 4 pines o también se  pueden soldar los cuatro  hilos de cada motor directamente al conector  en su lugar

A propósito de las conexiones soldadas del motor  : la conexión o desconexión de los cables de un motor paso a paso mientras el driver  está alimentado puede destruir al driver  (por ejemplo   soltando por accidente algún hilo, cruzando  entre si  hilos , etc) así que es buena idea que los cables de los  motores estén sólidamente  conectados a la placa.

Asimismo al  igual que otras controladoras, esta placa se alimenta aparte de la fuente de Arduino con una tensión continua entre 12-36V DC.  En este punto es de destacar que por el momento sólo los controladores DRV8825 pueden manejar hasta 36V , por lo que considere un  voltaje de funcionamiento menor  para  alimentar al escudo.

Respecto a los drivers de cada motor como se puede ver en la foto , son enchufables   para facilitar su remplazo en caso de avería o fallo  y   están basados en  controlados de motores paso a paso del tipo   A4988  o DRV8825. Cada driver incluye puentes para configurar el Micro-Stepping para los controladores paso a paso con cinco modos de paso seleccionables: full, 1/2, 1/4, 1/8 y 1/16. (algunos controladores como el DRV8825 pueden hacer hasta 1/32 micro-stepping)

Resumidamente estas son las características de este nuevo escudo controlador multi-driver:

  • Compatibilidad con Arduino GRBL
  • Baja salida RDS (On)
  • Se puede utilizar para una máquina de grabado
  • Es compatible con GRBL 0.9 (Firmware de código abierto que se ejecuta en un Arduino UNO que convierte los comandos de código G en señales para  los motores paso a paso)
  • Soporte de 4 ejes (X, Y, Z, A-Puede duplicar X, Y, Z o hacer un 4to eje completo con firmware personalizado usando los pins D12 y D13)

 

En la siguiente imagen  de un Arduino  vemos la correspondencia con los pines del escudo para el control de los tres motores:.

cnc_shield_v3_3

 

Excepto todos los pines  citados ,  este escudo ( Arduino CNC Shield V3.0 ) contiene otros pines que admiten más funciones:

Arduino-CNC-Shield-Scematics-V3.XX_

Arduino-CNC-Shield-V3-Layout

Las funciones de los pines extras son los siguientes:

  • Interruptor de límite de pines ha sido duplicado por que cada eje tenga un «Top / +» y «fondo /-«. Esto hace más fácil de instalar dos interruptores de límite para cada eje.(usar con un interruptor normalmente abierto)
  • EStop – estos pines se pueden conectar a un interruptor de parada de emergencia. Esto hace lo mismo que el botón RESET en la placa Arduino. ( también puede ser instalado un botón adicional de emergencia que corta la corriente a toda la maquinaria. )
  • Control del husillo y el refrigerante tiene sus propios pins.
  • Comando Pin externos GRBL  se han quitado lo que le permite añadir botones de pausa/espera, reanudar y abortar.
  • Los pines serie (D0-1) y  los de I2C (A4-5) tienen su propia salida   para futuras ampliaciones. Por ejemplo  I2C se podría implementar software para  controlar cosas como la velocidad del huso o control del calor.
  • Versión 3.00 añadió unos jumpers para configurar el eje 4 (clon el otro eje o pin D12-13), comunicaciones (RX+TX, I2C) y una cabecera de control paso a paso (todos los pines necesitan para ejecutar 4 steppers)

Instalación de hardware

Se deben observar las siguientes advertencias:

  • Inversión de la polaridad de la alimentación o conectar incorrectamente la energía destruirá el  escudo
  •  Siempre asegúrese de insertar conexiones en la a orientación correcta y en la toma adecuada  correctamente
  • El escudo de CNC Arduino es compatible con fuentes de alimentación hasta 36V. Eso significa que todos los drivers de chip paso a paso NO se deben alimentar con  ese valor pues  controladores A4988  no están diseñados para funcionar a 36V de modo que si lo alimenta con ese valor  puede destruirlos.  Alimentación de  36V son para los drivers  como la Pololu DRV8825 que pueden funcionar con + 36V

ESQUEMA CONEXIONES PARA MODULO A4988

A4988

ESQUEMA CONEXIONES PARA MODULO DRV8824/DRV8825

DRV8825

ESQUEMA CONEXIONES PARA MODULO TMC2100

TMC2100

Instalación del software

1) Obtener código GRBL en Arduino

Descargar el código GRBL desde enlace:grblmain.zip descomprimir el archivo y copiar a la carpeta de las bibliotecas de arduino IDE, haga clic en abierto arduino IDE File -> ejemplos -> grblmain -> GRBLtoArduino, elegir la mesa correcta y COM, luego cargar el código de GRBLtoArduino a UNO

2) Instalar software de controlador grbl

Descargar software de controlador grbl desde enlace:GrblController.exe , descarga e instala, abra el software de controlador grbl como sigue

grblcontroller361 (2)

Conectar el  Arduino UNO al PC con cable USB, seleccione el puerto correcto, ajustar la velocidad de Baute como «9600», haga clic en «Abrir», una vez conectado, el botón «Abrir» cambiará a «Cerrar/Reset» con color de fondo rojo. Haga clic en «seleccionar archivo» para seleccionar el archivo, haga clic en «Begin» para empezar a  el grabado  (si  es que los motores están configurados en una maquina CNC   al que se haya acoplado un diodo láser  como por ejemplo esta maquina hecha con piezas de CD’s )