Forums - Measuring Supply Voltage and Battery Current

6 posts / 0 new
Last post
Measuring Supply Voltage and Battery Current
James Wilson Moderator
Join Date: 11 Apr 14
Posts: 170
Posted: Mon, 2017-04-24 19:29

One of our flight stack engineers has contributed this snippet of code to document how to read voltage and current from the power adapter module (APM) that is provided with the Snapdragon Flight Kit.

#define LTC2946_I2C_ADDRESS 0b1101010   //I2C address to measure battery supply voltage and current
//#define LTC2946_I2C_ADDRESS 0b1101011   //I2C address to measure 5V supply voltage and current
 
static int ltc2946_config_sensor()
{
  uint8_t CTRLA = 0b01001000;   //offset calib every 128 conv, so sampling takes about 35ms (for both voltage and current together)
  //uint8_t CTRLA = 0b00001000; //Gnd ref, offset evey conv, volt=sense+, alternate volt and curr. if use this setting, it takes about 100ms to sample
  uint8_t CTRLB = 0b00000100;
 
  //resolution for voltage sensing is 25mV/LSB (not very high... but voltage range is high)
 
  if (i2c_write_check_reg(file_des,0x00,CTRLA)) return -3;
  if (i2c_write_check_reg(file_des,0x01,CTRLB)) return -4;
 
  return 0;
}
 
static int ltc2946_init()
{
  vsense_slave_addr = LTC2946_I2C_ADDRESS;
  isense_slave_addr = LTC2946_I2C_ADDRESS;
 
 //set the slave config
  if (i2c_slave_config(file_des, vsense_slave_addr, vsense_bit_rate, vsense_trx_timeout_us) != 0)
  {
    return -2;
  }
 
  if (ltc2946_config_sensor() !=0)
  {
    return -3;
  }
 
  return 0;
}
 
static int ltc2946_read_data()
{
  //set the slave config just in case
  if (i2c_slave_config(file_des, vsense_slave_addr, vsense_bit_rate, vsense_trx_timeout_us) != 0)
  {
    return -1;
  }
 
  uint64_t time_read_start  = // TODO: insert a function call to obtain the current tick count in usecs.
  uint8_t vraw[2];
  uint8_t iraw[2];
  int volt_read_ret = i2c_read_reg(file_des,0x1E,vraw,2);    //read raw voltage measurement from 0x1E register (2 bytes)
  int curr_read_ret = i2c_read_reg(file_des,0x14,iraw,2);    //read raw current measurement from 0x14 register (2 bytes)
 
  if ( (volt_read_ret==0) && (curr_read_ret==0))
  {
    uint16_t volt16 = (((uint16_t)vraw[0]) << 8) | vraw[1];  //MSB first
    volt16        >>= 4;                                     //data is 12 bit and left-aligned
    float v_now      = volt16/4095.0 * 102.4;                //102.4V is maximum voltage on this input
 
    uint16_t curr16 = (((uint16_t)iraw[0]) << 8) | iraw[1];  //MSB first
    curr16        >>= 4;                                     //data is 12 bit and left-aligned
 
    float r_sense    = 0.001;                                //current sense resistor value on Eagle ESC
    //float r_sense    = 0.0005;                             //current sense resistor value on Eagle APM (main current sense)
    //float r_sense    = 0.005;                              //current sense resistor value on Eagle APM (5V current sense)
    float i_now      = curr16/4095.0 * 0.1024 / r_sense;     //0.1024V is maximum voltage on this input, 0.001 Ohm resistor
 
    pthread_mutex_lock(&vsense_lock);
    vsense_read_counter++;
    vsense_fresh_data = 1;
    vsense_read_time  = time_read_start;
    vsense_voltage    = v_now;
    pthread_mutex_unlock(&vsense_lock);
 
    pthread_mutex_lock(&isense_lock);
    isense_read_counter++;
    isense_fresh_data = 1;
    isense_read_time  = time_read_start;
    isense_current    = i_now;
    pthread_mutex_unlock(&isense_lock);
 
  }
  else
  {
    return -2;
  }
 
  return 0;
}
Jim W.
  • Up0
  • Down0
rogelion
Join Date: 11 Feb 17
Posts: 1
Posted: Thu, 2017-07-20 16:33

How do you run this code snippet?

  • Up0
  • Down0
James Wilson Moderator
Join Date: 11 Apr 14
Posts: 170
Posted: Tue, 2017-07-25 12:36

This code runs on the aDSP and uses the DSPAL API for I2C access.  More information on the DSPAL API is documented here in the header files:

https://github.com/ATLFlight/dspal/tree/master/include

To compile this code you will need to create a project that compiles your code into AppsProc (ARM) and aDSP (Hexagon) components. Information on how to create such a project is availabe in the DSPAL Getting Started guide, available at the link below.  Once you have done this you will need to add the code in this post to your aDSP source file.

https://github.com/ATLFlight/ATLFlightDocs/blob/master/GettingStarted.md

Jim W.

  • Up0
  • Down0
bryanribas
Join Date: 31 Dec 16
Posts: 6
Posted: Mon, 2017-09-11 13:51

Hello,

         I am trying to compile this code and I am having some issues putting all the peices together. I am able to sucsefully comiple the Hello World as well as the DSPAL test. I am having a hard time figuing out where to insert this code. Any additional insight or directions would be greatly appreciated.

  • Up0
  • Down0
James Wilson Moderator
Join Date: 11 Apr 14
Posts: 170
Posted: Thu, 2017-09-14 18:43

If you can get the dspal_tester built, then you should be in good shape.  

If you look at the i2c test code, located at the link below, you could copy the code into the i2c_test_imp.c file and run it from there.  If this works for you, then you would remove the unwanted I2C code, along with the unit test code.

https://github.com/ATLFlight/dspal/blob/master/test/dspal_tester/adsp_pr...

Jim W.

  • Up0
  • Down0
bryanribas
Join Date: 31 Dec 16
Posts: 6
Posted: Wed, 2017-09-20 09:12

Hello,

Thanks for the quick response. Do you know if this code was written for the SnapDragon or for another device and the code needs to be ported? I ask becuase when I copy the above snippit of code into the i2c_test_imp.c file I receive errors like this

Quote:
implicit declaration of function 'i2c_slave_config

When I google it I can only find a reference to it in the Atmel software framework documentation. I will try to port it using the code as reference but I feel like I may be missing something, an include or something. Any additional insight or guidance would be greatly appreciated.

Thanks Bryan Ribas

  • Up0
  • Down0
or Register

Opinions expressed in the content posted here are the personal opinions of the original authors, and do not necessarily reflect those of Qualcomm Incorporated or its subsidiaries (“Qualcomm”). The content is provided for informational purposes only and is not meant to be an endorsement or representation by Qualcomm or any other party. This site may also provide links or references to non-Qualcomm sites and resources. Qualcomm makes no representations, warranties, or other commitments whatsoever about any non-Qualcomm sites or third-party resources that may be referenced, accessible from, or linked to this site.