Lawmate / BQ4050

Library for basic interfacing with BQ4050 battery fuel gauge from TI
Other
14 stars 6 forks source link

Unable to compile in Arduino #6

Closed jessydm closed 4 years ago

jessydm commented 4 years ago

Hi Thanks for writing the library. I am trying to use this library to connect with BQ4050 with arduino but I am getting error " Multiple definitions of registers ". I tried correcting it but my skills are not good enough.

There was also errors for Wire.receive and Wire.send function which has to renamed to Wire.read and Wire.write. I was able to rename and go forward on that one though.

Lawmate commented 4 years ago

Hi Jess, thanks for the feedback. Are you using the Arduino IDE? What board are you compiling for? Are you using an example from the library or are you writing your own code? Thanks

Lawmate commented 4 years ago

Hi Jess. So I wrote the library using platformio for the Teensy3.2 and haven't tested it for any other boards or on other platforms. I just tried it with the Arduino IDE and was getting compile errors about the library having an instance of Regt also called registers. You can fix this error by changing the 'Lorro_BQ4050::Regt registers' line to 'Lorro_BQ4050::Regt regs' then you will have to change the references throughout the code. Unfortunately I don't have a board on hand to test this but if I remember correctly, I think I made them the same so that you can change and update the values that are initially written in the header file. I'm pretty certain I named them similarly for a reason. But I won't be able to test it out for a little while I'm afraid. As for the wire library names, sorry about that. Teensy installs it's own version of the wire library that is different from the Arduino version. It's probably best to sort it out with a preprocessor. Hope it helps.

jessydm commented 4 years ago

HI Lawmate I was using with Arduino on ESP8266 board. First I tried to run your example readFuel which is where I encountered above error about multiple definitions. I did tried to rename and compile it , which went ahead and compiled fine but when I ran the program readFuel it just gave me all value for 0. I had borrowed some code and made my own program which is running fine and giving me all correct values. However I am stuck on few things. I tried to get the Current register 0x0A during discharge , it is reading incorrect value, but reads fine when it is charging or idle. All other registers are being read fine. Also were you able to test out ManufacturerAcess commands ? I am following your code but it is not responding to these commands. Mostly I have been trying reset or CHG or DCHG Fet toggle.

This is my code for LED Toggle

`void toggleLED(){ delay(100); Wire.beginTransmission(SMBUS_DEVICE); //MAC access Wire.write( 0x44 ); //little endian of address Wire.write(0x2C); // Wire.write( 0x00 );

byte ack = Wire.endTransmission(); if( ack == 0 ){ Serial.println("Command Executed Successfully"); }else{ Serial.println("Command FAILED"); } `}

I get msg for command being executed Successfully but BMS chip don't respond. I do have BQStudio Installed and the command works fine when run through it. I am not C programmer so limited to debugging it.

Thanks for your reply.

jessydm commented 4 years ago

bqstudio command reset

jessydm commented 4 years ago

Above is screenshot for same command in BQStudio

Lawmate commented 4 years ago

Hi Jess OK, so I've looked further into it. It's been 3 months since I looked at it, which is long enough for the code to lose its freshness in my mind as I am definitely not a pro c++ coder by any means. I think I hadn't fully tested the examples on recent library changes. I tried to write the library with the registers as objects, being nested structs. There is a regt for the main registers and dft for the data flash. Your program needs to access the same instantiation as the library. I think for this to work, the instantiation in your code must happen locally, within a function, rather than globally. If it's global it throws that error. I've pushed the change anyway, so maybe you can give it a test. In terms of manufacture access registers, that is all handled in the library, including writing to the data flash. The code above has the 0x00 commented out. I think you need to send this as well. Do you have a logic analyser at all? I found it super useful when using bqstudio, as it's not very forthcoming with exactly what is being sent. The documentation is super sparse for the DF writing too. You have to send a PEC byte which is a CRC-8 and also one byte is just a count of the number of bytes you will send. It's all easy to see on the logic analyser.

jessydm commented 4 years ago

screenshot- Manufacturer Command

jessydm commented 4 years ago

This is with my code

 Wire.beginTransmission(SMBUS_DEVICE);
  //MAC access
  Wire.write( 0x44 );
  //little endian of address
  Wire.write(0x2C); 
  Wire.write( 0x00 );

  byte ack = Wire.endTransmission();

screenshot2

jessydm commented 4 years ago

I have taken the code from your library writeCommand function

boolean Lorro_BQ4050::writeCommand( char devAddress, byte regAddress ){

  //Function that simply writes out a command to the device byt way of writing
  //a zero to a particular address

  Wire.beginTransmission( devAddress );
  //MAC access
  Wire.write( 0x44 );
  //little endian of address
  Wire.write( regAddress );
  Wire.write( 0x00 );
  byte ack = Wire.endTransmission();
  if( ack == 0 ){
    return true;
  }else{
    return false; //if I2C comm fails
  }
jessydm commented 4 years ago

Thanks Lawmate for helping earlier. I did figure out how to correctly send Manufacturer Access commands. We do not need to send number of bytes we need to write. Below is code for sending manaufacturer access command. In above case it was adding Wire.write(0x02).

  Wire.beginTransmission(SMBUS_DEVICE);
  //MAC access
  Wire.write( 0x44 );    // Manufacturer Access register
  Wire.write(0x02);       // Number of bytes will be sending
  //little endian of address
  Wire.write(0x2C); 
  Wire.write( 0x00 );

  byte ack = Wire.endTransmission(true);
Lawmate commented 4 years ago

Hey Jess, glad you got it working OK. I guess your first Saleae shot is from the bqstudio output? Bqstudio always uses the PEC at the end of the packet. It is in the spec to use it but I don't think the device requires it to call a command, that is why I think that your function worked. If you want to update the data flash values, you will need to send a correct PEC otherwise they won't update. That is why I included a PEC function. Anyway, I have written a new MAcommand function https://github.com/Lawmate/BQ4050/blob/master/Lorro_BQ4050.cpp#L375-L403. I don't have a device to test it on, so feel free to give it a go. I included the PEC even though it might not be necessary. Glad that you've got a Saleae, it made my life so much easier with it. I'm pretty sure I wouldn't be able to have write this library without it. Let me know if you have any other issues. Thanks

anandakrishnas commented 1 year ago

Thanks Lawmate for helping earlier. I did figure out how to correctly send Manufacturer Access commands. We do not need to send number of bytes we need to write. Below is code for sending manaufacturer access command. In above case it was adding Wire.write(0x02).

Wire.beginTransmission(SMBUS_DEVICE);
//MAC access
Wire.write( 0x44 );    // Manufacturer Access register
Wire.write(0x02);       // Number of bytes will be sending
//little endian of address
Wire.write(0x2C); 
Wire.write( 0x00 );

byte ack = Wire.endTransmission(true);

HELLO CAN YOU SHARE YOUR ARDUINO CODE? THANKS

jessydm commented 1 year ago

Sorry It has been while I have worked on this project. I don't think I have it anymore.