Autor Tema: Envio de datos por USB  (Leído 6126 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Envio de datos por USB
« en: 16 de Mayo de 2011, 11:45:46 »
Hola amigos,

Estoy trabajando con el PIC18F4550 es un proyecto que requiere de la digitalización de datos y utilizo los 10 bits del ADC interno. Me gustaría mandar estos datos en paquetes de 64 bytes, por lo que les mando el código para ver su opinión especialmente si el tipo de datos es el correcto para representar los 1024 posibles valores del ADC. Esta es parte del programa que implemente basandome en el buen trabajo del proyecto picUSB:
#include <18f4550.h>          //Librería del PIC utilizado

#device ADC=10
                              //Palabras de configuración
                             
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VREGEN

#use delay(clock=48000000)    //Frecuencia de Trabajo
//______________________________________________________________________________                               
//deshabilitamos el uso de las directivas HID
#define USB_HID_DEVICE     FALSE
//Habilita EP1(EndPoint1) para transf. de entrada bulk/interrup
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK
//Habilita EP1(EndPoint1) para transf. de salida bulk/interrup   
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK
//Tamaño del Endpoint TX 1 buffer
#define USB_EP1_TX_SIZE    64
//Tamaño del Endpoint RX 1 buffer
#define USB_EP1_RX_SIZE    3 
//______________________________________________________________________________
//Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <pic18_usb.h>
//Configuración del USB por Enumerador
#include <enumerador_pic.h>
//handles usb setup tokens and get descriptor reports
#include <usb.c>           
//__________________

#define LEDV      pin_C0
#define LEDR      pin_C1

#define alto      output_high
#define bajo      output_low 

#define modo      recibe[0]   //Selecciona los modos de trabajo de la interface
#define param1    recibe[1]
#define param2    recibe[2]
#define resul     envia[0]

//Variables Globales
int8 recibe[3];
int8 i,muestras[64];

void main()
{
   bajo(LEDV);
  alto(LEDR); 
   
  usb_init();     //inicializamos el USB
 
  usb_task();     //habilita periferico usb e interrupciones
 
                  //Esperar hasta que el Pic se configure por el host
  usb_wait_for_enumeration();
 
 
  bajo(LEDR);
  alto(LEDV);   

    setup_adc_ports(AN0_TO_AN1|VSS_VREF); //Configuración Canales Analógicos
      setup_adc(ADC_CLOCK_DIV_64);          //Configuración Reloj de Conversión
 
      #asm
      bsf 0xFC0,7 //Justificación a la derecha
      //Configuración del tiempo de adquisición, taq=2TAD
      bsf 0xFC0,3
      bcf 0xFC0,4
      bcf 0xFC0,5
      #endasm

while(1)
   {
      if(usb_enumerated())    //si el Pic está configurado
      {                   
         if(usb_kbhit(1))    //si el endpoint de salida contiene datos del host
         {
            usb_get_packet(1, recibe, 3); //cojemos el paquete de tamaño 2bytes del EP1 y almacenamos en recibe
switch(modo)
            {
              case 0:
set_adc_channel(0); //Canal 0 del ADC
                       
for(e = 0;e < 64;e++)
                        {
                           muestras[e]=read_adc();
                           delay_us(50);
                        }   
                        usb_put_packet(1,muestras,64,USB_DTS_TOGGLE);
                        break;
}
}
}

}

Básicamente la duda surge porque como se trabaja con un ADC=10 me confunde el formato de us datos que talves se deba enviar int16...
Saludos

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Envio de datos por USB
« Respuesta #1 en: 16 de Mayo de 2011, 13:27:31 »
read_adc(); te devuelva un valor de 16-bits, si lo guardas en una variable de 8-bits se trunca. Lo que tienes que hacer es guardar el valor de 16-bits en una variable temporal y luego dividirla en 2 bytes utilizando make8(...). Revisa la ayuda de CCS

En la PC tomas los 2 bytes y reconstruyes la variable de 16-bits. Cualquier duda utiliza el buscador, se ha hablado del tema en varias oportunidades.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado cristian_elect

  • PIC18
  • ****
  • Mensajes: 453
Re: Envio de datos por USB
« Respuesta #2 en: 16 de Mayo de 2011, 17:15:26 »
Un "switch" con solo un  "case"!!
Hay que saber usar el C lo mejor posible.

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #3 en: 16 de Mayo de 2011, 19:30:52 »
                        set_adc_channel(0); //Canal 0 del ADC
                        delay_us(50);
                        valorADC=read_adc();
                        valorH=make8(valorADC,1); //Byte MSB
                        muestras[0]=valorH;
                        valorL=make8(valorADC,0); //Byte LSB
                        muestras[1]=valorL;
                           .
                           .
                           .

Hasta llegar a la posición 64?? Hay alguna manera de implementar esto más fácil.. claro si esta es la manera correcta de enviar los datos del ADC
Saludos
                                       
                       
                        usb_put_packet(1,muestras,64,USB_DTS_TOGGLE);

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Envio de datos por USB
« Respuesta #4 en: 16 de Mayo de 2011, 20:03:36 »
Podes hacerlo dentro de un for:


for(k=0;k<64;k++){
muestras[k++]=valorH;
muestras[k]=valorL;
}
usb_put_packet(1,muestras,64,USB_DTS_TOGGLE);



Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #5 en: 16 de Mayo de 2011, 21:21:57 »
Listo, gracias suky... como estoy usando el C#

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #6 en: 16 de Mayo de 2011, 21:26:28 »
Como estoy usando el C# e imprimiendo en un archivo de texto los resultados.. este es el método que implemento para la recepcion de los datos:

public int[] RecibeDatos()
        {           
            DWORD RecvLength = 64;
            int []result = new int[64];
            byte* receive_buf = stackalloc byte[64];           
            ReciboPaquete(receive_buf, &RecvLength);
            for (int i = 0; i < 64; i++)
            {
                result = receive_buf;
            }
            return result;
        }


Pero no tengo idea como hacer para tomar valorH y valorL para reconstruir el valor del ADC del PIC..

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Envio de datos por USB
« Respuesta #7 en: 16 de Mayo de 2011, 21:32:57 »
Fácil:

Código: C
  1. for (int i = 0,j=0; i < 64; i+=2,j++)
  2.             {
  3.                 result[j] = receive_buf[i]*256+receive_buf[i+1];
  4.             }


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #8 en: 16 de Mayo de 2011, 22:56:46 »
Hola, que significa el *256??? y que tipo de dato es result[]???

1.for (int i = 0,j=0; i < 64; i+=2,j++)2.           
 {
    result[j] = receive_buf*256+receive_buf[i+1];
 }

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Envio de datos por USB
« Respuesta #9 en: 17 de Mayo de 2011, 09:22:56 »
Hola, que significa el *256??? y que tipo de dato es result[]???

1.for (int i = 0,j=0; i < 64; i+=2,j++)2.           
 {
    result[j] = receive_buf*256+receive_buf[i+1];
 }

 :shock: *256 Es Por 256, o sea multiplicar por 256. Si necesitas armar una variable que proviene de 2 byte de 8-bits, entonces es 8-bits + 8-bits = 16-bits.

Utiliza el buscador, se ha tratado varias veces el tema.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #10 en: 17 de Mayo de 2011, 12:31:32 »
Ok, ya entiendo bueno entonces el método de reconstrucción ya quedó modificado de la siguiente manera:
public long[] Reconstruccion()
      {
          DWORD RecvLength = 64;
          long[] datos_muestreados = new long[32];
          byte* receive_buf = stackalloc byte[64];
          ReciboPaquete(receive_buf, &RecvLength);

          for (int i = 0, j = 0; i < 64; i += 2, j++)
          {
              datos_muestreados[j] = receive_buf * 256 + receive_buf[i + 1];
          }
          return datos_muestreados;
     
Quedó bien definido el método???? El tipo de datos_muestrados[] esta bien???

Saludos

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Envio de datos por USB
« Respuesta #11 en: 17 de Mayo de 2011, 13:33:20 »
16-bits no es short? Yo uso VC++, no VC# por eso la duda. Igual da lo mismo usar 16-bits o 32-bits, el tema es no usar 8-bits porque se trunca.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #12 en: 18 de Mayo de 2011, 01:16:39 »
Muy bien suky ya esta funcionando gracias a tus consejos..... oye si quisiera usar 2 canales analogicos en vez de uno esta bien este procedimiento??

for(e=0;e<64;e++)
                        {                         
                           set_adc_channel(0); //Canal 0 del ADC
                           magnitud = read_adc();
                           magnitudH = make8(magnitud,1); //Byte MSB
                           magnitudL = make8(magnitud,0); //Byte LSB
                           muestras_mag[e++] = magnitudH;
                           muestras_mag[e] = magnitudL;
                           delay_us(20);                                                     
                        }                           
                                                     
                        usb_put_packet(1,muestras_mag,64,USB_DTS_TOGGLE);
                       
                        for(e=0;e<64;e++)
                        {                         
                           set_adc_channel(1); //Canal 1 del ADC
                           fase = read_adc();
                           faseH = make8(fase,1); //Byte MSB
                           faseL = make8(fase,0); //Byte LSB
                           muestras_fase[e++] = faseH;
                           muestras_fase[e] = faseL;
                           delay_us(20);                                                     
                        }                           
                                                     
                        usb_put_packet(1,muestras_fase,64,USB_DTS_TOGGLE);

Saludos

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Envio de datos por USB
« Respuesta #13 en: 18 de Mayo de 2011, 10:49:36 »
Si, es una opción, en la PC debes leer 2 tramas igualmente. Una cosa, has configurado para que el tiempo de adquisición se espere por hardware? Sino hay que colocar una demora de 5us al cambiar canal.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Esau

  • PIC10
  • *
  • Mensajes: 16
Re: Envio de datos por USB
« Respuesta #14 en: 18 de Mayo de 2011, 11:48:17 »
Hola, el tacq fue configurado por hardware:
 
setup_adc(ADC_CLOCK_DIV_64);          //Configuración Reloj de Conversión
 
      #asm
      bsf 0xFC0,7 //Justificación a la derecha
      //Configuración del tiempo de adquisición, taq=2TAD
      bsf 0xFC0,3
      bcf 0xFC0,4
      bcf 0xFC0,5
      #endasm

Esta bien asi???

Me decias en tu ultimo mensaje que la manera en que quería manejar 2 canales analógicos era una posibilidad... existe alguna ora forma?? O a lo que te mande que le falta??

Saludos