Hola a todos,
estoy empezando con esto del Arduino, no conocía el lenguaje, aunque fui programador hace años.
Hardware que utilizo
Arduino UNO
pantalla oled 128x64
encoder KY-040
Estoy intentando hacer un menú que por medio del encoder pueda mostrar las opciones y una vez en pantalla la deseada, pulsar el encoder para seleccionarla.
El código que os paso es sencillo, si lo ejecuto tal y como esta, la pantalla se inicializa, pero si descomento el 'if del 'loop' o las sentencias 'pantalla.' de menuPrincipal, da error de iniciar pantalla y no funciona. No entiendo, o no sé que puede pasar, agradecería vuestra ayuda para comprenderlo. Me ha pasado en todos los programas en los que utilizo esta pantalla.
hay bastante código anulado como comentario, porque he ido eliminado para dar con las sentencias que provocaban que la pantalla no se iniciara
//*****************************
//** DEFINICION Y CONEXION **
//**
//*****************************
//**** LIBRERIAS ****
//*****************************
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RotaryEncoder.h>
//*****************************
//** definicion **
//** DE HARDWARE **
//*****************************
// Definición de la pantalla OLED
#define ANCHO_PANTALLA 128
#define ALTO_PANTALLA 64
#define RESET_PANTALLA -1
#define DIRECCION_I2C_OLED 0x3C
#define PIN_SDA A4
#define PIN_SCL A5
Adafruit_SSD1306 pantalla(ANCHO_PANTALLA, ALTO_PANTALLA, &Wire, RESET_PANTALLA);
//------------------------------------------------------------------------------
// Definicion del encoder
#define PIN_ENCODER_CLK 2
#define PIN_ENCODER_DT 3
#define PIN_ENCODER_PULSADOR 4
#define PIN_LED_VERDE 5
#define PIN_LED_ROJO 6
//------------------------------------------------------------------------------
// definicion de funciones
//--------------------------------------------------------------------------------
// variables para el manejo del encoder
bool primeraVez = true;
int ANTERIOR = 0; // almacena valor anterior de la variable movimientoEncoder
int ultimoPulsadorEncoder = 0; // valor encoder del pulsador
volatile int pulsadorEncoder = 0; // valor encoder del pulsador
bool estadoPulsador = 0;
volatile int movimientoEncoder = 1; // variable movimientoEncoder con valor inicial de 50 y definida
volatile int limiteMaxEncoder = 0; // valor maximo del encoder
volatile int limiteMinEncoder = 0; //valor minimo del encoder
volatile int limite = 1; // limite = 1 (Min 1, Max 2)
static unsigned long ultimaInterrupcion = 0; // variable static con ultimo valor de
// tiempo de interrupcion
//-------------------------------------------------------------------------------
// variables para el manejo del menu
// Variables para controlar el menú
volatile int opcionMenu = 0; // opcion seleccionada
// 1 - CONFIGURACION
// 2 - CAMBIO DE AGUA
bool inSubMenu = false; // submenu
//char *opciones[] = { " ", "CONFIGURACION ", "CAMBIO DE AGUA " }; // Arreglo del Menu PRINCIPAL
char opciones[3][14]; // 5 elementos, cada uno con un tamaño máximo de 10 caracteres
// Asignación de valores a las variables del conjunto
// strcpy(opciones[0], "CONFIGURACION ");
// strcpy(opciones[1], "CAMBIO DE AGUA");
// strcpy(opciones[2], "Variable 3");
//-------------------------------------------------------------------------------
//*******************************************************
//**** funciones que nos devuelven datos ****
//*******************************************************
int encoder(volatile int limite) {
//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(PIN_ENCODER_DT) == HIGH) // si PIN_ENCODER_DT es HIGH, sentido horario
{
movimientoEncoder++; // incrementa movimientoEncoder en 1
} else { // si PIN_ENCODER_DT es LOW, senti anti horario
movimientoEncoder--; // decrementa movimientoEncoder en 1
}
}
if (limite == 1) {
limiteMinEncoder = 1;
limiteMaxEncoder = 2;
}
movimientoEncoder = min(limiteMaxEncoder, max(limiteMinEncoder, movimientoEncoder)); // establece limite inferior y
// superior para movimientoEncoder segun que tengamos que leer
ultimaInterrupcion = tiempoInterrupcion; // guarda valor actualizado del tiempo de la interrupcion en variable static
return movimientoEncoder;
}
// //------------------------------------------------------------------------------------------------
// int lecturaPulsadorEncoder() {
// 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.
// //Leer el estado del pin del pulsador del encoder
// boolean estadoPulsador = digitalRead(PIN_ENCODER_PULSADOR);
// Serial.println("lectua pin pulsador = ");
// Serial.println(estadoPulsador);
// if (estadoPulsador == LOW) { // suponemos que al estar en PULLUP, un LOW es que se ha pulsado
// //if (pulsador == LOW) { // suponemos que al estar en PULLUP, un LOW es que se ha pulsado
// pulsadorEncoder = 1;
// } else {
// (pulsadorEncoder = 0);
// }
// // al pulsar damos por terminada la captura de la posicion del encoder y fin de programa
// }
// Serial.print("lectura del pulsador = ");
// Serial.println(pulsadorEncoder);
// ultimaInterrupcion = tiempoInterrupcion; // guarda valor actualizado del tiempo
// return pulsadorEncoder;
// }
//*******************************************************
void setup() {
// Asignación de valores a las variables del conjunto
// strcpy(opciones[1], "CONFIGURACION ");
// strcpy(opciones[2], "CAMBIO DE AGUA");
// strcpy(opciones[0], " ");
// Inicializar el puerto serial con una velocidad de 9600 baudios
Serial.begin(9600);
Serial.println(" ");
Serial.println("entro den Setup");
Wire.begin();
Serial.println("voy a inicioOled");
inicioOled();
movimientoEncoder = 1;
// Asigna funcion de entrada a los PIN del encoder derecha izquierda y pulsador
pinMode(PIN_ENCODER_CLK, INPUT); // pin 2
pinMode(PIN_ENCODER_DT, INPUT); // pin 3
pinMode(PIN_ENCODER_PULSADOR, INPUT_PULLUP); // pin 4
attachInterrupt(digitalPinToInterrupt(PIN_ENCODER_CLK), encoder, LOW); // interrupcion sobre pin A con funcion ISR encoder y modo LOW
// attachInterrupt(digitalPinToInterrupt(PIN_ENCODER_PULSADOR), lecturaPulsadorEncoder, CHANGE); // interrupcion sobre pin A con funcion ISR encoder y modo LOW
}
void loop() {
//Serial.println("entramos en loop");
// Serial.println("voy a menu principal");
// Lectura del encoder y actualización del menú
Serial.print("movimiento encoder = ");
Serial.println(movimientoEncoder);
delay(1000);
int opcionMenu = movimientoEncoder;
Serial.print("Opcion Menu = ");
Serial.println(opcionMenu);
menuPrincipal(opcionMenu);
// Si se pulsa el botón del encoder
// if (pulsadorEncoder == 1) {
// if (opcionMenu == 1) {
// configurar(); // Llamar al programa 'configurar.ino'
// }
// else if (opcionMenu == 2) {
// cambiarAgua(); // Llamar al programa 'cambiarAgua.ino'
// }
// }
}
// //=============================================================================
void inicioOled() {
Serial.println("entro en inicioOled");
// Inicializar la pantalla OLED
pantalla.begin(SSD1306_SWITCHCAPVCC, DIRECCION_I2C_OLED);
Serial.println("intento iniciar pantalla");
if (!pantalla.begin(SSD1306_SWITCHCAPVCC, DIRECCION_I2C_OLED)) {
Serial.println("Error: No se pudo iniciar la pantalla OLED");
while (1)
; // Detener la ejecución en caso de error
}
pantalla.clearDisplay();
pantalla.setTextColor(WHITE); // Color del texto (blanco)
pantalla.setTextSize(1); // Tamaño de las letras (6x8 pixels)
pantalla.setCursor(0, 0);
pantalla.println("termino setup");
pantalla.setCursor(0, 32);
pantalla.println("VOY A MENU");
pantalla.display();
Serial.println("mira si ha funcionado la pantalla");
delay(50);
}
//===================================================================================
// FUNCION PRESENTACION DEL MENU PRINCIPAL
//
void menuPrincipal(int opcionMenu) {
Serial.println("estoy en MENU PRINCIPAL");
if (primeraVez == true) {
primeraVez = false;
movimientoEncoder = 1;
// acotamos los valoes del movimiento encoder a las opcinoes del menu principal
limite = 1;
}
// Serial.print("limite = ");
// Serial.println(limite);
// pantalla.clearDisplay();
// pantalla.setCursor(19, 24);
// pantalla.println(opciones[opcionMenu]);
// pantalla.println("CONFIGURACION");
// pantalla.display();
// MONITOR SERIAL
Serial.println(" ");
Serial.println("entro en MENU PRINCIPAL");
Serial.print("movimientoEncoder = ");
Serial.println(movimientoEncoder);
Serial.print("pulsadorEncoder = ");
Serial.println(pulsadorEncoder);
//
}
//===================================================================================