Autor Tema: 4-20mA Current Loop (SOLUCIÓN AD420)  (Leído 9367 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop
« Respuesta #15 en: 04 de Febrero de 2008, 12:04:27 »
Todavía no he recibido los AD420 pero tranquilos que os manetndré inforamdos de todo.

Un par de preguntas más. Cómoconecto dos AD420 a un mismo SPI? Puedo compartir reloj y datos y sólo utilziar el LACTH para validar los datos en uno u otro AD420?

Por otro lado tengo un "problemilla" de resoluciones. La entrada la capturo con el ADC del PIC a 8bits. Y al AD420 le tengo que enviar un valor en 16bits por lo que mis saltos en valores del AD420 serán de 256 en 256, es decir, si el valor del ADC es 50 el que le mando al AD420 es de 50*256 cosa que me da un salto en corriente de salida de 0,062464mA -> 0,0624mA/(20mA-4mA)=0,4% de error, es correcto?

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7865
Re: 4-20mA Current Loop
« Respuesta #16 en: 04 de Febrero de 2008, 13:06:05 »
Porque no utilizas el conversor a 10 bits, si usas un 16F eso es posible y tienes 4 veces mas resolucion!!
Por lo demas, debes enviar los valores al AD420 usando una regla de conversion del dato, escalandolo de 10 a 16 bits...

Respecto a como conectar varios DAC AD420, en la hoja de datos dicen que es asi:   :mrgreen: :mrgreen:

Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop
« Respuesta #17 en: 04 de Febrero de 2008, 15:25:14 »
OK!! Gracias!! Lo tenía delante!! Para mandar los 32 bits que dice que hay que mandar puedo seguir utilizando la misma rutina incluyendo en lugar de (int16 dato) -> (int16 Dato1, int 16 Dato2) y enviando uno después del otro, no?

Nunca he usado los 10 bits del ADC por la facilidad de tratarlo todo como int8 pero supongo que la mejor forma es aprovecharlo. Ya os contaré!!

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #18 en: 19 de Febrero de 2008, 15:48:00 »
Bueno, pues ya me han llegado los AD420 y he podido trastear un poquito con ellos.

El código que os adjunto va incrementando la variable 'val' de 500 en 500 y la va enviando por SPI al AD420. A la salida del loop del AD420 tengo una resistencia de 200 ohmios en la que se ve la caída de tensión producida por la corriente.

Al empezar el téster marca 0,80V clavados y va aumentando poco a poco. No lo he mirado mucho pero al llegar a medio rango (2,4V) se me reinicia y vuelve a 0,80... seguiré investigando.

Código: [Seleccionar]
#include <16F818.h>                                //PIC a utilizar

#fuses XT                                          //configuracion de fusibles
#fuses NOWDT
#fuses PROTECT
#fuses PUT
#fuses NOBROWNOUT
#fuses MCLR
#fuses NOLVP
#fuses CPD
#fuses NOWRT
#fuses NODEBUG

#use delay (clock=4000000)
#use fast_io(a)

#define LED          PIN_A1                        //LED de funcionamiento
#define AD420_LATCH  PIN_B3


void main(void)
{
   int16 val=0;

   disable_interrupts(GLOBAL);                     //deshabilitar interrupciones
   disable_interrupts(INT_EEPROM);                 //deshabilitar interrupcion EEPROM
   disable_interrupts(INT_RB);                     //deshabilitar interrupcion portb
   disable_interrupts(INT_TIMER0);                 //deshabilitar interrupcion del timer0
   disable_interrupts(INT_TIMER1);                 //deshabilitar interrupcion timer1
   disable_interrupts(INT_TIMER2);                 //deshabilitar interrupcion timer2
   disable_interrupts(INT_CCP1);                   //deshabilitar interrupcion CCP1
   disable_interrupts(INT_SSP);                    //deshabilitar interrupcion I2C / SPI
   disable_interrupts(INT_AD);                     //deshabilitar interrupcion ADC
   disable_interrupts(INT_EXT);                    //deshabilitar interrupcion RB0

   setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_1);      //preescaler=1
   setup_TIMER_1(T1_DISABLED);                     //desactivar timer1
   setup_TIMER_2(T2_DIV_BY_1,255,16);              //preescaler=16
   setup_CCP1(CCP_OFF);                            //desactivar modulo captura
   setup_SPI(spi_master | SPI_L_TO_H | SPI_CLK_DIV_16);
   setup_ADC_PORTS(AN0);                           //entradas analogicas
   setup_ADC(ADC_CLOCK_INTERNAL);                  //activar modulo ADC

   set_tris_a(0b00000000);                         //porta todo como salida
   set_tris_b(0b00000010);

   ext_int_edge(H_TO_L);                           //interrupcion externa en flanco de bajada

   port_b_pullups(TRUE);                           //pullups portb activadas

   enable_interrupts(GLOBAL);                      //interrupciones activadas

   delay_ms(1000);

   do
   {
      output_toggle(LED);

      output_low(AD420_LATCH);

      spi_write(val >> 8);                         // Send msb
      spi_write(val & 0xFF);                       // Send lsb

      output_high(AD420_LATCH);

      delay_ms(1000);
      val=val+500;

   }while(TRUE);
}

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7865
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #19 en: 19 de Febrero de 2008, 15:56:56 »
Podras poner aqui el esquema del circuito que usas, al menos una imagen de un esquema a mano sirve...
Asi podremos ser de mas ayuda... :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #20 en: 19 de Febrero de 2008, 16:04:31 »
Me marcho ya del despacho, pero mañana la pongo. Básicamente es la configuración del Datasheet con los condensadores que pide. Luego tengo el Data_In del AD420 a la salida SPI del PIC, el reloj igual y luego utilizo el pin B3 para hacer de Latch del AD420.

