Dos pulsadores y HX711

Hola a todos, soy principiante, perdonar si cometo algun fallo publicandolo asi y a ver si me podeis ayudar en este problema ya que llevo varios dias en este proyecto y no soy capaz.
Os explico tengo una balanza hx711 con un lcd 1602 y dos pulsadores en PULL UP con resistencia de 10 K. , mi problema es que con cada pulsador intento que me lo muestre en el lcd uno con tara1 y el otro pulsador con tara2 y que me lo reste del peso total de la balanza (que cambiando manualmente las taras si puedo a través del arduino IDE ) y que como indico llevo varios dias intentadolo sin resultado, a ver si me podeis ayudar un poco en este tema. Os paso el codigo a ver que me deciis:

#include <HX711.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LcdBarGraphX.h>

#define DEBUG_HX711


LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

 
// Parámetro para calibrar el peso y el sensor
#define CALIBRACION 1070000  // 111500            //  123126   
 
// Pin de datos y de reloj
byte pinData = 3;
byte pinClk = 2;

const byte boton1= 6;
const byte boton2= 7;

bool estado, flag, estadoAnt = false;


// Objeto HX711
HX711 balance ;
byte lcdNumCols = 16; // -- number of columns in the LCD

LcdBarGraphX lbg3(&lcd, 1, 2, 1); // -- Second line at column 0


void setup() {
  
 Serial.begin(9600);
 
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);

 pinMode(6, INPUT);
 pinMode(7, INPUT);

 
 lcd.begin(2, lcdNumCols);
 lcd.backlight();
 lcd.clear();
 // Iniciar sensor
  balance.begin(pinData, pinClk);
  // Aplicar la calibración
  balance.set_scale(CALIBRACION);
 
  // Iniciar la tara
  // No tiene que haber nada sobre el peso
  balance.tare();
 
}
 
void loop(){
 
  float peso= balance.get_units(5);    //unidad de peso (peso bruto).
  float tara1= 13.4; // peso solo del envase, se debera sustituir este valor segun peso, solo del envase. (tara)
  float tara2= 14.2; // peso solo del envase, se debera sustituir este valor segun peso, solo del envase. (tara)
  float total = (peso - tara1) ;
  float toter = (peso - tara2);


 estado = digitalRead(boton2);
    if (estado && !estadoAnt) {
        total = !total;
    }
    estadoAnt = estado;

    estado = digitalRead(boton1);
    if (estado && !estadoAnt) {
        toter = !toter;
    }
    estadoAnt = estado;

   
  
  if (total <2.000 ) digitalWrite(11, HIGH);
  if (total <1.000 ) digitalWrite(11, LOW);
  
  if(total <1.000 ) digitalWrite(12, HIGH); 
  else digitalWrite(12, LOW);

  lcd.setCursor(0, 0);
  lcd.print("But.:");
  lcd.setCursor(6, 0);
  lcd.print(total);
  lcd.print(" Kg. ");
  lcd.setCursor(0, 1);
  lcd.print("-|");
  lcd.setCursor(14, 1);
  lcd.print("|+");

  lbg3.drawValue( total, 1);
  
delay (500);

 }

Muchas gracias!

¿Eres principiante? (no del todo) La estructura es correcta y debo tirar fuegos artificiales con esos condicionales no redundantes.

Pon los pulsadores con un debounce. Usa un timer con millis().

Gracias cuantron, me podrías ayudar en cuanto a los pulsadores con debounce? Te lo agradecería.

Otra cosa debería usar la librería bounce2??

Gracias

me podrías ayudar en cuanto a los pulsadores con debounce?

Claro, te pongo un ejemplo pero yo programo a mi manera y no tengo esa lcd, pero un ejercicio con un lcd 16 x 2 quizás te ayude. De todas formas llevo varios días poniendo los mismos ejemplos de timers y debounces.

> Otra cosa debería usar la librería bounce2??

