Need help modifying gas gauge Library

Hi All,

I have been working on a project for a while now, and ive got to the stage of writing libraries for it. Unfortunately there is no library available for the chip i chose :frowning: I have used the STC3117 gas gauge fron ST micro. while there is a repo for it on there github, it only has pseudo code! so i have been busily updating the older STC3115 library to suit the new little brother with more features. So i started by updating registers and addresses and the likes, implemented a couple of new functions etc. but im stuck at this point waiting for hardware, and i wanted to make sure i was doing it the best way possible.

So the old 3115 has a 16byte table for the OCV (open circuit voltage, mV) Offset, the new 3117 has changed to a 32byte table and they also added a SOC (state of charge, %) Offset table that has 16bytes.

so basically i have done this

/* New in STC3117 the OCV offset is now 2bytes per table entry*/
#define OCV_OFFSET_TAB    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // OCVTAB    (Open Circuit Voltage curve, ie when the battery is relaxed (no charge or discharge)

#define SOC_OFFSET_TAB    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // SOCTAB    (State of Charge curve, ie when the battery is relaxed (no charge or discharge)

and this is in the function that makes use of it

  int OCVOffset[32] = OCV_OFFSET_TAB;
  int SOCOffset[16] = SOC_OFFSET_TAB;

  for(loop=0; loop<32; loop++)
  {
    if(OCVOffset[loop] > 127) OCVOffset[loop] = 127;
    if(OCVOffset[loop] < -127) OCVOffset[loop] = -127;
     ConfigData->OCVOffset[loop] = OCVOffset[loop];
  }
  for(loop=0; loop<16; loop++)
  {
    if(SOCOffset[loop] > 127) SOCOffset[loop] = 127;
    if(SOCOffset[loop] < -127) SOCOffset[loop] = -127;
     ConfigData->SOCOffset[loop] = SOCOffset[loop];
  }

is there a better way i should be doing the OCV offset? should the define still have 16 numbers and when writing preparing to write them to the RAM it should be something like

  for(loop=0; loop<32; loop = loop + 2)
  {
    if(OCVOffset[loop] > 255) OCVOffset[loop] = 255;
    if(OCVOffset[loop] < -255) OCVOffset[loop] = -255;
     ConfigData->OCVOffset[loop] = OCVOffset[loop];
     ConfigData->OCVOffset[loop + 1] = (OCVOffset[loop + 1] << 8 )
  }

Ill push sone stuff to my github now for the full library, and update this post… there is still alot more questions to come!

edit:
my version: https://github.com/Hootie81/STC3117
original : https://github.com/st-sw/STC3115GenericDriver/

STC3115 datasheet
STC3117 datasheet

I’m not realy a best practice authority by any means, but you could do this instead

  int OCVOffset[] = OCV_OFFSET_TAB;
  int SOCOffset[] = SOC_OFFSET_TAB;

  int cntOCV = sizeof(OCVOffset) / sizeof(OCVOffset[0]);
  int cntSoC = sizeof(SOCOffset) / sizeof(SOCOffset[0]);

  for(idx=0; idx<cntOCV; idx++)  // don't like loop ;-)
  {
     ConfigData->OCVOffset[loop] = constrain(OCVOffset[loop], -127, +127);
  }

  for(idx=0; idx<cntSoC; idx++)  // don't like loop ;-)
  {
     ConfigData->SOCOffset[loop] = constrain(SOCOffset[loop], -127, +127);
  }

This way you’d just need to change the #define between the two chips.

Why would the next offset not need constraining but multiplying by 256?

@ScruffR my thoughts were because it used to be a single byte per table item, now its 2 bytes per table item? but now im confused… the ConfigData->OCVOffset is of type unsigned char also? so why are the numbers constrained to -127 to 127? wouldnt that be a signed char/byte
I dont understand why the original lib was written this way

I have no idea, I just took your code and “reworded” it :wink:
Just did it without looking at the datasheets or library :blush:

You also said that the bigger sensor uses 32 byte table rather than using a 16x uint16_t table which gave me the impression that you got 32 items 1 byte each.

So now I’m confused :confused:

But if it’s a 16x2byte table, I’d use the same memory layout for your array

/* New in STC3117 the OCV offset is now 2bytes per table entry*/
#define OCV_OFFSET_TAB    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // OCVTAB    (Open Circuit Voltage curve, ie when the battery is relaxed (no charge or discharge)
#define SOC_OFFSET_TAB    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } // SOCTAB    

uint16_t OCVOffset[] = OCV_OFFSET_TAB;
uint8_t  SOCIffset[] = SOC_OFFSET_TAB;

int cntOCV = sizeof(OCVOffset) / sizeof(OCVOffset[0]);
int cntSoC = sizeof(SOCOffset) / sizeof(SOCOffset[0]);

This way you might even be able to use memcpy() to move your local copy into your ConfigData object.
For bytewise access you can always cast the uint16_t[] down to a uint8_t[].