viernes, 4 de noviembre de 2011

Robot panoramico...vamos prosperando

    Una vez montada la shield de potencia de los motores y tras familiarizarme con el lenguaje Arduino, me faltaba unos pulsadores para mover el motor manualmente, pues la intención era que se pudiera definir el angulo de la panoramica sin tener de entrar en programación, para evitar de pasear el portatil junto la camara mas otros "trastos" para realizar una panoramica. No tenia muy claro si utilizar un mando remoto inhalambrico o bién con pulsadores, finalmente me decanté por lo tradicional:
En la misma placa donde hay los pulsadores en cruz , he dispuesto de dos botones más que sirven para validar los extremos opuestos de la captura, luego el programa se autoajusta al número de filas y columnas necesarios
Ahora tocaba programar para "probar" si realmente me podia salir con la mia, y aquí está (cuidadín falta depurarlo y corregir errores, pero funciona):

/*
 Photo Robot 2x L298N + Nema 17
 language: Wiring/Arduino

 This program drives two bipolar stepper motor.
 The motor is attached to digital pins 8+9 & 10+12 of the Arduino.
 The pthoto-shots signals it's actuated by relay -Pin 13-
 Movement manual motor by array switchs

 Created 26 Oct. 2011

 by XavierGP

 */

// define the pins used


#include <Stepper.h>        // incluimos la Stepper library

#define motorStepsX 200     // Pasos motor X 360º/1.8º
#define motorStepsY 200     // Pasos motor Y 360º/1.8º                     
#define motorPinX1 10       // Pin OUT 1 control motor X
#define motorPinX2 12       // Pin OUT 2 control motor X
#define enablePin 11        // Pin OUT 11 habilita tensión en motores
#define motorPinY1 8        // Pin OUT 1 control motor Y
#define motorPinY2 9        // Pin OUT 2 control motor Y


int pasoX=10;                // º entre capturas eje X DÓNDE 10 SON 18º
int pasoY=10;                // º entre capturas eje Y
int xact=0;                 // º actual eje X
int yact=0;                 // º actual eje Y
int xmax=0;                 // º posición máxima eje X
int xmin=0;                 // º posición mínima eje X
int ymax=0;                 // º posición máxima eje Y
int ymin=0;                 // º posición mínima eje Y
int xtemp=0;
int ytemp=0;
int definecornerA=0;
int definecornerB=0;
int nshot=0;
int filasX;                 // número de filas eje X >> (xmax-xmin)/pasoX
int filasXX=0;
int columnasY;              // número de columnas eje Y    >> (ymax-ymin)/pasoY
int columnasYY=0;
int previsionShot;          // prevision número shots   filasX * columnasY

// initialize of the Stepper library:
Stepper myStepperX(motorStepsX, motorPinX1,motorPinX2); // libreria motor X
Stepper myStepperY(motorStepsY, motorPinY1,motorPinY2); // libreria motor Y

void setup() {

 pinMode(2, INPUT);        // Input digital 2 =  confirmación corner A 
 pinMode(3, INPUT);        // Input digital 3 =  confirmación corner B
 pinMode(4, INPUT);        // Input digital 4 =  -Y
 pinMode(5, INPUT);        // Input digital 5 =  +Y
 pinMode(6, INPUT);        // Input digital 6 =  +X
 pinMode(7, INPUT);        // Input digital 7 =  -X
 pinMode(13, OUTPUT);      // Output digital 13 = shot
 myStepperX.setSpeed(30); // set the motor X speed at 100 RPMS:
 myStepperY.setSpeed(30); // set the motor Y speed at 100 RPMS:
 
 pinMode(enablePin, OUTPUT);
 digitalWrite(enablePin, HIGH);  // habilita tensión en motores

 Serial.begin(9600);           // Initialize the Serial port:
 Serial.println("Posicione mediante cursores el extremo de origen y valide con CORNER A. Este pasara a ser el punto 0,0");
 Serial.println("A continuacion posicione mediante el otro extremo y valide con CORNER B");
}

