© Ozz Design/Shutterstock.com
PHPoC: Eine IoT-Lösung für PHP-Entwickler – Teil 2

Das PHP der Dinge: Peripheriegeräte


PHPoC (PHP on Chip) ist der Name einer IoT-Hardwareplattform für PHP-Entwickler aus dem Hause Sollae Systems. Wir unterziehen die Lösung einem Praxischeck und betrachten in Teil 2 der Serie die Möglichkeiten zur hardwarebeschleunigten Interaktion mit Peripheriegeräten. Da diese im Hintergrund auf einem klassischen STM32-Controller basieren, dürfen wir hohe Qualität erwarten. Zeit, dem Tier auf die Zähne zu blicken.

Egal, wie durchdacht die PHPoC-Plattform auch sein mag, es gilt trotzdem, dass Echtzeit-Aufgaben auf einem kleinen Achtbitter besser aufgehoben sind. PHPoC spielt seine Stärken immer dann aus, wenn es um „reichhaltige“ Interaktionsmöglichkeiten geht. In diesem Artikel wollen wir die im ersten Teil der Serie durchgeführten Experimente zum Anlass nehmen, um uns tiefer mit dem PHPoC API auseinanderzusetzen.

Ansteuerung von Motoren

Wer sich lang genug im elektronischen Bereich bewegt, bekommt irgendwann einen Gleichstrommotor in die Hände. Das im Allgemeinen anspruchslose Teil hat die Eigenschaft, seine Drehgeschwindigkeit mehr oder weniger direkt mit der angelegten Gleichspannung zu verändern. Ein weiterer Vorteil des Motors, der ihn für didaktische Übungen besonders gut geeignet erscheinen lässt, ist seine Trägheit. Der Rotor weist nämlich ein nicht unerhebliches Gewicht auf, weshalb man ihn über das Prinzip der Pulsbreitenmodulation (PWM) ansteuern kann. Dieses verbreitete Verfahren basiert darauf, dass man eine Arbeitsfrequenz für eine gewisse Zeit ein- und danach ausschaltet. Sind die einzelnen Zyklen schnell genug, sieht eine träge Last eine kontinuierlich veränderliche Ansteuerung.

Im Interesse der Quereinsteiger wollen wir hier nochmals anmerken, dass wir zur Programmierung des Boards im ersten Schritt die nur unter Windows lauffähige IDE des Systems öffnen. Sofern Sie noch auf dem Stand unseres letzten Experiments sind, findet sich dort eine Datei namens Init.php, die die eigentliche Arbeitsdatei aufruft. In ihr platzieren wir folgenden Header:

<?php if(_SERVER("REQUEST_METHOD")) exit; // avoid php execution via http request include_once "/lib/sd_340.php";

Die Selektion hat dabei die Aufgabe, den Benutzer am direkten Aktivieren dieser Payload über einen URL-Aufruf zu hindern. Die auf dem PHPoC implementierte PHP Runtime nimmt nämlich auch HTTP Requests entgegen und führt die von ihnen angeforderten Ressourcen aus. Die Inklusion der Datei via include_once "/lib/sd_340.php" sorgt dann dafür, dass die diversen Hardwarezugriffsbibliotheken ansprechbar sind. Im nächsten Schritt können wir uns auch schon darum kümmern, die eigentliche Ausgabe der PWM-Wellenform zu avisieren:

 st_pwm_setup(0, 5, 100, 200); st_pwm_setup(1, 9, 10, 100, "us"); ?>

Das Retournieren der Kontrolle an den Interpreter nach dem letzten Aufruf der Methode st_pwm_setup ist dabei übrigens kein Problem. Sind die Werte erst einmal in die PWM Engine des Prozessors geschrieben, erledigt dieser seine Arbeit selbsttätig und ohne weiteres Zutun unserer Software. Das ist auch eine der Ursachen, weshalb hardwarebeschleunigte Busse und PWM Engines auch auf Softwaresystemen mit hoher, durch Garbage Collector und Co. verursachter Latenz problemlos funktionieren.

Wie bei fast allen PWM Engines ist das primäre Problem auch hier die Parametrisierung – in der API-Referenz ist die zur Einrichtung vorgesehene Methode folgendermaßen beschrieben:

void st_pwm_setup(int $st_id, int $pin, int $width, int $period [, string $div = "ms"])

