(SOLUCIONADO) LCD I2C + Pulsadores Pullup

Hola a tod@s, a ver si me podeis orientar.

Tengo un wemos d1 r1 que controla 5 pulsadores y un LCD 16x2 por i2c.

El codigo que controla los botones funciona ok y cada boton realiza su funcion sin problemas. Por otro lado el lcd se enciende y presenta los mensajes igualmente sin problemas.

El problema viene cuando al presionar un pulsador el mensaje que presenta el LCD tiene que cambiar, y es que no lo hace. Es como si al presionar cualquier pulsador dejase colgado el LCD.

La funcion que controla el LCD es siempre la misma, tanto la que llamo desde el void_setup, como desde el void_loop, con lo que no creo que el problema venga de la libreria ni de la progracion del lcd.

Los pulsadores tambien funcionan perfectos, a pesar de que no muestre la informacion el lcd.

La conexion del lcd la tengo directa a los pines i2c del wemos + alimentacion.

Sabeis si tengo que añadir alguna resistencia o algo por lo que se me pueda estar bloqueando el lcd y no me presente la informacion, a pesar de que el resto del programa si siga funcionando??

Este es el codigo que escribe el lcd.

void LCD (){
   lcd.begin ();
   lcd.setCursor(0,0);
   lcd.print (String("Velocidad ") + String(velocidad));
}

Gracias

Hi, Para poderte ayudar necesitamos el sketch completo que estas usando. Como determinas que tiens que mandar ese mensaje. Por eso se necesita el sketch completo.

Gracias por responder.

Lo que no funciona es simple. A cada pulsacion de un pulsador, se resta 1 en un contador. Este contador determina la velocidad de giro de un motor, y debe de visualizarse en el lcd para saber como estamos trabajando. En este caso es un contador regresivo, de 10 a 0.

Adjunto codigo. Basicamente es el if que controla la variable velocidad. Al pulsar ese pulsador, lo que hay dentro del if se ejecuta correctamente, el motor remoto actua en consecuencia, la salida serial si la activo muestra el valor correcto, pero la pantalla LCD queda con el mensaje que adquirio en la primera llamada que hace el void_setup a LCD().

#include <FS.h>                  .
#include <SPI.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <WiFiUdp.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <SPI.h>

// Direccion ip del motor y puerto donde enviar datos
byte ipmotor[4] = {192, 168, 1, 201};
unsigned int port = 8888; // puerto destino

LiquidCrystal_I2C lcd(0x27,16,2);  
const byte Izquierda = D9;
const byte Derecha = D13;
const byte Velocidad = D5;
const byte Auto = D8;
const byte Modo = D7;
char  MensajeaMotor[20];  //cadena que se enviara

int velocidad=10;
int modo=1;



void setup() {

 Wire.begin();
  lcd.begin ();
  lcd.backlight();
  lcd.setCursor(2,0);
  lcd.print("Control Loop");  //presentacion
  lcd.setCursor(3,1);
  lcd.print("by me");
  delay(3000);

  LCD();
  
pinMode(D9, INPUT);//giro izquiera
pinMode(D13, INPUT);//giro derecha
pinMode(D5, INPUT);//boton velocidad
pinMode(D7, INPUT);//boton cambio modo de funcionamiento
pinMode(D8, INPUT);//boton auto
Serial.begin(115200);
Serial.println();

 
}
void LCD (){
  lcd.begin (); 
 delay(100);
 lcd.setCursor(0,0);
 lcd.printf("Modo Manual");
 lcd.setCursor(0,1);
 lcd.print (String("Velocidad ") + String(velocidad));
 
}
void loop() {
  
if (digitalRead(Izquierda) == LOW){   //Boton izquierda
     int valorPot = 1;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250);    
     }
if (digitalRead(Derecha) == LOW){   //Boton derecha
     int valorPot = 2;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
     }
 if (digitalRead(Velocidad) == LOW){   //Boton velocidad
     int valorPot = 3;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
      if (velocidad == 0){
          velocidad=10;}
          else {
            velocidad=velocidad -1;}
     LCD();    // ESTO ES LO QUE NO SE EJECUTA, Y SI ES QUE LO HACE NO SE VISUALIZA
                  // EL RESTO DEL SKETCH FUNCIONA BIEN
          }
 if (digitalRead(Auto) == LOW){   //Boton auto
     int valorPot = 4;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
    // LCD();
          }
 if (digitalRead(Modo) == LOW){   //Boton modo
     int valorPot = 5;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
     if (modo == 4){
          modo=1;}
          else {
           modo=modo+1;}
    }
}

Aunque el codigo envia datos udp, en este caso el lcd esta en local, es parte de un mando de control que se comunica con un motor y mas adelante con un medidor que hara a su vez de control de motor.
Pero por ahora es lo mas basico, visualizar la informacion en el lcd.

Observa algo

#include <FS.h>                  .
#include <SPI.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <WiFiUdp.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <SPI.h>                    // <== REPETIDA

Otra leve falla aunque funciona esto

lcd.print (String("Velocidad ") + String(velocidad));

es redundante. Una cadena const como “Velocidad” no tiene porque estar dentro de String
Esto es mas eficiente y mas rápido.

lcd.print ("Velocidad "+ String(velocidad));

