web analytics

The PLTB Arduino style train switch – Der automatische Keller 2

Die Post war da, und es kann weiter gehen. (Wir kommen von hier) Die Servos sind da, und damit ist es zeit die Sache mit den Weichen anzugehen. Zudem habe ich es endlich geschafft die erste Fuhre Holz heran zu schaffen, und im Keller ein wenig zu werken. Wieder einmal wird klar, dass mit „richtigem“, und ich meine „richtigem“ Werkzeug alles viel besser wird. Ersetze alte schraddelige Handkreissäge durch Profi Kappsäge (Danke, Claas!), und schon werden Schnitte gerade und Bauwerke waage.

Ein halber Sonntag Arbeit brachte uns zumindest schon einmal bis zu einem Unterbau, welcher die möglichen Maße im Keller definiert:

Zur Erklärung, diese 45 Grad abgeschrägten Stücke dienen NICHT später der Stabilität und werden noch verbaut! NEIN! „Das sind Schiffe, Papa, und die fahren hier unten alle rum.“ Ist doch klar, oder?

Noch ein paar Tage weiter, und aus Unterbau und inzwischen besorgten Platten (wieder Danke an Claas und seinen Bully) ist ein Tisch geworden. Logischerweise musste SOFORT etwas darauf aufgebaut werden. Wo kämen wir hin, wenn das Ganze nicht sofort bespielt werden kann?

Nun zur Sache, ich überspringe aktuell die Automation und bleibe bei der Hardware:

3. – Alle Weichen lassen sich zentral elektronisch und automatisch über die Weboberfläche steuern.

Phase1: Arduino gibt Pfötchen, äh – also steuert Servos

Grundlegend könnte ich auch die GPIO Ports des Raspberry für die Ansteuerung der Servos benutzen. Aber: Wer weiß was ich damit nochmal vor habe, und wozu diese Ports dort noch mal gut sind. Also, die Weichensteuerung erfolgt über einen am Pi angeschlossenen Arduino UNO, und dessen GPIO Digital PWM Ports.

Stückliste:

  • Der Raspberry Pi aus Teil eins, fröhlich die Züge steuernd
  • Arduino Board, in meinem Fall der UNO, alle Varianten sollten aber ohne Probleme gehen
  • Microservos – Ich verwende Hextronix HXT900, 9g, 1,6kg
  • LEGO PF Weichen

Das Servo wird zunächst am Arduino über 5V+ und GND, sowie über einen der PWM Ports angeschlossen. Ich habe ohne weitere Gründe Port 7 verwendet. In der Regel sind die Steuerleitungen der Servos gelb oder orange, während die üblichen Plus/Minus Farben rot/schwarz oder ähnlich sein dürften. Ich denke das ist selbsterklärend, da muss man nicht groß denken. Das Arduino Board wird einfach per USB am Pi betrieben, benötigt aber vorher noch eine Betankung.

Schaltbild Arduino (USB an Pi) und Servo an Pin PWM7

Damit wir später über den Pi und unser NodeJS mit dem Servo sprechen können, benötigt der Arduino als Programm noch eine der so genannten Arduino Firmata im Bauch. Dazu wird der Arduino lt. Tutorial an einen Rechner angeschlossen, und über die Arduino Entwicklungstools mit einem Firmata aus der Example Bibliothek versorgt.

Auszug aus der Arduino Anleitung:

Setting Up Firmata.
Before you can start programming your NodeBots, you will need to load Firmata onto your Arduino-compatible microcontroller:

    Download Arduino IDE
    Connect your Arduino-compatible microcontroller via USB
    Launch Arduino IDE and open the Firmata sketch via the menu: File > Examples > Firmata > StandardFirmata
    Select your Arduino board type (e.g. Arduino Uno) via Tools > Board
    Select the port for your board via Tools > Serial Port > (the comm port of your Arduino)
    Upload the program by selecting File > Upload

An dieser Stelle sei noch zwischengeschoben, dass sowohl Pi als auch Arduino im Endausbau wohl zu viel Last erzeugen, als dass ich die 5V Stromversorgung auf den Boards belassen könnte. Sobald ich einigermaßen abschätzen kann was da insgesamt später an Ampere heraus – nein, eher herein – kommt, werde ich das mit einem Stecker Netzteil lösen.

