TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: WOOD_girl en 09 de Febrero de 2009, 20:30:04
-
hola mis amigos, recurro a ustedes para unas dudas que me aquejan.
resulta que estoy tratando de enviar una señal seno de 60Hz por USB al pc mediante LABVIEW, pero cuando la vizualizo, el conversor en LV solo me entrega los valores picos de la señal obteniendo asi solo una señal triangular pero esta no es periodica, ni constante en amplitud. es por esto que quisiera saber que puedo hacer, ps se ve que es un problema de muestreo, porque tengo un filtro antes dela entrada analogica del pic.
quisiera saber como puedo establecer el periodo de muestreo ps lo unico ke hago es esto:
if (modo == 0) // ADC_Mode
{
while(True)
{
delay_ms(8); // supuestamente el periodo de muestreo
resultado = read_adc();
usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}
}
quisiera saber si alguien me puede ayudar con esto, si ese si es el preiodo de muestreo correcto, cuatas muestras cmo maximo p uede tomar el pic, como puedo configurar el conversor para ke trabaje a la frecuencia de muestreo que quiero, o si puedo hacer algo para que envie mas datos no valores locos .... seria de grana yuda, gracias
-
Hola, para poder ayudarte hacen falta otros datos. Seria bueno que colocaras el programa completo. Otra cosa, los datos del ADC se los asignas a resultado, pero por el USB mandas "envia" cual es la relacion entre estas dos variables? Resultado esta dentro de envia?
Como te dije antes, seria bueno que colocaras el programa completo y hasta la aplicación de LV, por que ahí también puede haber problemas. Saludos.
-
Para garantizar un periodo de muestreo preciso puedes usar el módulo CCP en modo comparación. Cuando el timer1 tenga un valor, el CCP lanzará una interrupción que puedes usar para iniciar una conversión ADC.
-
Yo tengo el mismo problema, puede ser que el usb necesite un tiempo demasiado largo en el envio del dato? Porque lo maximo que he logrado muestrear y enviar es a 100 ms, y no se que modificar en la comunicacion usb para que sea mas rapido.
El firmeware que utilizo es identico al ejemplo que ha hecho j1m, solo que envio consecutivamente como hace WOOD_girl
-
una pregunta ustedes lo simulan en proteus o lo prueban con alguna placa (vida real)...... Si ustedes lo estan simulando, el problema puede ser la velocidad de la simulacion (system->set animation options) en ese caso es el simulador el que les juega una mala pasada....
-
hola a todos, muchas gracias por responder, al igual que suki, el codigo que tengo es el original del programa PIC usb de J1M, sin embargo lo posteo en su totalidad para ke se entienda mejor lo que quiero hacer
#include <18F2550.h>
#device ADC=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VREGEN
#use delay(clock=48000000)
#define USB_HID_DEVICE FALSE
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK
#define USB_EP1_TX_SIZE 1
#define USB_EP1_RX_SIZE 3
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <PicUSB.h> //Configuración del USB y los descriptores para este dispositivo
#include <usb.c> //handles usb setup tokens and get descriptor reports
#define LEDV PIN_B6
#define LEDA PIN_B7
#define LED_ON output_high
#define LED_OFF output_low
#define modo recibe[0]
#define param1 recibe[1]
#define param2 recibe[2]
#define resultado envia[0]
void main(void) {
int8 recibe[3];
int8 envia[1];
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
LED_OFF(LEDV);
LED_ON(LEDA);
usb_init();
usb_task();
usb_wait_for_enumeration();
LED_OFF(LEDA);
LED_ON(LEDV);
while (TRUE)
{
if(usb_enumerated())
{
if (usb_kbhit(1))
{
usb_get_packet(1, recibe, 3);
if (modo == 0) // ADC_Mode
{
while(True)
{
delay_ms(8);
resultado = read_adc();
usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}
}
if (modo == 1) // Modo_Led
{
if (param1 == 0) {LED_OFF(LEDV); LED_OFF(LEDA);}
if (param1 == 1) {LED_ON(LEDV); LED_OFF(LEDA);}
if (param1 == 2) {LED_OFF(LEDV); LED_ON(LEDA);}
}
}
}
}
}
este programa lo probe conun voltaje dc y funciono de maravilla, pero ahora que lo intento con uno A.C pasa lo quepasa, seguire los consejos de migsantiago a ver que pasa y en cuanto a lo que pregunta cerebro, yo hago las pruebas en placa directamente. :(
una duda que me aqueja es si tal vez esta función setup_adc(ADC_CLOCK_INTERNAL); pueda ser configurada para obtener un muestreo mas preciso, o si talvez necesito de una herramienta en LV para que la señal se sincronice y sea mas sincronica, o sera que debo almacenar los datos en algun array???, pero en ese caso, como hago eso??. help!!!!
-
has leido este hilo osciloscopio USB, y en el PC, ¿Labview? (http://www.todopic.com.ar/foros/index.php?topic=2252.0) :)
-
si cerebro, me lo lei de principio a fin, pero no hablan mucho de la adquisición de datos, si no solo de los .dlls y de la creación de las mismas en LV.
-
en el codigo la carita feliz que me sale en el delay es 8mS, por aquello del teorema de nyquist 1/(2*60)= 8.3mS., asi es comose configura el periodo de muestreo? o como?
-
Hola WOOD_girl, probaste muestrear con un periodo menor, unas 10 veces o 20 o 30 o la cantidad necesaria para obtener una calidad razonable para lo que necesitas?
Además el amigo Nyquiest te dice la mínima frecuencia de muestreo que necesitas para que no halla un solapamiento de los espectros.
Haber, cuando se muestrea una señal el espectro de la señal muestreada es periódico respecto al espectro original de la señal a muestrear, como las espectros se repiten para que no halla solapamiento el requisito mínimo y necesario es que la frecuencia de muestreo sea 2 veces la máxima frecuencia de la señal a muestrear. Ahora de que utilizando una frecuencia del doble recuperes la señal como para decir "que hermosa señal senoidal tengo.... :mrgreen:", esta un poco difícil:
Si tenes una señal senoidal de 60Hz, o sea de aproximadamente 16ms de periodo. Entonces en estos 16ms, el seno va variando en todo su esplendor pasando por todos sus valores tanto positivos y negativos. y si de todos esos valores tomas 2, o sea 1 cada 8ms, tu señal puede llegar a ser una continua de cero o una triangular.
Espero que te sirva la explicación.
Saludos
P/D: una vez trabajando en LabView quise muestrear una señal seno pero en modo bulk y la transmisión era bastante lenta....parecía una escalera :shock:.
-
ayyy micro23 no me digas entonces ke en LV es como medio complicado??, gracias por tu ayuda, voy a tratar de mejorar el codigo con los aportes de todos uds, y ya veremos que sucede, muchas gracias!.
-
No digo que sea complicado o facil, el hecho esta en la velocidad de transmicion de datos. Yo si mal no recuerdo la libreria que utilisé en ese momento no me permitía gran velocidad.
Saludos y esperamos tus resultados
-
Hola amigos, como lo prometido es deuda, pues volví con los resultados de sus consejos, en cuanto al programa del PIC, lo modifique de la siguiente manera para ver qué opinan es decir, si estoy haciendo uso correcto de la interrupción por ccp2.
#include <18F2550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN // como uso un cirstal de 4MHz no necesito usar el divisor del pll por eso se pone PLL1
#use delay(clock=48000000)
#define USB_HID_DEVICE FALSE //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 1 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 3 //size to allocate for the rx endpoint 1 buffer
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <PicUSB.h> //Configuración del USB y los descriptores para este dispositivo
#include <usb.c> //handles usb setup tokens and get descriptor reports
#define LEDV PIN_B0
#define LEDA PIN_B1
#define PULSO PIN_B2 // Defino el Pin de control
#define LED_ON output_high
#define LED_OFF output_low
#define modo recibe[0]
#define param1 recibe[1]
#define param2 recibe[2]
#define resultado envia[0]
int1 flagConmuta=0;
int conver;
#int_ccp2
void handle_ccp2_int(){
if(++flagConmuta==1){
setup_ccp2(CCP_COMPARE_CLR_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Bajo
} else{
setup_ccp2(CCP_COMPARE_SET_ON_MATCH); // Configura CCP2 modo COMPARE cambiando a Alto
}
CCP_2=0;
set_timer1(0);
CCP_2 = 41439; // Quiero que se dispare cada 2ms en bajo y 2ms en alto...
// luego pongo los Ticks de TMR1 para ese tiempo.
Output_Toggle(PULSO); // pin de control
conver = Read_ADC();
}
void main(void) {
int8 recibe[3]; //declaramos variables
int8 envia[1];
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_ccp2(CCP_COMPARE_SET_ON_MATCH);
enable_interrupts(int_ccp2);
LED_OFF(LEDV); //encendemos led amariillo
LED_ON(LEDA);
usb_init(); //inicializamos el USB
usb_task(); //habilita periferico usb e interrupciones
usb_wait_for_enumeration(); //esperamos hasta que el PicUSB sea configurado por el host
LED_OFF(LEDA);
LED_ON(LEDV); //encendemos led verde
while (TRUE)
{
if(usb_enumerated()) //si el PicUSB 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 3bytes del EP1 y almacenamos en recibe
if (modo == 0) // ADC_Mode
{
while(True)
{
resultado = conver;
usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}
}
if (modo == 1) // Modo_Led
{
if (param1 == 0) {LED_OFF(LEDV); LED_OFF(LEDA);}
if (param1 == 1) {LED_ON(LEDV); LED_OFF(LEDA);}
if (param1 == 2) {LED_OFF(LEDV); LED_ON(LEDA);}
}
}
}
}
}
Pero lastimosamente los resultados en labview no fueron los esperados como se puede ver en el archivo adjunto, ahora en vez de tomar una señal triangular solo obtengo una señal bastante irregular, ahora si quede más perdida aun, si supuestamente trabaja en modo bulk no se por qué pareciera que los datos se demoran para llegar al lbaview.
Otra cosa es que yo puse la interrupción para 4mS, pero la monitoreo mediante un pulso por RB2 y resulta que esta a 6ms, entonces no sé como calcular un tiempo exacto en lenguaje C. alguna idea?, gracias por su ayuda muchachos, bye
-
Intenta de enviar pedido de medida desde el software hecho en LabView con ese mismo periodo, en vez de enviar continuamente desde el PIC. Haber si te funciona de esa manera.
-
uyyy tiempo sin pasar por aqui, gracias suki portu consejo, voy a mirarlo a ver que sucede
gracias!
-
muchas gracias atodos por sus consejos!, mi error mas que en el codigo, era problema del labview, estaba llamando mal la libreria.
-
Hola WOOD_gir podria aclarar como solucionaste el problema, o mejor dicho como se usa la libreria para que funvione correctamente?
Probaste hasta que frecuencia podes muestrear señales?
Saludos
-
cual es tu problema?, el mio era que estaba enviando un array, pero en el labview tenia declarada la variable que recibia los datos como int8, entonces no me llegaban los datos completos, cambien esto poniendo en library node un array de 32bit, y listo, ya me sirvio, no he mirado hasta que punto puedo muestrear señales, pero creo que eso viene delimitado es por el pic, yo trabajo a 60Hz y por eso no mire ese aspecto.