Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

02/09/2010 #1


3 Señales análogas para PIC18F4455
Un saludo foreros, vengo aca con una duda bastante interesante...

Me encuentro en la etapa inicial del desarrollo de un quadcopter (Helicoptero de 4 hélices), pero esto no es necesario saberlo para la resolución de mi duda, al grano como dijo el dermatólogo.

Me encuentro adquiriendo 3 señales análogas en un PIC 18F4455 con un cristal de 16MHZ, este cristal lo he seleccionado pues necesito una frecuencia especifica para generar un PWM con la conbinación de los timers, y he hecho una comunicación usb con labview, pero tengo problemas con el procesamiento de la señal, pues necesito procesarla porque estas señales provienen de un acelerometro, y cuando uso las funciones trigonometricas, la conexión usb no me funciona en LabView, aca abajo pondre parte del código.

Código:
#include <18F4455.h>
#device adc=10
#use delay(clock=16000000)
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL4,CPUDIV1,VREGEN,MCLR,NOCPD,STVREN

#define USB_HID_DEVICE     FALSE             // Deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   // EP1 para la entrada
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   // Ep1 para la salida
#define USB_EP1_TX_SIZE    31                // Tamaño del buffer de la entrada
#define USB_EP1_RX_SIZE    31                // Tamaño del buffer de salida

#include <pic18_usb.h> 
#include "usb_desc_scope.h"  
#include "usb.c" 
#include <math.h>
#include <stdlib.h>

#byte porta= 3968
#byte portb= 3969
#byte portc= 3970  
#byte portd= 3971
#byte porte= 3972

#bit CPP1 = 3970.0
//#bit CPP2 = 3970.1 

int16 duty1=0;
int16 med[3];
int   cont, cont_pwm, ch;
int1  flag; 
int8  bufferI[7]={0},i=0,len=0;

char x, s1[2], mensaje[7], sen1[7], sen2[7];
float medx1=0, medy1=0, medz1=0, medR=0, Angx=0, Angy=0, Angz=0;

#int_RTCC
void  RTCC_isr(void)
{
   if (cont_pwm==0)
   {
      flag=1;
      cont_pwm=10;
   }
   cont_pwm--;
   clear_interrupt(INT_RTCC);
}

#int_TIMER2
void  TIMER2_isr(void) 
{
 set_timer2(0);
   if (flag)
   {
      output_high(pin_E1);
      flag=0;
      CPP1=1;
      setup_timer_2(T2_DIV_BY_16,duty1,5);
   }
   else if (CPP1)
   {
      output_low(pin_E1);
      CPP1=0; 
   }
   else 
      setup_timer_2(T2_DIV_BY_16,100,5);
      clear_interrupt(int_TIMER2);
}

void volt2ang()
{
                  medx1=((((med[0]*3.3)/1023.0)-1.65)/3.3);
                  medy1=((((med[1]*3.3)/1023.0)-1.65)/3.3);
                  medz1=((((med[2]*3.3)/1023.0)-1.8)/3.3);
                  
                  medR=sqrt(pow(medx1,2)+pow(medy1,2)+pow(medz1,2));
                  
                  Angx=asin(medx1/medR);
                  Angy=asin(medy1/medR);
                  Angz=asin(medz1/medR); 
}

void usbsend()
{
         itoa(med[0],10,mensaje);        // integer to ASCII, convertimos medida en hexadecimal y lo guardamos en la variable mensaje
         strcat(mensaje,s1);
                      
         itoa(med[1],10,sen1);
         strcat(sen1,s1);
         
         itoa(med[2],10,sen2);
         strcat(sen2,s1);
         
         strcat(mensaje,sen1);
         strcat(mensaje,sen2);
           
         len=strlen(mensaje);            // Guardamos el tamaño de mensaje en la variable len
         usb_put_packet(1, mensaje,len, USB_DTS_TOGGLE);   // Enviamos mensaje de tamaño "len" al EP1 
  
           for(i=0;i<=6;i++)
           {
           mensaje[i]=0;
           }  
}

void main()
{
   output_low(pin_E1);
   setup_adc_ports(AN0_TO_AN11);
   setup_adc(adc_CLOCK_INTERNAL);  // Reloj interno para la conversión A/D
   
   set_tris_c(0b00000000);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_bit);
   setup_timer_2(T2_DIV_BY_16,100,5);
   
   output_low(pin_A5);
   output_low(pin_E1);                       // Flip Flop Puerto D (74LS373N)
   output_high(pin_E0);                      // Flip Flop Puerto D (74LS373N)
    
   strcpy(s1,";");                           // Copio el caracter ; en S1 
   
   enable_interrupts(INT_RTCC);
   enable_interrupts(INT_TIMER2); 
   enable_interrupts(GLOBAL);
    
           for(i=0;i<=6;i++)
           {
            mensaje[i]=0;
            bufferI[i]=0;
           }
   
   usb_init();                               // Inicialización de la USB
   usb_task();                               // Habilitamos periféricos he interrupciones
   usb_wait_for_enumeration();               // Esperamos asignación para la USb


while (1)
   {
      if(usb_enumerated())                     // Si la USB está enumerada por el host
      {
         if (usb_kbhit(1))                     // Si hay datos en el purto
         {
           usb_get_packet(1,bufferI, 8);       // Enviar bufferI de tamaño 8 bytes del EP1
           
            if (bufferI[0]== 65)               // Si la posición "0" es igual a "A" (Ascii)
            {
                  x=*strtok(bufferI,s1);
                  duty1=atoi(strtok(0,s1));
                          
                  for(ch=0;ch<3;ch++) { set_adc_channel(ch); delay_us(10); med[ch] = read_adc(); } 
               
                                
                  volt2ang(); 
     
                  usbsend();
          
            }
         }   
      }
   }
}
Estoy teniendo problemas cuando activo la función volt2ang(), función que implementé para convertir los valores de voltaje, en valores de grados de un acelerómetro.

La etapa siguiente, es implementar con estas señales un control PID.

Muchas gracias a todos de antemano.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.