// This #include statement was automatically added by the Particle IDE.
#include "BQ20Z45.h"
#include "application.h"
#include "BQ20Z45.h" //Include BQ78350 Header File
// Store an instance of the BQ20Z45 Sensor
BQ20Z45 bms;
//char strBuffer[33]; // This is a Buffer to store 32 bit data strings read from the BQ78350 Fuel Gauge. Not Sure if this is the best place for this code.
uint16_t GaugingStatus = 0;
void setup(void)
{
// We start the serial library to output our messages.
Serial.begin(115200);
// Start i2c communication.
Wire.begin();
}
void loop(void)
{
//Serial.print("Device Name: ");
bms.GaugingStatus(result);
delay(4000);
}
The .CPP :
#include "application.h"
#include "BQ20Z45.h"
//#include "Arduino.h"
#include "application.h"
/////////////////////////////////////////////////////////////////////////////
// Functions Below
// Fuel gague function to read Manufacturer Access Data registers when in sealed mode.
int BQ20Z45::readBytes(uint8_t address, void* buffer, size_t len, boolean exactLen)
{
int pos;
int cnt; // to hold the actual length the address would hold
// Read the length of the string
Wire.beginTransmission(BQ20Z45_Address); //Setup Write to Gauge
Wire.write(0x44); //Manufacturer Block Read
Wire.write(0x02); //How Many Bytes to expect Next
Wire.write(address); //Manufacturer Access Command - Example 0x01 Device Type
Wire.write(0x00); //First Byte of Command
Wire.endTransmission(true); //Repeated Start = True
Wire.beginTransmission(BQ20Z45_Address); //Setup Write to Gauge
Wire.write(0x44); //Manufacturer Block Read
Wire.endTransmission(true); //Repeated Start
Wire.requestFrom(BQ20Z45_Address, 1, true); //Setup Reading of Returned Data
cnt = Wire.read(); // length of the string thats about to return
cnt++; // plus one to allow for the length byte on the reread
cnt = Wire.requestFrom(BQ20Z45_Address, cnt, true); // readRequest returns # bytes actually read
if (cnt == len+3 || !exactLen && cnt > 3)
{ // we got the expected read count
cnt -= 3; // drop the first three bytes
Wire.read(); // length received lsb
Wire.read(); // length received msb (always 0) ???
Wire.read(); // address from which we just read
memset(buffer, 0, len); // clear the buffer for safe measure
for (pos = 0; pos < cnt; pos++)
{
if (pos < len) buffer[pos] = Wire.read(); // as long we have room in the buffer add to it
else Wire.read(); // otherwise just drop it
}
return cnt;
}
else
{ // drop them all
for(pos = 0; pos < cnt; cnt++)
Wire.read();
}
return -cnt; // includes the extra three bytes
}
/////////////////////////////////////////////////////////////////////////////
// Class Methods Below
int BQ20Z45::GaugingStatus(uint16_t* result) //int BQ20Z45::GaugingStatus(char *result)
{
return readBytes(BQ20Z45_GaugingStatus, (void*)result, sizeof(*result));
// for platforms with incompatible endianness you may want to
// add some code to correct the byte order
}
That was a long road to travel, but it's working now Feels good
THANK YOU SO MUCH FOR HELPING ME WITH THIS!
@Ric Thanks for that tip also! One less than I had to ask ScruffR for help with, which is nice
I would have figured out to add the GaugingStatus but adding the & sign in front of it is something I have not fully grasped yet, although @ScruffR did mention this to me in a post above:
And the more important point IMHO is not the success but the insight you gained on the way
The success is one benefit, but the lessons learnt will benefit you over and over when you run into similar questions.
Give a starving man a fish or teach him how to fish.
I have one command that is returning 34 bytes of data and I’m saving that in a StrBuffer that is sized to 34 bytes in size so it can actually hold that much data. Even though I increased the buffer size I now see that the Wire.RequestFrom function is coded to max out to only return 32 bytes max.
Hello can some body tell is it possible to reset bq20z45 using arudino.i want to clear the Flags,mosfet status,capacity,current,cycle count,…
here i found software http://be2works.com which does it but in my country related hardware is not available.
any help is appreciated
thank you for replay but i know only soldering no programming .also sourcing TI EV2300 or EV2400 to bhutan will cost around $350 which is way expensive to me afford..
can you guide any way to do..this will help alot..
thank you..!
You would need the Datasheet for the TI chip your trying to read and then create some code to read and write those registers you need to change using a Microcontroller of your choice.
You’re going to have to learn this yourself or search the web for Arduino code that is already written for this line of BQ devices. Search for the BQ40z50 and see if anything comes up, its a popular chip.
Great fault finding so far
I am working on the same project.But i need to pass battery voltage and current data from BMU to my arduino.My bmu has the BQ40z50. Im little bit lost… Can you repost your working code or give some basic example as reference point?
There will be plenty of examples out there like this https://github.com/ArminJo/Smart-Battery-Module-Info_For_Arduino but also others for other processors. You should also be able to get some ideas by looking at Particles code for their PMIC, or samples for other TI devices, many of them are similar.
For non-arduino style systems they won’t have the convenience of the Wire library so will implement I2C at quite a low level, the Wire library hides a lot of complexity.
If you find a full library it will include methods for every feature on the device, however (presumably) you only want a few select figures and you can get those with a few select commands.
I would recommend reading how to use Wire.read/write and experiment with reading some of the values off the chip. Once you can do that the only thing left is probably some maths to turn the values into numbers you can read.
Lastly I can also tell you that Linear BMU/PMICs typically have what they call “Linduino” libraries for their products in with their documentation, they need a little tweaking to work on a photon as they re-implement some I2C stuff for no apparent reason .