martes, 31 de marzo de 2009

Sistema de control.

Los motores y trayectorias son controlados por un microcontrolador PIC16F877A el cual recibirá la distancia a recorrer por el microcontrolador principal y este almacenara la distancia e ira midiendo la distancia por un conjunto de encoders colocados en los ejes de las ruedas para poder midiendo la cantidad de vueltas que dan las ruedas, con este mismo sistema se controlara que el robot mantenga la trayectoria en el sentido que se desea y compensando cualquier inclinación en la misma que se pudiera tener.

Con el microcontrolador también se controlara el sentido que deben tener las ruedas, mediante un driver para motores de DC L293, el cual tiene la capacidad de controlar el sentido de dos motores, después del driver se colocara una etapa de potencia para evitar quemar el driver y alimentar la corriente necesaria para mover los motores.

Estructura, Sistema de tracción y control de trayectoria.

La estructura del robot se basara en la forma de un bote de plástico con tapa esférica. La cámara se posicionara en la tapa del bote, la cual tendrá la capacidad de girar 360 grados.

En el interior de la estructura, se colocaran dos niveles los cuales tendrán almacenado la batería y circuitería de control del robot.

El sistema de tracción estará conformado por dos motores de DC de 12v, los cuales dan la tracción al robot junto con una rueda loca para darle estabilidad y facilidad de movimiento al mismo.

Ya que el peso aproximado del robot es de 5.5Kg se colocara una transmisión reductora para reducir las revoluciones de los motores y aumentarles el torque que será transmitido a las ruedas de tracción del robot.

Al principio se propuso utilizar una transmisión compuesta por poleas y bandas para hacer la reducción de revoluciones, y fabricada de polietileno, pero se encontró que en algunos caso al momento de llevar a la transmisión a trabajos forzados y encontrar puntos de quiebre o derrape del material, la transmisión tendía a que las bandas se patinaran en las poleas y por lo tanto el robot dejaría de moverse o hasta llegar a reventar las bandas de plástico. Por esta razón optamos por la implementación de una transmisión compuesta por engranes, de esta manera evitamos derrapes entre componentes dentro de la transmisión.

Las primeras pruebas de transmisiones que se hicieron fueron hechas con transmisiones de 3 engranes, con el propósito de tener un engrane que fuera el productor del movimiento de la transmisión, el cual va directamente al rotor del motor de DC, otro engrane es el engrane de salida de la transmisión el cual va conectado al eje de giro de las ruedas, entre ellos se colocaría un tercer engrane el cual seria el transmisor de energía entre el engrane de salida y el de entrada, además de tener la función de transmisor de energía, tendría la función de engrane fusible, el cual, en caso de que el robot estuviera en un momento en el que entro en una parte donde la rueda quedara atorada y el robot quisiera seguir avanzando, se quebrara así evitando que el motor se sobrecalentara pudiendo llegar a quemar el motor o la circuitería misma.

Debido a la complejidad de este sistema ya que los engranes requieren de estar muy bien alineados y la estructura debe ser lo suficientemente solida para soportar las fricciones y peso del robot, se opto por hacer una transmisión simple de dos engranes con una relación de 3 a 1, siendo el sistema final, un engrane en el eje de rotación de la rueda y otro en el rotor del motor de DC, esto quiere decir que el engrane que va en el eje de las ruedas es 3 veces aproximadamente mas grande que el que va en el rotor del motor.

Los engranes de las transmisiones, fueron moldeados con plásticos macizos para evitar que sufrieran fracturas causadas por la fricción al momento de estar en movimiento el robot, ya que los engranes van a estar interactuando directamente entre si, el engrane del rotor del motor de DC esta fabricado de plástico resistente al calor, con un total de 19 dientes en su circunferencia, el engrane que va colocado en el eje de la llanta esta hecho de plástico ligero para hacer mas fácil el giro de las ruedas, con un total de 60 dientes en su circunferencia.
Las ruedas del robot son de plástico duro de 2.5 pulgadas de diámetro, serán recubiertas de plástico blando para amortiguar el rebote que tenga el robot causada por las irregularidades del terreno por el que pueda transitar el robot.

martes, 17 de marzo de 2009

Interfaz Para Grabar la Trayectoria

Este segundo código es el de la interfaz en la cual el usuario puede predefinir la trayectoria y mandar la señal al microcontrolador para que éste la reproduza, este programa esta hecho en LabWindows CVI.

Interfaz de Usuario


Código
#include "Trayectoria.h"

static int panelHandle;

int SendAsciiString (int comport, char *send_ASCII);
int GetSerialMessage (int comport, char *readdata);

char readBuffer[256];

int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "Trayectoria.uir", PANEL)) < loopexit =" 0;" x="0;" error =" -1;" x="0;" begin =" Timer();" seconds =" 0.003;" inbuffer =" GetInQLen"> 2) {
ComRd (comport, readdata, InBuffer);
LoopExit = 1;
error = 0;
break;
}
SyncWait (Begin, Seconds);
}
if (x == 500)
break;
} while (LoopExit == 0);
return error;
}


