TODOPIC
Mecatrónica => UAV => Mensaje iniciado por: elgarbe en 11 de Febrero de 2014, 00:00:36
-
Todo UAV, si es eléctrico, debe tener un módulo para medir la corriente instantanea consumida, un totalizar, un indicador de tension de batería y si es posible un medidor de potencia.
En este caso estoy diseñando dicho módulo usando el INA219 de TI. Debido a que ofrecen muestras gratis de este componente es que tengo un par guardados.
Bueno, por ahora estoy trabajando con el diseño de un PCB básico para el testeo del mismo:
Lamentablemente imageshak ya no es mas gratuito y para subir imágenes hay que pagar.... dejo en adjunto las imágenes del esquemático y del pcb que voy a probar.
Saludos!
-
Bueno, hoy pude empezar con la placa:
(http://farm6.staticflickr.com/5507/12469262933_2ddd2686e3_z.jpg) (http://www.flickr.com/photos/117247358@N03/12469262933/)
aquí vemos el CI con los componentes y aquí algunas fotos de la placa armada:
(http://farm4.staticflickr.com/3805/12469256773_2c42f23698_z.jpg) (http://www.flickr.com/photos/117247358@N03/12469256773/)
bueno, a conectar al LPC1769 y a empezar a jugar. Ya iré comentando como me va.
Saludos!
-
Buena iniciativa con ese medidor, estare pendiente :mrgreen:
-
Una pregunta:
En el esquema figuran 10 resistencias en paralelo de 1/2 Watt.
Asumo que es un shunt para medir corriente.
Pero en el armado pusiste solo 5 de aparentemente 1/4 watt.
Como es el calculo ??
-
Hola, Marcos, como andas?
La idea es poner 10 resistencias de 0.1ohm 1% 1/2w o 1 w metal film (más pequeñas).
El tema es que no las tengo todavía, mañana viajo a capital y espero conseguirlas. Entonces para probar comunicacion con el INA y hacer alguna que otra lectura puse esas 5 de .82ohm, pero será solo para pruebas.
he visto resistencias shunt de presicion del orden de 0.01 ohm en la web. No sabes si se conseguirán en argentina?
esta parte aún no la he estudiado bien, pero tengo que medir corrientes de unos 30 amp (en el quadricoptero), por lo que con 0.01ohm tengo una perdida de 9 watt. 30 amp a 7.4 volts son 222wats... perdería un 4% en la medicion de corriente... no me gusta mucho... tengo a medio armar un sistema para medir corriente con un sensor de efecto hall y toroide partido... ya voy a ver que sistema implemento... en caso de un avion RC el consumo esta en el orden de 6-7A con lo que tendría 500mw de perdidas... en ese caso me vendría bien este sistema...
Saludos!
PD: anoche estuve hasta la 1 de la mañana porque no podía comunicarme con el INA... ya medio dormido me di cuenta que en la hoja de datos estan la identificacion de pines de los dos encapsulados, sot23 de 8 pines y soic8... estan espejados uno de otro... yo use el del sot23!!!!! puse el INA patas pa'rriba y ya me comunique... ahora hay que leer datos...
-
Lamentablemente imageshak ya no es mas gratuito y para subir imágenes hay que pagar.... dejo en adjunto las imágenes del esquemático y del pcb que voy a probar.
Imageshack siempre ha sido una chufa, cuando era gratuito perdía montones de fotos, yo lo dejé de usar hace tiempo porque cada 2x3 me desaparecían muchas fotos y los post se me quedaban huérfanos sin las fotos a las que se refería el texto. Solo espero, que las fotos que se subieron cuando era gratuito, no se las carguen, porque entonces si que es para pegarles fuego, tengo montones de post en varios foros, con fotos subidas a Imageshack
Tienes otras alternativas gratuitas, como Tinypic o Photobucket, que además son mucho más fiables y funcionan mejor que la difunta Imageshack, yo actualmente uso sobre todo Tinypic y va fenomenal.
salu2
-
Lamentablemente imageshak ya no es mas gratuito y para subir imágenes hay que pagar.... dejo en adjunto las imágenes del esquemático y del pcb que voy a probar.
Imageshack siempre ha sido una chufa, cuando era gratuito perdía montones de fotos, yo lo dejé de usar hace tiempo porque cada 2x3 me desaparecían muchas fotos y los post se me quedaban huérfanos sin las fotos a las que se refería el texto. Solo espero, que las fotos que se subieron cuando era gratuito, no se las carguen, porque entonces si que es para pegarles fuego, tengo montones de post en varios foros, con fotos subidas a Imageshack
Tienes otras alternativas gratuitas, como Tinypic o Photobucket, que además son mucho más fiables y funcionan mejor que la difunta Imageshack, yo actualmente uso sobre todo Tinypic y va fenomenal.
salu2
lo voy a tener en cuenta, empecé a usar flickr ya que es super conocido y espero no pase a la historia.
saludos!
-
La idea es poner 10 resistencias de 0.1ohm 1% 1/2w o 1 w metal film (más pequeñas).
El tema es que no las tengo todavía, mañana viajo a capital y espero conseguirlas. Entonces para probar comunicacion con el INA y hacer alguna que otra lectura puse esas 5 de .82ohm, pero será solo para pruebas.
he visto resistencias shunt de presicion del orden de 0.01 ohm en la web. No sabes si se conseguirán en argentina?
esta parte aún no la he estudiado bien, pero tengo que medir corrientes de unos 30 amp (en el quadricoptero), por lo que con 0.01ohm tengo una perdida de 9 watt. 30 amp a 7.4 volts son 222wats... perdería un 4% en la medicion de corriente... no me gusta mucho... tengo a medio armar un sistema para medir corriente con un sensor de efecto hall y toroide partido... ya voy a ver que sistema implemento... en caso de un avion RC el consumo esta en el orden de 6-7A con lo que tendría 500mw de perdidas... en ese caso me vendría bien este sistema...
Saludos!
PD: anoche estuve hasta la 1 de la mañana porque no podía comunicarme con el INA... ya medio dormido me di cuenta que en la hoja de datos estan la identificacion de pines de los dos encapsulados, sot23 de 8 pines y soic8... estan espejados uno de otro... yo use el del sot23!!!!! puse el INA patas pa'rriba y ya me comunique... ahora hay que leer datos...
no conocía ese sensor, la útlima vez que medí corriente solo use una shunt con un seguidor y directo al pic :shock:, gracias por el dato.
en cuanto a la resistencia, si no consigues una shunt con facilidad tal vez puedas sacarle una a un multimetro de los baratos
-
en cuanto a la resistencia, si no consigues una shunt con facilidad tal vez puedas sacarle una a un multimetro de los baratos
muy buena idea, me parece que por ahí vendra el tema...
Saludos!
-
Utiliza mejor un shunt de 1 miliohmio o menos.
El INA219 acepta diferencias de tensión de +-40 milivoltios sin problema.
Cuando circulen 30 amperios, la potencia en la resistencia de 1 miliohmio será de 0.9 vatios.
Para hacer el shunt, sólo necesitas tomar la tensión de dos puntos del cable de alimentación.
Con un cable de cobre de 3mm de diámetro y 20 centímetros de longitud, tienes una resistencia de 0.5 miliohmios y puede aguantar 30 Amperios.
El INA daría una resolución de 20 miliamperios.
Saludos.
-
Utiliza mejor un shunt de 1 miliohmio o menos.
El INA219 acepta diferencias de tensión de +-40 milivoltios sin problema.
Cuando circulen 30 amperios, la potencia en la resistencia de 1 miliohmio será de 0.9 vatios.
Para hacer el shunt, sólo necesitas tomar la tensión de dos puntos del cable de alimentación.
Con un cable de cobre de 3mm de diámetro y 20 centímetros de longitud, tienes una resistencia de 0.5 miliohmios y puede aguantar 30 Amperios.
El INA daría una resolución de 20 miliamperios.
Saludos.
mejor aún ((:-))
-
Con un cable de cobre de 3mm de diámetro y 20 centímetros de longitud, tienes una resistencia de 0.5 miliohmios y puede aguantar 30 Amperios.
El INA daría una resolución de 20 miliamperios.
Saludos.
Una pregunta ¿Influye que este cable de 3mm de diametro y 20 cm de lo longitud este alargado o este bobinado como si fuera una resistencia bobinada?
Gracias!
-
Hace tiempo ocupe este sensor "ACS758 (http://www.allegromicro.com/en/Products/Current-Sensor-ICs/Fifty-To-Two-Hundred-Amp-Integrated-Conductor-Sensor-ICs/ACS758.aspx)"
-
Aqui en Argentina se consigue en ML a solo 30 dolares !! :D :D :D
O en OpenHacks a solo 26 dolares !!
Imposible de usar !!
-
Hace tiempo ocupe este sensor "ACS758 (http://www.allegromicro.com/en/Products/Current-Sensor-ICs/Fifty-To-Two-Hundred-Amp-Integrated-Conductor-Sensor-ICs/ACS758.aspx)"
esos ACS son carísimos, pero aparte algo raro tiene que haber, nunca lei la hoja de datos en detalles, pero no creo que pueda medir corrientes pequeñas...
el ina lo que tiene de bueno es que tiene sensibilidad configurable entre +-40mV y 320mV, entonces podes medir en un rango amplio de corrientes.
Anoche consegui medir la V shunt, pero al querer medir la Vbus no obtenia buenas lecturas. Tengo que revisar la parte de filtro de en Vin+ y Vin- ya que yo no tengo puesto nada. En la hoja de datos recomienda no poner nada y empezar a probar la comunicación (con la programacion por defecto) y luego ir agregando filtro, programacion, etc.
Otra cosa que tengo que ver es si puedo poner un Shunt de cualquier medida y luego hacer la calibracion interna... la verdad tengo que leer bien la hoja de datos, ya cuando tenga todo un poco más pulido empezaré a leer bien y a postear lo que valla aprendiendo...
Saludos!
-
Yo pensaba usar un MCP6S26 (http://ww1.microchip.com/downloads/en/DeviceDoc/21117B.pdf) de microchip, que les parece?
Es mejor o peor que el INA ??
-
Yo pensaba usar un MCP6S26 (http://ww1.microchip.com/downloads/en/DeviceDoc/21117B.pdf) de microchip, que les parece?
Es mejor o peor que el INA ??
sin haber estudiado demasiado los dos, te diría que el TI es mejor. En realidad, el de microchip no es una unidad de medicion, es un amplificador de ganancia programable, al cual lo podes usar para medir tension en un shunt y obtener la corriente. Pero todos los cálculos los tenes que hacer vos. En cambio el INA es una unidad de medicion, diseñado específicamente para eso. Tiene varios registros internos para calibracion de la Rshunt y por el I2C podes obtener lectura directa de tension de shunt, tension de bus, corriente y potencia. El INA tiene un PGA interno + una lógica integrada para el càlculo de I, V y P. Probablemnte las caracyerísticas del PGA de microchip sean mejores que las del INA... yo me quedo con el INA (aparte tiene muestras gratis para testeo :-/)
Saludos!
-
Con un cable de cobre de 3mm de diámetro y 20 centímetros de longitud, tienes una resistencia de 0.5 miliohmios y puede aguantar 30 Amperios.
El INA daría una resolución de 20 miliamperios.
Saludos.
Una pregunta ¿Influye que este cable de 3mm de diametro y 20 cm de lo longitud este alargado o este bobinado como si fuera una resistencia bobinada?
Gracias!
no afecta, la resistencia del alambre será la misma si está embobinado o no
-
Te recomiendo que uses solo una shunt puesto que varias shunts puede producir un error de lectura dependiendo de en que punto hagas la medicion, ademas de variar mucho el % de error debido a que son varias no solo una.
-
Una pregunta ¿Influye que este cable de 3mm de diametro y 20 cm de lo longitud este alargado o este bobinado como si fuera una resistencia bobinada?
Gracias!
Si lo bobinas tendrá más inductancia y puede dar lecturas falsas cuando la corriente varíe.
Lo mejor es doblarlo por la mitad y bobinar los dos hilos doblados a la vez. La inductancia que aporta un trozo de hilo, lo quitará el otro trozo de hilo.
Saludos.
-
Yo pensaba usar un MCP6S26 (http://ww1.microchip.com/downloads/en/DeviceDoc/21117B.pdf) de microchip, que les parece?
Es mejor o peor que el INA ??
Aunque sea rail to rail, no vale para tensiones mayores que la alimentación.
Para medir diferencias de tensión con tensiones mayores de Vcc, se utilizan los amplificadores diferenciales para medición de corriente:
http://www.analog.com/en/specialty-amplifiers/current-sense-amplifiers/products/index.html#Current_Sense_Amplifiers
(http://www.analog.com/static/imported-files/images/functional_block_diagrams/AD8217_fbs.png)
(Analog Devices manda samples)
Saludos.
-
Otro circuito similar con filtro emi:
AD8208 (http://www.analog.com/en/power-management/power-monitors/ad8208/products/product.html)
(http://www.analog.com/static/imported-files/images/functional_block_diagrams/AD8208_fbs.png)
Saludos.
-
Gracias a los dos por la aclaración.
Saludos!
-
Estos circuitos sirven para medir corriente sobre un shunt.
Para medir tensión puedes utilizar un divisor resistivo.
La potencia puedes calcularla dentro del micro, multiplicando tensión por corriente.
Saludos.
-
Estos circuitos sirven para medir corriente sobre un shunt.
Para medir tensión puedes utilizar un divisor resistivo.
La potencia puedes calcularla dentro del micro, multiplicando tensión por corriente.
Saludos.
es necesario medir la tensión?, la potencia también se puede sacar de la resistencia y la corriente
-
Yo pensaba usar un MCP6S26 (http://ww1.microchip.com/downloads/en/DeviceDoc/21117B.pdf) de microchip, que les parece?
Es mejor o peor que el INA ??
Aunque sea rail to rail, no vale para tensiones mayores que la alimentación.
Para medir diferencias de tensión con tensiones mayores de Vcc, se utilizan los amplificadores diferenciales para medición de corriente:
http://www.analog.com/en/specialty-amplifiers/current-sense-amplifiers/products/index.html#Current_Sense_Amplifiers
(http://www.analog.com/static/imported-files/images/functional_block_diagrams/AD8217_fbs.png)
(Analog Devices manda samples)
Saludos.
esto es si no se puede usar la mediocion en el Low side. Si podes medir en el GND no te molesta la tension de alimentacion. Lo bueno del INA219 es que es para high side, o sea en el positivo de la alimentacion lo cual evita el pequeño desbalance de GND que se puede producir al medir en el low side.
siempre me gusto más texas... quizá porque tiene muestras gratis en Argentina?:
http://www.ti.com/lsds/ti/amplifiers-linear/current-shunt-monitor-products.page
y la explicacion de que tipo de sensor usar en cada caso:
http://www.ti.com/lit/slyb194
PD: Analog no manda (o nomandaba a Argentina)
Saludos!
-
Estos circuitos sirven para medir corriente sobre un shunt.
Para medir tensión puedes utilizar un divisor resistivo.
La potencia puedes calcularla dentro del micro, multiplicando tensión por corriente.
Saludos.
es necesario medir la tensión?, la potencia también se puede sacar de la resistencia y la corriente
sacarías la potencia que disipa el shunt, pero no la que dicipa la carga ;-)
Saludos!
-
Estos circuitos sirven para medir corriente sobre un shunt.
Para medir tensión puedes utilizar un divisor resistivo.
La potencia puedes calcularla dentro del micro, multiplicando tensión por corriente.
Saludos.
es necesario medir la tensión?, la potencia también se puede sacar de la resistencia y la corriente
sacarías la potencia que disipa el shunt, pero no la que dicipa la carga ;-)
Saludos!
Cierto!! :oops:, no se porque me perdí del tema y me olvide que lo que lo que queremos es la potencia del circuito completo
-
Bueno, volviendo al tema que nos compete, el INA219, jeje
aquí una foto de la medicion obtenida vs mi tester chino:
(http://farm6.staticflickr.com/5532/12501819815_aedb143b9c_z.jpg) (http://www.flickr.com/photos/117247358@N03/12501819815/)
aquí otra:
(http://farm8.staticflickr.com/7406/12501804395_9cb18a9cb0_z.jpg) (http://www.flickr.com/photos/117247358@N03/12501804395/)
lo que marca el ide del lpcxpresso es la tension en mV multiplicado por 100. notar que hay una diferencia de unos 2 a 4 mV en las mediciones. Se lo atribuyo a ruido ya que no tengo puesto el filtro de entrada del INA y la diferencia entre donde mide el tester y donde mide el INA o bien el tester chino... a la noche si puedo pruebo con el fluke
ya iremos viendo como mejorar eso y que vamos obteniendo.
Saludos!
-
Alguien se anima a adivinar por que obtengo estas mediciones?
(http://farm4.staticflickr.com/3826/12529663533_0db662dc83_z.jpg) (http://www.flickr.com/photos/117247358@N03/12529663533/)
como ven tengo 7 u 8 mediciones buenas y luego 2 o 3 mediciones "malas"... estoy tomando la V de shunt, con la configuracion por defecto y mido 1 vez por segundo...
Le tengo miedo al drive del I2C del LPCXpresso... estoy viendo por todos lados que ese drive esta lleno de bugs... pero lo raro es que ese mismo drive lo estoy usando para otros sensores y funciona...
Saludos!
-
Hoy es mi día de suerte! ya probe con exito el OSD y ahora me puse otra vez con la medicion con el INA219.
Lo último que postie fue que no estaba midiendo bien, que habia variaciones en la medicion y estaba estancado en eso... bueno, hoy pensando un poco descubrí el error. El tema es que no estaba conectando el GND de la fuente de "potencia" con el GND del INA219. Por eso las mediciones erroneas.
Bien, solucionado eso, me puse con la configuracion de la calibracion para poder medir corriente y potencia.
En la hoja de datos está toda la serie de cálculos que hay que ir haciendo para obtener el valor de calibracion. Como aún no tengo el shunt definitivo, hice los cálculos a mano en papel mas o menos, como para medir algo. Cuando tenga el shunt definitivo ahí mostraré como hacer bien los cálculos.
Veamos entonces como quedó el código de mi uC:
main.c
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
volatile uint32_t msTicks;
__INLINE static void delay_ms (uint32_t delayTicks) {
uint32_t currentTicks;
currentTicks = msTicks; // read current tick counter
while ((msTicks - currentTicks) < delayTicks);
}
#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "uart2.h"
#include <stdio.h>
#include "i2c.h"
#include "INA219.h"
void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}
/*******************************************************************************
** Main Function main()
*******************************************************************************/
int main (void){
signed short data=0;
unsigned char resultado=0;
//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000000)) {
while (1);
}
I2C1Init(); // Inicializo el I2C1
UART2_Init(115200); // Inicializo el UART a 115200
UART2_PrintString ("\r\nINA219\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");
INA219_write_reg(INA219_REG_CALIBRATION, 2560);
resultado=INA219_read_reg(INA219_REG_CALIBRATION, &data);
UART2_PrintString("\r\nConfiguracion: ");
uart2_printUint32(data, 10);
delay_ms(2000000);
while ( 1 ){
resultado=INA219_read_reg(INA219_REG_SHUNTVOLTAGE, &data);
UART2_PrintString("\r\nTens. sht: ");
uart2_printDouble(data/10000.0, 3);
delay_ms(2000);
resultado=INA219_read_reg(INA219_REG_BUSVOLTAGE, &data);
UART2_PrintString("V\tTens. bus: ");
uart2_printDouble(data/1000.0, 3);
delay_ms(2000);
resultado=INA219_read_reg(INA219_REG_POWER, &data);
UART2_PrintString("V\tPot : ");
uart2_printDouble(data/1000.0, 3);
delay_ms(2000);
resultado=INA219_read_reg(INA219_REG_CURRENT, &data);
UART2_PrintString("W\tCorr : ");
uart2_printDouble(data/10000.0, 3);
UART2_PrintString("A");
delay_ms(300000);
}
}
Como primer dato, la funcion delay_ms es en realidad delay_us, tengo configurado el SysTick para 1useg.
Bueno, luego de inicializar los buses, grabo el registro de calibracion del INA con el valor 2560. Luego lo leo para verificar que se alla almacenado y de paso para mostrarlo en el terminal.
Luego en el bucle infinito llamo a la funcion de leer registros del INA y le paso la direccion de la variable como puntero. Luego divid por 1000 o 10000 dependiendo el caso y muestro los valores.
El resultado:
(https://s3.yimg.com/so/7376/12667250584_a0a79d60be_z.jpg) (http://www.flickr.com/photos/117247358@N03/12667250584/)
Bueno, ya van quedando los módulos de a poco... ahora hay que empezar a juntar cosas!
Salludos!
-
Me parece a mi o la potencia es la mitad de la que debería ser????....
-
Podrías compartirme las librerías del INA219 en C ??
Voy a trabajar en CCS para PIC, pero igual me ahorras trabajo... ;-)
-
Marcos, está lejos de ser una librería!!! te dejo el código que estoy usando.
INA219.h
#ifndef INA219_H_
#define INA219_H_
#include "i2c.h"
extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define INA219_WRITE_ADDR (0x80) // 1000000 (A0+A1=GND)
#define INA219_READ_ADDR (0x81)
/*=========================================================================*/
/*=========================================================================
CONFIG REGISTER (R/W)
-----------------------------------------------------------------------*/
#define INA219_REG_CONFIG (0x00)
/*---------------------------------------------------------------------*/
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
/*=========================================================================*/
/*=========================================================================
SHUNT VOLTAGE REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_SHUNTVOLTAGE (0x01)
/*=========================================================================*/
/*=========================================================================
BUS VOLTAGE REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_BUSVOLTAGE (0x02)
/*=========================================================================*/
/*=========================================================================
POWER REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_POWER (0x03)
/*=========================================================================*/
/*=========================================================================
CURRENT REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_CURRENT (0x04)
/*=========================================================================*/
/*=========================================================================
CALIBRATION REGISTER (R/W)
-----------------------------------------------------------------------*/
#define INA219_REG_CALIBRATION (0x05)
/*=========================================================================*/
#define PORT_USED 1
void INA219_init();
unsigned char INA219_read_reg(unsigned char reg, signed short *value);
unsigned char INA219_write_reg(unsigned char reg_address, unsigned short value);
unsigned char INA219_read_reg(unsigned char reg, signed short *value){
int i;
for ( i = 0; i < BUFSIZE; i++ )
{
I2CSlaveBuffer[PORT_USED][i] = 0x00;
}
unsigned char result=0;
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 2;
I2CMasterBuffer[PORT_USED][0] = INA219_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg;
I2CMasterBuffer[PORT_USED][2] = INA219_READ_ADDR;
result=I2CEngine(PORT_USED);
*value = ((I2CSlaveBuffer[PORT_USED][0] << 8) | I2CSlaveBuffer[PORT_USED][1]);
if (reg == INA219_REG_BUSVOLTAGE){
*value = (*value >> 3) * 4;
}
return(result);
}
unsigned char INA219_write_reg(unsigned char reg_address, unsigned short value){
I2CWriteLength[PORT_USED] = 4;
I2CReadLength[PORT_USED] = 0;
I2CMasterBuffer[PORT_USED][0] = INA219_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg_address;
I2CMasterBuffer[PORT_USED][2] = ((value >> 8) & 0xFF);
I2CMasterBuffer[PORT_USED][3] = (value & 0xFF);
return(I2CEngine( PORT_USED ));
}
#endif /* INA219_H_ */
main.c
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
volatile uint32_t msTicks;
__INLINE static void delay_ms (uint32_t delayTicks) {
uint32_t currentTicks;
currentTicks = msTicks; // read current tick counter
while ((msTicks - currentTicks) < delayTicks);
}
#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "uart2.h"
#include <stdio.h>
#include "i2c.h"
#include "INA219.h"
void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}
/*******************************************************************************
** Main Function main()
*******************************************************************************/
int main (void){
signed short data=0;
unsigned char resultado=0;
//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000000)) {
while (1);
}
I2C1Init(); // Inicializo el I2C1
UART2_Init(115200); // Inicializo el UART a 115200
UART2_PrintString ("\r\nINA219\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");
INA219_write_reg(INA219_REG_CALIBRATION, 2560);
resultado=INA219_read_reg(INA219_REG_CALIBRATION, &data);
UART2_PrintString("\r\nConfiguracion: ");
uart2_printUint32(data, 10);
delay_ms(2000000);
while ( 1 ){
resultado=INA219_read_reg(INA219_REG_SHUNTVOLTAGE, &data);
UART2_PrintString("\r\nTens. sht: ");
uart2_printDouble(data/10000.0, 3);
delay_ms(2000);
resultado=INA219_read_reg(INA219_REG_BUSVOLTAGE, &data);
UART2_PrintString("V\tTens. bus: ");
uart2_printDouble(data/1000.0, 3);
delay_ms(2000);
resultado=INA219_read_reg(INA219_REG_POWER, &data);
UART2_PrintString("V\tPot : ");
uart2_printDouble(data/1000.0, 3);
delay_ms(2000);
resultado=INA219_read_reg(INA219_REG_CURRENT, &data);
UART2_PrintString("W\tCorr : ");
uart2_printDouble(data/10000.0, 3);
UART2_PrintString("A");
delay_ms(300000);
}
}
Cuanso lo use en la aplicacion final voy a acomodar esta porquería de código y seguiré publicando... si necesitas algo en particular avisame.
Saludos!
-
Ja..ja..!!
Lejos de ser una porquería !!
Para mi esta genial y clarisimo !!
Gracias !! :mrgreen:
-
Me parece a mi o la potencia es la mitad de la que debería ser????....
Comenta que carga y a que tensión esta conectado, y revisamos juntos el calculo de la calibración, por ahí puede venir la cosa...
Igual es extraño... :shock:
-
Me había olvidado de esto...
veamos según la hoja de datos hay que seguir estos pasos:
VbusMax = 16V - Esto lo defino yo de acuerdo a mi sistema
VshuntMax = 0,32V - Puede ser 40/80/160 mV
Rshunt = 0.82ohm/5 = 0.164ohm
MaxPosibleI = 0.32V/0.164ohm = 1.95A
MaxExpectedI = 1.5A - Esto es lo que yo considero como máxima corriente esperada en mi sistema.
MinimumLSB = 1.5A/32767 = 45.8uA
MaximumLSB = 1.5A/4096 = 366uA
De esos dos valores elijo uno que este entre los dos, lo más chico posible para tener presicion y en lo posible redondo. Por ejemplo 100uA
CurrentLSB = 100uA
Calibracion = 0.04096 / (100 .10-6 * 0.164) = 2497 - Acá hay que tener en cuenta que el bit 0 del registro de calibracion es siempre 0, por lo que los datos impares se almacenarán como el impar menor más cercano (2496)
PotLSB = 20 x CurrentLSB = 2mW
Con todo esto puedo guardar la calibracion y hacer las converciones de datos Raw en valores reales.
Modifiqué levemente el programa para que quede mejor y cumpla con estas condiciones:
INA219.h
#ifndef INA219_H_
#define INA219_H_
#include "i2c.h"
extern volatile uint8_t I2CMasterBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint8_t I2CSlaveBuffer[I2C_PORT_NUM][BUFSIZE];
extern volatile uint32_t I2CReadLength[I2C_PORT_NUM];
extern volatile uint32_t I2CWriteLength[I2C_PORT_NUM];
/*=========================================================================
I2C ADDRESS/BITS
-----------------------------------------------------------------------*/
#define INA219_WRITE_ADDR (0x80) // 1000000 (A0+A1=GND)
#define INA219_READ_ADDR (0x81)
/*=========================================================================*/
/*=========================================================================
CONFIG REGISTER (R/W)
-----------------------------------------------------------------------*/
#define INA219_REG_CONFIG (0x00)
/*---------------------------------------------------------------------*/
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
/*=========================================================================*/
/*=========================================================================
SHUNT VOLTAGE REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_SHUNTVOLTAGE (0x01)
/*=========================================================================*/
/*=========================================================================
BUS VOLTAGE REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_BUSVOLTAGE (0x02)
/*=========================================================================*/
/*=========================================================================
POWER REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_POWER (0x03)
/*=========================================================================*/
/*=========================================================================
CURRENT REGISTER (R)
-----------------------------------------------------------------------*/
#define INA219_REG_CURRENT (0x04)
/*=========================================================================*/
/*=========================================================================
CALIBRATION REGISTER (R/W)
-----------------------------------------------------------------------*/
#define INA219_REG_CALIBRATION (0x05)
/*=========================================================================*/
#define PORT_USED 1
void INA219_init();
unsigned char INA219_read_reg(unsigned char reg, signed short *value);
unsigned char INA219_write_reg(unsigned char reg_address, unsigned short value);
unsigned char INA219_read_reg(unsigned char reg, signed short *value){
int i;
for ( i = 0; i < BUFSIZE; i++ )
{
I2CSlaveBuffer[PORT_USED][i] = 0x00;
}
unsigned char result=0;
I2CWriteLength[PORT_USED] = 2;
I2CReadLength[PORT_USED] = 2;
I2CMasterBuffer[PORT_USED][0] = INA219_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg;
I2CMasterBuffer[PORT_USED][2] = INA219_READ_ADDR;
result=I2CEngine(PORT_USED);
*value = ((I2CSlaveBuffer[PORT_USED][0] << 8) | I2CSlaveBuffer[PORT_USED][1]);
return(result);
}
unsigned char INA219_write_reg(unsigned char reg_address, unsigned short value){
I2CWriteLength[PORT_USED] = 4;
I2CReadLength[PORT_USED] = 0;
I2CMasterBuffer[PORT_USED][0] = INA219_WRITE_ADDR;
I2CMasterBuffer[PORT_USED][1] = reg_address;
I2CMasterBuffer[PORT_USED][2] = ((value >> 8) & 0xFF);
I2CMasterBuffer[PORT_USED][3] = (value & 0xFF);
return(I2CEngine( PORT_USED ));
}
#endif /* INA219_H_ */
Luego mi main.c me queda:
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
volatile uint32_t msTicks;
__INLINE static void delay_ms (uint32_t delayTicks) {
uint32_t currentTicks;
currentTicks = msTicks; // read current tick counter
while ((msTicks - currentTicks) < delayTicks);
}
#include <cr_section_macros.h>
#include <NXP/crp.h>
#include "uart2.h"
#include <stdio.h>
#include "i2c.h"
#include "INA219.h"
void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}
/*******************************************************************************
** Main Function main()
*******************************************************************************/
int main (void){
signed short data=0;
//Configuro el SysTick para que interrumpa cada 1mseg
if (SysTick_Config(SystemCoreClock / 1000)) {
while (1);
}
I2C1Init(); // Inicializo el I2C1
UART2_Init(115200); // Inicializo el UART a 115200
UART2_PrintString ("\r\nINA219\r\n");
UART2_PrintString ("======== elgarbe ==========\r\n");
UART2_PrintString ("Escribiendo calibración (2497)\r\n");
INA219_write_reg(INA219_REG_CALIBRATION, 2497);
INA219_read_reg(INA219_REG_CALIBRATION, &data);
UART2_PrintString("\r\nConfiguracion leida: ");
uart2_printUint32(data, 10);
delay_ms(2000);
while ( 1 ){
INA219_read_reg(INA219_REG_SHUNTVOLTAGE, &data);
UART2_PrintString("\r\nTens. sht: ");
uart2_printDouble(data * 0.00001, 3); //El LSB es 10uV
delay_ms(2);
INA219_read_reg(INA219_REG_BUSVOLTAGE, &data);
UART2_PrintString("V\tTens. bus: ");
uart2_printDouble((data>>3) * 0.004, 3); //Alineo el resultado y el LSB es 4mV
delay_ms(2);
INA219_read_reg(INA219_REG_POWER, &data);
UART2_PrintString("V\tPot : ");
uart2_printDouble(data * 0.002, 3); //El LSB de potencia me dió 2mW
delay_ms(2);
INA219_read_reg(INA219_REG_CURRENT, &data);
UART2_PrintString("W\tCorr : ");
uart2_printDouble(data * 0.0001, 3); //El LSB de corriente es 100uA
UART2_PrintString("A");
delay_ms(300);
}
}
Algo importante es que la tensión de bus estpa desplazada 3 posiciones en el registro, por ello el desplazamiento que hago en el código. Luego es cuestion de multiplicar cada valor por su LSB.
El LSB de la V de shunt es fijo y es 10uV y el de la V bus es de 4mV. El resto los hemos calculado.
La salida ahora es:
(http://farm4.staticflickr.com/3690/12733832253_9094dcf446_z.jpg) (http://www.flickr.com/photos/117247358@N03/12733832253/)
Ahora sí, si hacemos Vbus * I nos da lo mismo que la potencia medida, cosa que antes no sucedía!!!!
Saludos!
-
Nunca habías hecho ese calculo ?? :shock: :shock:
O sea que no soy el unico apurado para hacer las cosas !! :D :D :D
-
En realidad había hecho los cálculos y me habia dado 2560, pero lo que no habia visto, por apurado, es el tema de los LSB de cada medicion. Entonces estaba midiendo mal...
Bueno, ahora más tranquilo (despues de resolver el tema de las tierras compartidas) leí bien la hoja de datos y ya quedó funcionando todo bien!
Saludos!
-
Me alegro mucho, estoy aprendiendo un montón de estas experiencias tuyas, gracias por compartirlas !!
De que se trata lo de las tierras compartidas ??
-
El tema de las tierras era que yo tenía alimentado el INA desde la placa del uC con 3.3V. Por otro lado tenía una fuente de alimentacion de "potencia", haciendo corcuilar corriente por un grupo de resistencias de potencia. Yo metía en el circuito la R de shunt y quería medir de ese modo. Lo que vi es que la tierra del INA y la tierra de la fuente de "potencia" deben estar unidas. Sino tenía mediciones que variaban constantemente como en los ejemplos más arriba.
Ahora estoy programando el totalizador de corriente (para ver cuanta corriente le voy sacando a la Lipo en vuelo) y ver de mezclar esto y la info del GPS en el OSD. Para ello estoy estudiando la implementacion de DMA, asi que ahí se puede venir otro gran tema!
saludos!
-
Utiliza mejor un shunt de 1 miliohmio o menos.
El INA219 acepta diferencias de tensión de +-40 milivoltios sin problema.
Cuando circulen 30 amperios, la potencia en la resistencia de 1 miliohmio será de 0.9 vatios.
Para hacer el shunt, sólo necesitas tomar la tensión de dos puntos del cable de alimentación.
Con un cable de cobre de 3mm de diámetro y 20 centímetros de longitud, tienes una resistencia de 0.5 miliohmios y puede aguantar 30 Amperios.
El INA daría una resolución de 20 miliamperios.
Saludos.
El finde estuve volando y haciendo pruebas con el shunt. La cosa cambió un poco. El consumo máximo que espero ahora son 12A. El tema es que 20cm de alambre de cobre se me complica para poner... que pasa si uso alambre de 3mm pero de aluminio, el que se usa para bobinados de transformadores? que resistividad puedo tomar para ese alambre?
Saludos!
-
Bueno, despues de las pruebas del finde y de casi estrellar el planeador por el peso excesivo me dí a la tarea de emprolijar el "engendro". La idea de todo el plaqueterío que ven en la parte del OSD era para probar circuitos y ver que funcione todo y empezar a programar.
Ahora que esta funcionando y ya tengo todo más aprendido empiezo a diseñar todo un poco mejor.
En cuanto a la medicion de parámetros eléctricos del avion he decidido hacer una placa exclusiva para la medicion. Con dos conectores XT-60 y las R de shunt y el ina219. De esa forma, lo enchufaría entre el ESC y la LiPo sin tener que tocar las fichas. El tamaño final: 22x63mm, un poquito mas largo que el ESC.
El tema de la R de shunt aún no me convence. Lo unico que consegui son resistencias de .27ohm, 2W metal film. Decidi poner 20 en pararlelo para obtener 0.0135 ohm. Podría medir hasta 23.7A, aunque discipando 7.6W. Es mucho. Como espero una I máxima de 12A, la potencia que disiparían sería 2W... Pero si quisiera medir corrientes mas altas estoy frito.
El tema de poner un alambre como shunt me gusta, pero tendría que ser de no más de 10cm... creo que la resistencia sería muy chica... que Ro se usa para el alambre de cobre comercial? Voy a probar que onda con shunts de alambre... pero mientras tanto tengo que seguir adelante....
Adjunto esquemático y pcb
Como ven he metido los componentes SMD en la capa bottom, entonces los puedo poner "debajo" de las R de potencia, ganando lugra. Si bien hay lugar para 10 R, arriba de esas van 10 más... mañana espero poder hacer la placa en el laburo...
Si quieren el proyecto en altium, me avisan y lo subo!
-
Bueno, El CI ya esta listo y armado.
Tuve suerte de desarmar un tester que no funcionaba y encontrar un buen shunt. Es de 0.01ohm. Con él podría achicar mas la placa, la idea del diseño acual es para poner varias R en paralelo...
Un panel con 3 placas. La pintura anti solder es blanca porque justo estaba pintando con ese color (placas a led)
(http://farm4.staticflickr.com/3586/13038422045_90676f69e7_z.jpg) (http://www.flickr.com/photos/117247358@N03/13038422045/)
Shunt, conector con alimentacion y salida I2C y conectores XT-60:
(http://farm8.staticflickr.com/7440/13038792524_9be53df80b_z.jpg) (http://www.flickr.com/photos/117247358@N03/13038792524/)
Vista de abajo con los componentes SMD:
(http://farm8.staticflickr.com/7364/13038798954_f90cf76b92_z.jpg) (http://www.flickr.com/photos/117247358@N03/13038798954/)
Bueno, ahora estoy trabajando en la placa de control, achicando el "engendro OSD" para que entre dentro del avion. Cuando la termine podré probar esta parte en conjunto con el OSD...
Saludos!