| assets | ||
| etc | ||
| .gitignore | ||
| powermon.ino | ||
| powermon.pdf | ||
| README.md | ||
Power Monitor - Linux Setup Guide (Debian)
This document explains how to install, configure, and run the Arduino Power Monitor service on a Debian‑based Linux system.
The service listens to USB serial messages from an Arduino Uno and executes specific scripts when certain power‑related events occur.
It is used in conjunction with a UPS. My UPS does not have monitoring tools, so that's why I created this project so I can detect a power outage.
1. Requirements
On the linux server side
- Debian or any Debian-based (I haven't tested other linux distributions other than Proxmox)
- Python 3.7+
- Root access (required for running shutdown scripts)
Additional hardware
- Uninterruptible Power Supply (UPS) (with you your server powered from that UPS)
Electronics:
- Arduino Uno (or compatible clone)
- USB cable (To connect the arduino to the server)
- 5v Power adaptor
- 3x LEDS (green, yellow, red)
- 3x 220 Ohm resistors
- 1x 10k Ohm resistor
- 1x Piezoelectric speaker
- 1x Toggle switch to arm/disarm.
- 5V external power supply (like an old phone charger)
If you want to decouple the external powersupply, you can use additional components like a relay or optocoupler.
2. Install Dependencies
Install Python and the serial library:
sudo apt update
sudo apt install python3 python3-serial -y
3. Create the Power Monitor Directory
sudo mkdir -p /etc/powermon
sudo mkdir -p /etc/powermon/scripts
Place your event scripts inside:
/etc/powermon/scripts/recovery.sh
/etc/powermon/scripts/warning.sh
/etc/powermon/scripts/alert.sh
/etc/powermon/scripts/panic.sh
/etc/powermon/scripts/powerdown.sh
The scripts can mean something different for each individual use case. The important thing is that you handle the powerdown.sh, because if that script gets called, it really is time to make sure your server safely shuts down to protect against damage and data loss.
Make all scripts executable:
sudo chmod +x /etc/powermon/scripts/*.sh
File Structure:
/etc/powermon/
├── power_monitor.py
└── scripts/
├── recovery.sh
├── warning.sh
├── alert.sh
├── panic.sh
└── powerdown.sh
4. Install the Python Monitor Script
Save the monitor script as:
/etc/powermon/power_monitor.py
5. Serial Port Permissions
Debian requires users to be in the dialout group to access /dev/ttyACM* or /dev/ttyUSB*. (root already has permission)
Add your user:
sudo usermod -a -G dialout $USER
Log out and back in.
Note: The systemd service runs as root, so this step is only needed if you test manually.
6. Auto-Port Detection
The monitor automatically detects Arduino boards on:
- /dev/ttyACM* (official Uno)
- /dev/ttyUSB* (CH340 clones)
No manual configuration is required.
7. Event Mapping
The Arduino sends text messages over serial. The monitor reacts to these messages:
| Arduino Message | Action |
|---|---|
Voltage OK |
Do nothing |
Voltage recovered |
Run /etc/powermon/scripts/recovery.sh and reset all flags |
LOW VOLTAGE WARNING |
Run /etc/powermon/scripts/warning.sh |
LOW VOLTAGE ALERT |
Run /etc/powermon/scripts/alert.sh |
LOW VOLTAGE ALERT PANIC!! |
Run /etc/powermon/scripts/panic.sh |
POWERDOWN |
Run /etc/powermon/scripts/powerdown.sh |
Each script is executed only once per session. When "Voltage recovered" is received, all flags reset and scripts may run again.
8. Create the Systemd Service
Create the service file:
sudo nano /etc/systemd/system/powermon.service
Paste:
[Unit]
Description=Arduino Power Monitor Service
After=network.target
[Service]
ExecStart=/usr/bin/python3 /etc/powermon/power_monitor.py
Restart=always
User=root
[Install]
WantedBy=multi-user.target
Save and reload systemd:
sudo systemctl daemon-reload
sudo systemctl enable powermon.service
sudo systemctl start powermon.service
9. Check Service Status
View logs:
journalctl -u powermon.service -f
Check if it's running:
systemctl status powermon.service
10. Testing
- Plug in the Arduino
- Open logs
- Trigger events on the Arduino (simulate voltage drops)
- Verify the correct scripts execute
- Verify scripts do not run twice
- Trigger "Voltage recovered"
- Verify flags reset and scripts can run again
11. Electronic Schematic:
- Connect ground pin on arduino to ground of the 5v adaptor to create common ground.
- You can also opt to isolate this with an optocoupler or a relay. In either case, you will need to modify the arduino code.
- Connect the VCC from the 5V adaptor, through a 10K Ohm resistor to ground. This will be the pull down resistor.
- Connect the VCC from the 5V adaptor to pin A5 of the arduino.
- Connect all the LED grounds and a piezoelectric speaker lead together and connect them to common ground.
- Connect the Green LED positive, through a 150 Ohm resistor to pin 13 of the Arduino.
- Connect the Yellow LED positive, through a 150 Ohm resistor to pin 8 of the Arduino.
- Connect the Red LED positive, through a 150 Ohm resistor to pin 4 of the Arduino.
- Connect the remaining lead of the piezoelectric speaker to pin 3 of the Arduino.
- Connect the common (Pin 2) of the toggel switch to Pin A4.
- Connect Pin 1 of the toggle switch to ground.
- Connect Pin 3 of the toggle switch to 5V VCC of the Arduino.
- Connect the RESET pin of the Arduino to Pin 7.
- (Optional) connect all other digital pins (except pin 1 & 2) to ground.
- (Optional) Connect all other analog pins to ground.
Arduino Status LEDs
1. Periodic Green Flash - Normal Operation
The green LED flashes once every 5 seconds to indicate that the Arduino is running normally and actively monitoring the input voltage. During this mode, the Arduino sends "Voltage OK" to the serial port once every second.
2. Blinking Yellow - Warning Mode
The yellow LED blinks every 0.5 seconds, and the buzzer emits short beeps. This means the Arduino has detected a power loss or no voltage on the sensing pin (A5). It will send "LOW VOLTAGE WARNING" on the serial port.
3. Rapid Yellow Blinking - Alert Mode
The yellow LED blinks every 0.25 seconds, and the buzzer continues beeping. This indicates a prolonged loss of power or continued absence of voltage on pin A5. The Arduino will send "LOW VOLTAGE ALERT" on the serial port.
4. Alternating Red-Yellow Flash - Panic Mode
The red and yellow LEDs flash alternately every 0.5 seconds, and the buzzer plays a siren sound. This signals a critical and extended power loss. If power is not restored soon, the Arduino will issue a POWERDOWN command over serial. During this mode, it sends "LOW VOLTAGE ALERT PANIC!!" on the serial port.
5. Rapid Red Flash - Powerdown Mode
The red LED blinks every 0.25 seconds, and the buzzer continues the siren. This indicates that the Arduino is repeatedly sending the "POWERDOWN" command over serial, instructing the connected host to shut down immediately.
6. Solid Red - Halted State
The red LED remains fully lit.
This means the Arduino program has halted, typically after receiving the r0 command over serial, which puts it into hardware reset mode.
To enable automatic hardware reset, connect the RESET pin to PIN 7. PIN 7 is normally held high, but in the Halted State it is pulled low, triggering a reset when connected to the RESET pin.
7. Short Flash of All LEDs - Power Recovered
When power is restored, all LEDs briefly turn on for about one second. After this confirmation flash, the Arduino returns to Normal Operation Mode, where the green LED flashes periodically to indicate stable voltage and normal monitoring.
8. Periodic Red Flash - Disarmed
The red LED flashes once every 5 seconds to indicate that the Arduino currently disarmed. During this mode, the Arduino sends "DISARMED" to the serial port once every second.
To disarm the Arduino connect A4 to ground. To arm, connect it to the 5V VCC of the Arduino.
Commands You Can Send to the Arduino Over Serial
Status Command - "s"
Send "s" to request the Arduino's current status. It will return the active mode and any relevant voltage information.
Example response:
1234567890 - POWERMON v1.0.0 - Current voltage:5.00 V
Test-On Command - "t1"
Send "t1" to enable testing mode. In this mode, the Arduino simulates a power loss by setting the internal voltage variable to -1.0. A negative voltage is used specifically to indicate a test condition—real power loss always results in 0V (or slightly above zero).
Because the voltage is forced to -1.0, the Arduino will behave exactly as if a real power failure occurred. It will progress through all power-loss states, including issuing the POWERDOWN command.
Make sure your host system recognizes testing mode; otherwise, it may interpret the simulated failure as real and shut down unexpectedly.
Test-Off Command - "t0"
Send "t0" to disable testing mode and resume normal voltage sensing on pin A5. This transition triggers a Power-Recovered state. You may optionally follow this command with a reset.
Soft Reset Command - "r1"
Send "r1" to perform a soft reset. This clears internal detection flags and variables without halting the program.
Hard Reset Command - "r0"
Send "r0" to trigger a hardware reset. This command pulls Pin 7 low, and putting the Arduino into a halting state.
To ensure the Arduino actually resets, Pin 7 must be physically connected to the RESET pin. If not connected, the Arduino will remain halted indefinitely until manually reset.
