Ajuda urgente com Conversor HX711 + Arduino Uno e Display de sete segementos

om dia,

Sou iniciante no Arduino e gostaria de pedir uma ajuda aos mais experientes no assunto.

Estou tentando desenvolver uma balança utilizando o conversor hx711 com um Arduino UNO.

Eu consigo ler a célula numa boa. Porem eu eu tenho dois problemas para resolver:

1º - Eu estou usando 4 displays de sete segmentos multiplexados diretamente pelo o arduino. Então quando eu tento ler a célula os números são mostrados no display de forma intermitente na mesma frequencia que os valores são mostrados na serial impossibilitando a visualização.

2º Os display mostram valores inteiros e a leitura da célula é em float.

O código é esse:

//==============================Inicio==========================================

 
#include "HX711.h"

#define DOUT  A1
#define CLK  A0

HX711 balanza(DOUT, CLK);

int pausa = .5;

const int pin_pot = 500;
const int pin_tempo = 1;

const int pin_a = 2;
const int pin_b = 3;
const int pin_c = 4;
const int pin_d = 5;
const int pin_e = 6;
const int pin_f = 7;
const int pin_g = 8;

const int pin_com1 = 9;
const int pin_com2 = 10;
const int pin_com3 = 11;
const int pin_com4 = 12;


void setup() {

  pinMode(pin_a, OUTPUT);  
  pinMode(pin_b, OUTPUT);  
  pinMode(pin_c, OUTPUT);  
  pinMode(pin_d, OUTPUT);  
  pinMode(pin_e, OUTPUT);  
  pinMode(pin_f, OUTPUT);    
  pinMode(pin_g, OUTPUT);  
  
  pinMode(pin_com1, OUTPUT);  
  pinMode(pin_com2, OUTPUT);  
  pinMode(pin_com3, OUTPUT); 
  pinMode(pin_com4, OUTPUT);
 
  
//  pinMode(pin_pot, INPUT); 
//  pinMode(pin_tempo, INPUT); 
  
  
  Serial.begin(9600);
  Serial.print("Leitura do valor do Conversor: ");
  Serial.println(balanza.read());
  Serial.println("Não ponha nenhum objeto na balança");
  Serial.println("Zerando tara...");
  Serial.println("...");
  balanza.set_scale(-516990); // Establecemos la escala
  balanza.tare(20);  //El peso actual es considerado Tara.
  
  Serial.println("Pronto para pesar");  
}

/*void loop() {
  Serial.print("Peso: ");
  Serial.print(balanza.get_units(20),3);
  Serial.println("Kg");
  delay(500); */





/* void setup() {               
  pinMode(pin_a, OUTPUT);  
  pinMode(pin_b, OUTPUT);  
  pinMode(pin_c, OUTPUT);  
  pinMode(pin_d, OUTPUT);  
  pinMode(pin_e, OUTPUT);  
  pinMode(pin_f, OUTPUT);    
  pinMode(pin_g, OUTPUT);  
  
  pinMode(pin_com1, OUTPUT);  
  pinMode(pin_com2, OUTPUT);  
  pinMode(pin_com3, OUTPUT); 
  pinMode(pin_com4, OUTPUT);
 
  
  pinMode(pin_pot, INPUT); 
  pinMode(pin_tempo, INPUT); 
  
  //Serial.begin(9600);
  
} */


/*
Conversion table number to bit
If a segment is used to compose the digit, then sum the bit value

	A	B	C	D	E	F	G	
#	1	2	4	8	16	32	64	
------------------------------------------------------------------								
0	1	1	1	1	1	1		63
1		1	1					6
------------------------------------------------------------------
2	1	1		1	1		1	91
3	1	1	1	1			1	79
------------------------------------------------------------------
4		1	1			1	1	102
5	1		1	1		1	1	109
------------------------------------------------------------------
6	1		1	1	1	1	1	125
7	1	1	1					7
------------------------------------------------------------------
8	1	1	1	1	1	1	1	127
9	1	1	1			1	1	103
*/
int get_7SD_value(int n) {
  if (n>9) n=9;
  if (n<0) n=0;
 
  switch(n) {
    case 0: return 63; break;
    case 1: return 6; break;
    case 2: return 91; break;
    case 3: return 79; break;
    case 4: return 102; break;
    case 5: return 109; break;
    case 6: return 125; break;
    case 7: return 7; break;
    case 8: return 127; break;
    case 9: return 103;
  }
  return 0;
}