Yo NO uso librerías para un timer. Me niego a usar una librería para un if restando millis(). Las librerías lo único que usan son variables globales y yo muchas veces hago hago los timers dentro del loop con estaticas y gasto menos memoria. Un timer lo puedes hacer simple con una función, con un array, con un struct... con lo que quieras pero al final es un if().

Este ejercicio refresca la lcd cuando se cambia el estado del pulsador.
Los pulsadores se hacen con un debounce.
SÓLO cuando se refresca la lcs se hacen los cálculos y cambiamos los estados de los leds evitamos así el uso de delay.
Cuando se presiona boton 1 se hace el calculo de este, si se presiona de nuevo se quita, lo mismo para el otro e igual para los leds.

#include <LiquidCrystal.h> 
LiquidCrystal lcd(2, 3, 4, 8, 9, 10, 11);


#define DEBOUNCE 30
#define N_LED ARRAY_LENGTH(mis_leds)
#define N_BTN ARRAY_LENGTH(mis_pulsadores)
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))

#define COL 16
#define FIL 2

struct Leds{
  const byte pin;
  bool estado;      
};
Leds mis_leds[] = {
  {6}, {7} //pines, el resto en false por defecto
};

struct Pulsadores{
  const byte pin;
  bool pulsado, estado_previo, estado;
  unsigned long tiempo;        
};
Pulsadores mis_pulsadores[] = {
  {A1}, {A5} // pines, el resto en 0 o false por defecto
};
bool refresh_lcd;

void setup(){
  Serial.begin(9600);
  lcd.begin(COL, FIL);
  for(byte i = 0; i < N_BTN; i++)
    pinMode(mis_pulsadores[i].pin, INPUT);
  for(byte i = 0; i < N_LED; i++)
    pinMode(mis_leds[i].pin, OUTPUT);  
}
void loop(){

  float peso =  800; // cambiar por el resultado de la pesa
  float tara1= 13.4; 
  float tara2= 14.2;

  //comprobación de los pulsadores
  lectura_pulsadores();
  
  //refrescamos pantalla cuando se pulse un botón
  //nos ahorramos el delay ;)
  if(refresh_lcd){
  	lcd.clear();
    
    //calculamos
    if(mis_pulsadores[0].estado){
      lcd.setCursor(0, 0); 
      lcd.print(peso - tara1);
    }
    if(mis_pulsadores[1].estado){
      lcd.setCursor(0, 1); 
      lcd.print(peso - tara2);
    }
    
    //Estados de los leds
    mis_leds[0].estado = (mis_pulsadores[0].estado && peso - tara1 > 2000 && peso - tara1 < 1000 ) ? true : false;
    mis_leds[1].estado = (mis_pulsadores[1].estado && peso - tara1 < 1000) ? true : false;
    
    refresh_lcd = false;
  }
  
  //encendemos o apagamos los leds en base al estado
  for(byte i = 0; i < N_LED; i++)
    digitalWrite(mis_leds[i].pin, mis_leds[i].estado);
}


void lectura_pulsadores(){
  for(byte i = 0; i < N_BTN; i++){
    if(millis() - mis_pulsadores[i].tiempo >= DEBOUNCE){
      mis_pulsadores[i].pulsado = digitalRead(mis_pulsadores[i].pin);
      if(mis_pulsadores[i].pulsado){
        mis_pulsadores[i].estado_previo = true;
      }
      else if(mis_pulsadores[i].estado_previo){
        mis_pulsadores[i].estado_previo = false;
        mis_pulsadores[i].estado = !mis_pulsadores[i].estado;       
        refresh_lcd = true; // se ha pulsado un botón, refrescar lcd
      }
      mis_pulsadores[i].tiempo = millis();
    }
  }
}

Gracias,!!! Mañana me pongo manos a la obra y te digo que resultados tengo...

Gracias cuantron

discúlpame que metí el bool de resfrescar entre medio del setup y el loop al copiar. Ya está arreglado.

¿Cuál es el propósito de esta instrucción? Tratándose de un float no le encuentro sentido…

La misma pregunta para