Der erste Parameter legt dabei die logische ID der Zeitgebereinheit fest. Wir verwenden hier einfach die Timer 0 und 1. Über den Pinparameter legen wir den Ausgangswert fest. Interessant sind die Werte period und width: Der erste legt die Länge des gesamten PWM-Pulses fest, während der zweite bestimmt, wie viel davon im High-Zustand verbracht werden soll. Der erste Aufruf mit den Parametern 200 und 100 würde also eine On-Zeit von 50 Prozent ergeben, während der zweite mit den Parametern 110 nur noch 10 Prozent der Zeit im aktiven Zustand verbringt. Zu guter Letzt dürfen wir noch eine Konstante übergeben, die die Länge der beiden Zeiteinheiten festlegt.

Wir übergeben hier für einen der beiden Aufrufe us, während der zweite den Defaultwert eingeschrieben bekommt. Auf dem Oszilloskop lässt sich die Korrektheit der Annahmen wie in Abbildung 1 gezeigt verifizieren: Trace 1 ist mit Pin 5 verbunden, Trace 2 mit Pin 9. Die darunter eingeblendete Mathematik-Trace ist dann eine Expansion des am Trace 2 anliegenden Signals. Ob der eingeschränkten Speichertiefe kommt es hier zu etwas Aliasing. In der Praxis würde es sich anbieten, das zweite Signal mit einer separaten Zeitbasis anzusehen.

hanna_phpoc_1.tif_fmt1.jpgAbb. 1: Dank Oszilloskop sieht man klarer

Motor fernsteuern

In der Theorie könnten wir uns an dieser Stelle an das Realisieren einer Transistorschaltung machen, um den Impeller von PHPoC aus zu steuern. Schöner wäre es allerdings, wenn der Benutzer Geschwindigkeitswerte über einen Webbrowser eingeben könnte. Wie im letzten Heft festgestellt, stehen auf der PHPoC-Plattform je nach verwendetem Board unterschiedliche Wege zum Aufbau einer Netzwerkverbindung zur Verfügung. Wir arbeiten in den folgenden Schritten mit einem PHPoC Blue, das ein USB-Dongle aufnehmen kann. Falls Sie den Prozessrechner ohne Dongle gestartet haben, sollten Sie ihn von der Energieversorgung trennen, den USB-Stick anstecken und ihn wie im ersten Teil besprochen als Accesspoint konfigurieren.

Im Interesse der Bequemlichkeit nutzen wir die PHPoC IDE im nächsten Schritt zum Anlegen einer neuen Datei namens index.php. Ganz analog zum großen Server gilt auch am Prozessrechner, dass ein direkter Aufruf der IP-Adresse dieses File aktiviert. Als Nächstes platzieren wir dort die folgende Sequenz, die anfangs eine Gruppe von Hyperlinks emittiert (Listing 1). Auffällig ist hier vor allem die Verwendung des Werts ?led0, der sich von Link zu Link ändert und der später die Drehgeschwindigkeit des Impellers festlegen soll.

Listing 1

<html> <head> <title>PHPoC Systemname <?echo system("uname -i")?></title> </head> <body> <h2>Impellersteuerung</h2> <?php echo "<br><a href='index.php?led0=0'>0%</a><br>"; echo "<br><a href='index.php?led0=25'>25%</a><br>"; echo "<br><a href='index.php?led0=50'>50%</a><br>"; echo "<br><a href='index.php?led0=75'>75%</a><br>"; echo "<br><a href='index.php?led0=100'>100%</a><br>"; ?> <?php ?> </body> </html>

Der im Snippet weiter oben noch leer abgedruckte PHP-Block nimmt danach den in Listing 2 gezeigten Code auf.

Listing 2

 <?php include_once "/lib/sd_340.php"; $led0 = _GET("led0"); st_pwm_setup(0, 5, (int) $led0, 100); ?> </body> </html>

In PHPoC wurde die vom „großen“ PHP bekannte Variablenhandhabung implementiert. Wir können URL-Parameter also wie gewohnt durch _GET abernten und die Ergebnisse danach in Richtung der Funktion st_pwm_setup weiterschreiben. Interessant ist in diesem Zusammenhang noch die Art der Wertkonversion. Sollae Systems implementiert nur einen kleinen Teil der in PHP enthaltenen Komfortfunktionen. Aus diesem Grund muss die Umwandlung in einen numerischen Wert über einen harten Cast erfolgen.

An dieser Stelle bietet sich ein erster Testlauf mit dem Oszilloskop an – wir stellen fest, dass die Ein- und Ausschaltzeiten vergleichsweise lang sind. Das ist insofern unvorteilhaft, als der Benutzer bei einer Lichtquelle ein Flackern wahrnehmen würde, während sich ein Motor bei zu langsamerer Ansteuerung durch ruckartige Fahrt bemerkbar zeigt. Zur Lösung des Problems reicht es aus, nach folgendem Schema eine Beschleunigung zu befehlen. Abbildung 2 zeigt die neue Wellenform:

st_pwm_setup(0, 5, (int) $led0 * 10, 1000, "us"); ?>
hanna_phpoc_2.tif_fmt1.jpgAbb. 2: Eine Zykluszeit von 1000 Hz ist für motorische Lasten gut geeignet

Die Auswahl der korrekten Arbeitsfrequenz ist dabei eine Wissenschaft für sich. Achten Sie darauf, dass jeder Schaltvorgang Energie verbraucht, und dass insbesondere Leistungstransistoren nicht wirklich schnell arbeiten können. Andererseits gilt es aber auch, Fiepen und Flackern zu vermeiden.

UART-Kommunikation

Außer Frage steht, dass es zum Motor und seiner Steuerung noch viel zu erzählen gäbe – ein direktes Anschließen an den PHPoC ist ja nicht möglich, weshalb wir einen Darlington-Transistor oder einen anderen Stromverstärker benötigen. Wie wollen uns an dieser Stelle allerdings nicht allzu sehr mit Elektronik auseinandersetzen, sondern uns stattdessen ein weiteres Hardwareinterface ansehen.

Serielle Schnittstellen – man denke beispielsweise an das mittlerweile nur noch wenig verwendete RS232 – waren einst groß in Mode, wurden mittlerweile aber im Computerbereich durch USB abgelöst. Im Bereich Hardware und Internet of Things ist das nicht der Fall. Als UART, kurz für Universal Asynchronous Receiver/Transmitter, bezeichnete Leseempfänger kommen auch heute noch in vielen Hardwaregeräten zum Einsatz. Im Prinzip ist eine UART-Verbindung dabei nach dem in Abbildung 3 gezeigten und aus der Android-Things-Dokumentation entnommenen Schema aufgebaut.

hanna_phpoc_3.tif_fmt1.jpgAbb. 3: UART-Schema: Daten wandern in Reih und Glied [1]

Vorteil der Nutzung der Hardware-Engine ist, dass sich unser Programm nicht um das permanente Beobachten der Leitungszustände kümmern muss. Stattdessen bekommen wir ein an printf erinnerndes API, über das wir die eingehenden Informationen einlesen und – sofern von der Gegenstelle unterstützt – auch Informationen in ihre Richtung senden können.

Die Verwendung dieser auf den ersten Blick antiquierten Schnittstelle ist übrigens ein durchaus bequemer Weg, um kombinatorische Prozessrechner zu realisieren. Die meisten 8-Bit-Mikrocontroller haben nämlich ebenfalls einen Hardware-UART, der das Entgegennehmen der Informationen erledigt.

Als praktisches Demonstrationsbeispiel wollen wir diesmal das unter der Seriennummer 113020002 beispielsweise bei Mouser erhältliche RFID-Lesemodul verwenden. Das von Seeed eigentlich im Rahmen des Grove-Ökosystems angebotene Produkt weist einen UART-Transmitter auf, über den es die angetroffenen 125-kHz-RFID-Karteninformationen ausliest. 125-kHz-RFID-Karten sind normalerweise scheckkartengroße Elemente, die sehr preiswert sind. Zudem ist im Zusammenhang mit der von Seeed angebotenen Spule die Reichweite sehr gering (weniger als 3 cm), was Fehllesungen stark einschränkt.

Nur Lesen!

Beachten Sie, dass das hier verwendete Interface Karten nicht beschreiben kann – eine nicht beschriebene Karte kann es nicht erkennen. Die meisten Verkäufer bieten allerdings (gegen einen kleinen Aufpreis) an, Dummyinformationen auf die Kartenrohlinge zu brennen.

Das Grove-Modulsystem ist auf die Arbeit mit 5-V-Signalen ausgelegt: Der im PHPoC verbaute STM32-Mikrocontroller ist allerdings ein reines 3,3-V-Gerät. Zur Lösung dieses Problems bietet sich die in Abbildung 4 gezeigte Schaltung an, die eine Pegelkonversion vornimmt.

hanna_phpoc_4.tif_fmt1.jpgAbb. 4: So findet der 113020002-Anschluss an den PHPOC

Sollae erleichtert uns die Arbeit hier insofern, als der PHPoC die als Eingangsversorgung angebundene 5-V-Spannungsquelle über einen Pin an seinem Header exponiert. Beachten Sie allerdings, dass Sie über diesen Pin nicht unbegrenzt viel Strom ziehen können – er ist also nicht geeignet, um Großverbraucher wie den weiter oben erwähnten Impeller mit Betriebsenergie zu versorgen. Für unseren kleinen und sehr sparsamen Cardreader reicht es allerdings aus. Die Zenerdioden beschränken die anliegende Spannung dann auf ihren jeweiligen Kn...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang