Example added. rework library with float.

This commit is contained in:
lilian 2016-12-22 15:01:10 +01:00
parent 69280f8ec8
commit 1ee624c5fb
4 changed files with 174 additions and 72 deletions

View file

@ -0,0 +1,3 @@
PROGRAM=ina3221_test
EXTRA_COMPONENTS = extras/i2c extras/mcp4725
include ../../common.mk

View file

@ -0,0 +1,106 @@
/*
* Example of using INA3221
*
* Part of esp-open-rtos
* Copyright (C) 2016 Zaltora
* MIT Licensed as described in the file LICENSE
*/
#include "espressif/esp_common.h"
#include "FreeRTOS.h"
#include "task.h"
#include <esp/uart.h>
#include <stdbool.h>
#include "ina3221/ina3221.h"
#define PIN_SCL 4
#define PIN_SDA 2
#define ADDR INA3221_ADDR_0
//#define STRUCT_SETTING 1
void loop(void *pvParameters)
{
uint32_t measure_number = 0;
float bus_voltage;
float shunt_voltage;
float shunt_current;
// Create ina3221 device
ina3221_t dev = {
.addr = ADDR,
.shunt = { 100 ,100 ,100 }, // shunt values are 100 mOhm for each channel
.mask.mask_register = INA3221_DEFAULT_MASK, // Init
.config.config_register = INA3221_DEFAULT_CONFIG, // Init
};
#ifndef STRUCT_SETTING
if(ina3221_setting(&dev ,false, true, true)) // trigger mode, bus and shunt activated
goto error_loop;
if(ina3221_enableChannel(&dev , true, true, true)) // Enable all channels
goto error_loop;
if(ina3221_setAverage(&dev, INA3221_AVG_64)) // 64 samples average
goto error_loop;
if(ina3221_setBusConversionTime(&dev, INA3221_CT_2116)) // 2ms by channel
goto error_loop;
if(ina3221_setShuntConversionTime(&dev, INA3221_CT_2116)) // 2ms by channel
goto error_loop;
#else
dev.config.mode = false; // trigger mode
dev.config.esht = true; // shunt enable
dev.config.ebus = true; // bus enable
dev.config.ch1 = true; // channel 1 enable
dev.config.ch2 = true; // channel 2 enable
dev.config.ch3 = true; // channel 3 enable
dev.config.avg = INA3221_AVG_64; // 64 samples average
dev.config.vbus = INA3221_CT_2116; // 2ms by channel (bus)
dev.config.vsht = INA3221_CT_2116; // 2ms by channel (shunt)
if(ina3221_sync(&dev))
goto error_loop;
#endif
while(1)
{
measure_number++;
do
{
if (ina3221_trigger(&dev)) // Start a measure & get mask
goto error_loop;
} while(!(dev.mask.cvrf)); // check if measure done
for (uint8_t i = 0 ; i < BUS_NUMBER ; i++) {
if(ina3221_getBusVoltage(&dev, i, &bus_voltage)) // Get voltage in V
goto error_loop;
if(ina3221_getShuntValue(&dev, i, &shunt_voltage, &shunt_current)) // Get voltage in mV and currant in mA
goto error_loop;
printf("Measure number %u\n", measure_number);
printf("Bus voltage: %.02f V\n", bus_voltage );
printf("Shunt voltage: %.02f mV\n", shunt_voltage );
printf("Shunt current: %.02f mA\n\n", shunt_current );
}
vTaskDelay(5000/portTICK_PERIOD_MS);
}
error_loop:
printf("%s: error while com with INA3221\n", __func__);
for(;;){
vTaskDelay(2000 / portTICK_PERIOD_MS);
printf("%s: error loop\n", __FUNCTION__);
}
}
void user_init(void)
{
uart_set_baud(0, 115200);
printf("SDK version:%s\n", sdk_system_get_sdk_version());
i2c_init(PIN_SCL,PIN_SDA);
xTaskCreate(loop, "tsk1", 512, NULL, 2, NULL);
}

View file