/*
ATTENTION: I'm using Common Anodes 7 Segment Display.
For Commom Cathodes, you have to invert HIGH and LOW on code bellow.
*/

void check_pin(int pin, int b) {
    if (b == 1) {
      digitalWrite(pin, LOW); 
      delay(pausa);
      digitalWrite(pin, HIGH);  
    } else 
      digitalWrite(pin, HIGH);
}


/*
ATTENTION: I'm using Common Anodes 7 Segment Display.
For Commom Cathodes, you have to invert HIGH and LOW on code bellow.
*/

void display_7sd(int v, int pin_com) {
  if (v>9) v=9;
  if (v<0) v=0;
  
  int n = get_7SD_value(v);
  
  /* turn on common */
  digitalWrite(pin_com, HIGH);
  
  
  /* check all segments, and turn on the necessary ones to compose the number */
  check_pin(pin_a, bitRead(n, 0));
  check_pin(pin_b, bitRead(n, 1));
  check_pin(pin_c, bitRead(n, 2));
  check_pin(pin_d, bitRead(n, 3));  
  check_pin(pin_e, bitRead(n, 4));
  check_pin(pin_f, bitRead(n, 5));
  check_pin(pin_g, bitRead(n, 6));

  /* turn off common */
  digitalWrite(pin_com, LOW);     
}

void display_value(int v) {
  int n;

  
  
  // Print hundred part - fourth digit
  n = v / 1000;  
  v = v - (n*1000);
  display_7sd(n, pin_com4); 
  
  // Print hundred part - first digit
  n = v / 100;  
  v = v - (n*100);
  display_7sd(n, pin_com1);
  
  // Print decimal part - second digit  
  n = v / 10;
  v = v - (n*10);
  display_7sd(n, pin_com2);
  
  // Print the unit, the remainder - third digit  
  display_7sd(v, pin_com3);
  
  
}  


void loop() {

  Serial.print("Peso: ");
//  Serial.print(balanza.get_units(20),3);
  Serial.println("Kg");
  delay(1);
   int tpot =0;
  pausa = 1 ;

  for (tpot=0;tpot <= 9999;tpot++)
  display_value(tpot); 


}

//====================================Fim=====================================

Observem que eu coloquei uma contador e armazenei navariável "tpot" só para exemplificar, pois ainda não consegui fazer aparecer os valores da célula.

Por favor alguem pode me ajudar ?

Por favor, edite seu post e coloque seu código em tags [ code][ /code], ele vai aparecer assim:

Seu código

Facilita bastante a leitura.

Para solucionar seu 1º problema da intermitência de uma forma rápida, coloque delay() no seu loop:

void loop() {

  Serial.print("Peso: ");
//  Serial.print(balanza.get_units(20),3);
  Serial.println("Kg");
  delay(1);
   int tpot =0;
  pausa = 1 ;

  for (tpot=0;tpot <= 9999;tpot++){
    display_value(tpot);
    delay(1000);
  }


}

Lembrando que ao usar, delay(), seu código se torna "bloqueador", pois bloqueia a execução de qualquer outro código durante a execução do delay();

Para contornar, de forma um pouco mais complexa, use millis():

void loop() {

  Serial.print("Peso: ");
//  Serial.print(balanza.get_units(20),3);
  Serial.println("Kg");
  delay(1);
   int tpot =0;
  pausa = 1 ;

  static unsigned long temporizador = 0;
  if(millis() - temporizador > 1000){
    temporizador = millis();

    for (tpot=0;tpot <= 9999;tpot++)
      display_value(tpot);
  }

}

Assim seu código não será "bloqueador".
Ambos os códigos fazem praticamente a mesma coisa, porém a segunda opção é preferível, pois em códigos complexos (e na maioria dos programas), usar delay() impede execução "pararela".

