logiclrd / lights

Scheduler for aquarium light control using relay hat on a pi's GPIO

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lights

I am using a Libre Computer Le Potato currently:

I originally tried to do the build with a Banana Pi M64, but unfortunately their design runs exclusively on 3.3V and doesn't bother to power the 5V pins on the GPIO connector. The relay board (below) requires 5V and thus doesn't function on the Banana Pi M64. It does function on Le Potato, though :-)

As with any Pi type computer, this requires a Micro SD card to act as the "hard drive". I bought this one:

The Le Potato does not have an integrated Wi-Fi adapter. This USB device seems to do the trick:

In my early attempts with the Banana Pi M64, I encountered problems with it overheating while doing such mundane tasks as compiling code. To combat this, I installed heat sinks:

Even with heat sinks, the Banana Pi would consistently overheat with the default governor, which defaulted to performance. Changing the M64's governor to powersave was what finally solved the overheating problem. However, Le Potato's default governor is the more conservative ondemand, and it does not seem to have the heat problems of the M64 with the default configuration. (Ubuntu doesn't come with cpufrequtils installed. But, it is easy to install with apt.)

The lights are controlled with a "hat" with four mains voltage relays on it:

In order to avoid aggravating the overheating problem, I purchased an extension cable to allow the relay board to be physically separate from the Banana Pi board:

Instead of slapping an adapter on a standard Female to Female cable, you can also buy Female to Male 40 Pin cables, but for some reason they are considerably more expensive. The Male-to-Male adapter shown here seems to work just fine.

With all of these bits assembled, the rest is all in software. I installed Ubuntu 22.04.1, which is linked to from the Le Potato official product page:

Basic configuration of the OS:

  • dpkg-reconfigure console-setup to change the font. (The largest possible font makes it much easier to use when it's up on a TV screen across the room.)
  • timedatectl set-timezone America/Winnipeg sets the correct timezone. This appears to persist across reboots.
  • In /etc/default/keyboard, change XKBLAYOUT to dvorak. This will take effect after a reboot, but can be applied immediately as well by running setupcon.
  • Listing files in /sys/class/net identifies the name of the Wi-Fi adapter. In this case, wlx3420032e4801. I assume that's a MAC address or something, so yours will likely be completely different.
  • Network configuration in /etc/netplan/50-cloud-init.yaml:
network:
  wifis:
    wlx3420032e4801:
      optional: true
      access-points:
        "Name of network":
          password: "password"
      dhcp4: true
  • Installation of PowerShell by downloading the package from Microsoft's GitHub releases.
    • At the time of writing this, the latest release is 7.3.4, at the following URL:
      • https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz
    • Installation:
mkdir /powershell
cd /powershell
tar zvfx /tmp/powershell-7.3.4-linux-arm64.tar.gz
  • This repository: cd / ; git clone https://github.com/logiclrd/lights
  • User account to run the lights service: adduser lights
  • Grant the lights user access to GPIO: usermod -a -G dialout lights

On the software side, the first step was to figure out how to talk to the GPIO pins.

On the Banana Pi M64, the most straightforward way to do this seems to be via the filesystem, which has dev nodes that interact with GPIO. However, on the Libre Computer device, this interface is officially deprecated, and instead they would like you to use gpioset, which comes installed as part of the gpiod package.

With some trial and error, I identified the GPIO pin numbers corresponding to the four relays:

  • Relay 0: Pin 83
  • Relay 1: Pin 82
  • Relay 2: Pin 84
  • Relay 3: Pin 86

(I noticed after setting up this mapping and doing the wiring that the silkscreen on the board lists "LED1" through "LED4" in the opposite order. Oh well :-) )

The mapping of relay numbers (0..3) to pin numbers is encapsulated in the pins subdirectory in this repository.

Then I created a straightforward abstraction of the control mechanism, which is in the control subdirectory in this repository. The on and off scripts take a relay number and do all the necessary translation internally to control the corresponding pin. For instance, on 1 turns on relay #1, which, behind the scenes, means that it sets the value of pin #82 to 0.

Finally, the actual scheduling engine was written using PowerShell. The current shebang line assumes a PowerShell installation in /powershell. The schedule is defined in a custom-format text file schedule.txt in the schedule subdirectory, and the script Run-Schedule.ps1 reads this file in and processes it, turning it into invocations of control/on and control/off.

The scheduling engine Run-Schedule.ps1 is invoked using systemctl. A definition for a systemctl service was created, and a copy of it is committed to this repository in the systemctl subdirectory. I created a regular user lights to run the persistent script, and the init script updates the permission bits on the value dev nodes so that code doesn't need to be root to control the lights.

The service needs to be "enabled" to be run automatically on system startup:

systemctl enable lights

You can inspect the current state of the lights service with the command:

systemctl status lights

The output of this command includes the log tail, and the log tail includes the basic diagnostic output from the RunSchedule.ps1 scheduling engine, e.g.:

Feb 15 14:53:49 bananapim64 RunSchedule.ps1[4019]: Current time: 02/15/2023 14:53:49
Feb 15 14:53:49 bananapim64 RunSchedule.ps1[4019]: Next switch: Turn light # 0 to the ON state at 02/15/2023 15:00:00
Feb 15 14:53:49 bananapim64 RunSchedule.ps1[4019]: Sleeping for 5 minutes
Feb 15 14:58:49 bananapim64 RunSchedule.ps1[4019]: Current time: 02/15/2023 14:58:49
Feb 15 14:58:49 bananapim64 RunSchedule.ps1[4019]: Next switch: Turn light # 0 to the ON state at 02/15/2023 15:00:00
Feb 15 14:58:49 bananapim64 RunSchedule.ps1[4019]: Sleeping for 71 seconds
Feb 15 15:00:00 bananapim64 RunSchedule.ps1[4019]: Sending control ON to 0
Feb 15 15:00:00 bananapim64 RunSchedule.ps1[4019]: Current time: 02/15/2023 15:00:00
Feb 15 15:00:00 bananapim64 RunSchedule.ps1[4019]: Next switch: Turn light # 2 to the ON state at 02/15/2023 18:00:00
Feb 15 15:00:00 bananapim64 RunSchedule.ps1[4019]: Sleeping for 90 minutes

I investigated NTP time synchronization as well, because I'm not sure how reliable the wall clock is on a Banana Pi M64, but I've decided to give it the benefit of the doubt. The NTP synchronization code is committed to the repository but I'm not currently using it.

Finally, this all needs to go into a case. That's a different project, involving OpenSCAD and a 3D printer. :-)

About

Scheduler for aquarium light control using relay hat on a pi's GPIO


Languages

Language:PowerShell 97.3%Language:Shell 2.7%