Envío Gratis en compras mínimas de $1200 mxn Enviamos a toda la Republica Mexicana
Buscar

Práctica 7 con Miuva. Servomotor con potenciómetro con PIC C

En esta práctica vamos a integrar la práctica del servomotor junto con la del ADC para que mediante un potenciómetro se varíe el voltaje de entrada a Miuva, y esto ocasione que el servomotor se mueva proporcionalmente al giro del potenciómetro.

Definiremos en una función de interrupción por desborde del timer0 el proceso para mandar el pulso deseado al servomotor, recordando que este debe de ser con un periodo de 20ms y el pulso en alto debe de durar entre 1 y 2ms.

Podemos ver las siguientes equivalencias de: Valor_digital -> Voltaje -> Tiempo en microsegundos

valor_digital -> Voltaje -> tiempo_alto

1023 -> 5V -> 1000

La conversión del dato digital a voltaje y a tiempo la podemos realizar de la siguiente forma:

Voltaje = valor_digital * 5.0 / 1023.0

tiempo_alto = voltaje * 1000.0 / 5.0

valor_digital = read_adc(); //Lee el ADC
voltaje = 5.0*valor_digital/1024; //Convierte el ADC a voltaje
TIEMPO_ALTO = voltaje * 1000.0/5.0; //Convierte el voltaje a un valor entre 0 y 10001

Entonces tendremos los valores en microsegundos para 0 y 1ms, por lo tanto si le sumamos 1000 a cada valor, tendremos el valor en microsegundos para 1 y 2ms que son justo los valores que necesitamos.

TIEMPO_ALTO = TIEMPO_ALTO + 1000; //Convierte a un valor entre 1000 y 2000

Este tiempo en alto se enviará al servomotor en la función de interrupción y posteriormente tendremos que calcular el tiempo que debe de tardar en desbordarse el timer0 para que haya pasado el periodo de 20ms.

Con esto podemos crear el siguiente código:

Código en PIC C:

#include <18f4550.h>          // la librería del PIC
#device ADC = 10           //Bits del ADC
#Fuses HSPLL, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL2, CPUDIV1, VREGEN
#use delay (clock=48M)        //Seleccionamos la frecuencia de reloj de 48MHz
#use standard_io(b)        //preconfiguracion del puerto b
int16 TIEMPO_ALTO, carga, adc_read;    //Variables
float v;                               //Variable flotante
#int_TIMER0       //Funcion de interrupcion
void TIMER0_isr(void){   
   output_high(PIN_C1);       //PWM ON
   delay_us(TIEMPO_ALTO);     //Tiempo que estará en alto en microsegundos
   output_low(PIN_C1);        //PWM OFF
   carga = 20 - (TIEMPO_ALTO/1000);    //Para calcular el tiempo de 
   carga = carga*48000.0/32.0;         //la precarga del timer0
   carga = 65535 - carga;
   set_timer0(carga);         //Precargar el timer0
}
void main(){
   setup_adc_ports(AN0);                  //Configura A0 como analógico
   setup_adc(ADC_CLOCK_INTERNAL);         //ADC con oscilador interno
   setup_timer_0(T0_INTERNAL|T0_DIV_8);   //Configura Timer0
   enable_interrupts(int_TIMER0);         //Habilita interrupciones
   enable_interrupts(GLOBAL);
   set_timer0(0x8AD0);                    //Precarga del timer0
   set_adc_channel(0);                    //Configura para ller A0
   delay_us(20);                          //Retardo de 20us
   while(true){
      adc_read = read_adc();              //Lee el ADC
      v = 5.0*adc_read/1024;              //Convierte el ADC a voltaje
      TIEMPO_ALTO = v * 1000.0/5.0;       //Convierte el voltaje a un valor
                                          //entre 0 y 1000
      TIEMPO_ALTO = TIEMPO_ALTO + 1000;   //Convierte a un valor entre 1000 y 2000
   }
}

Conexiones

 

Observa el video demostrativo