Herzschrittmacher für den Raspberry Pi – Teil 4: Mikrocontroller Software

Herzschrittmacher Projekt LogoIm vorhergegangenen Artikel hatte ich beschrieben, wie wir uns eine Programmierumgebung für den ATtiny 13A Mikrocontroller einrichten. Nachdem wir erfolgreich unseren ersten Sketch auf den µC geflasht haben, sind wir nun bereit für die eigentliche Herzschrittmacher-Software. In diesem Artikel geht es um den Softwareteil, der auf dem Mikrocontroller läuft. Der ATtiny soll über einen Anschlusspin auf einen regelmäßigen Signalwechsel des Raspberry Pi hören. Wenn dieser Herzschlag für eine vorgegebene Zeit ausbleibt, müssen wir annehmen, dass der Raspberry Pi nicht mehr aktiv ist. Er hat sich aufgehängt oder befindet sich in einer Endlosschleife, aus der er sich nicht mehr befreien kann – jedenfalls erfüllt er nicht mehr seine Aufgabe. An dieser Stelle greift der Mikrocontroller ein und dreht dem Raspberry Pi kurzzeitig den Strom ab. Danach kann der RasPi neu booten, seine Funktion wieder aufnehmen und der Mikrocontroller seinerseits wird erneut mit der Überwachung beginnen.

Funktion der Herzschrittmacher Software

Herzschrittmacher BlockschaltbildIn der Einleitung habe ich bereits grob beschrieben, was die Aufgabe des Herzschrittmachers ist. Nebenstehend auch zur Erinnerung nochmal das Blockschaltbild. Der Mikrocontroller hat zwei Hauptaufgaben:

  1. Überwachung auf Timeout und
  2. Stromabschaltung im Falle eines Timeouts

Genau das macht der Hauptteil des Programm, wie wir gleich sehen werden.

Herzschrittmacher-Schaltung auf einem Raspberry Pi 3Herzschrittmacher Software

Für einen Mikrocontroller schreibt man Software üblicherweise nicht in Python wie beim Raspberry Pi sondern in der Programmiersprache C. Die Arduino IDE hat bereits alle Bestandteile an Board, um das C-Programm zu compilieren und auf den Mikrocontroller zu flashen.

Hier mein Herzschrittmacher Programm in C:

#define BOOTZEIT 30000
#define AUSZEIT 5000
#define AUSGANG 3
#define EINGANG 1
unsigned long warteZeit=60000;
volatile unsigned long letzterHerzschlag;

void setup() {
 pinMode(AUSGANG, OUTPUT);
 digitalWrite(AUSGANG, LOW);

 pinMode(EINGANG, INPUT);
 letzterHerzschlag = millis();                               // aktuelle Zeit merken
 attachInterrupt(digitalPinToInterrupt(EINGANG), isr, CHANGE);
 stromAn();                                                  // Strom einschalten
}

void loop() {
 if((millis() - letzterHerzschlag) > warteZeit) {            // Timeout eingetreten
  stromAus();
  stromAn();
 }
 delay(100);
}

void isr() {
 letzterHerzschlag = millis();                               // letzten Herzschlag merken
}

void stromAus() {
 digitalWrite(AUSGANG, HIGH);                                // Strom ausschalten
 delay(AUSZEIT);                                             // für ein paar Sekunden
}

void stromAn() {
 digitalWrite(AUSGANG, LOW);                                 // Strom einschalten
 delay(BOOTZEIT);                                            // und Bootzeit abwarten
 letzterHerzschlag = millis();                               // aktuelle Zeit merken
}

