Camion Lavacontenedor

Hola a todos, me encuentro aqui escribiendo en busca de una ayuda o alguna idea, para con mi proyecto…mi “codigo” o lo que trato de hacer es un camion para lavar contenedores de basura en las calles, mi codigo hasta los momentos funciona ya que lo he probado con el camion y anda bien…, por favor les pido vean este video para que me entiendan mejor… lava contenedor carga lateral a plc - YouTube

Se tiene un sensor ultrasonico que sale con los brazos, mide la distancia del contenedor y asi se detiene, hace todo el proceso…pero mi pregunta es:

¿Como podria dejar el contenedor en el mismo sitio? , por favor si pueden ayudarme estaria agradecido, dejo aca mi codigo…(Se que no es el mejor o es perfecto, pero lo ando mejorando)

P.D : Estoy usando Arduino Mega

Saludos!

#define RELAY_ON LOW  // Define la activación, ya que el modulo relay trabaja modo Active-Low, la logica es inversa
#define RELAY_OFF HIGH

//Entradas
int Embrague = 53; // Pedal de Embrague
int Bot_Toma = 52; //Boton de toma
int Bot_Play = 51; //Boton para play
int Bajar = 50; // Sensor de Bajada
int Subir = 49; // Sensor de Subida
int Brazos_Arriba = 48; //Sensor de brazos arriba
int Brazos_Abajo = 47; // Sensor Brazos Abajo
int Ultrasonido = A0; // Sensor de Ultrasonido (Cable Negro)
int Palpador_Izquierdo = 46; //Sensor palpador Izq
int Palpador_Derecho = 45; //Sensor Palpador Dere
int Final_de_Carrera = 44; //Sensor final de traslacion adentro
int Max_Rotacion = 43; // Sensor de maxima rotación

//Variables de Lectura
int Lec_Embrague;
int Lec_Toma;
int Lec_Bajar; 
int Lec_Ultra;
int Lec_Play;
int Lec_Subir;
int Lec_BrazosArriba;
int Lec_BrazosAbajo;
int Lec_Palpador_Izquierdo;
int Lec_Palpador_Derecho;
int Lec_Valvula;
int Lec_Final_de_Carrera;
int Lec_Max_Rotacion;
//int Lec_Elevador;

//Salidas Electrovalvulas
int ElecValv_Toma =22; 
int ElecValv_Bajar = 23;
int ElecValv_Traslacion_Afuera = 24;
int ElecValv_Subir = 25;
int ElecValv_BrazosArriba = 26;
int ElecValv_BrazosAbajo = 27;
int ElecValv_Apretar_Brazos = 28;
int ElecValv_Pinza_Cierre = 29;
int ElecValv_Pinza_Libera = 30;
int ElecValv_Abrir_Tapa = 31;
int ElecValv_Traslacion_Adentro = 32;
int ElecValv_Agua = 33;
int ElecValv_Robot = 34;

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);
  
    pinMode(Embrague,INPUT);
    pinMode(Bot_Toma,INPUT);
    pinMode(Bot_Play,INPUT);
    pinMode(ElecValv_Toma,OUTPUT);
    pinMode(Bajar,INPUT);
    pinMode(Ultrasonido,INPUT);
    pinMode(ElecValv_Traslacion_Afuera, OUTPUT);
    pinMode(Subir,INPUT);
    pinMode(ElecValv_Subir,OUTPUT);
    pinMode(Brazos_Arriba,INPUT);
    pinMode(ElecValv_BrazosArriba,OUTPUT);
    pinMode(Brazos_Abajo,INPUT);
    pinMode(ElecValv_Bajar,OUTPUT);
    pinMode(ElecValv_Apretar_Brazos,OUTPUT);
    pinMode(ElecValv_Pinza_Cierre,OUTPUT);
    pinMode(ElecValv_Pinza_Libera,OUTPUT);
    pinMode(ElecValv_Abrir_Tapa,OUTPUT);
    pinMode(Final_de_Carrera,INPUT);
    pinMode(ElecValv_Traslacion_Adentro,OUTPUT);
    pinMode(Max_Rotacion, INPUT);
    pinMode(ElecValv_Agua,OUTPUT);
    pinMode(ElecValv_Robot,OUTPUT);

  
   digitalWrite(ElecValv_Toma, HIGH); 
   digitalWrite(ElecValv_Bajar, HIGH);
   digitalWrite(ElecValv_Traslacion_Afuera, HIGH);
   digitalWrite(ElecValv_Subir, HIGH);
   digitalWrite(ElecValv_BrazosArriba, HIGH);
   digitalWrite(ElecValv_BrazosAbajo , HIGH);
   digitalWrite(ElecValv_Apretar_Brazos, HIGH);
   digitalWrite(ElecValv_Pinza_Cierre, HIGH);
   digitalWrite(ElecValv_Pinza_Libera, HIGH);
   digitalWrite(ElecValv_Abrir_Tapa, HIGH);
   digitalWrite(ElecValv_Traslacion_Adentro, HIGH);
   digitalWrite(ElecValv_Robot,HIGH);
   digitalWrite(ElecValv_Agua,HIGH);
   
  
    
}

