Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions apps/oled_piroman5/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OLED IP Display

Simple example using **piroman5** Raspberry Pi OLED driver (based on `luma.oled`) to show the current IP address and timestamp on a small OLED screen. The fan on BCM pin 18 of the piroman5 max board is automatically controlled based on the CPU temperature.
Simple example using **piroman5** Raspberry Pi OLED driver (based on `luma.oled`) to show the current IP address and timestamp on a small OLED screen. The fan on BCM pin 18 of the piroman5 max board is automatically controlled based on the CPU temperature and can be limited to a percentage of a two-minute interval with the ``--fan-duty`` option.


## Installation
Expand All @@ -16,11 +16,19 @@ sudo apt install libgpiod-dev

## Running

Add an entry to ``crontab`` so the script runs every minute:
Add an entry to ``crontab`` so the script runs every two minutes:

```bash
* * * * * /usr/bin/python3 /path/to/ip_display.py
*/2 * * * * /usr/bin/python3 /path/to/ip_display.py
```

Each run updates the OLED with the current IP address and the date/time (including seconds). The fan is powered on when the script starts. It remains on whenever the CPU temperature is 50 °C or higher and turns off once the temperature falls below that threshold.
To run the fan for less than the full two minutes when the CPU is cool, pass a percentage with ``--fan-duty`` (default is ``100``):

```bash
*/2 * * * * /usr/bin/python3 /path/to/ip_display.py --fan-duty 75
```

Each run updates the OLED with the current IP address and the date/time (including seconds). The fan is powered on when the script starts. It remains on whenever the CPU temperature is 50 °C or higher and, when cooler, runs only for the specified portion of the two-minute cycle.

The display also shows the current fan duty setting as ``Duty: <percentage>/120s`` on the last line.

47 changes: 39 additions & 8 deletions apps/oled_piroman5/ip_display.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/usr/bin/env python3
"""Display IP address and time on the OLED using the piroman5 driver.

This script is designed to be called from ``cron`` once per minute.
This script is designed to be called from ``cron`` once every two minutes.
It updates the OLED with the current IPv4 address and timestamp, and
controls the cooling fan on the piroman5 max board when the CPU
temperature exceeds ``50°C``.
controls the cooling fan on the piroman5 max board. By default the
fan runs continuously, but a different duty cycle (e.g. 75 or 50) may
be specified via ``--fan-duty`` to run the fan only for part of the
two-minute interval when the CPU temperature is below ``50°C``.

Dependencies can be installed with::

Expand All @@ -13,6 +15,7 @@

from datetime import datetime
import subprocess
import argparse

# piroman5 OLED driver, built on luma.oled
from luma.core.interface.serial import i2c
Expand Down Expand Up @@ -44,9 +47,30 @@ def get_ip_address(interface="eth0"):
return "0.0.0.0"


def parse_args():
"""Return parsed command line arguments."""

parser = argparse.ArgumentParser(
description="Update the OLED and control the cooling fan once."
)
parser.add_argument(
"--fan-duty",
type=int,
default=100,
help=(
"Percentage of the two-minute cycle to run the fan when the CPU "
"temperature is below the threshold (0-100)."
),
)
return parser.parse_args()


def main():
"""Update the OLED and control the cooling fan once."""

args = parse_args()
args.fan_duty = max(0, min(args.fan_duty, 100))

# Prevent gpiozero from resetting the pin states on exit so the fan
# remains in the state we set. Older versions of gpiozero may not
# expose ``Device._shutdown``, so handle that case gracefully.
Expand All @@ -66,8 +90,6 @@ def main():


fan = OutputDevice(FAN_PIN, active_high=True)
# Ensure the fan starts running when the program launches
fan.on()
rgb_leds = [OutputDevice(pin, active_high=True) for pin in RGBFAN_PIN]
rgb_leds[0].on()
rgb_leds[1].on()
Expand All @@ -80,8 +102,12 @@ def main():
ip = get_ip_address("eth0")
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

total_runtime = 120
fan_on_duration = total_runtime * args.fan_duty / 100
remaining = total_runtime

temp = cpu.temperature
if temp >= TEMP_THRESHOLD:
if temp >= TEMP_THRESHOLD or remaining > total_runtime - fan_on_duration:
fan.on()
else:
fan.off()
Expand All @@ -100,11 +126,16 @@ def main():
draw.text((0, 0), ip, font=font, fill=255)
draw.text((0, 16), now, font=font, fill=255)
draw.text((0, 32), f"CPU {temp:.1f}C F:{fan_status}", font=font, fill=255)
draw.text(
(0, 48),
f"Duty: {args.fan_duty}%/{int(total_runtime)}s",
font=font,
fill=255,
)

remaining = 60
while remaining >= 0:
temp = cpu.temperature
if temp >= TEMP_THRESHOLD:
if temp >= TEMP_THRESHOLD or remaining > total_runtime - fan_on_duration:
fan.on()
else:
fan.off()
Expand Down
Loading