Hallo Gemeinde,
ich bastle gerade an einer Steuerung und möchte Euch an den Ergebnissen gerne teilhaben lassen.
Das Ganze soll ein Steuer-/Regelwerk werden, bei dem spezielle Funktionen von Arduino Pro Mini Controllern autonom übernommen werden, die dann aber ihre Werte mit einer Super-Controller-Software, die auf einem RPi läuft, austauschen und von diesem Anweisungen entgegen nehmen.
Einen Link zur Idee, dem Konzept des Gesamt-Vorhabens und dem Source-Code für den Raspberry Pi findet ihr demnächst -> hier <- unter der Rubrik "Programmierung -> andere Programmiersprachen" in meiner Übersicht unter "Multithreaded 'Super-Controller' für den Raspberry Pi".
Dort lege ich auch den zugehörigen Source-Code für den Raspberry Pi ab und halte ihn dort auch auf dem aktuellsten Stand.
Beim hier angehängten Sketch handelt es sich um einen autonom arbeitendes Subsystem mit zwei Ultraschall-Sensoren. Die Software ist ebenfalls ein aktueller Arbeitsstand. Es kann also sein, dass noch irgendwelche Fehler drin sind ... die Software läuft aber augenscheinlich recht sauber.
Diesen Sketch werde ich ebenfalls immer wieder einmal aktualisieren ... behaltet also die History im Auge.
Aufbau der Schaltung:
Ich habe mir aus einer Loch-/Streifenraster-Platine ein kleines Board gebastelt und alle benötigten Komponenten darauf platziert (ein Foto sowie den Schaltplan findet ihr ebenfalls im Anhang).
Kerstück ist natürlich ein Arduino Pro Min, der zwei Ultraschall-Sensoren steuert. Desweiteren sind auf dem Board zweimal vier Leuchtdioden angebracht, die den aktuellen Status optisch signalisieren. Sie sind jeweils direkt über einen passenden Vorwiderstanden mit den zugehörigen Pins des Arduino verbunden (D4 bis D7 bzw. D12 bis A1).
Die LEDs haben die Farben blau (Richtung des "ping" - vorne oder hinten), rot (kritische Distanz), gelb (Distanz nähert sich dem kritischen Bereich) und grün (kein Objekt in "Sicht").
Die anderen benötigten Anschluss-Pins des Arduino sind über Pfosten-Anschlüsse verfügbar.
Das Board hat zusätzlich Anschlüsse für +5V und GND, die zur Spannungsversorgung der Ultraschall-Sensoren dienen. Die Trigger- und Echo-Anschlüsse der Sensoren gehen auf die entsprechenden Ein- bzw. Ausgangspins des Pro Mini (D8 und D9 bzw. D10 und D11).
Die Pins A4 und A5 des Arduino sind über einen Pegelwandler mit dem IIC-Bus verbunden, an dem der Raspberry Pi als Master angeschlossen ist.
Pin D2 des Arduino geht, ebenfalls über den Pegelwandler, auf einen GPIO des Raspberry Pi. Diese Verbindung dient als "Interrupt"-Leitung ... sie wird kurzzeitig auf HIGH gesetzt wenn ein kritisches Ereignis eintritt und signalisiert dieses dadurch dem Raspberry Pi, der dann wiederum umgehend darauf reagieren kann.
Funktion:
Ich habe auf Konstanten zur Initialisierung weitgehend verzichtet. Alle relevanten Werte werden in Variablen gehalten. Das hat den Vorteil, dass ein Feintuning bzw. eine individuelle Anpassung des Sketches möglich ist. Um die einmal eingestellten Werte zu erhalten werden diese im EEPROM gespeichert und bei jedem Start des Sketches aus diesem ausgelesen.
Nach dem Initialisieren der Variablen wird eine Verbindung mit dem IIC Bus aufgebaut. Der Subcontroller meldet sich dabei mit einer festen Adresse am Bus als Teilnehmer an (i2cSlaveAddr) und ist unter dieser vom RPi aus erreichbar. Für den Empfang und die Verarbeitung von Steuerbefehlen werden noch zwei Funktionen, eine für den receive- und eine für den request-Event der IIC Schnittstelle registriert.
Es folgt noch die Initialisierung der benötigten I/O Pins. Damit wäre die Setup-Phase schon beendet.
Die Main-Loop ist ziemlich unspektakulär:
Dort wird lediglich auf ein evtl. User-Kommando geprüft (siehe weiter unten) und, falls die Anwendung nicht pausiert wurde (ebenfalls weiter unten) eine Messung in die aktuelle Richtung (pingDirection) durchgeführt und das Ergebnis überprüft. Ist ein Objekt innerhalb der kritischen Distanz, wird der Status auf "rot" gesetzt. Ist die Distanz zwar unkritisch aber innerhalb eines gefährlichen Bereichs wird der Status auf "gelb" und ist kein Objekt innerhalb einer bestimmten Distanz auf "grün" gesetzt.
Im Falle einer kritischen Situation wird zudem der Master-Controller (Raspberry Pi) per Interrupt Leitung benachrichtigt.
Nach einer einstellbaren Wartezeit (pingInterval) wird der Durchgang wiederholt.
Die Hauptarbeit wird in der callback-Routine i2cRequest() erledigt.
Ich habe mir ein einfaches Protokoll ausgedacht um vom RPi aus mit diesem (und später auch anderen) Subcontroller-Boards über IIC zu kommunizieren.
Dabei werden Befehle an den Arduino übermittelt, der diese dann auswertet, ausführt und einen Status an den Master (RPi) zurückschickt.
Um das Ganze möglichst flexibel zu halten habe ich derzeit knapp 30 Befehls-Sequenzen festgelegt.
Für die reine Steuerungsebene würden ein paar wenige zwar ausreichen, da ich aber plane mit PHP-Seiten eine grafische Oberfläche für die Steuerung zu realisieren, habe ich mir gedacht, dass ein paar mehr Kommandos nicht schaden können ...
Eine Kommando-Sequenz besteht aus einem Prozent-Zeichen, einem Buchstaben für das Kommando und, falls ein Parameter erforderlich ist, einem weiteren Prozent-Zeichen gefolgt vom Parameter-Wert.
Folgende [an=protocol]Befehls-Sequenzen[/an] werden derzeit vom Arduino erkannt und ausgewertet:
Spoiler anzeigen
%d gibt die aktuelle ping-Richtung zurück
%D gibt die Entfernung zum nächsten Objekt in cm zurück
%C gibt den aktuellen Status (rot, gelb, grün) zurück
%A setzt den Grenzwert für "kritische Distanz"
%W setzt den Grenzwert für "fast kritische Distanz"
%G setzt den Grenzwert für "unproblematische Distanz"
%a gibt den aktuellen Grenzwert für "kritische Distanz" zurück
%w gibt den aktuellen Grenzwert für "fast kritische Distanz" zurück
%g gibt den aktuellen Grenzwert für "unproblematische Distanz" zurück
%f setzt die Richtung des "ping" nach vorn
%b setzt die Richtung des "ping" nach hinten
%i setzt das Intervall in dem die "pings" gesendet werden
%I gibt das aktuelle Intervall in dem die "pings" gesendet werden zurück
%r setzt die Richtung des "ping" nach rechts (wird ignoriert)
%l setzt die Richtung des "ping" nach links (wird ignoriert)
%u übermittelt ein User-Kommando
%s stoppt den Subcontroller (wird ignoriert)
%p pausiert den Subcontroller
%c setzt die Verarbeitung im Subcontroller nach einer Pause bzw. einem Stopp fort
%x beendet den Sbcontroller
%S speichert die aktuellen Einstellungen im EEPROM
%V gibt Log-Datensätze auf die serielle Schnittstelle aus (wird ignoriert)
%H setzt die Ping-Richtung per Parameter (wird noch ignoriert)
%P setzt den aktuellen Abstand zum nächsten Objekt (wird noch ignoriert -> Debug Modus)
%Z setzt den aktuellen Ping-Status (wird noch ignoriert -> Debug Modus)
%T schaltet den Debug Modus ein bzw. aus (wird noch ignoriert)
%R setzt alle Einstellungen auf ihre Default-Werte zurück (factory settings)
%n gibt die Anzahl der Alarmzustände zurück, ab denen der Master per Interrupt informiert wird
%N setzt die Anzahl der Alarmzustände, ab denen der Master per Interrupt informiert wird
Alles anzeigen
Die Antwort auf ein solches Kommando ist das Kommando-Token (also der Buchstabe) gefolgt von einem Statusbyte und einem optionalen Parameter. Die einzelnen Werte werden wiederum durch ein führendes Prozent-Zeichen gekennzeichnet.
Viel näher möchte ich an dieser Stelle noch gar nicht auf die Einzelheiten der Kommunikations-Schnittstelle eingehen, weil es durchaus möglich ist, dass sich hier im Laufe der Weiterentwicklung noch einiges ändert.
Ich habe noch ein weiteres Ultraschall-Modul in Arbeit, das mit vier Sensoren aber dafür nur vier Status-LEDs ausgestattet ist. Deshalb werden einige Kommandos nicht oder noch nicht verwendet.
Ausserdem kommen im Laufe der nächsten Tage und Wochen noch weitere, bereits geplante SubController hinzu.
Die Kommando-Schnittstelle ist u.a. auch deshalb so umfangreich, weil noch eine API für eine grafische (PHP-/wxWidgets-) Oberfläche als auch eine Telnet-Schnittstelle gepant sind.
Dazu aber Näheres im anderen Subforum ( -> hier <- in der Übersicht unter "Multithreaded 'Super-Controller' für den Raspberry Pi" ).
Ich hoffe, ich habe jetzt nichts wichtiges vergessen und konnte die eine oder andere brauchbare Anregung vermitteln.
Viele Grüsse aus ... nein, nicht dem Morgenland ... sondern dem Bayernland,
-ds-
History:
Urversion: 27.09.2014