Arduino y pistones hidráulicos

Hola a todos, soy nuevo en el foro y pensé que podría recibir algo de ayuda.
Estoy intentando realizar un proyecto de control de uno pistones hidráulicos mediante Arduino. La secuencia la hago sensando la posición del pistón con unos sensores ITR9608. El código y el hardware me funcionó bien al haber conectado solo las electrovalvulas, pero si conecto la bomba que impulsa los pistones pues…o funciona solo 3 ciclos y se para, o funciona y la pantalla LCD (usada mediante el protocolo I2C) me empieza a sacar letras japonesas. Alguna idea de que hacer para que funcione con todo montado? Cualquier ayuda se agradece :slight_smile:
Anexo el código por si de pronto tiene que ver con el problema.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR    0x27  // Define I2C Address where the SainSmart LCD is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
int sensorPin1 = A0 ;    // seleccionar la entrada para el sensor 1
int sensorPin2 = A1 ;    // seleccionar la entrada para el sensor 2
int sensorPin3 = A2 ;    // seleccionar la entrada para el sensor 3
int sensorPin4 = A3 ;    // seleccionar la entrada para el sensor 4
int sensorPin5 = A4;     // seleccionar la entrada para el sensor 5
int sensorPin6 = A5;     // seleccionar la entrada para el sensor 6
int incrementar = A6;    // Entrada para aumentar el tiempo, puerto 6
int decrementar = A7;    // Entrada para disminuir el tiempo, puerto 7
int enter = A8; //Enter
int frenado = A9; //Parar la maquina
int sensorValue1; // variable que almacena el valor raw1 (0 a 1023)
int sensorValue2; // variable que almacena el valor raw2 (0 a 1023)
int sensorValue3; // variable que almacena el valor raw3 (0 a 1023)
int sensorValue4; // variable que almacena el valor raw4 (0 a 1023)
int sensorValue5; // variable que almacena el valor raw5 (0 a 1023)
int sensorValue6; // variable que almacena el valor raw6 (0 a 1023)
int aumento;
int disminuyo;
int enteer;
int borrar;
int parar;
int salidaON = 9; //pin de salida ON
int salidaOFF = 8; //pin de salida OFF
int contador = 9;
long int tiempo_activo = 1000;
long int tiempo_espera = 250;
int n = 10; //cantidad de tiempos de espera para poner las piezas, se modifica con los pulsadores
long int ciclos = 0;
long int piezas = 0;
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

void setup() {
Serial.begin(9600); // Comunicacion a 9600 bits por segundo
pinMode(9, OUTPUT); //configurando el pin 9 como salida
pinMode(8, OUTPUT); //configurando el pin 8 como salida
pinMode(10, OUTPUT);
pinMode(A0, INPUT); //configurando el pin A0 como ENTRADA
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
pinMode(A6, INPUT);
pinMode(A7, INPUT);
pinMode(A8, INPUT);
pinMode(A9, INPUT);
lcd.begin (20, 4);
// Prende los LED de fondo
lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
lcd.setBacklight(HIGH);
// Escribe los titulos y los numeros iniciales
// Position cursor and write some text
lcd.home ();                   //Primera linea
lcd.print("Tiempo:");
lcd.setCursor ( 7, 0 );
lcd.print("10 Segundos");
lcd.setCursor ( 0, 1 );  // Segunda Linea
lcd.print("Ciclos:");
lcd.setCursor ( 7, 1 );
lcd.print(ciclos);
lcd.setCursor ( 0, 2 );        // Tercera Linea
lcd.print("Piezas:");
lcd.setCursor ( 7, 2 );
lcd.print(piezas);
lcd.setCursor (12, 2);
lcd.print("Unidades");

}

