ACS712 se queda "colgado"

Hola:

Estoy controlando el sentido de giro un motor de 30VDC 2A con un puente H hecho con relés. Para medir el consumo utilizo un ACS712.

Pulsando dos pulsadores el motor gira hacia un lado y hacia otro mostrando el consumo correcto (verificado) sin problemas.

El problema viene cuando, pasado un tiempo, la entrada analógica lee sólo 2,5V y deja de funcionar. La solución está en quitar alimentación del ACS712 y volver a conectar (sin necesidad de resetear el programa).

Claro está que no quiero tener que estar quitando alimentación constantemente al ACS712. La pregunta es ¿porqué deja de funcionar el ACS712? yo sospecho que puede ser por un problema de ruido producido por los relés.

Creo que el ACS712 es totalmente analógico con lo que díficilmente pueda "colgarse". Mas que eso apunto a que el que se "cuelga" es Arduino.

Para que podamos comprender mejor la situación nos haria falta un esquema del hardware de tu montaje tal y como lo tienes y el código que utilizas para Arduino.

Reseteando arduino sigue fallando. Sólo consigo que vuelva a funciona quitando tensión.
Dejo el código y el esquema.

int Out_Subir = 4;  /*  *** Probador: 22 / Uno: 4 *** */
int Out_Bajar = 5;  /*  *** Probador: 24 / Uno: 5 *** */
int In_Subir = 6;  /*  *** Probador: 9 / Uno: 7 *** */
int In_Bajar = 7;  /*  *** Probador: 8 / Uno: 6 *** */
int Pulsado_Subir, Pulsado_Bajar, Pulsado_Subir_Ant, Pulsado_Bajar_Ant;
bool EstadoOut_Subir;
bool EstadoOut_Bajar;
float SENSIBILITY = 0.185;   // Modelo 5A
int SAMPLESNUMBER = 500;

void setup() {

  Serial.begin(9600);
  pinMode(In_Subir, INPUT); /*  *** Pulsador Subir *** */
  pinMode(In_Bajar, INPUT); /*  *** Pulsador Subir *** */
  pinMode(Out_Subir, OUTPUT); /*  *** Relé Subir *** */
  pinMode(Out_Bajar, OUTPUT); /*  *** Relé Bajar *** */
  digitalWrite(Out_Subir, HIGH); /*  *** Forzado a Off de los relés al inicio para evitar activación al réset  *** */
  EstadoOut_Subir = false; /*  *** Salida negada ***/
  digitalWrite(Out_Bajar, HIGH); /*  *** Forzado a Off de los relés al inicio para evitar activación al réset  *** */
  EstadoOut_Bajar = false; /*  *** Salida negada ***/
  Serial.println("------------------------------------------------");
}
void loop() {
  Pulsadores();
}
void Pulsadores()
{
  Pulsado_Subir = digitalRead(In_Subir);
  Pulsado_Bajar = digitalRead(In_Bajar);
  /*  *** Prueba Amperímetro  *** */
  if (Pulsado_Subir == 1)
  {
    float LecturaConsumo;
    LecturaConsumo = getCorriente(SAMPLESNUMBER);
    Serial.print("Consumo en Subida: ");
    Serial.println(LecturaConsumo);
  }
  if (Pulsado_Bajar == 1)
  {
    float LecturaConsumo;
    LecturaConsumo = getCorriente(SAMPLESNUMBER);
    Serial.print("Consumo en Bajada: ");
    Serial.println(LecturaConsumo);
  }
  if ((Pulsado_Subir == 0) && (Pulsado_Bajar == 0))
  {
    float LecturaConsumo;
    LecturaConsumo = getCorriente(SAMPLESNUMBER);
    Serial.print("Consumo en Reposo: ");
    Serial.println(LecturaConsumo);
  }
  if ((Pulsado_Subir == 1) && (Pulsado_Subir_Ant == 0))
  {
    //Serial.println("Pulsado Subir");
    digitalWrite(Out_Subir, LOW);
  }
  if ((Pulsado_Subir == 0) && (Pulsado_Subir_Ant == 1))
  {
    //Serial.println("Soltado Subir");
    digitalWrite(Out_Subir, HIGH);
  }
  if ((Pulsado_Bajar == 1) && (Pulsado_Bajar_Ant == 0))
  {
    //Serial.println("Pulsado Bajar");
    digitalWrite(Out_Bajar, LOW);
  }
  if ((Pulsado_Bajar == 0) && (Pulsado_Bajar_Ant == 1))
  {
    //Serial.println("Soltado Bajar");
    digitalWrite(Out_Bajar, HIGH);
  }
  Pulsado_Subir_Ant = Pulsado_Subir;
  Pulsado_Bajar_Ant = Pulsado_Bajar;

}
float getCorriente(int samplesNumber)
{
  float voltage;
  float corrienteSum = 0;
  float LecturaAnalogica;
  float AnalogSum = 0;
  for (int i = 0; i < samplesNumber; i++)
  {
    voltage = analogRead(A0) * 5.0 / 1023.0;
    corrienteSum += (voltage - 2.5) / SENSIBILITY;
    LecturaAnalogica = analogRead(A0);
    AnalogSum += LecturaAnalogica;
  }
  return (corrienteSum / samplesNumber);
}

