Control brazo robotico por puerto serie en lenguaje C

Te has preguntado como comunicar turbo C con un microcontrolador por puerto serie?? pues aqui esta la respuesta. El programa funciona para controlar 4 servomotores, se corre el programa desde la pc y se reciben los datos RS232 en un microcontrolador, en este caso se uso la placa arduino, de la cual se anexa el programa y el circuito.

Ambos programas estan lo suficientemente comentados para su entendimiento, primero tenemos el programa para turbo C.

[code language=c]
//Se incluyen las librerias necesarias
#include
#include
#include
#include
#include

//Se definen constantes que utilizaremos durante el programa
#define ENTER 13
#define ESCAPE 27
#define PUERTO 0x3E8
#define LONG_MAX 1000

//Declaracion de variables a usar
char tecla,cont;
int pos = 0;
int opc;
int i = 0,servo=1,angulo=90;
int mode=1;
char cadena[400];
char mensaje[40];

void inicializar();//prototipo de la funcion inicializar

//Comienza el programa principal
void main(){
clrscr();
inicializar();//llamamos a la funcion inicializar para que prepare el puerto

cout< >mode;

while (tecla != ESCAPE)//Mientras no presionemos escape para salir del programa
{
if (mode==1){//Si modo es igual a 1 entrara al modo guiado
//modo guiado
setservo:
cout< >servo;
if (servo=5){//Rango de servos disponible
cout< <"n Fuera del rango";
goto setservo;//Si esta fuera del rango nos regresa a la etiqueta setservo
}
outportb(PUERTO,servo+249);//Manda por el puerto el comando del servo a mover

setangulo:
cout<>angulo;
if (angulo=181){//Rango de angulos disponibles
cout< <"n Fuera del rango";
goto setangulo;//Si esta fuera del rango nos regresa a la etiqueta setangulo
}

outportb(PUERTO,angulo);//Manda por el puerto el valor del angulo

cout<>cont;
if (cont==110){
tecla=ESCAPE;
}//si cont es n entonces tecla=ESCAPE y saldra del programa

}
else if (mode==2) {//Si mode = 2 entrara al modo consola
// modo consola

if (inportb(PUERTO+5)&1)//Si hay datos en el buffer del puerto
{
for (i=0;((inportb(PUERTO+5)&1)); i++)//Recorre el buffer del puerto
{
cadena[i] =inportb(PUERTO);//guarda cada byte en una cadena
printf(“%c”,cadena[i]);//Imprime los caracteres en pantalla
}
printf(” “);
}

if (kbhit())//preguntamos si se presiono alguna tecla
{
tecla = getch();
if (tecla!=ESCAPE && tecla!=8 )//preguntamos si tecla es distinto de escape
{
if (tecla==ENTER)//preguntamos si la tecla presionada es un enter
{
mensaje[pos] = tecla;//Guarda la ultima tecla presionada en la ultima posicion de mensaje
printf(” “);
i = 0;
while(mensaje[i]!= ENTER && i < LONG_MAX)//Hasta que se encuentre un enter o espacio en la cadena
{
outportb(PUERTO,mensaje[i]);//enviamos la cadena, letra por letra, al puerto
i++;
}
pos=0;//Reinicia el indice para mensaje
}
else
{
mensaje[pos] = tecla; //guardamos la tecla presionada
cprintf("%c",mensaje[pos]); //imprimimos el caracter
++pos;
}
}
}
}
}
}

//Inicializa el puerto serie con las propiedades siguientes
void inicializar()
{
outportb(PUERTO+1,0);// Turn off interrupts – Port1
outportb(PUERTO+3,0×80);//SET DLAB ON
outportb(PUERTO+0,0x0C);// 9,600 BPS
outportb(PUERTO+1,0×00);//Set Baud rate – Divisor Latch High Byte
outportb(PUERTO+3,0×03);// 8 Bits, No Parity, 1 Stop Bit
outportb(PUERTO+2,0XC7);//FIFO Control Register
outportb(PUERTO+4,0X0B);//Turn on DTR, RTS, and OUT2
}
[/code]

Aqui el circuito diseñado
[singlepic id=129 w=420 h=340 float=center]

Y el codigo para el arduino

[code language=c]
#include
#undef int
#undef abs
#undef double
#undef float
#undef round

Servo servo[4]; //creamos 4 objetos servo

boolean commandFlag=0;
int led=13;
int inByte = 0,i;
int Home[]={
90,90,90,90};
int angle[] = {
90,90,90,90}; //posicion inicial de los servos (home)
int currServo=0;

