Introducción
Se propone armar, a fin de ensamblar con la
fabricación de la pista para competencia de robótica en la categoría
velocistas, un sistema de cronometrado, contador de vueltas, semáforo de
largada, a fin de obtener información
más precisa del rendimiento de cada uno de los robots que correrán y
participarán de la competencia pudiendo así, mejorar el funcionamiento de cada
uno de ellos, dándole una inmejorable posibilidad a cada diseñador y/o dueño
del robot de tener en su poder, datos concretos y precisos del rendimiento de
su corredor, con la posibilidad de corregir y mejorar cada robot.
Esto le dará también a la escuela un aporte fundamental ya que la misma participa de competencias nacionales donde allí se necesita el mejor funcionamiento posible del robot, pondrá a la escuela en una situación de privilegio ya que esta es una idea innovadora y muy poco aplicada a este tipo de competencias y beneficiará exponencialmente el rendimiento de los robots.
Objetivos
Nuestro
proyecto son dos semáforos para la pista de robots. Se basa en un dispositivo
que mida los tiempos totales, el tiempo de vuelta y las vueltas que realice cada robot en dicha
pista.
En dicha
práctica se realizaron dos tipos de semáforos de diferentes tamaños, uno para
que sea visible por los competidores que se colocara en la línea de largada
para sensar tiempos y demás y un “semáforo central” que se encontrara en el
centro de la pista para que sea visible para el público presente. Este semáforo
además poseerá un parlante en la parte superior del mismo que emitirá pitidos
cuando las luces del semáforo cambien de estado (de color).
Otra función
de nuestro semáforo es que mediante sensores colocados en el semáforo de pista
se pueden observar los tiempos y el número de vueltas de cada robot en una
pantalla para que el público pueda observar lo que sucede en la pista donde se
realiza dicha carrera.
Diagrama en Bloques
La
“placa central”, como su nombre lo indica es la plaqueta madre del proyecto, de
allí salen todas las conexiones para que puedan funcionar de la manera más
eficiente y cómoda todas las etapas que componen al proyecto, ahorrando así el
espacio necesario para que la pista no sea excesivamente “invadida” con cables,
plaquetas o cualquier otro elemento que pueda perjudicar el normal desarrollo
de la competencia. Esta placa se ubica en el interior del semáforo principal y
de allí salen todos los cables necesarios para lograr el efectivo
funcionamiento de cada etapa.
El bloque “lámparas semáforo” está conectado a través de 5 cables (dos para las lámparas rojas, uno para la amarilla, uno para la verde y uno para masa) y el bloque “parlante” está conectado a través de 2 cables (alimentación), estas dos etapas forman parte del semáforo central donde la última se encuentra en la parte superior de la estructura del semáforo y la primera en su interior.
Luego se encuentra la etapa del sensado, donde está el bloque “roseta” conectado a través de un cable de ocho hilos en su interior a la placa central, de este bloque se derivan dos bloques más, uno es el de “ojos de buey” conectado a la “roseta” con cinco cables (dos para los leds rojos, uno para el amarillo, uno para el verde, y uno para GND), y el otro es el bloque “sensores” conectado a través de cuatro cables (uno para cada sensor, uno para Vcc y uno para GND), cabe destacar que esta etapa forma parte del “semáforo de la largada” cuya visibilidad estará solo afectada a los participantes de la competencia.
Por último se encuentra la etapa “conversor USB a RS-232” que de esta se deriva
otra etapa llamada “PC”, esta parte del circuito será fundamental ya que todos
los datos obtenidos por los sensores serán enviados a una computadora que a
través del programa “Visual Basic” podrán mostrarse los tiempos de cada robot.
El bloque “lámparas semáforo” está conectado a través de 5 cables (dos para las lámparas rojas, uno para la amarilla, uno para la verde y uno para masa) y el bloque “parlante” está conectado a través de 2 cables (alimentación), estas dos etapas forman parte del semáforo central donde la última se encuentra en la parte superior de la estructura del semáforo y la primera en su interior.
Luego se encuentra la etapa del sensado, donde está el bloque “roseta” conectado a través de un cable de ocho hilos en su interior a la placa central, de este bloque se derivan dos bloques más, uno es el de “ojos de buey” conectado a la “roseta” con cinco cables (dos para los leds rojos, uno para el amarillo, uno para el verde, y uno para GND), y el otro es el bloque “sensores” conectado a través de cuatro cables (uno para cada sensor, uno para Vcc y uno para GND), cabe destacar que esta etapa forma parte del “semáforo de la largada” cuya visibilidad estará solo afectada a los participantes de la competencia.
Por último se encuentra la etapa “conversor USB a RS-
Diseño de Estructuras en 3D
Puente:
Usando el programa lightwave 3D hicimos un diseño de la estructura del puente. Al comienzo, el diseño era recto y robusto, con 5 varillas roscadas a 45° grados, una varilla de madera para poner las 4 luces y otra varilla de madera para poner los 2 sensores.
Luego el diseño se retoco para que tenga una curva de madera con el fin de aproximar la distancia entre las luces y los sensores. Deja de ser robusto y se usan maderas mas finas porque el tamaño era excesivo, y se achico la base para que coincida con la pista. Este fue el diseño final:
Semáforo:
El primer diseño del semáforo era un tubo cilíndrico de 125 mm de diámetro con una estructura que consta de 3 varillas roscadas que sostienen 4 estantes de madera. En cada estante hay un portalámparas.
En el siguiente diseño le agregamos una base rectangular para mantener el equilibrio del tubo y reemplazamos los portalámparas por 4 lámparas LED de auto ya que mejoramos el consumo y rendimiento. También se modifico el tubo, que ahora es de 110 mm, ya que el anterior no se conseguía. Este es el diseño final:
Placas
Comenzamos el diseñando la placa
base, primero realizamos un diagrama en bloques antes mencionado, y luego
fuimos viendo cómo resolver cada parte del diagrama.
El bloque “Roseta”, se convenio
utilizar un el ULN2003, que se utiliza para adaptar la corriente a la salida,
hasta 500mA por línea, saliendo directamente al semáforo, y con unas
resistencias a el puente.
En las salidas hacia el puente se
pusieron leds en paralelo, el cálculo del mismo Rled= (5V – 3V) / 40mA = 50Ω = 47Ω (valor comercial)
Los leds que van al
semáforo se alimentan con 12V, además del parlante, en cambio el resto se
alimentan con 5V, por lo que se utilizó
un 7805 para reducir la misma.
El parlante tiene un
7809, para poder alimentar el parlante con 9V, se conectó a la salida del
micro/PWM un octoacoplador 4n35 para conformar la señal cuadrara del micro, y también
separ la fase
Para la comunicación
por puerto RS-232 se utilizó un MAX232, conectando los capacitores de 1µF
respetando las polaridades indicadas.
Le agregamos
también ICSP (In Circuit Serial
Programmer), para poder programarlo mediante un programador, a través del RJ12.
Para la conexión del
puente, se utilizó RJ45, conectado mediante pines a la placa, para así poder
quitar los mismos si es necesario arreglar el semáforo.
Luego de realizar el circuito, y probarlo, observamos
que había varios problemas por lo que, debido al poco tiempo, pusimos puentes
en la placa en los siguientes lugares:
Luego de realizado la placa base,
se realizaron 2 placas adicionales para los sensores, las mismas son idénticas
modularmente.
El funcionamiento del sensor se
basa en un detector de frecuencias lm567, se utilizó inicialmente un lm555 para
elevar la potencia del TX infrarrojo, para aumentar el alcance del mismo,
enviado así una frecuencia X, la misma rebota en la superficie, y la señal es
recibida por el lm567, que detectara a partida del valor RC la frecuencia del
555, y enviara un 1 a la salida, a través de una Schmitt trigger.
Se conectará en el 567 un multivuelta
de 10K para así regular con precisión la frecuencia que se recibe. También hay
otro potenciómetro que regula el alcance del RX. El otro Sensor realizará lo
mismo pero tendrá otra frecuencia, para así que no haya problemas de
interferencias.
Luego de realizado los sensores,
observamos un comportamiento inestable en relación al sensado, para solucionar
este inconveniente, se optó por eliminar el lm555, y utilizar la misma
frecuencia del 567 (pata 5), pasándola por un darlington, conformados por 2
transistores 2N3904 que excitan asi al TX infrarrojo, de esta manera evitamos
tener que calibrar la frecuencia del lm567, basada en la frecuencia del 555,
con la mejora de estabilidad de frecuencia, al no tener que calibrar la misma.
Para mejorar la precisión del 567 se utilizaron resistencias al 1% y
capacitores multicapa.
La frecuencia del primer sensor
es de 1,4KHz y la frecuencia del segundo sensor es de 4KHz. 5,15K
2,27K
Para el cálculo de
las resistencias se utilizó la fórmula del 567
f= 1 / (1,1 . R . C)
f1= 1 / ( 1,1 . 5,15K . 100nF) ≈ 1,4KHz
ff2= 1 / (1,1 . 2,27K . 100nF) ≈ 4KHz
Quedando el circuito de la siguiente
manera:
Panel
de conexión
Este panel se
encuentra en la parte inferior del semáforo y allí se encuentran 4 conectores:
2 RJ45, 1 DB9 y una ficha de alimentación.
Los RJ45 se
utilizan, uno para programación (negro) y otro para conectarlo con la roseta
del puente.
El DB9 se encarga
de transmitir los datos al conversor que es conectado por USB a la PC.
La ficha de
alimentación conecta el transformador de 220v rectificado, para que este nos
entregue 12v 1A. Este alimenta directamente a las lámparas de led, y el resto
de la placa a través de un 7805.
Programa de C
La rutina del microcontrolador, se divide en 4 pasos:
1.
Modo de calibración: Se apoyan los robots
en la pista debajo de los sensores, y se van arrimando hacia adelante, hasta
que el sensor lo detecte. Al detectarlo, se nos enciende una luz en el
semáforo, lo que indica que hay que retroceder el robot hasta que esta se
apague. Una vez apagada, esta será la posición de largada. Este paso termina al
recibir las configuraciones desde la pc.
2. Guardar las configuraciones: Las configuraciones constan de la duración de competencia por vueltas y por tiempo. Al recibirlas, microcontrolador las decodifica y las guarda en variables que luego van a ser utilizadas.
3. Largada: El dispositivo, se queda esperando el comando de largada de la computadora. Al recibirlo, se inicia la secuencia de luces del semáforo, con señales auditivas. Durante la secuencia, también se está sensando la posición del robot, para que no se adelante antes de tiempo. Si algún corredor se adelanta, la secuencia del semáforo se detiene, y se envía un comando a la pc que avisa esto, para que este nos envíe el comando de largada nuevamente.
4. Principal: En esta etapa, el programa se encarga de contar tiempo, y sensar las pasadas de los sensores. Cuando se sensa un corredor, se envía por el puerto serie hacia la pc el tiempo en el que cruzo el mismo con precisión de una décima de segundo.
También se encarga revisar las variables de configuración, y chequear si cumplió la duración de carrera, o si alguno llego a la cantidad de vueltas requeridas.
El terminar la competencia, se envía hacia la pc un comando que indica quien es el ganador y si gano por tiempo o por vueltas.
#zero_ram
void main()
{ int8 i;
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1);
setup_comparator(NC_NC_NC_NC);
disable_interrupts(INT_TIMER0);
disable_interrupts(INT_RB);
disable_interrupts((INT_RB0) | (INT_RB1));
disable_interrupts(INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_4MHZ|OSC_NORMAL);
//prueba de robot en sensor (apoyo robot en pista hasta que se apague el led correspondiente)
flag_rx = FALSE;
output_low(LR1);
output_low(LR2);
output_low(LA1);
output_low(LV1);
while(flag_rx == FALSE){
output_high(LA1);
if(input(SENSOR_A)== TRUE){
output_high(LR1);
}else{
output_low(LR1);
}
if(input(SENSOR_B) == TRUE){
output_high(LV1);
}else{
output_low(LV1);
}
} // se repite hasta que recibo las configuraciones
output_low(LA1);
void main()
{ int8 i;
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1);
setup_comparator(NC_NC_NC_NC);
disable_interrupts(INT_TIMER0);
disable_interrupts(INT_RB);
disable_interrupts((INT_RB0) | (INT_RB1));
disable_interrupts(INT_EXT);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
setup_oscillator(OSC_4MHZ|OSC_NORMAL);
//prueba de robot en sensor (apoyo robot en pista hasta que se apague el led correspondiente)
flag_rx = FALSE;
output_low(LR1);
output_low(LR2);
output_low(LA1);
output_low(LV1);
while(flag_rx == FALSE){
output_high(LA1);
if(input(SENSOR_A)== TRUE){
output_high(LR1);
}else{
output_low(LR1);
}
if(input(SENSOR_B) == TRUE){
output_high(LV1);
}else{
output_low(LV1);
}
} // se repite hasta que recibo las configuraciones
output_low(LA1);
2. Guardar las configuraciones: Las configuraciones constan de la duración de competencia por vueltas y por tiempo. Al recibirlas, microcontrolador las decodifica y las guarda en variables que luego van a ser utilizadas.
//espero configuración y guardo los valores
do{
if ((flag_rx==TRUE)&&(bufferrx[0]=='<')&&(bufferrx[5]=='>')){
tiempo = ((bufferrx[1] - 48)*10) + (bufferrx[2] - 48);
vueltas = ((bufferrx[3] - 48)*10) + (bufferrx[4] - 48);
printf("CONFIGURACION ELEGIDA: Minutos:%u, Vueltas:%u.\r\n",tiempo,vueltas);
flag_configlista = TRUE;
}
}while (flag_configlista == FALSE);
do{
if ((flag_rx==TRUE)&&(bufferrx[0]=='<')&&(bufferrx[5]=='>')){
tiempo = ((bufferrx[1] - 48)*10) + (bufferrx[2] - 48);
vueltas = ((bufferrx[3] - 48)*10) + (bufferrx[4] - 48);
printf("CONFIGURACION ELEGIDA: Minutos:%u, Vueltas:%u.\r\n",tiempo,vueltas);
flag_configlista = TRUE;
}
}while (flag_configlista == FALSE);
3. Largada: El dispositivo, se queda esperando el comando de largada de la computadora. Al recibirlo, se inicia la secuencia de luces del semáforo, con señales auditivas. Durante la secuencia, también se está sensando la posición del robot, para que no se adelante antes de tiempo. Si algún corredor se adelanta, la secuencia del semáforo se detiene, y se envía un comando a la pc que avisa esto, para que este nos envíe el comando de largada nuevamente.
// Si recibo el comando <L>, da comienzo la rutina de semaforo y habilito la cuenta de tiempo.
flag_largadalista == FALSE;
while(flag_largadalista == FALSE){
flag_rx = FALSE;
while(flag_rx == FALSE){} //Espera la rx de 232
flag_temprano = FALSE;
do{
if(flag_temprano == TRUE){
printf ("<T>\r\n"); // AVISO AL MICRO PARA VOLVER A HABILITAR EL BOTON LARGADA
flag_temprano = FALSE;
}
output_a(0);
while((bufferrx[1]!='L') || flag_rx == FALSE){} //Se larga la competencia.
bufferrx[1]= ' ';
enable_interrupts((INT_RB0) | (INT_RB1));
i = 1;
for( i=1 ; i<16 ; i *= 2){
if(flag_temprano == FALSE){
output_a(i);
delay_ms(2000);
}
else{
break;
}
}
}while(flag_temprano == TRUE);
enable_interrupts(INT_TIMER0);
disable_interrupts(INT_RB0 | INT_RB1);
flag_largadalista = TRUE;
set_timer0(0);
vueltascumplidasizq = 0;
vueltascumplidasder = 0;
delay_ms(3000);
output_a(0);
}
flag_largadalista == FALSE;
while(flag_largadalista == FALSE){
flag_rx = FALSE;
while(flag_rx == FALSE){} //Espera la rx de 232
flag_temprano = FALSE;
do{
if(flag_temprano == TRUE){
printf ("<T>\r\n"); // AVISO AL MICRO PARA VOLVER A HABILITAR EL BOTON LARGADA
flag_temprano = FALSE;
}
output_a(0);
while((bufferrx[1]!='L') || flag_rx == FALSE){} //Se larga la competencia.
bufferrx[1]= ' ';
enable_interrupts((INT_RB0) | (INT_RB1));
i = 1;
for( i=1 ; i<16 ; i *= 2){
if(flag_temprano == FALSE){
output_a(i);
delay_ms(2000);
}
else{
break;
}
}
}while(flag_temprano == TRUE);
enable_interrupts(INT_TIMER0);
disable_interrupts(INT_RB0 | INT_RB1);
flag_largadalista = TRUE;
set_timer0(0);
vueltascumplidasizq = 0;
vueltascumplidasder = 0;
delay_ms(3000);
output_a(0);
}
4. Principal: En esta etapa, el programa se encarga de contar tiempo, y sensar las pasadas de los sensores. Cuando se sensa un corredor, se envía por el puerto serie hacia la pc el tiempo en el que cruzo el mismo con precisión de una décima de segundo.
También se encarga revisar las variables de configuración, y chequear si cumplió la duración de carrera, o si alguno llego a la cantidad de vueltas requeridas.
El terminar la competencia, se envía hacia la pc un comando que indica quien es el ganador y si gano por tiempo o por vueltas.
//bucle de trabajo
while(TRUE){
if ((flag_rx == TRUE) && (bufferrx[1] == 'S')){ // PARADA DE EMERGENCIA ¿ LA HAGO EN INTERRUPCION?
reset_cpu();
}
if(flag_sensorA == TRUE){
flag_sensorA = FALSE;
delay_ms(20);
vueltascumplidasder ++;
printf ("<%02u:%02u:%u.0>\r\n",minutos,segundos,decimas);
printf ("vueltas corredor der: %u\r\n",vueltascumplidasder);
}
if(flag_sensorB == TRUE){
flag_sensorB = FALSE;
delay_ms(20);
vueltascumplidasizq ++;
printf ("<%02u:%02u:%u.1>\r\n",minutos,segundos,decimas);
printf ("vueltas corredor izq: %u\r\n",vueltascumplidasizq);
}
if(vueltas > 0){
if (vueltascumplidasizq == vueltas){
printf ("<W0V>\r\n"); // WIN 0 (izquierdo) por vueltas
reset_cpu();
}
if (vueltascumplidasder == vueltas){
printf ("<W1V>\r\n"); // WIN 1 (derecho) por vueltas
reset_cpu();
}
}
if (tiempo > 0){
if(minutos >= tiempo){
if (vueltascumplidasder > vueltascumplidasizq){
printf ("<W1T>\r\n"); // WIN 1 (derecho) por tiempo
}else{
printf ("<W0T>\r\n"); // WIN 0 (izquierdo) por tiempo
}
reset_cpu();
}
}
}
}
while(TRUE){
if ((flag_rx == TRUE) && (bufferrx[1] == 'S')){ // PARADA DE EMERGENCIA ¿ LA HAGO EN INTERRUPCION?
reset_cpu();
}
if(flag_sensorA == TRUE){
flag_sensorA = FALSE;
delay_ms(20);
vueltascumplidasder ++;
printf ("<%02u:%02u:%u.0>\r\n",minutos,segundos,decimas);
printf ("vueltas corredor der: %u\r\n",vueltascumplidasder);
}
if(flag_sensorB == TRUE){
flag_sensorB = FALSE;
delay_ms(20);
vueltascumplidasizq ++;
printf ("<%02u:%02u:%u.1>\r\n",minutos,segundos,decimas);
printf ("vueltas corredor izq: %u\r\n",vueltascumplidasizq);
}
if(vueltas > 0){
if (vueltascumplidasizq == vueltas){
printf ("<W0V>\r\n"); // WIN 0 (izquierdo) por vueltas
reset_cpu();
}
if (vueltascumplidasder == vueltas){
printf ("<W1V>\r\n"); // WIN 1 (derecho) por vueltas
reset_cpu();
}
}
if (tiempo > 0){
if(minutos >= tiempo){
if (vueltascumplidasder > vueltascumplidasizq){
printf ("<W1T>\r\n"); // WIN 1 (derecho) por tiempo
}else{
printf ("<W0T>\r\n"); // WIN 0 (izquierdo) por tiempo
}
reset_cpu();
}
}
}
}