Wie man sieht ist das Programm ziemlich kompakt. Gehen wir es der Reihe nach durch. Zu Beginn werden einige Parameter definiert:

  • BOOTZEIT steht für die Zeit im Millisekunden, die dem Raspberry Pi zugestanden wird um zu booten. Hier 30s.
  • Attiny-PinsAUSZEIT ist Dauer der Stromunterbrechung um einen Reboot auszulösen. Hier 5s.
  • AUSGANG ist die Pinbezeichnung für den Anschluss zur Stromabschaltung. Hier PB3 = Pin Nummer 2.
  • EINGANG ist die Pinbezeichnung für den Herzschlageingang. Hier PB1 = Pin Nummer 6.
  • warteZeit ist die Zeit, die maximal ohne Herzschlag verstreichen darf, bevor ein Reboot ausgelöst wird. Hier großzügig 60s

Die Zeiten können natürlich angepasst werden, wenn beispielsweise ein Reboot länger als 30 Sekunden dauert.

Zusätzlich wird am Programmanfang eine Variable letzterHerzschlag definiert, die jeweils die Zeit des letzten erkannten Signalwechsels speichert.

In der Funktion setup() werden die Ein- und Ausgänge festgelegt und beschaltet. Dabei wird der AUSGANG auf LOW gelegt. Daran müssen wir denken, dass wir es hier mit einer Reverse Logic zu tun haben, denn der MOSFET invertiert das Signal. Es gilt also:

  • AUSGANG = LOW : Strom an
  • AUSGANG = HIGH : Strom aus

Dann wird die Variable letzterHerzschlag mit der aktuellen Zeit vorbelegt und eine Interruptbehandlung eingerichtet mit der Zeile:

attachInterrupt(digitalPinToInterrupt(EINGANG), isr, CHANGE);

Dadurch wird laufend der Anschluss EINGANG überwacht und im Falle eines Polaritätswechsels (CHANGE) die Funktion isr aufgerufen. Diese Funktion, wie man weiter unten im Programm sehen kann, macht nichts anderes als die Variable letzterHerzschlag erneut mit der aktuellen Zeit zu versorgen. Das passiert jetzt automatisch bei jedem Wechsel von HIGH auf LOW und von LOW auf HIGH am Pin EINGANG.

Die letzte Aktion der Funktion setup() ist das Einschalten des Stroms über die Funktion stromAn().  Die finden wir am Ende des Programms. stromAn() legt zuerst den AUSGANG auf LOW um den Strom für den Raspberry Pi einzuschalten und wartet dann die BOOTZEIT ab. Dann wird wiederum die Variable letzterHerzschlag mit der aktuellen Zeit belegt.

Analog zu stromAn() gibt es auch die Funktion stromAus(). Sie macht nichts anderes als den AUSGANG auf HIGH zu legen um dem Raspberry Pi den Strom abzuschalten und die vorgegebene AUSZEIT abzuwarten.

Das Hauptprogramm loop() verbindet nun alle Funktionen und ist trotzdem recht simpel. Es überprüft, ob der TimeOut abgelaufen ist. Das ist dann der Fall, wenn die Differenz aus aktueller Zeit und der Zeit des letzten erkannten Herzschlags größer ist als die vorgegebene warteZeit. Nur dann werden der Reihe nach stromAus() und stromAn() aufgerufen um den Raspberry Pi zwangsweise durchzubooten. Andernfalls wird nur 100ms gewartet um dann von vorne zu beginnen.

Nano-Programmer-Steckplatine

Herzschrittmacher Software flashen

Um das Programm auf einen ATtiny 13A zu bekommen, kopieren wir den Quelltext auf dieser Seite und fügen ihn in eine neue Seite der Arduino IDE ein. Abspeichern nicht vergessen! Wenn dann die Programmier-Hardware (siehe Schaltung) bereit ist, lässt sich der Sketch leicht auf den ATtiny flashen durch drücken der Shift-Taste und gleichzeitigem Klick auf das Icon mit dem Pfeil nach rechts. Am Programmer (Nano) werden die Lämpchen kurz blinken, dann ist der Flash-Vorgang beendet. Wenn die Arduino IDE keine Fehler auswirft, kann der ATtiny vom Steckbrett entnommen und in die eigentliche Herzschrittmacher-Schaltung eingesetzt werden.


Weitere Artikel in dieser Kategorie:

Schreiben Sie einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert