Steuerung der Modellbahn
mit Raspberry

PHP-Programmierung
(In Bearbeitung)
   


Die unter Steuerung der Modellbahn mit einem Computer beschriebene "Hardware", die bei der Steuerung mittels "Scratch" genutzt wurde, soll auch in dieser Variante zur Steuerung verwendet werden.
Das Wesentliche ist also die "Nutzbarmachung" von php!

PHP ist eine äußerst leistungsstarke Programmiersprache, die speziell für die Programmierung dynamischer WWW-Seiten geschaffen wurde. Vom Leistungsumfang vereint sie, grob gesagt, die Programmiersprache C++ und den UNIX-Befehl AWK. Der Aufbau der WWW-Seiten erfolgt sehr schnell.
PHP fungiert beim Aufruf solcher Seiten als Interpreter, er erzeugt durch Abarbeitung des php-Codes eine WWW-Seite im html-Code. Der Nutzer bekommt nur diesen Code zu Gesicht, die Daten bleiben unsichtbar.
Vom Sicherheitsaspekt ist das von enormer Bedeutung. Natürlich hat die Nutzung nicht nur Vorteile, es gibt natürlich Zwänge. Als wichtigste Voraussetzung braucht man auf dem Rechner einen WWW-Server, der die Einbindung von php anbietet, der muss also installiert werden.

    Arbeitsprinzip des WWW-Servers
Der Client (Auftrag zum Holen einer WWW-Seite) gibt an :
wie er mit welchem Server kommunizieren und welche WWW-Seite er haben möchte. Die Seite hat dann die Namenserweiterung .htm(l).
In diesem Fall holt der Server diese Seite aus seinem Speicher (gestrichelte Linie) und schickt sie dem Client.
Hat die Seite die Erweiterung .php dann wird diese Seite nicht zurück geschickt, sondern zum Interpreter. Der Interpreter sucht nach dem Teil der in dem html-Befehl: <?php ... ?> steht, diese darin stehenden php-Befehle werden ausgeführt. Dabei kann der Interpreter auf Dateien des WWW-Servers zugreifen und, sofern installiert, auch auf eine Datenbank, die ihrerseits natürlich wieder Daten nutzt. Und er kann natürlich auch die Verbindung zu den GPIO-Pins herstellen und dort Bits ausgeben (und auch einlesen). Ist es gefordert, werden html-Befehle erzeugt und im temporären Speicher abgelegt. Ist die php-Seite abgearbeitet, ist auch die temporäre WWW-Seite fertig und kann dem Client geschickt werden.
Damit wird nun auch deutlich, dass Fehlermeldungen nur in der zurückgeschickten Seite enthalten sein können. Es kann eben auch sein, dass der Interpreter bei Fehler seine Arbeit abbricht, dann gibt es keine Seite und auch keine Fehlermeldung!
Der Client bekommt eine html-Seite, die php-Datei bekommt er nicht zu sehen!

Nervig kann dementsprechend das Erarbeiten von php-Programmen sein. Je nach System gibt es bei Fehlern mehr oder weniger oder gar keine Fehlermeldungen, beim Raspi wird bei Programmierfehlern die Seite einfach nicht dargestellt, der Interpreter gibt nichts aus! Man sollte deshalb mit ganz kleinen Programmen beginnen und nach dem Hinzufügen weniger Zeilen immer erst einmal testen. Man kann natürlich auch alles mit /* ... */ zum Kommentar erklären und läßt dann Stück für Stück wieder die Bearbeitung zu. Jeder wird da so seine Strategie entwickeln.
Ganz wichtig sind die Zugriffsrechte
Die muss man entsprechend setzen. Ein Client ist immer, auch wenn die Seite vom Browser auf dem Raspi aufgerufen wird, ein "other"-Nutzer, die php-Seite muss für other immer die Rechte r-- haben, Daten-Dateien rw- wenn etwas zurück geschrieben wird.
Das Ganze funktioniert nur, wenn sich der Server in einem Netz befindet und dementsprechend auch eine IP-Nr. hat. Die wird durch den Router vergeben, auch eine Nutzung des Raspi eigenen Internet-Browser hat keine Verbindung zum WWW-Server des Raspi, der Raspi muss mit dem Netz verbunden sein!

