N900 Hardware Charge Meter/bq-script


 * 1) !/bin/sh

RS=20

WARN=1
 * 1) 1 = Warn if battery is getting low

FIRSTWARNING=0 SECONDWARNING=0
 * 1) Internal: Have we warned user?

debugecho {       if [ $LOOPMODE -eq 0 ]; then echo $* fi } debugechon {       if [ $LOOPMODE -eq 0 ]; then echo -n $* fi } dot {       debugechon "." }

if [ ! -e ./i2cget ] ; then echo "Need ./i2cget" return fi

LOOPMODE=0 LOOPCOUNT=0 if [ -n "$1" ] ; then if [ $(($1)) -gt 1 ] ; then LOOPMODE=$(($1)) else LOOPMODE=1 fi fi

echo LOOPMODE=$LOOPMODE

doit=1 while [ $doit -eq 1 ] ; do ## MAIN LOOP ##

doit=0
 * 1) Data acquisition ##############

debugechon "Reading values"
 * 1) debugechon "About to stop bme. "
 * 2) killall -STOP bme_RX-51
 * 3) debugecho "Bme stopped."
 * 4) sleep 1;

AR=$(./i2cget -y 2 0x55 0x02 w) ; dot ARTTE=$(./i2cget -y 2 0x55 0x04 w); dot VOLT=$(./i2cget -y 2 0x55 0x08 w) ; dot TEMP=$(./i2cget -y 2 0x55 0x06 w) ; dot CSOC=$(./i2cget -y 2 0x55 0x2c) ; dot RSOC=$(./i2cget -y 2 0x55 0x0b) ; dot NAC=$(./i2cget -y 2 0x55 0x0c w) ; dot CACD=$(./i2cget -y 2 0x55 0x0e w) ; dot CACT=$(./i2cget -y 2 0x55 0x10 w); dot AI=$(./i2cget -y 2 0x55 0x14 w) ; dot TTF=$(./i2cget -y 2 0x55 0x18 w) ; dot TTE=$(./i2cget -y 2 0x55 0x16 w) ; dot FLAGS=$(./i2cget -y 2 0x55 0x0A) ; dot

if [ $LOOPMODE -eq 0 ] ; then CYCL=$(./i2cget -y 2 0x55 0x28 w) ; dot CYCLTL=$(./i2cget -y 2 0x55 0x2a w) ; dot SI=$(./i2cget -y 2 0x55 0x1A w) ; dot STTE=$(./i2cget -y 2 0x55 0x1C w); dot MLI=$(./i2cget -y 2 0x55 0x1e w) ; dot MLTTE=$(./i2cget -y 2 0x55 0x20 w); dot LMD=$(./i2cget -y 2 0x55 0x12 w) ; dot

ILMD=$(./i2cget -y 2 0x55 0x76); dot EDVF=$(./i2cget -y 2 0x55 0x77); dot EDV1=$(./i2cget -y 2 0x55 0x78); dot ISLC=$(./i2cget -y 2 0x55 0x79); dot DMFSD=$(./i2cget -y 2 0x55 0x7A); dot TAPER=$(./i2cget -y 2 0x55 0x7B); dot IMLC=$(./i2cget -y 2 0x55 0x7D); dot fi
 * 1) TODO: PKCFG

debugecho "done." debugecho ""
 * 1) debugechon "Waking up bme."
 * 2) killall -CONT bme_RX-51
 * 3) debugecho "Done. "


 * 1) Calculate ##############

CSOC=$(($CSOC))                     # CSOC Compensated state of charge %. CACT/LMD * 100 RSOC=$(($RSOC))                     # RSOC Relative state of charge %. NAC/LMD * 100 NAC=$(($NAC * 3570 / $RS / 1000))   # NAC Nominal available capaciy, mAh. CACD=$(($CACD * 3570 / $RS / 1000)) # CACD Discharge rate compensated available capacity, mAh. CACT=$(($CACT * 3570 / $RS / 1000)) # CACT Temperature compensated CACD, mAh. AI=$(($AI * 3570 / $RS / 1000))     # AI Average (last 5.12 seconds) current, mA. VOLT=$(($VOLT))                      # VOLT Battery voltage, mV. TTF=$(($TTF))                       # TTF Time to Full minutes. 65535 if no charging. TTE=$(($TTE))                       # TTE Time to Empty minutes. 65535 if charging.

F=$(($FLAGS)) FLAGS_CHARGE=$(($F/128))            # There is charging activity. AI is measuring charge current. F=$(($F-$F/128*128)) FLAGS_NOACT=$(($F/64))              # No charge/discharge activity detected. F=$(($F-$F/64*64)) FLAGS_IMIN=$(($F/32))               # Charge current has tapered off (battery charge is near/at completion) F=$(($F-$F/32*32)) FLAGS_CI=$(($F/16))                 # Capacity inaccurate. >32 cycles since last learning cycle. F=$(($F-$F/16*16)) FLAGS_CALIP=$(($F/8))               # External offset calibration in progress. F=$(($F-$F/8*8)) FLAGS_VDQ=$(($F/4))                 # Valid discharge. All requirements met for learning the battery's capacity when reaching EDV1 F=$(($F-$F/4*4)) FLAGS_EDV1=$(($F/2))                # First end of discharge-voltage flag. Battery voltage is at or below preprogrammed EDV1 threshold. If VDQ is 1, LMD is updated and VDQ set to 0. F=$(($F-$F/2*2)) FLAGS_EDVF=$F                       # Final end of discharge-voltage flag. The battery has discharged to 0% threshold.