Otro error.
lcd.begin() debe ejecutarse solo en el setup, no a cada momento.
Y además suele llevar la cantidad de lineas y columnas involucradas como lcd.begin(16,2) o lcd.begin(20,4)

Para mi gusto si lo llamas desde el setup debería estar antes aunque supongo que como no lo comentas te funciona igual.
Yo por orden los pongo al comienzo o al final.

Para mi gusto tu rutina LCD() quedaría asi

void LCD (){
 lcd.setCursor(0,0);
 lcd.printf("Modo Manual");
 lcd.setCursor(0,1);
 lcd.print ("Velocidad " + String(velocidad));
}

y en el setup cambio por esto

void setup() {

  Wire.begin();
  lcd.begin(16,2);      // o como dije lcd.begin(20,4); 
  lcd.backlight();
  lcd.setCursor(2,0);
  lcd.print("Control Loop");  //presentacion
  lcd.setCursor(3,1);
  lcd.print("by me");
  delay(3000);

  LCD();
  
  pinMode(D9, INPUT);//giro izquiera
  pinMode(D13, INPUT);//giro derecha
  pinMode(D5, INPUT);//boton velocidad
  pinMode(D7, INPUT);//boton cambio modo de funcionamiento
  pinMode(D8, INPUT);//boton auto*/
  Serial.begin(115200);
  Serial.println();
}

Hi, En linea con las sugerencias de surbyte si sigues con el problema anadele un mensaje antes de cada if como el siguente mensaje "lcd.printf(" entrada al if numero 1")", La razon es que tienes varios If en el programa y se puede quedar en uno de ellos. Cuando haces esto mensajes se conoce como debug que te permite tener una idea como el programa esta corriendo. Viendo el ultimo mensajes te pude decir donde el programa se quedo. Acuerdate de anadirle un numero mas cuando usas en cada if.

Como se va a quedar en un if ?

Por otro lado envia mensajes UDP de modo que esta viendo que ocurre con dichos mensajes.

Hi, Si, pero en esos if el esta llamando otra routina. UPD

Buenas tardes, disculpar la tardanza, pero el trabajo esta semana ha sido duro y no me ha dejado tiempo para mi aficcion.

He hecho las modificaciones que indicabas surbyte y funcionando está.
No se exactamente donde estaba el fallo, entiendo que en la duplicidad de la libreria spi.h.

Mi codigo queda asi:

#include <FS.h>                   //this needs to be first, or it all crashes and burns...
#include <SPI.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <WiFiUdp.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


// Direccion ip del motor y puerto donde enviar datos
byte ipmotor[4] = {192, 168, 1, 201};
unsigned int port = 8888; // puerto destino
WiFiUDP udp;
LiquidCrystal_I2C lcd(0x27,16,2);  // Set the LCD I2C address
const byte Izquierda = D5;
const byte Derecha = D6;
const byte Velocidad = D7;
const byte Auto = D9;
const byte Modo = D11;
char  MensajeaMotor[20];  //cadena que se enviara

int velocidad=10;
int modo=1;



void setup() {

 Wire.begin();
lcd.begin();      
lcd.backlight();
 lcd.setCursor(2,0);
  lcd.print("Control Loop");  //presentacion
  lcd.setCursor(3,1);
  lcd.print("by me");
  delay(3000);
  LCD();
  
pinMode(D9, INPUT);//giro izquiera
pinMode(D13, INPUT);//giro derecha
pinMode(D5, INPUT);//boton velocidad
pinMode(D7, INPUT);//boton cambio modo de funcionamiento
pinMode(D8, INPUT);//boton acoplador automatico*/
Serial.begin(115200);
Serial.println();

 
}
void LCD (){
 
  delay(100);
 lcd.setCursor(0,0);
 lcd.printf("Modo Manual");
 lcd.setCursor(0,1);
 lcd.print ("Velocidad "+ String(velocidad));
 lcd.setCursor(0,1);
 }
void loop() {
  // put your main code here, to run repeatedly:

if (digitalRead(Izquierda) == LOW){   //Boton izquierda
     int valorPot = 1;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250);    
     }
if (digitalRead(Derecha) == LOW){   //Boton izquierda
     int valorPot = 2;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
     }
 if (digitalRead(Velocidad) == LOW){   //Boton velocidad
     int valorPot = 3;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
      if (velocidad == 0){
          velocidad=10;}
          else {
            velocidad=velocidad -1;}
            lcd.printf(" entrada  al if  velocidad");
            Serial.println("entra al if velocidad");
     LCD(); 
          }
 if (digitalRead(Auto) == LOW){   //Boton autotune
     int valorPot = 4;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
     udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); //pausa para que envie solo un paquete en cada pulsacion
    // LCD();
          }
 if (digitalRead(Modo) == LOW){   //Boton izquierda
     int valorPot = 5;
     sprintf(MensajeaMotor, "ValPot:%i", valorPot); 
     udp.beginPacket(ipmotor, port); 
    udp.write(MensajeaMotor); 
     udp.endPacket(); 
     digitalWrite(Izquierda,HIGH);
     delay(250); 
     if (modo == 4){
          modo=1;}
          else {
           modo=modo+1;}
    }
}

Gracias por todas las ayudas.