Primera Fase del Programa para la Planeacion de la Trayectoria

EL siguiente código es la primera etapa del programa base para el control del robot, éste corre en el microcontrolador y está hecho en CodeWarrior para la tarjeta DEMOQE128. En esta primera fase el programa permite grabar una trayectoria predefinida por el usuario para después reproducirla, además en la trayectoria se pueden establecer puntos específicos dónde se desean tomar fotografías.

/*********************************************************************/
/* Project Name: Treyectory */
/* Source fle name: RTC.c */
/*********************************************************************/
/* Robotecnicos */
/*********************************************************************/
/*********************************************************************/
/* Code for QE128 MCU's */
/* Module: Trayectory */
/* The code was developed and tested on CodeWarrior 6.0 version */
/* */
/* Description: To learn the trayecory to be followed */
/* */
/*********************************************************************/
/* */
/* Date: 07/03/2009 */
/* Robotecnicos */
/* ITESM */
/*********************************************************************/

#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

/*********************************************************************/
/* Globals */
/*********************************************************************/

#define RECORDING 1
#define LOOP 2
#define RESET 3

#define UP 1
#define DOWN 2
#define RIGHT 4
#define LEFT 8
#define PHOTO 16

typedef unsigned char UINT8;

unsigned char edo_past = 0;

unsigned char begin= 0;
unsigned char finish = 0;

unsigned char in = 0;

unsigned int count = 0;
unsigned int direction = 0;
unsigned int elements = 0;

unsigned int i = 0;

unsigned char state = RECORDING;

unsigned int trayectory[5][2];


/*********************************************************************/
/* Function declarations */
/*********************************************************************/

void MCU_Init(void) {

SOPT1 = 0x23; /* Watchdog disable. Stop Mode Enable. Background Pin enable. RESET pin enable */
SCGC1 = 0x01; /* Bus Clock to the SCI1 module is enable */
SCGC2 = 0x04; /* Bus Clock to the RTC module is enable */
}

void GPIO(void) {


PTAPE = 0x0C;
PTADD = 0x00; // Configure Port A as inputs

PTDPE = 0x0C;
PTDDD = 0x00; // Configure Port D as inputs

PTCDD = (PTCD 0x3F); /* Configure PTC0-PTC5 as outputs */
PTEDD = (PTED 0xC0); /* Configure PTE6 and PTE7 pins as outputs */
PTCD = 0x3F; /* Put 1's in port C in order to turn off the LEDs */
PTED = 0xC0; /* Put 1's in port E port in order to turn off the LEDs */


}

// To print data in the LEDs of DEMOQE

void display(byte x){ /* LEDS low power active */

x = ~x;
PTED = (x & 0xC0); /* Move the adquired ADC value to port E */
PTCD = (x & 0x3F); /* Move the adquired ADC value to port C */
}


void RTC_configuration (void) {

RTCSC = 0x08; /* RTCPS configure prescaler period every 1s */
RTCMOD = 0x00; /* RTCMOD configure to interrupt every 1s */
}

void SCI_configuration (void) {

SCI1C1 = 0x00; /* 8-bit mode. Normal operation */
SCI1C2 = 0x2C; /* Receiver interrupt enable. Transmitter and receiver enable */
SCI1C3 = 0x00; /* Disable all errors interrupts */
SCI1BDL = 0x1A; /* This register and the SCI1BDH are used to configure the SCI baud rate */
SCI1BDH = 0x00; /* BUSCLK 4MHz */
/* Baud rate = -------------------- = ------------ = 9600bps */
} /* [SBR12:SBR0] x 16 26 x 16 */

/*********************************************************************
* Main Function *
*********************************************************************/

void main(void) {


MCU_Init(); /* Function that initializes the MCU */
GPIO(); /* Function that initializes the Ports of the MCU */
RTC_configuration(); /* Function that initializes the RTC module */
SCI_configuration();

EnableInterrupts; /* enable interrupts */

/* Enable RTC interrupt */
for(;;) {

// in = ((~PTAD) & 0x0C);
// in = in >> 2;
// in = in ((~PTDD) & 0x0C);

switch (state){

case RECORDING:



if (finish == 0x01){

finish = 0x00;
begin = 0x00;
trayectory[elements][0] = direction;
trayectory[elements][1] = count;
count = 0;
elements ++;
//if (elements == 5) state = LOOP;
}

if(begin == 0x00) {

edo_past = in;
switch(in){
case 1 : PTCD_PTCD0 =0; RTCSC_RTIE = 1; begin = 0x01; direction = UP; break;
case 2 : PTCD_PTCD1 =0; RTCSC_RTIE = 1; begin = 0x01; direction = DOWN; break;
case 4 : PTCD_PTCD2 =0; RTCSC_RTIE = 1; begin = 0x01; direction = RIGHT; break;
case 8 : PTCD_PTCD3 =0; RTCSC_RTIE = 1; begin = 0x01; direction = LEFT; break;
case 16: PTCD_PTCD4 =1; RTCSC_RTIE = 1; begin = 0x01; direction = PHOTO; break;
default: PTCD = 0xEF; RTCSC_RTIE = 0;

}
}


break;

case LOOP:

PTED_PTED6 = 0;
RTCSC_RTIE = 1;


break;

case RESET:

elements = 0;

PTCD_PTCD0 =1;
PTCD_PTCD1 =1;
PTCD_PTCD2 =1;
PTCD_PTCD3 =1;
PTCD_PTCD4 = 0;


break;


}



} /* loop forever */
/* please make sure that you never leave this function */
}


