Reducir o eliminar Ruido en celda de carga

Compañeros tengo un problema con las lecturas que me da la celda de carga, pues pesa muy bien pero tiene unos intervalos de tiempo de un segundo aproximadamente donde el peso se distorsiona, bajando o subiendo el peso.
El problema pasa muy pocas veces, pero para mi caso no tendria que suceder ninguna vez ya que una pequeña variacion hace saltar mi codigo a que haga otra instruccion, es por eso que necesito solucionarlo.
No se si se podran tomar unas 10 muestras y promediar el peso, si es que fuera asi necesito su ayuda y experiencia.
Esto es un ejemplo cuando se distorsiona el peso ( pues no hay peso y aveces muestra -21.449).

0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
-21.449
-21.449
-21.449
-21.449
-21.449
-21.449
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000
0.000

Este es mi codigo

#include "HX711.h"

#define DOUT  A1
#define CLK  A0

HX711 balanza(DOUT, CLK);

float calibration_factor =  404200.75;


void setup() {
  
     Serial.begin(9600);
     Serial.println("CALIBRANDO ZERO");
     
     balanza.set_scale();
     balanza.tare();  //Resetear a cero
     balanza.set_scale();
     balanza.tare(); 
     long zero_factor = balanza.read_average(20); 
     return(zero_factor);    
}

void loop() {

  balanza.set_scale(calibration_factor);  

 double valor = balanza.get_units(1);
if (abs(valor) == 0.0) 
   Serial.println("0.000");


  /*//visualizar el factor de calibracion//
  Serial.print(" calibration_factor: ");
  Serial.print(calibration_factor);
  Serial.println();*/

  //si se necesitara ajustar el  peso//
  if(Serial.available())
  {
    char temp = Serial.read();
     if(temp == '+' || temp == 'a')
      calibration_factor += 10;
     if(temp == '-' || temp == 'z')
      calibration_factor -= 10;
      
      if(temp == 'x'){
      Serial.println("----------");
     balanza.set_scale();
     balanza.tare(); 
     long zero_factor = balanza.read_average(20); 
     return(zero_factor);
      }
  }
}

Un valor negativo que tiene que ver? es un problema de la tara?

ese valor negativo sale solo sin tarar la balanza y solo sale unas cuantas veces, no siempre, y aveces es positivo casi como se fuera un ruido.

Con 24 bits no tener ruido es dificil. No se como será tu cableado. Si usas o no cables con malla, si has cuidado estas cosas precisamente.
Yo tomaría todas las precauciones.
Analiza la librería, mira que pasa con los valores proximos a 0 y negativos.

solo un pregunta para probar ¿de cuanto debe ser el adaptador para conectar 12 arduino nano y un arduino mega conectados todos por i2c?. Porque yo estoy usando un adaptador de 9v 1 amp, y con el alimento a todos los 13 arduinos. Quizas la corriente en el adaptador no sea la suficiente para los 13 arduinos y me esten jugando una mala pasada con el peso.
No se si estara bien alimentar a los arduino independientemente o con un solo adaptador podria gobernar todos.
Si fuera la primera opcion( alimentar independientemente cada arduino) tendria que juntar las masas, ya que me podria perjudicar la comunicacion i2c o no es necesario juntar la masas.
La verdad que no cuento con tantos adaptadores para todos los arduinos. :slight_smile:

park:
Si fuera la primera opcion( alimentar independientemente cada arduino) tendria que juntar las masas, ya que me podria perjudicar la comunicacion i2c o no es necesario juntar la masas.

Irremediablemente hay que. Sin la referencia de tierra, la señal podría ser desde ilegible, hasta nula.
Intenta escuchar música desde auriculares/audífonos, y con la línea a tierra desconectada.

La única forma de "aislar" señales, es mediante "transmisión sin contacto". Por ejemplo: optoacoplador o fibra óptica (mediante luz), aislador galvanizado (mediante campo electromagnético) y radiofrecuencia (mediante ondas de radio, por supuesto).