Además de que toter realmente no se utiliza. flag tampoco.

El código y el diagrama propuestos por @cuantron corresponden a resistencias de pulldown. Tu código sugiere que estás usando pulldown.

¿Podrías anexar un diagrama de tu proyecto para despejar dudas?

Finalmente, sugiero revisar el valor de CALIBRACION, me parece alto.

Las conexiones son:

Lcd 1602 i2c está conectado en pines A4 y A5
Pulsadores están conectados en D6 y D7 en pullup con resistencia cada de 10 k
El hx711 pin data en D3 y CLK en D2 y los leds en pines D11 y D12...

En cuanto los pulsadores los tengo conectados de esta manera.... ya os pasaré diagrama en cuanto lo tenga...

Mi pregunta es debería tenerlos en pulldown según diagrama??

Gracias

Mancera1979 en cuanto calibracion esta mal es el valor 111500 hay no lo cambié en cuanto la instrucción de los pulsadores estoy en una duda extrema porque no se como pillarlo y de hay comiéndome la cabeza varios días con ese apartado.... la cosa esta que en el tema de.pulsadores estoy muy verde por lo demás lo llevo bien, mi idea es que cada pulsador me descuente del peso total la tara indicada (tara1) y (tara2), es decir que la balanza en 0 sin nada de peso me descuente un pulsador la tara1 o sii le doy al otro pulsador me descuente la tara 2.

Cuantron porque están los pulsadores en pines analógicos? Algo en concreto?

Saludos

Bueno he echo modificaciones tanto en las conexiones de los pulsadores ahora estan segun diagrama de cuantron, y aparte echo modificaciones en el codigo, pero me surgen dos problemas...
el primer problema es que los pulsadores van de vez en cuando, cuando pulsas se queda el lcd en blanco o aparece una tara... el segundo problema es que me sale el valor de tara1 y de tara2 en el lcd sin salir el valor de la balanza, solo me sale el valor de las dos taras.... os paso el codigo a ver si me podeis echar una mano...

#include <LiquidCrystal_I2C.h>
#include <HX711.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


#define DEBOUNCE 30
#define N_LED ARRAY_LENGTH(mis_leds)
#define N_BTN ARRAY_LENGTH(mis_pulsadores)
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))

// Parámetro para calibrar el peso y el sensor
#define CALIBRACION 1070000  // 111500            //  123126 

// Objeto HX711
HX711 balance ;


struct Leds{
  const byte pin;
  bool estado;      
};
Leds mis_leds[] = {
  {6}, {7} //pines, el resto en false por defecto
};

// Pin de datos y de reloj
byte pinData = 3;
byte pinClk = 2;

struct Pulsadores{
  const byte pin;
  bool pulsado, estado_previo, estado;
  unsigned long tiempo;        
};
Pulsadores mis_pulsadores[] = {
  {A1}, {A2} // pines, el resto en 0 o false por defecto
};
bool refresh_lcd;

void setup(){
  Serial.begin(9600);
  lcd.begin(16,2);
  for(byte i = 0; i < N_BTN; i++)
    pinMode(mis_pulsadores[i].pin, INPUT);
  for(byte i = 0; i < N_LED; i++)
    pinMode(mis_leds[i].pin, OUTPUT);

     // Iniciar sensor  
  balance.begin(pinData, pinClk);
  // Aplicar la calibración
  balance.set_scale(CALIBRACION);
 
  // Iniciar la tara
  // No tiene que haber nada sobre el peso
  balance.tare();
 
   }
