RasPi zeitgesteuert starten per RTC

Auf Dauerbetrieb

Der Dauerbetrieb erfordert noch ein paar Arbeiten an der Konfiguration, um die manuell vorgenommenen Aktionen zu automatisieren. Deaktivieren Sie dazu in der Datei /etc/modprobe.d/raspi-blacklist.conf den Eintrag blacklist i2c-bcm2708, und tragen Sie stattdessen entweder in der Datei /etc/modprobe.d/raspi.conf die Zeile options i2c-bcm2708 baudrate=400000 oder in /etc/modules die Zeile i2c-dev ein.

Mit sudo update-rc.d fake-hwclock remove und sudo update-rc.d hwclock remove bereinigen Sie die Startskripte. Dann wenden Sie im Verzeichnis /etc/init.d den Patch aus Listing 5 mit dem folgenden Kommando auf das entsprechende Skript an:

$ patch < hwclock.sh.patch

Listing 5

 

--- hwclock.sh.original 2012-12-22 06:57:47.000000000 +0100
+++ hwclock.sh  2013-11-03 19:27:50.653988109 +0100
@@ -21,10 +21,10 @@
 ### BEGIN INIT INFO
 # Provides:          hwclock
-# Required-Start:    mountdevsubfs
+# Required-Start:    kmod
 # Required-Stop:     $local_fs
 # Default-Start:     S
-# X-Start-Before:    checkroot
+# X-Start-Before:
 # Default-Stop:      0 6
 ### END INIT INFO
@@ -33,6 +33,7 @@
 HWCLOCKACCESS=yes
 HWCLOCKPARS=
 HCTOSYS_DEVICE=rtc0
+I2CBUS=0
 # We only want to use the system timezone or else we'll get
 # potential inconsistency at startup.
@@ -43,6 +44,7 @@
     [ ! -x /sbin/hwclock ] && return 0
     [ ! -r /etc/default/rcS ] || . /etc/default/rcS
     [ ! -r /etc/default/hwclock ] || . /etc/default/hwclock
+    [ ! -r /etc/default/rtc ] || . /etc/default/rtc
     . /lib/lsb/init-functions
     verbose_log_action_msg() { [ "$VERBOSE" = no ] || log_action_msg "$@"; }
@@ -61,8 +63,8 @@
                printf "0.0 0 0.0\n0\nUTC" > /etc/adjtime
            fi
-           if [ -d /run/udev ] || [ -d /dev/.udev ]; then
-               return 0
+           if [ ! -c /dev/HCTOSYS_DEVICE ]; then
+               echo mcp7941x 0x6f > /sys/bus/i2c/devices/i2c-$I2CBUS/new_device
            fi
            if [ "$HWCLOCKACCESS" != no ]; then

Außerdem fügen Sie das neue Startskript aus Listing 6 hinzu. Beide Startskripte lesen aus der Datei in Listing 7 den zu verwendenden I2C-Bus.

Listing 6

 

#!/bin/sh
### BEGIN INIT INFO
# Provides:          raspi-rtc-power
# Required-Start:    kmod
# Required-Stop:     halt
# X-Stop-After:      networking
# Default-Start:     S
# Default-Stop:      0
# Short-Description: on/off Raspi-RTC-Power
# Description:       switching on/off power via RTC chip on Raspi extension board
### END INIT INFO
set -e
. /lib/lsb/init-functions
ALARM=0;
I2CBUS=0;
if [ -r /etc/default/rtc ]; then
  . /etc/default/rtc
fi
if [ -r /etc/wakealarm ]; then
  ALARM=$(cat /etc/wakealarm)
fi
case "${1:-}" in
  start)
    log_action_begin_msg "Switching on RasPi-RTC-Power "
    modprobe i2c-dev
    i2cset -f -y $I2CBUS 0x6f 0x07 0x00
    ES=$?
    log_action_end_msg $ES
    ;;
  stop)
    log_action_begin_msg "Switching off RasPi-RTC-Power "
    /sbin/rtc-power $I2CBUS $ALARM
    ES=$?
    log_action_end_msg $ES
    ;;
  *)
    echo "Usage: ${0:-} {start|stop}" >&2
    exit 1
    ;;
esac

Listing 7

 

