Arduino y AD620

No entiendo...
¿No estás usando el circuito de #45?
De ser así te falta unir las masas, el esquema es claro.

Lo que te dije de separar las masas aplicaba para la configuración que mostraste en #25 que era un amplificador no inversor.

Claro, pero esa configuración del #45 la estoy tomando como si fuera un conjunto, así que, va a la misma masa, que en este caso sería la masa del Arduino y se alimenta con el 5V del Arduino, y el Arduino lo alimento con el cable USB, el sensor lo alimento con 12V de una fuente separada, y su masa está separada del Arduino (intenté que tuvieran las masas unidas (Arduino y sensor), pero no amplifica, se satura).

Me hago entender?e.e

Si estás usando exactamente la misma configuración y circuitería del esquema en #45 tienes que unir la masa de la fuente del sensor con la del resto.
Sino muestra cual es el circuito que estás usando porque ya estoy perdido.

El circuito del gráfico #45, es el que estoy usando actualmente y me funciona, el que tiene un ad620, dos lm358, etc, eso lo tengo conectado a una masa diferente a la del sensor, podría intentar conectarlos a la misma masa, pero creo que lo intente así la primera vez y el sensor no me entregaba datos. Voy a intentarlo ahorita que tenga disponible todo y te comento

Mirá, tendrías que obtener algo así (línea roja)


Claramente tu captura (que es la azul) se debe a que el circuito está oscilando o que se está metiendo ruido por falta de alguna masa.
Me inclino más por lo segundo.

Hola gatul, te actualizo,

Alimente mi circuito #45 con 12[V], con la misma fuente y tierra que alimento el sensor MPX, conecte la salida y la tierra al arduino, y se fue la oscilacion, por ahora todo va viento en popa, mañana hare algunas pruebas pero por lo que vi hoy, funciona de maravilla :slight_smile:

Muchisimas gracias gatul, surbyte y los demas que apoyaron, si vuelvo a tener algun inconveniente me veran de nuevo por aca.

Les comparto un código para medir nivel de liquidos el codigo original lo encontre en el foro en español hace unos años lo busque para incluir la referncia pero no di con el
saludos.

#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <Relay.h>
#include<Wire.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

const float NIVEL_INFERIOR = 8061.0;
const float NIVEL_SUPERIOR = 49603.0;

const byte RELE_NIVEL_INFERIOR = 8;
const byte RELE_NIVEL_SUPERIOR = 9;
const unsigned long TIEMPO_MPXPIN = 2500UL;
const unsigned long TIEMPO_PRESENTACIO = 5000UL;
float nivel;
float litros;
float centimetros;
int ESTADOS;
const byte mpxpin = A0;
unsigned long tiempompxpin = 0 ;
unsigned long tiempopresentacion = 0 ;
enum estados_l {
  ESTADO_MPXPIN,
  ESTADO_LITROS,
  ESTADO_CENTIMETROS,
  ESTADO_NIVEL_INFERIOR,
  ESTADO_NIVEL_SUPERIOR
} estado = mpxpin;

void setup() {
  Wire.begin();
  lcd.begin(20, 4);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  Serial.begin(9600);
  lcd.print("D. Marmo Servicios");
  lcd.setCursor(0, 2);
  lcd.print(" cisterna 50 000 ");

  tiempopresentacion = millis();

  pinMode(A0, INPUT);
  pinMode(RELE_NIVEL_INFERIOR, OUTPUT);
  pinMode(RELE_NIVEL_SUPERIOR, OUTPUT);
  digitalWrite (RELE_NIVEL_INFERIOR, HIGH);
  digitalWrite (RELE_NIVEL_SUPERIOR, HIGH);
  tiempompxpin = millis();
  delay (10);
}

void loop() {
  
  if (millis() - tiempompxpin > 2500UL) {
    nivel = analogRead (mpxpin);
    tiempompxpin  = millis();
    float mv = (nivel / 1023.0) * 5000.0;
    float centimetros = mv / 10.960;
    float litros (centimetros * 116.1);

    Serial.print("litros ");
    Serial.println(litros);
    Serial.print("   ctm:  ");
    Serial.println(centimetros);
    Serial.print("   mv:  ");
    Serial.println(mv);
    lcd.setCursor(0, 0);
    lcd.print("litros    ");
    lcd.print(litros);
    lcd.setCursor(0, 2);
    lcd.print("centimetros ");
    lcd.print(centimetros);


    //if (NIVEL_INFERIOR) {
    if ( litros < NIVEL_INFERIOR ) {
      digitalWrite (RELE_NIVEL_INFERIOR, LOW);
    } else {

      digitalWrite (RELE_NIVEL_INFERIOR, HIGH);
    }
    //if (NIVEL_SUPERIOR) {
    if (litros > NIVEL_SUPERIOR ) {

      digitalWrite (RELE_NIVEL_SUPERIOR, LOW);
    } else {

      digitalWrite (RELE_NIVEL_SUPERIOR, HIGH);
    }
  }
}