void loop(){

  float peso= balance.get_units(5); // cambiar por el resultado de la pesa
  float tara1= 13.4; 
  float tara2= 14.2;
 
  
  //comprobación de los pulsadores
  lectura_pulsadores();
  
  //refrescamos pantalla cuando se pulse un botón
  //nos ahorramos el delay ;)
  if(refresh_lcd){
  lcd.clear();
        //calculamos
    if(mis_pulsadores[0].estado){
      lcd.setCursor(6, 0);
      lcd.print(tara1 - peso);
       lcd.setCursor(0, 0);
      lcd.print("but:");
    }
    if(mis_pulsadores[1].estado){
      lcd.setCursor(6, 0); 
      lcd.print(tara2 - peso);
      lcd.setCursor(0, 0);
      lcd.print("but:");
    }
    
    //Estados de los leds
    mis_leds[0].estado = (mis_pulsadores[0].estado && peso - tara1 > 2000 && peso - tara1 < 1000 ) ? true : false;
    mis_leds[1].estado = (mis_pulsadores[1].estado && peso - tara1 < 1000) ? true : false;
    
    refresh_lcd = false;
  }
  
  //encendemos o apagamos los leds en base al estado
  for(byte i = 0; i < N_LED; i++)
    digitalWrite(mis_leds[i].pin, mis_leds[i].estado);
}


void lectura_pulsadores(){
  for(byte i = 0; i < N_BTN; i++){
    if(millis() - mis_pulsadores[i].tiempo >= DEBOUNCE){
      mis_pulsadores[i].pulsado = digitalRead(mis_pulsadores[i].pin);
      if(mis_pulsadores[i].pulsado){
        mis_pulsadores[i].estado_previo = true;
      }
      else if(mis_pulsadores[i].estado_previo){
        mis_pulsadores[i].estado_previo = false;
        mis_pulsadores[i].estado = !mis_pulsadores[i].estado;       
        refresh_lcd = true; // se ha pulsado un botón, refrescar lcd
      }
      mis_pulsadores[i].tiempo = millis();
    }
  }
}

Los protoboards suelen caracterizarse por tener malos contactos.
En este foro muchos problemas resultaron ser responsabilidad de un mal protoboard.

Yo creo que antes de estar peleando con la tara1 y tara2 debes asegurarte que el funcionamiento de los pulsadores es el adecuado.
Descarta todo lo que tienes y prueba un código simple que funcione con los pulsadores para estar seguro que cuando presionas 1 responde y cuando presionas el otro también lo hace.

Usando una resistencia pullup, cuando el pulsador se oprima, el Pin 6 leerá LOW y digitalRead(pin 6) será false.

Con una resistencia de pulldown, al oprimir el pulsador el Pin 6 leerá HIGH y digitalRead(pin 6) sera true

Las fotos que compartiste no aclaran el tipo de conexión que estás usando.

Por otro lado,es posible que se estén declarando los mismos pines para el display y para el HX711 y los LEDS. ¿Podrías decirnos de dónde descargaste la librería que estás usando para manejar el display LCD? Si es esta https://github.com/fmalpartida/New-LiquidCrystal, deberías usar otros pines para controlar el HX711 y los LEDs o cambiar de constructor a

Creo que

debería ser

[quote="xpolt84, post:11, topic:950118"]

Bueno ahora estoy usando estos pulsadores:

Perdona mancera1979 que significa que estoy declarando los mismo pines para el lcd, hx711 y los led??

La librería del LCD la saque de este enlace:

No encuentro un constructor como el que utilizas

El único consrtrutor que encuentro en ese enlace es algo como esto:


LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

Ese constructor ya no se usa hace bastante (está "deprecated" :thinking:) , es de una versión antigua de la librería, lo correcto es lo que te indica @mancera1979

Saludos

Vale, entonces que deberia de hacer? Instalr esta libreria indicado por mancera1979?:

Me siento perdido jejeje en esto...

Gracias por vuestra ayuda...

No, cambia

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

por

LiquidCrystal_I2C lcd(0x27, 20, 4);

nada más.

Saludos

@xpolt84 , usé esos analógicos por mero espacio en el diagrama, lo que yo pongo son ejemplos, ya cada cual que lo adapte cómo guste o si lo quiere usar cómo base.

LiquidCrystal_I2C lcd(0x27, 16, 2);

Lo he cambiado como dijisteis y ahora el problema que la pantalla parpadea... a que se debe?? La pantalla es un LCD1602 en I2C.