Nachdem die Grundbetankung des UNO nun abgeschlossen ist und dieser am Pi hängt geht es zunächst erst einmal wieder hinein in die Software und zurück zu socket.io. Für die Kommunikation mit dem Servo sind NodeJS noch ein paar Kleinigkeiten zu erklären.

Phase2: Servobefehle durch die Kabelkette

NodeJS und JohnnyFive merken beim Start der passenden Module später selbst, ob und an welchem USB Port der Arduino hängen. Darüber muss man sich keine Gedanken machen, wie unverhofft einfach. Nein. Nicht wirklich.
Denn vor die Connection mit dem Arduino als Board hat NodeJS das Modul Serialport gesetzt. Und das war nur schwer von seiner Funktion zu überzeugen.

Wir befinden uns im Verzeichnis des Projektes aus Teil 1 und installieren das Modul für die serielle Verbindung. Vorher braucht es allerdings dafür eine C Compilerumgebung, welche serialport selbst mitbringen möchte, mit welcher ich allerdings böse Probleme bekam:

# Zunächst vorab der Versuch mit -g das modul node-pre-gyp per Hand zu platzieren - sollte ohne Fehler klappen

npm install -g node-pre-gyp

# Dann das eigentliche Serialport

npm install serialport

An dieser Stelle sind die folgenden Zeilen erst einmal zu ignorieren. Startet aber das JS Projekt später mit dem Fehler „Could not find node-pre-gyp“ in Serialport werden die Links evtl. hilfreich:

  • Der Versuch mit -fallback-to-build die Version zu erzwingen, die serialport benötigt – node-pre-gyp install –fallback-to-build
  • https://github.com/rwaldron/johnny-five/issues/750 könnte helfen
  • Evtl. node-pre-gyp mit der Hand installieren – Downloaden, im modules Verzeichnis entpacken, und dann im eignen Verzeichnis npm install
  • Weitere Tipps evtl. hier

Wenn das wehrhafte Modul Serialport erledigt ist, geht es zurück an den JS Code, und es wird Zeit Kontakt zum Servo zu suchen.

Das Init JS Script wird erweitert um die Arduino Module einzubinden:

// Raspberry Module laden
	var five = require('johnny-five'),servo;
	var raspi = require("raspi-io");
	
	//var five = require("johnny-five");
   var arduboard = new five.Board();
	// Arduino initialisieren

	var board = new five.Board({
  		io: new raspi()

Dazu die Zeilen zur Definition des ersten Servo an Port 7:

// Weiche 1 an Port 7 Arduino definieren
arduboard.on("ready", function() {
// Weiche 1 an Port 7 Arduino definieren
  servo7 = new five.Servo({
    pin:7,
    range: [0,45],
    type: "standard",
    center:false
  });

//    var switchServo = new five.Servo(7); // Crossing Arm
	// Add devices to REPL (optional)
    this.repl.inject({
        servo7: servo7,
    });
     servo7.to(0); // Adjust this servo angle as needed
});
//*********************************************

Ganz nebenbei, die Funktion „this.repl.inject“ sorgt dafür, dass man nach Start des Scripts mit node interaktiv mit dem Script und damit mit der Hardware interagieren kann. Gut für mich, so war es möglich die Einstellungen und Armwege etc. für mein Servo direkt auszuloten, ohne jedes mal im Quellcode zu arbeiten.

Wenn alles klappt sollte der Output beim Start des Skriptes in etwa so aussehen:

pi@legopi ~/lego $ sudo node start_pltb.js 
1447796629353 Device(s) RaspberryPi-IO  
1447796629700 Connected RaspberryPi-IO  
1447796629801 Repl Initialized  
>> 1447796631564 Device(s) /dev/ttyACM0  
1447796631761 Connected /dev/ttyACM0  
1447796635659 Repl Initialized  
>> 

Sollte sich ein „throw error“ einschleichen und dabei der Verweis auf node-pre-gyp erscheinen ist leider die Schleife zu drehen, welche ich weiter oben beschrieben habe.

Sollte alles gut gehen, könnt ihr mal das Servo drehen. Ein Befehl dafür wäre z.B. der Folgende:

servo7.to(45)

Eine gute Beschreibung zum Thema Servos und JohnnyFive ist hier zu finden.

Phase3: Eine Weiche vorbereiten

Damit die Weichen ihre Stellung halten, haben sie in Fachkreisen professionell so benannte „Nupsis“. Diese gilt es allerdings für eine reibungslose Funktion am Servo zu entfernen. Mit etwas stärkeren Servos oder einer anderen Schalttechnik kann man sich diesen Schritt bestimmt schenken, jedoch ist in meiner Version „Eins“ ein Messer im Spiel. Zunächst werden wie im linken Bild zu sehen die Befestigungspunkte vorsichtig mit einem Bohrer oder einem Messer geöffnet. Danach lassen sich die kleinen Nupsis an der frei liegenden Schiene wie im rechten Bild sichtbar abknipsen. Schon rutscht die Weiche smooth ohne „Klick/Klack“ in ihre Positionen…

 

Für Version 2 denke ich natürlich schon über mögliche Verbesserungen nach, allerdings ist dies zunächst die günstigste Variante. Im Netz finden sich hier und da Umbauten von Weichen mit Hilfe von Lego PF Motoren oder sogar mit Mindstorms Stellmotoren. Die Kosten Pro Weiche gehen dabei aber locker deutlich über 10 Euro, wogegen meine Version mit ca. 2,49 Euro pro Weiche dann doch einen guten Start darstellt.

Phase4: Und es bewegt sich (doch)

 

Der digitaltauglich geschnippelten Weiche fehlt nun noch ihr Servo. Für meine Proof of concept Version hier habe ich zunächst auf einfachste Arte und Weise Servoarm mit etwas Lego Technik gekoppelt, und das Servo an sich in einer kleinen Box aus Steinen befestigt. Auch hier ist bestimmt Luft nach oben, aber wer hat schon all die Zeit und Geduld, wenn es doch darum geht erste Ergebnisse zu bekommen?!

Auf der Clientseite – also in der index.html für den Browser sorgt eine bootstrap Buttongroup für das Aussehen, ein input mit value= für Daten, und ein Fitzel Javascript für den Auslöser des socket.io Emit der Servoarmbewegung. Hier geht es lang für die je aktuellen Stände des Codes.

$('.servobtn').button();
      $('.servobtn').on('change',function(){
          console.log("Setting Servo Pos:",$('input[name=servo]:checked').val())
          socket.emit('servo7call',{pos:$('input[name=servo]:checked').val()});
      });

Auf der Serverseite – also in der start_pltb.js im NodeJS empfängt socket.io den Befehl und stellt den Arm lt. Funktion:

// Servo 1 Pin 7 bewegen
socket.on('servo7call', function (winkel) {
    console.log(winkel);
    if(board.isReady){ servo7.to(winkel.pos);  }
  });
// Servo 1 Pin 7 ende

Die Stellweite des Arms verbirgt sich im Value des input Feldes. Das war reines trial & error – 100 ist der Wert, der in meiner Konstellation passt. Leider habe ich das „Servobrummen“ noch nicht ganz weg bekommen. Ich bin mir unsicher ob dies an den Servos, oder meinen Programmierkünsten liegt. Offiziell „brummen“ digitale Servos eigentlich nur, wenn sie Ihre Stellpositionen nicht richtig erreichen, oder auf Last stehen bleiben. Beides trifft hier irgendwie nicht ganz zu. Ein Update zu dem Thema findet Ihr hier, wenn ich es gefunden habe…

About the Author

David Wagner

David Wagner

IT Berater, Technology Evangelist, Nerd, Geek, Daddy of Darth Tom, Star Wars, LEGO®, Foto, und Wakeboarding. Lebt im Internet, und mit der Familie in einem norddeutschen Kaff namens Hude.

1 Comment

Schreibe einen Kommentar

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