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.
//Se incluyen las librerias necesarias
#include <stdio .h>
#include <conio .h>
#include <string .h>
#include <iostream .h>
#include <dos .h>
//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< <"\n Elige un modo de uso: \n\n (1) Modo guiado\n (2) Modo consola (Avanzado)\n";
cin>>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< <"\n Elige el servo que deseas mover del 1 al 4\n ";
cin>>servo;
if (servo< =0 || 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<<"\n Elige el angulo deseado de 1 al 180\n ";
cin>>angulo;
if (angulo< =0 || 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<<"\n\n Deseas realizar otro movimiento? \n cualquier tecla para continuar, n para salir ";
cin>>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,0x80);//SET DLAB ON
outportb(PUERTO+0,0x0C);// 9,600 BPS
outportb(PUERTO+1,0x00);//Set Baud rate - Divisor Latch High Byte
outportb(PUERTO+3,0x03);// 8 Bits, No Parity, 1 Stop Bit
outportb(PUERTO+2,0XC7);//FIFO Control Register
outportb(PUERTO+4,0X0B);//Turn on DTR, RTS, and OUT2
}
Y el codigo para el arduino
#include <Servo.h>
#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]);
}
}
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.
Popularity: 98%






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