void loop() 
{
   
   Lec_Play = digitalRead(Bot_Play);
   Lec_Toma = digitalRead(Bot_Toma);
   Lec_Embrague= digitalRead(Embrague); //Lee el estado del embrague
   
            
    if(Lec_Toma==HIGH && Lec_Embrague == HIGH) //Si el EMBRAGUE estan puestos permite leer el estado de la toma
            {
            delay(20);
            digitalWrite(ElecValv_Toma,RELAY_ON);     
            }
      if(Lec_Toma==LOW){
              digitalWrite(ElecValv_Toma,RELAY_OFF);
            }    


if(Lec_Toma == HIGH && Lec_Play == HIGH)
{
  while(true)
  {

   // ------------------- Activar toma de Fuerza-----------------//
    
                
           // ------------------- Play -----------------//
    
      
   
     //-----------------------Subir Brazos-------------------// 
    
    digitalWrite(ElecValv_BrazosArriba,RELAY_ON);
    delay(1800);
    digitalWrite(ElecValv_BrazosArriba,RELAY_OFF);
    delay(1000);
    
    //-----------------------Bajar Carro-------------------//
    digitalWrite(ElecValv_Bajar,RELAY_ON);
    delay(1500);
    digitalWrite(ElecValv_Bajar,RELAY_OFF);
    delay(1000);
    
    
    //-----------------------Ultrasonido y Traslacion Afuera-------------------//
      for(int i= 0; i<=100;i++)
      {
       Lec_Ultra = analogRead(Ultrasonido);
       delay(50);
       map(Lec_Ultra,0,1023,0,255);
       delay(20);
       Serial.println(Lec_Ultra); 
          if(Lec_Ultra >= 280)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_ON);
           }
           if(Lec_Ultra <= 400)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_OFF);
           }
      }            
       
        //-------------------Apretar Brazos---------------------//
     
    digitalWrite(ElecValv_Apretar_Brazos,RELAY_ON);
    delay(1200);
    digitalWrite(ElecValv_Apretar_Brazos,RELAY_OFF);
    
    
 
    //-----------------------Subir Brazos (2)-------------------//
    digitalWrite(ElecValv_BrazosArriba,RELAY_ON);
    delay(2000);
    digitalWrite(ElecValv_BrazosArriba,RELAY_OFF);
        
    //------------------------Aprieta Pinzas-----------------------//
    digitalWrite(ElecValv_Pinza_Libera,RELAY_ON);
    delay(1000);
    digitalWrite(ElecValv_Pinza_Cierre,RELAY_OFF);
    delay(1500);
    digitalWrite(ElecValv_Pinza_Libera,RELAY_OFF);
    delay(3000);
    Lec_Palpador_Izquierdo = digitalRead(Palpador_Izquierdo);
    Lec_Palpador_Derecho = digitalRead(Palpador_Derecho);
    
     while(Lec_Palpador_Derecho == HIGH && Lec_Palpador_Derecho == HIGH)
    {
    delay(2000);
    digitalWrite(ElecValv_Pinza_Cierre,RELAY_ON);
    delay(1000);
    digitalWrite(ElecValv_Abrir_Tapa,RELAY_ON);
    delay(3000);
    digitalWrite(ElecValv_Abrir_Tapa,RELAY_OFF);
    delay(1000);
    digitalWrite(ElecValv_Subir,RELAY_ON);
    delay(2000);
    digitalWrite(ElecValv_Subir,RELAY_OFF);
    delay(1000);
    digitalWrite(ElecValv_Traslacion_Adentro,RELAY_ON);
    delay(2000);
    digitalWrite(ElecValv_Traslacion_Adentro,RELAY_OFF);
    delay(1000);
    digitalWrite(ElecValv_BrazosArriba,RELAY_ON);
    delay(6000);
    digitalWrite(ElecValv_BrazosArriba,RELAY_OFF);
    delay(1000);
    digitalWrite(ElecValv_Agua,RELAY_ON);
    digitalWrite(ElecValv_Robot,RELAY_ON);
    delay(5000);
    digitalWrite(ElecValv_Agua,RELAY_OFF);
    digitalWrite(ElecValv_Robot,RELAY_OFF);
    break;
    }
    
    
    while(Lec_Palpador_Derecho == LOW && Lec_Palpador_Derecho == LOW)
    {
      delay(2000);
      digitalWrite(ElecValv_Pinza_Cierre,RELAY_OFF);
      digitalWrite(ElecValv_Pinza_Libera,RELAY_ON);
      digitalWrite(ElecValv_Abrir_Tapa,RELAY_OFF);
      digitalWrite(ElecValv_Subir,RELAY_OFF);
      digitalWrite(ElecValv_Traslacion_Adentro,RELAY_OFF);
      digitalWrite(ElecValv_BrazosArriba,RELAY_OFF);
      digitalWrite(ElecValv_Agua,RELAY_OFF);
      digitalWrite(ElecValv_Robot,RELAY_OFF);
      break;
      
      
    }
    break;
   }  

  delay(60000);
  }
  else if (Lec_Toma == LOW)
  {
   digitalWrite(ElecValv_Toma,RELAY_OFF);
   digitalWrite(ElecValv_Toma, HIGH); 
   digitalWrite(ElecValv_Bajar, HIGH);
   digitalWrite(ElecValv_Traslacion_Afuera, HIGH);
   digitalWrite(ElecValv_Subir, HIGH);
   digitalWrite(ElecValv_BrazosArriba, HIGH);
   digitalWrite(ElecValv_BrazosAbajo , HIGH);
   digitalWrite(ElecValv_Apretar_Brazos, HIGH);
   digitalWrite(ElecValv_Pinza_Cierre, HIGH);
   digitalWrite(ElecValv_Pinza_Libera, HIGH);
   digitalWrite(ElecValv_Abrir_Tapa, HIGH);
   digitalWrite(ElecValv_Traslacion_Adentro, HIGH);
   digitalWrite(ElecValv_Robot,HIGH);
   digitalWrite(ElecValv_Agua,HIGH);
  }
}

