The PiWatcher is a very small board that helps you fully shut down or reboot a Raspberry Pi, in case of an incident or simply for power saving purposes. You can even program your PiWatcher to shut down and automatically reboot your Pi a few minutes or hours later. In essence, the PiWatcher is a programmable watchdog circuit for the Raspberry Pi, usable with the humble Pi Zero up to the power-hungry Pi 3. It not recommended for the Raspberry Pi 4.
The board must be fitted on the first 6 pins of the Raspberry GPIO header and plugged into a micro USB power supply suitable for the Raspberry Pi in use. The board will then switch on or off the power provided to the Raspberry Pi based on instructions it receives through I2C. The board also features a miniature tact switch to allow manual control.
A solution for Raspberry Pi power management
The PiWatcher is designed to solve 2 problems with power management on the Raspberry Pi.
First, if you shut down a Raspberry Pi through software, for example by issuing a
your Raspberry Pi will cease to operate, but it does not completely shut down. Instead, it enters a quiescent state
where it continues to eat 30 to 50mA, sometimes more depending on connected peripherals. This is wasteful and can
become an issue in battery powered systems.
The PiWatcher can be programmed to fully cut power to the Raspberry Pi after a certain delay of inactivity. For
example, you can tell the PiWatcher to cut power 10 seconds after a
shutdown command has been issued, giving
the Raspberry Pi enough time to cleanly power off.
The second issue with power management has to do with the ability to recover from situations where a Raspberry Pi becomes stuck in an unrecoverable state. While in theory, this should not happen, a long-running Raspberry Pi can get 'stuck' or 'freeze', due to software or hardware failures or even environmental factors such as heat. In some cases the least unsatisfactory approach to deal with this issue is to simply switch off and on again the Raspberry Pi, enabling the application to continue and/or send out an alert.
The PiWatcher can be programmed to automatically power cycle a Raspberry Pi if it does not receive a 'heartbeat' from the device after a user selectable delay. This can allow some critical applications to continue to operate without human intervention.
Furthermore, the PiWatcher can be programmed to "sleep" for a certain delay after a shutdown, ranging from a few seconds to about 36 hours, before rebooting your Raspberry Pi.
The table below summarizes the power consumption of a PiWatcher connected to a Raspberry Pi (measurements were done with a Pi Zero W).
|PiWatcher is running normally||7mA in addition to the power consumption of the Raspberry Pi (typically >130mA).|
|PiWatcher is "sleeping" until reboot||3mA|
|PiWatcher has fully shut down||>0.5mA|
It has an LED and a button too!
The PiWatcher has an LED. When the Raspberry Pi is powered on, the LED is continuously on. When the Raspberry Pi is "sleeping" for a certain delay, the LED blinks slowly. When the Raspberry Pi is powered off, the LED remains off.
The PiWatcher also has a useful micro tact-switch:
- When your Raspberry Pi is running:
- a long press (5 seconds) on the button, followed by a button release, will fully power off the Raspberry Pi.
- a short press (half a second) on the button will send a software signal that can be exploited for user-defined purposes.
- When your Raspberry Pi is shut down, a short press on the button will restart the Raspberry Pi.
Using the PiWatcher
To start using the PiWatcher, follow these steps.
Plug the PiWatcher in the first 6 pins of the Raspberry-Pi GPIO header. For greater mechanical stability it is recommended to secure the PiWatcher to the Pi with a standard 11mm standoff (2.5mm).
Next, plug the USB power supply into the PiWatcher. In turn, this will boot the Raspberry Pi.
To use the PiWatcher on the Raspberry Pi, you will need to enable I2C on the Raspberry Pi. Use
sudo raspi-config for this
purpose (as described in this Adafruit tutorial for example).
piwatcher command line tool:
wget -N http://omzlo.com/downloads/piwatcher
Note: you can also compile the file yourself from source.
You'll need to make sure the file is executable and that it is located in a directory included in your PATH (e.g.
/usr/local/bin on a Raspbian system).
chmod a+x piwatcher sudo mv piwatcher /usr/local/bin/
piwatcher tool can then be used to query and configure the PiWatcher.
piwatcher status should return:
If you press the micro-switch on the PiWatcher and then re-run
piwatcher status, you should see the following output:
OK 0x80 button_pressed
You can clear this button_press event, resetting the status of the PiWatcher by running
piwatcher status will show again status 0x00.
Setup on older Raspberry-Pi models
The PiWatcher works on all recent Raspberry Pi models, except for the Pi 4. On older Raspberry-Pi models (e.g. The 2012 model B), you may encounter inconsistent behaviors with the
piwatcher command because of I2C clock speed issues. To fix this problem on these older models, you will need to slow down the I2C clock from the default 100kHz to 50kHz, by editing the file
/boot/config.txt and changing the following line:
After modifying the file, reboot your machine and you should be good to go.
We will now program the PiWatcher to shut off the Raspberry-Pi after 30 seconds if it does not receive any message from the Raspberry Pi, with the command
piwatcher watch 30.
After this command has been issued, the PiWatcher will start a 30 second counter. If the counter reaches 0, the power to the Raspberry Pi will be cut off. However, this counter will be reset to 30 seconds each time the PiWatcher receives a 'read request' from the Raspberry Pi. A simple way to issue a 'read request' is to issue the command
In this example, a simple way to keep the Raspberry-Pi form shutting down would be to run the following loop:
while true do piwatcher status sleep 25 done
sleep 25 assures that the PiWatcher is called approximately every 25 seconds, taking a 5-second safety margin from our 30-second deadline.
If this loop gets interrupted for any reason, the Raspberry-Pi will reboot after at most 30 seconds.
This feature can be exploited to completely shut off a RaspberryPi after a shutdown. Assuming the Pi takes at most 15 seconds to shut down, we can issue the following commands:
piwatcher watch 15 shutdown now
By default, the PiWatcher will shut off the Raspberry Pi until the user presses the button or until USB power is cycled.
We can program the PiWatcher to "wake" the Raspberry Pi after a certain delay (expressed in seconds).
To reboot the Raspberry-Pi 10 minutes after shutdown, we would simply type:
piwatcher wake 600
A clock under the hood
The PiWatcher is based on a Microchip attiny45 8-bit microcontroller, which runs with an 8Mhz internal oscillator.
An internal clock ticks about 25.04 times per second (8.000.000/(8192*39)). Watchdog and reboot time values are converted to internal clock ticks by multiplying their value by 25. Because of variations in temperature and voltage, the accuracy of these timings may be off by +/-10%.
You can view the actual value of the clock by issuing the command
Running piwatcher automatically
In most cases, you don't want to type commands with
piwatcher each time your Raspberry Pi boots up.
Instead, you will want to run PiWatcher automatically each time the Raspberry Pi boots up, with the correct configuration.
Fortunately, this is rather easy thanks to systemd.
As an example, we will consider the case where you want the Raspberry-Pi to fully shut down automatically after 30 seconds of inactivity, either because you've halted it or because it got 'stuck'.
For simplicity, we will assume you are running a recent version of Raspbian Linux and that you have installed the
piwatcher binary in the directory
It takes 3 steps to implement our scenario.
STEP 1. Create a monitoring script
Use your favorite editor to create the file
/home/pi/piwatcher.sh with the following content.
#!/bin/bash /usr/local/bin/piwatcher watch 30 while true; do /usr/local/bin/piwatcher status >> /dev/null sleep 15 done
This will essentially set a 30-second watchdog, and start an infinite loop that sends a message to the piwatcher every 15 seconds to assure that the watchdog is not triggered.
We need to make this script executable as follows.
chmod a+x /home/pi/piwatcher.sh
STEP 2: Create a new systemd service
Now we will create a systemd service for the previously created script. As we need 'root permission' to create the script, we will use sudo:
sudo vim /etc/systemd/system/piwatcher.service
You can replace
nano or your favorite editor in the line above.
The content of the file should look as follows.
[Unit] Description=PiWatcher Service StartLimitIntervalSec=0 [Service] Type=simple Restart=always RestartSec=1 User=pi ExecStart=/home/pi/piwatcher.sh [Install] WantedBy=multi-user.target
STEP 3: Activate and start the service
Finally, we will activate the service.
sudo systemctl enable piwatcher
This will typically output the following message: "Created symlink /etc/systemd/system/multi-user.target.wants/piwatcher.service → /etc/systemd/system/piwatcher.service."
We will also start the service, as follows.
sudo systemctl start piwatcher
The activation (and start) only needs to be performed once. The piwatcher will now be launched automatically each time the machine boots up.
The PiWatcher uses an extremely simple communication protocol based on I2C. The board essentially features an 8-byte register array that can you can read to or write from, at I2C address 0x62.
This register array is structured as follows:
|1||Watchdog timeout in seconds, 0=disabled.|
|2-3||Wakeup delay in seconds divided by 2 (5 means 10 seconds). LSB first. 0=disabled.|
|4-7||Internal clock. LSB first.|
The status byte has the following structure:
|Bit 7||BUTTON_PRESSED||A 1 indicates that the PiWatcher button has been pressed. Writing a 1 will clear the bit.|
|Bit 6||TIMER_BOOT||A 1 means that the PiWatcher rebooted the Pi after a wake-up period. Writing a 1 will clear the bit. This is unreliable however since the PiWatcher may have reset.|
|Bit 5||BUTTON_BOOT||A 1 means that the PiWatcher rebooted the Pi because the user pressed the button. Writing a 1 will clear the bit. This is unreliable however since the PiWatcher may have reset.|
./piwatcher dump will print the raw content of all registers.
The content of the registers can be manipulated with
i2c-tools as well (see instructions here for example). For example, you can get the status byte with the command
i2cget -y 1 0x62 0.