@ -13,8 +13,6 @@
#define debug(fmt, ...)
#endif
#define sign(x) ((x > 0) - (x < 0))
static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value)
{
i2c_start();
@ -31,7 +29,7 @@ static int _wireWriteRegister (uint8_t addr, uint8_t reg, uint16_t value)
return 0 ;
error:
debug("Error while xmitting I2C slave INA3221\n");
debug("Error while xmitting I2C slave\n");
i2c_stop();
return -EIO;
}
@ -55,7 +53,7 @@ static int _wireReadRegister(uint8_t addr, uint8_t reg, uint16_t *value)
return 0;
error:
debug("Error while xmitting I2C slave INA3221\n");
debug("Error while xmitting I2C slave\n");
i2c_stop();
return -EIO;
}
@ -131,87 +129,82 @@ int ina3221_reset(ina3221_t *dev)
{
dev->config.config_register = INA3221_DEFAULT_CONFIG ; //dev reset
dev->mask.mask_register = INA3221_DEFAULT_CONFIG ; //dev reset
dev->config.reset = 1 ;
dev->config.rst = 1 ;
return _wireWriteRegister(dev->addr, INA3221_REG_CONFIG, dev->config.config_register); // send reset to device
}
int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage)
int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, float *voltage)
{
int16_t raw_value;
int err = 0;
if ((err = _wireReadRegister(dev->addr,INA3221_REG_BUSVOLTAGE_1+channel*2, (uint16_t*)&raw_value)))
return err;
*voltage = (raw_value>>3)*8; //mV 8mV step
*voltage = raw_value*0.001 ; //V 8mV step
return 0;
}
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage, int32_t *current)
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, float *voltage, float *current)
{
int16_t raw_value;
int err = 0;
if ((err = _wireReadRegister(dev->addr,INA3221_REG_SHUNTVOLTAGE_1+channel*2, (uint16_t*)&raw_value)))
return err;
*voltage = (raw_value>>3)*40 ; //uV 40uV step
*voltage = raw_value*0.005; //mV 40uV step
if(!dev->shunt[channel])
{
debug("No shunt configured for channel %u. Dev:%X INA3221\n",channel+1, dev->addr);
debug("No shunt configured for channel %u. Dev:%X\n",channel+1, dev->addr);
return -EINVAL;
}
*current = *voltage/dev->shunt[channel] ; //mA = uV / mOhm
*current = (*voltage*1000.0)/dev->shunt[channel] ; //mA
return 0;
}
int ina3221_getSumShuntValue(ina3221_t *dev, int32_t *voltage)
int ina3221_getSumShuntValue(ina3221_t *dev, float *voltage)
{
int16_t raw_value;
int err = 0;
if ((err = _wireReadRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM, (uint16_t*)&raw_value)))
return err;
*voltage = (raw_value>>1)*40; //uV 40uV step
*voltage = raw_value*0.02; //uV 40uV step
return 0;
}
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current)
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, float current)
{
int16_t raw_value = ((current*dev->shunt[channel]+20*sign(current))/40)<<3; // round and format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ?
return _wireWriteRegister(dev->addr,INA3221_REG_CRITICAL_ALERT_1+channel*2, *ptr_value);
int16_t raw_value = current*dev->shunt[channel]*0.2; // format
return _wireWriteRegister(dev->addr,INA3221_REG_CRITICAL_ALERT_1+channel*2, *(uint16_t*)&raw_value);
}
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current)
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, float current)
{
int16_t raw_value = ((current*dev->shunt[channel]+ 20*sign(current))/40)<<3; // round and format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ?
return _wireWriteRegister(dev->addr,INA3221_REG_WARNING_ALERT_1+channel*2, *ptr_value);
int16_t raw_value = current*dev->shunt[channel]*0.2 ; // format
return _wireWriteRegister(dev->addr,INA3221_REG_WARNING_ALERT_1+channel*2, *(uint16_t*)&raw_value);
}
int ina3221_setSumWarningAlert(ina3221_t *dev, int32_t voltage)
int ina3221_setSumWarningAlert(ina3221_t *dev, float voltage)
{
int16_t raw_value = ((voltage + 20*sign(voltage))/40)<<1; // round and format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ?
return _wireWriteRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, *ptr_value);
int16_t raw_value = voltage*50.0 ; // format
return _wireWriteRegister(dev->addr,INA3221_REG_SHUNT_VOLTAGE_SUM_LIMIT, *(uint16_t*)&raw_value);
}
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, int32_t voltage)
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, float voltage)
{
if(!dev->config.ebus)
{
debug("Bus not enable. Dev:%X INA3221\n", dev->addr);
debug("Bus not enable. Dev:%X\n", dev->addr);
return -ENOTSUP;
}
int16_t raw_value = ((voltage+4*sign(voltage))/8)<<3; // round and format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ?
return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_UPPER_LIMIT, *ptr_value);
int16_t raw_value = voltage*1000.0; //format
return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_UPPER_LIMIT, *(uint16_t*)&raw_value);
}
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, int32_t voltage)
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, float voltage)
{
if(!dev->config.ebus)
{
debug("Bus not enable. Dev:%X INA3221\n", dev->addr);
debug("Bus not enable. Dev:%X\n", dev->addr);
return -ENOTSUP;
}
int16_t raw_value = ((voltage+4*sign(voltage))/8)<<3; // round and format
uint16_t* ptr_value = (uint16_t*)&raw_value; // FIXME: Need this to convert int to uint without change data ?
return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_LOWER_LIMIT, *ptr_value);
int16_t raw_value = voltage*1000.0; // round and format
return _wireWriteRegister(dev->addr,INA3221_REG_VALID_POWER_LOWER_LIMIT, *(uint16_t*)&raw_value);
}