Y porque dices que no lo deja en el mismo sitio, a mi me parece que lo deja justamente donde lo encontró.

Quiero hacer lo que muestro en el vídeo, ya hago todos los demás pasos, y estoy precisamente en el que debo dejar el contenedor en el mismo sitio en el cual mi sensor midió…no se como decirlo en código…Algo como:

"Si lo tomaste a 100 cm , vuelve a dejarlo en 100 cm "

No comprendo?
No tienes control de cuanto se movió el sistema hidráulico?
Se mueve hasta encontrar el contenedor a lo bruto? Si es asi, o como sea requieres de un sensor.
Solo que en ese ambiente SUCIO como garantizas que el sensor trabaje bien siempre? Pensaba en un sensor ultrasónico pero lo descarto

Veo que el actuador que mueve el brazo de las dos pestañas que terminan levantando el contedor se desplaza horizontalmente hasta encontrar al contenedor.
Obviamente tiene un fin de carrera. No se si eso que se ve es controlado manualmente o no.
Supongamos que es manual.
Tendrias que tener un sensor que registre ese desplazamiento y ahi tienes tu respuesta.

DistanciaDesplazada.png

Si, tiene un sensor ultrasonico en la parte de abajo de la lamina metálica que se ve en el centro,

 //-----------------------Ultrasonido y Traslacion Afuera-------------------//
      for(int i= 0; i<=100;i++)
      {
       Lec_Ultra = analogRead(Ultrasonido);
       delay(50);
       map(Lec_Ultra,0,1023,0,255);
       delay(20);
       Serial.println(Lec_Ultra); 
          if(Lec_Ultra >= 280)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_ON);
           }
           if(Lec_Ultra <= 400)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_OFF);
           }
      }