# Default settings for Raspi-RTC-Power. This file is
# sourced by /bin/sh from /etc/init.d/raspi-rtc-power.
# Number of I2C bus hosting the RTC chip: 0 or 1
I2CBUS=bus#

Die nunmehr aktualisierten Startskripte übernehmen Sie mit den folgenden zwei Kommandos wieder in den Systembetrieb:

$ sudo update-rc.d hwclock defaults
$ sudo update-rc.d raspi-rtc-power defaults

Wie erwähnt stehen im aktuellen Treiber für den MCP79410 nicht alle notwendigen Funktionen bereit. Daher braucht es noch ein eigenes Programm (siehe Listing 8), um beim Systemstopp sowohl die Weckzeit zu programmieren als auch das Control-Register so zu setzen, dass die Verzögerungszeit des Zeitgebers abläuft [5].

Setzen Sie die Weckzeit auf 0, weckt der Chip den RasPi nicht auf. Das klappt dann nur manuell oder durch Wiederkehr der Stromversorgung. Liegt die Weckzeit aber mindestens 120 Sekunden in der Zukunft, dann gilt diese, ansonsten gilt der Zeitpunkt in genau 120 Sekunden von jetzt als Weckzeit.

Das Listing 8 speichern Sie in der Datei rtc-power.c und übersetzen diese mit gcc rtc-power.c -o rtc-power gleich am RasPi selbst. Bevor Sie rtc-power ins Verzeichnis /sbin/ verschieben, setzen Sie noch den Eigentümer und die Gruppe mit sudo chown root:root rtc-power auf die passenden Werte.

Listing 8

 

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <time.h>
#define MCP7941X        0x6f
#define CTRLREG         0x07
#define ALARM0REG       0x0a
#define ALARMREGSETLEN  6
#define ALARMMC         0x70
#define RTCOUT1         0x80
#define ALARM0EN        0x10
#define MINTIMEGAP      120
char int2bcd(char val) {
  return (val%10+16*(val/10));
}
int main(int argc, char *argv[])
{
  int file;
  int i2cbus; // I2C bus number
  char i2cdevicename[11];
  char cbuffer[2]; // I2C Control Buffer
  char buffer[ALARMREGSETLEN+1]; // I2C Alarm0 Buffer
  char *end;
  time_t atime; // Alarm time in seconds since epoch
  time_t now = time(NULL);
  struct tm *alarm; // Alarm in broken down time
  /* get command line parameters */
  if (argc != 3) {
    printf("Error: 2 Parameters expected.\n");
    exit(1);
  }
  i2cbus = strtol(argv[1], &end, 0);
  if (*end || i2cbus < 0 || i2cbus > 1) {
    printf("Error: I2C Bus Number 0 or 1 expected.\n");
    exit(2);
  }
  atime = strtol(argv[2], &end, 0);
  if (*end || atime < 0) {
    printf("Error: Alarm time zero or greater expected.\n");
    exit(3);
  }
  /* set RTC control and ALARM0 accordingly */
  if (atime == 0) { // in case alarm time is zero then ...
    int i;
    cbuffer[1] = RTCOUT1; // ... simply switch off ...
    for (i=1; i<=ALARMREGSETLEN; i++) buffer[i]=0; // ... and clear alarm time
  }
  else { // in case of a non-zero alarm time ....
    cbuffer[1] = ALARM0EN; // ... enable the alarm ...
    if (atime - now < MINTIMEGAP) atime = now + MINTIMEGAP; // ... make alarm causal ...
    alarm = gmtime(&atime);
    if (alarm->tm_sec > 59) alarm->tm_sec = 59; // ... skip any leap seconds if any ...
    buffer[1] = int2bcd(alarm->tm_sec); // and write seconds
    buffer[2] = int2bcd(alarm->tm_min); // minutes
    buffer[3] = int2bcd(alarm->tm_hour); // hour
    buffer[4] = int2bcd(alarm->tm_wday+1); // day of week
    buffer[4] |= ALARMMC; // add alarm match condition and write
    buffer[5] = int2bcd(alarm->tm_mday); // day of month
    buffer[6] = int2bcd(alarm->tm_mon+1); // month
  }
  /* open i2c device */
  snprintf(i2cdevicename, 11, "/dev/i2c-%d", i2cbus);
  file = open(i2cdevicename, O_WRONLY);
  if (file < 0) {
    printf("Error: Can't open /dev/i2c-%d.\n", i2cbus);
    exit(4);
  }
  if (ioctl(file, I2C_SLAVE_FORCE, MCP7941X) < 0) {
    printf("Error: Can't attach I2C Client 0x%x.\n", MCP7941X);
    exit(5);
  }
  /* write alarm0 to RTC */
  buffer[0] = ALARM0REG; // set ALARM0 register address
  if (write(file, buffer, ALARMREGSETLEN+1) != ALARMREGSETLEN+1) {
    printf("Error: Can't write alarm to I2C Client 0x%x.\n", MCP7941X);
    exit(6);
  }
  /* activate alarm and deactivate power rail */
  cbuffer[0] = CTRLREG; // set RTC control register address
  if (write(file, cbuffer, 2) != 2) {
    printf("Error: Can't write configuration to I2C Client 0x%x.\n", MCP7941X);
    exit(7);
  }
  exit(0);
}