Installation des WWW-Servers
Sehr gut erschlossen für Linux-Maschinen ist der "Apache-Server", der sollte installiert werden. Anleitung dazu findet man im Internet an vielen Stellen, z.B. bei:

Simtronyx: Raspberry Pi, LED über eine Webseite ein und ausschalten
oder
elektronX: Raspberry Pi: GPIO per PHP ansteuern

Es wurde der Server Apache2 und php installiert, die auch mögliche Datenbank MySQL wurde weggelassen. Ist man soweit kann man bereits auf der Kommandozeilen-Ebene testen ob die GPIO-Pins angesteuert werden (siehe dazu angegebene Internetstellen). Man braucht für die Ausgabe 2 Befehle:
gpio mode 0 out ⇐ Pin wird als Ausgabe erklärt
gpio write 0 x ⇐ es erfolgt die Ausgabe: x=0 - LED aus / x=1 - LED an

    Zu beachten ist aber, dass die Stift-Nr. der GPIO-Kontakte nicht mit den Nummern der Ansteuerung übereinstimmen.
Mit dem Befehl:
gpio readall
erhält man die Stiftbelegung des Raspberry Pi 2.
Das Bild sieht etwas anders aus, als in den Stellen im Internet. Das liest sich etwa so:
(6.Zeile, links) |17|0|GPIO.0|IN|0|11|
GPIO.0 ist auf der dem Steckerstift 11 über Adresse 17 zu erreichen!!!
Also will man mit dem Befehl oben (gpio write 0 1) eine LED anschalten, so muss sie über einen Widerstand mit Stift 11 verbunden werden!
Soll die LED am Stift 11 über ein php-Programm angesteuert werden, dann ist das die Adresse 17!

    Das Bild zeigt die Stifte und die Programmier-Adressen (auch gpio genannt).

Nun zu ersten Tests
Die Befehle in der Kommandozeilen-Ebene funktionieren!
Mutig wird nun wie in den InternetStellen angegeben ein Programm in php mit dem Befehl (nach genannten Internetstellen)

trim(@shell_exec("/usr/local/bin/gpio -g write 17 1"));

geschrieben, zuvor wurde 17 als Ausgabe festgelegt.
Und was passiert - Nichts!
Alle angegebenen Maßnahmen brachten keine Änderung, erst der letzte Hinweis in den Anleitungen brachte eine Möglichkeit. Mit dem Befehl (im Terminal):
cat /var/log/apache2/error.log
kam die Mitteilung, dass "gpio" in "/usr/local/bin/" nicht vorhanden ist, was natürlich verblüfend ist, da es ja mit dem Terminal-Befehl schon ging, muss "gpio" vorhanden sein. Im Endeffekt stellte sich heraus, dass bei der Installation "gpio" nicht in "/usr/local/bin/" sondern in "/usr/bin/" gelegt wurde! Also wurde in dem php-Befehl nur "/local" gestrichen
trim(@shell_exec("/usr/bin/gpio -g write 17 1"));
und schon ging es!
Diese Versuche wurden mit dem Experementier-Brett durchgeführt. Da das klappte konnte nun sofort die Bussteuerung aufgesteckt werden, womit nun 8 LEDs angesteuert werden konnten.

Für Tests wurde nun in php ein ähnliches Programm wie in Scratch erstellt. Es wurde jedoch davon ausgegangen, dass die dezimale Adresse bereits vorhanden ist und als Parameter in dieses Programm übergeben wird.

php-Programm zur Steuerung der Schaltelemente auf den Modulen

