├── smbus.jpg ├── bin └── LGC-AS10D81-bq20z955-0302-program-flash.bin ├── readme.md ├── ReadAllSubclasses.ino ├── ReadEEPROM.ino ├── ReadProgramFlash.ino └── SmartBattery.ino /smbus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsa-a/Arduino-Smart-Battery/HEAD/smbus.jpg -------------------------------------------------------------------------------- /bin/LGC-AS10D81-bq20z955-0302-program-flash.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsa-a/Arduino-Smart-Battery/HEAD/bin/LGC-AS10D81-bq20z955-0302-program-flash.bin -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Arduino Smart Battery. 2 | Several utilities for working with TI bq20z... IC. 3 | Tested on Arduino Nano with Atmega328PB 16 MHz and bq20z955 IC. 4 | ### !!! Everything you do you do at your own risk !!! 5 | P.S. If you need UNSEAL keys, please contact me in the forum - 6 | 7 | https://forum.arduino.ru/t/obshhenie-s-batareyami-ot-noutbuka-na-chipah-bq20z/10399 ! 8 | 9 | ![](https://raw.githubusercontent.com/dsa-a/Arduino-Smart-Battery/main/smbus.jpg) 10 | -------------------------------------------------------------------------------- /ReadAllSubclasses.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * ReadAllSubclasses.ino (https://github.com/dsa-a/Arduino-Smart-Battery) 4 | * Copyright (C) 2021, Andrei Egorov 5 | * 6 | * This program is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | #include //!!! The WIRE library must be edited to increase the buffer to 34 (0x22) bytes !!! 21 | //!!! The standard Arduino Wire library needs to be changed in two places - Wire.h and utility/twi.h !!! 22 | 23 | //#define debug 24 | 25 | #define addr 0x0B 26 | 27 | byte buff[34]; 28 | byte sp; 29 | 30 | byte PEC(byte p, byte b) { 31 | b^=p; 32 | for (byte i=0; i<8; i++ ) { 33 | byte t=b&0x80; 34 | b<<=1; 35 | if (t!=0) b^=0x07; 36 | } 37 | return b; 38 | } 39 | 40 | void CheckWireStatus(byte wire_status) { 41 | if (wire_status!=0) { 42 | Serial.print(F("Wire error - ")); 43 | Serial.println(wire_status); 44 | while (true) ; 45 | } 46 | } 47 | 48 | void SMBCommand(byte comm) { 49 | Wire.beginTransmission(addr); 50 | Wire.write(comm); 51 | CheckWireStatus(Wire.endTransmission(false)); 52 | } 53 | 54 | void Read(byte n) { 55 | Wire.requestFrom(addr,n+1); 56 | byte p=PEC(sp, (addr<<1)+1); 57 | byte b=Wire.available(); 58 | for (byte i=0; i. 18 | */ 19 | 20 | #include //!!! The WIRE library must be edited to increase the buffer to 34 (0x22) bytes !!! 21 | //!!! The standard Arduino Wire library needs to be changed in two places - Wire.h and utility/twi.h !!! 22 | 23 | //#define debug 24 | 25 | #define addr 0x0B 26 | 27 | #define unseal_key_1 0x0414 28 | #define unseal_key_2 0x3672 29 | 30 | #define full_access_key_1 0xFFFF 31 | #define full_access_key_2 0xFFFF 32 | 33 | byte buff[34]; 34 | byte sp; 35 | 36 | byte PEC(byte p, byte b) { 37 | b^=p; 38 | for (byte i=0; i<8; i++ ) { 39 | byte t=b&0x80; 40 | b<<=1; 41 | if (t!=0) b^=0x07; 42 | } 43 | return b; 44 | } 45 | 46 | void CheckWireStatus(byte wire_status) { 47 | if (wire_status!=0) { 48 | Serial.print(F("Wire error - ")); 49 | Serial.println(wire_status); 50 | while (true) ; 51 | } 52 | } 53 | 54 | void SMBCommand(byte comm, byte ws=false) { 55 | Wire.beginTransmission(addr); 56 | Wire.write(comm); 57 | CheckWireStatus(Wire.endTransmission(ws)); 58 | } 59 | 60 | void Read(byte n) { 61 | Wire.requestFrom(addr,n+1); 62 | byte p=PEC(sp, (addr<<1)+1); 63 | byte b=Wire.available(); 64 | for (byte i=0; i. 18 | */ 19 | 20 | #include //!!! The WIRE library must be edited to increase the buffer to 98 (0x62) bytes !!! 21 | //!!! The standard Arduino Wire library needs to be changed in two places - Wire.h and utility/twi.h !!! 22 | 23 | //#define debug 24 | 25 | #define addr 0x0B 26 | 27 | #define unseal_key_1 0x0414 28 | #define unseal_key_2 0x3672 29 | 30 | #define full_access_key_1 0xFFFF 31 | #define full_access_key_2 0xFFFF 32 | 33 | byte buff[98]; 34 | byte sp; 35 | 36 | byte PEC(byte p, byte b) { 37 | b^=p; 38 | for (byte i=0; i<8; i++ ) { 39 | byte t=b&0x80; 40 | b<<=1; 41 | if (t!=0) b^=0x07; 42 | } 43 | return b; 44 | } 45 | 46 | void CheckWireStatus(byte wire_status) { 47 | if (wire_status!=0) { 48 | Serial.print(F("Wire error - ")); 49 | Serial.println(wire_status); 50 | while (true) ; 51 | } 52 | } 53 | 54 | void SMBCommand(byte comm, byte ws=false) { 55 | Wire.beginTransmission(addr); 56 | Wire.write(comm); 57 | CheckWireStatus(Wire.endTransmission(ws)); 58 | } 59 | 60 | void Read(byte n) { 61 | Wire.requestFrom(addr,n+1); 62 | byte p=PEC(sp, (addr<<1)+1); 63 | byte b=Wire.available(); 64 | for (byte i=0; i. 18 | */ 19 | 20 | #include //!!! The WIRE library must be edited to increase the buffer to 34 (0x22) bytes !!! 21 | //!!! The standard Arduino Wire library needs to be changed in two places - Wire.h and utility/twi.h !!! 22 | 23 | //#define debug 24 | 25 | #define addr 0x0B 26 | 27 | #define new_capacity 4400 28 | 29 | #define unseal_key_1 0x0414 30 | #define unseal_key_2 0x3672 31 | 32 | #define full_access_key_1 0xFFFF 33 | #define full_access_key_2 0xFFFF 34 | 35 | #define pf_clear_key_1 0x2673 36 | #define pf_clear_key_2 0x1712 37 | 38 | #define year (__DATE__[7]-'0')*1000+(__DATE__[8]-'0')*100+(__DATE__[9]-'0')*10+(__DATE__[10]-'0') 39 | #define month (__DATE__[0] == 'J' && __DATE__[1] == 'a') ? 1 : \ 40 | (__DATE__[0] == 'F') ? 2 : \ 41 | (__DATE__[0] == 'M' && __DATE__[2] == 'r') ? 3 : \ 42 | (__DATE__[0] == 'A' && __DATE__[1] == 'p') ? 4 : \ 43 | (__DATE__[0] == 'M' && __DATE__[2] == 'y') ? 5 : \ 44 | (__DATE__[0] == 'J' && __DATE__[2] == 'n') ? 6 : \ 45 | (__DATE__[0] == 'J' && __DATE__[2] == 'l') ? 7 : \ 46 | (__DATE__[0] == 'A' && __DATE__[1] == 'u') ? 8 : \ 47 | (__DATE__[0] == 'S') ? 9 : \ 48 | (__DATE__[0] == 'O') ? 10 : \ 49 | (__DATE__[0] == 'N') ? 11 : \ 50 | (__DATE__[0] == 'D') ? 12 : 0 51 | #define day (((__DATE__[4] >= '0') ? (__DATE__[4]) : '0')-'0')*10+(__DATE__[5]-'0') 52 | 53 | byte buff[34]; 54 | 55 | #if defined (debug) 56 | byte sp; 57 | 58 | byte PEC(byte p, byte b) { 59 | b^=p; 60 | for (byte i=0; i<8; i++ ) { 61 | byte t=b&0x80; 62 | b<<=1; 63 | if (t!=0) b^=0x07; 64 | } 65 | return b; 66 | } 67 | #endif 68 | 69 | void CheckWireStatus(byte wire_status) { 70 | if (wire_status!=0) { 71 | Serial.print(F("Wire error - ")); 72 | Serial.println(wire_status); 73 | while (true) ; 74 | } 75 | } 76 | 77 | void SMBCommand(byte comm) { 78 | Wire.beginTransmission(addr); 79 | Wire.write(comm); 80 | CheckWireStatus(Wire.endTransmission(false)); 81 | } 82 | 83 | void Read(byte n) { 84 | Wire.requestFrom(addr,n+1); 85 | #if defined (debug) 86 | byte p=PEC(sp, (addr<<1)+1); 87 | #endif 88 | byte b=Wire.available(); 89 | for (byte i=0; i>1)); Serial.print("."); Serial.print(((buff[1]&0b00000001)<<3)+(buff[0]>>5));Serial.print("."); Serial.println(buff[0]&0b00011111); 176 | ReadSMB(byte(0x19)); Serial.print(F("DesignVoltage: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 177 | ReadBlockSMB(0x20); Serial.print(F("ManufName: ")); printBlock(); 178 | ReadBlockSMB(0x21); Serial.print(F("DeviceName: ")); printBlock(); 179 | ReadSMB(byte(0x1C)); Serial.print(F("SerialNumber: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 180 | ReadSMB(byte(0x14)); Serial.print(F("ChargingCurrent: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mA"); 181 | ReadSMB(byte(0x15)); Serial.print(F("ChargingVoltage: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 182 | ReadBlockSMB(0x22); Serial.print(F("DeviceChemistry: ")); printBlock(); 183 | ReadSMB(byte(0x08)); Serial.print(F("Temperature: ")); Serial.print(float(buff[1]*256+buff[0])/10-273); Serial.println(" C"); 184 | ReadSMB(byte(0x09)); Serial.print(F("Voltage: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 185 | ReadSMB(byte(0x0A)); Serial.print(F("Current: ")); Serial.print(int(buff[1]*256+buff[0])); Serial.println(" mA"); 186 | ReadSMB(byte(0x0D)); Serial.print(F("RelativeSOC: ")); Serial.print(buff[0]); Serial.println(" %"); 187 | ReadSMB(byte(0x0E)); Serial.print(F("AbsoluteSOC: ")); Serial.print(buff[0]); Serial.println(" %"); 188 | ReadSMB(byte(0x0F)); Serial.print(F("RemainingCapacity: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mAh"); 189 | ReadSMB(byte(0x3C)); Serial.print(F("VCELL4: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 190 | ReadSMB(byte(0x3D)); Serial.print(F("VCELL3: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 191 | ReadSMB(byte(0x3E)); Serial.print(F("VCELL2: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 192 | ReadSMB(byte(0x3F)); Serial.print(F("VCELL1: ")); Serial.print(buff[1]*256+buff[0]); Serial.println(" mV"); 193 | ReadSMB(byte(0x1A)); Serial.print(F("SpecificationInfo: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 194 | ReadSMB(byte(0x16)); Serial.print(F("Battery Status: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 195 | if (buff[1]&0b10000000) Serial.print("OCA|"); 196 | if (buff[1]&0b01000000) Serial.print("TCA|"); 197 | if (buff[1]&0b00010000) Serial.print("OTA|"); 198 | if (buff[1]&0b00001000) Serial.print("TDA|"); 199 | if (buff[1]&0b00000010) Serial.print("RCA|"); 200 | if (buff[1]&0b00000001) Serial.print("RTA|"); 201 | if (buff[0]&0b10000000) Serial.print("INIT|"); 202 | if (buff[0]&0b01000000) Serial.print("DSG|"); 203 | if (buff[0]&0b00100000) Serial.print("FC|"); 204 | if (buff[0]&0b00010000) Serial.print("FD|"); 205 | if (buff[0]&0b00001000) Serial.print("EC3|"); 206 | if (buff[0]&0b00000100) Serial.print("EC2|"); 207 | if (buff[0]&0b00000010) Serial.print("EC1|"); 208 | if (buff[0]&0b00000001) Serial.print("EC0|"); 209 | Serial.println(); 210 | ReadSMB(word(0x0054)); Serial.print(F("Operation Status: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 211 | if (buff[1]&0b10000000) Serial.print("PRES|"); 212 | if (buff[1]&0b01000000) Serial.print("FAS|"); 213 | if (buff[1]&0b00100000) Serial.print("SS|"); 214 | if (buff[1]&0b00010000) Serial.print("CSV|"); 215 | if (buff[1]&0b00000100) Serial.print("LDMD|"); 216 | if (buff[0]&0b10000000) Serial.print("WAKE|"); 217 | if (buff[0]&0b01000000) Serial.print("DSG|"); 218 | if (buff[0]&0b00100000) Serial.print("XDSG|"); 219 | if (buff[0]&0b00010000) Serial.print("XDSGI|"); 220 | if (buff[0]&0b00000100) Serial.print("R_DIS|"); 221 | if (buff[0]&0b00000010) Serial.print("VOK|"); 222 | if (buff[0]&0b00000001) Serial.print("QEN|"); 223 | Serial.println(); 224 | if (buff[1]&0b00100000) { 225 | Serial.println(F("Sealed")); 226 | Read123(); 227 | } else { 228 | Serial.println(F("Unsealed")); 229 | if (!(buff[1]&0b01000000)) { 230 | Serial.println(F("Pack in Full Access mode")); 231 | ReadBlockSMB(0x60); Serial.print(F("UnSealKey: ")); printHEX(buff[2]); printHEX(buff[1]); printHEX(buff[4]); printHEX(buff[3]); Serial.println(" Hex"); 232 | ReadBlockSMB(0x61); Serial.print(F("FullAccessKey: ")); printHEX(buff[2]); printHEX(buff[1]); printHEX(buff[4]); printHEX(buff[3]); Serial.println(" Hex"); 233 | ReadBlockSMB(0x62); Serial.print(F("PFKey: ")); printHEX(buff[2]); printHEX(buff[1]); printHEX(buff[4]); printHEX(buff[3]); Serial.println(" Hex"); 234 | }; 235 | ReadSMB(byte(0x0C)); Serial.print(F("MaxError: ")); Serial.print(buff[0]); Serial.println(" %"); 236 | ReadSMB(word(0x0051)); Serial.print(F("SafetyStatus: ")); 237 | if ((buff[1]==0)&&(buff[0]==0)) { 238 | Serial.println("OK"); 239 | } else { 240 | printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 241 | if (buff[1]&0b10000000) Serial.print("OTD|"); 242 | if (buff[1]&0b01000000) Serial.print("OTC|"); 243 | if (buff[1]&0b00100000) Serial.print("OCD|"); 244 | if (buff[1]&0b00010000) Serial.print("OCC|"); 245 | if (buff[1]&0b00001000) Serial.print("OCD2|"); 246 | if (buff[1]&0b00000100) Serial.print("OCC2|"); 247 | if (buff[1]&0b00000010) Serial.print("PUV|"); 248 | if (buff[1]&0b00000001) Serial.print("POV|"); 249 | if (buff[0]&0b10000000) Serial.print("CUV|"); 250 | if (buff[0]&0b01000000) Serial.print("COV|"); 251 | if (buff[0]&0b00100000) Serial.print("PF|"); 252 | if (buff[0]&0b00010000) Serial.print("HWDG|"); 253 | if (buff[0]&0b00001000) Serial.print("WDF|"); 254 | if (buff[0]&0b00000100) Serial.print("AOCD|"); 255 | if (buff[0]&0b00000010) Serial.print("SCC|"); 256 | if (buff[0]&0b00000001) Serial.print("SCD|"); 257 | Serial.println(); 258 | }; 259 | ReadSMB(word(0x0053)); Serial.print(F("PFStatus: ")); 260 | if ((buff[1]==0)&&(buff[0]==0)) { 261 | Serial.println("OK"); 262 | } else { 263 | printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 264 | if (buff[1]&0b10000000) Serial.print("FBF|"); 265 | if (buff[1]&0b00010000) Serial.print("SOPT|"); 266 | if (buff[1]&0b00001000) Serial.print("SOCD|"); 267 | if (buff[1]&0b00000100) Serial.print("SOCC|"); 268 | if (buff[1]&0b00000010) Serial.print("AFE_P|"); 269 | if (buff[1]&0b00000001) Serial.print("AFE_C|"); 270 | if (buff[0]&0b10000000) Serial.print("DFF|"); 271 | if (buff[0]&0b01000000) Serial.print("DFETF|"); 272 | if (buff[0]&0b00100000) Serial.print("CFETF|"); 273 | if (buff[0]&0b00010000) Serial.print("CIM|"); 274 | if (buff[0]&0b00001000) Serial.print("SOTD|"); 275 | if (buff[0]&0b00000100) Serial.print("SOTC|"); 276 | if (buff[0]&0b00000010) Serial.print("SOV|"); 277 | if (buff[0]&0b00000001) Serial.print("PFIN|"); 278 | Serial.println(); 279 | }; 280 | ReadSMB(word(0x0055)); Serial.print(F("Charging Status: ")); 281 | if ((buff[1]==0)&&(buff[0]==0)) { 282 | Serial.println("OK"); 283 | } else { 284 | printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 285 | if (buff[1]&0b10000000) Serial.print("XCHG|"); 286 | if (buff[1]&0b01000000) Serial.print("CHGSUSP|"); 287 | if (buff[1]&0b00100000) Serial.print("PCHG|"); 288 | if (buff[1]&0b00010000) Serial.print("MCHG|"); 289 | if (buff[1]&0b00001000) Serial.print("TCHG1|"); 290 | if (buff[1]&0b00000100) Serial.print("TCHG2|"); 291 | if (buff[1]&0b00000010) Serial.print("FCHG|"); 292 | if (buff[1]&0b00000001) Serial.print("PULSE|"); 293 | if (buff[0]&0b10000000) Serial.print("PLSOFF|"); 294 | if (buff[0]&0b01000000) Serial.print("CB|"); 295 | if (buff[0]&0b00100000) Serial.print("PCMTO|"); 296 | if (buff[0]&0b00010000) Serial.print("FCMTO|"); 297 | if (buff[0]&0b00001000) Serial.print("OCHGV|"); 298 | if (buff[0]&0b00000100) Serial.print("OCHGI|"); 299 | if (buff[0]&0b00000010) Serial.print("OC|"); 300 | if (buff[0]&0b00000001) Serial.print("XCHGLV|"); 301 | Serial.println(); 302 | }; 303 | ReadSMB(byte(0x46)); Serial.print(F("FETControl: ")); 304 | if (buff[0]==0) { 305 | Serial.println("OK"); 306 | } else { 307 | printHEX(buff[0]); Serial.println(" Hex"); 308 | if (buff[0]&0b00010000) Serial.print("OD|"); 309 | if (buff[0]&0b00001000) Serial.print("ZVCHG|"); 310 | if (buff[0]&0b00000100) Serial.print("CHG|"); 311 | if (buff[0]&0b00000010) Serial.print("DSG|"); 312 | Serial.println(); 313 | }; 314 | ReadSMBSubclass(82,0x78); 315 | Serial.print(F("Update Status: ")); Serial.println(buff[13]); 316 | Serial.print(F("Qmax Cell0: ")); Serial.println(buff[1]*256+buff[2]); 317 | Serial.print(F("Qmax Cell1: ")); Serial.println(buff[3]*256+buff[4]); 318 | Serial.print(F("Qmax Cell2: ")); Serial.println(buff[5]*256+buff[6]); 319 | Serial.print(F("Qmax Cell3: ")); Serial.println(buff[7]*256+buff[8]); 320 | Serial.print(F("Qmax Pack : ")); Serial.println(buff[9]*256+buff[10]); 321 | for (byte i=88; i<=91; i++) { 322 | ReadSMBSubclass(i,0x78); 323 | Serial.print("Cell"); 324 | Serial.print(i-88); 325 | Serial.print(" R_a flag: "); printHEX(buff[1]); printHEX(buff[2]); Serial.println(); 326 | } 327 | Read123(); 328 | ReadSMB(word(0x0006)); Serial.print(F("Manufacturer Status: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 329 | if (buff[1]&0b10000000) Serial.print("FET1|"); 330 | if (buff[1]&0b01000000) Serial.print("FET0|"); 331 | if (buff[1]&0b00100000) Serial.print("PF1|"); 332 | if (buff[1]&0b00010000) Serial.print("PF0|"); 333 | if (buff[1]&0b00001000) Serial.print("STATE3|"); 334 | if (buff[1]&0b00000100) Serial.print("STATE2|"); 335 | if (buff[1]&0b00000010) Serial.print("STATE1|"); 336 | if (buff[1]&0b00000001) Serial.print("STATE0|"); 337 | Serial.println(); 338 | ReadSMB(word(0x0008)); Serial.print(F("Chemistry ID: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 339 | delay(100); 340 | ReadSMB(byte(0x03)); Serial.print(F("BatteryMode: ")); printHEX(buff[1]); printHEX(buff[0]); Serial.println(" Hex"); 341 | if (buff[1]&0b10000000) Serial.print("CapM|"); 342 | if (buff[1]&0b01000000) Serial.print("ChgM|"); 343 | if (buff[1]&0b00100000) Serial.print("AM|"); 344 | if (buff[1]&0b00000010) Serial.print("PB|"); 345 | if (buff[1]&0b00000001) Serial.print("CC|"); 346 | if (buff[0]&0b10000000) Serial.print("CF|"); 347 | if (buff[0]&0b00000010) Serial.print("PBS|"); 348 | if (buff[0]&0b00000001) Serial.print("ICC|"); 349 | Serial.println(); 350 | }; 351 | 352 | } 353 | 354 | void setup() { 355 | Wire.begin(); 356 | Serial.begin(9600); 357 | Serial.println(F("Arduino Smart Battery")); 358 | Serial.println(F("Several utilities for working with TI bq20z... IC")); 359 | Serial.println(F("Press Enter...")); 360 | while (Serial.available()==0); 361 | Serial.print(F("Checking communication with the device at address 0x")); 362 | printHEX(addr); 363 | Serial.println("..."); 364 | byte st; 365 | do { 366 | Wire.beginTransmission(addr); 367 | st=Wire.endTransmission(); 368 | if (st!=0) Serial.println(F("The device is not responding.")); delay(1000); 369 | } while (st!=0); 370 | Serial.println(F("The device was found !!!")); 371 | } 372 | 373 | void loop() { 374 | delay(1); 375 | if (Serial.available()==0) { 376 | Serial.println(F("--------------------")); 377 | Serial.println(F("Select operation:")); 378 | Serial.println(F("1. Read pack info.")); 379 | Serial.println(F("2. Pack Reset.")); 380 | Serial.println(F("3. Unsealing a pack.")); 381 | Serial.println(F("4. Move pack to Full Access mode.")); 382 | Serial.println(F("5. Clearing a Permanent Failure.")); 383 | Serial.println(F("6. Clearing CycleCount.")); 384 | Serial.println(F("7. Setting current date.")); 385 | Serial.println(F("8. Writing DesignCapacity, QMAX, Update status, Ra_table.")); 386 | Serial.println(F("9. Begin the Impedance Track algorithm.")); 387 | while (Serial.available()==0); 388 | switch (Serial.read()) { 389 | case 0x31: 390 | Serial.println(F("Pack Info...")); 391 | info(); 392 | break; 393 | case 0x32: 394 | WriteSMBWord(0x00,0x0041); 395 | Serial.println(F("Reseting...")); 396 | delay(1000); 397 | break; 398 | case 0x33: 399 | WriteSMBWord(0x00,unseal_key_1); 400 | WriteSMBWord(0x00,unseal_key_2); 401 | Serial.println(F("Unsealing...")); 402 | break; 403 | case 0x34: 404 | WriteSMBWord(0x00,full_access_key_1); 405 | WriteSMBWord(0x00,full_access_key_2); 406 | Serial.println(F("Move to Full Access mode...")); 407 | break; 408 | case 0x35: 409 | WriteSMBWord(0x00,pf_clear_key_1); 410 | WriteSMBWord(0x00,pf_clear_key_2); 411 | Serial.println(F("Clearing a Permanent Failure...")); 412 | break; 413 | case 0x36: 414 | WriteSMBWord(0x17,0x0000); 415 | Serial.println(F("Clearing CycleCount...")); 416 | break; 417 | case 0x37: 418 | WriteSMBWord(0x1B,(year-1980)*512+int(month)*32+day); 419 | Serial.println(F("Setting current date...")); 420 | break; 421 | case 0x38: 422 | Serial.println(F("Writing DesignCapacity, QMAX, Update status, Ra_table...")); 423 | WriteSMBWord(0x18,new_capacity); 424 | delay(100); 425 | ReadSMBSubclass(82,0x78); 426 | buff[1]=highByte(new_capacity); 427 | buff[2]=lowByte(new_capacity); 428 | buff[3]=highByte(new_capacity); 429 | buff[4]=lowByte(new_capacity); 430 | buff[5]=highByte(new_capacity); 431 | buff[6]=lowByte(new_capacity); 432 | buff[7]=highByte(new_capacity); 433 | buff[8]=lowByte(new_capacity); 434 | buff[9]=highByte(new_capacity); 435 | buff[10]=lowByte(new_capacity); 436 | buff[13]=0x00; 437 | WriteSMBSubclass(82,0x78); 438 | for (byte i=88; i<=95; i++) { 439 | buff[0]=0x20; 440 | buff[1]=0xFF; 441 | buff[2]=(i<92) ? 0x55 : 0xFF; 442 | buff[3]=0x00; 443 | buff[4]=0xA0; 444 | buff[5]=0x00; 445 | buff[6]=0xA6; 446 | buff[7]=0x00; 447 | buff[8]=0x99; 448 | buff[9]=0x00; 449 | buff[10]=0x97; 450 | buff[11]=0x00; 451 | buff[12]=0x91; 452 | buff[13]=0x00; 453 | buff[14]=0x98; 454 | buff[15]=0x00; 455 | buff[16]=0xB0; 456 | buff[17]=0x00; 457 | buff[18]=0xCC; 458 | buff[19]=0x00; 459 | buff[20]=0xDE; 460 | buff[21]=0x00; 461 | buff[22]=0xFE; 462 | buff[23]=0x01; 463 | buff[24]=0x3B; 464 | buff[25]=0x01; 465 | buff[26]=0xB5; 466 | buff[27]=0x02; 467 | buff[28]=0x8B; 468 | buff[29]=0x03; 469 | buff[30]=0xE9; 470 | buff[31]=0x05; 471 | buff[32]=0xB2; 472 | WriteSMBSubclass(i,0x78); 473 | } 474 | break; 475 | case 0x39: 476 | WriteSMBWord(0x00,0x0021); 477 | Serial.println(F("Begin the Impedance Track algorithm...")); 478 | break; 479 | } 480 | } else Serial.read(); 481 | } 482 | --------------------------------------------------------------------------------