diff --git a/README.md b/README.md index 2c5b6c2..ef3740b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # [SMB](https://github.com/ArminJo/Smart-Battery-Module-Info_For_Arduino) - Smart Battery Module (Laptop Battery Pack) Info ### Version 4.0.0 [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) +[![Commits since latest](https://img.shields.io/github/commits-since/ArminJo/Smart-Battery-Module-Info_For_Arduino/latest)](https://github.com/ArminJo/Smart-Battery-Module-Info_For_Arduino/commits/master) [![Build Status](https://github.com/ArminJo/Smart-Battery-Module-Info_For_Arduino/workflows/TestCompile/badge.svg)](https://github.com/ArminJo/Smart-Battery-Module-Info_For_Arduino/actions) [![Hit Counter](https://hitcounter.pythonanywhere.com/count/tag.svg?url=https%3A%2F%2Fgithub.com%2FArminJo%2FSmart-Battery-Module-Info_For_Arduino)](https://github.com/brentvollebregt/hit-counter) @@ -18,8 +19,8 @@ Download and extract the repository. In the Arduino IDE open the sketch with Fil ## Identifying the right connection The minimal connector layout is: | GROUND | THERMISTOR (103AT) | CLOCK | DATA | VCC (11 or 14 volt) | (clock and data my be switched). -- The **thermistor** connection has 10 kOhms to ground at 25 degree celsius. -- **Clock** und data connectors have the same resistance (around 1 MOhm) to ground. +- The **thermistor** connection has 10 kOhm to ground at 25 degree celsius. +- **Clock** und data connectors have the same resistance (around 0.3 to 1 MOhm) to ground. - **VCC** may not be enabled. Sometimes it gets enabled when *Host Present* is connected to ground or clock and data are pulled high to 3.3 or 5 volt. Some packs (e.g.for IBM-T41 with bq29310) require once an external voltage (e.g. 11 volt) at the VCC connector to initially get alive after full discharge condition. @@ -35,7 +36,7 @@ Examples: After startup, the program scans for a connected I2C device.
In version 4.0 a voltage and resistance measurement by means of 4 additional resistors is integrated **to identify the I2C pins**. It measures voltage or resistance to ground (if voltage is zero).
-**The I2c pins have around 300 kOhm to 1000 kOhm**, the thermistor 10 kOhm. +**The I2c pins have around 300 kOhm to 1000 kOhm**, the thermistor 10 kOhm (sometimes up to 40 kOhm). You can try different I2C pin combinations until led stops blinking and `Found I2C device attached at address: 0x0B` is printed. If you connect clock or data with the thermistor connector or ground, the scanning stops.
@@ -195,6 +196,7 @@ Average minutes remaining until empty: 16 h 11 min - Integrated voltage and resistance measurement. - Major improvements in I2C communication and output. - Detection of disconnect. +- Improved LCD output. ### Version 3.1.1 - Better prints at scanning. diff --git a/SBMInfo/ADCUtils.cpp b/SBMInfo/ADCUtils.cpp index aa94d05..416a1e7 100644 --- a/SBMInfo/ADCUtils.cpp +++ b/SBMInfo/ADCUtils.cpp @@ -28,11 +28,11 @@ // Union to speed up the combination of low and high bytes to a word // it is not optimal since the compiler still generates 2 unnecessary moves // but using -- value = (high << 8) | low -- gives 5 unnecessary instructions -union Myword { +union WordUnionForADCUtils { struct { uint8_t LowByte; uint8_t HighByte; - } byte; + } UByte; uint16_t UWord; int16_t Word; uint8_t *BytePointer; @@ -42,7 +42,7 @@ union Myword { * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. */ uint16_t readADCChannel(uint8_t aChannelNumber) { - Myword tUValue; + WordUnionForADCUtils tUValue; ADMUX = aChannelNumber | (DEFAULT << SHIFT_VALUE_FOR_REFERENCE); // ADCSRB = 0; // Only active if ADATE is set to 1. @@ -53,8 +53,8 @@ uint16_t readADCChannel(uint8_t aChannelNumber) { loop_until_bit_is_clear(ADCSRA, ADSC); // Get value - tUValue.byte.LowByte = ADCL; - tUValue.byte.HighByte = ADCH; + tUValue.UByte.LowByte = ADCL; + tUValue.UByte.HighByte = ADCH; return tUValue.UWord; // return ADCL | (ADCH <<8); // needs 4 bytes more } @@ -63,7 +63,7 @@ uint16_t readADCChannel(uint8_t aChannelNumber) { * Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h. */ uint16_t readADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference) { - Myword tUValue; + WordUnionForADCUtils tUValue; ADMUX = aChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE); // ADCSRB = 0; // Only active if ADATE is set to 1. @@ -74,8 +74,8 @@ uint16_t readADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference) loop_until_bit_is_clear(ADCSRA, ADSC); // Get value - tUValue.byte.LowByte = ADCL; - tUValue.byte.HighByte = ADCH; + tUValue.UByte.LowByte = ADCL; + tUValue.UByte.HighByte = ADCH; return tUValue.UWord; } @@ -160,7 +160,7 @@ uint16_t readADCChannelWithReferenceOversample(uint8_t aChannelNumber, uint8_t a ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished // Add value - tSumValue += ADCL | (ADCH << 8); // using myWord does not save space here + tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here // tSumValue += (ADCH << 8) | ADCL; // this does NOT work! } ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) @@ -189,7 +189,7 @@ uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aChannelNumber, uint8 ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished // Add value - tSumValue += ADCL | (ADCH << 8); // using myWord does not save space here + tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here // tSumValue += (ADCH << 8) | ADCL; // this does NOT work! } ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) @@ -217,7 +217,7 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aChannelNumber, uint8_t ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished // Add value - tSumValue += ADCL | (ADCH << 8); // using myWord does not save space here + tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here // tSumValue += (ADCH << 8) | ADCL; // this does NOT work! } ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode) diff --git a/SBMInfo/SBMInfo.ino b/SBMInfo/SBMInfo.ino index cdf65cd..c5fe795 100644 --- a/SBMInfo/SBMInfo.ino +++ b/SBMInfo/SBMInfo.ino @@ -308,7 +308,7 @@ BQ20Z70_PackVoltage, Pack_Voltage, &printVoltage } }; /* * From the specs: * Its clock frequency range is 10 kHz to 100 kHz. - * The charger must NOT charge a battery when it senses the resistance between the Safety Signal pin and ground to be in the range between 425 and 3150 ohms. + * The charger must NOT charge a battery when it senses the resistance between the Safety Signal pin and ground to be in the range between 425 and 3150 ohm. * E.g. NiMH battery may use a 103AT thermistor for this. * Only Read Word, Write Word, Read Block or Write Block protocol is used. * bq2084 spec: With SMBus, the most-significant bit (MSB) of a data byte is transmitted first. @@ -784,16 +784,15 @@ void printCapacity(struct SBMFunctionDescriptionStruct *aSBMFunctionDescription, myLCD.print(sDesignCapacity); if (sCapacityModePower) { myLCD.print('0'); // here we have units of 10 mWh + myLCD.print("->"); + } else { + myLCD.print(" -> "); } - myLCD.print(" -> "); // if (tPercent < 100) { // myLCD.print(' '); // } myLCD.print(aCapacity); - if (sCapacityModePower) { - myLCD.print('0'); // here we have units of 10 mWh - } - myLCD.print((getCapacityModeUnit() + 1)); + myLCD.print((getCapacityModeUnit())); myLCD.print('h'); Serial.print(" = "); diff --git a/extras/IdeaPadIntern.log b/extras/IdeaPadIntern.log new file mode 100644 index 0000000..d41d518 Binary files /dev/null and b/extras/IdeaPadIntern.log differ