How to automatically stop charging your Android phone when a certain battery level is reached

I recently found out about AccuBattery, an Android app that encourages behavior to increase the lifespan of your battery.

Batteries have a limited lifespan. Every time you charge your device, it wears out the battery, lowering its total capacity. Scientific research shows that battery lifespan can be extended up to 200%, when you charge your device to only 80%.

– Use our charge alarm to prolong your battery lifespan.

I have set my charge alarm to 75%, and it works beautifully throughout the day. Whenever I get low, I would plug it in and charge it, until I hear the notification that is played when 75% is reached.

 

Here is the problem

I like to charge my phone at night. I just like to start the day with a full (or 75%) battery instead of somewhere down in the 30% – ready to go. I also use Sleep as Android to track my sleep and to wake me up with a vibrating smartwatch rather than a blaring alarm to not wake up my wife and the offspring. I have found no app for Android (for non-root devices) that would allow me to stop charging my phone at a certain level.

But fret no more, I have found an inexpensive solution.

 

What you will need

  • Raspberry PI 3 / Raspberry PI 3 B+
  • Power supply
  • 4GB or bigger micro SD card
  • An Android phone
  • Your charging cable

 

Step by step guide

I am trying to cover all steps, I am using Linux myself but I am trying to give enough information on how to do these steps with Windows. If you seem to get stuck, there is a download link for a precompiled image at the bottom.

Download the Debian Buster image

Go to https://wiki.debian.org/RaspberryPi3 and download the preview image. By the time of writing, it should be located at https://people.debian.org/~stapelberg/raspberrypi3/2018-01-08/2018-01-08-raspberry-pi-3-buster-PREVIEW.img.xz but it might have moved by the time you are reading this. If I have not updated this post, google for “Debian Buster for Raspberry PI 3“.

 

Copy the image to a micro SD card

Using linux, you can just type

xzcat 2018-01-08-raspberry-pi-3-buster-PREVIEW.img.xz | dd of=/dev/mmcblk0 bs=64k oflag=dsync status=progress

to copy the image to your micro SD card. You might need to replace /dev/mmcblk0 with the actual device of your cardreader

Windows users: Using 7-Zip or WinRAR to extract the .img.gz file, you can use Etcher or Win32DiskImager to copy the image to your micro SD card. More directions can be found here. Simply copying the file to the card will not work, you need either program.

 

Insert and boot your Raspberry PI

This should be pretty straightforward. Insert the micro SD card into the slot at the Raspberry PI, connect it either to a network (for ssh access) and/or attach a screen and a keyboard to it and then connect it to the power supply.

There are now different ways to…

 

Connect to your Raspberry PI

Screen and Keyboard

Wait for the Raspberry PI to boot up. At the prompt enter root as username and raspberry as password. Beware, if you are not using a US keyboard layout that you might need to swap y and z or other characters depending on your keyboard layout. Using your network is recommended.

Using your network (ssh / putty)

You need to figure out the IP address of your Rasperry PI. If you know how to use your router’s interface, there you go. Otherwise, install Network Discovery, open it, download the NIC database and hit discover. You should find an IP address with the manufacturer “Raspberry PI Foundation”. If you tap on that, you should see one open port (22). You will need this IP. In my case it is 172.17.2.7

To connect on Linux, type

ssh root@172.17.2.7

replacing 172.17.2.7 with the IP address you just discovered. The password is raspberry

Windows Users: Download PuTTY, open it and enter the IP address. Use the username root and password raspberry to proceed.

 

Update your Raspberry PI

To update all software packages, issue these commands. This might not be necessary, but is good practice.

apt update
apt -y dist-upgrade
reboot

After reboot, reconnect again.

 

Install necessary tools

We need adb for this to work, as we read the battery percentage through adb.

apt -y install android-tools-adb

 

Install the script

This is why I recommend connecting via network. You need to install a script and if you can’t copy/paste, it will be a lot of typing for you. Type

nano -w checkbattery.sh

And copy/paste this script.

#!/bin/bash
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
THRESHOLD=`cat /proc/cmdline  | grep -o "chargelimiter=[0-9].:[0-9]." | cut -d"=" -f2 | cut -d":" -f1 || echo 80`
PAUSE=`cat /proc/cmdline  | grep -o "chargelimiter=[0-9].:[0-9]." | cut -d"=" -f2 | cut -d":" -f2 || echo 30`
if [ "$THRESHOLD" == "" ]; then
THRESHOLD=80
fi
if [ "$PAUSE" == "" ]; then
PAUSE=30
fi
LEVEL=`adb shell dumpsys battery | grep "  level" | rev | cut -d" " -f1 | rev`
if [ $LEVEL -gt $THRESHOLD ]; then
shutdown -r $PAUSE
echo '1-1' | tee /sys/bus/usb/drivers/usb/unbind
fi

Hit Ctrl+x and y and then <enter> to save and exit.

Make this script executable by typing

