2828
2929#include " SBMInfo.h"
3030#include < Wire.h>
31+ #include " ADCUtils.hpp"
3132
3233#define VERSION_EXAMPLE " 4.1"
3334
35+ #if defined(__AVR__)
3436/*
37+ * Available only for some AVR CPU's like ATmega328
3538 * This requires 4 resistors at Pins A0 to A3, see documentation in file MeasureVoltageAndResistance.hpp
3639 */
3740#define USE_VOLTAGE_AND_RESISTANCE_MEASUREMENT
4750// #define STOP_DISCHARGE_AT_PERCENTAGE
4851#define DISCHARGE_STOP_MILLIVOLT 3300 // to be below the guessed EDV2 value
4952#define STOP_DISCHARGE_AT_MILLIVOLT
50- #if defined(STOP_DISCHARGE_AT_PERCENTAGE) && defined(STOP_DISCHARGE_AT_MILLIVOLT)
53+ # if defined(STOP_DISCHARGE_AT_PERCENTAGE) && defined(STOP_DISCHARGE_AT_MILLIVOLT)
5154#warning Ignore STOP_DISCHARGE_AT_MILLIVOLT value and stop discharge at DISCHARGE_STOP_PERCENTAGE value
52- #else
53- #endif
55+ # endif
56+ #endif // defined(__AVR__)
5457
5558/*
5659 * Activate the type of LCD connection you use.
@@ -110,7 +113,7 @@ LiquidCrystal_I2C myLCD(0x27, LCD_COLUMNS, LCD_ROWS); // set the LCD address to
110113LiquidCrystal myLCD (7 , 8 , 3 , 4 , 5 , 6 ); // This also clears display
111114#endif
112115
113- #if defined(USE_VOLTAGE_AND_RESISTANCE_MEASUREMENT)
116+ #if defined(USE_VOLTAGE_AND_RESISTANCE_MEASUREMENT) // Available only for some AVR CPU's like ATmega328
114117#define NO_PRINT_OF_RESISTOR_MEASURMENT_VOLTAGE
115118// Include it after LCD settings, it requires the macros USE_LCD and USE_2004_LCD to be set
116119#include " MeasureVoltageAndResistance.hpp"
@@ -208,22 +211,22 @@ const char RemainingTimeAlarm[] PROGMEM = "Remaining time alarm";
208211const char Battery_Mode[] PROGMEM = " Battery mode" ;
209212const char Pack_Status[] PROGMEM = " Pack config and status" ;
210213
211- struct SBMFunctionDescriptionStruct sBatteryModeFuctionDescription = { BATTERY_MODE, Battery_Mode, &printBatteryMode };
214+ struct SBMFunctionDescriptionStruct sBatteryModeFuctionDescription = { BATTERY_MODE, Battery_Mode, &printBatteryMode, NULL , 0 , 0 };
212215/*
213216 * Design voltage must be read before reading other capacity values for conversion of mWh to mAh
214217 */
215218struct SBMFunctionDescriptionStruct sSBMStaticFunctionDescriptionArray [] = { {
216- SERIAL_NUM, Serial_Number }, {
217- MFG_DATE, Manufacture_Date, &printManufacturerDate }, {
218- DESIGN_VOLTAGE, Design_Voltage, &printVoltage, " " }, {
219- DESIGN_CAPACITY, Design_Capacity, &printCapacity, " " }, {
220- CHARGING_CURRENT, Charging_Current, &printCurrent }, {
221- CHARGING_VOLTAGE, Charging_Voltage, &printVoltage }, {
222- SPEC_INFO, Specification_Info, &printSpecificationInfo }, {
223- CYCLE_COUNT, Cycle_Count, &printSigned, " cycl." }, {
224- MAX_ERROR, Max_Error_of_charge_calculation, &printPercentage }, {
225- REMAINING_TIME_ALARM, RemainingTimeAlarm, &printTime }, {
226- REMAINING_CAPACITY_ALARM, Remaining_Capacity_Alarm, &printCapacity } };
219+ SERIAL_NUM, Serial_Number, NULL , NULL , 0 , 0 }, {
220+ MFG_DATE, Manufacture_Date, &printManufacturerDate, NULL , 0 , 0 }, {
221+ DESIGN_VOLTAGE, Design_Voltage, &printVoltage, " " , 0 , 0 }, {
222+ DESIGN_CAPACITY, Design_Capacity, &printCapacity, " " , 0 , 0 }, {
223+ CHARGING_CURRENT, Charging_Current, &printCurrent, NULL , 0 , 0 }, {
224+ CHARGING_VOLTAGE, Charging_Voltage, &printVoltage, NULL , 0 , 0 }, {
225+ SPEC_INFO, Specification_Info, &printSpecificationInfo, NULL , 0 , 0 }, {
226+ CYCLE_COUNT, Cycle_Count, &printSigned, " cycl." , 0 , 0 }, {
227+ MAX_ERROR, Max_Error_of_charge_calculation, &printPercentage, NULL , 0 , 0 }, {
228+ REMAINING_TIME_ALARM, RemainingTimeAlarm, &printTime, NULL , 0 , 0 }, {
229+ REMAINING_CAPACITY_ALARM, Remaining_Capacity_Alarm, &printCapacity, NULL , 0 , 0 } };
227230
228231const char Full_Charge_Capacity[] PROGMEM = " Full charge capacity" ;
229232const char Remaining_Capacity[] PROGMEM = " Remaining capacity" ;
@@ -243,19 +246,19 @@ const char Temperature[] PROGMEM = "Temperature";
243246#define VOLTAGE_PRINT_DELTA_MILLIDEGREE 100 // Print only if changed by 0.1 ore more degree
244247
245248struct SBMFunctionDescriptionStruct sSBMDynamicFunctionDescriptionArray [] = { {
246- RELATIVE_SOC, Relative_Charge, &printRelativeCharge }, { /* must be first, value is printed in Remaining_Capacity */
247- ABSOLUTE_SOC, Absolute_Charge, &printPercentage }, {
248- FULL_CHARGE_CAPACITY, Full_Charge_Capacity, &printCapacity, " " }/* DescriptionLCD must be not NULL */ , {
249- REMAINING_CAPACITY, Remaining_Capacity, &printCapacity, " remCap" }, {
250- VOLTAGE, Voltage, &printVoltage, " " , VOLTAGE_PRINT_DELTA_MILLIVOLT } /* DescriptionLCD must be not NULL */ , {
251- CURRENT, Current, &printCurrent, " " , VOLTAGE_PRINT_DELTA_MILLIAMPERE } /* DescriptionLCD must be not NULL */ , {
252- AVERAGE_CURRENT, Average_Current_of_last_minute, &printCurrent, NULL , 5 } /* Print only changes of 5 mA or more */ , {
253- TEMPERATURE, Temperature, &printTemperature, NULL , VOLTAGE_PRINT_DELTA_MILLIDEGREE }, {
254- RUN_TIME_TO_EMPTY, Minutes_remaining_until_empty, &printTime, " min " }, {
255- AVERAGE_TIME_TO_EMPTY, Average_minutes_remaining_until_empty, &printTime }, {
256- TIME_TO_FULL, Minutes_remaining_for_full_charge, &printTime, " min " }, {
257- BATTERY_STATUS, Battery_Status, &printBatteryStatus }, {
258- PACK_STATUS, Pack_Status, &printPackStatus } };
249+ RELATIVE_SOC, Relative_Charge, &printRelativeCharge, NULL , 0 , 0 }, { /* must be first, value is printed in Remaining_Capacity */
250+ ABSOLUTE_SOC, Absolute_Charge, &printPercentage, NULL , 0 , 0 }, {
251+ FULL_CHARGE_CAPACITY, Full_Charge_Capacity, &printCapacity, " " , 0 , 0 }/* DescriptionLCD must be not NULL */ , {
252+ REMAINING_CAPACITY, Remaining_Capacity, &printCapacity, " remCap" , 0 , 0 }, {
253+ VOLTAGE, Voltage, &printVoltage, " " , VOLTAGE_PRINT_DELTA_MILLIVOLT, 0 } /* DescriptionLCD must be not NULL */ , {
254+ CURRENT, Current, &printCurrent, " " , VOLTAGE_PRINT_DELTA_MILLIAMPERE, 0 } /* DescriptionLCD must be not NULL */ , {
255+ AVERAGE_CURRENT, Average_Current_of_last_minute, &printCurrent, NULL , 5 , 0 } /* Print only changes of 5 mA or more */ , {
256+ TEMPERATURE, Temperature, &printTemperature, NULL , VOLTAGE_PRINT_DELTA_MILLIDEGREE, 0 }, {
257+ RUN_TIME_TO_EMPTY, Minutes_remaining_until_empty, &printTime, " min " , 0 , 0 }, {
258+ AVERAGE_TIME_TO_EMPTY, Average_minutes_remaining_until_empty, &printTime, NULL , 0 , 0 }, {
259+ TIME_TO_FULL, Minutes_remaining_for_full_charge, &printTime, " min " , 0 , 0 }, {
260+ BATTERY_STATUS, Battery_Status, &printBatteryStatus, NULL , 0 , 0 }, {
261+ PACK_STATUS, Pack_Status, &printPackStatus, NULL , 0 , 0 } };
259262
260263/*
261264 * These aren't part of the standard, but work with some packs.
@@ -271,11 +274,11 @@ const char State_of_Health[] PROGMEM = "State of Health";
271274#define NON_STANDARD_INFO_NOT_SUPPORTED 2
272275int sNonStandardInfoSupportedByPack = NON_STANDARD_INFO_NOT_INTIALIZED;
273276struct SBMFunctionDescriptionStruct sSBMNonStandardFunctionDescriptionArray [] = { {
274- CELL1_VOLTAGE, Cell_1_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT }, {
275- CELL2_VOLTAGE, Cell_2_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT }, {
276- CELL3_VOLTAGE, Cell_3_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT }, {
277- CELL4_VOLTAGE, Cell_4_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT }, {
278- STATE_OF_HEALTH, State_of_Health } };
277+ CELL1_VOLTAGE, Cell_1_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT, 0 }, {
278+ CELL2_VOLTAGE, Cell_2_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT, 0 }, {
279+ CELL3_VOLTAGE, Cell_3_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT, 0 }, {
280+ CELL4_VOLTAGE, Cell_4_Voltage, &printCellVoltage, NULL , VOLTAGE_PRINT_DELTA_MILLIVOLT, 0 }, {
281+ STATE_OF_HEALTH, State_of_Health, NULL , NULL , 0 , 0 } };
279282
280283bool sCapacityModePower ; // false = current, true = power
281284uint16_t sDesignVoltageMillivolt ; // to retrieve last value for mWh to mA conversion
@@ -302,17 +305,17 @@ const char TimeToEmpty_at_rate[] PROGMEM = "TimeToEmpty at rate";
302305const char Can_be_delivered_for_10_seconds_at_rate[] PROGMEM = " Can be delivered for 10 seconds at rate " ;
303306
304307struct SBMFunctionDescriptionStruct sSBMATRateFunctionDescriptionArray [] = { {
305- AtRateTimeToFull, TimeToFull_at_rate, &printTime }, {
306- AtRateTimeToEmpty, TimeToEmpty_at_rate, &printTime }, {
307- AtRateOK, Can_be_delivered_for_10_seconds_at_rate } };
308+ AtRateTimeToFull, TimeToFull_at_rate, &printTime, NULL , 0 , 0 }, {
309+ AtRateTimeToEmpty, TimeToEmpty_at_rate, &printTime, NULL , 0 , 0 }, {
310+ AtRateOK, Can_be_delivered_for_10_seconds_at_rate, NULL , NULL , 0 , 0 } };
308311
309312const char Charging_Status[] PROGMEM = " Charging Status" ;
310313const char Operation_Status[] PROGMEM = " Operation Status" ;
311314const char Pack_Voltage[] PROGMEM = " Pack Voltage" ;
312315struct SBMFunctionDescriptionStruct sSBMbq20z70FunctionDescriptionArray [] = { {
313- BQ20Z70_ChargingStatus, Charging_Status, &printHexAndBinary }, {
314- BQ20Z70_OperationStatus, Operation_Status, &printHexAndBinary }, {
315- BQ20Z70_PackVoltage, Pack_Voltage, &printVoltage } };
316+ BQ20Z70_ChargingStatus, Charging_Status, &printHexAndBinary, NULL , 0 , 0 }, {
317+ BQ20Z70_OperationStatus, Operation_Status, &printHexAndBinary, NULL , 0 , 0 }, {
318+ BQ20Z70_PackVoltage, Pack_Voltage, &printVoltage, NULL , 0 , 0 } };
316319
317320/*
318321 * Helper macro for getting a macro definition as string
@@ -354,8 +357,10 @@ void setup() {
354357 // set up the LCD's number of columns and rows:
355358 myLCD.begin (LCD_COLUMNS, LCD_ROWS); // This also clears display
356359 myLCD.print (F (" SBMInfo " VERSION_EXAMPLE " " ));
360+ #if defined(__AVR__)
357361 myLCD.print (((float ) getVCCVoltageMillivolt ()) / 1000 , 2 );
358362 myLCD.print (F (" V" ));
363+ #endif
359364
360365 myLCD.setCursor (0 , 1 );
361366 myLCD.print (F (__DATE__));
@@ -371,11 +376,13 @@ void setup() {
371376 Serial.println (F (" mV" ));
372377#endif
373378
379+ #if defined(__AVR__)
374380 if (getVCCVoltageMillivolt () < 4300 || digitalRead (FORCE_LCD_DISPLAY_TIMING_PIN) == LOW) {
375381 sVCCisLIPO = true ;
376382 } else {
377383 Serial.println (F (" No LiPo supply detected -> fast display timing" ));
378384 }
385+ #endif
379386
380387 /*
381388 * Check for I2C device attached.
@@ -391,17 +398,18 @@ void setup() {
391398 * Check for I2C device and blink until device attached
392399 * This sets the I2C stop condition for the next commands
393400 */
394- sI2CDeviceAddress = scanForAttachedI2CDevice (&Serial);
395- if (sI2CDeviceAddress == I2C_SCAN_TIMEOUT) {
401+ int8_t tI2CDeviceAddress = scanForAttachedI2CDevice (&Serial);
402+ if (tI2CDeviceAddress == I2C_SCAN_TIMEOUT) {
396403 myLCD.setCursor (0 , 2 );
397404 myLCD.print (F (" SDA or SCL at ground" ));
398- } else if (sI2CDeviceAddress == I2C_SCAN_NO_DEVICE) {
405+ } else if (tI2CDeviceAddress == I2C_SCAN_NO_DEVICE) {
399406 myLCD.setCursor (0 , 2 );
400407 myLCD.print (" Scan for device " );
401408 char tString[5 ];
402409 sprintf_P (tString, PSTR (" %4u" ), sScanCount );
403410 myLCD.print (tString);
404- } else if (sI2CDeviceAddress >= 0 ) {
411+ } else if (tI2CDeviceAddress >= 0 ) {
412+ sI2CDeviceAddress = tI2CDeviceAddress;
405413 myLCD.setCursor (0 , 2 );
406414 myLCD.print (F (" Found device at 0x" ));
407415 myLCD.print (sI2CDeviceAddress , HEX);
@@ -585,7 +593,7 @@ void writeCommandWithRetry(uint8_t aCommand) {
585593
586594/*
587595 * First write the command/function address byte, then read the word value for this function
588- * From the BQ spec: The processor then sends the bq2060 device address of 0001011 (bits 7 1)
596+ * From the BQ spec: The processor then sends the bq2060 device address of 0001011 (bits 7– 1)
589597 * plus a R/W bit (bit 0) followed by an SMBus command code.
590598 */
591599uint16_t readWord (uint8_t aCommand) {
@@ -762,7 +770,7 @@ void printlnHex(uint16_t aValue) {
762770 Serial.println ();
763771}
764772
765- void printHexAndBinary (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription, uint16_t aValue) {
773+ void printHexAndBinary (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription __attribute__ ((unused)) , uint16_t aValue) {
766774 printByteHex (aValue);
767775 Serial.print (" | 0b" );
768776 Serial.print (aValue, BIN);
@@ -994,7 +1002,7 @@ void printCurrent(struct SBMFunctionDescriptionStruct *aSBMFunctionDescription,
9941002 }
9951003}
9961004
997- void printTemperature (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription, uint16_t aTemperature) {
1005+ void printTemperature (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription __attribute__ ((unused)) , uint16_t aTemperature) {
9981006 Serial.print ((float ) (aTemperature / 10.0 ) - 273.15 );
9991007 Serial.print (" C" );
10001008}
@@ -1048,7 +1056,7 @@ void printTime(struct SBMFunctionDescriptionStruct *aSBMFunctionDescription, uin
10481056/*
10491057 * Format as ISO date
10501058 */
1051- void printManufacturerDate (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription, uint16_t aDate) {
1059+ void printManufacturerDate (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription __attribute__ ((unused)) , uint16_t aDate) {
10521060
10531061 int tDay = aDate & 0x1F ;
10541062 int tMonth = (aDate >> 5 ) & 0x0F ;
@@ -1065,7 +1073,7 @@ void printManufacturerDate(struct SBMFunctionDescriptionStruct *aSBMFunctionDesc
10651073 myLCD.print (tDateAsString);
10661074}
10671075
1068- void printSpecificationInfo (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription, uint16_t aSpecificationInfo) {
1076+ void printSpecificationInfo (struct SBMFunctionDescriptionStruct *aSBMFunctionDescription __attribute__ ((unused)) , uint16_t aSpecificationInfo) {
10691077 if (aSpecificationInfo >= 0x40 ) {
10701078 printByteHex (aSpecificationInfo);
10711079 Serial.print (F (" | " ));
@@ -1375,7 +1383,7 @@ void printSBMATRateInfo(void) {
13751383 // print also mA since changing capacity mode did not work
13761384 Serial.print (" | " );
13771385#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1378- Serial.print (-tmA);
1386+ Serial.print (-tmA); // !s initialized above, but compiler complains :-(
13791387 Serial.print (StringCapacityModeCurrent);
13801388 }
13811389 Serial.println ();
0 commit comments