Tu problema es otro.
12 arduinos consumiendo generan un ruido considerable con ADC de 24bits.
Todavia no te queda claro en que lio te has metido.
Mira.. 24 bits = 2^24 = 16777216
Ahora si usas 5V la resolución de tu ADC HX711 será de 5V/16777216= 0,000000298 V= 0.3uV
Tu resolución es de 0.3uV
Sabes cuanto debe ser el riple de tu fuente con 12 arduinos conectados a la misma fuente?
Toma el multímetro, ponlo en AC y midelo y luego me cuentas y agárrate la cabeza con el resultado.

Espero que no uses una fuente de Switching para alimentarlos.

Compañeros disculpen la demora, bueno estube haciendo todas las mediciones correspondiente y exacto como lo dijo surbyte los voltajes no eran parejos para todos los arduino, ademas que estaba usando un fuente switching. Pese a todo eso, me puse manos a la obra y rearme todos mis circuitos q estaban hecho un caos porque los tengo armados en protoboard, ademas que reemplaze la fuente que tenia, por una fuente lineal que esta un poco viejita y empolvada pero esta ok ya que tiene un execelnte trafo.
Monte el circuito y sigue igual con el mismo problema, volvi a rearmar todo alimentado un arduino independientemente y aun asi seguia el mismo problema.

::slight_smile: Estube pensando un poco y queria descartar un trozo de codigo , no sin antes consutarles a ustedes como reemplazar un trozo de codigo sin usar goto(podria ser que me este dando problemas), la idea esta en que si se cumple la condicion unos led deben encender y si no se cumple la condicion aumenta un contador y avanza el codigo repitiendose consecutivamente( si tienen otra idea de como reemplazar mi codigo, sin usar el goto, pues quiero descartar todo, quizas el problema sea mi codigo.

///ESCLAVO 1 ////
   slave1:
   if(conta ==1){
    Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1(); 
   Wire.requestFrom(1,8);    // Pedimos 8 bytes al esclavo 1
   CompararDatos();
  
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo1, HIGH);           //encendemos led para el esclavo 1
   goto slave1;
   
      }
  else{
    apagarLeds(); //apagamos todos lo leds
    conta++;
  }  
  }
  
                       ///ESCLAVO 2 ////
      slave2:
     if(conta ==2){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
     pesoBal1();
     Wire.requestFrom(2,8);    // Pedimos 8 bytes al esclavo 2
      CompararDatos();
   
     if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
      digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
     digitalWrite(ledEsclavo2, HIGH);          //encendemos led para el esclavo 2
      goto slave2;
      }
  else{
   apagarLeds();//apagamos todos lo leds
    conta++;       //aumento el contador
  }  
  }

                             ///ESCLAVO 3 ////
 slave3:
   if(conta ==3){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(3,8);    // Pedimos 8 bytes al esclavo 3
   CompararDatos(); // comparo los datos
   
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo3, HIGH);          //encendemos led para el esclavo 3
   goto slave3;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }
                               ///ESCLAVO 4 ////
     slave4:
     if(conta ==4){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
     pesoBal1();
     Wire.requestFrom(4,8);    // Pedimos 8 bytes al esclavo 4
     CompararDatos();
   
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo4, HIGH);          //encendemos led para el esclavo 4
   goto slave4;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }

           /////////ESCLAVO5/////

     slave5:
    if(conta ==5){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
     pesoBal1();
     Wire.requestFrom(5,8);    // Pedimos 8 bytes al esclavo 5
     CompararDatos();
   
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo5, HIGH);          //encendemos led para el esclavo 5
   goto slave5;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }

         /////////ESCLAVO6/////

 slave6:
   if(conta ==6){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(6,8);    // Pedimos 8 bytes al esclavo 6
   CompararDatos();
  
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo6, HIGH);          //encendemos led para el esclavo 6
   goto slave6;
      }
  else{
  apagarLeds();
   conta++;
  
  }  
  }
  
        //////////ESCLAVO7/////