en esta parte de mi código uso ese sensor y va perfecto, todos los movimientos ( baja brazos, sale a buscar el contenedor, lo agarra, lo eleva, lava, bajan los brazos) los hago, pero me falta es programar la salida para volver a salir a la misma distancia en que lo busco

Que sensor ultrasónico usas? Marca y modelo por favor.

//-----------------------Ultrasonido y Traslacion Afuera-------------------//
      for(int i= 0; i<=100;i++)
      {
       Lec_Ultra = analogRead(Ultrasonido);
       delay(50);
       map(Lec_Ultra,0,1023,0,255);
       delay(20);
       Serial.println(Lec_Ultra); 
          if(Lec_Ultra >= 280)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_ON);
           }
           if(Lec_Ultra <= 400)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_OFF);
           }
      }

Este código es por lo menos poco acostumbrado a menos que uses un sensor industrial con salida 0-5V

Pepperl+Fuchs 3RG6343

A su salida, le hice un divisor de tensión y entran de 0 a 5VDC a traves el puerto analogo A0 de mi arduino

Que suerte que estamos en tu cabeza y ya sabíamos eso!!! Entiendes mi ironía supongo, no?

Bueno, entrega 5V en fondo de escala cual es el rango de medición?

Se supone que leiste las normas del foro, y con ellas debes poner la información que haga falta para que podamos ayudarte.

Aporta un enlace con la hoja de datos del sensor ultrasónico que citas.

Edito: bueno mide hasta 1000 mm en fondo de escala.
De modo que esto no lo entiendo

map(Lec_Ultra,0,1023,0,255);

porque limitas algo entre 0 1023 a un rango 0-255 cuando la medicion real es 0-1000?

Ademas map() debe ser asignado a una variable y no lo haces, no guardas el dato que has medido del sensor.
Y que ese dato sea tu valor luego a alcanzar.

Pido disculpas, pase por alto eso, el trabajo me tiene un poco atontado…En fin gracias por responder

Hago ese divisor de tensión para que no le entren los 10V de salida…Leyendo ahorita el datasheet me doy cuenta que tiene de resolución 8 bits …ya quitare esa función map de alli

Ahorita mismo estoy en el trabajo y estaba probando algo como

//-----------------------Ultrasonido y Traslacion Afuera-------------------//
      for(int i= 0; i<=100;i++)
      {
       Lec_Ultra = analogRead(Ultrasonido);
       delay(50);
       
       delay(20);
       
          if(Lec_Ultra >= 280)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_ON);
             Cont_Ultra++;
           }
           if(Lec_Ultra <= 400)
           {
             digitalWrite(ElecValv_Traslacion_Afuera,RELAY_OFF);
           }
           Serial.println(Cont_Ultra);      
      }                     
      

    //--------------------------Traslacion Adentro------------//
    digitalWrite(ElecValv_Traslacion_Adentro,RELAY_ON);
    delay(3000);
    digitalWrite(ElecValv_Traslacion_Adentro,RELAY_OFF);
    delay(1000);
    //---------------------------Traslación Afuera----------------------------//
     for(i2=0;i2==Con_Ultra;i2++)
      {
        digitalWrite(ElecValv_Traslacion_Afuera,RELAY_ON);
      }
     
      digitalWrite(ElecValv_Traslacion_Afuera,RELAY_OFF);

