como dice el título más o menos, mediante un solo encoder deseo modificar dos variables, haciendo el cambio mediante un pulsador (he sido incapaz de hacer servir el propio del encoder)
Estoy usando una nano, y el código actual hasta dónde he llegado, mediante el pulsador si accedo a la variable en cuestión, pero al querer modificar el valor sólo me permite de 0 a 1... con una sola variable y sin cambios si que funciona... agradecería una ayudita...
(todo ello se muestra en lcd y va combinado con una sonda de temperatura, pero con estos elementos no tengo problema)
adjunto código por si ven algo que esté haciendo mal....
muchas gracias!!
#include <Wire.h> // libreria necesaria para bus I2C
#include <LiquidCrystal_I2C.h> // libreria necesaria para display I2C
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>
//Encoder myEnc2(2, 3);
//Encoder myEnc(2, 3);
#define LED 11
#define push 9
int push_lee = 0;
int estadoLed = 0;
int estadoAnterior = 0;
OneWire ourWire(6); //Se establece el pin 7 como bus OneWire
DallasTemperature sensors(&ourWire); //Se declara una variable u objeto para nuestro sensor
LiquidCrystal_I2C lcd(0x27,16,2); // configuramos el LCD en la direccion de bus I2C que es
// 0x27 y el tamaño columnas x filas 16x2
const int rele = 5;
long oldPosition = 0; //encoder
long oldPosition2 = 0; //encoder
void setup()
{
lcd.init(); // initialza el lcd
lcd.backlight(); // enciende la luz de fondo del display
pinMode(LED, OUTPUT);
pinMode(push, INPUT);
Serial.begin(9600);
sensors.begin();
pinMode(rele,OUTPUT);
oldPosition = 0; //encoder
oldPosition2 = 0;
//pinMode(LED,OUTPUT);
//pinMode(BOTON,INPUT);
}
void loop()
{
push_lee = digitalRead(push);
if ((push_lee == 1) && (estadoAnterior == 0)) {
estadoLed = 1 - estadoLed;
//delay(10);
}
estadoAnterior = push_lee;
if (estadoLed == 1) {
digitalWrite(LED, HIGH);
Encoder myEnc(2, 3);
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.print("valor1: ");
Serial.println(newPosition);
}
} else {
digitalWrite(LED, LOW);
Encoder myEnc2(2, 3);
long newPosition2 = myEnc2.read();
if (newPosition2 != oldPosition2) {
oldPosition2 = newPosition2;
Serial.print("valor2: ");
Serial.println(newPosition2);
}
}
}
//lcd.clear();
// delay(1000);
if (estadoLed == 1) {
digitalWrite(LED, HIGH);
Encoder myEnc(2, 3); // <== Defines el encoder para los pines 2 y 3
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.print("valor1: ");
Serial.println(newPosition);
}
} else {
digitalWrite(LED, LOW);
Encoder myEnc2(2, 3); // <== vuelves a definir en los mismos pines
Librería Enconder que dice?
Supongamos que fuera lo que yo he indicado.
Lo primero es que luego de llamar a la libreria se instancia el objeto
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(5, 6);
// avoid using pins with LEDs attached
Esos pines deberías ser preferentemente aquelos que tienen interrupciones en el arduino que estes usando.
para un UNO/NANO hablamos de pines 2 y 3 asi que por ahi vas bien
Pero eso no se hace en el loop.
Mira los ejemplos de tu librería y verifica si funcionan bien, y luego volvemos a tu menú.
efectivamente los pines del encoder los defino en la cabezera, el ejemplo de codigo que he pegado aquí es una de las mil pruebas que he ido haciendo y se han quedado dentro del loop... si hago sólo el incremental para una única variable no hay problema. No lo hace bien cuando intento "meter" dos variables en el juego con un sólo encoder. de hecho, ahora mismo estoy probando de hacer lo mismo sin la libreria encoder.h y me arroja el mismo resultado...
#include <Wire.h> // libreria necesaria para bus I2C
#include <LiquidCrystal_I2C.h> // libreria necesaria para display I2C
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>
//Encoder myEnc2(2, 3);
//Encoder myEnc(2, 3);
#define LED 11
#define push 9
int CLK=2;
int DT=3;
int CLK2=2;
int DT2=3;
int anteriorCLK;
int valorCLK;
int valorDT;
int cont;
int anteriorCLK2;
int valorCLK2;
int valorDT2;
int cont2;
int push_lee = 0;
int estadoLed = 0;
int estadoAnterior = 0;
OneWire ourWire(6); //Se establece el pin 7 como bus OneWire
DallasTemperature sensors(&ourWire); //Se declara una variable u objeto para nuestro sensor
LiquidCrystal_I2C lcd(0x27,16,2); // configuramos el LCD en la direccion de bus I2C que es
// 0x27 y el tamaño columnas x filas 16x2
const int rele = 5;
//long oldPosition = 0; //encoder
//long oldPosition2 = 0; //encoder
void setup()
{
lcd.init(); // initialza el lcd
lcd.backlight(); // enciende la luz de fondo del display
pinMode(LED, OUTPUT);
pinMode(push, INPUT);
Serial.begin(9600);
sensors.begin();
pinMode(rele,OUTPUT);
//oldPosition = 0; //encoder
//oldPosition2 = 0;
//pinMode(LED,OUTPUT);
//pinMode(BOTON,INPUT);
pinMode(LED, OUTPUT);
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
digitalWrite(LED, LOW);
anteriorCLK=digitalRead(CLK);
cont=0;
pinMode(CLK2, INPUT);
pinMode(DT2, INPUT);
digitalWrite(LED, LOW);
anteriorCLK2=digitalRead(CLK2);
cont2=0;
}
void loop()
{
push_lee = digitalRead(push);
if ((push_lee == 1) && (estadoAnterior == 0)) {
estadoLed = 1 - estadoLed;
//delay(10);
}
estadoAnterior = push_lee;
if (estadoLed == 1) {
digitalWrite(LED, HIGH);
valorCLK=digitalRead(CLK);
if(valorCLK!=anteriorCLK){
valorDT=digitalRead(DT);
if(valorDT==valorCLK){ //derecha
cont++;
if(cont>255){
cont=0;
}
}else{ //izquierda
cont--;
if(cont<0){
cont=255;
}
}
analogWrite(LED,cont);
anteriorCLK=valorCLK;
Serial.print("valor1: ");
Serial.print(valorCLK);
Serial.print("-");
Serial.print(anteriorCLK);
Serial.print("-");
Serial.println(valorDT);
delay(1000);
}
}
else {
digitalWrite(LED, LOW);
valorCLK2=digitalRead(CLK2);
if(valorCLK2!=anteriorCLK2){
valorDT2=digitalRead(DT2);
if(valorDT2==valorCLK2){ //derecha
cont2++;
if(cont2>255){
cont2=0;
}
}else{ //izquierda
cont2--;
if(cont2<0){
cont2=255;
}
}
analogWrite(LED,cont);
anteriorCLK2=valorCLK2;
Serial.print("valor2: ");
Serial.println(valorCLK2);
}
}
}
//lcd.clear();
// delay(1000);
valor2: 0
valor2: 1
valor2: 0
valor2: 1
valor2: 0
valor2: 1
<<<<<<<<<<<<------aqui es cuando presiono pulsador
valor1: 1-1-1 <<<--- en el caso del valor1, saco por monitor el valor de las variables para ver como se comportan...
valor1: 0-0-0
valor1: 1-1-1
valor1: 0-0-0
por fin he logrado que mediante un pulsador seleccione una variable u otra, y mediante encoder subir o bajar ese valor... pero ahora me encuentro que a la que quiero imprimir los datos por serial o por el lcd, a la que lo pongo en el loop, no funciona correctamente... me podriaís ayudar o decirme dónde o como es mejor colocar esas funciones?
#include <Wire.h> // libreria necesaria para bus I2C
#include <LiquidCrystal_I2C.h> // libreria necesaria para display I2C
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>
#define LED 11
#define push 9
//variables per a encoder e incrementals
int CLK = 2;
int DT = 3;
int CLK2 = 2;
int DT2 = 3;
int anteriorCLK;
int valorCLK;
int valorDT;
int cont;
int anteriorCLK2;
int valorCLK2;
int valorDT2;
int cont2;
//variables del pulsador
int push_lee = 0;
int estadoLed = 0;
int estadoAnterior = 0;
OneWire ourWire(6); //Se establece el pin 6 como bus OneWire
DallasTemperature sensors(&ourWire); //Se declara una variable u objeto para nuestro sensor
LiquidCrystal_I2C lcd(0x27, 16, 2); // configuramos el LCD en la direccion de bus I2C que es
// 0x27 y el tamaño columnas x filas 16x2
//variable relè
const int rele = 5;
void setup()
{
lcd.init(); // initialza el lcd
lcd.backlight(); // enciende la luz de fondo del display
pinMode(LED, OUTPUT); //definicio sortida polsador
pinMode(push, INPUT);
Serial.begin(9600);
sensors.begin(); //inici sensor
pinMode(rele, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
digitalWrite(LED, LOW);
anteriorCLK = digitalRead(CLK);
cont = 0;
pinMode(CLK2, INPUT);
pinMode(DT2, INPUT);
digitalWrite(LED, LOW);
anteriorCLK2 = digitalRead(CLK2);
cont2 = 0;
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
}
void imprimirLCD()
{
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
int temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
lcd.setCursor(0,0); // apuntamos el cursor a la primera fila y primer caracter e
lcd.print("Temp. Actual: ");
lcd.setCursor(14,0);
lcd.print(temp);
lcd.setCursor(0, 1);
lcd.print("Ton: ");
lcd.setCursor(4, 1);
lcd.print(cont);
lcd.setCursor(8, 1);
lcd.print("Toff: ");
lcd.setCursor(14, 1);
lcd.print(cont2);
}
void imprimirSerial()
{
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
int temp= sensors.getTempCByIndex(0);
Serial.print("Temp. Actual: ");
Serial.println(temp);
Serial.print(" valor1: ");
Serial.println(cont);
Serial.print("valor2: ");
Serial.println(cont2);
delay(500);
}
void loop()
{
imprimirLCD();
push_lee = digitalRead(push);
if ((push_lee == 1) && (estadoAnterior == 0)) {
estadoLed = 1 - estadoLed;
delay(10);
}
estadoAnterior = push_lee;
if (estadoLed == 1) {
digitalWrite(LED, HIGH);
valorCLK = digitalRead(CLK);
if (valorCLK != anteriorCLK) {
valorDT = digitalRead(DT);
if (valorDT == valorCLK) { //derecha
cont++;
if (cont > 101) {
cont = 0;
}
} else { //izquierda
cont--;
if (cont < 0) {
cont = 0;
}
}
analogWrite(LED, cont);
anteriorCLK = valorCLK;
//delay(1000);
}
}
else {
digitalWrite(LED, LOW);
valorCLK2 = digitalRead(CLK2);
if (valorCLK2 != anteriorCLK2) {
valorDT2 = digitalRead(DT2);
if (valorDT2 == valorCLK2) { //derecha
cont2++;
if (cont2 > 101) {
cont2 = 0;
}
} else { //izquierda
cont2--;
if (cont2 < 0) {
cont2 = 0;
}
}
analogWrite(LED, cont);
anteriorCLK2 = valorCLK2;
}
}
}
#include <Encoder.h>
#include <Bounce2.h>
#define ENCODER_SW 9
#define ENCODER_CLK 2
#define ENCODER_DT 3
#define CANTIDAD_DE_VAIRABLES 3
#define MINIMO_VARIABLE_UNO 0
#define MAXIMO_VARIABLE_UNO 101
#define MINIMO_VARIABLE_DOS 20
#define MAXIMO_VARIABLE_DOS 100
#define MINIMO_VARIABLE_OTRA -20
#define MAXIMO_VARIABLE_OTRA 20
Encoder myEnc(ENCODER_CLK, ENCODER_DT);
Bounce pulsadorEncoder;
long variableUno = MINIMO_VARIABLE_UNO;
long variableDos = MINIMO_VARIABLE_DOS;
long variableOtra = MINIMO_VARIABLE_OTRA;
int variableActiva = 0;
void setup()
{
pulsadorEncoder.attach(ENCODER_SW, INPUT_PULLUP);
pulsadorEncoder.interval(10);
Serial.begin(9600);
}
void loop()
{
pulsadorEncoder.update();
if (pulsadorEncoder.fallingEdge()) { // Cambiar fallingEdge por risingEdge dependiendo de si se quiere que actue al presional o al soltar el botón
variableActiva = (variableActiva + 1) % CANTIDAD_DE_VAIRABLES; // variableActiva valdrá de 0 a (CANTIDAD_DE_VAIRABLES - 1).
switch (variableActiva) {
// Cuidado, la primera es la que vale 0, no la que vale 1
case 0:
Serial.print(F("Seleccionada la variable uno: "));
Serial.println(variableUno);
break;
case 1:
Serial.print(F("Fijando la variable dos: "));
Serial.println(variableDos);
break;
case 2:
Serial.print(F("Estableciendo otra variable: "));
Serial.println(variableOtra);
break;
}
}
long cambio = myEnc.readAndReset();
if (cambio) {
switch (variableActiva) {
// Cuidado, la primera es la que vale 0, no la que vale 1
case 0:
variableUno += cambio;
if (variableUno < MINIMO_VARIABLE_UNO) {
variableUno = MINIMO_VARIABLE_UNO;
}
if (variableUno > MAXIMO_VARIABLE_UNO) {
variableUno = MAXIMO_VARIABLE_UNO;
}
Serial.print(F("Uno: "));
Serial.println(variableUno);
break;
case 1:
variableDos += cambio;
if (variableDos < MINIMO_VARIABLE_DOS) {
variableDos = MINIMO_VARIABLE_DOS;
}
if (variableDos > MAXIMO_VARIABLE_DOS) {
variableDos = MAXIMO_VARIABLE_DOS;
}
Serial.print(F("Dos: "));
Serial.println(variableDos);
break;
case 2:
variableOtra += cambio;
if (variableOtra < MINIMO_VARIABLE_OTRA) {
variableOtra = MINIMO_VARIABLE_OTRA;
}
if (variableOtra > MAXIMO_VARIABLE_OTRA) {
variableOtra = MAXIMO_VARIABLE_OTRA;
}
Serial.print(F("Otra: "));
Serial.println(variableOtra);
break;
}
}
}
Es sólo un ejemplo de cómo hacer algo como lo que creo que quieres hacer y he usado tres variables. Las variables las he llamado variableUno, variableDos y variableOtra para que "sea visible" que no tienen porqué ser "la misma cosa". Con variableActiva controlamos qué variable se va a modificar. Hay que tener en cuenta que variableActiva tendrá, en este caso, valores de 0 a 2. Se podría tener un array de variables y "controlarlas todas por igual" pero creo que lo que interesa es que tanto el cambio de selección de variable, como el cambio de los valores, se controlen "de forma personalizada". Esto permite que, de ser necesario, el código fuera muy diferente para cada una de las variables.
Una cosa muy importante a tener en cuenta: no poner ningún delay(). El uso del delay() hace que cualquier programa deje de funcionar "con fluidez".
Para evitar los problemas de rebotes, y por comodidad, he usado la librería Bounce2 para controlar el pulsador del encoder (la función pulsadorEncoder.fallingEdge() es útil para deterctar fácilmente cuando se presiona el botón). Para el encoder he usado la librería que indicó surbyte (librería encoder).
Nótese que aprovecho la función myEnc.readAndReset() para obtener sólo el incremento/decremento que produce el encoder y sumar su valor a la variable que se esté controlanto en ese momento.
Para cada variable se controlan unos límites diferentes, sólo a modo de demostración.
probaré el codigo con estas librerias que mencionas, bien seguro es más fluido... el problema que tenía lo he solucionado implementando millis.
A parte al código he añadido la gestión de un relé y una alarma zumbador. Funcionar, funciona... pero no tengo experiencia y bien seguro se podría depurar...
lo adjunto por si alguien le puede hacer uso...
un saludo,
#include <Wire.h> // libreria necesaria para bus I2C
#include <LiquidCrystal_I2C.h> // libreria necesaria para display I2C
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Encoder.h>
#define LED 11
#define push 9
#include <EEPROM.h>//Se incluye la librería EEPROM
int Direccion1 = 1;
int Direccion2 = 2;
//variables per a encoder e incrementals
int CLK = 2;
int DT = 3;
int CLK2 = 2;
int DT2 = 3;
int anteriorCLK;
int valorCLK;
int valorDT;
int cont;
int anteriorCLK2;
int valorCLK2;
int valorDT2;
int cont2;
const int pinBuzzer = 13;
bool isAlarmOn = 0;
//variables del pulsador
int push_lee = 0;
int estadoLed = 0;
int estadoAnterior = 0;
OneWire ourWire(6); //Se establece el pin 6 como bus OneWire
DallasTemperature sensors(&ourWire); //Se declara una variable u objeto para nuestro sensor
LiquidCrystal_I2C lcd(0x27, 16, 2); // configuramos el LCD en la direccion de bus I2C que es
// 0x27 y el tamaño columnas x filas 16x2
//variable relè
const int rele = 5;
int periodo = 1000;
unsigned long TiempoAhora = 0;
void setup()
{
pinMode(pinBuzzer, OUTPUT); //definir pin como salida // Definimos el pin 13 como salida alarma
lcd.init(); // initialza el lcd
lcd.backlight(); // enciende la luz de fondo del display
pinMode(LED, OUTPUT); //definicio sortida polsador
pinMode(push, INPUT);
Serial.begin(9600);
sensors.begin(); //inici sensor
pinMode(rele, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
digitalWrite(LED, LOW);
anteriorCLK = digitalRead(CLK);
cont = EEPROM.read(1) ;
cont2 = EEPROM.read(2);
pinMode(CLK2, INPUT);
pinMode(DT2, INPUT);
digitalWrite(LED, LOW);
anteriorCLK2 = digitalRead(CLK2);
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
cont == EEPROM.read(1) ;
cont2 == EEPROM.read(2);
}
bool GetSystemState()
{
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
int temp= sensors.getTempCByIndex(0);
if (temp>cont2){
return true;
}
else
{return false;
}
}
void imprimirLCD()
{
//temperatura();
lcd.setCursor(0,1);
lcd.print("Tmin:");
lcd.setCursor(5, 1);
lcd.print(cont);
lcd.setCursor(8, 1);
lcd.print("Tmax:");
lcd.setCursor(13, 1);
lcd.print(cont2);
}
void imprimirSerial()
{
sensors.requestTemperatures(); //Se envía el comando para leer la temperatura
int temp= sensors.getTempCByIndex(0);
Serial.print("T.Actual: ");
Serial.println(temp);
Serial.print(" valor1: ");
Serial.println(cont);
Serial.print("valor2: ");
Serial.println(cont2);
delay(500);
}
/*void temperatura()
{
sensors.requestTemperatures();
int temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
lcd.setCursor(0,0); // apuntamos el cursor a la primera fila y primer caracter e
lcd.print("Temp. Actual: ");
lcd.setCursor(14,0);
lcd.print(temp);
}
*/
void loop()
{
if(millis() > TiempoAhora + periodo){
TiempoAhora = millis();
//Serial.println("Hola");
sensors.requestTemperatures();
int temp= sensors.getTempCByIndex(0); //Se obtiene la temperatura en ºC
lcd.setCursor(0,0); // apuntamos el cursor a la primera fila y primer caracter e
lcd.print("T.Actual: ");
lcd.setCursor(9,0);
lcd.print(temp);
Serial.print("T.Actual: ");
Serial.println(temp);
Serial.print(" cont: ");
Serial.println(cont);
Serial.print("cont2: ");
Serial.println(cont2);
lcd.setCursor(12, 0);
if(temp<=cont){
if(temp<=cont2){
digitalWrite(rele, HIGH);
lcd.print("ON ");
}}
else{
if(temp>cont){
if(temp>cont2){
digitalWrite(rele, LOW);
lcd.print("OFF");
}}
}
}
cont == EEPROM.read(1) ;
cont2 == EEPROM.read(2);
push_lee = digitalRead(push);
if ((push_lee == 1) && (estadoAnterior == 0)) {
estadoLed = 1 - estadoLed;
delay(10);
}
estadoAnterior = push_lee;
if (estadoLed == 1) {
digitalWrite(LED, HIGH);
valorCLK = digitalRead(CLK);
if (valorCLK != anteriorCLK) {
valorDT = digitalRead(DT);
if (valorDT == valorCLK) { //derecha
cont++;
if (cont > 101) {
cont = 0;
}
} else { //izquierda
cont--;
if (cont < 0) {
cont = 0;
}
}
anteriorCLK = valorCLK;
imprimirLCD();
//delay(1000);
}
}
else {
digitalWrite(LED, LOW);
valorCLK2 = digitalRead(CLK2);
if (valorCLK2 != anteriorCLK2) {
valorDT2 = digitalRead(DT2);
if (valorDT2 == valorCLK2) { //derecha
cont2++;
if (cont2 > 101) {
cont2 = 0;
}
} else { //izquierda
cont2--;
if (cont2 < 0) {
cont2 = 0;
}
}
anteriorCLK2 = valorCLK2;
}
imprimirLCD();
EEPROM.write(Direccion1, cont);
EEPROM.write(Direccion2, cont2);
isAlarmOn = GetSystemState();
if(isAlarmOn)
{
digitalWrite(pinBuzzer, HIGH); // poner el Pin en HIGH
//delay(5000); // esperar 5 segundos
}
else
{
digitalWrite(pinBuzzer, LOW); // poner el Pin en LOW
}
}
}