void loop(){

  if(definecornerA==0 || definecornerB==0)   //  definimos máximos y mínimos de X e Y
 {
  int sensorValue0 = digitalRead(6);   // Input digital 2 =  +X
  int sensorValue1 = digitalRead(7);   // Input digital 3 =  -X
  int sensorValue2 = digitalRead(5);   // Input digital 4 =  -Y
  int sensorValue3 = digitalRead(4);   // Input digital 5 =  +Y
  int sensorValue4 = digitalRead(2);   // Input digital 6 =  confirmación corner A
  int sensorValue5 = digitalRead(3);   // Input digital 7 =  confirmación corner B
   
  if(sensorValue0==HIGH)
  {
    xact=xact+pasoX;
    Serial.print(xact*1.8);
    Serial.print("  ,  ");
    Serial.println(yact*1.8);
  }
 
   if(sensorValue1==HIGH)
  {
    xact=xact-pasoX;
    Serial.print(xact*1.8);
    Serial.print("  ,  "); 
    Serial.println(yact*1.8);
  }
   if(sensorValue3==HIGH)
  {
    yact=yact-pasoY;
    Serial.print(xact*1.8);
    Serial.print("  ,  ");
    Serial.println(yact*1.8);
  }
   if(sensorValue2==HIGH)
  {
    yact=yact+pasoY;
    Serial.print(xact*1.8);
    Serial.print("  ,  ");
    Serial.println(yact*1.8);
  }
   if(definecornerA!=1){
   if(sensorValue4==HIGH)
  {
    xmin=xact;
    ymin=yact;
    definecornerA=1;
    Serial.println("Esquina A -inferior izquierda- CONFIRMADA ! Punto de inicio");
  }
   }
   if(definecornerB!=1 && definecornerA==1){
   if(sensorValue5==HIGH)
  {
    xmax=xact;
    ymax=yact;
    definecornerB=1;
    Serial.println("Esquina B -superior derecha- CONFIRMADA !");
  }
   }
  myStepperX.step(xact-xtemp);
  xtemp=xact;
  myStepperY.step(yact-ytemp);
  ytemp=yact;
  delay(200);
 }
 else{

  xact=-xmin;
  yact=-ymin;
  filasX=((xmax-xmin)/pasoX)+1;
  filasXX=filasX;
  columnasY=((ymax-ymin)/pasoY)+1;
  columnasYY=columnasY;
  previsionShot=filasX*columnasY;
  myStepperX.step(-(filasX-1)*pasoX);
  myStepperY.step(-(columnasY-1)*pasoY);   
  Serial.println("Panorama data:");
  Serial.println("n SHOT :  Filas X , Columna Y , grados X, grados Y");
  Serial.print(previsionShot);
  Serial.print("      ,    ");
  Serial.print(filasX);
  Serial.print("     ,   ");
  Serial.print(columnasY);
  Serial.print("     ,   ");
  Serial.print((-xmin+xmax)*1.8);
  Serial.print("  ,   ");
  Serial.println((-ymin+ymax)*1.8);
  Serial.println("Home position! Pulse Corner A  para empezar");
 
  int sensorValue4 = digitalRead(2);   // Input digital 9 =  confirmación corner A
  while(digitalRead(2)==LOW)
  {
    }
  Serial.println("Start!");
  Serial.println("SHOT numero:  Filas X , Columna Y ,posicion X, posición Y");
 
xmax=xmax-xmin;
ymax=ymax-ymin;
xmin=0;
ymin=0;
xact=0;
yact=0;
 
  for(int i=0; i<(columnasY); (i++))        
  {
   delay(1000);
    for(int j=0; j<filasX; (j++))
   {
     digitalWrite(13, HIGH);
     delay(500);
     digitalWrite(13, LOW);
     nshot=nshot++;
   
   Serial.print(nshot);
   Serial.print("   :   ");
   Serial.print(j+1);
   Serial.print("   ,   ");
   Serial.print(i+1);
   Serial.print("   ,   ");
   Serial.print(xact*1.8);
   Serial.print("   ,   ");
   Serial.println(yact*1.8);
   
     delay(1500);
    
     if(j!=(filasX+1)){  ///   if(j!=(filasX-1*sentidoX)-1)
     myStepperX.step(pasoX);
     xact=xact+(pasoX);
     } 
     delay(1500);
    }
  
   myStepperX.step((-filasXX)*pasoX);
   xact=0;
   if(i!=columnasY-1){         
   myStepperY.step(pasoY);
   }                                
   yact=yact+(pasoY);
   delay(1000);
    }
    Serial.println("Panoramica completa!");
  myStepperY.step((-columnasYY+1)*pasoY);
  delay(1000000);
 }
}


Los que dominais la programación posiblemente lo reduciriais a la mitad....pero eso es cuestion de minimizarlo (ya se hará!)


Tuve varios problemas (dependiendo de si la panoramica iba de izquierda a derechas o al revés) provocandome duros "quebraderos de cabeza" con los signos < > por lo que al final decidí que sólo seria viable en sentido horario al igual que se mueve el sol (de izquierda a derecha y de abajo a arriba).


Luego me di cuenta que los L298N se calentaban un huevo (si , casi para poder hacer huevos fritos) por lo que temporalmente le monté un radiador casero con una platina de aluminio. Ahora tengo pendiente montarle un ventilador forzado. Aparte del factor temperatura me di cuenta porque cada vez tenia que incrementar más el voltaje de los motores Nema 17 (incluso alimentandolos a 6 voltios cuando lo necesario son 2.8 v 2A).

De momento parece que tiene la intención de funcionar, todo y desconocer si los motores seran capaces de mover los 3 kg....

Os dejo un par de capturas de pantalla de como se ve desde el PC:
Y finalmente unos videos en funcionamiento (mañana intentaré grabar uno mejor):



Ahora tocará la parte que para mi es más complicada: la mecánica por lo que tengo previsto tomarmela con muucha calma, pero sin pausa . A cacharrear  !!!

1 comentario:

  1. Muy bien campeón!!! Si ya lo dominas más que yo...
    Al radiador solo le falta un ventilador a 220v y el kit sera antidestruible por la calor...
    Por cierto, me gusta el video que se ve dentro de tu video, pura motivación a lo rocky...

    ResponderEliminar