Robot que evita obstáculos v1.0



Cordiales saludos a todos los lectores del blog!!! Hace ya tiempo que tengo arrumbado este pequeño robot, lo realice con el motivo de probar el sensor ultrasonico, debo confesar que no esta terminado al 100% pero así se quedo en su tiempo, falta mejorar el acomodo de las baterías para que se vea mas presentable (tal vez unas tipo AA recargables en lugar de las de celular que tiene), ademas de que la versión del firmware esta realizado de una forma muy básica así que aun falta detallarlo. Espero poder darme un tiempo y dejarlo trabajando al 100%.

Bueno en que consta este robot, pues la estructura esta realizada de material reciclado (es plástico con una capa adherida de aluminio, no recuerdo el nombre), un par de motorreductores y sus debidas llantas (de esas que encuentras en la electrónicas o tiendas de robótica), para el sensado se usa un sensor ultasonico (HC-SR04), en la parte del circuito de control se usa un PIC18F1320 que es el encargado de tomar las lecturas del sensor y activar el puente H que controla los motores.

Hablemos un poco mas del circuito propuesto, tenemos el conector de alimentación (actualmente alimento con dos baterías de celular en seria así que bien cargadas das unos 7V, que sera el voltaje al que se alimenten los motores), pasamos por su interruptor general y se allí a un regulador 7805 para alimentar el resto del circuito, tiene un LED Verde con su debida resistencia que indica la salida de 5V. Tenemos el PIC18F1320 (que la he colocado en SMD ya que era el que tenia a la mano) con su puerto ICSP para la debida programación, 2 LEDs para indicar cuando gire a la izquierda o derecha, botón de reset y conector para el sensor HC-SR04, la parte para controlar los motores he usado un driver para mosfet (el IR4427) y lo estoy utilizando como puente H así que uso 2, uno para cada motor, en sus salidas he colocado los diodos de protección para evitar que el regreso de corriente parásita provocada por los motores, bueno e circuito completo es el siguiente:

Bueno toca el turno para hablar del firmware que hace posible que esto cobre vida.

