Skip to content

Commit 0deae77

Browse files
committed
Documentation
1 parent 710948e commit 0deae77

File tree

5 files changed

+145
-92
lines changed

5 files changed

+145
-92
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ Download and extract the repository. In the Arduino IDE open the sketch with Fil
2020
## Identifying the right connection
2121
Valuable information about battery pinout can also be found [here](https://www.laptopu.ro/community/laptop-battery-pinout/) or [here](https://powercartel.com/projects/packprobe/battery-connection/).<br/>
2222
The minimal connector layout is: | GROUND | THERMISTOR (103AT) | CLOCK | DATA | VCC (11 or 14 volt) | (clock and data my be switched).
23-
- The **thermistor** connection has 10 kOhm to ground at 25 degree celsius.
24-
- **Clock** und data connectors have the same resistance (around 0.3 to 1 MOhm) to ground and are next to each other.
23+
- The **thermistor** connection has 10 k&ohm; to ground at 25 degree celsius.
24+
- **Clock** und data connectors have the same resistance (around 0.3 to 1 M&ohm;) to ground and are next to each other.
2525
- **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.
2626

2727
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.
@@ -37,7 +37,7 @@ Examples:
3737
After startup, the program scans for a connected I2C device.<br/>
3838
In version 4.0 a voltage and resistance measurement by means of 4 additional resistors is integrated **to identify the I2C pins**.
3939
It measures voltage or resistance to ground (if voltage is zero).<br/>
40-
**The I2c pins have around 300 kOhm to 1000 kOhm**, the thermistor 10 kOhm (sometimes up to 40 kOhm).
40+
**The I2c pins have around 300 k&ohm; to 1000 k&ohm;**, the thermistor 10 k&ohm; (sometimes up to 40 k&ohm;).
4141

4242
You can try different I2C pin combinations until led stops blinking and `Found I2C device attached at address: 0x0B` is printed.
4343
If you connect clock or data with the thermistor connector or ground, the scanning stops.<br/>
@@ -80,7 +80,7 @@ Basiert auf https://github.com/PowerCartel/PackProbe von Power Cartel http://pow
8080

8181
## Finden der Anschlüsse.
8282
In der Version 4.0 ist eine Spannungs und Widerstandsmessung mittels 4 Widerständen integriert, um die I2C Pins zu identifizieren.
83-
Die Clock und Data Eingänge waren bei meinen Packs die Anschlüsse mit einem Widerstand von ca. 300 k bis 1 MOhm nach Masse.
83+
Die Clock und Data Eingänge waren bei meinen Packs die Anschlüsse mit einem Widerstand von ca. 300 k bis 1 M&ohm; nach Masse.
8484
Nach dem Booten sucht das Programm nach einem angeschlossenen I2C Device.
8585
Man kann also alle möglichen Pinkombinationen von Clock und Data am Battery Pack ausprobieren.
8686
Bei der Richtigen hört das Blinken der Led auf und es kommt sofort die Ausgabe `Found I2C device attached at address: 0x0B` und direkt danach werden die Daten ausgegeben.
@@ -90,7 +90,7 @@ Wenn mehr als 5 Kontakte vorhanden waren, waren sie wie folgt belegt:
9090
- Masse und Plus doppelt. z.B. + | + | Thermistor | Data | Clock | - | -
9191
- Ein Enable (nur im Laptop mit Masse verbunden) und eine Signal Anschluss (nur im Battery Pack mit Masse verbunden). z.B. VCC | VCC | CLOCK | DATA | Signal | Enable | THERMISTOR | GROUND | GROUND |
9292

93-
Der Thermo-Sensor Anschluss war uneinheitlich, mal nicht messbar beschaltet, mal 1 MOhm, mal 1,6 Volt, mal 10 kOhm nach Masse.
93+
Der Thermo-Sensor Anschluss war uneinheitlich, mal nicht messbar beschaltet, mal 1 M&ohm;, mal 1,6 Volt, mal 10 k&ohm; nach Masse.
9494

9595
Zur Verbindung mit den Kontakten habe ich normales 1,5 qmm Kupferkabel aus der Hausinstallation genommen, dessen eines Ende ich mit einem Hammer etwas plattgeklopft hab. Stecknadeln oder Breadboard Wires gehen auch.
9696

@@ -169,7 +169,7 @@ Cell 4 Voltage 0x0
169169
170170
*** CHANGED VALUES ***
171171
172-
--- Next values are from another Pack! I connected 22 Ohm Resistor -> 699 mA discharging
172+
--- Next values are from another Pack! I connected 22 ohm Resistor -> 699 mA discharging
173173
174174
Voltage 15.788 V
175175
Average current of last minute -187 mA

SBMInfo/ADCUtils.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* ADCUtils.h
33
*
4-
* Copyright (C) 2016-2021 Armin Joachimsmeyer
4+
* Copyright (C) 2016-2022 Armin Joachimsmeyer
55
66
*
77
* This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.
@@ -17,12 +17,12 @@
1717
* GNU General Public License for more details.
1818
*
1919
* You should have received a copy of the GNU General Public License
20-
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
20+
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
2121
*
2222
*/
2323

24-
#ifndef SRC_ADCUTILS_H_
25-
#define SRC_ADCUTILS_H_
24+
#ifndef _ADC_UTILS_H
25+
#define _ADC_UTILS_H
2626

2727
#if defined(__AVR__) && (!defined(__AVR_ATmega4809__))
2828
#include <Arduino.h>
@@ -47,14 +47,6 @@
4747
#define ADC_PRESCALE ADC_PRESCALE128
4848
#endif
4949

50-
/*
51-
* By replacing this value with the voltage you measured a the AREF pin after a conversion
52-
* with INTERNAL you can calibrate your ADC readout. For my Nanos I measured e.g. 1060 mV and 1093 mV.
53-
*/
54-
#ifndef ADC_INTERNAL_REFERENCE_MILLIVOLT
55-
#define ADC_INTERNAL_REFERENCE_MILLIVOLT 1100L // Value measured at the AREF pin
56-
#endif
57-
5850
/*
5951
* Reference shift values are complicated for ATtinyX5 since we have the extra register bit REFS2
6052
* in ATTinyCore, this bit is handled programmatical and therefore the defines are different.
@@ -122,7 +114,7 @@
122114
uint16_t readADCChannel(uint8_t aChannelNumber);
123115
uint16_t readADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference);
124116
uint16_t waitAndReadADCChannelWithReference(uint8_t aChannelNumber, uint8_t aReference);
125-
uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUX(uint8_t aChannelNumber, uint8_t aReference);
117+
uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t aChannelNumber, uint8_t aReference);
126118
uint16_t readADCChannelWithOversample(uint8_t aChannelNumber, uint8_t aOversampleExponent);
127119
void setADCMultiplexerAndReferenceForNextConversion(uint8_t aChannelNumber, uint8_t aReference);
128120
uint16_t readADCChannelWithReferenceOversample(uint8_t aChannelNumber, uint8_t aReference, uint8_t aOversampleExponent);
@@ -150,6 +142,4 @@ float getTemperature(void);
150142

151143
#endif // defined(ADATE)
152144
#endif // defined(__AVR__)
153-
#endif /* SRC_ADCUTILS_H_ */
154-
155-
#pragma once
145+
#endif // _ADC_UTILS_H
Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/*
2-
* ADCUtils.cpp
2+
* ADCUtils.hpp
33
*
44
* ADC utility functions. Conversion time is defined as 0.104 milliseconds for 16 MHz Arduinos in ADCUtils.h.
55
*
6-
* Copyright (C) 2016-2020 Armin Joachimsmeyer
6+
* Copyright (C) 2016-2022 Armin Joachimsmeyer
77
88
*
99
* This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.
@@ -19,11 +19,23 @@
1919
* GNU General Public License for more details.
2020
*
2121
* You should have received a copy of the GNU General Public License
22-
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
22+
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
2323
*/
2424

25+
26+
#ifndef _ADC_UTILS_HPP
27+
#define _ADC_UTILS_HPP
28+
2529
#include "ADCUtils.h"
26-
#if defined(__AVR__) && defined(ADATE)
30+
#if defined(__AVR__) && defined(ADCSRA) && defined(ADATE)
31+
32+
/*
33+
* By replacing this value with the voltage you measured a the AREF pin after a conversion
34+
* with INTERNAL you can calibrate your ADC readout. For my Nanos I measured e.g. 1060 mV and 1093 mV.
35+
*/
36+
#if !defined(ADC_INTERNAL_REFERENCE_MILLIVOLT)
37+
#define ADC_INTERNAL_REFERENCE_MILLIVOLT 1100L // Value measured at the AREF pin. If value > real AREF voltage, measured values are > real values
38+
#endif
2739

2840
// Union to speed up the combination of low and high bytes to a word
2941
// it is not optimal since the compiler still generates 2 unnecessary moves
@@ -92,7 +104,7 @@ uint16_t waitAndReadADCChannelWithReference(uint8_t aChannelNumber, uint8_t aRef
92104
* Conversion time is defined as 0.104 milliseconds by ADC_PRESCALE in ADCUtils.h.
93105
* Restores ADMUX after reading
94106
*/
95-
uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUX(uint8_t aChannelNumber, uint8_t aReference) {
107+
uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t aChannelNumber, uint8_t aReference) {
96108
uint8_t tOldADMUX = checkAndWaitForReferenceAndChannelToSwitch(aChannelNumber, aReference);
97109
uint16_t tResult = readADCChannelWithReference(aChannelNumber, aReference);
98110
checkAndWaitForReferenceAndChannelToSwitch(tOldADMUX & MASK_FOR_ADC_CHANNELS, tOldADMUX >> SHIFT_VALUE_FOR_REFERENCE);
@@ -331,13 +343,6 @@ uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aChannelNumber, uint8_t aDe
331343
return (tMax + tMin) / 2;
332344
}
333345

334-
/*
335-
* !!! Resolution is only 20 millivolt !!!
336-
*/
337-
float getVCCVoltage(void) {
338-
return (getVCCVoltageMillivolt() / 1000.0);
339-
}
340-
341346
/*
342347
* !!! Function without handling of switched reference and channel.!!!
343348
* Use it ONLY if you only call getVCCVoltageSimple() or getVCCVoltageMillivoltSimple() in your program.
@@ -372,6 +377,13 @@ uint16_t getVCCVoltageReadingFor1_1VoltReference(void) {
372377
return ((1023L * 1023L) / tVCC);
373378
}
374379

380+
/*
381+
* !!! Resolution is only 20 millivolt !!!
382+
*/
383+
float getVCCVoltage(void) {
384+
return (getVCCVoltageMillivolt() / 1000.0);
385+
}
386+
375387
/*
376388
* Read value of 1.1 volt internal channel using VCC (DEFAULT) as reference.
377389
* Handles reference and channel switching by introducing the appropriate delays.
@@ -435,8 +447,11 @@ float getTemperature(void) {
435447
return (tTemp / 1.22);
436448
#endif
437449
}
438-
#elif defined(ARDUINO_ARCH_APOLLO3)
450+
451+
#elif defined(ARDUINO_ARCH_APOLLO3) // defined(__AVR__) && defined(ADATE)
439452
void ADCUtilsDummyToAvoidBFDAssertions(){
440453
;
441454
}
442-
#endif // defined(__AVR__)
455+
#endif // defined(__AVR__) && defined(ADATE)
456+
457+
#endif // _ADC_UTILS_HPP

SBMInfo/MeasureVoltageAndResistance.hpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MeasureVoltageAndResistance.hpp
33
*
4-
* Measures voltage and resistance with 1 mV and 2 Ohm resolution at the lower end.
4+
* Measures voltage and resistance with 1 mV and 2 ohm resolution at the lower end.
55
* First voltage is measured. If voltage is zero, then resistance to ground is measured using 5 volt (VCC) and 10 kOhm or 100 kOhm supply.
66
*
77
* Copyright (C) 2021 Armin Joachimsmeyer
@@ -20,7 +20,7 @@
2020
* GNU General Public License for more details.
2121
*
2222
* You should have received a copy of the GNU General Public License
23-
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
23+
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
2424
*
2525
*/
2626

@@ -58,9 +58,13 @@
5858
* Rx = R1 * x / (1023-x)
5959
*
6060
*/
61+
62+
#ifndef _MEASURE_VOLTAGE_AND_RESISTANCE_HPP
63+
#define _MEASURE_VOLTAGE_AND_RESISTANCE_HPP
64+
6165
#include <Arduino.h>
6266

63-
#include "ADCUtils.h"
67+
#include "ADCUtils.hpp"
6468

6569
//#define NO_PRINT_OF_RESISTOR_MEASURMENT_VOLTAGE // enables print of voltage at resistor under measurement (0 to VCC).
6670

@@ -79,15 +83,15 @@
7983
#endif
8084

8185
// Fixed attenuator for voltage measurement
82-
#ifndef RESISTOR_TO_VOLTAGE_PIN_KOHM
86+
#if !defined(RESISTOR_TO_VOLTAGE_PIN_KOHM)
8387
#define RESISTOR_TO_VOLTAGE_PIN_KOHM 100 // R1
8488
#endif
85-
#ifndef RESISTOR_FROM_VOLTAGE_PIN_TO_GROUND_PIN_KOHM
89+
#if !defined(RESISTOR_FROM_VOLTAGE_PIN_TO_GROUND_PIN_KOHM)
8690
#define RESISTOR_FROM_VOLTAGE_PIN_TO_GROUND_PIN_KOHM 22 // R2
8791
#endif
8892

8993
// fixed resistors for resistor measurement
90-
#ifndef RESISTOR_2_TO_VCC_KOHM
94+
#if !defined(RESISTOR_2_TO_VCC_KOHM)
9195
#define RESISTOR_2_TO_VCC_KOHM 10 // R3
9296
#endif
9397
#define RESISTOR_1_TO_VCC_KOHM RESISTOR_TO_VOLTAGE_PIN_KOHM // R1
@@ -152,7 +156,7 @@ uint16_t measureVoltage(uint16_t tVCCVoltageMillivolt) {
152156
}
153157
}
154158
#pragma GCC diagnostic pop
155-
#ifdef DEBUG
159+
#if defined(DEBUG)
156160
Serial.print(F("Raw="));
157161
Serial.println(tInputVoltageRaw);
158162
#endif
@@ -182,7 +186,7 @@ bool measureResistance(uint16_t aVCCVoltageMillivolt, ResistanceMeasurementResul
182186
if (tInputVoltage > REFERENCE_SWITCHING_VOLTAGE_THRESHOLD_MILLIVOLT) {
183187
if (tReadingAtVCC > tInputReading) {
184188
tRxOhm = (RESISTOR_1_TO_VCC_KOHM * 1000L * tInputReading) / (tReadingAtVCC - tInputReading);
185-
// Here we have a resolution of 160 to 350 Ohm at 1 MOhm
189+
// Here we have a resolution of 160 to 350 ohm at 1 MOhm
186190
// Clip at 10 MOhm
187191
if (tRxOhm > 9999999) {
188192
tRxOhm = 9999999;
@@ -197,7 +201,7 @@ bool measureResistance(uint16_t aVCCVoltageMillivolt, ResistanceMeasurementResul
197201
/*
198202
* Switch to 1.1 volt reference increasing the resolution by around 4
199203
* This happens at around 28 kOhm (at 4.7 volt) depending on the current value of VCC
200-
* Here we have a resolution of 24 to 37 Ohm
204+
* Here we have a resolution of 24 to 37 ohm
201205
*/
202206
tInputReading = waitAndReadADCChannelWithReference(OHM_CHANNEL, INTERNAL);
203207

@@ -208,16 +212,16 @@ bool measureResistance(uint16_t aVCCVoltageMillivolt, ResistanceMeasurementResul
208212

209213
/*
210214
* Formula is: (for 5 V and 1050 mV, in order to get a constant value)
211-
* Rx = Rvcc * 1.050 V / 3.95 V = 2416 Ohm
212-
* Here we have a resolution of 2 to 6 Ohm
215+
* Rx = Rvcc * 1.050 V / 3.95 V = 2416 ohm
216+
* Here we have a resolution of 2 to 6 ohm
213217
*/
214218
const uint16_t tResistanceForThresholdVoltage = (RESISTOR_1_TO_VCC_KOHM * RESISTOR_2_TO_VCC_KOHM
215219
* REFERENCE_SWITCHING_VOLTAGE_THRESHOLD_MILLIVOLT * 1000)
216220
/ ((RESISTOR_1_TO_VCC_KOHM + RESISTOR_2_TO_VCC_KOHM) * (5000 - REFERENCE_SWITCHING_VOLTAGE_THRESHOLD_MILLIVOLT));
217221
if (tRxOhm < tResistanceForThresholdVoltage) {
218-
#ifdef DEBUG
222+
#if defined(DEBUG)
219223
Serial.print(tResistanceForThresholdVoltage);
220-
Serial.print(F(" Ohm "));
224+
Serial.print(F(" ohm "));
221225
#endif
222226
// tResistanceRange = 2;
223227
/*
@@ -237,7 +241,7 @@ bool measureResistance(uint16_t aVCCVoltageMillivolt, ResistanceMeasurementResul
237241
*/
238242
tInputVoltage = tInputReading * 1100L / 1023;
239243
}
240-
#ifdef DEBUG
244+
#if defined(DEBUG)
241245
Serial.print(tInputReading);
242246
Serial.println(F(" LSB"));
243247
#endif
@@ -266,7 +270,7 @@ void MeasureVoltageAndResistance() {
266270
// to enable discharge of stray capacitance
267271
pinMode(VOLTAGE_MEASUREMENT_PIN, OUTPUT);
268272
digitalWrite(VOLTAGE_GROUND_PIN, LOW);
269-
#ifdef DEBUG
273+
#if defined(DEBUG)
270274
uint16_t tVCCVoltageMillivolt = printVCCVoltageMillivolt(&Serial);
271275
#else
272276
uint16_t tVCCVoltageMillivolt = getVCCVoltageMillivolt();
@@ -289,7 +293,7 @@ void MeasureVoltageAndResistance() {
289293
# if defined(USE_2004_LCD)
290294
myLCD.setCursor(0, 3);
291295
myLCD.print(tStringForPrint);
292-
# ifndef NO_PRINT_OF_RESISTOR_MEASURMENT_VOLTAGE
296+
# if !defined(NO_PRINT_OF_RESISTOR_MEASURMENT_VOLTAGE)
293297
myLCD.print(F(" V ")); // clears old resistor output
294298
# else
295299
myLCD.print(F(" V ")); // clears old resistor output
@@ -329,7 +333,7 @@ void MeasureVoltageAndResistance() {
329333
myLCD.print(F(" k\xF4 "));
330334
# endif
331335
#endif
332-
#ifndef NO_PRINT_OF_RESISTOR_MEASURMENT_VOLTAGE
336+
#if !defined(NO_PRINT_OF_RESISTOR_MEASURMENT_VOLTAGE)
333337
Serial.print(F(" at: "));
334338
Serial.print(tResistanceMeasurementResult.VoltageAtResistor, 3);
335339
Serial.println(F(" V"));
@@ -388,3 +392,5 @@ void printVoltageAndResistanceUsage() {
388392
Serial.println(F(" mV resolution is 5 mV, below 1050 mV resolution is 1 mV"));
389393
Serial.println();
390394
}
395+
396+
#endif // _MEASURE_VOLTAGE_AND_RESISTANCE_HPP

0 commit comments

Comments
 (0)