Nachdem ich mit meinem QRP-PC nun schon
einige Jahre gearbeitet habe, wurde es so langsam mal Zeit, eine
neuere/verbesserte Version davon herzustellen. Das bisherige Gerät hat
zwar noch einige Erweiterungen bekommen (WLAN-Anschlußbuchse, Schalter,
um den Lüfter bei Bedarf auf 12V zu schalten, ...), aber irgendwie
wäre eine Echtzeituhr, eine Lüftersteuerung, und ein einfachere
Start/Stop-Prozedur doch ganz schön ... Naja, um das Gerät einfach
mal auszuschalten, und es kümmert sich selber darum, das System
herunterzufahren, wäre ein Pufferakku und eine Kommunikation mit dem
RasPi schon notwendig. Die Kommunikation könnte ein Mikrocontroller
übernehmen, der dann auch gleich eine Echtzeituhr bereitstellen
könnte ... Also habe ich mal ein grobes Diagramm entworfen, welches
sich im Laufe der Entwickung noch mehrfach veränderte.
|
Der neue Entwurf
Da der steuernde Microcontroller (der u.a. als Echtzeituhr fungiert)
dauernd mit 5V versorgt werden muss, das gesamte Gerät aber auch mit
12V betreibbar sein soll (→Solarbetrieb), bot sich ein
12V-Bleigelakkumulator und ein Spannungswandler "12V→5V" an.
Dieser Spannungswandler ist für 3A ausgelegt, da u.U.
(12V-Betrieb oder Netzausfall) über diesen Weg auch der RasPi mit 5V
versorgt wird. Bei Netzbetrieb übernimmt ein 5V/5A-Schaltnetzteil die
Versorgung des Controllers und des RasPi. Außerdem wird dabei der Akku mit
Hilfe eines weiteren Spannungswandlers "5V→∼13.8V" geladen.
Die genaue Ausgangspannung dieses Wandlers wird mit Hilfe eines
Temperaturfühlers (am Akku montiert) geregelt, um den Akku auch an
sehr warmen Tagen nicht zu überladen. Die aus verschiedenen Quellen
stammenden "5V"-Spannungen werden im Blockschaltplan mit Hilfe von
Dioden zusammengeführt. In der realen Schaltung werden dafür
MOSFET-Dioden verwendet, da
konventionelle Dioden eine zu hohe Flußspannung (und damit
Verlustleistung) hätten. Die Ausgangsspannung des 5V-Netzteils ist
geringfügig höher eingestellt als der Ausgang des Spannungswandlers,
damit sicher gestellt ist, daß das Netzteil den RasPi bei Netzbetrieb
versorgt (und nicht der Spannungswandler).
|
Die Schaltung des Controllers
Die primäre Aufgabe des Controllers ist es, die Stromversorgung des RasPi
mit Hilfe eines MOSFETs ein- und auszuschalten. Um die entsprechenden
Zeitpunkte dafür zu bestimmen, sind ein paar Messwerte (z.B. Ausgangsspannung
des Netzteils und Spannung/Ladezustand des Akkus) notwendig, sowie eine
Kommunikation mit dem RasPi. Zur Kommunikation wird in diesem Fall
der I2C-Bus
des RasPi verwendet, dessen Signale mit Hilfe von
bidirektionalen Pegelwandlern an die
Betriebsspannung des Controllers angepasst werden. Über diesen
Bus kann z.B. ein Programm/Script, welches auf dem RasPi läuft, die
(verzögerte) Abschaltung anfordern. Andererseits kann der Controller
auf diesem Weg ermitteln, ob der RasPi noch läuft, und im Falle eines
"Hängens" den RasPi abschalten ("Communication Timeout").
Zur Drehzahlregelung des Lüfters ist ein Temperaturfühler vorgesehen, mit dem die Temperatur im Gehäuse gemessen wird. Außer dieser autonomen Funktion kann die Drehzahl auch durch eine Anweisung vom RasPi erhöht werden (z.B. von einem Programm, welches die CPU-Temperatur bestimmt). Zusätzlich sind noch ein (Start/Stop-) Taster, LEDs zur Zustandsanzeige, und ein Interface zu meinem "Eindraht-Kommunikationsbus" vorgesehen. |
Das Layout der Steuerungsplatine
Der Entwurf des Gehäuses
Um den Platzbedarf des Geräts auf dem Basteltisch möglichst gering zu
halten, habe ich einen Aufstellungsort gewählt, der sonst kaum genutzt
werden kann: Unter dem Oszilloskop, welches auf dem aufgeklappten Tragegriff
steht, um einen bequemen Zugang zu den Bedienelementen zu bieten. Damit ergab
sich ein keilförmiger Raum mit einer Grundfläche von ca. 24x25cm, in
dem die Einzelkomponenten anzuordnen sind.
Als Material habe ich Sperrholz gewählt, welches relativ einfach zu
bearbeiten ist, und mit Hilfe von Profilleisten zu einem recht soliden
Gehäuse führt. Dadurch konnte ich mir die fummelige Herumlöterei
auf dem RasPi-Board ersparen, die für die Herausführung eines
WLAN-Anschlußes notwendig gewesen wäre.
Da zu erwarten war, daß die Anordnung und Befestigung der Bauteile im Gehäuse nicht gerade trivial wird, habe ich den Aufbau erst einmal in Blender simuliert. Dieses Programm ist zwar nicht unbedingt für die Anwendung im CAD-Bereich vorgesehen, kann dafür aber (nach etwas Einarbeitung) zweckentfremdet werden, und liefert durchaus Eindrücke, ob etwas etwas in der vorgesehenen Weise konstruiert werden kann, oder nicht. |
|
Der Aufbau
Beim Entwurf des Gehäuses (und den Überlegungen, welche Teile
miteinander verleimt, und welche verschraubt werden) zeichnete sich schon ab,
daß das Gerät eine "ziemlich verbaute Kiste" werden
würde, bei dessen Aufbau die Reihenfolge der Verbindung der Elemente
wichtig wäre, um die entsprechenden Schrauben noch erreichen zu
können.
|
Die Firmware des Controllers
Die Firmware des Controllers dient hauptsächlich der Kommunikation
mit dem RasPi und dem "Eindraht-Kommunikationsbus". Außerdem
sind einige Funktionen zum Ein- und Ausschalten des RasPi, die Echtzeituhr,
eine Lüftersteuerung, und einige Timer implementiert. Die eigentliche
Steuerung des Systems erfolgt großteils vom RasPi aus.
Das Einschalten des Systems kann auf verschiedene Weisen erfolgen: |
—
|
Einschalten der Netzversorgung: Die dadurch anliegende Spannung aus dem
Netzteil wird durch die Firmware detektiert, und die
"Startup"-Phase eingeleitet, die etwa zwei Minuten dauert, und
durch ein Blinken (kurz an, lang aus) der Staus-LED signalisiert wird.
Hierbei wird der RasPi mit Betriebsspannung versorgt, und die
I2C-Schnittstelle aktiviert. Erfolgt eine Kommunikation mit
dem RasPi, wird die "Startup"-Phase vorzeitig beendet. Am Ende
der "Startup"-Phase leuchtet die Status-LED dauernd. Ist die
Akkuspannung beim Einschalten der Netzversorgung zu gering, wird der
Start verzögert, bis der Akku so weit geladen ist, daß die
Ladung des Aukkus ausreicht, um das System bei einem Netzausfall wieder
herunterfahren zu können.
Um zwar die Netzversorgung einzuschalten, jedoch ein Starten des Systems zu verhindern, kann die Taste gedrückt, während des Einschaltens der Netzversorgung gehalten, und danach wieder losgelassen werden. Dieser Modus kann z.B. zum Laden des Akkus verwendet werden, ohne daß dabei der RasPi läuft und Strom verbraucht. |
—
|
Betätigung des Tasters (1-2s): Auch in diesem Fall wird die
"Startup"-Phase eingeleitet und der RasPi mit Spannung versorgt,
jedoch läuft das System mit Hilfe der 12V-(Akku)-Versorgung, was am Ende
der "Startup"-Phase durch ein gleichmäßiges Blinken
der Status-LED angezeigt wird. Ist die Akkuspannung zu gering, wird ein
Start verhindert.
|
—
|
Einschaltbefehl vom "Eindraht-Kommunikationsbus": Auf diese Weise
kann das Starten des Systems durch einen anderen Microcontroller (z.B. mit
Fernbedienungsempfänger oder Bewegungsmelder) ausgelöst werden.
|
—
|
Timer: Sowohl über den I2C-Bus (RasPi),
als auch den "Eindraht-Kommunikationsbus" kann ein (Sleep-)Timer
(1-65535 Minuten) gesetzt werden, der nach dem Abschalten des Systems aktiv
wird, und nach Ablauf der vorgegebenen Zeit das System wieder startet.
|
Auch das Ausschalten des Systems kann auf verschiedene Weisen ausgelöst
werden:
|
—
|
Abschaltung der Netzversorgung: Der Wegfall der 5V aus dem Schaltnetzteil
wird vom Controller detektiert, und führt nach ein paar Sekunden (damit
ein kurzzeitiges "Wackeln" der Netzspannung keine Abschaltung
auslöst) zur Einleitung der "Shutdown"-Phase, die etwa eine
Minute dauert, und durch ein Blinken (lang an, kurz aus) der Status-LED
signalisiert wird. Nach Ablauf der Zeit wird die Stromversorgung des RasPi
abgeschaltet, und die Status-LED verlischt.
|
—
|
Betätigung des Tasters (1-2s): Auch in diesem Fall wird die
"Shutdown"-Phase eingeleitet.
|
—
|
Absinken der Akkuspannung: Verringert sich die Akkuspannung unter einen
Wert, der eine genügende Ladung für ein sicheren Akku-Betrieb
signalisiert, wird automatisch die "Shutdown"-Phase eingeleitet.
|
—
|
Kommunikations-Timeout: Findet für etwa eine Minute keine Kommunikation
mit dem RasPi über den I2C-Bus statt, wird davon ausgegangen,
daß das RasPi-System "hängengeblieben" ist, und die
"Shutdown"-Phase wird eingeleitet. In Kombination mit dem
"Sleep"-Timer lässt sich mit dieser Funktion eine Art
"Watchdog" realisieren, der bei einem "Hängen" des
Systems einen Neustart auslöst.
Diese Funktionalität kann durch Betätigung des Tasters (1-2s) während der "Startup"-Phase abgeschaltet werden, um z.B. Modifikationen an den Programmen/Skripten vornehmen zu können, die für die I2C-Kommunikation auf dem RasPi notwendig sind. |
—
|
Abschaltbefehl vom "Eindraht-Kommunikationsbus": Auf diese Weise
kann das Herunterfahren des Systems durch einen anderen Microcontroller
ausgelöst werden.
|
—
|
Abschaltbefehl über den I2C-Bus (vom RasPi): Auch vom RasPi
kann das Herunterfahren des Systems ausgelöst werden.
|
Die Software auf dem RasPi
Die Kommunikation zwischen Controller und RasPi erfolgt über den
I2C-Bus des RasPi, dessen Signale (GPIO2/SDA1 und GPIO3/SCL1) auf
dem 40poligen Stecker zugänglich sind. Wenn der I2C-Bus im
"raspi-config" aktiviert wurde, können Programme mit Hilfe des
Devices "/dev/i2c-1" auf diesen Bus zugreifen und darüber
Daten senden und empfangen. Damit es keine Zugriffskonflikte auf dieses Device
gibt, wenn verschiedene Programme mit dem Controller kommunizieren
möchten, habe ich mich entschlossen, ein
Daemon-Programm
zu verwenden, welches die direkte Kommunikation mit dem Controller
übernimmt. Dieses Programm kann von anderen Programmen über einen
UNIX Domain Socket
angesprochen werden, um Befehle an den Controller zu senden oder Informationen
vom Controller abzufragen. Während das Programm läuft, wird
regelmäßig der Status des Controllers abgefragt, um u.a.
festzustellen, ob dieser die "Shutdown"-Phase gestartet hat, und das
System heruntergefahren werden soll. Dieser Umstand wird durch die Beendigung
des Daemons mit einem speziellen Exitcode (2) signalisiert, der von einem
entsprechenden Shellscript detektiert werden kann, welches dann das
Herunterfahren des Systems anstoßen kann. Durch die ständige
Statusabfrage stellt dieses Programm auch sicher, daß eine
regelmäßige Kommunikation mit dem Controller stattfindet, und
kein Kommunikations-Timeout auftritt. Wie aus der
Befehlszeile ersichtlich, kann der Daemon optional auch noch einige weitere
Funktionen übernehmen:
|
raspipwrd [-t] [-f] [-w] [-l <logfile>] -d <device>
|
-d <device>
|
Hiermit wird das Device angegeben, über das die
I2C-Kommunikation erfolgen soll. In diesem Falle also
"-d /dev/i2c-1". Dieser Parameter muss in jedem Fall angegeben werden.
|
-f
|
Mit dieser optionalen Angabe wird das Programm angewiesen, die CPU-Temperatur
des RasPi auszulesen, und bei Bedarf (>50°C) den Lüfter zu
beschleunigen.
|
-l <logfile>
|
Diese optionale Angabe bewirkt, daß jegliche Aktion in der mit
"logfile" angegebenen Datei (z.B.
"/var/log/local/pwrstat.log") protokolliert wird.
|
-t
|
Mit dieser Option wird das Programm angewiesen, beim Start des Programms
die Echtzeituhr aus dem Controller zu lesen. Erscheint der gelesene Wert
plausibel (<30 Tage später als die aktuellen Systemzeit)
wird die Systemzeit entsprechend gesetzt. Das Setzen der Systemzeit ist
jedoch nur möglich, wenn das Daemon-Programm mit entsprechenden
Rechten (→ als "root") gestartet wird. Beim Beenden des
Programms wird auf jeden Fall die aktuelle Systemzeit in den Controller
geschrieben.
|
-w
|
Diese Option bewirkt, daß beim Programmstart der
Sleep-Timer des Controllers auf zwei Minuten gesetzt wird,
und die Befehle des RasPi zur Änderung diese Timers nicht direkt an den
Controller weitergeleitet werden. Stattdessen werden die neuen Werte in einer
Variablen gespeichert, die erst bei der Beendigung des Programms an den
Controller übertragen wird. Dieses Verfahren bewirkt, daß
bei einem "Hängen" des Systems ein
Kommunikations-Timeout auftritt, der Controller die
"Shutdown"-Phase startet, das System abschaltet, und nach zwei
Minuten erneut startet.
|
Um auch als "Benutzer" (oder entsprechendes Shellscript) mit dem
Controller kommunizieren zu können, existiert ein zweites Programm,
welches entsprechende Anfragen an den (ständig laufenden) Daemon stellt,
und dessen Daten ausgibt. Die möglichen Befehlszeile dieses
(Client-)Programms sind:
|
raspipwr_cli -s
|
Mit diesem Befehl werden die aktuellen Statusbits des Controllers angefragt.
Die Antwort besteht aus fünf Ziffern, die "0" oder
"1" sein können, durch Kommata getrennt sind, und die
Zustände von "Netzversorgung", "Akkuversorgung",
"Zu geringe Akkuspannung", "Shutdown-Phase aktiviert",
und "Von Timer gestartet worden" anzeigen. Eine Ausgabe von z.B.
"1,1,0,0,0" bedeutet, daß die Stromversorgung sowohl vom
Netzteil, als auch vom Akku möglich ist, die Akkuspannung genügend
hoch ist, kein "Shutdown" eingeleitet wurde, und das System nicht
vom Timer gestartet wurde. Diese Art der Darstellung ist zwar für einen
Benutzer etwas schwer zu interpretieren, aber recht gut geeignet, um von einem
Shellscript verarbeitet zu werden.
|
raspipwr_cli -v
|
Dieser Befehl fragt einige Messwerte des Controllers ab.
Die Antwort besteht aus vier Werten, die durch Kommata getrennt sind, und die
Messwerte von von "Spannung vom Netzteil", "Spannung des
Akkus", "Betriebsspannung des Contollers", und "Temperatur
im Gehäuse" anzeigen. Eine "normale" Ausgabe wäre
z.B. "5.5,13.7,5.4,22.6".
|
raspipwr_cli -o
|
Dieser Befehl dient zur Einleitung der "Shutdown"-Phase. Da dieser
Befehl keine Werte liefert, besteht die Antwort nur aus "Done" oder
einer Fehlermelung. Kurz nach der erfolgreichen Ausführung sollte der
Deamon-Prozess den neuen Zustand des Controllers detektieren, und sich mit dem
Exit-Code "2" beenden. Das Skript, welches den Daemon gestartet hat,
erkennt diesen Umstand, und leitet das Herunterfahren des Systems ein.
|
raspipwr_cli -w <val>
|
Hiermit wird der "Sleep"-Timer des Controllers auf dem Wert
"val" (0 bis 65535) gesetzt. Das ist die Zeit in Minuten, nach der
der Controller nach dem Shutdown das System wieder aktiviert. Ein Wert von
"0" schaltet den Timer ab. Da auch dieser Befehl keinen Wert ausgibt,
besteht die Antwort nur aus "Done" oder einer Fehlermelung.
|
raspipwr_cli -f <val>
|
Dieser Aufruf setzt die Geschwindigkeit des Lüfters auf dem Wert
"val" (0 bis 255). Damit kann z.B. bei steigender CPU-Temperatur
der Luftstrom zu besseren Kühlung erhöht werden. Da der Controller
schon eine Drehzahl aus der Gehäusetemperatur selber berechnet, kann die
Drehzahl mit diesem Befehl nur erhöht und nicht verringert werden. Die
Reduktion der Drehzahl erfolgt langsam und automatisch, bis auf den vom
Controller berechneten Wert. Daher ist es ratsam, diesen Befehl alle paar
Minuten (bei Bedarf) zu wiederholen.
|
raspipwr_cli -b <channel>
|
Hiermit wird eine (zeitbegrenzte) Aufzeichnung und Ausgabe der Daten auf dem
"Eindraht-Kommunikationsbus" angefordert. Damit die Daten von
ggf. mehreren anfragenden Programmen/Skripten nicht durcheinanderkommen und
eindeutig zugeordnet werden können, ist die Angabe einer Kanalnummer
("channel") notwendig. Diese Kanalnummer wird beim ersten Aufruf
mit der Kanalnummer "0" neu vergeben, und ist Bestandteil der
Antwort. Bei weiteren Aufrufen (zur Abfrage der gepufferten Daten) ist dann
die in der letzten Antwort angegebene Kanalnummer zu verwenden. Die Antwort
auf diesen Befehl besteht aus der Kanalnummer, der Anzahl der folgenden
Datenbytes, und ggf. den hexadezimalen Datenbytes. Eine Antwort auf den
ersten Aufruf (mit der Kanalnummer 0) könnte z.B. lauten
" 4, 0" was bedeutet, daß beim nächsten Aufruf die
Kanalnummer 4 zu verwenden ist, und daß derzeitig keine Daten vorliegen.
Die Antwort auf den nächsten Aufruf (diesmal mit der Kanalnummer 4)
könnte z.B. lauten " 4, 2,3A,C5", was bedeutet, daß
für den Kanal 4 zwei Bytes, nämlich "3A" und "C5"
aufgezeichnet wurden. Da nicht beliebig viele Datenbytes in dem Antwortstring
enthalten sein können, ist es ratsam, nach einem Aufruf, der Datenbytes
enthielt, den Aufruf zu wiederholen, bis keine Daten mehr in der Antwort
enthalten sind. Damit nicht Unmengen von Daten gepuffert werden müssen,
ist diese Funktionalität zeitlich begrenzt: Werden eine Minute lang
keine Anfragen für einen Kanal gestellt, wird der entsprechende Kanal
gelöscht, und weitere Aufrufe für diesen Kanal mit einer
Fehlermeldung beantwortet.
|
raspipwr_cli -d <data>
|
Dieser Befehl dient dazu, Daten auf dem "Eindraht-Kommunikationsbus"
zu senden. Damit können Daten z.B. zu einem anderen Microcontroller
gesendet werden, der ebenfalls am dem Bus angeschlossen ist. "data"
sind dabei 2 bis 7 zu sendende Datenbytes, die als Hexadezimalwerte (also
4-14 Zeichen) anzugeben sind.
|
Das Material
Das hier angebotene Material unterliegt der Creative Commons Lizenz
"CC BY-NC-SA".
|
In diesem Archiv befinden sich die Dateien der beiden
KiCad-Projekte
"raspipwr" (Controller mit Spannungs- und Pegelwandlern) und
"raspicon" (kleine Zusatzplatinen für die
Außenanschlüsse).
|
|
Diese Datei enthält die
Blender-Datei, mit der
ich den Aufbau simuliert habe. Die verschiedenen Bestandteile (Platinen,
Leitungen, etc.) befinden sich in verschiedenen Layern, was ein
Ein- und Ausblenden einzelner Gruppen erleichtert.
|
|
In dieser Datei befindet sich das Hexfile, welches zur Programmierung des
Microcontrollers auf dem Steuerungsboard notwendig ist.
|
|
In diesem Archiv befindet sich der Quellcode, um die Firmware (→Hexfile)
für den Controller herzustellen. Diese Dateien werden nur benötigt,
wenn Änderungen an der Firmware des Controllers vorgenommen werden
sollen. Zur Herstellung eines neuen Hexfiles ist die Installation des Pakets
"gputils" z.B. aus dem "Raspbian"-Repository (oder von
gputils.sourceforge.net
) notwendig.
|
|
Diese Archiv enthält den Quellcode der Programme, die auf dem RasPi laufen.
Der Shell-Befehl "make" in dem (ggf. temporären) Verzeichnis, in dem
dieses Archiv entpackt wurde, bewirkt die Erzeugung der Programme
raspipwrd und raspipwr_cli.
Diese beiden Programme sollten zusammen mit dem Shellscript
pwr_ctrl.sh nach
"/usr/local/bin/" kopiert werden, um im System implementiert zu
werden. Das Shellscript dient dazu, "raspipwrd" mit entsprechenden
Befehlszeilen-Parametern zu starten, und das System bei Bedarf
herunterzufahren. Damit dieses Script bei jedem Systemstart ausgeführt
wird, sollte die Zeile "/usr/local/bin/pwr_ctrl.sh &"
in "/etc/rc.local" eingetragen werden (Das "&" am Ende
der Zeile nicht vergessen!). In "pwr_ctrl.sh" ist das Verzeichnis
"/var/log/local/" für die Logdatei der Programme vorgesehen.
Da dieses Verzeichnis nicht bei allen Systemen vorhanden ist, sollte es
ggf. neu angelegt (oder das Script entsprechend geändert) werden.
Damit die Logdatei im Laufe der Zeit nicht übermäßig groß
wird, ist eine entsprechende Eintragung im "logrotate"
empfehlenswert.
|
Hinweise für Nachbauwillige
Wer diese Konstruktion nachbauen möchte, sollte über etwas Kenntnisse
der Herstellung einseitiger Leiterplatten, der Programmierung von
Mikrocontrollern, und etwas handwerkliches Geschick verfügen.
Es handelt sich hierbei nicht um einen Bausatz, sondern eher um eine
Anregung für eigene Konstruktionen. Alles, was ich dazu anbieten kann,
befindet sich auf dieser Seite, d.h. Nachfragen nach fertigen Geräte
oder Bausätzen sind zwecklos → Ich "produziere"
ausschliesslich für den Eigenbedarf.
|
Für die Funktionalität und Nachbausicherheit dieser Konstruktion kann ich keinerlei Verantwortung übernehmen. Ich verkaufe weder fertige aufgebaute Schaltungen, noch komplette Geräte oder Bausätze. Eine kommerzielle Verwertung des hier angebotenen Materials (Schaltpläne, Layouts, 3D-Modelle, Quell- und Hexcodes) oder auch Teilen davon ist nur mit meiner ausdrücklichen Genehmigung zulässig.
Startseite Hardware Rechtliches Kontakt