"Hack" a laptop battery, see what's going on in its head. Send commands to reset and change values, read the voltage, temperature, charge rate, anything the controller can report. And more. With the awesome flexibility of phi_prompt, this little program has a nice menu-based UI that scales to whatever type of LCD you happen to have (I can only imagine how it looks on 20x4)! Plus, if you have a battery whose controller isn't supported yet (I only have bq2040 support embedded, but it's pretty easy to add a whole new command library that you can select from the menus).
Menus:
Setup
Test SMBus - checks for proper connection and response from the selected address
Scan SMBus - scans all usable SMBus addresses and displays the devices that respond to their address
Enter Address - directly enter a binary address to contact on SMBus for all functions
Command Set - change the command set that's used for built-in functions in Read Info and Single Command (only one is included, for the bq2040, but more can be easily added)
Read Info
Battery ID - displays manufacturer, model, chemistry info
Charge Data - displayes voltage, amps, percent charge, and temperature twice a second
Statistics - Manufacturing date and cycle count
Control
Single Command - displays a full, labeled list of all known commands within the command set - select one, and it'll show you the formatted result (volts, amps, percent, string, hex, etc).
Write Word - modify a value on the battery's controller, if it can be modified. Many parameters, like the serial number, cycle count, max charge, etc., can be written by referencing the chip's datasheet. Most changes are temporary, but should last long enough to put it back into a PC and see your changed values (like modifying the string "Dell" into "Hell" for kicks).
Read Word - reads a raw hex value from the controller.
Read Block - reads a text string onto the display, if it's a proper block value.
The code is pretty huge, compiles to 19450 bytes (obviously only compatible with 328p's). Strings for the commands account for about 580 bytes of it, the rest is pretty much code and libraries.
It makes use of the phi_prompt library by liudr (primarily), as well as I2C Master to more accurately harness the power of the ATMega's TWI interface to emulate SMBus instead of true I2C (repeated starts, commands, etc). It works a treat!
Configure your LCD and button arrangement by reading over the top of the file (all neatly consolidated for semi-readability), then upload away!
Planning on doing some kinda video soon with this thing, but meanwhile, here are some teaser pics.
And the code is attached!
edit: Ugh, it's amazing how much trouble a "<" where a "<=" should go can cause. Quick fix for selecting command set. =P
Little update... even though nobody's even downloaded it yet... xD
Charge data view now only updates the screen when the values change (still polls every 500ms). It also creates a histogram next to the values on the screen using 2 LCD characters for each value (10 history values total), and the range is set by the peak values (highest and lowest, starts about in the center). Except for voltage, it reads that from the battery: peak is charging voltage+0.3v, low is EDVF (End of Discharge Voltage, Final = battery usually cuts power to the PC).
(hey, now that would be a useful library to have!)
Aye, I've got the tripod all set up, and in fact I even finished up another quirkly little project (musical relays) after setting up the tripod and all. Silliness. I guess I still haven't done a video of this because it's harder to capture the function of the program in an interesting way on camera... whereas, hell, just go watch the musical relays video! xD It's so catchy from the first click... this is more, "umm, that's nice and all" kinda thing. I imagine more people will get here via Google than anything, haha... it's sad just how little information there is out there about interfacing with laptop batteries. None, to be exact... none at least that's not for manufacturers, etc. I'm sure this will come up pretty often for people
Still finding bugs in the software, though... I've got like 5 batteries that I can talk to with this thing, 3 that won't, and each of those 5 has revealed another function that's not quite working as intended. SOOOO much trouble working with datatypes and bits... le ugh. I also found out that ALL laptop "smart batteries" (i.e.: all batteries) are compatible with this protocol, so this is a much more useful tool than I originally imagined. It's called the "Smart Battery Specification", and it defines all those commands I built into the program. So I might be able to clean it up even more... getting rid of some of the redundant features (like multiple command sets, when there's only one), and adding more (like using that spec to verify communication, parse a bit field, etc). Augh... I almost think I need to waste my time on more useful endeavors =P
Hi everyone !
I have question that is: using the i2cmaster library, i can not write anything ti bq20z95 (using "i2c_smbus_write_word" function) however I can read from bq20z95. I think that it relevants to security mode of bq20z95, can any one tell me the problem ?
Thanks in advanced !
I know that, we should need "unsealed key", however, this key of every laptop's battery are different, can anyone tell me how to restart or where to find the key ?
Hello, I was looking for a way to charge a lenovo's battery with a diy charger when I found your job. It's amazing and I would love to give it a try but when I tried to compile it I have had several issues due to libraries being modified over the time
My biggest issue is with the lcd_reinit_phi() function since compiler will fail to compile there.
I was wondering if you could please post the versions of the libraries and IDE you used for your project since phi_ libraries have been updated and modified over the years (to the point that phi_buttons no longer exists).
considering the file extension of your code i am trying to compile with arduino IDE 0023 since 1.0 and so would probably give even more problems compiling...
I2C\twimaster.c.o: In function `i2c_init':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:31: multiple definition of `i2c_init'
I2C\i2cmaster.S.o:(.text+0x10): first defined here
I2C\twimaster.c.o: In function `i2c_start':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:42: multiple definition of `i2c_start'
I2C\i2cmaster.S.o:(.text+0x1a): first defined here
I2C\twimaster.c.o: In function `i2c_start_wait':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:78: multiple definition of `i2c_start_wait'
I2C\i2cmaster.S.o:(.text+0x36): first defined here
I2C\twimaster.c.o: In function `i2c_rep_start':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:130: multiple definition of `i2c_rep_start'
I2C\i2cmaster.S.o:(.text+0x22): first defined here
I2C\twimaster.c.o: In function `i2c_stop':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:141: multiple definition of `i2c_stop'
I2C\i2cmaster.S.o:(.text+0x4a): first defined here
I2C\twimaster.c.o: In function `i2c_write':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:161: multiple definition of `i2c_write'
I2C\i2cmaster.S.o:(.text+0x5a): first defined here
I2C\twimaster.c.o: In function `i2c_readAck':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:182: multiple definition of `i2c_readAck'
I2C\i2cmaster.S.o:(.text+0x96): first defined here
I2C\twimaster.c.o: In function `i2c_readNak':
C:\Users\ugur\Documents\Arduino\libraries\I2C/twimaster.c:197: multiple definition of `i2c_readNak'
I2C\i2cmaster.S.o:(.text+0x92): first defined here
Where is the problem ?
i need this program so much. i am trying to fix all problems . please help me
Hi:
I have read this post and I think the code is awesome. I have some batteries with bq2040 chip and this is the only code that I've found. But I think that is very difficult to find the correct libraries for it, at least for people who is begining with arduino like me.
I have spent many days testing and finding libraries. I'll be very grateful if somebody could give the correct libraries. I only can post my discoveries: two packet of libraries:
One of them (I have named it LibrariesPhiNew.zip) With they I have been able to compile many of the examples that came with it, but there are many errors compiling "SMBusBattery_Phi" file.
Download link:
The second: I think that many errors come from phi_prompt library, for this I have been testing and finding old libraries, and here it is: LibrariesPhiOld.zip (there are phi_prompt old libraries inside). With them I have some errors too, for example:
SMBusBattery_Phi.ino: In function 'void lcdPadBinary(uint8_t, uint8_t)':
SMBusBattery_Phi:917: error: return-statement with a value, in function returning 'void'
Download link:
I have changed: #include <WProgram.h>
for : #include <arduino.h>
In all files too.
If somebody can test, check or send us the correct libraries....
The other hand: No everybody has the LCD that came with the code..but what about to try to test the code with serial port?, I think that it will be very interesting.
"In file included from SMBusBattery_Phi.ino:2:
C:\Users\ugur\Documents\Arduino\libraries\phi_prompt/phi_prompt.h:106: error: 'multiple_button_input' has not been declared
SMBusBattery_Phi.ino: In function 'void setup()':
SMBusBattery_Phi:251: error: call of overloaded 'write(int)' is ambiguous
C:\Users\ugur\Documents\Arduino\libraries\LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t)
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:49: note: size_t Print::write(const char*)
SMBusBattery_Phi.ino: In function 'void DisplayChargeData()':
SMBusBattery_Phi:629: error: call of overloaded 'write(int)' is ambiguous
C:\Users\ugur\Documents\Arduino\libraries\LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t)
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:49: note: size_t Print::write(const char*)
SMBusBattery_Phi.ino: In function 'void lcdPadBinary(uint8_t, uint8_t)':
SMBusBattery_Phi:917: error: return-statement with a value, in function returning 'void'
SMBusBattery_Phi.ino: In function 'void lcd_reinit_phi()':
SMBusBattery_Phi:1016: error: cannot convert 'phi_buttons**' to 'int**' for argument '2' to 'void init_phi_prompt(LiquidCrystal*, int**, char**, int, int, char)'
In file included from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:28:0,
from /Users/Brusnicki/Documents/Arduino/libraries/phi_prompt/phi_prompt.h:72,
from SMBusBattery_Phi.ino:1:
SMBusBattery_Phi:149: error: variable 'bq2040Labels' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
SMBusBattery_Phi:155: error: variable 'cmdset_items' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
SMBusBattery_Phi:209: error: variable 'top_menu_items' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
SMBusBattery_Phi:216: error: variable 'setup_menu_items' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
SMBusBattery_Phi:222: error: variable 'read_menu_items' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
SMBusBattery_Phi:229: error: variable 'control_menu_items' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
C:\Users\PM\Documents\sketch_jan22b\SMBusBattery_Phi\SMBusBattery_Phi.ino:919:37: warning: return-statement with a value, in function returning 'void' [-fpermissive]
if (bits > 8) return lcd.write('E');
^
C:\Users\PM\Documents\sketch_jan22b\SMBusBattery_Phi\SMBusBattery_Phi.ino: In function 'void lcd_reinit_phi()':
SMBusBattery_Phi:1018: error: cannot convert 'phi_buttons**' to 'multiple_button_input**' for argument '2' to 'void init_phi_prompt(LiquidCrystal*, multiple_button_input**, char**, int, int, char)'
init_phi_prompt(&lcd,btns,lcd_columns, lcd_rows, '\x7e'); // Supply the liquid crystal object and the phi_buttons objecst. Also supply the column and row of the lcd, and indicator as '>'. You can also use '\x7e', which is a right arrow.