void setup()
{
pinMode(led, OUTPUT);
//pines donde se conectan los servos
servo[0].attach(2);
servo[1].attach(3);
servo[2].attach(4);
servo[3].attach(5);

//se llama a la funcion setAngle() para setear la posicion inicial de los servos
setAngle();

//inicia comunicacion serial
Serial.begin(9600);
Serial.print(“Conectado…”);
}

void loop()
{
if (Serial.available() > 0) { //si hay datos en el bufer del puerto
inByte = Serial.read();
Serial.print(inByte,BYTE);
Serial.print(” “);
Serial.println(inByte, DEC);//imprime el byte recibido
if (commandFlag){//si un comando espera valor
if (inByte< =180){
angle[currServo]=inByte;
setAngle();
commandFlag=false;
digitalWrite(led, LOW);
}
else
{
Serial.println("El comando introducido no acepta ese valor");
}

}
else
{
switch (inByte){
case 250:
currServo=0;
commandFlag=true;
Serial.println("servo 1 OK ingrese angulo");
digitalWrite(led,HIGH);
break;
case 251:
currServo=1;
commandFlag=true;
Serial.println("servo 2 OK ingrese angulo");
digitalWrite(led,HIGH);
break;
case 252:
currServo=2;
commandFlag=true;
Serial.println("servo 3 OK ingrese angulo");
digitalWrite(led,HIGH);
break;
case 253:
currServo=3;
commandFlag=true;
Serial.println("servo 4 OK ingrese angulo");
digitalWrite(led,HIGH);
break;
default:
Serial.println("Comando desconocido…");
break;
}
}
}
Servo::refresh(); //refresca la posicion de los servos
}

//setea los valores de los angulos en los objetos servo
void setAngle(){
for(i=0;i<=3;i++){
servo[i].write(angle[i]);
}
}
[/code]

La estructura del brazo fue hecha con acrílico, y los servos se fijaron con tornillos. Son las únicas fotos que tome. El brazo no posee pinza de sujeción y es muy sencillo, ya que el proyecto solo trataba de implementar el uso de la comunicación serial con un dispositivo electrónico.
[singlepic id=380 w=320 h=240 float=center]
[singlepic id=381 w=320 h=240 float=center]
[singlepic id=382 w=320 h=240 float=center]
[singlepic id=383 w=320 h=240 float=center]

Adrian MB

Me gusta la electrónica, programación y todo lo relacionado. Ing. en Mecatronica de la UPIITA del IPN y estudiante de Diseño Industrial en la UAM. @adrianmtzb http://adrianmb.mx