<?php
$dez=$_REQUEST["dez"];
if($dez>=0 and $dez<256)
{

 //---Dezimalzahl im Wertebereich---
 echo "dez: $dez / dual: ";

 function pin_def($p_nr)
 {
   //pin als Ausgang definieren
   $val=trim(@shell_exec("/usr/bin/gpio -g mode $p_nr out"));
 }

 function pin_ein($p_nr)
 {
   //LED ein
   $val = trim(@shell_exec("/usr/bin/gpio -g write $p_nr 1"));
 }

 function pin_aus($p_nr)
 {
   //LED aus
   $val = trim(@shell_exec("/usr/bin/gpio -g write $p_nr 0"));
 }

 //---Zuordnung bits zu Brett-Adr.-------------
 $pinsz[0]=29;
 $pinsz[1]=31;
 $pinsz[2]=33;
 $pinsz[3]=35;
 $pinsz[4]=36;
 $pinsz[5]=37;
 $pinsz[6]=38;
 $pinsz[7]=40;

 //---Zuordnung Brett-Adr. zu GPIO-Adr.-------------
 $pins[29]=5;
 $pins[31]=6;
 $pins[33]=13;
 $pins[35]=19;
 $pins[36]=16;
 $pins[37]=26;
 $pins[38]=20;
 $pins[40]=21;
 $pins[32]=12;

 //---Array $pitd mit 0 belegen ---------
 for($i=0;$i<=7;$i++)
 {
    $bitd[$i]=0;
 }

 //---Dezimalzahl $dez in Dual umwandeln---
 // -(speich.auf bitd)-
 $zahl=$dez;
 $i=0;
 while($zahl!=0)
 {
    $rest=$zahl % 2;
    $zahl=floor($zahl / 2);
    $bitd[$i]=$rest;
    $i++;
 }

//---Bits aus $bitd auf GPIO-Kont.ausgeben---------
 for($i=0;$i<=7;$i++)
 {
    //$nr1=$pinsz[$i];
    //$nr=$pins[$nr1];
    $nr=$pins[$pinsz[$i]];
    call_user_func("pin_def",$nr);

    if($bitd[$i]==1)
      call_user_func("pin_ein",$nr);
    else
      call_user_func("pin_aus",$nr);
 }

 //---Dualzahl darstellen--------------------
 for($i=7;$i>=0;$i--)
 {
    echo "$bitd[$i]";
 }
 echo "<br>";

 //---strobe-Signal fuer 1 sec ausgeben--pin32-------
 call_user_func("pin_def",12);
 call_user_func("pin_ein",12);
 sleep(1);
 call_user_func("pin_aus",12);

}
else
 echo "Die Dezimalzahl <b>$dez liegt nicht im Wertebereich</b><br>
  (< 0 oder > 255)!";

?>

    Im Groben stellt sich der gleiche Ablaufplan wie bei "Scratch" ein:

Die zu nutzende Adresse wird als Parameter in dieses Programm übergeben:
$dez=$_REQUEST["dez"];
übernimmt den Parameter auf Speicherplatz $dez.

Die weitere Bearbeitung erfolgt nur, wenn der Wert im definierten Wertebereich liegt.

Als Vereinbarung werden zunächst für die Ansteuerung der Pins 3 Funktionen definiert, Parameter ist die php-Adresse der Pins.

In der weiteren Folge gibt es 2 Zuordnungstabellen in Form von Arrays. Das erste ($pinsz) ordnet die berechneten Bits zu den Stift-Nr. des GPIO-Feldes des Raspi zu. Das Bit ist zugleich Index in diesem Array.
Im zweiten Array ($pins) wird der Stift-Nr. die interne Berechnungs-Nr. zugeordnet (Stift-Nr. ist Index).
Diese beiden Zuordnungen hätte man auch mit nur einem Array realisieren können, z.B. $pinsz[0]=5, so ist es jedoch übersichtlicher und auch leicht änderbar.

Die Berechnungen der Dualzahl landen im Array ($bitd). Profilaktisch werden nun einmal im nächsten Teil alle Array-Elemente (0 ... 7) auf 0 gesetzt, die Berechnung überschreibt später den Wert. Aber man brauch nicht im Nachhinein ermitteln, wie viele Nullen noch eingeschrieben werden müssen.

Nun erfolgt die Umwandlung der dezimalen Adresse in eine duale.
Das geht genau wie in Scratch.
while($zahl!=0) { ... } entspricht der Konstroktion "wiederhole bis Zahl = 0" und der dann eingeschlossenen Zeilen.
$rest=$zahl % 2; auf Speicherplatz $rest wird das Ergebnis der Modulo-Operation von $zahl mit 2 gespeichert.
$zahl=floor($zahl / 2); führt die ganzzahlige Division und deren abrunden durch. Das Ergebnis steht wieder auf $zahl.
Den nächsten Befehl könnte man sparen, wenn man gleich die Modulo-Operation ins Array speichert.
Ganz wichtig ist auch der letzte Schritt $i++;, bedeutet $i=$i+1, das ist der genutzte Index im Array ($bitd).

Die Bitfolge liegt nun vor. Der folgende Schritt muss nun entsprechend dem ermittelten Wert die GPIO-Pins ansteuern. Diese Aktion könnte man natürlich gleich bei der Berechnung anfügen, jetzt müssen die einzelnen Elemente des Arrays ($bitd) abgefragt werden.
Für die Ausgabe braucht man nun die php-Adresse der pins. Das kann man nun relativ einfach durch den Befehl $nr=$pins[$pinsz[$i]]; erledigen. Die php-Version läßt als Index auch ein Array-Element zu. Geht das nicht, geht das auch mit den zwei davor befindlichen Befehlen (jetzt als Kommentar gekennzeichnet).
Da ich nicht weiß, ob dieses pin schon aktiviert wurde, wird nun immer dieses pin erst einmal als Ausgabe-pin erklärt, mit dem Funktionsaufruf
call_user_func("pin_def",$nr);,
$nr wird als Parameter in die Funktion übertragen. Danach wird dann in Abhängigkeit vom Array-Wert das pin mittels Funktionsaufruf ein- oder ausgeschaltet.

Der nächste Teil muss nicht sein, es soll die ermittelte Dual-Zahl auch auf dem Bildschirm als Text ausgegeben werden, die haben wir so aber nicht ermittelt. Entweder fügt man das bei der Berechnung oben noch mit ein oder man gibt die Bits aus dem Array ($bitd) einfach einzel aus. Man muss nun aber die richtige Reihenfolge wählen, also rückwärtz! Deshalb gibt es die Schleife für $i von 7 bis 0 ( for($i=7;$i>=0;$i--) ). Der "echo"-Befehl organisiert die Ausgabe auf dem Bildschirm.

Die pins sind nun geschaltet, mit der angeschlossenen Technik aber nicht sichtbar, denn sie sollen alle zeitgleich aktiviert werden. Dazu wird im nächsten Teil das strobe-Signal ausgegeben. Das ist eine Ausgabe auf pin32, welches die php-Adresse 12 hat, die wird so eingegeben.

Jetzt wird der Teil für die richtige Eingabe mit } beendet (oben gab es dazu { ) und nach dem Befehl else für den Fehlerfall (falsche Eingabe) eine Fehlermeldung generiert.

Nun muss noch geklärt werden, wie dieses Programm gestartet wird.
Dieser dargestellte Programmteil kann nur durch Aufruf als WWW-Seite gestartet werden. Der WWW-Server entnimmt aus seinem Speicher die WWW-Seite (Datei) und schickt sie in den php-Interpreter (das weiß er, weil die Datei die Erweiterung .php hat. Der Interpreter versucht nun aus den Anweisungen html-Befehle zu generieren und erstellt eine temporäre WWW-Seite. Diese schickt der WWW-Server nun dem Aufrufer (Client).
In unserem Fall wird das zu Fehlern führen, bzw. es wird keine Seite generiert, da die Seite so nicht dem Aufbau einer html-Seite entspricht, also (minimal):

<html>
<head> ... </head>
<body>
...
html-Befehle (z.B. unser php-Teil)
...
</body>
</html>

d.h. wir müssen unser Programm in diesen Rahmen stecken!
Dieses Seite kann man dann über die bekannte Methode aufrufen, indem man einfach die Adresse eintippt (in der Adresszeile des Browsers), z.B.:
http://Server-Adresse/Name-WWW-Seite.php?dez=13
Server-Adresse und Name-WWW-Seite (ohne Erweiterung php) muss den Tatsachen entsprechen (Name-WWW-Seite kann auch den Pfad enthalten), hinter ? wird der Parameter der Variablen dez mit dem Wert 13 angefügt.

html-Programm zum Start der Schaltelemente-Steuerung

Eine andere Variante zum Start der Seite wäre, diese aus einer anderen WWW-Seite als Link aufzurufen. Hier würde dann auch die Eingabe der Dezimalzahl (Adresse) erfolgen.


<html>
<head>
<title>Formular Adr.Eingabe</title>
<head>

<body>
<form action="http://192.168.2.100/pin_ausg_run.php" method="GET">
<table>
<tr>
<td>Dezimalzahl:</td>
<td>
<input type="text" name="dez" size=8>
</td>
<td>(0 ... 255)</td>
</tr>
</table>
<input type="submit" name="ok" value="ok">
</form>

</body>
</html>

    Es wurde eine Seite: "pin_ausg_form.html" geschrieben, in der über den "form"-Befehl die Eingabe und der Aufruf der php-Seite organisiert wird.

Der Dezimalwert wird mit der Zeile input type="text" ... eingegeben und durch die method=GET als Parameter an die Seitenadresse angehängt.

Das Formular sieht dann so aus:

Mit Anklicken des ok-Buttons wird der Vorgang ausgelöst.

Schreibt man am Ende des php-Programms (vor </body>) noch den Aufruf dieser html-Seite:

<a href="http://Server-richtiger Name/pin_ausg_form.html">Adr.Eing.</a>
kann man ständig zwischen den beiden Seiten hin und her wechseln.

php-Programm zur Steuerung der Fahrspannung

Im Prinzip läuft das Programm ähnlich ab, wie das zur Steuerung der Schaltelemente. Aus dem übergebenen Wert der Fahrstufe (0...4) werden jeweils die Steuerbits ermittelt (zugeordnet) und auf die GPIO-Pins ausgegeben.
Links ist das php-Programm dargestellt, rechts ein mögliches Programm zur Eingabe der Werte und Start des php-Programms.

<html>
<head>
<title>Fahspannung/Mod steuern</title>
<head>

<body>
Fahrspannung/Mod steuern

<?php
  $fspg=$_REQUEST["fspg"];
  $nrb=$_REQUEST["nrb"];

  echo "fspg: $fspg / nrb (mod): $nrb<br>";
  $feh=0;

  if($fspg<-4 or $fspg > 4)
  {
    echo "Wert Fahrspg $fspg falsch - auf 0 gesetzt<br>";
    $fspg=0;
    $feh=1;
  }
  if($nrb!=0 and $nrb!=1)
  {
    echo "Wert Fahrbetrieb $nrb falsch - auf 0 gesetzt<br>";
    $nrb=0;
    $feh=1;
  }

  function pin_def($p_nr)
  {
    //pin als Ausgang definieren
    $val=trim(@shell_exec("/usr/bin/gpio -g mode $p_nr out"));
  }  

  function pin_ein($p_nr)
  {
    //LED ein
    $val = trim(@shell_exec("/usr/bin/gpio -g write $p_nr 1"));
  }

  function pin_aus($p_nr)
  {
    //LED aus
    $val = trim(@shell_exec("/usr/bin/gpio -g write $p_nr 0"));
  }

  //---Zuordnung bits zu Brett-Adr.-------------
  $pinfz[1]=11;
  $pinfz[2]=12;
  $pinfz[3]=13;
  $pinfz[4]=15;
  $pinfz[5]=16;

  //---Zuordnung Brett-Adr. zu GPIO-Adr.-------------
  $pinf[11]=17;
  $pinf[12]=18;
  $pinf[13]=27;
  $pinf[15]=22;
  $pinf[16]=23;

  if($feh>0)
  echo "fspg: $fspg / nrb (mod): $nrb<br>";

  //---alle $bitf auf 0 setzen---
  for($i=1;$i<=5;$i++)
  $bitf[$i]=0;

  //---$bitf[4] auf 1 setzen - Rangierbetrieb---
  if($nrb==1)
  $bitf[4]=1;

  //---$bitf[5] auf 1 setzen - Richtungswechsel---
  if($fspg<0)
  {
    $bitf[5]=1;
    $fspg=abs($fspg);
  }

  //---Fahrst. -> $bitf auf 1 setzen---
  if($fspg==0)   // Fahrst.0
    $bitf[1]=1;
  if($fspg==1)   // Fahrst.1
  {
    $bitf[2]=1;$bitf[3]=1;$bitf[4]=1;
  }
  if($fspg==2)   // Fahrst.2
    $bitf[2]=1;
  if($fspg==3)   // Fahrst.3
    $bitf[3]=1;
// Fahrst.4 - kein Bit gesetzt!

  echo "Anstrg. Regler (Bit 5...1): ";
  echo "$bitf[5] $bitf[4] $bitf[3] $bitf[2] $bitf[1]<br>";

  //---GPIO ansteuern---
  $k=5;
  if($fspg==0)$k=1;
  for($i=$k;$i>=1;$i--)
  {
    $nr=$pinf[$pinfz[$i]];
    call_user_func("pin_def",$nr);

    if($bitf[$i]==1)
      call_user_func("pin_ein",$nr);
    else
      call_user_func("pin_aus",$nr);
  }
?>

<a href="http://192.168.2.100/fspg_form.html">Fahrsp. neu<a>

</body>
</html>

    Die Eingabe der Werte erfolgt in ähnlicher Form wie oben:

<html>
<head>
<title>Formular Fahrspannung Eingabe</title>
</head>

<body>
<form action="http://192.168.2.100/fspg_run.php" method="GET">
<table>
<tr>
<td>Fahrspg (-4...0...4):</td>
<td>
<input type="text" name="fspg" size=1 value=0>
</td>
</tr><tr>
<td>
Fahrspg_Mod (0 - nb/1 - rb):
</td>
<td>
<input type="text" name="nrb" size=1 value=0>
</td>
</tr>
</table>

<input type="submit" name="ok" value="ok">
</form>

</body>
</html>

So sieht dazu das Eingabeformular aus:

Noch einige Bemerkungen zum php-Programm.
Die Ausgabe auf die GPIO-Kontakte erfolgt nicht wie beim Bus über ein Strobe-Signal-Steuerung, sondern nacheinander, wie sie bearbeitet werden, d.h. von Bit1 nach Bit5. Bit1 bis 3 steuern über das TG sofort die Regler-Widerstände an, Bit4 und 5 über TG's Transistoren und dann Relais. Es ist anzunehmen, dass die Relais später als die Reglerwiderstände ihre Funktion beenden. Das bedeutet, wenn die Fahrtrichtung das Schalten des Relais erfordert und der Ausgangspunkt die Fahrstufe 0 ist, dass die Fahrspannung schon mal in die falsche Richtung zeigt und dann etwas später erst die Fahrtrichtungsumschaltung wirksam wird.
Man kann versuchen, das Problem einfach durch Vertauschen der Ausgabereihenfolge, also Bit5 ... Bit1 zu beheben. Sollte das noch immer nicht reichen, fügt man hinter der Ausgabe von Bit5 eine Verzögerung ein - aber es hat gereicht, die Spannung läuft nun sofort in die richtige Richtung!
Weitere Änderungen waren notwendig, da auch beim Schalten nach 0 ebenfalls nicht sofort die richtigen Spannungswerte eingestellt wurden. Das wurde behoben, indem bei der Fahrstufe 0 nur noch Bit1 ausgegeben wird, damit bleiben alle alten Einstellungen bestehen, bringen so keine Impulse mehr.

Die ersten Überlegungen zur Steuerung der Fahrspannung sahen so aus:

           

Um die Ausgabe im bereits vorhandenem php-Programm einzufügen, wurden aus Schaltelementesteuerung und aus der Fahrspannungserzeugung php-Funktionen erstellt. Das ist sinnvoll, da in dem php-Programm die Ausgaben der jeweiligen Dezimalwerte schon vorhanden ist, die Werte brauchen dann nur noch als Parameter in diese Funktionen übergeben zu werden. Die Unterschiede bei der Fahrspannungserzeugung (hier Fahrstufen 0...4, bei der Technik -4...4, Fahrtrichtungsschalter) werden programmtechnisch angepasst, der Rangierbetrieb kann im Test nicht eingeschaltet werden, das bedarf eines weiteren Schalters, was in Version7 durch eine andere Darstellung geregelt wird.
Der Regler wird bedient, indem mit dem Kursor auf ein Feld der Fahrspannung geklickt wird, also auf halt (aus) oder ¼ oder ½ (halb) oder ¾ oder voll. Der Schieber stellt sich dann auf diesen Wert ein.
Damit gibt es nun aber ein Problem, denn nun kann man ohne Probleme von halt auf volle Fahrt schalten, das wollten wir vermeiden. Das kann man programmtechnisch realisieren, so wie auch die Fahrtrichtung nur bei 0 umgeschaltet werden kann.
(eine Testversion zu dieser Bedienung war: Bedienung vom PC (V6.0) )
Hinzu kommt nun noch die Möglichkeit, zwischen Normal- und Rangierbetrieb umschalten zu können (rechts vom Strich, wurde in dieser Version nicht genutzt).
Tests zeigen, dass die Schaltflächen des Reglers zu klein sind, man trifft sie einfach schlecht. Eine Verbesserung bringt der Regler, der im Scratch-Programm genutzt wurde.

       

Das programmtechnischen Konzept entspricht der vorhergehenden Variante, die Fahrstufen können jedoch nur über die mit ◀ und ▶ gekennzeichneten Flächen immer nur um eine Stufe geändert werden. Der Fahrtrichtungsumschalter entfällt, das erledigt der Regler automatisch.
Des Weiteren wird eine "Notbremse" vorgesehen, hier wird dann bewußt aus jeder Fahrstufe ohne Übergang auf halt geschaltet. In Gefahrensituationen kann man den Zug sofort anhalten.
Die Umschaltung von Normal- (Strecken-) auf Rangierbetrieb geht in jeder Fahrstufe und bleibt bis zum Rückschalten in den Normalbetrieb bestehen.

Bedienung vom PC (V7.0)

Weitere Programm-Änderungen

Um etwas Zeit zu sparen, wird die Definition der GPIO-Pins als Ausgang
    call_user_func("pin_def",$nr);
aus dem ständigen Aufruf heraus genommen. Das ist möglich, da einmal eingestellte Pins über die gesamte Einschaltzeit des Raspi ihre Funktion behalten. Das kann man durch ein Programm erledigen, welches beim Start des Raspis automatisch gestartet wird, oder man startet die Steuerprogramme nicht mit Ihrem Namen sondern aus einen (Vor)Programm heraus, was Einstellung der Pins vornimmt und mittels Parameter, der eine Kennung der Einstellung möglich macht, das Steuerprogramm startet.
Im Programm kann dann mittels if-Anweisung entschieden werden, ob noch eine Initialisierung der Pins notwendig ist.
  if($gen==0)
    call_user_func("pin_def",$nr);
Somit kann das Steuer-Programm aber auch wie bisher gestartet werden.
Immer wenn der Parameter $gen 0 ist, erfolgt die Generierung, nun aber bei jeder Ausgabe!