Por lo visto el que se cuelga es tu fuente step-down LM2596 con la que alimentas Arduino al pin de 5V.

Porque no la ajustas a 6.5 o 7V y entras por VIN y modificas todo para que funcione alimentado desde Arduino?

Uff. Modificar toda la alimentación es un follón. Está montado en una caja pequeñita.

Pero, si se quedara colgado el LM2596, se quedaría colgado también el Arduino y no es así. Yo puedo seguir moviendo el motor con los pulsadores sólo que en el monitor serial la lectura de la A0 se queda fija a 0 (o sea 2,5V). Quitando alimentación al ACS712 (Y SÓLO AL ACS712), vuelvo a leer correctamente la entrada sin resetear Arduino. Pasado un rato, deja de funcionar.

He pensado en usar algún tipo de driver para el motor, he encontrado el L298 que soporta motores de hasta 2A, pero se me queda un poco corto ya que mi motor a veces supera ese amperaje. También he pensado en algún puente H simple hecho con transistores, pero no encuentro ninguna PCI hecha y me da pereza currarme una.

Ok.

Prueba esto:

float getCorriente(int samplesNumber) {
  float voltage;
  unsigned long corrienteSum = 0;
  //float LecturaAnalogica; comentados porque no estaban en uso
  //unsigned long AnalogSum = 0;

  for (int i = 0; i < samplesNumber; i++)  {
      corrienteSum += analogRead(A0);
  }
  voltage = ((float) corrienteSum/samplesNumber - 2.5) / SENSIBILITY;
  return voltage;
}

Voy a probarlo. Si no funciona probaré de alimentar el ACS712 con una salida de Arduino y controlarla.
Luego os cuento

He probado la modificación propuesta y nada.
Al final he conectado la alimentación del ACS712 a una salida del Arduino que enciendo y apago antes y después de hacer una lectura y no ha fallado en todo el fin de semana.

int Out_ACS712 = 3;  /*  *** Probador: 20 / Uno: 3 *** */
int Out_Subir = 4;  /*  *** Probador: 22 / Uno: 4 *** */
int Out_Bajar = 5;  /*  *** Probador: 24 / Uno: 5 *** */
int In_Subir = 6;  /*  *** Probador: 9 / Uno: 7 *** */
int In_Bajar = 7;  /*  *** Probador: 8 / Uno: 6 *** */
int Pulsado_Subir, Pulsado_Bajar, Pulsado_Subir_Ant, Pulsado_Bajar_Ant;
bool EstadoOut_Subir;
bool EstadoOut_Bajar;
float SENSIBILITY = 0.185;   // Modelo 5A 0.185
int SAMPLESNUMBER = 500;