if [ $LOOPMODE -eq 0 ] ; then AR=$(($AR * 3570 / $RS / 1000))     # AR At-rate ARTTE=$(($ARTTE))                   # At-rate time to empty LMD=$(($LMD * 3570 / $RS / 1000))   # LM Last measured discharge, mAh. SI=$(($SI * 3570/ $RS / 1000))      # SI Standby Current, mA. STTE=$(($STTE))                      # STTE Time to empty at standby, minutes. MLI=$(($MLI * 3570 / $RS / 1000))   # MLI Maximum Load Current, mA. MLTTE=$(($MLTTE))                    # MLTTE Time to empty at maximum load, minutes. CYCL=$(($CYCL))                     # CYCL Cycles since last learning cycle (last time LMD was updated) CYCLTL=$(($CYCLTL))                 # CYCLTL Cycles since last full reset.

ILMD=$(($ILMD * 913920 / $RS / 1000)) # eeprom Initial Last Measured Discharge. LMD = ILMD if no valid learning cycle has been completed. EDVF=$(($EDVF * 8 + 8*256))          # eeprom End of discharge voltage threshold. EDV1=$(($EDV1 * 8 + 8*256))          # eeprom 6.25% Capacity voltage threshold. ISLC=$(($ISLC * 7140 / $RS / 1000))  # eeprom Initial standby load current.

DMF=$(($DMFSD/16)) SD=$(($DMFSD-$DMF*16)) DMF=$(($DMF * 4900))                # eeprom Digital Magnitude Filter, nanoVolts SD=$((1610 / $SD))                  # eeprom Self Discharge rate, thousandth of percent (1/1000 %) per day at 25 degrees celcius
 * 1) DMF in bits 4:7
 * 1) SD in bits 0:3

AGELMD=$(($TAPER/128))              # eeprom Battery capacity aging estimation on/off TAPER=$(($TAPER-$AGELMD*128)) TAPER=$(($TAPER * 228000 / $RS / 1000)) # eeprom Taper current mA

IMLC=$(($IMLC * 457000 / $RS / 1000))   # eeprom Initial Max Load Current

fi


 * 1) Display ##############

if [ $WARN -eq 1 ] ; then if [ $FLAGS_EDVF -eq 1 ] && [ $SECONDWARNING -eq 0 ] ; then dbus-send --print-reply --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:'Battery at CRITICAL low level' uint32:0 string:'ok' SECONDWARNING=1 else SECONDWARNING=0 if [ $FLAGS_EDV1 -eq 1 ] && [ $FIRSTWARNING -eq 0 ] ; then dbus-send --print-reply --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog string:'Warning: Battery Low' uint32:0 string:'ok' FIRSTWARNING=1 else FIRSWARNING=0 fi       fi fi if [ $LOOPMODE -eq 0 ] ; then

echo -n CSOC: $CSOC "% " echo RSOC: $RSOC "%" echo Average Current: $AI mA echo -n TTF: $(($TTF)) "minutes " echo TTE: $(($TTE)) minutes

echo -n NAC: $NAC "mAh " echo -n CACD: $CACD "mAh " echo CACT: $CACT "mAh "

echo -n SI: $SI "mA " echo STTE: $STTE "minutes"

echo -n MLI: $MLI "mA " echo MLTTE: $MLTTE "minutes"

echo -n AR: $AR "mA " echo ARTTE: $ARTTE "minutes"

echo Last Measured Discharge: $LMD mAh echo Cycle Count since Learning: $CYCL Total Cycle Count since last full reset: $CYCLTL echo Reported Battery Voltage: $VOLT mV echo Battery Gauge die Temperature: $(($TEMP * 250 / 1000 - 273)) C echo -e "Flags:\t" $FLAGS echo -e "\t" Charge:$FLAGS_CHARGE NOACT:$FLAGS_NOACT IMIN:$FLAGS_IMIN CI:$FLAGS_CI CALIP:$FLAGS_CALIP VDQ:$FLAGS_VDQ EDV1:$FLAGS_EDV1 EDVF: $FLAGS_EDVF echo -e "eeprom data:" echo -e "\t" ILMD=$ILMD EDVF=$EDVF EDV1=$EDV1 ISLC=$ISLC echo -e "\t" DMF=$DMF nanoVolt SD=$SD thousandths of percent per day echo -e "\t" AGELMD=$AGELMD TAPER=$TAPER mA echo -e "\t" IMLC=$IMLC mA

else # loopmode

if [ $LOOPCOUNT -eq 0 ] ; then LOOPCOUNT=24 echo -e "     mv   RSOC CSOC mA   NAC  CACD CACT TTF   TTE   TEMP EDV1 LOW" fi LOOPCOUNT=$(($LOOPCOUNT-1))

C=$AI if [ $FLAGS_CHARGE -eq 0 ] ; then C="-"$C fi printf "$(date +%H:%M) %4d %-3d %-3d  %-4d %-4d %-4d %-4d %-5d %-5d %-3d %d\n" $VOLT $RSOC $CSOC $C $NAC $CACD $CACT $TTF $TTE $(($TEMP * 250 /1000 - 273)) $FLAGS_EDV1 sleep $LOOPMODE doit=1 fi # if loopmode

done # main