Cualquier pregunta o sugerencia son bienvenidas

Sugerencias...
Si defines, por ej.

const byte relepinA = 8;

luego no hagas

pinMode(8, OUTPUT);

o

digitalWrite (8, LOW);

es más fácil de entender lo que estás haciendo si lo escribes

pinMode(relepinA, OUTPUT);

y

digitalWrite (relepinA, LOW);

¿Qué pretendes que haga esto?

if (NIVEL_INFERIOR) {

Porque te cuento que salvo que NIVEL_INFERIOR alguna vez sea 0, siempre va a rjecutar el if() porque cualquier valor distinto de 0 se considera true.
Lo mismo pasa con

if (NIVEL_SUPERIOR) {

Seguramente hay más detalles (como la variable estado que defines pero no usas).

Saludos

Hola Gatul tu sugerencia de relepinA en lugar de (8, LOW); me parece perfecta, (lo modificare) lo de nivel inferior y superior, son los limites de las alarmas si es menor de 8061.0 se activa, la alarma de nivel bajo y si rebasa los 49603.0 se activa la alarma de nivel alto.
si seguro y me falta alguna variable que no e definido, tienes alguna sugerencia.
Saludos

Ya edite, quite esto ( 8, LOW); y puse esto (relepinA, LOW);, en post #68
cambiando de tema, en el hilo de Seguidor Solar hice un borrador en maquina de estados, le puedes revisar

Ya se para que son los límites, yo te expliqué otra cosa

Hola Gatul, después de mucho investigar llegue a la conclusión, de que if (NIVEL_INFERIOR) no cumple ninguna función así que lo elimine lo mismo para NIVEL_SUPERIOR. Lo que mas me tiene pensando es porque en esta maquina no me da ningún error, el IDE de Arduino es portable, en una SD eso es lo de menos, intente float mpxpin=A0; const byte mpxpin = A0; en realidad no se como sea correcto a ti te envia error? en tu compu (mpxpin),
el programa funciona bien, eso no quiere decir que este bien programa

E:\arduino-1.8.19\portable\sketchbook\cisterna_machie_state\cisterna_machie_state.ino:28:12: advertencia: conversión no válida de 'int' a 'estados_l' [-fpermissive]
  } estado = mpxpin;
             ^~~~~~

@silvia96 creo que no entiendes que no tiene sentido esto

 if (NIVEL_INFERIOR)

debería ser algo como

if (valor > NIVEL_INFERIOR) {
  // hago algo
}

No has entendido lo que @anon90500195 se viene rompiendo la cabeza para explicarte.

const float NIVEL_INFERIOR = 8061.0;

Es una constante, para que preguntas si (contante) que sentido tiene?

Hola @Surbyte, el post #68 lo edite y elimine el if (NIVEL_SUPERIOR); y el if (NIVEL_INFERIOR); y al parecer ni falta le hace al código, (según yo) siguiendo su sugerencia, if (valor < NIVEL_SUPERIOR); solo cambie "valor<, por nivel<. y en ambos post, #68 y #75 funciono el código sin ningún problema, hace un rato solucione el error permisivo, y cambie esto para que no diese error Arduino.
} estado = mpxpin; por esto, } estado = ESTADO_MPXPIN; y ya no dio error permisivo, adjunto como quedo hasta hora.
Quiero modificarlo para que las ordenes a los reles sean en "switch case" espero lograrlo pronto.

//https://forum.arduino.cc/t/arduino-y-ad620/979015/74
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <Relay.h>
#include<Wire.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

const float NIVEL_INFERIOR = 8061.0;
const float NIVEL_SUPERIOR = 49603.0;

const byte RELE_NIVEL_INFERIOR = 8;
const byte RELE_NIVEL_SUPERIOR = 9;
const unsigned long TIEMPO_MPXPIN = 2500UL;
const unsigned long TIEMPO_PRESENTACIO = 5000UL;

float nivel;
float litros;
float centimetros;
int ESTADOS;
const byte mpxpin = A0;
unsigned long tiempompxpin = 0 ;
unsigned long tiempopresentacion = 0 ;

enum estados_l {
  ESTADO_MPXPIN,
  ESTADO_LITROS,
  ESTADO_CENTIMETROS,
  ESTADO_NIVEL_INFERIOR,
  ESTADO_NIVEL_SUPERIOR
} estado = ESTADO_MPXPIN;