slave7:
   if(conta ==7){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(7,8);    // Pedimos 8 bytes al esclavo 7
   CompararDatos();
  
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo7, HIGH);          //encendemos led para el esclavo 7
   goto slave7;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }
      /////////ESCLAVO 8/////

 slave8:
   if(conta ==8){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(8,8);    // Pedimos 8 bytes al esclavo 8
   CompararDatos();
  
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo8, HIGH);          //encendemos led para el esclavo 8
   goto slave8;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }

      /////////ESCLAVO 9/////

 slave9:
   if(conta ==9){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(9,8);    // Pedimos 8 bytes al esclavo 9
   CompararDatos();
   
   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo9, HIGH);          //encendemos led para el esclavo 9
   goto slave9;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }
      /////////ESCLAVO 10/////

 slave10:
   if(conta ==10){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(10,8);    // Pedimos 8 bytes al esclavo 10
   CompararDatos();

   if((result >= 0.495) && (result < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo10, HIGH);          //encendemos led para el esclavo 10
   goto slave10;
      }
  else{
  apagarLeds();
   conta++;
  }  
  }
  
                           ///ESCLAVO 1 Y 2 ////(CONTADOR= 11)
                           
 slave11:
   if(conta ==11){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(1,8);     // Pedimos 8 bytes al esclavo 1
   CompararDatos2();
    Wire.requestFrom(2,8);    // Pedimos 8 bytes al esclavo 2
    CompararDatos3();
   
   
   if((result3 >= 0.495) && (result3 < 0.510)){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);             //encendemos led maestro
   digitalWrite(ledEsclavo2, HIGH);            //encendemos led para el esclavo 2 y 1
   digitalWrite(ledEsclavo1, HIGH);
   goto slave11;
      }
  else{
  apagarLeds();
   conta++;

hasta el contador 55..luego vuelve a contador uno y se repite el proceso

  }

Como digo siempre, hay que volver a lo básico.
Resuelve el problema en un Arduino. Que se lea estable, luego prueba con dos y comprueba y ve viendo que pasa.
No hagas todo de golpe si individualmente las cosas no funcionan. Hay que analizar con método científico que esta bien y que no. Paso a paso.
1 funciona .... n funciona. Okay.
Ahora agrupas y compruebas.. funciona, sigo.
Todos no funciona.. algo pasa? Fuente, masas, sección de cables?

al final el problema no era el bus 12c, sino era mi codigo... :wink:

Una vez mas.
Hay que resolver siempre lo básico y luego ir creciendo con el proyecto.
Cada etapa de tu programa debe ser sólida y estable. Si no se consigue no se debe avanzar a la siguiente etapa.
Cuando comienzas a programar a veces no se visualizan las etapas.
En este caso hay muchas etapas simples.

  1. lograr leer correctamente el peso (con tara, con estabilidad, y que sea confiable).
  2. comunicar dos, luego 3 luego N arduinos por I2C enviando el tipo de datos que se va a enviar. No con un demo y luego quiero enviar algo diferente.
  3. Finalmente, se puede unir todo. Que cada arduino lea su balanza y que su valor quede disponible para ser requerido por el I2C Master.

Este es un esquema simple (aparentemente) pero que establece un criterio de cómo trabajar. Si pongo todo junto, las cosas no funcionan en la mayor parte de las veces. Si lo hago asi, aún de este modo surgen problemas, como con la alimentación y la estabilidad de la lectura de un módulo de 24 bits como el HX711.

Joseph90:
al final el problema no era el bus 12c, sino era mi codigo... :wink:

Podrías, por favor, explicar cómo lo solucionaste?

No lo digo por mi, ni por los moderadores/administradores; sino por los que a futuro estén en un problema similar al tuyo.

Modifique el codigo tanto del master como cada uno de los esclavos, separe la operaciones matematicas que se hacia con los float, y tambien la recepcion de datos, elimine algunos delays que estaban demas, probe cada arduino por separado y fui aumentando un arduino ( priemro con uno,luego con dos y asi consecutivamente) y como todo estaba funcionando correctamente junte todo y sorpresa :o , ya no tenia variaciones ni saltos de peso.
Ahora yo no tengo variacion de peso, ni ruido( los led ya no parpadean) y todo esta ok( aparentemente nuevamente).
Pero ahora tengo un nuevo problema, que al alimentar el sistema de los 13 arduino esclavo, 2 tengo que volverlos a reprogramar, porque no transmiten datos ( como si se desprogramaran solos), luego los programo y el sistema vuelve a funcionar correctamente sin ningun problema, hasta el dia siguiente que los vuelvo a encender y nuevamente se desprograma cualquiera de ellos( puede ser cualquier arduino)
Momentaneamente estoy alimentando todos los 13 arduino con una fuente lineal de 1.5 amp porque no se nota mucho bien las letras.
Creo que ahora el problema es electrico, no tengo mucha experiencia en la alimentacion de los arduino y quisiera que me recomendaran con cuanto debo alimentar el sistema( 12 arduino nano y un arduino mega), de cuanto deberia ser la fuente( lineal o switching), la verdad quisiera alimentarla con una sola fuente porque no necesito tanto espacio. Por ahora los arduino estan trabajando solos, pero luego acad uno de ellos va llevar un display lcd.
Esta es la modificacion del codigo y funciona perfecto.