Un par de apuntes.
Entiendo por el código que el sensor ultrasónico se desplaza con el brazo. Por lo tanto, si no hay forma de conocer la posición de los brazos en el momento de recoger el contenedor, o no tenemos un sensor de distancia fijo en el camión, no sabremos en qué momento el contenedor vuelve a estar a la distancia inicial (estará en todo momento a distancia cero del brazo, mientras no lo soltemos.
En cuanto al map, tal como está no hace nada, ya que no se está asignando el valor devuelto por la función a nada. Si se borra esa línea no afectará en nada al funcionamiento actual.
Y para finalizar, este es un ejemplo perfecto en el que está plenamente justificado el esfuerzo de hacer una máquina de estados y eliminar delays, para seguir atendiendo sensores o botones de parada, etc...

El sensor ultrasonico puede estar fijo tambien, yo lo coloque alli para ir creando mi codigo, pero lo puedo colocar fijo ya que el camion posee una base para colocarlo

Tambien pense en eso, pero por ahora estoy interesado en saber como volver a dejar el contenedor en el mismo sitio.

Pensaba en usar el sensor fijo, pero como podria almacenar esa variable analoga y decirle que salga a esa misma distancia

Si usos relay, o sea no podria usar algo como analogWrite ();

Si usos relay, o sea no podria usar algo como analogWrite ();

@noter habla de delay no de relay.

Bueno, yo te puse una captura donde esta claro el desplazamiento del brazo y que en esa posición extrema derecha podria ir el sensor ultrasónico. No se donde esta ubicado porque no lo has dicho.
Entendemos que estes abrumado pero tu vienes con la consulta y por eso te pido que te esmeres a la hora de explicar porque lo que puede estar claro para ti no siempre lo estará para nosotos.

Tu código esta plagado de delays(). NO PUEDES USAR DELAYS en algo que require mediciones.

Tienes que usar un maquina de estados, Ve a Documentacion => Indice de temas tutoriales => máquina de estados y tmb lee millis() que será lo que reemplace a delay a cada delay que debe desaparecer.

Cuando entiendas eso, podremos seguir, sin eso es imposible que tu código haga las operaciones y a la vez mire donde esta el brazo.

Espero se comprenda.

Entiendo lo de la función millis() , usaba los delay(); en los movimientos lineales, porque mientras no necesito hacer mas nada...pero esta bien, tomare sus consejos y luego les informo...

Muchas gracias por sus tiempos

Bueno tal vez puedas separar gran parte del código haciendo la tarea secuencial correspondiente y reservar un par de momentos en los que uses una maquina de estados para el posicionamiento del contenedor antes y despues.

Actualizo, este tema

Aca en el trabajo le adaptaron una lamina de metal con agujeros, la cual cuando sale el brazo a buscar el contenedor un sensor inductivo basico https://files.pepperl-fuchs.com/webcat/navi/productInfo/edb/800735_spa.pdf?v=20180403000106 , va contando los agujeros…Se me ocurrio que podria usar este codigo

const int  buttonPin = 50;    // the pin that the pushbutton is attached to
const int ledPin = 22;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int Contador= 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);


  
}
void loop() {

 
  // read the pushbutton input pin
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
        
        buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
    }
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
    
   
         
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;

Que es uno de los ejemplos, este codigo ya almacena los pulsos contados, pero pensaba algo como

for(Contador=0; Contador==buttonPushCounter;Contador++)
  {
    digitalWrite(40,HIGH);
  }

Basicamente necesitaria grabar esos pulsos que se van a contar en la primera salida del brazo que haga todo el proceso y luego cuando lo vaya a dejar en su sitio, de alguna forma crear como un loop que repita la cantidad de veces que ya conte

Me darian alguna idea?, o estoy completamente perdido? =´D

Gracias!