Lo raro es que si directamente le digo al PIC que envíe el valor 0xFFFF el AD420 se pone de inmediato a 4,0V de salida.

Debe de haber algún error tonto en el código.

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7865
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #21 en: 19 de Febrero de 2008, 16:10:20 »
Estas seguro que hay que enviar primero el MSB ?? :mrgreen:

Verificalo en la hoja de datos...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #22 en: 20 de Febrero de 2008, 06:24:14 »
Según veo en el Datasheet va primero el MSB:



Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #23 en: 20 de Febrero de 2008, 07:03:14 »
Más o menos voy viendo por dónde van los tiros. Con el código siguiente primero le mando 0x0000 para que la salida de ponga a 0,80V (4mA) y luego le mando 0xFFFF para que se ponga a 4,0V (20mA). Lo que físicamente observo es que la salida empieza a 0,80V, luego mando el 0xFFFF y la salida pasa a la mitad del rango (2,4V) y la siguiente vez si que se pone a los 4,0V.

Parece como si entre medio hubiese algo que no lo entiende.

Código: [Seleccionar]
#include <16F818.h>                                //PIC a utilizar

#fuses XT                                          //configuracion de fusibles
#fuses NOWDT
#fuses PROTECT
#fuses PUT
#fuses NOBROWNOUT
#fuses MCLR
#fuses NOLVP
#fuses CPD
#fuses NOWRT
#fuses NODEBUG

#use delay (clock=4000000)
#use fast_io(a)

#define LED          PIN_A1                        //LED de funcionamiento
#define AD420_LATCH  PIN_B3


void main(void)
{
   int16 val=0;

   disable_interrupts(GLOBAL);                     //deshabilitar interrupciones
   disable_interrupts(INT_EEPROM);                 //deshabilitar interrupcion EEPROM
   disable_interrupts(INT_RB);                     //deshabilitar interrupcion portb
   disable_interrupts(INT_TIMER0);                 //deshabilitar interrupcion del timer0
   disable_interrupts(INT_TIMER1);                 //deshabilitar interrupcion timer1
   disable_interrupts(INT_TIMER2);                 //deshabilitar interrupcion timer2
   disable_interrupts(INT_CCP1);                   //deshabilitar interrupcion CCP1
   disable_interrupts(INT_SSP);                    //deshabilitar interrupcion I2C / SPI
   disable_interrupts(INT_AD);                     //deshabilitar interrupcion ADC
   disable_interrupts(INT_EXT);                    //deshabilitar interrupcion RB0

   setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_1);      //preescaler=1
   setup_TIMER_1(T1_DISABLED);                     //desactivar timer1
   setup_TIMER_2(T2_DIV_BY_1,255,16);              //preescaler=16
   setup_CCP1(CCP_OFF);                            //desactivar modulo captura
   setup_SPI(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);
   setup_ADC_PORTS(AN0);                           //entradas analogicas
   setup_ADC(ADC_CLOCK_INTERNAL);                  //activar modulo ADC

   set_tris_a(0b00000000);                         //porta todo como salida
   set_tris_b(0b00000010);

   ext_int_edge(H_TO_L);                           //interrupcion externa en flanco de bajada

   port_b_pullups(TRUE);                           //pullups portb activadas

   enable_interrupts(GLOBAL);                      //interrupciones activadas

   delay_ms(1000);
   output_low(LED);

   do
   {
      output_toggle(LED);

      output_low(AD420_LATCH);

      spi_write(val >> 8);                         // Send msb
      spi_write(val & 0xFF);                       // Send lsb

      output_high(AD420_LATCH);

      val=65535;
      delay_ms(8000);

   }while(TRUE);
}

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #24 en: 20 de Febrero de 2008, 07:28:37 »
Subo el esquema para quien quiera utilizarlo:



Una pregunta más, alguien sabe cómo puedo saber si el SPI debe ir SPI_L_TO_H o SPI_H_TO_L??

Gracias!!

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #25 en: 20 de Febrero de 2008, 07:36:43 »
SOLUCIONADO Y FUNCIONANDO!!

Me respondo a mi mismo. El AD420 requiere que el SPI se configure con el SPI en SPI_H_TO_L.

Ahora el programa ese que va incrementando val de 500 en 500 funciona perfectamente y con una precisión extraordinaria.

Espero que os pueda servir para vuestros proyectos.

Un saludo!!

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7865
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #26 en: 20 de Febrero de 2008, 08:16:36 »
Felicitaciones!!
Ahora si que me animo a usarlo yo!! :D :D
Me alegro que hayas llegado a buen termino. :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #27 en: 20 de Febrero de 2008, 08:28:18 »
La verdad es que temía bastante que el tema del SPI me amargara pero por suerte en la primera prueba que hice conseguí que el AD420 respondiera, mal pero respondiera. A partir de ahí ha sido ir depurando el fallo.

Me ha sorprendido la facilidad de uso del SPI. Con 4 líneas lo tienes enviando lo que quieras. Ahora sólo me falta hacer la prueba de enlazar los dos AD420 en serie a ver si consigo que ambos respondan correctamente.

Un saludo!!

Desconectado DarkVect

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 302
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #28 en: 21 de Febrero de 2008, 08:58:50 »
Comentar que ya tengo los 2 AD420 en serie y todo va de maravilla. El proceso sigue el mismo esquema que con uno, simplemente hay que transmitir 32 bits en lugar de los 16 y ya está.

Un saludo!!

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7865
Re: 4-20mA Current Loop (SOLUCIÓN AD420)
« Respuesta #29 en: 21 de Febrero de 2008, 09:05:44 »
Bravo !!! :-/ :-/
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.