Buenas tardes gente del foro. Estoy realizando / aprendiendo el uso de Arduino (en mi caso es un Arduino Due) y ademas estoy creando un termostato de ambiente (futuramente va a ser con conexión wifi y bluetooth.
1- Realice el programa del termostato de ambiente y sete que a 24°C se encienda un led (caldera).
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire ourWire(7); //Se establece el pin 2 como bus OneWire
DallasTemperature sensors(&ourWire); //Se declara una variable u objeto para nuestro sensor
LiquidCrystal lcd (44,42,40,38,36,34);
void setup() {
delay(1000);
sensors.begin();//Se inicia el sensor
lcd.begin(16,2);
int LED = 50;
pinMode (50, OUTPUT);
}
void loop() {
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
float temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
delay(500);
lcd.setCursor(0,0);
lcd.print("TEMP.:");
lcd.print(temp);
lcd.print("C");
if (temp < 24)
{
digitalWrite (50, HIGH);
lcd.setCursor(0,1);
lcd.print("Calefaccion ON");
}
else
{
digitalWrite (50, LOW);
lcd.setCursor(0,1);
lcd.print("Calefaccion OFF");
}
}
2- Ahora quiero que esos 24°C sean variables para el usuario. Para esto utilice un encoder rotatorio ky-040.
int A = 5; //DT en modulo
int B = 6; //CLK en modulo
int ANTERIOR = 50;
volatile int POSICION = 10;
void setup() {
pinMode(A, INPUT); // A como entrada
pinMode(B, INPUT); // B como entrada
Serial.begin(9600); // incializacion de comunicacion serie a 9600 bps
attachInterrupt(digitalPinToInterrupt(A), encoder, HIGH);
Serial.println("Listo"); // imprime en monitor serial Listo
}
void loop() {
if (POSICION != ANTERIOR) { // si el valor de POSICION es distinto de ANTERIOR
Serial.println(POSICION); // imprime valor de POSICION
ANTERIOR = POSICION ; // asigna a ANTERIOR el valor actualizado de POSICION
}
}
void encoder() {
static unsigned long ultimaInterrupcion = 0; // variable static con ultimo valor de
// tiempo de interrupcion
unsigned long tiempoInterrupcion = millis(); // variable almacena valor de func. millis
if (tiempoInterrupcion - ultimaInterrupcion > 5) { // rutina antirebote desestima
// pulsos menores a 5 mseg.
if (digitalRead(B) == HIGH) // si B es HIGH, sentido horario
{
POSICION++ ; // incrementa POSICION en 1
}
else { // si B es LOW, senti anti horario
POSICION-- ; // decrementa POSICION en 1
}
POSICION = min(30, max(10, POSICION)); // establece limite inferior de 0 y
// superior de 100 para POSICION
ultimaInterrupcion = tiempoInterrupcion; // guarda valor actualizado del tiempo
} // de la interrupcion en variable static
}
El problema radica en que no se como unir ambos codigos, tanto los void loop con el void encoder del ky040.
Espero que me puedan ayudar. Desde ya muchisimas gracias.
Jonathan
Hola jonistanki,
Bueno, según veo, tienes dos programas ambos con una función setup y una función loop.
Has de colocar las lineas que estén antes de la función setup todas juntas, en su lugar. Las lineas dentro de void_setup todas juntas y las de void_loop juntas también.
Has de tener en cuenta que no haya dos variables que hayan puesto con el mimso nombre en el código 1 y el código 2 (los dos que tienes ahora por separado). Si es así has de cambiar el nombre en uno de los dos códigos para evitar que haga cosas raras.
Permíteme una pregunta.
Para qué el uso de un encoder para hacer un termostáto?
Supongo que la idea es subir y bajar la temperatura de consigna que quieres.
Pero para ello sería más sencillo usar dos pulsadores: uno para subir la temperatura y otro para bajarla.
Un saludo.
Normalmente no hago esto, pero como posteaste bien, te doy una mano aunque deberías seguir los consejos que dio @fontanares para que entiendas lo que hice.
No uses mayúsculas con variables. Se usa para Constantes.
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire ourWire(7); // Se establece el pin 2 como bus OneWire
DallasTemperature sensors(&ourWire); // Se declara una variable u objeto para nuestro sensor
LiquidCrystal lcd (44, 42, 40, 38, 36, 34);
int A = 5; // DT en modulo
int B = 6; // CLK en modulo
int anterior = 50;
volatile int posicion = 10;
void setup() {
delay(1000);
sensors.begin();//Se inicia el sensor
lcd.begin(16, 2);
int LED = 50;
pinMode (50, OUTPUT);
pinMode(A, INPUT); // A como entrada
pinMode(B, INPUT); // B como entrada
Serial.begin(9600); // incializacion de comunicacion serie a 9600 bps
attachInterrupt(digitalPinToInterrupt(A), encoder, HIGH);
Serial.println("Listo"); // imprime en monitor serial Listo
}
void loop() {
if (posicion != anterior) { // si el valor de posicion es distinto de anterior
Serial.println(posicion); // imprime valor de posicion
anterior = posicion ; // asigna a anterior el valor actualizado de posicion
}
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
float temp = sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
delay(500);
lcd.setCursor(0, 0);
lcd.print("TEMP.:");
lcd.print(temp);
lcd.print("C");
if (temp < posicion) {
digitalWrite (50, HIGH);
lcd.setCursor(0, 1);
lcd.print("Calefaccion ON");
}
else {
digitalWrite (50, LOW);
lcd.setCursor(0, 1);
lcd.print("Calefaccion OFF");
}
}
void encoder() {
static unsigned long ultimaInterrupcion = 0; // variable static con ultimo valor de
// tiempo de interrupcion
unsigned long tiempoInterrupcion = millis(); // variable almacena valor de func. millis
if (tiempoInterrupcion - ultimaInterrupcion > 5) { // rutina antirebote desestima
// pulsos menores a 5 mseg.
if (digitalRead(B) == HIGH) { // si B es HIGH, sentido horario
posicion++ ; // incrementa posicion en 1
}
else { // si B es LOW, senti anti horario
posicion-- ; // decrementa posicion en 1
}
posicion = min(30, max(10, posicion)); // establece limite inferior de 0 y
// superior de 100 para posicion
ultimaInterrupcion = tiempoInterrupcion; // guarda valor actualizado del tiempo
} // de la interrupcion en variable static
}
fontanares:
Hola jonistanki,
Bueno, según veo, tienes dos programas ambos con una función setup y una función loop.
Has de colocar las lineas que estén antes de la función setup todas juntas, en su lugar. Las lineas dentro de void_setup todas juntas y las de void_loop juntas también.
Has de tener en cuenta que no haya dos variables que hayan puesto con el mimso nombre en el código 1 y el código 2 (los dos que tienes ahora por separado). Si es así has de cambiar el nombre en uno de los dos códigos para evitar que haga cosas raras.
Permíteme una pregunta.
Para qué el uso de un encoder para hacer un termostáto?
Supongo que la idea es subir y bajar la temperatura de consigna que quieres.
Pero para ello sería más sencillo usar dos pulsadores: uno para subir la temperatura y otro para bajarla.
Un saludo.
Buenos días Fontanares. Mucha gracias por tu pronta respuesta. Entendí a la perfección tu explicación y respondiendo tus consultas: Comercialmente en Argentina se venden termostatos con encoder y en rara ocasión se utiliza botonera para modificar la temperatura de consigna. Aparte quería aprender a usarlo para futuramente hacer un crono termostato.
Muchas gracias.
Buenas noches chicos. Hoy me pude poner con el Arduino nuevamente.
Cargue el programa recomendado por "surByte" y me ocurrio lo siguiente:
-
El programa unificado no inicia sensando la temperatura constantemente (como si lo hace el programa individual que propuse) sino que comienza a medir temperaturas una vez que giro el encoder.
-
La temperatura se fija en un valor y no cambia cuando giro el pomo encoder, no tiene la variación que si tiene con el programa individual.
-
Los cambios de seteo del Ky040 no son de manera rapida, sino que giro varias veces el pomo encoder y a los 10 segundos se actualiza la temperatura.
Algo estoy haciendo mal.
Espero que me puedan ayudar.
Saludos!