Weckruf

Beim Systemstopp – am einfachsten initiiert mit sudo halt – erwartet das Skript aus Listing 6 die Weckzeit in der Datei /etc/wakealarm als Anzahl der Sekunden seit dem 1. Januar 1970 um 00:00:00 UTC [6]. Listing 9 zeigt, wie Sie eine absolute Weckzeit am Weihnachtsabend oder eine relative von der Kommandozeile aus anlegen.

Listing 9

 

$ sudo sh -c 'date -d "2014-12-24 17:59:30" +%s > /etc/wakealarm'
$ sudo sh -c 'echo $((`date +%s` + (7 * 60 + 11) * 60 + 13)) > /etc/wakealarm'

Das Wecken deaktivieren Sie durch das Löschen dieser Datei oder indem Sie die Weckzeit auf 0 setzen.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 8 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Raspberry Pi Geek kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

Aktuelle Ausgabe

04/2019
TV & Multimedia

Diese Ausgabe als PDF kaufen

Preis € 9,99
(inkl. 19% MwSt.)

Stellenmarkt

Neuigkeiten

  • Finger weg

    Ein Temperatursensor verrät, ob Sie einen Gegenstand gefahrlos berühren dürfen. Beim Messen brauchen Sie dabei noch nicht einmal Kontakt zum Objekt.

  • Aus einer Hand

    Um einen Mikrocontroller zu programmieren, genügt ein Raspberry Pi. Wir zeigen, was Sie dazu noch benötigen.

  • Im Gleichtakt

    Synchronisierte Live-Loops und selbst erstellte Funktionen helfen dabei, Sonic Pi wie ein Live-Instrument zu spielen.

  • Mach mal

    Das Ftduino-Modul schlägt die Brücke zu Fischertechnik und ermöglicht es unter anderem, einen Drei-Achsen-Roboter anzusteuern.

  • Eleganter Diener

    Jeden Morgen dieselben Handgriffe, um zu sehen, ob die S-Bahn fährt und wie das Wetter wird? Ein cleverer Infoscreen auf RasPi-Basis automatisiert den Vorgang.

  • Bienenflüsterer

    Bienenzüchter, die ihre Völker besser kennenlernen möchten, müssen die fleißigen Insekten nicht pausenlos stören. Mit einem Raspberry Pi und verschiedenen Sensoren überwachen sie Temperatur, Luftfeuchtigkeit und bald auch das Gewicht des Bienenstocks.

  • Beerige Musik

    Für echten Hi-Fi-Sound braucht es mehr als einen kleinen Bluetooth-Brüllwürfel. Mit Volumio und einem Raspberry Pi rüsten Sie Ihre klassische Hi-Fi-Anlage mit smarten Funktionen auf.

  • Ton ab!

    Auf den ersten Blick erscheint der RasPi zu schwachbrüstig für den Betrieb leistungshungriger DAW-Software. Doch der Schein trügt.

  • Himbeer-TV

    Der DVB TV µHAT rüstet den Raspberry Pi mit einem DVB-T/T2-Tuner auf. Die deutsche TV-Landschaft schränkt dessen Möglichkeiten allerdings ein.

  • Git à la RasPi

    Mit wenigen Handgriffen zum Git-Hoster: Die dezentrale Arbeitsweise von Git erleichtert in Kombination mit der Netzwerkfähigkeit des RasPi das Verwalten von Quellcode.