void loop() {
//Lectura de los valores entregados por los sensores
sensorValue1 = digitalRead(sensorPin1);
sensorValue2 = digitalRead(sensorPin2);
sensorValue3 = digitalRead(sensorPin3);
sensorValue4 = digitalRead(sensorPin4);
sensorValue5 = digitalRead(sensorPin5);
sensorValue6 = digitalRead(sensorPin6);
aumento = digitalRead(incrementar);
disminuyo = digitalRead(decrementar);
enteer = digitalRead(enter);
parar = digitalRead(frenado);
if (aumento == HIGH)
{
  n = n + 1;
  if (n > 60) {
    n = 60;
  }
  lcd.home ();                   //Primera linea
  lcd.print("Tiempo:");
  lcd.setCursor ( 7, 0 );
  lcd.print(n);
  lcd.setCursor(10, 0);
  lcd.print("Segundos");
  lcd.setCursor ( 0, 1 );  // Segunda Linea
  lcd.print("Ciclos:");
  lcd.setCursor ( 7, 1 );
  lcd.print(ciclos);
  lcd.setCursor ( 0, 2 );        // Tercera Linea
  lcd.print("Piezas:");
  lcd.setCursor ( 7, 2 );
  lcd.print(piezas);
  lcd.setCursor (12, 2);
  lcd.print("Unidades");
}
if (disminuyo == HIGH)
{
  n = n - 1;
  if (n < 10) {
    n = 10;
  }
  lcd.home ();                   //Primera linea
  lcd.print("Tiempo:");
  lcd.setCursor ( 7, 0 );
  lcd.print(n);
  lcd.setCursor(10, 0);
  lcd.print("Segundos");
  lcd.setCursor ( 0, 1 );  // Segunda Linea
  lcd.print("Ciclos:");
  lcd.setCursor ( 7, 1 );
  lcd.print(ciclos);
  lcd.setCursor ( 0, 2 );        // Tercera Linea
  lcd.print("Piezas:");
  lcd.setCursor ( 7, 2 );
  lcd.print(piezas);
  lcd.setCursor (12, 2);
  lcd.print("Unidades");
}
if (enteer == HIGH)
{
  contador = 0;
}

if (contador == 0) //llevar el piston al punto 0
{
  digitalWrite(9, HIGH);
  delay(tiempo_activo);
  digitalWrite(9, LOW);
  delay(tiempo_espera);
  contador = 1;
}
if (contador == 1) //comienza la secuencia
{
  if (parar == HIGH)
  {
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);

  }
  else {
    if ((sensorValue1 == LOW) && (sensorValue2 == LOW)) //Sensores 1 y 2 para llevar el piston al punto 0
    {
      delay(tiempo_espera);
      digitalWrite(9, HIGH);
      delay(tiempo_activo);
      digitalWrite(9, LOW);
    }
    if ((sensorValue3 == LOW) && (sensorValue4 == LOW)) //Sensores 1 y 2 para llevar el piston al punto A
    {
      delay(n * (tiempo_espera + 750));
      digitalWrite(9, HIGH);
      delay(tiempo_activo);
      digitalWrite(9, LOW);
      ciclos = ciclos + 1;
      piezas = ciclos * 4;
      lcd.home ();                   //Primera linea
      lcd.print("Tiempo:");
      lcd.setCursor ( 7, 0 );
      lcd.print(n);
      lcd.setCursor(10, 0);
      lcd.print("Segundos");
      lcd.setCursor ( 0, 1 );  // Segunda Linea
      lcd.print("Ciclos:");
      lcd.setCursor ( 7, 1 );
      lcd.print(ciclos);
      lcd.setCursor ( 0, 2 );        // Tercera Linea
      lcd.print("Piezas:");
      lcd.setCursor ( 7, 2 );
      lcd.print(piezas);
      lcd.setCursor (12, 2);
      lcd.print("Unidades");
    }
    if ((sensorValue5 == LOW) && (sensorValue6 == LOW)) //Sensores 1 y 2 para llevar el piston al punto B
    {
      delay(tiempo_espera);
      digitalWrite(8, HIGH);
      delay(2 * tiempo_activo);
      digitalWrite(8, LOW);
    }
  }
}
}

program.txt (6.25 KB)

Hola,
Lo de las letras chinas o japonesas en el display pasa cuando no le llega bien la alimentación, tu problema parece cosa de consumos, seguramente con alimentar el motor con una fuente externa será suficiente.
Un saludo.

rodripelto: Hola, Lo de las letras chinas o japonesas en el display pasa cuando no le llega bien la alimentación, tu problema parece cosa de consumos, seguramente con alimentar el motor con una fuente externa será suficiente. Un saludo.

El motor tiene su fuente aparte

Tienes ruido, ruido y mas ruido, que se mete por todos lados.
La activación de los actuadores y electroválvulas en algun momento provocan que el Arduino se tilde/resetee.

Bien, es un tema de dificil solución a veces y en otras unos simples cambios mejoran notablemente los problemas.

Veamos cual es tu caso?

El código y el hardware me funcionó bien al haber conectado solo las electrovalvulas, pero si conecto la bomba que impulsa los pistones pues

Electroválvulas de que tipo DC o AC, si son DC tienes diodo en antiparalelo, como las comandas, RELE o MOSFET?
Si son AC, tienes Snubbers? Usas SSR (disparo por triac x cruce por cero)?
Los cables que comandan RELES o elementos de control tienen malla?
Motor, mismo tema. Contactor? SSR mono o trifásico?
Hay puesta a tierra

Tienes el arduino con caja metálica
Usas cilindro ferrite en el cable que alimenta el arduino o unfiltro RFI?

Ya ves que son muchas cosas a tener en cuenta.

Demasiadas cosas, es verdad jaja. No tengo el arduino en caja metálica, las electrovalvulas son AC controladas por software (con sus respectivos relés, claro está). Básicamente quiero controlar el movimiento con 3 sensores (y son dos pistones, de ahí que en el código pregunte por dos sensores). Los sensores estan cableados con par trenzado.

Bueno comienza a ver quien es el culpable. Si es el motor, las válvulas o ambos. Asi que prueba prender apagar a tontas y ver que pasa.. y luego concentras esfuerzos.

Si son AC, usa Snubbers o considera los SSR, los compras segun la potencia del motor/valvula.

Basicamente tu le envias la señal a la válvula o motor y el disparo se hace x cruce por cero minimizando las EM y toda perturbación posibles.

Moudlo RELE ESTADO SOLIDO

Este no tiene cruce x cero.

Tengo conectado tanto el motor como las electrovalvulas, pero la pantalla LCD esta desconectada (bueno, solo los cables SCL y el otro que no recuerdo el nombre) y funciona sin problema hasta ahora, que podría ser? , siento ser tan cansón con este tema.

Ahh entonces la que sufre el problema es la pantalla? con los caracteres raros? Tu dijiste que hacia 3 ciclos y se detenía?

Así es, hace 3 y se detiene, o hace infinitos y saca los caracteres raros. Y si quito lo que te digo no presenta problema, es que es algo bastante extraño...

Bueno, he logrado solucionar el problema (bueno, casi, porque a veces se presentan fallas pero muy espontaneas, y bueno, solucionamos*, pues los procedimientos que hice fue siguiendo las instrucciones de Surbyte, quien me guió claramente y con detalle para solucionar los problemas paso a paso). Básicamente hice un par de cosas: Implementar el arreglo que se muestra en la imagen (que es un llamado filtro “apaga chispas”)
Además, utilice un cable 4x22 para el LCD controlado con I2C (con esto logro que casi nunca me salgan caracteres extraños). Aún se presenta el problema pero de manera muy esporádica. Aún falta ensayar una última instrucción: usar relés de estado sólido.

Ultimo post sobre el tema (eso espero). Finalmente dejé el sistema con unos relés de estado sólido (SSR), con esta modificación se vio reducido todo problema ocasional que sucedía. Adicionalmente se le puso tambíen el filtro "apagachispas". Recomendaciones: Si hay que leer valores de sensores (como en mi caso), es bueno no almacenar el valor en una variable (de ser necesario, pues se hace) sino mas bien utilizar la lectura en el momento que se requiera; así el valor siempre estará actualizado. Por otra parte, a lo que el LCD respecta, fue bastante útil el uso de la función "sprintf" para poder mostrar números de 1 y 2 cifras sin problema al pasar del uno al otro. Por último, para la lectura de los botones, se utilizó la función Bounce con su respectiva librería. garantizando que los valores que registran los botones estan siempre actualizados. Agradecimientos a Surbyte por todos los consejos y soluciones que me dio para los problemas presentados, los cuales fueron expuestos en este y en anteriores posts.