/*********************************************************************
* Interrupt Service Routines *
*********************************************************************/

void interrupt VectorNumber_Vsci1rx SCI_RX_ISR(void) {

SCI1S1_RDRF = 0; /* Receive interrupt disable */

// display (SCI1D); /* Display on PTE the received data from SCI */

switch (SCI1D){

case '0': in = 0; break;
case '1': state = RECORDING; break;
case '2': state = LOOP; break;
case '3': in = 1; break;
case '4': in = 2; break;
case '5': in = 4; break;
case '6': in = 8; break;
case '7': in = 16; break;
case '8': state = RESET; break;

}



while (SCI1S1_TDRE == 0); /* Wait for the transmitter to be empty */
//SCI1D = '1'; /* Send a character by SCI */
}

void interrupt VectorNumber_Vrtc RTC_ISR(void) {

RTCSC = RTCSC 0x80; /* Clear the RTC flag */
PTED_PTED7 ^= 1; /* Toggles PTE7 pin */


// in = ((~PTAD) & 0x0C);
// in = in >> 2;
// in = in ((~PTDD) & 0x0C);

switch(state){

case RECORDING:
count++;
if(edo_past != in){

finish = 0x01;
RTCSC_RTIE = 0;

}

break;

case LOOP:



if (count == trayectory[i][1]){ PTCD_PTCD0 =1; PTCD_PTCD1 =1; PTCD_PTCD2 =1; PTCD_PTCD3 =1; PTCD_PTCD4 = 0; i++; count = 0;}
count ++;

if(i == elements) i = 0;

direction = trayectory[i][0];

switch(direction) {
case UP : PTCD_PTCD0 =0; break;
case DOWN : PTCD_PTCD1 =0; break;
case RIGHT : PTCD_PTCD2 =0; break;
case LEFT : PTCD_PTCD3 =0; break;
case PHOTO : PTCD_PTCD4 =1; break;
default: PTCD = 0xFF;
}



break;
}

}

viernes, 6 de marzo de 2009

Disparador externo CHDK

Gracias al CHDK es posible usar un programa que detecte una diferencia de voltaje en el puerto usb de la cámara para así poder tomar fotografías o realizar acciones que sean indicadas desde el micro.
El diagrama que se usa es muy simple

Se requiere un puerto USB con la entrada mini B que se conecta a la cámara, mientras que del otro extremo se puede conectar a un hembra que este conectado al micro o podemos cortar directamente el cable y aplicar la diferencia de voltaje ahí.
El programa que usamos para detectar el puerto usb es muy simple

@title Remote button
while 1
wait_click 1
if is_key "remote" then shoot
wend

end

Es un ciclo infinito (while 1) que espera por algún botón para ser presionado (wait_click 1). Si el “botón” es en realidad la diferencia de voltaje en el usb (remote) entonces realiza un disparo y repite el ciclo, si es algún otro botón repite el ciclo sin disparar.
El voltaje que se aplica en la cámara depende de cada modelo en nuestro caso es suficiente con 3.75, sin embargo otros modelos requieren mas voltaje mientras que otros requieren menos.

El CHDK detecta al puerto USB como otro botón mas, es decir que se puede usar para alterar el comportamiento del programa y no solo para disparar la cámara., el día de hoy en clase trataremos de hacer que la cámara tome fotos en intervalos, y que cuando reciba una señal del micro tome fotos al detectar movimiento.

Estructura del Robot

Estas son algunas imágenes de cómo se ve la estructura del robot, hecha a partir de un bote de basura, cortesía de nuestro compañero Oscar.

martes, 3 de marzo de 2009

Programación del pic 16f877a / CCS

Programming PIC16F877A Using CCS C Compiler and US-Burn

Eye-fi baja de precio

Hoy nos enterramos de que la tarjeta que pensamos comprar para pasar las fotos de manera inalámbrica ha bajado de precio. Ahora cuesta solo 50 dólares el modelo mas económico, esto es debido a que se introdujo una nueva versión que soporta el poder subir videos a youtube. Esperamos que ahora el robot sea de un precio mas accesible y poder invertir el dinero en otras partes del robot.

R2BEER2 !!!!!!!!!!