Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Buenas a todos.
Después de controlar los grados de los servos me toca controlar su velocidad.
BoOpS me dio la idea para hacerlo.
1 - Se tiene que calcular el incremento en ticks cada 20ms.
2 - Se tiene que incrementar o disminuir en funcion del angulo final.
El problema es que me dejo algo ya que aplicado a mi código no funciona.
¿Tengo que hacer algo mas aparte de lo descrito anteriormente?
(No puedo adjuntar el código en ese momento, después lo pondré)
Saludos y gracias.
La idea es que en vez de decirle que vaya, por ejemplo, de (posición inicial) -90º a (posición final) 30º; cada 20 ms le dices que vaya "pasito a pasito" dependiendo del tiempo que tengas que tardar:
Si en un segundo quieres recorrer 120º, tienes que avanzar 120/(1000/20)=120/50=2,4º cada 20 ms. Por tanto, a cada interrupción aumentas el tiempo proporcional a 2,4º al tiempo en ON del servo.
La idea es que en vez de decirle que vaya, por ejemplo, de (posición inicial) -90º a (posición final) 30º; cada 20 ms le dices que vaya "pasito a pasito" dependiendo del tiempo que tengas que tardar:
Si en un segundo quieres recorrer 120º, tienes que avanzar 120/(1000/20)=120/50=2,4º cada 20 ms. Por tanto, a cada interrupción aumentas el tiempo proporcional a 2,4º al tiempo en ON del servo.
efectivamente, fácil, sencillo y para toda la familia 😛
Wolfskin, tengo un problema contigo... exceso de comunicación te digo cosas por msn cuando te veo y por aquí cuando no me ves...
El sistema es como estas pensando y como dice dragonet solo hay que tener en cuenta dos cosas más:
-La precisión con la que creas el pulso en alto, tendrás que redondear.
-El calculo del tiempo ocupa tiempo, puedes usar el tiempo "muerto" del servo al principio del pulso en alto (todos tienen un tiempo mínimo en Alto para la posición mínima)
Ahora los servos por encima de los 120 grados responden bien, pero por debajo no hacen nada, como mucho tiemblan.
Código://------------------------------------------------------------------------------
// Control de SERVO X
//------------------------------------------------------------------------------
// Cuadro de Tiempos :
// Periodo 20 ms (Frecuencia 50 Hz)
// TMR1 a 1:1 -> 1 Desbordamiento cada 5 ms
// -> 1 Tick cada 5 / 65536 = 0.076ms
// -> 1 Tick REAL = 0.0002ms
// -> precarga = 40536
// -> 20 ms = 4 INT_TIMER1 Completas
//------------------------------------------------------------------------------
#include <16F876A>
#device adc = 8
#priority TIMER1, RDA
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High Speed
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#use delay(crystal=20000000)
#use standard_io(B)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
// Registros
#byte PORTB = 0x06
#byte TRISB = 0x86
// LED
#bit LED = PORTB.1
// SERVOS
#bit SERVO1 = PORTB.7
#bit SERVO2 = PORTB.6
// Misc.
#define ON 1
#define OFF 0
// Funcions
void disparoPulso();
void controlPulso();
int16 calcularTicks(int parGraus);
int calcularIncremento(int parGrados, int parTemps);
// Constants
const int32 precarga = 40536;
const int32 ticksPosMin = 3500;
const float valorTick = 44.4444;
// Variables
int picoServo1 = 0;
int picoDesbordamiento = 0;
int contDesbordamientos = 0;
int16 ticks2Do = 3500;
int32 valorTIMER1;
int16 incremento = 0;
int grados = 0;
int velocidad = 0;
int16 ticksActuals = 3500;
#INT_RDA
void RDA_getGraus() {
while(kbhit()){
grados = getc();
velocidad = getc();
/*
if(ticksActuals > ticks2Do){
temp = (ticksActuals - ticks2Do) * valorTick;
incremento = calcularIncremento(temp, velocidad);
}
else{
incremento = calcularIncremento(grados, velocidad);
}
*/
//ticks2Do = calcularTicks(grados);
//incremento = calcularIncremento(grados, velocidad);
}
}
#INT_TIMER1
void TMR1_Contar()
{
++contDesbordamientos;
set_TIMER1(precarga);
if(contDesbordamientos == 4){
picoDesbordamiento = 1;
contDesbordamientos = 0;
}
}
void main(){
//Configuracion
//---------------------------------------------------------------------------
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//---------------------------------------------------------------------------
// Configura les interrupciones.
enable_interrupts(global);
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER1);
TRISB = 0x00;
PORTB = 0x00;
set_TIMER1(precarga);
while(TRUE)
{
disparoPulso();
controlPulso();
}
}
void disparoPulso()
{
if(picoDesbordamiento == 1)
{
picoDesbordamiento = 0;
SERVO1 = ON;
ticks2Do = calcularTicks(grados);
incremento = calcularIncremento(grados, velocidad);
if(ticksActuals < ticks2Do) ticksActuals += incremento;
if(ticksActuals == ticks2Do) ticksActuals = ticks2Do; // No serà igual ja que ho tinc d'arrodonir
if(ticksActuals > ticks2Do) ticksActuals -= incremento;
picoServo1 = 1;
}
}
void controlPulso()
{
if(picoServo1 == 1)
{
valorTIMER1 = get_TIMER1();
if((valorTIMER1 - precarga) > ticksActuals)
{
picoServo1 = 0;
SERVO1 = OFF;
}
}
}
int16 calcularTicks(int parGraus)
{
return ticksPosMin + (parGraus * valorTick);
}
int calcularIncremento(int parGrados, int parTemps)
{
return ((parGrados / (50 * parTemps) * valorTick);
}
Si alguien ve algo raro que lo comente.
Saludos y gracias.
P.D: Mí código es una mezcla de catalan y castellano. xD