miércoles, 6 de julio de 2011

Pierna III - control de motor

No se si lo dije pero me cargue el ultimo ic que tenia por aquí capaz de aguantar el motor que estoy usando, así que hasta que lleguen me he puesto con otro motor que trae un encoder en una pequeña pcb.
Después de un ratazo con el código manejo el motor dc 12v canijo de las fotos a una resolución de 10 pasos por vuelta a esta velocidad de giro con un código optimizado en lo posible para que mientras este buscando la posición que le diga no tenga que hacer mas procesos que leer el encoder, el arduino no da para mucho en este sentido.

Realmente el encoder con mi código tiene una resolución de 50 pasos con medios pasos, osease 100 efectivos, pongamos que el motor es capaz de darnos unas 1000rpm, 1000rpm/60= a 16,6rpm por segundo que * 100 pasos de resolución del encoder nos da 1660 pulsos por segundo recibidos del encoder, lo que nos obligaría a leer pulsos cada menos de medio mili segundo. No se si el arduino podrá leer a mas velocidad pero yo de momento no se programarlo para ello, directamente el código pasa de cierta cantidad de pulsos del encoder, proporcional a la velocidad.














Esquema del L293




En el montaje de los servos el disco del encoder podría ir despues de la reductora del motor, así que la velocidad de giro a máxima corriente entregada al motor, no superaría las 300rpm, 5 por segundo a máxima velocidad, que seria 1 segundo entre (5 rps * 10 pasos por ejemplo) cada 20 ms una lectura, y a bajas velocidades.
Sabiendo el tiempo entre paso y paso, se puede ajustar la tensión de modo que a mas carga mas voltaje enviado al motor y a menos carga lo inverso, de modo que se mantengan las rpm deseadas lo mas posible, pero esto lo implementare en la próxima atacada que le de al código, ademas no tengo nada con lo que hacer el puente h del motor gordo.

Este seria el codigo asta ahora:


#define velocidadRodillaI 3 // timer 2 (pines 3 y 11) a 31khz
#define extensionRodillaI 52
#define flexionRodillaI 50


int hope, posicion, optico1B, optico2B, optico1, optico2, conta, dir;
int dig2, valor, numBytes;




void setup()
 {
  posicion=0, optico1B=0, optico2B=0, conta=0;
  byte mask = B11111000;
  TCCR2B &= mask; 
  TCCR2B |= (0<<CS22) | (0<<CS21) | (1<<CS20); 
        
  pinMode(24, INPUT);
  pinMode(26, INPUT);
  pinMode(velocidadRodillaI, OUTPUT);
  pinMode(extensionRodillaI, OUTPUT);
  pinMode(flexionRodillaI, OUTPUT);
  Serial.begin(9600);
}


void loop()
 {
   
   optico1B=optico1;            // guardamos la posicion anterior del encoder
   optico2B=optico2;
   optico1=digitalRead(24);    // leemos 0 o 1 del sensor optico en sus dos canales
   optico2=digitalRead(26);    // segun que canal sea primero uno y cual cero, sabremos la direccion de giro.
  
   if(optico1==0 && optico2==0) 
    {
      if(optico1B==1 && optico2B==0) posicion++;
      else if(optico1B==0 && optico2B==1) posicion--;
    } 
   else if(optico1==1 && optico2==1) 
    {
     if(optico1B==0 && optico2B==1) posicion++;
     else if(optico1B==1 && optico2B==0) posicion--;
    }



  if(hope < posicion) // avanza hasta
   {  
    analogWrite(velocidadRodillaI, 255); // duty cicle al 50%
    digitalWrite(extensionRodillaI, LOW);
    digitalWrite(flexionRodillaI, HIGH);
   }
  else if(hope > posicion) // retroceso hasta
   {  
    analogWrite(velocidadRodillaI, 255); // duty cicle al 50%
    digitalWrite(extensionRodillaI, HIGH);
    digitalWrite(flexionRodillaI, LOW);
   }
  else if(hope == posicion || hope==0) // ruitinas I/O cuando el micro queda "liberado" de cargas
   {
    analogWrite(velocidadRodillaI, 0); // duty cicle al 50%
    digitalWrite(extensionRodillaI, LOW);
    digitalWrite(flexionRodillaI, LOW);
    Serial.print("Actual: ");
    Serial.print(optico1, DEC); // por control de momento visualizamos los dos canales del encoder por serial
    Serial.print(" / ");
    Serial.print(optico2, DEC);
    Serial.print("  anterior: ");
    Serial.print(optico1B, DEC); // por control de momento visualizamos los dos canales del encoder por serial
    Serial.print(" / ");
    Serial.print(optico2B, DEC);
    Serial.print("  Pos: ");
    Serial.print(posicion, DEC);
    Serial.print("  Hope: ");
    Serial.println(hope);
    numBytes=Serial.available();
    if(numBytes>0 )
     {
      valor=Serial.read();
      if(valor!=0) valor=valor-48;
      dig2=Serial.read();
      dig2=dig2-48;
      Serial.flush();
      hope=(valor*10)+dig2;
     }
     
     //  posicionamos el motor en diferentes puntos una vuelta en un sentido y otra en el contrario
     //  asi que podemos borrar estos 4 if y posicionar por serial
     if(conta==0) dir=1;  
     if(conta==10) dir=0;
     
     if(dir==1)
      {
        hope=hope+2;
        conta++;
        delay(500);
      }
     else if(dir==0
     )
      {
        hope=hope-2;
        conta--;
        delay(500);
      }
      
    }


   
 } // FIN loop



Edito: dejo este link a pagina con brazo robotico y redes neuronales

1 comentario:

  1. hola miguel te felicito por tu blog. Mira precisamente tengo este motor con la tarjeta q tiene el encoder instalado y me gustaria controlar la velocidad de este motor, pero no he podido encontrar el datasheet del encoder para saber como conectarlo y no quisiera dañarlo. Me podrias dibujar un esquema de como conectar el encoder y el motor a la arduino. Te lo agradeceria mucho

    ResponderEliminar