Iniciamos con el archivo "word_config.h" en donde se encuentran declarado todos los fusibles de nuestro microcontrolador.
/*
* File: word_config.h
* Author: MrChunckuee
*
* Created on 20 de mayo de 2013, 09:42 PM
*/
#ifndef WORD_CONFIG_H
#define WORD_CONFIG_H
// Configuracion del microcontrolador PIC18F1320
#pragma config OSC = INTIO2 //Uso de oscilador interno
#pragma config FSCM = OFF
#pragma config IESO = OFF
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config MCLRE = ON //Master Clear activado
#pragma config STVR = ON
#pragma config LVP = OFF
#pragma config DEBUG = ON
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRTC = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTRB = OFF
#endif /* WORD_CONFIG_H */
En el archivo "mcu.h" están declaradas la funciones utilizadas en "mcu.c" así como también todas las etiquetas que se usan en el resto del firmware, declaración de puertos y nombre de cada uno de ellos:
/*
* File: mcu.h
* Author: MrChunckuee
*
* Created on 20 de mayo de 2013, 09:48 PM
*/
#ifndef MCU_H
#define MCU_H
#define HIGH 1
#define LOW 0
#define INPUT 1
#define OUTPUT 0
#define CLEAR 0x00
#define MOTOR_IZQUIERDA_INA PORTBbits.RB0
#define TRIS_MOTOR_IZQUIERDA_INA TRISB0
#define MOTOR_IZQUIERDA_INB PORTBbits.RB1
#define TRIS_MOTOR_IZQUIERDA_INB TRISB1
#define MOTOR_DERECHA_INA PORTBbits.RB4
#define TRIS_MOTOR_DERECHA_INA TRISB4
#define MOTOR_DERECHA_INB PORTBbits.RB5
#define TRIS_MOTOR_DERECHA_INB TRISB5
#define LED_DERECHA PORTAbits.RA0
#define TRIS_LED_DERECHA TRISA0
#define LED_IZQUIERDA PORTBbits.RB3
#define TRIS_LED_IZQUIERDA TRISB3
//Pines para elsensor ultrasonico
#define TRIG PORTAbits.RA4
#define TRIS_TRIG TRISA4
#define ECHO PORTAbits.RA1
#define TRIS_ECHO TRISA1
void MCU_Init(void);//Inicializa sistema
void Delay_MS(unsigned int t);//Funcion para retardos en ms
unsigned int Medir_Distancia(void);//Funcion para medir la distancia
void Navegacion(void);//Funcion de navegarion
void Opcion_Movimiento(unsigned char X);//Funcion para activar las salidas
#endif /* MCU_H */
En el archivo "mcu.c" tenemos todo el código en cada una de sus funciones que en conjunto hacen que nuestro robot se mueva: 
/*******************************************************************************
*
* ROBOT QUE EVITA OBSTACULOS
*
*******************************************************************************
* FileName: mcu.c
* Processor: PIC18F1320
* Complier: XC8 v1.32
* Author: Pedro Sánchez (MrChunckuee)
* Blog: http://mrchunckuee.blogspot.com/
* Email: mrchunckuee.psr@gmail.com
* Description: Robot que evita obstaculos a una distancia de 15cm
* utiliza un sensor ultrasonico HC-SR04
* OSC Interno = 8MHz
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <xc.h>
#include "mcu.h"
#define _XTAL_FREQ 8000000
enum{AVANZAR, RETROCEDER, GIRO_DER, GIRO_IZQ, PARO};
unsigned int DISTANCIA, DISTANCIA_DER, DISTANCIA_IZQ;
void MCU_Init(void){
OSCCONbits.IRCF=0b111; //Oscilador interno a 8MHz
ADCON1=0xFF; //Configuramos entrada/salida digitales
//Definimos entradas y salidas
TRIS_MOTOR_IZQUIERDA_INA=OUTPUT;
TRIS_MOTOR_IZQUIERDA_INB=OUTPUT;
TRIS_MOTOR_DERECHA_INA=OUTPUT;
TRIS_MOTOR_DERECHA_INB=OUTPUT;
TRIS_LED_DERECHA=OUTPUT;
TRIS_LED_IZQUIERDA=OUTPUT;
TRIS_TRIG=OUTPUT; //Pin TRIG del HC-SR04 como salida
TRIS_ECHO=INPUT; //Pin ECHO del HC-SR04 como entrada
//Limpiamos los puertos
PORTA=CLEAR;
PORTB=CLEAR;
}
void Navegacion(void){
DISTANCIA=Medir_Distancia();//Mido la distancia
if(DISTANCIA>15){ //Si la distancias es mayor a 15cm
Opcion_Movimiento(AVANZAR);//Robot avanza
}
else {//Si es menor a 15cm
Opcion_Movimiento(PARO);//Robot se detiene
Opcion_Movimiento(GIRO_DER);//Gira hacia la derecha
Delay_MS(1000);//Retardo de 1 segundo mientras gira a la derecha
Opcion_Movimiento(PARO);//Se detiene
DISTANCIA_DER=Medir_Distancia();//Y mide la distancia
Opcion_Movimiento(GIRO_IZQ);//Gira a la izquierda
Delay_MS(2000);//Retardo de 2 segundos mientras gira a la izquierda
Opcion_Movimiento(PARO);//Se detiene
DISTANCIA_IZQ=Medir_Distancia();//Mide la distancia una vez mas
Opcion_Movimiento(GIRO_DER);//Gira a la derecha para regresar
Delay_MS(1000);//Retardo de 1 segundo mientras vuelve al origen
Opcion_Movimiento(PARO);//Se detiene
//Compara las distancias medidas
//Si distancia derecha es mayor a distancia izquierda
if(DISTANCIA_DER>=DISTANCIA_IZQ){
Opcion_Movimiento(GIRO_DER);//Gira a la derecha
Delay_MS(1000);//Retardo de 1 segundo mientras gira
Opcion_Movimiento(PARO);//Se para
}
else{//Si ditancia derecha es menor a distancia izquierda
Opcion_Movimiento(GIRO_IZQ);//Gira a la izquierda
Delay_MS(1000);//Retardo de 1 segundo mientras gira
Opcion_Movimiento(PARO);//Se para
}
//Termina esto y vuelve a repetir las intrucciones
}
}
//Rutina para retardos en mS personalizada
void Delay_MS(unsigned int t){
unsigned int j;
for(j=0;j<t;j++){
__delay_ms(1);
}
}
unsigned int Medir_Distancia(void){
unsigned int CENTIMETROS=0;
TRIG=HIGH;
__delay_us(10); //Retardo de 10uS
TRIG=LOW;
while(ECHO==LOW); //Espera flanco de subida por el pin echo
while(ECHO==HIGH){
CENTIMETROS++;
__delay_us(58);
}
return(CENTIMETROS);
}
void Opcion_Movimiento(unsigned char X){
switch(X){
case AVANZAR:
MOTOR_IZQUIERDA_INA=LOW;
MOTOR_IZQUIERDA_INB=HIGH;
MOTOR_DERECHA_INA=LOW;
MOTOR_DERECHA_INB=HIGH;
break;
case RETROCEDER:
MOTOR_IZQUIERDA_INA=HIGH;
MOTOR_IZQUIERDA_INB=LOW;
MOTOR_DERECHA_INA=HIGH;
MOTOR_DERECHA_INB=LOW;
break;
case GIRO_DER:
MOTOR_IZQUIERDA_INA=LOW;
MOTOR_IZQUIERDA_INB=HIGH;
MOTOR_DERECHA_INA=HIGH;
MOTOR_DERECHA_INB=LOW;
break;
case GIRO_IZQ:
MOTOR_IZQUIERDA_INA=HIGH;
MOTOR_IZQUIERDA_INB=LOW;
MOTOR_DERECHA_INA=LOW;
MOTOR_DERECHA_INB=HIGH;
break;
case PARO:
MOTOR_IZQUIERDA_INA=LOW;
MOTOR_IZQUIERDA_INB=LOW;
MOTOR_DERECHA_INA=LOW;
MOTOR_DERECHA_INB=LOW;
break;
default:
break;
}
}
En el archivo "main.c" tenemos nuestra función principal y nuestro bucle desde donde se estara ejecutando las tareas que va a realizar el robot: 
/*******************************************************************************
*
* ROBOT QUE EVITA OBSTACULOS
*
*******************************************************************************
* FileName: main.c
* Processor: PIC18F1320
* Complier: XC8 v1.32
* Author: Pedro Sánchez (MrChunckuee)
* Blog: http://mrchunckuee.blogspot.com/
* Email: mrchunckuee.psr@gmail.com
* Description: Robot que evita obstaculos a una distancia de 15cm
* utiliza un sensor ultrasonico HC-SR04
* OSC Interno = 8MHz
*******************************************************************************
* Rev. Date Comment
* v1.00 20/05/2013 Creación del firmware
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <xc.h>
#include "mcu.h"
#include "word_config.h" //Configuracion de fuses solo en este archivo se llama
#define _XTAL_FREQ 8000000
void main(void){
MCU_Init(); //Inicializamos PIC, calores por defecto
while(1){
Navegacion();//Siemre mandamos a llamar la funcion de navegacion
}
}
Aquí unas fotos del paso a paso del armado del robot, en la siguiente se ve como quedaron los motores fijados a la base y ademas con sus llantas una vista TOP.


Ahora se ve la parte BOTOM de nuestro robot, un par de cinchos para fijar los motores ayudados de algo de silicón, la llanta loca se ha fijado con unos tornillos y listo.

Aquí una imagen del PCB ya con todos los componentes soldados y listo para ser montado sobre el robot.

Ahora una foto donde se aprecia el PIC en versión SMD, el acabado de las pistas y la soldadura no ha quedado tan chulo pero el circuito cumple con su función.

Ahora si ya va tomando forma, agregando la PCB sobre nuestro robot, solo falta agregarle los conectores a los motores y colocar el sensor ultrasonico.

Como mencione anteriormente uso dos baterías de celular para alimentar tanto a los mores como a todo el circuito, algo se silicón para fijar el sensor y listo a cargarle el firmware al PIC para realizar pruebas.

Otra foto mas de como ha quedado el robot.


Dejo un vídeo del robot en acción para que vean que esta vivo (Prueba 1):


Espero que les guste y que les sea de utilidad lo que aquí les presento, como mencione anteriormente ya veré si mas adelante mejoro el firmware o realizo una segunda versión del robot.



Descargas:
Aquí el enlace directo para DESCARGAR los archivos disponibles, también puedes revisar o descargar la información desde mi repositorio en GitHub, si no sabes como descargarlo puedes checar aquí, bueno por el momento es todo si tienes dudas, comentarios, sugerencias, inquietudes, traumas, etc. dejarlas y tratare de responder lo mas pronto posible.

Donaciones:
Si te gusta el contenido o si los recursos te son de utilidad, comparte el enlace en tus redes sociales o sitios donde creas que puede ser de interés y la otra puedes ayudarme con una donación para seguir realizando publicaciones y mejorar el contenido del sitio. También puedes hacer donaciones en especie, ya sea con componentes, tarjetas de desarrollo o herramientas. Ponte en contacto para platicar, o puedes volverte uno de nuestros sponsors.


Pido una retroalimentación avisando cada que un enlace no sirva o tenga errores al momento de abrirlo, así también si una imagen no se ve o no carga, para corregirlo en el menor tiempo posible.

Publicar un comentario

2 Comentarios

  1. esta excelente... La verdad me gustaria que me dijeras como hacer el mismo codigo pero en un PIC 18F452. Si sabes por fa dime como hacerlo, muchas gracias, espero tu pronta respuesta

    ResponderEliminar
    Respuestas
    1. Saludos Fabian!! Exactamente que deseas, digo no es nada complicado migrar el código que muestro al PIC que mencionas, es mas lo que tienes que hacer es una tanto genérico, podrías por empezar a configurar los bits fuses, las entradas y salidas, lo demás es completamente igual.

      Eliminar