void setup() {

  Serial.begin(9600);
  pinMode(In_Subir, INPUT); /*  *** Pulsador Subir *** */
  pinMode(In_Bajar, INPUT); /*  *** Pulsador Subir *** */
  pinMode(Out_Subir, OUTPUT); /*  *** Relé Subir *** */
  pinMode(Out_Bajar, OUTPUT); /*  *** Relé Bajar *** */
  pinMode(Out_ACS712, OUTPUT); /*  *** Alimentación ACS712 *** */
   digitalWrite(Out_ACS712, LOW);
  digitalWrite(Out_Subir, HIGH); /*  *** Forzado a Off de los relés al inicio para evitar activación al réset  *** */
  EstadoOut_Subir = false; /*  *** Salida negada ***/
  digitalWrite(Out_Bajar, HIGH); /*  *** Forzado a Off de los relés al inicio para evitar activación al réset  *** */
  EstadoOut_Bajar = false; /*  *** Salida negada ***/
  Serial.println("------------------------------------------------");
}
void loop() {
  Pulsadores();
}
void Pulsadores()
{
  Pulsado_Subir = digitalRead(In_Subir);
  Pulsado_Bajar = digitalRead(In_Bajar);
  /*  *** Prueba Amperímetro  *** */
  if (Pulsado_Subir == 1)
  {
    float LecturaConsumo;
    LecturaConsumo = getCorriente(SAMPLESNUMBER);
    Serial.print("Consumo en Subida: ");
    Serial.println(LecturaConsumo);
  }
  if (Pulsado_Bajar == 1)
  {
    float LecturaConsumo;
    LecturaConsumo = getCorriente(SAMPLESNUMBER);
    Serial.print("Consumo en Bajada: ");
    Serial.println(LecturaConsumo);
  }
  if ((Pulsado_Subir == 0) && (Pulsado_Bajar == 0))
  {
    float LecturaConsumo;
    LecturaConsumo = getCorriente(SAMPLESNUMBER);
    Serial.print("Consumo en Reposo: ");
    Serial.println(LecturaConsumo);
  }
  if ((Pulsado_Subir == 1) && (Pulsado_Subir_Ant == 0))
  {
    //Serial.println("Pulsado Subir");
    digitalWrite(Out_Subir, LOW);
   delay(100);
   digitalWrite(Out_ACS712, HIGH);
    
  }
  if ((Pulsado_Subir == 0) && (Pulsado_Subir_Ant == 1))
  {
    //Serial.println("Soltado Subir");
    digitalWrite(Out_Subir, HIGH);
digitalWrite(Out_ACS712, LOW);
  }
  if ((Pulsado_Bajar == 1) && (Pulsado_Bajar_Ant == 0))
  {
    //Serial.println("Pulsado Bajar");
    digitalWrite(Out_Bajar, LOW);
   delay(100);
   digitalWrite(Out_ACS712, HIGH);
  }
  if ((Pulsado_Bajar == 0) && (Pulsado_Bajar_Ant == 1))
  {
    //Serial.println("Soltado Bajar");
    digitalWrite(Out_Bajar, HIGH);
   digitalWrite(Out_ACS712, LOW);
  }
  Pulsado_Subir_Ant = Pulsado_Subir;
  Pulsado_Bajar_Ant = Pulsado_Bajar;

}
float getCorriente(int samplesNumber)
{
  float voltage;
  float corrienteSum = 0;
  for (int i = 0; i < samplesNumber; i++)
  {
    voltage = (analogRead(A0) * 5.0 / 1023.0);
    corrienteSum += (voltage - 2.5) / SENSIBILITY;
    corrienteSum += 0.67;
  }
  return (corrienteSum / samplesNumber);
}

En mi opinión no es una solución elegante, pero de momento me vale. Como tengo que hacer más cosas con el ACS712, ya iré desvelando el misterio…