También te podría gustar...

  • John bonachon

    CUALES SON LAS LIBRERIAS!!!!

  • Podias indicar los componentes electrónicos que usas.
    Ademas en el código que pones no han salido el nombre de las librerias:
    //Se incluyen las librerias necesarias
    002. #include ……. (no sale el nombre)

    • Con todos los cambios que ha sufrido el blog se modificaron algunas entradas y se borraron fragmentos del código, en cuanto tenga un tiempo libre lo corrijo, saludos y gracias por el aviso 🙂

  • felix

    En la foto donde pones el diagrama veo que la fuente externa, no entra a la tarjeta arduino, solo entra al proto ahi entra el regulador y los servos y listo????

  • Quintana

    Hola, disculpa estoy realizando un brazo robotico con 5 servomotores futaba que trabajan con un voltaje de 4.8v a 6v pero tengo problemas con la potencia ya que quiero utilizar los 5v que me proporciona mi arduino, para esto me dicen que es recomendable utilizar un amplificador operacional para retroalimentar a cada servomotor, o me recomiendas mejor con estos reguladores de voltaje? si utilizo estos es necesario añadir las 5 fuentes una para cada servo? saludos!

  • Hola que tal, no se utilizan transistores para este proyecto, el CI utilizado es un regulador de tension LM7805 para no sobrealimentar los servomotores, los capacitores son de 100nF que sirven como filtro.

    Saludos

  • fanny

    ola estoy muy interesada en este proyecto pero igual me gustaria saber que tipo de capasitores y transistor necesito o conque matricula los puedo pedir o buscar ??? xfa ayudam! ñ_ñ gracias

  • Angel Villanueva

    Hola que tal yo de nuevo, disculpa la insistencia, me servira la tarjeta Arduino Uno-R3, para hacer este proyecto o hay que modificarle algo al codigo. gracias.

    • Si claro esa versión de arduino te serviría bien, los servos son marca hitec, aunque cualquier servo estándar funcionaria excelente.

      • Angel Villanueva

        Disculpa de nuevo yo. en el diagram veo que tienes unos capacitores y un transistor, si no es mucha molestia me podrias asesorar que funcion estan haciendo en el circuito y con que datos los puedo conseguir gracias, que tengas buen dia.

  • Angel Villanueva

    Sorry lo escribi mal Arduino y las matriculas de los servomotores, gracias de nuevo.

  • Angel Villanueva

    Hola buen dia, me encantaria realizar este proyecto, solo tengo algunas dudas.
    cual es el modelo de la tarjeta de Ardruino utilizada y los valores de los capaciotres y matricula del transistor. muchas gracias.

  • jose benito guillen badillo

    HOLA ME INTERESO EL PROYECTO.YO ESTOI REALIZANDO UNO IGUAL PERO CON MOTORES DE CD CON ENCODER Y OTROS MOTORES SI ENCODER NO SE SI ESTE PROGRAMA ME PUEDE SERVIR PARA CONTROLAR LA POSICION DE LOS MOTORES DE CORRIENTE DIRECTA, POR TU ATENCION GRACIAS

    • Hola que tal, este programa no te servirá para tus motores con encoder, esta diseñado específicamente para trabajar con servos.

      Saludos 🙂

  • cesar mendoza

    tengo algunos años que termine de estudiar la ingenieria en sistemas y la verdad por cuestiones de trabajo me aleje de todo este mundo de la programacion, mi interes es realizar un prototipo robotico y leyendo todos estos comentarios me nacen las ganas de reiniciar tengo nociones sobre el lenguaje c++
    e incluso estoy retomando todo esto es muy agradable ver que tanta gente tenga el interes de aprender y tambien exista el desinteres de enseñar nunca olviden ni dejen de aprender y ante todo muchas gracias por compartir sus conocimientos con todos nosotros.

  • jose benito guillen badillo

    hola amigos en my escuela estoy desarrollando un brazo robot RX 160 CR es parecido al brazo robot PUMA, en my caso quisiera alguna ayuda de ustedes.. quiero implementar motores CD de elevadores de vidrio de carro y con una targeta de adquisicion EASYUSB 10 tengo una etapa de potencia con relevadores y quisiera saver como puedo hacer para la posicion de mis motores….

  • CoLcHoN

    saludos ^^ buen proyecto n.n aunq no le entendi mucho ya que no se programar en c 😕 bueno tengo un proyecto con unos amigos el cual se trata de controlar un brazo robot de 2 maneras:

    1ª el brazo hara un proceso de “tomar” y “poner” el cual sera continuo (le pondra tapas a una cajita que se encuentre en una banda) a traves de un pic.

    2ª el brazo debe ser controlado mediante un modulo bluetooth y un celular con sistema android y en este caso “nosotros” le mandaremos las instrucciones a travez del celular.

    y pues de entrada no sabemos bien por donde comenzar, queremos programarlo en C ya que tiene menos errores de compilacion que basic, y pues no sabemos C 😥 si nos pudieras ayudar en algo muchas gracias y si no pues gracias de todos modos. seria de mucha ayuda un tutorial de programacion en C para quienes no tienen ni idea de como programar (en C) ^^

    gracias n.n

  • Erick Adrian

    .: Q hay! en si es un buen proyecto el tuyo :.

    .: Veras, mi duda es algo quiza problematico….estoy haciendo un robot, igual que el que has usado solamente que el mio tiene pinza (aunque es opcional como veras), mi profesor me dijo que tiene que realizar la tarea de pick and place y pues puede agarrar, atrapar, magnetizar etc etc el objeto, moverlo y demas…. :.

    .: Estaba usando Visual Basic, pero yo estaba programando las posiciones, hasta que me dijo que tenia que pasar por una etapa donde mi cinematica se involucrara (obtuve parametros D-H) y en lo que pida el programa era simplemente darle las posiciones en X, Y, y Z (aunque Z es opcional) y que el robot se mueva en su plano de trabajo….. :.

    .: Debo de decir que el problema que se me ha presentado es esa parte, en que punto puedo meter mi cinematica para ser interpretara, y por ende, hacer que responda de manera correcta….estoy leyendo tu codigo en C, y no se en que punto aplicas alguna parametrizacion o algun punto clave para poder moverlo libremente a travez de tu espacio de trabajo, o podrias decirme que consideraciones has tomado? :.

    .: En verdad ese es mi unico problema, puesto que puedo manipular los servos, y habia propuesto unas posiciones, asi, aunque me pidieran X o Y cosas, terminaria agarrando la pieza…….hasta hoy que el profesor me dijo que esa face se nececitaba para formalmente tener ese ‘control’….puesto que despues de aplicar ese control, se moveria, se realizaria la funcion y luego volveria a esperar coordenadas :.

    .: Espero en verdad pueda ayudarme, y espero haber descrito mi problema bien, cualquier cosa mi correo lo deje por si acaso, y lo repito aqui: avfaev_01….de la extencion de hotmail ^^ :.

    .: Saludos y buenos dias / tardes / noches :.

  • ADRIAN

    oye me podrias pasar tu coreo por favor porque me intereso el trabajo que realizaste y pienso realizar algo parecido y por si me surgen algunas dudas x favor espero y se pueda.

  • Adrian

    Hola que tal oye m podrias decir si es necesario algun tipo de servo en especifico y que otros materiales utilizaste o solo los servos y el arduino porque el circuito no se que componentes lleve y si necesitaste alguna interfase o algo asi por favor espero tu respuesta gracias.

    • Son servos estándar, los materiales para el brazo son a tu elección tomando en cuenta el peso que puedan levantar tus servos, y de componentes ademas del arduino, use un regulador para alimentar los servos desde una fuente de 12V

  • luismirandasolari@hotmail.com

    puedes explicarme la inicializacion?

    outportb(PUERTO+1,0);//
    outportb(PUERTO+3,0x80);//
    outportb(PUERTO+0,0x0C);//
    outportb(PUERTO+1,0x00);// outportb(PUERTO+3,0x03);//
    outportb(PUERTO+2,0XC7);
    outportb(PUERTO+4,0X0B);

    no entiendo el 0x80, 0x0c, etc
    gracias

  • juan

    mil graxias flaco realmente me ayudo mucho tu contestacion!

  • Iván

    Muchas gracias por responder.
    ¿Me podrías ayudar por favor?
    Estoy estudiando ing en sistemas, pero no vemos nada sobre puerto serie, tendrás algún manual para iniciar en esto, me gustaría bastante aprender, si es posible un curso de novatos o el nombre de algún libro.
    Gracias.

  • Iván

    Excelente trabajo. ¿Crees que se pueda hacer en otro lenguaje como C++ o Java?
    Saludos.

    • Por supuesto, solo es cuestion de usar las librerias necesarias para cada lenguaje

  • jaun

    hola tengo una duda yo quiero hacer ese brazo pero no consigo el atmega 8 para el ardruino que otro ontegrado puedo usar?

    • Hola que tal, si no consigues el arduino puedes usar cualquier otro microcontrolador, el único requisito es que necesitaras el conversor para la comunicación USB-Serial, ademas de que el micro que uses cuente con el puerto UART. Para este proyecto te puede servir un PIC pequeño como el 12f675 o uno un poco mas robusto como el 16f628, 16f88.

      Los arduinos mas recientes trabajan con el ATMEGA328 quizás ese si lo consigas, el inconveniente de usar un chip nuevo es que tendrás que grabarle el bootloader (firmata) y necesitaras de un programador de micros AVR.

  • Nuevo:

    Hola tengo un brazo rombotico que compre en steren y lo quiero conectar con puerto paralelo y usarlo mediante c pero no tengo idea de pordonde comenzar ni el codigo a usar. Ojala me puedas orientar un poco

  • darly

    Hola muchas gracias claro ya tenemos el robot costruido los motores y los servos ademas del arduino y la cinematica directa e inversa desarrollada ya, solo que necesitamos algo de ayuda para escribir en ambiente del programa arduino el codigo para visulaizar el control de las trayectorias.

    • Al parecer ya tiene lo mas dificil que es la mecanica de su robot, la programación de arduino es lo mas sencillo relativamente, te invito a que crees un nuevo tema en el foro http://blog.make-a-tronik.com en la seccion correspondiente, asi podemos darle mas seguimiento a tu proyecto 😉

  • darly

    hola me gustaria saber si tienen una idea de como realizar el programa en arduino de control de la posicion de un robot delta con un arduino

  • daniel hh

    hola oye yo estoy haciendo un brazo robot pero no tengo la plaquita de arduino de que otra forma puedo comunicar a mi brazo con la pc o si solo la puedo conectar con un joistick aun que es de poca categoria

    • Pues depende de que tipo de motores estes usando y la interfaz que quieras usar, si usas servos lo mas conveniente es usar algún microcontrolador y comunicarlo con la pc por el puerto serial, si usas motores dc con reductor te puede servir el puerto paralelo y te ahorras la programada del microcontrolador.

      Con un poco mas de detalles podemos buscar una solución mas precisa 😉

      • daniel hh

        veras tengo 2 servos y dos paso a paso pero esos los voy a controlar aparte por un puente h pero los servos ocmo los controlaria y en que software puedo hacer el codigo

        • para mover un servo se utiliza modulacion por ancho de pulso, checa el post acerca de los servos , el codigo lo puedes realizar en C con el compilador CCS o si prefieres en basic te recomiendo un compilador que se llama PIC SIMULATOR IDE esta muy completo y facil de usar.