View file

@ -85,19 +85,19 @@ typedef enum {
typedef union
{
struct {
uint16_t esht : 1 ; // Enable/Disable shunt measure // LSB
uint16_t ebus : 1 ; // Enable/Disable bus measure
uint16_t mode : 1 ; // Single shot measure or continious mode
uint16_t vsht : 3 ; // Shunt voltage conversion time
uint16_t vbus : 3 ; // Bus voltage conversion time
uint16_t avg : 3 ; // number of sample collected and averaged together
uint16_t ch3 : 1 ; // Enable/Disable channel 3
uint16_t ch2 : 1 ; // Enable/Disable channel 2
uint16_t ch1 : 1 ; // Enable/Disable channel 1
uint16_t reset : 1 ; //Set this bit to 1 to reset device // MSB
uint16_t esht : 1; // Enable/Disable shunt measure // LSB
uint16_t ebus : 1; // Enable/Disable bus measure
uint16_t mode : 1; // Single shot measure or continious mode
uint16_t vsht : 3; // Shunt voltage conversion time
uint16_t vbus : 3; // Bus voltage conversion time
uint16_t avg : 3; // number of sample collected and averaged together
uint16_t ch3 : 1; // Enable/Disable channel 3
uint16_t ch2 : 1; // Enable/Disable channel 2
uint16_t ch1 : 1; // Enable/Disable channel 1
uint16_t rst : 1; //Set this bit to 1 to reset device // MSB
};
uint16_t config_register ;
} ina3221_config_t ;
uint16_t config_register;
} ina3221_config_t;
/*
@ -123,17 +123,17 @@ typedef union
uint16_t scc1 : 1 ; // channel 1 sum (1:enable)
uint16_t : 1 ; //Reserved //MSB
};
uint16_t mask_register ;
} ina3221_mask_t ;
uint16_t mask_register;
} ina3221_mask_t;
/*
* Device description
*/
typedef struct {
uint8_t addr ; // ina3221 I2C address
ina3221_config_t config ; //Memory of ina3221 config
ina3221_mask_t mask ; //Memory of mask_config
uint16_t shunt[BUS_NUMBER] ; //Memory of shunt value (mOhm)
const uint8_t addr; // ina3221 I2C address
const uint16_t shunt[BUS_NUMBER]; //Memory of shunt value (mOhm)
ina3221_config_t config; //Memory of ina3221 config
ina3221_mask_t mask; //Memory of mask_config
} ina3221_t;
/**
@ -221,76 +221,76 @@ int ina3221_setShuntConversionTime(ina3221_t *dev,ina3221_ct_t ct);
int ina3221_reset(ina3221_t *dev);
/**
* Get Bus voltage (mV)
* Get Bus voltage (V)
* @param dev Pointer to device descriptor
* @param channel Select channel value to get
* @param voltage Data pointer to get bus voltage (mV)
* @param voltage Data pointer to get bus voltage (V)
* @return Non-zero if error occured
*/
int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage);
int ina3221_getBusVoltage(ina3221_t *dev, ina3221_channel_t channel, float *voltage);
/**
* Get Shunt voltage (uV) and current (mA)
* Get Shunt voltage (mV) and current (mA)
* @param dev Pointer to device descriptor
* @param channel Select channel value to get
* @param voltage Data pointer to get shunt voltage (uV)
* @param voltage Data pointer to get shunt voltage (mV)
* @param current Data pointer to get shunt voltage (mA)
* @return Non-zero if error occured
*/
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, int32_t *voltage, int32_t *current);
int ina3221_getShuntValue(ina3221_t *dev, ina3221_channel_t channel, float *voltage, float *current);
/**
* Get Shunt-voltage (uV) sum value of selected channels
* Get Shunt-voltage (mV) sum value of selected channels
* @param dev Pointer to device descriptor
* @param channel Select channel value to get
* @param voltage Data pointer to get shunt voltage (uV)
* @param voltage Data pointer to get shunt voltage (mV)
* @return Non-zero if error occured
*/
int ina3221_getSumShuntValue(ina3221_t *dev, int32_t *voltage);
int ina3221_getSumShuntValue(ina3221_t *dev, float *voltage);
/**
* Set Critical alert (when measurement(s) is greater that value set )
* @param dev Pointer to device descriptor
* @param channel Select channel value to set
* @param current Value to set (mA)
* @param current Value to set (mA) // max : 163800/shunt (mOhm)
* @return Non-zero if error occured
*/
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current);
int ina3221_setCriticalAlert(ina3221_t *dev, ina3221_channel_t channel, float current);
/**
* Set Warning alert (when average measurement(s) is greater that value set )
* @param dev Pointer to device descriptor
* @param channel Select channel value to set
* @param current Value to set (mA)
* @param current Value to set (mA) // max : 163800/shunt (mOhm)
* @return Non-zero if error occured
*/
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, int32_t current);
int ina3221_setWarningAlert(ina3221_t *dev, ina3221_channel_t channel, float current);
/**
* Set Sum Warning alert (Compared to each completed cycle of all selected channels : Sum register )
* @param dev Pointer to device descriptor
* @param voltage voltage to set (uV) : 40uV step
* @param voltage voltage to set (mV) // max : 655.32
* @return Non-zero if error occured
*/
int ina3221_setSumWarningAlert(ina3221_t *dev, int32_t voltage);
int ina3221_setSumWarningAlert(ina3221_t *dev, float voltage);
/**
* Set Power-valid upper-limit ( To determine if power conditions are met.)( bus need enable )
* If bus voltage exceed the value set, PV pin is high
* @param dev Pointer to device descriptor
* @param voltage voltage to set (mV) : 8mV step
* @param voltage voltage to set (V)
* @return Non-zero if error occured
*/
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, int32_t voltage);
int ina3221_setPowerValidUpperLimit(ina3221_t *dev, float voltage);
/**
* Set Power-valid lower-limit ( To determine if power conditions are met.)( bus need enable )
* If bus voltage drops below the value set, PV pin is low
* @param dev Pointer to device descriptor
* @param voltage voltage to set (mV) : 8mV step
* @param voltage voltage to set (V)
* @return Non-zero if error occured
*/
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, int32_t voltage);
int ina3221_setPowerValidLowerLimit(ina3221_t *dev, float voltage);
#ifdef __cplusplus
}