chmod +x checkbattery.sh

And then install the script as recurring task to your crontab

crontab -e

If prompted which editor to choose, type the number for nano, probably 1 and hit enter.

Add this line to the bottom of the file

* * * * * /root/checkbattery.sh

Hit Ctrl+x and y and then <enter> to save and exit.

 

Change defaults (optional)

The default values are:

  • Charge until 80%
  • Stop charging for 30 minutes

After 30 minutes, the Raspberry PI will reboot and charge until 80% again.

If you want to change these default values, edit /boot/firmware/cmdline.txt. Type:

nano -w /boot/firmware/cmdline.txt

and add chargelimiter=80:30 to the end of the line. The first number is the target battery percentage, the second number the pause between charging. Hit Ctrl+x and y and then <enter> to save and exit. The line should look something like this:

console=tty0 console=ttyS1,115200 root=/dev/mmcblk0p2 rw elevator=deadline fsck.repair=yes net.ifnames=0 rootwait chargelimiter=75:60

You need to reboot for this changes to take effect. To do so, type

reboot

Windows Users: This file is visible when you insert the SD card in Windows, so even without Linux you can easily change these values if you pop the card into your machine.

 

Enable debugging

To read the battery percentage, you need to enabe USB debugging. To do so, go to your Phone Settings, “About phone” and tap on the Build number a couple times until it says “You are now a developer”. Then typ back, go into “Developer Options” and enable “USB Debugging”

 

Connect your phone and allow

The first time you connect your phone to one of the USB ports on your Raspberry PI, it will ask you if you want to trust this device. Check “Always allow from this computer” and tap on “OK”. You are good to go. Test your setup, your phone should charge to the desired percentage and then stop. Important: This only works when you see the Android notification “USB debugging connected”.

 

The Ugly

There is a big issue that I kept from you so far. If you are using a screen lock, depending on your phone you need to unlock your screen after connecting the usb cable and every time the Raspberry PI reboots and tries charging again. If you don’t, it will just charge to 100%, because it can’t connect with adb until the device gets unlocked. There is however a workaround: If you use smart lock to keep the device unlocked while at a certain location or while connected to a certain bluetooth device, it will allow for adb to work even without manually unlocking the screen. Just as an example. On my OnePlus 6, it works always, even when locked without smart lock active. On my Moto G5 it only works when unlocked.

 

Read-Only root partition

To not wear out your micro SD card and to survive loss of power, once you verified that everything is working as expected, I suggest that one to three days later you edit the file /etc/fstab to set the root filesystem to readonly. The advantage of doing so is that nothing should destroy your setup, even if you just unplug the device. On the downside, it will throw a bunch of errors when looking at it connected to a screen. They can easily be ignored.

nano -w /etc/fstab

Change the rw to ro for both instances in the file. Add a line

tmpfs   /tmp         tmpfs   nodev,nosuid,rw          0  0

Hit ctrl+x and y to save and exit.

nano -w /boot/firmware/cmdline.txt

Change the rw to ro here, too. Hit ctrl+x and y to save and exit. Type

rm /etc/network/interfaces.d/eth0

to stop Debian from waiting for network for startup.

reboot

for it to take effect. It is now completely safe to unplug your raspberry PI at any time. You can even put it on your nightstand and it will just work as-is. Just remember to watch out for the “USB debugging connected” indicator on your phone.

 

Troubleshooting

My PI 3B+ won’t connect to network

The preview image dated 2018-01-08 comes with an old kernel that does not have support for the PI 3B+ network card. You will need to prepare the SD card on an older PI running

apt update
apt dist-upgrade
reboot

to upgrade the kernel to a newer version.

My Phone does not stop charging

If your phone is locked, USB debugging will not be active. I have come across this problem with my Moto G5 which I don’t use on a daily basis (So screen is usually locked). Unfortunately it is only allowing an adb connection once the phone has been unlocked after plugging in. Try plugging in the phone and then unlocking it once. A good indicator that it is working is if a notification says “USB debugging connected”. If you don’t use screen lock or have smart unlock active, it should work without turning on the screen.

It does not work when not connected to network

See “Read Only Partition“. For some reason, Debian tries to wait indefinitely if there is no network present during startup.

 

Disk image for the lazy

I promised you a disk image. Download it, unpack it and put it on a SD card as described in step 2. Then go ahead and adjust your cmdline.txt as described in step 3.8 (optional). Eject/unmount the card, put it into your Raspberry PI and put it wherever you want to charge your phone. Don’t forget to enable USB debugging on your phone and always allowing the Raspberry PI. It will work automatically with no further adjustment needed.

You can download it via bittorrent.

charger.img.xz.torrent or magnet link

3 thoughts on “How to automatically stop charging your Android phone when a certain battery level is reached”

  1. So far, I have only tested it on Raspberry PI 3, tomorrow I will be able to test it on the PI 3+ and the PI 2

Leave a Reply

Your email address will not be published. Required fields are marked *