Seu 2º problema:
Os displays 7 segmentos possuem 8 LEDS: os 7 segmentos (a ~ g) e mais um ponto.
Para exibir valores decimais, precisa do ponto.
No seu código, o ponto não é considerado.
Este LED do ponto está ligado fisicamente em seu circuito?
Em qual pino está ligado?

O pino decimal ainda não está ligado fisicamente

Mas por enquanto isso não é um problema muito grave.

Obrigado pela a ajuda

Vou tentar fazer como vc falou

Sem mensagem

Mude sua função display_7sd() para processar ponto decimal:

void display_7sd(int v, boolean decimal, int pin_com) {
  if (v>9) v=9;
  if (v<0) v=0;
 
  int n = get_7SD_value(v);
  bitWrite(n,7,decimal);

  /* turn on common */
  digitalWrite(pin_com, HIGH);
 
 
  /* check all segments, and turn on the necessary ones to compose the number */
  check_pin(pin_a, bitRead(n, 0));
  check_pin(pin_b, bitRead(n, 1));
  check_pin(pin_c, bitRead(n, 2));
  check_pin(pin_d, bitRead(n, 3)); 
  check_pin(pin_e, bitRead(n, 4));
  check_pin(pin_f, bitRead(n, 5));
  check_pin(pin_g, bitRead(n, 6));

  /* turn off common */
  digitalWrite(pin_com, LOW);     
}

E mude sua função display_value() para aceitar float:

void display_value(float v) {

  int dezena = v / 10; 
  v = fmod(v,10);
  display_7sd(centena, false, pin_com4);
 
  int unidade = v / 1; 
  v = fmod(v,1);
  display_7sd(unidade, true, pin_com1);
 
  int decimo = v / 0.1;
  v = fmod(v,0.1);
  display_7sd(decimo, false, pin_com2);
 
  int centesimo = v / 0.01;
  v = fmod(v,0.01);
  display_7sd(centesimo, false, pin_com3);
  
}

O valor máximo será 99.99, sempre com duas casas decimais fixas.

Teste novamente.

Vou tentar

Por enquanto já agradeço a ajuda pessoal

Tentei compilar e deu essa mensagem:

exit status 1

'centena' was not declared in this scope

Desculpe, errei uma palavra enquanto estava pensando no código.

Porém antes de ler a solução, pense: Você sabe o que o erro quer dizer? Como arrumá-lo? Você ao menos tentou arrumá-lo?
Este erro é considerado básico, pois só de lê-lo já consigo identificar a solução.
Apenas para reflexão :slight_smile:

Basta corrigir a função display_value():

void display_value(float v) {

  int dezena = v / 10;
  v = fmod(v,10);
  display_7sd(dezena , false, pin_com4);
 
  int unidade = v / 1;
  v = fmod(v,1);
  display_7sd(unidade, true, pin_com1);
 
  int decimo = v / 0.1;
  v = fmod(v,0.1);
  display_7sd(decimo, false, pin_com2);
 
  int centesimo = v / 0.01;
  v = fmod(v,0.01);
  display_7sd(centesimo, false, pin_com3);
 
}

Fiz as alterações que vc falou e recompilei. Não deu erro.

Agora e quanto a parte da leitura do conversor vc tem alguma idéia?

Os números piscam e somem rápido

Esse era o problema principal.

Desculpa a minha inexperiência mas o problema continua do mesmo jeito !

Modifique seu loop() para:

void loop() {

  static unsigned long temporizador = 0;
  if(millis() - temporizador > 2000){
    temporizador = millis();
	
    display_value(balanza.get_units(20));
  }

}

Modifique check_pin() para:

void check_pin(int pin, int b) {
    digitalWrite(pin, !b);
}

Veja bem,

Eu não tenho problemas com a multiplexação entende?

O problema é quando eu leio o conversor ai então os números ficam piscando.

Ou seja, se eu comentar as linhas que lêem a célula e atribuir algum valor à função display_value, o número atribuído aparece normalmente entende?

void setup()

/* Serial.begin(9600);
  Serial.print("Leitura do valor do Conversor: ");
  Serial.println(balanza.read());
  Serial.println("Não ponha nenhum objeto na balança");
  Serial.println("Zerando tara...");
  Serial.println("...");*/