void pesoBal1(){
  while( Wire.available()) //Leemos hasta que no haya datos. Teoricamente son 2.
  {
    
     dat1 = Wire.read();//Leemos los bytes
     inString5+=dat1;
     dat2 = Wire.read();
     inString5+=dat2;
     dat3 = Wire.read();
     inString5+=dat3;
     dat4 = Wire.read();
     inString5+=dat4;
     dat5 = Wire.read();
     inString5+=dat5;
     dat6 = Wire.read();
     inString5+=dat6;
      dat7 = Wire.read();
     inString5+=dat7;
      dat8 = Wire.read();
     inString5+=dat8;
   
    balanza1=inString5.toFloat();
    inString5="";
    // }                    
  }
}

  
  

void CompararDatos(){
while( Wire.available()) //Leemos hasta que no haya datos. Teoricamente son 2.
  {
    
     dat1 = Wire.read();//Leemos los bytes
     inString+=dat1;
     dat2 = Wire.read();
     inString+=dat2;
     dat3 = Wire.read();
     inString+=dat3;
     dat4 = Wire.read();
     inString+=dat4;
     dat5 = Wire.read();
     inString+=dat5;
     dat6 = Wire.read();
     inString+=dat6;
      dat7 = Wire.read();
     inString+=dat7;
      dat8 = Wire.read();
     inString+=dat8;
  
      pesoRecibido=inString.toFloat();
     inString="";
    // }                    
     }


}
void sumaBal(){
  
  if((pesoRecibido2 > 0.010)&&(pesoRecibido3 > 0.010)){
  result3 = balanza1 + pesoRecibido2 + pesoRecibido3;
  Serial.println(result3,(3));
 
  if((result3 >= 0.495) && (result3 < 0.510)){
    correcto = true;
   }
  else{
    result3 = 0.000;
    correcto = false;
  }
  } 
}
while(conta ==1){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
     pesoBal1(); 
     Wire.requestFrom(1,8);    // Pedimos 8 bytes al esclavo 1
     CompararDatos();
  suma();
  
   if(correcto == true){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo1, HIGH);           //encendemos led para el esclavo 1
 
   
      }
  else{
    correcto=false;
    apagarLeds(); //apagamos todos lo leds
    conta++;
  }  
  }
  
                       ///ESCLAVO 2 ////
   
      while(conta ==2){
      Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
      pesoBal1();
      Wire.requestFrom(2,8);    // Pedimos 8 bytes al esclavo 2
      CompararDatos();
      suma();
  
     if(correcto==true){ //Comparamos si el resultado esta dentro del rango
      digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
     digitalWrite(ledEsclavo2, HIGH);          //encendemos led para el esclavo 2
     
      }
  else{
    correcto=false;
   apagarLeds();//apagamos todos lo leds
    conta++;       //aumento el contador
  }  
  }

                             ///ESCLAVO 3 ////

   while(conta ==3){
     Wire.requestFrom(12,8);     // Pedimos 8 bytes al esclavo 12(balanza 1)
 pesoBal1();
   Wire.requestFrom(3,8);    // Pedimos 8 bytes al esclavo 3
   CompararDatos(); // comparo los datos
   suma();
  
   if(correcto ==true){ //Comparamos si el resultado esta dentro del rango
   digitalWrite(ledMaestro, HIGH);           //encendemos led maestro
   digitalWrite(ledEsclavo3, HIGH);          //encendemos led para el esclavo 3
  
      }
  else{
    correcto=false;
  apagarLeds();
   conta++;
  }  
  }