gracias willynovi, que bien que van avanzando, espero poder contribuir, por lo pronto les dejo el código que tengo para manejar 8 servos y 8 LEDs, que en esencia es lo mismo, equivalente a tener 18 servos, los servos tienen como 15 pasos, se que no es mucha resolución, pero tal vez se pueda mejorar o sacar alguna idea de ahí, por cierto, también tengo un programa que resolvía la cinemática inversa de 2 grados de libertad, tal vez pueda ser útil, ese también lo posteo, solo que tengo que comentarlo, haber si me acuerdo, por que tiene como 2 años que lo hice XD.
El programa del control de servos y LEDs es muy largo, por lo pronto lo pongo tal como está, pero pienso quitarle la parte del menú y de los LEDs, para que sea más entendible. Saludos!
/* Este código sirve para controlar por medio de PWM el encendido de hasta
8 LEDs, y la posición de hasta 8 servos, por medio de comandos seriales
propios del puerto de comunicaciones seriales del PIC16F887, aunque
fácilmente se puede migrar a otros dispositivos.
En una pantalla LCD de 16x2 caracteres, se puede ver el menú de la aplicación
el cuál consta de un menú principal, al mandar el comando ASCII "ENTER" que
corresponde con el valor decimal 13, se pasa a la siguiente pantalla, para
volver al menu principal, es con ESCAPE, en el segundo menú es donde
da a escoger entre controlar los LEDs o los servos, con los números 1 y 2
respectivamente, posteriormente se muestra el número actual del LED o servo
que se esté controlando, pudiendo cambiar de número solo con presionar el
correspondiente dígito, si se presiona un número que no es, manda un mensaje
de error, al presionar "-" o "=" (lo deje con el signo igual, por que mi lap
no tiene signo más sin presionar shift) decremente o incrementa el pwm del
dispositivo en cuetión, con la barra espacioadora se va a ambos extremos, 0 o
180 grados en los servos, o prendido o apagado en los LEDs, toda la info que
se imprimie en el LCD también se manda serialmente a la computadora.
*/
#include <16F887.h>
#fuses HS, MCLR, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP, NODEBUG
#use delay(clock=20Mhz)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7,bits=8,parity=N) // Definición del RS232
#include <total_lcd.h>
#define LED1 PIN_B5
#define LED2 PIN_B4
#define LED3 PIN_B3
#define LED4 PIN_B2
#define LED5 PIN_B1
#define LED6 PIN_B0
#define LED7 PIN_C5
#define LED8 PIN_C4
#define SERVO1 PIN_A0
#define SERVO2 PIN_A1
#define SERVO3 PIN_A2
#define SERVO4 PIN_A3
#define SERVO5 PIN_A4
#define SERVO6 PIN_A5
#define SERVO7 PIN_E0
#define SERVO8 PIN_E1
#define SERVO9 PIN_E2
#define MIN_SERVO 9
#define MAX_SERVO 34
#define DEGREE 6.923
#define ENTER 13
#define ESCAPE 27
#define REGRESO 8
int8 duty_cycle=0,n=0;
int8 LED[8] = {0,0,0,0,0,0,0,0};
int8 SERVO[8] = {0,0,0,0,0,0,0,0};
int8 directory=0;
//int16 t=1000;
int1 flag_data=1;
char data=ESCAPE,last_data;
float degress[8] = {0,0,0,0,0,0,0,0};
void configure()
{
set_tris_A(0x00);
set_tris_B(0x00);
set_tris_C(0x00);
set_tris_D(0x00);
set_tris_E(0x00);
output_A(0x00);
output_B(0x00);
output_C(0x00);
output_D(0x00);
output_E(0x00);
setup_timer_0(T0_INTERNAL|T0_DIV_1);
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
lcd_init();
}
void print_LED()
{
flag_data=0;
printf(lcd_putc,"\fPulsa + - SPACE\n LED %d: %U %%" ,(n+1),LED[n]);
printf("Pulsa + - SPACE\rLED %d: %U %%\r\r" ,(n+1),LED[n]);
}
void print_servo()
{
flag_data=0;
printf(lcd_putc,"\fPulsa + - SPACE\nSERVO%d: %.2f¡"(n+1),degress[n]);
printf("Pulsa + - SPACE\rSERVO%d: %.2f¡\r\r"(n+1),degress[n]);
}
void print_error()
{
lcd_putc("\f ERROR! \nOpcion invalida");
lcd_putc("ERROR! Opcion invalida\r\r");
delay_ms(500);
data=last_data;
flag_data=1;
}
//==========================
void main()
{
configure();
lcd_putc("LCD OK!!!");
delay_ms(500);
while(TRUE)
{
if(flag_data==1&&directory==0)
{
flag_data=0;
switch(data)
{
case ESCAPE:
lcd_putc("\f--- M E N U ---\n PRESS ENTER");
printf("--- M E N U ---\r PRESS ENTER\r\r");
while(data!=ENTER) {}
directory=0;
break;
case ENTER:
lcd_putc("\f 1 = LEDs\n 2 = SERVOS ");
printf("1 = LEDs\r 2 = SERVOS \r");
directory=1;
break;
default: print_error(); break;
}
}
if(flag_data==1&&directory==1)
{
flag_data=0;
switch(data)
{
case '1':
lcd_putc("\fSelecciona led:\n 1 -- 8");
printf("Selecciona led: 1 -- 8\r");
directory=2;
break;
case '2':
lcd_putc("\fSelecciona servo\n 1 -- 8");
lcd_putc("Selecciona servo: 1 -- 8\r");
directory=3;
break;
case ESCAPE:
directory=0;
flag_data=1;
break;
default: print_error(); break;
}
}
if(flag_data==1&&directory==2)
{
flag_data=0;
switch(data)
{
case '1': n=0; print_LED(); directory=4; break;
case '2': n=1; print_LED(); directory=4; break;
case '3': n=2; print_LED(); directory=4; break;
case '4': n=3; print_LED(); directory=4; break;
case '5': n=4; print_LED(); directory=4; break;
case '6': n=5; print_LED(); directory=4; break;
case '7': n=6; print_LED(); directory=4; break;
case '8': n=7; print_LED(); directory=4; break;
case ESCAPE:
directory=0;
flag_data=1;
break;
default: print_error(); break;
}
}
if(flag_data==1&&directory==3)
{
flag_data=0;
switch(data)
{
case '1': n=0; print_servo(); directory=5; break;
case '2': n=1; print_servo(); directory=5; break;
case '3': n=2; print_servo(); directory=5; break;
case '4': n=3; print_servo(); directory=5; break;
case '5': n=4; print_servo(); directory=5; break;
case '6': n=5; print_servo(); directory=5; break;
case '7': n=6; print_servo(); directory=5; break;
case '8': n=7; print_servo(); directory=5; break;
case ESCAPE:
directory=0;
flag_data=1;
break;
default: print_error(); break;
}
}
if(flag_data==1&&directory==4)
{
flag_data=0;
switch(data)
{
case '=':
{
if(LED[n]<100) LED[n]+=10;
print_LED();
}
break;
case '-':
{
if(LED[n]>0) LED[n]-=10;
print_LED();
}
break;
case ' ':
{
if(LED[n]<50) LED[n]=100;
else LED[n]=0;
print_LED();
}
break;
case '1': n=0; print_LED(); directory=4; break;
case '2': n=1; print_LED(); directory=4; break;
case '3': n=2; print_LED(); directory=4; break;
case '4': n=3; print_LED(); directory=4; break;
case '5': n=4; print_LED(); directory=4; break;
case '6': n=5; print_LED(); directory=4; break;
case '7': n=6; print_LED(); directory=4; break;
case '8': n=7; print_LED(); directory=4; break;
case ESCAPE:
directory=0;
flag_data=1;
break;
default: print_error(); break;
}
}
if(flag_data==1&&directory==5)
{
flag_data=0;
switch(data)
{
case '=':
{
if(SERVO[n]>MIN_SERVO)
{
SERVO[n]--;
degress[n]-=DEGREE;
print_servo();
}
}
break;
case '-':
{
if(SERVO[n]<MAX_SERVO)
{
SERVO[n]++;
degress[n]+=DEGREE;
print_servo();
}
}
break;
case ' ':
{
if(SERVO[n]<23)
{
SERVO[n]=MAX_SERVO;
degress[n]=179.998;
}
else
{
SERVO[n]=MIN_SERVO;
degress[n]=0;
}
print_servo();
}
break;
case '1': n=0; print_servo(); directory=5; break;
case '2': n=1; print_servo(); directory=5; break;
case '3': n=2; print_servo(); directory=5; break;
case '4': n=3; print_servo(); directory=5; break;
case '5': n=4; print_servo(); directory=5; break;
case '6': n=5; print_servo(); directory=5; break;
case '7': n=6; print_servo(); directory=5; break;
case '8': n=7; print_servo(); directory=5; break;
case ESCAPE:
directory=0;
flag_data=1;
break;
default: print_error(); break;
}
}
}
}
#INT_TIMER0
void timer0()
{
if(duty_cycle==0)
{
if(LED[0]) output_high(LED1);
if(LED[1]) output_high(LED2);
if(LED[2]) output_high(LED3);
if(LED[3]) output_high(LED4);
if(LED[4]) output_high(LED5);
if(LED[5]) output_high(LED6);
if(LED[6]) output_high(LED7);
if(LED[7]) output_high(LED8);
if(SERVO[0]) output_high(SERVO1);
if(SERVO[1]) output_high(SERVO2);
if(SERVO[2]) output_high(SERVO3);
if(SERVO[3]) output_high(SERVO4);
if(SERVO[4]) output_high(SERVO5);
if(SERVO[5]) output_high(SERVO6);
if(SERVO[6]) output_high(SERVO7);
if(SERVO[7]) output_high(SERVO8);
}
if(LED[0]==duty_cycle) output_low(LED1);
if(LED[1]==duty_cycle) output_low(LED2);
if(LED[2]==duty_cycle) output_low(LED3);
if(LED[3]==duty_cycle) output_low(LED4);
if(LED[4]==duty_cycle) output_low(LED5);
if(LED[5]==duty_cycle) output_low(LED6);
if(LED[6]==duty_cycle) output_low(LED7);
if(LED[7]==duty_cycle) output_low(LED8);
if(SERVO[0]==duty_cycle) output_low(SERVO1);
if(SERVO[1]==duty_cycle) output_low(SERVO2);
if(SERVO[2]==duty_cycle) output_low(SERVO3);
if(SERVO[3]==duty_cycle) output_low(SERVO4);
if(SERVO[4]==duty_cycle) output_low(SERVO5);
if(SERVO[5]==duty_cycle) output_low(SERVO6);
if(SERVO[6]==duty_cycle) output_low(SERVO7);
if(SERVO[7]==duty_cycle) output_low(SERVO8);
duty_cycle++;
if(duty_cycle==101) duty_cycle=0;
SET_TIMER0(0);
}
#int_rda
void serial_isr()
{
if (kbhit())
{
last_data=data;
data=getch();
printf(data);
flag_data=1;
}
}