void setup() {
  Wire.begin();
  lcd.begin(20, 4);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  Serial.begin(9600);
  lcd.print("D. Marmo Servicios");
  lcd.setCursor(0, 2);
  lcd.print(" cisterna 50 000 ");

  tiempopresentacion = millis();

  pinMode(A0, INPUT);
  pinMode(RELE_NIVEL_INFERIOR, OUTPUT);
  pinMode(RELE_NIVEL_SUPERIOR, OUTPUT);
  digitalWrite (RELE_NIVEL_INFERIOR, HIGH);
  digitalWrite (RELE_NIVEL_SUPERIOR, HIGH);
  tiempompxpin = millis();
  delay (10);
}

void loop() {

  if (millis() - tiempompxpin > 2500UL) {
    nivel = analogRead (mpxpin);
    tiempompxpin  = millis();
    float mv = (nivel / 1023.0) * 5000.0;
    float centimetros = mv / 10.960;
    float litros (centimetros * 116.1);

    Serial.print("litros ");
    Serial.println(litros);
    Serial.print("   ctm:  ");
    Serial.println(centimetros);
    Serial.print("   mv:  ");
    Serial.println(mv);
    lcd.setCursor(0, 0);
    lcd.print("litros    ");
    lcd.print(litros);
    lcd.setCursor(0, 2);
    lcd.print("centimetros ");
    lcd.print(centimetros);


    if (nivel < NIVEL_INFERIOR) {
      if ( litros < NIVEL_INFERIOR ) {
        digitalWrite (RELE_NIVEL_INFERIOR, LOW);
      } else {

        digitalWrite (RELE_NIVEL_INFERIOR, HIGH);
      }
      if (nivel > NIVEL_SUPERIOR) {
        if (litros > NIVEL_SUPERIOR ) {

          digitalWrite (RELE_NIVEL_SUPERIOR, LOW);
        } else {

          digitalWrite (RELE_NIVEL_SUPERIOR, HIGH);
        }
      }
    }
  }
}


Le quedo una cola de llaves al final, al rato intento ponerlas en su lugar, ahora hay que dormir un rato.
saludos

hola @Surbyte, encontré en el foro en español, en la siguiente liga, (Lectura inestable en las entradas analogicas Arduino Mega 2560 - #4 by Surbyte) donde aconsejas esta especie de ciclo for con millis (no se como se llame ) yo lo subí al código del sensor de presión y funciona con estabilidad (con fluctuaciones mínimas )

// rutina promediacion 

unsigned long sumaADC = 0;
unsigned long start;
unsigned int contador;

void setup() {
	Serial.begin(9600);
   start = millis();
   contador = 0;
}

void loop() {

	sumaADC += analogRead(A0);  // modifica A0 para que coincida con el pin Analogico que estes usando
    contador++;

	if (millis()-start > 1000UL){  // 1000 milisegundos = 1seg
		float promedio = (float) (sumaADC/contador)* 5.0/1023.0;
		Serial.print("AD = ");
		Serial.println(promedio);
		sumaADC = 0;
		contador = 0;
		start = millis(); // preparo para proxima presentación
	}
}

Mi pregunta es: (sumaADC = 10000;), así lo suma 10 mil veces, y así lo divide 10 mil veces (contador = 10000;) , el promedio es lo que imprime en monitor serial, ? o unsigned long sumaADC = 10000;

Donde ves ?

sumaADC = 10000;

Ahi dice, cada 10000 mseg lo que tenga sumaADC (acumulado del ADC y por eso uso unsigned long) será dividido por contador (que se incrementa con cada lectura del ADC) mostrando un promedio.

En que parte del código le pongo que lo sume 10000 veces, para que promedio lo divida y me de el promedio ?, no alcanzo a comprender en que parte se ajusta las veces que quiera que se sumen.
Saludos.

El código lee el puerto analógico contador veces durante 1 segundo y lo acumula en sumaACD, luego calcula el promedio

sumaADC / contador

Para que haga X cantidad de lecturas y luego calcule el promedio tienes que cambiar el código ya que tu ventana de muestreo ya no será por tiempo sino por número de muestras.

Saludos

Hola @anon90500195, entonces tendría que hacerlo en un ciclo for, y hay determinar X cantidad de veces, para que en la ventana de muestreo salga el total de las sumas promediadas?

Vaya otro error de mi parte. Me confundió el 10000.
La ventana de tiempo es de 1000 mseg = 1 segundo.
Toma las muestras del ADC y las acumula durante 1 segundo. Finalmente las promedia gracias a contador y la suma acumulada.
El for sería bloqueante, es decir, si pones eso dentro de un for, el micro acumula valores fijos y finalmente hace la misma operación. O sea el promedio por esa suma fija de iteracciones de tu ciclo for.