domingo, 19 de febrero de 2012

Matilde Mini

Os presento a Matilde-Mini:

La antigua Matilbot funcionaba bastante bien, aunque nunca la termine del todo. Sin embargo tenia un par de espinitas, la primera era que usaba un arduino entero y un driver para motores comprado. Yo quería algo mas barato, artesanal, rustico, de andar por casa vaya... Así que me puse manos al soldador y hice aproximadamente esto:


Pude sustituir toda la tarjeta de arduino por su microcontrolador, un regulador de tensión y un cristal. Al mismo tiempo cambie el driver de motor basado L298 por un L293NE.

Recorte la estructura de Meccano, le quite los bumpers frontales, los infrarrojos bajeros y los módulos de radiofrecuencia, sin embargo le puse unos ultrasonidos, quedando tal que así:

Vista superior

Vista frontal

Le quite todas las pilas lipo y cargadores por usb, dejando solo una pila 9v para la lógica, pila recargable muy mala que se agota enseguida. Y cuatro pilas AA recargables también:


Esta vez la idea era simplificar incluso la programación así que le implemente un algoritmo mas simple: al detectar un obstáculo gira y busca el espacio suficiente para continuar avanzando, este es el programa que tiene a día de hoy:

#define PIN11 9
#define PIN12 10
#define PIN21 5
#define PIN22 11
#define PIN_ULTRAS 13

#define RETRAZO 20
#define INICIO 30

#define DISTANCE 30

#define MAX_SPEED 255
#define MEDIUM_SPEED 180

#define MICROS2CTM(a) a / 29 / 2

#define MOTOR_RIGHT motor(PIN11, PIN12, speedRight)
#define MOTOR_LEFT motor(PIN22, PIN21, speedLeft)
#define MOTOR_RIGHT_BACK motor(PIN12, PIN11, speedRight)
#define MOTOR_LEFT_BACK motor(PIN21, PIN22, speedLeft)

#define STOP_MOTOR(a, b, c) a = 0;digitalWrite(b, LOW);digitalWrite(c, LOW)

void setup()
{
  pinMode(PIN11, OUTPUT);
  pinMode(PIN12, OUTPUT);
  pinMode(PIN21, OUTPUT);
  pinMode(PIN22, OUTPUT);

  digitalWrite(PIN11, LOW);
  digitalWrite(PIN12, LOW);
  digitalWrite(PIN21, LOW);
  digitalWrite(PIN22, LOW);
  
  delay(2000);
}

int speedLeft = MAX_SPEED;
int speedRight = MAX_SPEED;

void loop() {

  if (MICROS2CTM(distanceInTime()) < DISTANCE)
  {
    speedLeft = MAX_SPEED;
    MOTOR_LEFT;
    speedRight = MAX_SPEED;
    MOTOR_RIGHT_BACK;

    while (MICROS2CTM(distanceInTime()) <= DISTANCE)
      delay(50);
  }

  speedRight = MAX_SPEED;
  speedLeft = MAX_SPEED;

  MOTOR_RIGHT;
  MOTOR_LEFT;

  while (MICROS2CTM(distanceInTime()) > (DISTANCE + 10))
    delay(50);
}

void motor(int pinA, int pinB, int speedM)
{
  digitalWrite(pinB, LOW);
  analogWrite(pinA, speedM);
}

long distanceInTime()
{
  pinMode(PIN_ULTRAS, OUTPUT);
  digitalWrite(PIN_ULTRAS, LOW);
  delayMicroseconds(2);
  digitalWrite(PIN_ULTRAS, HIGH);
  delayMicroseconds(5);
  digitalWrite(PIN_ULTRAS, LOW);

  pinMode(PIN_ULTRAS, INPUT);
  return pulseIn(PIN_ULTRAS, HIGH);
}


Un programa muy simple en que solamente avanza hasta que detecta un objeto a menos de 30ctms, momento en que invierte el movimiento de la rueda derecha hasta que encuentra espacio mayor de 30ctms tras lo cual vuelve a moverse hacia adelante y repite el ciclo.

Observaciones y resultados:
Funciona... Pero...
  • La pila de 9v no aguanta dos asaltos y en cuanto empieza a decaer se queda colgado.
  • No parece detectar muy bien los obstáculos cuando va poco frontal y tropieza con superficies oblicuas.
  • Precisamente por lo anterior se queda trabado con las ruedas en las esquinas, quizás podría mejorarse sustituyendo las ruedas por otras mas finas que hicieran desplazarse ante los choques en lugar de quedar trabado.
  • Parece que el hecho de que el L293 solo pueda conducir 1A por canal y el de solo tener 5V para los motores hace que sea bastante lento :P, quizás poniendo mas pilas en serie y/o cambiando el puente en h(L293) por un L298 mejore esta lentitud. Pero el L298 es mas complejo y caro...
En fin que me hace falta mas tiempo libre para hacer mas guarrerías de estas...