//  balanza.set_scale(-516990); // Establecemos la escala
//  balanza.tare(20);  //El peso actual es considerado Tara.
  
 // Serial.println("Pronto para pesar"); 




void loop()

{
      
static unsigned long temporizador = 0;
//  if(millis() - temporizador > 2000){
//  temporizador = millis();
  
//  display_value(balanza.get_units(20));
    display_value(85);
  
  }

Alterou o check_pin() conforme meu post anterior?

Alterei sim

Como te falei eu não tinha problemas relacionados aos displays e sim na hora de ler os valores da célula.

Ou seja, quando começa ler os valores ai o os displays ficam piscando todos. Eles mostram os numeros bem rapidamente somem. E ficam piscando conforme o loop.

Agora entendi melhor seu problema.

Teste este loop():

void loop() {
    display_value(balanza.get_units(20));
}

Quais os resultados?

Testei e agora ficou mais rápido ainda as piscadas

Primeiro, vamos testar o display 7 segmentos.

Ao executar o seguinte código, o que você ve no display:

const int pin_a = 2;
const int pin_b = 3;
const int pin_c = 4;
const int pin_d = 5;
const int pin_e = 6;
const int pin_f = 7;
const int pin_g = 8;

const int pin_com1 = 9;
const int pin_com2 = 10;
const int pin_com3 = 11;
const int pin_com4 = 12;

void setup() {

  pinMode(pin_a, OUTPUT);
  pinMode(pin_b, OUTPUT);
  pinMode(pin_c, OUTPUT);
  pinMode(pin_d, OUTPUT);
  pinMode(pin_e, OUTPUT);
  pinMode(pin_f, OUTPUT);
  pinMode(pin_g, OUTPUT);

  pinMode(pin_com1, OUTPUT);
  pinMode(pin_com2, OUTPUT);
  pinMode(pin_com3, OUTPUT);
  pinMode(pin_com4, OUTPUT);


  int n = 102;

  digitalWrite(pin_com1, HIGH);
  digitalWrite(pin_com2, HIGH);
  digitalWrite(pin_com3, HIGH);
  digitalWrite(pin_com4, HIGH);

  digitalWrite(pin_a, !bitRead(n, 0));
  digitalWrite(pin_b, !bitRead(n, 1));
  digitalWrite(pin_c, !bitRead(n, 2));
  digitalWrite(pin_d, !bitRead(n, 3));
  digitalWrite(pin_e, !bitRead(n, 4));
  digitalWrite(pin_f, !bitRead(n, 5));
  digitalWrite(pin_g, !bitRead(n, 6));
}

void loop() {

}

Olá

Eu vejo o número "4444"

Ok, queria confirmar as ligações e lógicas.

Agora teste este com a multiplexação:

const int pin_a = 2;
const int pin_b = 3;
const int pin_c = 4;
const int pin_d = 5;
const int pin_e = 6;
const int pin_f = 7;
const int pin_g = 8;

const int pin_com1 = 9;
const int pin_com2 = 10;
const int pin_com3 = 11;
const int pin_com4 = 12;

void setup() {

  pinMode(pin_a, OUTPUT);
  pinMode(pin_b, OUTPUT);
  pinMode(pin_c, OUTPUT);
  pinMode(pin_d, OUTPUT);
  pinMode(pin_e, OUTPUT);
  pinMode(pin_f, OUTPUT);
  pinMode(pin_g, OUTPUT);

  pinMode(pin_com1, OUTPUT);
  pinMode(pin_com2, OUTPUT);
  pinMode(pin_com3, OUTPUT);
  pinMode(pin_com4, OUTPUT);



}

const int n = 102;

void loop() {

  for (int pin = 9; pin <= 12; pin++) {
    digitalWrite(pin, HIGH);

    digitalWrite(pin_a, bitRead(n, 0));
    digitalWrite(pin_b, bitRead(n, 1));
    digitalWrite(pin_c, bitRead(n, 2));
    digitalWrite(pin_d, bitRead(n, 3));
    digitalWrite(pin_e, bitRead(n, 4));
    digitalWrite(pin_f, bitRead(n, 5));
    digitalWrite(pin_g, bitRead(n, 6));

    digitalWrite(pin, LOW);
  }
}