Jekyll2022-07-27T19:56:32+00:00/feed.xmlAlbrecht Weinert’s blogAlbrecht Weinert, blog on GitHub Pages4 Schalter an 2 (3) Leitungen2022-07-27T00:00:00+00:002022-07-27T00:00:00+00:00/4switchesOn2Lines_de<p>Der Artikel beschreibt eine Lösung, um 4 Schalter oder Taster über nur 2 (3)
(anstatt 4 (5)) Leitungsadern mit einer Verteilung zu verbinden, in der sie
vier Relais oder<!--more--> Eltakos steuern. Siehe auch
<a href="allOut4eltakos.html" title="Komfortables Alle Lichter Aus mit Stromstoßschaltern">Komfort mit Eltakos</a>.</p>
<h2 id="der-anlass--ein-unglück">Der Anlass – ein Unglück</h2>
<p>Für vier Taster an einer entfernten Wand war ein 7-adriges NYM-Kabel von der
in
<a href="allOut4eltakos_de.html" title="Komfortables Alle Lichter Aus mit Stromstoßschaltern">Komfort mit Eltakos</a>
beschrieben Verteilung zu einer Doppel-UP-Dose in der abgehängten Decke
verlegt worden: 7 Adern - 1 PE - 1 Reserve waren die 5 für standardmäßig
erforderlichen Leitungsdrähte.</p>
<p>Bei der Montage der Deckenheizung wurde eine Schraube an der Lattung
vorbei in dieses Kabel getrieben; sie verband 5 Adern miteinander. Als das
entdeckt und die Stelle des Schadens lokalisiert wurde, war die Deckenheizung
bereits verputzt, befüllt und in Betrieb. <br />
Eine Reparatur der Leitung mit vertretbarem Aufwand und Risiko war nicht
mehr möglich. Aber auch ohne diesen unglücklichen Anlass kommt man
gelegentlich in die Situation, dass für eine gewünschte Anzahl von Schaltern
oder Tastern die Zahl der Adern nicht reicht.
<a href="/assets/images/postEltako/\4LinesOo2\4LinesOo2.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/\4LinesOo2\4LinesOo2_333.jpg" width="333" height="168" title="Halbwellenansatz; click: groß" alt="Halbwellenansatz" class="imgonright" /></a></p>
<h2 id="lösungsansatz">Lösungsansatz</h2>
<p>Bei Wechselspannung liegt es nahe, jeder Information (oder jedem
Verbraucher) eine Halbwelle auf der Leitung zuzuordnen. Das Bild rechts zeigt
dies für 4 Taster und Relais.</p>
<p>Nun zeigt es sich, dass moderne Kleinrelais vorteilhafterweise so geringe
bewegte Massen haben, dass sie bei einer solchen Halbwellenspeisung 50 mal
pro Sekunde klappern. Dies trifft auch auf Eltako-Stromstoßschalter und
-Relais zu. <br />
Hinzu kommt, dass Relais für 230V~ bei einer solchen Gleichstromspeisung
Schaden nehmen würden, selbst wenn es für Stromstoßschalter i.A. nur
kurzzeitig wäre.</p>
<p>Hier sind also (2 oder 4) Vorwiderstände und 4 Siebkondensatoren (einer pro
Relais) erforderlich. Dies für 230V~-Relais direkt zu machen ist aufwändig
und voluminös. Es birgt zusätzliche Gefahren durch bei Unterbrechungen auf
bis zu 320V= aufgeladene Kondensatoren. Und bei der
<a href="allOut4eltakos.html" title="Komfortables Alle Lichter Aus mit Stromstoßschaltern">vorliegenden Anwendung</a>
auch gegebenen Ansteuerung derselben Eltakos mit Wechselspannung verbietet
sich das parallel Schalten eines Siebkondensators selbst mit einer
zusätzlichen Entkopplungsdiode.</p>
<p>Mit Kleinspannung und einer zusätzlichen Ebene von über Transistoren
angesteuerte Relais umgeht man all diese Hindernisse.<a href="/assets/images/postEltako/4LinesOo2\relayModCirc.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/4LinesOo2/relayModCirc_333.jpg" width="333" height="309" title="Relaismodul; click: groß" alt="Relaismodul" class="imgonright" /></a></p>
<h2 id="relaismodule">Relaismodule</h2>
<p>Es gibt vielfältige und preiswerte Angebote kompakter Relaismodule für
Kleinspannung (5V, 12V etc.) und Ansteuerung über Optokoppler. Die
übliche Schaltung für ein Relais zeigt das Diagramm rechts. Die Module gibt
es mit einem oder mehreren – teilweise bis zu 12 oder 16 – Relais. Für
unseren Fall wurde ein 5V-Modul mit vier Relais 1*Um eingesetzt
– Preis 7€.</p>
<p>Der gemeinsame Nachteil bei allen gefundenen Angeboten ist der gemeinsame
Minus-Anschluss – im Diagram Gnd<sub>anst</sub> genannt – der Ansteuerung
über die Optokoppler. Mit diesem Designfehler geht die Möglichkeit der
auch untereinander potentialgetrennten Ansteuerung und mit unterschiedlicher
Polarität verloren.</p>
<p>Letzteres wird hier gebraucht. Zwei Trennstellen und ein paar Brücken
führen zu der gewünschten Verschaltung der Optokoppler-Ansteuerung. Die
vier Anzeige-<abbr title="Leuchtdiode">LED</abbr>s des Relaismoduls
ersetzen die vier Eingangsdioden rechts
im ersten Diagram. Mit jeweils einem kleinen
<abbr title="Elektrolytkondensator">Elko</abbr> 10µF,16V.Minus an Kathode
der Leuchtdiode des Optokopplers (angedeutet als m) und Plus an der Kathode
der Anzeige-LED (angedeutet als p) gibt es kein 50Hz-Klappern.</p>
<p>Im unteren linken Bild sind die Modifikationen Zusatz-Elkos und gemeinsamer
Vorwiderstand erkennbar. Das rechte Bild zeigt die Integration im
Schaltschrank: Mit den Arbeitskontakten
(<abbr title="normally open">NO</abbr>) werden die betreffenden Eltakos auf
der Hutschiene darüber ganz normal mit 230V~ angesteuert. <br />
</p>
<p><a href="/assets/images/postEltako/4LinesOo2\relayMod.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/4LinesOo2/relayMod_359.jpg" width="359" height="482" title="Relaismodul modifiziert; click: groß" alt="Relaismodul" class="imgonleftt" /></a>
<a href="/assets/images/postEltako/4LinesOo2\relayModInt.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/4LinesOo2/relayModInt_333.jpg" width="333" height="482" title="Relaismodul eingebaut; click: groß" alt="Relaismodul" class="imgonright" /></a></p>Albrecht WeinertDer Artikel beschreibt eine Lösung, um 4 Schalter oder Taster über nur 2 (3) (anstatt 4 (5)) Leitungsadern mit einer Verteilung zu verbinden, in der sie vier Relais oder“All off” plus extra comfort with multiple Eltako light circuits2022-04-05T00:00:00+00:002022-04-05T00:00:00+00:00/allOut4eltakos<p>To have multiple independent electrical light circuits in large or
adjacent rooms with many distributed switches for each circuit
applying latching relays (+ pushbuttons) is a viable<!--more--> solution.</p>
<p>In large or adjacent rooms one or some extra “all off” – and
“on again”, of course – push buttons may be required. By itself this is
is no problem.</p>
<p>If a person has been forgotten and left in the now dark rooms it would be
comfortable if pushing any light circuit’s pushbutton would turn the
(previously lit) lights on again. This might even enhance safety in some
environments.</p>
<p>The <a href="allOut4eltakos_de.html" title="Sorry no full English text">German post</a>
describes a scheme this extra comfort. <br />
Sorry for having no English version; my “electric English” is too poor
to avoid miss-understanding.<br />
Even when understanding quite few of the
<a href="allOut4eltakos_de.html">German text</a> the diagrams might, hopefully,
be self explaining.</p>Albrecht WeinertTo have multiple independent electrical light circuits in large or adjacent rooms with many distributed switches for each circuit applying latching relays (+ pushbuttons) is a viable“Alles Aus” mit Komfort für viele Eltako- (Licht-) Stromkreise2022-04-05T00:00:00+00:002022-04-05T00:00:00+00:00/allOut4eltakos_de<p>Der Artikel beschreibt eine Lösung für “Alle-Lichter-Aus”-Schalter (und
natürlich auch “Wieder-An” für größere Räumlichkeiten. Die
Besonderheit liegt darin, dass Der “Alles-Aus”-Zustand durch
Betätigung <strong>jedes</strong><!--more--> Lichtschalters beendet
wird. Dies wird mit minimalem Zusatzaufwand zum
konventionellen Ansatz erreicht.</p>
<h2 id="schalten-mit-tastern-und-stromstoßrelais">Schalten mit Tastern und Stromstoßrelais</h2>
<p>Wenn mehrere Schalter für Lichtstromkreise gefordert sind, ist der Einsatz
von Tastern und Stromstoßrelais – vulgo Eltakos – häufig <a href="/assets/images/postEltako/eltako1.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/eltako1-sm.jpg" width="327" height="189" title="Licht mit Strom­stoß­re­lais; click: groß" alt="Licht mit Eltako" class="imgonright" /></a>
die unaufwändigere Lösung im Vergleich zu Wechsel- oder gar Kreuzschaltungen.</p>
<p>Außerdem kann der (elektromechanische) Eltako ohne weitere Modifikationen
durch einen (elektronischen) Dimmer ersetzt werden. Dieser ist dann auch
von mehreren Stellen aus bedienbar. <a href="/assets/images/postEltako/eltako2.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/eltako2-sm.jpg" width="327" height="168" title="Licht mit Strom­stoß­re­lais; click: groß" alt="Licht mit Eltako" class="imgonleft" /></a>
Dies ist mit Standard-Dimmern i.a.
nicht realisierbar.</p>
<p>Anstelle von gegen L schaltenden Tastern der ersten Schaltung (rechts) kann
man auch gegen N schaltende Taster (2. Schaltung, links) einsetzen.
Dieser Ansatz spart i.A. Aufwand bei Verdrahtung und Verkabelung und man
gewinnt Flexibilität. Dies gilt insbesondere bei ausgedehnten Räumlichkeiten
mit zahlreichen Schaltstellen und Lichtkreisen – vor allem, wenn diese auch
noch zu unterschiedlichen Stromkreisen / Sicherungsautomaten / Phasen
gehören. <br />
Hinweis: In dem Falle müssen dann aber alle betreffenden Lichtstromkreise am
selben (oder an keinem)
<abbr title="Fehlerstrom, engl. RC(D)">FI</abbr>-Schutzschalter
hängen.<br clear="left" /></p>
<h2 id="zusätzliche-forderung-alles-aus-tasten">Zusätzliche Forderung “Alles-Aus”-Tasten</h2>
<p>Insbesondere bei großen Räumlichkeiten werden manchmal und dann i.A.
an den Ausgangstüren zusätzliche Taster gefordert, die alle Lichter
ausschalten. Über einen zusätzlichen Eltako ist das einfach zu
realisieren. Dieses “Alles Aus”-Stromstoßrelais unterbricht alle
Lichtstromkreise (das L zu den Eltakos vgl. oben) entweder selbst
oder über ein zusätzliches “Ausschalt”-Relais mit einer passenden
Anzahl von (Ruhe- oder Wechsel-) Kontakten mit hinreichender Belastbarkeit.</p>
<p>Erneutes Drücken einer “Alles-Aus”-Taste beendet den Zustand “Alles-Aus”.
Es sind also auch “Wieder-An”-Tasten.</p>
<h2 id="weitere-forderung-wieder-an-mit-jeder-taste">Weitere Forderung “Wieder An” mit jeder Taste</h2>
<p>Die einfache “Alles-Aus”-Lösung hat folgende Konsequenz: <br />
Falls jemand beim Verlassen die “Alles-Aus”-Taste betätigt, kann eine
unbemerkte Person im Dunkeln zurück bleiben. Diese müsste dann eine solche
Taste oder wenigstens einen Ausgang finden. Unter diesem Aspekt kam in
einem Projekt die Forderung auf, dass <strong>jede</strong> “normale” Taste von
<strong>jedem</strong> Lichtkreis den Zustand “Alles Aus” zurück setzt. Den nächstgelegenen
oder zuletzt selbst betätigten Lichtschalter bzw. irgendeinen findet man
bei schlechten Sichtverhältnissen ja leichter und mit weniger Gefahr. Ein
solches Funktionsmerkmal (feature) kann also einen Sicherheitsgewinn
bedeuten.</p>
<p>Das feature bringt aber auch einfach Komfort und vermeidet zusätzlichen
Erklärungsbedarf gegenüber Besuchern: “Wenn Du
einen Lichtschalter betätigst und Nichts passiert, musst Du zu einem
dieser Schalter gehen und …”</p>
<p>Also “Wieder An” mit jeder Taste? Bei einem gegebenen Ansatz mit Relais
ist man geneigt, dies (ohne
<abbr title="speicherprogrammierbare Steuerung">SPS</abbr> oder
<abbr title="Mikro-Controller">µC</abbr>-Einsatz) als
undurchführbar abzulehnen. Es gibt aber eine überraschend einfache Lösung.</p>
<h2 id="komfortables-wieder-an--die-lösung-mit-relais">Komfortables “Wieder An” – die Lösung mit Relais</h2>
<p>Sie benötigt lediglich ein zusätzliches Relais sowie die doppelte Anzahl an
(Wechsel-) Kontakten beim Ausschaltrelais. Wenn alle Eltakos <a href="/assets/images/postEltako/allOffLogic.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/allOffLogic-sm.jpg" width="532" height="252" title="Relaislogik komfortables Alles Aus; click: groß" alt="Alles aus mit Komfort" class="imgonright" /></a>
in einer Verteilung untergebracht sind – was bei der hier ins
Auge gefassten Größe der Anlage die Regel sein wird – fällt praktisch
kein erhöhter Verdrahtungsaufwand an.<br />
Hinweis: Klicken Sie auf das Bild für eine große Variante in einem anderen
Fenster oder “Tab”.</p>
<p>Das Betätigen einer Alles-Aus-Taste (“All off” im Stromlaufplan) ändert den
Zustand eine eines Eltakos (“all off latch”), der im Zustand “gesetzt”
das Alles-Aus-Relais (all off relay) einschaltet. Dies unterbricht mit einem
Wechselkontakt (erster von rechts) die L-Versorgung der Kontakte der
betreffenden “Licht-Eltakos”. Mit der
<abbr title="normally open; Arbeitskontakt">NO</abbr>-Seite
dieses Kontakts kann man ein Nachtlicht / Orientierungslicht versorgen.<br />
Für die einfache “Alles-Aus”-Funktion wäre das schon Alles.</p>
<p>Der zweite Wechselkontakt schaltet die L-Versorgung der Spulen der
betreffenden “Licht-Eltakos” vom “Kontakt-L” auf eine Leitung (button pushed
when all out) zu dem einem Extra-Relais (“on again sense relay” im Stromlauf)
um. <br />
Hinweis: Die Trennung der L-Versorgung der Spulen erfolgt bewusst über zwei
hintereinander geschaltete Kontakte, da die Umschaltung auf die selbe Leitung
/ dasselbe Relais auch für andere Lichtgruppen (im Stromlauf links angedeutet)
erfolgt, die zu anderen Sicherungsautomaten und ggf. auch Phasen gehören.</p>
<p>Bei Betätigung eines beliebigen Licht-Tasters wird nun das Extra-Relais
(“on again sense relay”) betätigt, welches mit seinem Arbeitskontakt den
Alles-Aus-Eltako (“all off latch”) betägtigt – und in diesem Zustand
zurücksetzt. Damit fällt das Alles-Aus-Relais (all off relay) ab und als
unmittelbare Folge auch das “sense relay”.</p>
<p>Der potentiell kritische Teil dieses Ansatzes ist, dass beim geschilderten
“Wieder-Alles-An”-Vorgang das sog. “sense”-Relais (Eltako R12-100) und ein
Stromstoßrelais (Eltako S12-100) hintereinander geschaltet an 230 V~
liegen. Beide haben eine Nennspulenspannung von 230V, die sie nicht wirklich
benötigen – die halbe Spannung (115 V) genügt aber nicht.<br />
Es funktioniert trotzdem zuverlässig, da der S12-110 bei Nennspannung
den doppelten Strom (ca. 25mA) zieht und somit bei der Reihenschaltung
nur 1/3 der Spannung bekommt (und sich so nicht bewegt).</p>
<p>Die Befürchtung, dass elektronische Relais und Dimmer mit
potentialfreier sog. Universal-Steuerspannung 8..230 V hier nicht
funktionieren würden, erwies sich als unbegründet. Die haben eine
Einschaltstromspitze von deutlich über 30mA und das
“sense”-Relais in Reihe zieht zuverlässig an. Die oben
genannte problemlose Austauschbarkeit ohne
Funktionsverlust von elektromechanischem Eltako und
elektronischem bleibt gegeben.<br clear="right" /></p>
<h2 id="der-aufbau-in-einem-schaltschrank">Der Aufbau in einem Schaltschrank</h2>
<p><a href="/assets/images/postEltako/schaltSchrGes.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/schaltSchrGes-sm.jpg" width="285" height="429" title="Im Schaltschrank; click: groß" alt="Aufbau gesamt" class="imgonleft" /></a>
Im realisierten Projekt “wohnt” das Ganze gut passend und handhabbar in
einem Standard-Verteiler (Hager), der oben um eine zusätzliche Hutschiene
ergänzt wurde.</p>
<p>1. Hutschiene: <br />
Rangierfeld Lampen</p>
<p>2. Hutschiene: <br />
Ausschaltrelais 4*Um mit roter LED <br />
bzw. seine Fassung<br />
Netzteil für Türsprechanlage (hier unbeteiligt)</p>
<p>3. Hutschiene: <br />
Die Relais</p>
<p>4. Hutschiene: <br />
Rangierfeld Taster <br />
Zwei Schalter (hier unbeteiligt)<br clear="left" /><a href="/assets/images/postEltako/schaltSchrDet.jpg" title="click: groß" target="_blank"><img src="/assets/images/postEltako/schaltSchrDet-sm.jpg" width="327" height="254" title="Aufbau im Detail; click: groß" alt="Aufbau im Detail" class="imgonright" /></a></p>
<h2 id="aufbau-im-detail">Aufbau im Detail</h2>
<p>Die 12 Relais auf der 3. Hutschiene sind:</p>
<ul>
<li>5 Eltakos für Lichtstromkreise Raum A</li>
<li>Das oben sogenannte “sense”-Relais</li>
<li>Der “Alles-Aus”-Eltako (all out latch)</li>
<li>5 Stromstoßschalter *) für Lichtstromkreise Raum B</li>
</ul>
<p><strong>__</strong>___ <br />
Anm. *): Der weiße “Nicht-Eltako” wurde inzwischen gegen einen blauen
“Richtigen” getauscht.</p>Albrecht WeinertDer Artikel beschreibt eine Lösung für “Alle-Lichter-Aus”-Schalter (und natürlich auch “Wieder-An” für größere Räumlichkeiten. Die Besonderheit liegt darin, dass Der “Alles-Aus”-Zustand durch Betätigung jedes4 switches on 2 lines2022-04-05T00:00:00+00:002022-04-05T00:00:00+00:00/4switchesOn2Lines<p>The <a href="4switchesOn2Lines_de.html" title="4 Schalter an 2 Leitungen">German article</a>. <br />
Sorry for having no English version; my “electric English” is
too<!--more--> poor to avoid miss-understanding. <br />
Even when understanding quite few of the
<a href="4switchesOn2Lines_de.html">German text</a> the diagrams might, hopefully,
be self explaining.</p>Albrecht WeinertThe German article. Sorry for having no English version; my “electric English” is tooNew fixture for Bosch PMF 250 CES2022-03-11T00:00:00+00:002022-03-11T00:00:00+00:00/boschPMFrepair<p>Since years I use a Bosch multi function power tool PMF 250 CES.
Recently the fixture for the vibration tool broke. Neither<!--more--><a href="\assets\images\postTooltime\pmf250ces.jpg" title="click: large" target="_blank"><img src="\assets\images\postTooltime\pmf250cesKl.jpg" width="442" height="128" title="Bosch PMF 250 CES; click: large image" alt="Bosch PMF 250 CES" class="imgonright" /></a>
the spare part nor a new Bosch machine with the same kind of fixture
are available. <br />
This renders a whole (expensive) collection of tools useless. <a href="\assets\images\postTooltime\pmf250cesSchaden.jpg" title="click: large" target="_blank"><img src="\assets\images\postTooltime\pmf250cesSchadenKl.jpg" width="180" height="128" title="PMF 250 CES damage (broken dents); click: large image" alt="Bosch PMF 250 CES dents broken" class="imgonleft" /></a></p>
<p>The <a href="boschPMFrepair_de.html" title="Sorry no full Engish text">German post</a>
describes a repair – or modification to be precise – solving
the problem. <br />
Sorry for having no English version; my tool time English is too poor.<br />
Even when understanding quite few of the
<a href="boschPMFrepair_de.html">German text</a> the pictures might, hopefully,
be self explaining.</p>Albrecht WeinertSince years I use a Bosch multi function power tool PMF 250 CES. Recently the fixture for the vibration tool broke. NeitherNeue Halterung für Bosch PMF 250 CES2022-03-11T00:00:00+00:002022-03-11T00:00:00+00:00/boschPMFrepair_de<p>Seit vielen Jahren tut ein Bosch Multifuktionswerkzeug
<abbr title="power multi function">PMF</abbr> 250 CES
mit Schubladenköfferchen und vielem Säge- Schab-
und Schleifzubehör gute<!--more--> <a href="\assets\images\postTooltime\pmf250ces.jpg" title="click: groß" target="_blank"><img src="\assets\images\postTooltime\pmf250cesKl.jpg" width="442" height="128" title="Bosch PMF 250 CES; click: groß" alt="Bosch PMF 250 CES" class="imgonright" /></a>
Dienste. Bei Wohnungsrenovierungen
wurde es u.a. zum Fliesen ablösen intensiv eingesetzt.</p>
<h2 id="der-konstruktionsfehler">Der Konstruktionsfehler</h2>
<p>Die <a href="\assets\images\postTooltime\pmf250cesFehler.jpg" title="click: groß" target="_blank"><img src="\assets\images\postTooltime\pmf250cesFehlerKl.jpg" width="285" height="195" title="PMF 250 CES Konstruktionsfehler; click: groß" alt="Bosch PMF 250 CES Konstruktionsfehler" class="imgonleft" /></a>
Konstruktion der Werkzeughalterung nervte von Anfang an. Wie man
(insbesondere nach drauf klicken auf dem
vergrößerten Bild) unschwer erkennt, erfasst der exzentrische Haken
nur ein oder zwei dünne
Blechzüngchen des Werkzeugs. Mit der (gewollten) Vibration hat das von
Anfang an nie gut gehalten, und teilweise ist das betroffene Zünglein
gebrochen.</p>
<h2 id="der-schaden">Der Schaden</h2>
<p><a href="\assets\images\postTooltime\pmf250cesSchaden.jpg" title="click: groß" target="_blank"><img src="\assets\images\postTooltime\pmf250cesSchadenKl.jpg" width="180" height="128" title="PMF 250 CES Zahnausfall; click: groß" alt="Bosch PMF 250 CES Zahnausfall" class="imgonright" /></a> Bei einer größeren Hausrenovierung
und Einsatz mit etwas Kraft und in
fremder Hand passierte es: Es brach nichts am Werkzeug – eh ein
Verschleißteil – sondern einige Stifte / Zähnchen an
der Werkzeughalterung.</p>
<p>Die Werkzeuge waren nun nur noch in ungewöhnlichen und praktisch
nie gebrauchen Winkeln anbringbar. D.h. die Maschine war kaputt.<br />
Nach mehreren Reparaturen von Bosch-Geräten sollte das
kein Problem sein: Maschinchen auseinander nehmen, kleinste kaputte Einheit
amputieren, Ersatzteil bestellen, …</p>
<h2 id="kein-ersatz">Kein Ersatz</h2>
<p>Nun war es schon öfter ärgerlich, dass es keine vollständige deutsche
Online-Quelle für Bosch-Ersatzteile – möglichst mit
1-Tag-Lieferung – gibt. Zuweilen wird man nur bei ausländischen
Händlern mit teilweise wochenlanger Lieferzeit fündig. Immerhin wird dies
bei der Bestellung schon angekündigt.</p>
<p><a href="\assets\images\postTooltime\pmf220CE_starlock.jpg" title="click: groß" target="_blank"><img src="\assets\images\postTooltime\pmf220CE_starlockKl.jpg" width="180" height="128" title="PMF 220 CE Starlock; click: groß" alt="Bosch PMF PMF 220 CE Starlock" class="imgonleft" /></a> Bei diesem Teil mit Zahnausfall
meldeten alle gefundenen deutschen und ausländischen Händler:
Teil nicht lieferbar! Es war immer auf der
Explosionszeichnung mit Teilenummer auffindbar.</p>
<p>Das gleiche Gerät nochmal neu kaufen ist auch nicht möglich, denn alle
derzeitigen “PMFs” haben eine inkompatible bessere Werkzeughalterung,
genannt “Starlock”. Werkzeuge werden von nun an nur noch für die neue
Maschine gekauft.</p>
<p>Der Verlust der vielen z.T. noch neuen Werkzeuge nach
altem System wäre aber sehr ärgerlich, da ihr Wert (die Preise sind ja
teilweise unverständlich hoch) den Neuwert beider Maschinen übersteigt.</p>
<h2 id="die-reparatur-bzw-modifikation">Die Reparatur bzw. Modifikation</h2>
<p><a href="\assets\images\postTooltime\pmf250cesReparatursatz.jpg" title="click: groß" target="_blank"><img src="\assets\images\postTooltime\pmf250cesReparatursatzKl.jpg" width="285" height="125" title="PMF 250 CES Konstruktionsfehler; click: groß" alt="Bosch PMF 250 CES Konstruktionsfehler" class="imgonright" /></a>
Eine Reparatur ohne das abgekündigte Ersatzteil ist also wünschenswert,
und sie ist – siehe Bild – einfach.</p>
<p>Man benötigt jeweils eine</p>
<ul>
<li>Imbusschraube – Zylinderkopf, Edelstahl,
Teilgewinde – M6 x 65 (~0,60€)</li>
<li>Unterlegscheibe 6 x 18</li>
<li>Unterlegscheibe 8 x 24</li>
<li>Unterlegscheibe dto. aus weichem Kunststoff</li>
</ul>
<p><a href="\assets\images\postTooltime\pmf250cesModifiziert.jpg" title="click: groß" target="_blank"><img src="\assets\images\postTooltime\pmf250cesModifiziertKl.jpg" width="285" height="173" title="PMF 250 CES modifiziert; click: groß" alt="Bosch PMF 250 CES modifiziert" class="imgonleft" /></a> Die Kunststoffscheibe benötigt man, wenn
das Halteblech des Werkzeugs dünner ist als die Zähnchenhöhe. Man kann
sie auch mit einer Lochsäge aus geeignetem Material (Frischhaltedose)
herstellen.</p>
<p>Das Werkzeug wird nun in der gewünschten Lage auf die Zähnchen gesetzt und
die Schraube zunächst von Hand oder mit passendem Imbusschlüssel angezogen.
Richtig fest presst man das Werkzeug dann wie gewohnt mit dem
Hebelmechanismus an. Trotz fehlender Zähnchen sitzen alle Werkzeuge besser
als je zuvor.</p>
<p>Übrigens: Für diese Modifikation musste man die Maschine nicht
auseinander nehmen.</p>Albrecht WeinertSeit vielen Jahren tut ein Bosch Multifuktionswerkzeug PMF 250 CES mit Schubladenköfferchen und vielem Säge- Schab- und Schleifzubehör guteWeb hyphenation2021-07-16T00:00:00+00:002021-07-16T00:00:00+00:00/webHyphenation<p>As became clear from from the posts <a href="/twoJekyllTricks.html">Jekyll Tricks</a>
and <a href="/leaveTypo3.html" title="Out of Typo3">Dispose of Typo3</a> I
am a strong proponent of static web sites generated with tools.</p>
<p>I’ve used static site generation for over twelve years with
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>
based <!--more-->tools. 2019 I switched my web sites as well as those I’m in
charge of to Jekyll / Liquid.</p>
<h2 id="hyphenation">Hyphenation</h2>
<p>A generous dose of conditional or soft hyphens (<code>"&shy;"</code>)
on the site’s texts can greatly enhance the appearance especially with
variable sizes and menus. On the other hand, putting the “&shy;s” in
by hand is troublesome and the spoils the readability for the
developer or author. Some tool support or automatism would be welcome.</p>
<p>But alas, for many tools and editors, hyphenation is no bright story
even when the language is mere English – and Jekyll is no exception here. <br />
This post presents a tool able to add conditional (“soft” &shy;)
breaks to the (markdown) texts and (html) layouts or to remove them for sake
of source readability.</p>
<p>All needed is an actual (implementation version >= 1.21.06)
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a> best as
installed extension on a Java8 and an hyphenation definition file in the
form of
<a href="https://weinert-automation.de/software/jekyll/hyphDef_de.txt" title="actual version, German, UTF8" target="_blank">this example</a>,
appropriate for your texts’ topic and language.</p>
<p>For all that follows you need the tool
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>. <br />
If you can start it to see the online help e.g. by one of the following
commands you got it perfectly.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java de.frame4j.FuR <span class="nt">-help</span> <span class="nt">-de</span> <span class="c"># show help in German (de)</span>
java FuR <span class="nt">-help</span> <span class="nt">-de</span> <span class="c"># show help with comfort starter in English</span>
</code></pre></div></div>
<h2 id="definition-file">Definition file</h2>
<p>The excerpt of the hyphenation
<a href="https://weinert-automation.de/software/jekyll/hyphDef_de.txt" title="actual version, German, UTF8" target="_blank">definition file </a>
shows the “one word per line with the hyphenation wanted” grammar:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="c1"># Definitions for [de-]hyphenation by de.frame4j.FuR</span>
<span class="c1"># A collection for German language for markdown texts and </span>
<span class="c1"># Jekyll web layouts. This file's encoding is UTF-8.</span>
<span class="c1"># Copyright 2021 Albrecht Weinert a-weinert.de</span>
<span class="c1"># $Revision: 58 $ # $Date: 2021-07-08 $)</span>
<span class="nn">---</span>
Aus<span class="ni">&shy;</span>bil<span class="ni">&shy;</span>dungs<span class="ni">&shy;</span>tag
Aus<span class="ni">&shy;</span>dauer
aus<span class="ni">&shy;</span>ge<span class="ni">&shy;</span>nom<span class="ni">&shy;</span>men
Be<span class="ni">&shy;</span>rufs<span class="ni">&shy;</span>wahl<span class="ni">&shy;</span>messe
Blu<span class="ni">&shy;</span>men<span class="ni">&shy;</span>ge<span class="ni">&shy;</span>stecke
dem<span class="ni">&shy;</span>sel<span class="ni">&shy;</span>ben
elek<span class="ni">&shy;</span>tro<span class="ni">&shy;</span>ni<span class="ni">&shy;</span>sches
Ent<span class="ni">&shy;</span>scheidungen
ent<span class="ni">&shy;</span>wor<span class="ni">&shy;</span>fen
er<span class="ni">&shy;</span>hielt
Er<span class="ni">&shy;</span>zie<span class="ni">&shy;</span>hungs<span class="ni">&shy;</span>be<span class="ni">&shy;</span>rech<span class="ni">&shy;</span>tigte
... and so on and so forth
</code></pre></div></div>
<p>For better readability – and for giving the file to a linguist for
checking / correcting – use the tool FuR to replace
<code>&shy;</code> by <code>-</code>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>D:<span class="se">\e</span>clips...>java FuR hyphDef_de.txt <span class="nt">-omitFrntM</span> <span class="s2">"&shy;"</span> <span class="s2">"-"</span>
D:<span class="se">\e</span>clipse18-09WS<span class="se">\w</span>eb-hansibo<span class="se">\f</span>actory<span class="se">\h</span>yphDef_de.txt
157 occurrences of search texts
</code></pre></div></div>
<p>The first parameter names the (only one in this case) file to work on, the
option <code>-omitFrntM</code> says “Don’t touch a front matter” and the
second and third parameter define the pattern to find and its replacement.
The result is</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="c1"># Definitions for [de-]hyphenation by de.frame4j.FuR</span>
<span class="c1"># A collection for German language for markdown texts and </span>
<span class="c1"># Jekyll web layouts. This file's encoding is UTF-8.</span>
<span class="c1"># Copyright 2021 Albrecht Weinert a-weinert.de</span>
<span class="c1"># $Revision: 58 $ # $Date: 2021-07-08 $)</span>
<span class="nn">---</span>
Aus-bil-dungs-tag
Aus-dauer
aus-ge-nom-men
Be-rufs-wahl-messe
Blu-men-ge-stecke
dem-sel-ben
elek-tro-ni-sches
Ent-scheidungen
ent-wor-fen
er-hielt
Er-zie-hungs-be-rech-tigte
... and so on and so forth
</code></pre></div></div>
<p>After having done the copy editing in this form do not forget to restore
the form usable for [de-] hyphenation by</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>D:<span class="se">\e</span>clips...>java FuR hyphDef_de.txt <span class="nt">-omitFrntM</span> <span class="s2">"-"</span> <span class="s2">"&shy;"</span>
D:<span class="se">\e</span>clipse18-09WS<span class="se">\w</span>eb-hansibo<span class="se">\f</span>actory<span class="se">\h</span>yphDef_de.txt
157 occurrences of search texts
</code></pre></div></div>
<p>Except for the interchange of search pattern and replacement it is the same
as for the other way round. But here the option <code>-omitFrntM</code> is
crucial lest to spoil the file’s starting comment.</p>
<h2 id="hyphenate-jekylls-markdown">Hyphenate Jekyll’s markdown</h2>
<p>To hyphenate a Jekyll generated web site best go to respective sources
root by <br />
<code> cd /D D:\eclipse18-09WS\web-hansibo\hansiboDE </code>
, e.g.</p>
<p>For an realistic examples sake I assume we want to add hyphenation to
all texts (extension .md for markdown) as well as to all Liquid templates
(extension .html or .htm as not to confuse them with “real” pure HTML).
We want do do this recursively in all sub directories excluding
<code>.jekyll-cache</code>, <code>_data</code> and <code>_site</code>.</p>
<h3 id="step-0-remove-all-shys">Step 0: Remove all &shy;s</h3>
<p>Before inserting &shy;s according to your favourite hyphenation
definition file you might remove all &shy;s randomly inserted by hand.
At the root of the site’s Jekyll sources <br />
<code> java FuR -r .md;.html;.htm -filUTF8 -OmitDirs _site;.jekyll-cache;_data -omitFrntM </code>&shy<code>;" -v</code><br />
would do the trick. <br />
<code>FuR: </code> The top most liked / used applications in
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a> have a
starter application in the unnamed package. <code>FuR</code> just delegates
to
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>. <br />
<code>-r .md;.html;.htm -filUTF8 : </code> Recursively (from the
current directory) visit all files of the given three extensions and assume
their encoding be UTF-8. <br />
<code>-OmitDirs _site;.jekyll-cache;_data : </code> While visiting the
sub-directory tree (starting from . ) omit directories + their children
with the three names given.
<code>-omitFrntM : </code> In the (text) files visited omit a front matter in
the process of searching patterns and replacing their occurrences. <br />
<code>"&shy;" </code> (and no further parameter): Search the
pattern <code>&shy;</code> and replace it by nothing.
<code>-v : </code> verbose output (optional). That option list all files
visited with the number of finds (and replaces).</p>
<h3 id="step-1-hyphenate-by-definition-file">Step 1: Hyphenate by definition file</h3>
<p>Using the same file and directory criteria as in the “Step 0” example
and being in the same directory the command is: <br />
<code> java FuR -r .md;.html;.htm -filUTF8 -OmitDirs _site;.jekyll-cache;_data -omitFrntM -hyphen ..\factory\hyphDef_de.txt</code></p>
<p><code>-hyphen ..\factory\hyphDef_de.txt </code> hyphenate all files in
question by the definitions found in the file (<code>hyphDef_de.txt</code)
named after the option.
all other options and parameters: As explained for "Step 0".</code></p>
<p>To hyphenate a single file use: <br />
<code> java FuR -omitFrntM -hyphen C:\wherItIs\hyphDef_de.txt -filUTF8 singleFile.md</code></p>
<p>Technically for every line in the hyphenation file FuR generates a
search pattern (without the <code>&shy;</code>s) and a replacement (with
them). Then in a wide sense the same procedures are taken as when defining
multiple search and replace definitions in an extra .properties file – which
over the years was FuR’s primary work on servers.</p>
<p>Note 1: At present (19.07.2021)
up to 1024 search and replace definitions are generated from the hyphenation
definition file (may be risen in future). <br />
Note 2: Those past and present n patterns * m files task with those numbers
in order of 100s and 1000s would not go well with Java’s standard String
search. As other
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a> tools
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>
uses
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>’s
implementation of the Rabin-Karp algorithms. Rabin-Karp brings the search
from O(t*s) (naive String.indexOf() and consorts) to less than O(t), where
t is the length of the text and s is length of the substring to spot. <br />
Note 3: Step 1 is the main step – the one where all this was done for. We
generate and (ftp) deploy web sites by Jekyll on the SVN (subversion) server
in a post commit hook. And we very well may put <code>FuR -hyphen ...</code>
there.</p>
<h3 id="step-2-de-hyphenate-by-definition-file">Step 2: De-Hyphenate by definition file</h3>
<p>With a command very similar to the one in “Step 1” FuR can remove (only)
the hyphenations applied: <br />
<code> java FuR -r .md;.html;.htm -filUTF8 -OmitDirs _site;.jekyll-cache;_data -omitFrntM -dehyphen ..\factory\hyphDef_de.txt</code></p>
<p><code>-dehyphen ..\factory\hyphDef_de.txt </code> de-hyphenate all files in
question by the definitions found in the file (<code>hyphDef_de.txt</code>)
named after the option. The procedure is the same as explained ion “Step 1”
except for the reversal of the find pattern and the replacement. <br />
all other options and parameters: As explained for “Step 0”.</p>
<p>To de-hyphenate a single file use: <br />
<code> java FuR -omitFrntM -dehyphen C:\wherItIs\hyphDef_de.txt -filUTF8 singleFile.md</code></p>
<p>Applying “Step 1” to a set of “hyphen-less” (by “Step 0”, e.g.) files and
then applying “Step 2” should bring the set of files respectively texts
back in the previous state – or in other word one operation is the inverse
of the other.<br />
Note 4: Be aware of shadowing effects especially with compound words like
(German) runter, gekommen und runtergekommen that would be defined as e.g.</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>run<span class="ni">&shy;</span>ter<span class="ni">&shy;</span>ge<span class="ni">&shy;</span>kom<span class="ni">&shy;</span>men
run<span class="ni">&shy;</span>ter
ge<span class="ni">&shy;</span>kom<span class="ni">&shy;</span>men
kom<span class="ni">&shy;</span>men
</code></pre></div></div>
<p>If you change the order here by, e.g., setting <code>"kom&shy;men"</code>
(kommen) before the others, this would inhibit the extra hyphenations
of gekommen and runtergekommen. <br />
Note 5: As
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>
reverses the order of find and replace on <code>-dehyphen</code> to the one
used for <code>-hyphen</code> the “inverse operation” property should hold.
Note 6: When writing or editing a hyphenation definition file always have
<code>-hyphen</code> in mind. Rule of thump: compounds and longer words
one gets by adding to shorter ones first.</p>
<p>Mathematical question to the learned readers: <br />
Would just length on the non hyphenated word be the right sorting criterion?</p>
<p>Well, as I think the the answer is Yes. Hence, since 31.07.2021 (resp.
Implementation-Version 1.21.07) FuR will sort the hyphenation definitions
accordingly before use. <br />
Note 7: If you use this
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>
version or a newer one (and don’t switch off this
sorting) you may ignore Note 4 and 6.</p>
<p>Happy automatic hyphenation.</p>Albrecht WeinertAs became clear from from the posts Jekyll Tricks and Dispose of Typo3 I am a strong proponent of static web sites generated with tools. I’ve used static site generation for over twelve years with Frame4 basedWeb-Silbentrennung2021-07-16T00:00:00+00:002021-07-16T00:00:00+00:00/webHyphenation_de<p>Die Leser von <a href="/twoJekyllTricks_de.html">Jekyll-Tricks</a> und
<a href="/leaveTypo3_de.html" title="Aus für Typo3">Fort von Typo3</a> wissen, dass ich
ein engagierter Befürworter der statischen Generierung von Web-Bereichen
bin. Über zwölf Jahre habe ich statische Generierung von Web-Bereichen mit
<a href="https://frame4j.de/index.html" title="ein Java (8) framework">Frame4</a>-<!--more-->Tools
betrieben. 2019 habe ich meine sowie die mir anvertrauten
Web-Bereiche auf Jekyll (/Liquid) umgestellt.</p>
<h2 id="silbentrennung">Silbentrennung</h2>
<p>Eine großzügige Dosis von von bedingten – oder “weichen” (soft) –
Trennstrichen (<code>"&shy;"</code>) kann das Erscheinungsbild eines
Webbereichs sehr verbessern insbesondere bei variablen Abmessungen und
abschaltbaren Menus. Andererseits ist das Einbringen der von “&shy;s”
mühselig und fehlerträchtig, und es beeinträchtigt die Lesbarkeit für
Entwickler und Autoren. Ein bisschen Werkzeugunterstützung und Automatismen
wären willkommen.</p>
<p>Aber die Silbentrennung ist leider für viele Werkzeuge und Editoren ein
eher düsteres Kapitel – und das oft selbst dann, wenn die Sprache
bloß Englisch ist. Jekyll mach da keine Ausnahme. <br />
Diese Beitrag zeigt ein Werkzeug, mit dem man die (markdown) Texte und
(html) layouts mit bedingten (“weichen” &shy;) Trennstrichen versehen
oder diese wieder entfernen kann.</p>
<p>Man benötigt lediglich ein aktuelles (implementation version >= 1.21.06)
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>, am besten
als “installed extension” unter Java8 sowie eine Definitionsdatei der
gewünschten Trennungen in einer einfachen Syntax gemäß
<a href="https://weinert-automation.de/software/jekyll/hyphDef_de.txt" title="die aktuelle Trennungsdatei" target="_blank">dieses Beispiels</a>,
passend zu Sprache und Themenbereichen Ihrer Texte.</p>
<p>Für alles Folgende brauchen Sie nur die Applikation
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>. <br />
Falls Sie diese mit einem der folgenden Kommandos zum Angucken der Hilfe
starten können, haben Sie es.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java de.frame4j.FuR <span class="nt">-help</span> <span class="nt">-de</span> <span class="c"># show help in German (de)</span>
java FuR <span class="nt">-help</span> <span class="nt">-de</span> <span class="c"># show help with comfort starter in English</span>
</code></pre></div></div>
<h2 id="die-trennungsdatei">Die Trennungsdatei</h2>
<p>Der Auszug aus der aktuellen
<a href="https://weinert-automation.de/software/jekyll/hyphDef_de.txt" title="UTF8, neuer Tab" target="_blank">Trennungsdatei</a>
Beispieldatei zeigt die
“ein Wort pro Zeile mit der gewünschten bedingten Trennung”-Grammatik:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="c1"># Definitions for [de-]hyphenation by de.frame4j.FuR</span>
<span class="c1"># A collection for German language for markdown texts and </span>
<span class="c1"># Jekyll web layouts. This file's encoding is UTF-8.</span>
<span class="c1"># Copyright 2021 Albrecht Weinert a-weinert.de</span>
<span class="c1"># $Revision: 58 $ # $Date: 2021-07-08 $)</span>
<span class="nn">---</span>
Aus<span class="ni">&shy;</span>bil<span class="ni">&shy;</span>dungs<span class="ni">&shy;</span>tag
Aus<span class="ni">&shy;</span>dauer
aus<span class="ni">&shy;</span>ge<span class="ni">&shy;</span>nom<span class="ni">&shy;</span>men
Be<span class="ni">&shy;</span>rufs<span class="ni">&shy;</span>wahl<span class="ni">&shy;</span>messe
Blu<span class="ni">&shy;</span>men<span class="ni">&shy;</span>ge<span class="ni">&shy;</span>stecke
dem<span class="ni">&shy;</span>sel<span class="ni">&shy;</span>ben
elek<span class="ni">&shy;</span>tro<span class="ni">&shy;</span>ni<span class="ni">&shy;</span>sches
Ent<span class="ni">&shy;</span>scheidungen
ent<span class="ni">&shy;</span>wor<span class="ni">&shy;</span>fen
er<span class="ni">&shy;</span>hielt
Er<span class="ni">&shy;</span>zie<span class="ni">&shy;</span>hungs<span class="ni">&shy;</span>be<span class="ni">&shy;</span>rech<span class="ni">&shy;</span>tigte
... und so weiter und so fort
</code></pre></div></div>
<p>Für eine bessere Lesbarkeit – und um die Datei der Germanistin Ihres
Vertrauens zur Korrektur zu geben – nutzen Sie das Tool FuR um
<code>&shy;</code> durch <code>-</code> zu ersetzen.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>D:<span class="se">\e</span>clips...>java FuR hyphDef_de.txt <span class="nt">-omitFrntM</span> <span class="s2">"&shy;"</span> <span class="s2">"-"</span>
D:<span class="se">\e</span>clipse18-09WS<span class="se">\w</span>eb-hansibo<span class="se">\f</span>actory<span class="se">\h</span>yphDef_de.txt
157 occurrences of search texts
</code></pre></div></div>
<p>Der erste Parameter benennt die (in diesem Fall einzige) zu bearbeitende
Datei. Die Option <code>-omitFrntM</code> sagt “Lass die Finger vom
sog. front matter”, während der zweite und dritte Parameter das
Suchmuster und und seinen Ersatz definieren. Das Ergebnis ist</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="c1"># Definitions for [de-]hyphenation by de.frame4j.FuR</span>
<span class="c1"># A collection for German language for markdown texts and </span>
<span class="c1"># Jekyll web layouts. This file's encoding is UTF-8.</span>
<span class="c1"># Copyright 2021 Albrecht Weinert a-weinert.de</span>
<span class="c1"># $Revision: 58 $ # $Date: 2021-07-08 $)</span>
<span class="nn">---</span>
Aus-bil-dungs-tag
Aus-dauer
aus-ge-nom-men
Be-rufs-wahl-messe
Blu-men-ge-stecke
dem-sel-ben
elek-tro-ni-sches
Ent-scheidungen
ent-wor-fen
er-hielt
Er-zie-hungs-be-rech-tigte
... und so weiter und so fort
</code></pre></div></div>
<p>Nach der in dieser Form durchgeführten Schlussredaktion vergessen Sie nicht
die fürs Einfügen und Entfernen von bedingten Trennungen verwendbare From
wieder herzustellen:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>D:<span class="se">\e</span>clips...>java FuR hyphDef_de.txt <span class="nt">-omitFrntM</span> <span class="s2">"-"</span> <span class="s2">"&shy;"</span>
D:<span class="se">\e</span>clipse18-09WS<span class="se">\w</span>eb-hansibo<span class="se">\f</span>actory<span class="se">\h</span>yphDef_de.txt
157 occurrences of search texts
</code></pre></div></div>
<p>Außer der Vertauschung von Suchmuster und Ersatz ist es dasselbe Kommando
wie eben. Nur so herum wird die Option <code>-omitFrntM</code> wichtig, da
man sonst die Kommentare am Anfang verdirbt.</p>
<h2 id="das-trennen-von-jekylls-markdown-quelltexten">Das Trennen von Jekylls markdown Quelltexten</h2>
<p>Um einen von Jekyll generierten Web-Bereich mit bedingten Trennungen zu
versehen, geht man am besten in’s Wurzelverzeichnis der betreffenden Quellen
mit beispielsweise <br />
<code> cd /D D:\eclipse18-09WS\web-hansibo\hansiboDE </code></p>
<p>In einem realistischen Beispiel würden wir zu allen Texten (Erweiterung
.md für markdown) ebenso wie zu allen Liquid templates (Erweiterung
.html oder .htm) bedingte Trennungen zufügen. Wir möchten dies auch in
allen Unterverzeichnissen tun, aber die Verzeichnisse
<code>.jekyll-cache</code>, <code>_data</code> and <code>_site</code>
und deren Unterverzeichnisse ausschließen.</p>
<h3 id="schritt-0-alle-bisherigen-shys-entfernen">Schritt 0: Alle bisherigen &shy;s entfernen</h3>
<p>Bevor wir &shy;s gemäß unserer Definitionsdatei einfügen, mag man meist
das bisher “Handgemachte” entfernen. Im erwähnten Wurzelverzeichnis der
der Jekyll-Quellen macht <br />
<code> java FuR -r .md;.html;.htm -filUTF8 -OmitDirs _site;.jekyll-cache;_data -omitFrntM </code>&shy<code>;" -v</code><br />
genau das. <br />
<code>FuR : </code> Die beliebtesten / am meisten genutzten
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>-Tools
haben eine Start-Applikation im unbenannten Verzeichnis. <code>FuR</code>
delegiert schlicht und einfach an
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>. <br />
<code>-r .md;.html;.htm -filUTF8 : </code> Rekursiv (vom aktuellen
Verzeichnis aus) besuche alle Dateien mit den gegebenen Endungen (Typen)
und nimm als deren Textkodierung UTF-8 an.
<code>-OmitDirs _site;.jekyll-cache;_data : </code> Beim Besuchen des (Unter-)
Verzeichnisbaums (bei . beginnend) lass die benannten Verzeichnisse und
ihre Kinder aus.
<code>-omitFrntM : </code> In den besuchten Textdateien ändere nichts an einem
ggf. “front matter” im Laufe des Findens und Ersetzens. <br />
<code>"&shy;" </code> (und kein weiterer Parameter): Suche das Muster
<code>&shy;</code> und ersetze es durch nichts.
<code>-v: </code> Ausführlichere Ausgaben (optional).</p>
<h3 id="schritt-1-trennungen-gemäß-der-definitionsdatei">Schritt 1: Trennungen gemäß der Definitionsdatei</h3>
<p>Unter Verwendung derselben Kriterien für Dateien und Verzeichnisse wie im
Beispiel “Schritt 0” ist der Befehl hierfür: <br />
<code> java FuR -r .md;.html;.htm -filUTF8 -OmitDirs _site;.jekyll-cache;_data -omitFrntM -hyphen ..\factory\hyphDef_de.txt</code></p>
<p><code>-hyphen ..\factory\hyphDef_de.txt </code> trenne alle betreffenden
Dateien bzw. Texte gemäß den Definitionen der nach der option genannten
Datei (<code>hyphDef_de.txt</code im Beispiel)..
alle anderen Optionen und Parameter: Wie für den "Schritt 0" erklärt.</code></p>
<p>Für Trennungen in einer einzelnen Datei verwende: <br />
<code> java FuR -omitFrntM -hyphen C:\wherItIs\hyphDef_de.txt -filUTF8 singleFile.md</code></p>
<p>Technisch gesehen erzeugt jede Zeile in der “Trennungsdatei” ein Suchmuster
(jeweils ohne die <code>&shy;</code>s) und einen Ersatztext (mit ihnen).
dann laufen im weitesten Sinne die gleichen Vorgänge ab, als hätte man mit
einer gesonderten .properties-Datei viele “Finde und ersetze”-Definitionen
vorgegeben – was über viele Jahre FuR’s Hauptbeschäftigung auf einigen
Servern war.</p>
<p>Anm. 1: Zur Zeit (19.07.2021) sind so bis 1024 Trennungsdefinitionen
möglich. (Könnte erhöht werden.) <br />
Anm. 2: Diese früheren und neuen Aufgaben mit n Mustern * m Dateien, wobei
diese Zahlen in der Größenordnung 100 bzw. 1000 (und mehr) liegen, würden mit
Javas String-Suche nicht so gut laufen. Wie auch andere
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>-Tools
nutzt auch
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>s
Implementierung der Rabin-Karp-Algorithmen. Rabin-Karp bringt die Suche
eines Sub-Texts in einem String von O(t*s) (naive String.indexOf()
und Konsorten) auf deutlich weniger als O(t), wobei t die Länge des Texts
und s die Länge des zu findenden Teiltexts ist. <br />
Anm. 3: Schritt 1 ist der wichtigste Vorgang – hierfür wurde diese
Erweiterung gemacht. Wir generieren Web-Bereich auf einem SVN-Server mit
Jekyll im post commit hook und verbreiten (deploy) sie dann (mit FTP) zum
jeweiligen Web-Server. Dieser “Schritt 1” wird Teil dieser post commit hooks
werden.</p>
<h3 id="schritt-2-die-trennungen-wieder-beseitigen">Schritt 2: Die Trennungen (wieder) beseitigen</h3>
<p>Mit einem ganz ähnlichen Kommando wie in “Schritt 1” kann FuR genau die dort
applizierten Trennungen entfernen: <br />
<code> java FuR -r .md;.html;.htm -filUTF8 -OmitDirs _site;.jekyll-cache;_data -omitFrntM -dehyphen ..\factory\hyphDef_de.txt</code></p>
<p><code>-dehyphen ..\factory\hyphDef_de.txt </code> beseitige die in der nach
Option genannten Trennungsdatei (<code>hyphDef_de.txt</code>) definierten
Trennungen.<br />
Alle anderen Optionen und Parameter: Wie in “Schritt 0” erklärt.</p>
<p>Für Beseitigung der Trennungen in einer einzelnen Datei verwende: <br />
<code> java FuR -omitFrntM -hyphen C:\wherItIs\hyphDef_de.txt -filUTF8 singleFile.md</code></p>
<p>Das Anwenden von “Schritt 1” und dann das Anwenden von “Schritt 2” auf
einen von vornherein (oder nach “Schritt 0”) “trennungslosen” Satz von
Dateien / Texten sollte diesen in den ursprünglichen
Zustand zurück versetzen. Oder mit anderen Worten: die eine Operation ist
die Inverse der anderen.</p>
<p>Anm. 4: Seien Sie sich gewisser “Abschattungseffekte” bewusst, insbesondere
bei Wortverbindungen, wie runter, gekommen und runtergekommen, deren
Trennungen beispielsweise so definiert würden:</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code>run<span class="ni">&shy;</span>ter<span class="ni">&shy;</span>ge<span class="ni">&shy;</span>kom<span class="ni">&shy;</span>men
run<span class="ni">&shy;</span>ter
ge<span class="ni">&shy;</span>kom<span class="ni">&shy;</span>men
kom<span class="ni">&shy;</span>men
</code></pre></div></div>
<p>Wenn Sie hier die Reihenfolge ändern und beispielsweise
<code>"kom&shy;men"</code> nach vorne setzten, würde dies alle weiteren
Trennungen bei <code>"gekommen"</code> und
<code>"runtergekommen"</code> verhindern. <br />
Anm. 5: Weil
<a href="https://weinert-automation.de/java/docs/frame4j/de/frame4j/FuR.html">de.frame4j.FuR</a>
die Reihenfolge der “Finden-und-ersetzen”-Aufträge
bei <code>-dehyphen</code> gegenüber derjenigen bei <code>-hyphen</code>
umkehrt, sollte die “inverse Operationen”-Eigenschaft zugesichert sein. <br />
Anm. 6: Wenn Sie “<a href="#die-trennungsdatei">Trennungsdateien</a>” schreiben oder
bearbeiten, haben Sie immer <code>-hyphen</code> auf dem Schirm.
Daumenregel: Zusammensetzungen und durch Vor- oder Nachsilben verlängerte
Worte nach vorn.</p>
<p>Mathematische Frage an die gelehrten Leser: Wäre ein Sortieren der
Trennungsdatei nach Wortlänge – ohne die <code>&shs;</code>s genommen
– hinreichend?</p>
<p>Ich denke die Anzwort ist “Ja”. Seit dem 31.07.2021 (bzw. der
Implementation-Version 1.21.07) sortiert FuR die Trennungsdefinitionen vorher
entsprechend. <br />
Anm. 7: Falls Sie diese oder eine neuere Version von
<a href="https://frame4j.de/index_en.html" title="a Java (8) framework">Frame4</a>
haben (und diese Sortierung nicht abschalten), mögen Sie die Anmerkungen 4
und 6 ignorieren.</p>
<p>Glückliche (automatische) Trennung</p>Albrecht WeinertDie Leser von Jekyll-Tricks und Fort von Typo3 wissen, dass ich ein engagierter Befürworter der statischen Generierung von Web-Bereichen bin. Über zwölf Jahre habe ich statische Generierung von Web-Bereichen mit Frame4-Raspberry Pi IO with Java2021-06-11T00:00:00+00:002021-06-11T00:00:00+00:00/raspiGPIOjava<p><a href="https://frame4j.de/index_en.html"><img src="/assets/icons_logos/frame4jlogo-02t.png" alt="Frame4J" title="> Frame4J" class="imgonright" height="40px" width="206px" /></a></p>
<h2 id="pi-io-and-process-control-with-c">Pi IO and process control with C</h2>
<p>The natural language for a small Linux controller, like a Raspberry Pi, is
C — especially when it comes to process control using Pi’s GPIO
<!--more-->(general purpose input and output) to control actuators
and read sensors. This we and others did with good success.
See the
<a href="https://a-weinert.de/pub/raspberry4remoteServices.pdf" title="Raspberry for remote services">publication</a>
or the
<a href="https://weinert-automation.de/svn/rasProject_01/" title="rasProject_0 (guest:guest)">SVN repo</a>.
One part of the success story is using Joan N.N.’s C
<a href="http://abyz.me.uk/rpi/pigpio/index.html">pigpio library</a> with its daemon/server approach.</p>
<h2 id="java-on-the-pi">Java on the Pi</h2>
<p>Nevertheless, some people would like to use Java on a Pi, too. That’s not a
problem. You can have a Java 8 on a Pi 3 and even have
<a href="https://frame4j.de/index_en.html" title="frame4j home (en)" class="bbi">Frame4J</a> installed and
enjoy all the tools etc.</p>
<p>Problems start — on any platform by the way — when wanting
process control with Java. To get the know how for Raspberry Pi I ported a
<a href="https://a-weinert.de/pub/raspberry4remoteServices.pdf" title="Raspberry for remote services">rasProject_01</a>
C demo program
<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/rdGnPiGpioDBlink.c" title="C GPIO demo">rdGnPiGpioDBlink.c</a>.
All of a sudden I had a growing
<a href="https://github.com/a-weinert/weAut/">project</a> and a German
<a href="https://a-weinert.de/publication_en.html">publication</a> on Java Magazin.</p>
<h2 id="native-jni-or-pure-java">Native (JNI) or pure Java</h2>
<p>The C program uses the
<a href="http://abyz.me.uk/rpi/pigpio/index.html">pigpio library</a> in the
daemon/server variant and a
Linux C lock file standard procedure to force control programs using process
IO (and optionally the Pi watch-dog) singleton, as well as shutdown hooks
to leave process IO in an inactive
safe state. The little demo shows process IO (by three LEDs) as well as
professional approaches. Well, the little demo does not use the watch-dog,
as do the real control programs. (See all in above mentioned
<a href="https://a-weinert.de/pub/raspberry4remoteServices.pdf" title="Raspberry for remote services">publication</a>).
<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/rdGnPiGpioDBlink.c" title="C GPIO demo">rdGnPiGpioDBlink.c</a>
with all its behaviour was ported to
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/RdGnPiGpioDBlink.html" title="RdGnPiGpioDBlink docu">RdGnPiGpioDBlink.java</a>
(<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/doc-files/RdGnPiGpioDBlink.java" title="RdGnPiGpioDBlink.java">source</a>).</p>
<p>For the IO part this very first port uses a part of Neil Kolban’s
<a href="https://github.com/nkolban/jpigpio" title="interface to pigpio[d]">library</a>
that also uses
<a href="http://abyz.me.uk/rpi/pigpio/sif.html" title="socket interface docu">pigpio’s</a>
socket interface. Hence we have all the advantages of
Joan N.N.’s <a href="http://abyz.me.uk/rpi/pigpio/index.html" title="pigpio library">approach</a>.
Additionally Neil Kolban’s
<a href="https://github.com/nkolban/jpigpio" title="interface to pigpio[d]">library</a>
includes among others also a JNI implementation plus its C layer for
pigpiod’s non socket interface pigpiod. These extras obfuscate and complicate
things a bit, and the library is nowhere written with the aspect of
avoiding throw away objects.</p>
<p>Considering that and some other points a compact pure Java solution
to connect to the pigpioD socket interface was implemented and – in between
– made an integral part of <a href="https://frame4j.de/index_en.html" title="frame4j home (en)" class="bbi">Frame4J</a>. That means
no matter if on a PC, Laptop, server or on a Pi one has Pi IO with Java –
be the IO on a PI (with the control application) itself or on any (other)
Pi in the same (private) [W]LAN. The application
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/TestOnPi.html" title="TestOnPi docu">TestOnPi</a>
let you show or test binary input and output,
<abbr title="pulse width modulation">PWM</abbr> and servos on all IO pins
of a Pi.</p>
<h2 id="side-problems-with-java-gpio-or-process-control">Side problems with Java GPIO or process control</h2>
<h3 id="incompatible-file-lock">Incompatible file lock</h3>
<p>An immediate <a href="javaIncompFlock.html" title="see also extra post">problem</a> that had
to be solved in the light of porting
“all its behaviour” was implementing the lock file approach (for singleton
use of process IO and watch-dog) established in all our control installations
with Raspberries and consorts. It turned out that locking a random access
file fully and exclusively with Java (java.nio.channels.FileLock) on a Linux
system is incompatible with Linux C file locking by flock() — the
standard approach on Linux. From all C programmes or program
instances (processes) competing for one lock file the first would win and
the others would have to end or wait. The same can be said of all Java
program instances using java.nio.channels.FileLock — but even if a
C program has a lock (flock()) on the very same file.</p>
<p>This violation of the singleton use of certain process resources when having control programs in Java, too, is, of course,
not acceptable. This problem had to be solved before releasing Java to a
real life control module. You can’t allow the process control program going in cyclic
run mode while a Java calibration / service application (e.g.) is touching
parts of the sensors or actuators.</p>
<p>The compatible solution are two lock methods (openLock() and closeLock) in
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/PiUtil.html" title="openLock() and closeLock()">Frame4J: de.weAut.PiUtil</a>
using a C helper program
<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/justLock.c">justLock</a>. Running this little program (<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/justLock.c">justLock</a>) directly and the
Java application <a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/JustNotFLock.html" title="de.weAut.demos.JustNotFLock">JustNotFLock</a> at the same time will demonstrate the double lock on the same file.</p>
<h3 id="throw-away-objects">Throw away objects</h3>
<p>With OO languages and Java the garbage collector is widely seen as a risk for a real time behaviour otherwise assessed theoretically and experimentally. A WG on automating critical processes with OO languages demanded no objects to be created while in cyclic run mode. Even if one would perhaps not be such strict, it is a good principle. It relieves you from the risks of garbage collection and of memory administration.</p>
<p>And all demo examples here and the corresponding Java applications adhere to it. Mutable classes are used instead of making new immutable objects, like StringBuilder en lieu de String and (own) Container classes instead of Long.</p>
<p>By constantly using mutable objects garbage collection and memory allocation etc. go out of the job. But, the widely used Linux approach “file as device” does not go well with Java. The listing (excerpt from
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/Pi1WireThDemo.html" title="de.weAut.tests.Pi1WireThDemo">Pi1WireThDemo</a>)
shows one reading of a 1-wire thermometer. They are available in a stainless casing, too, and, by standard dimensions, suitable for boilers, e.g..</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nc">String</span> <span class="n">line1</span><span class="o">;</span>
<span class="nc">String</span> <span class="n">line2</span><span class="o">;</span>
<span class="kd">final</span> <span class="nc">String</span> <span class="n">devID</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span> <span class="c1">// 28-02119245cd92 e.g.</span>
<span class="nc">BufferedReader</span> <span class="n">thermometer</span><span class="o">;</span>
<span class="nc">File</span> <span class="n">thermPath</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">File</span><span class="o">(</span>
<span class="s">"/sys/bus/w1/devices/w1_bus_master1/"</span> <span class="o">+</span> <span class="n">devID</span> <span class="o">+</span> <span class="s">"/w1_slave"</span><span class="o">);</span>
<span class="k">for</span><span class="o">(;</span><span class="n">runningOn</span><span class="o">;)</span> <span class="o">{</span> <span class="c1">// cyclic run mode</span>
<span class="n">thermometer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileReader</span><span class="o">(</span><span class="n">thermPath</span><span class="o">));</span>
<span class="n">line1</span> <span class="o">=</span> <span class="n">thermometer</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span>
<span class="n">line2</span> <span class="o">=</span> <span class="n">thermometer</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span>
<span class="c1">// Auswertung</span>
</code></pre></div></div>
<p>The 1-wire Linux device (as file) driver yields one reading as two text lines [sic!]. Having read them the file closes automatically. Hence, opening that file has to go in the endless loop, hinting the cyclic run mode. Every reading thus makes:</p>
<ul>
<li>1 BufferedReader,</li>
<li>1 FileReader and indirectly</li>
<li>1 FileInputStream,</li>
<li>1 FileDescriptor etc.
plus finally</li>
<li>2 String objects.</li>
</ul>
<p>We have at least, 6 objects per temperature reading. By using a byte array and spoiling all readability only the Reader and the Strings could be avoided. Of course, a thermometer would seldom be read more than once per second. But imagine such thing in a 10ms or in an 1ms cycle on a little (embedded) computer.</p>
<p>The Pi (BCM) watchdog, also implemented as device as file, is in this aspect much better: The dog — i.e. with Java his OutputStream — stays open for writing all the time. Here we are lucky. But, alas, we have no influence on device drivers deeply embedded in the OS.</p>
<h2 id="repositories">Repositories</h2>
<p>Find most of the sources on the GitHub repository
<a href="https://github.com/a-weinert/weAut/">weAut</a> which mirrors parts of the larger
<a href="https://weinert-automation.de/svn/" title="guest:guest">SVN development repositories</a>
essential for this project. For comments and
issues on <a href="https://github.com/a-weinert/weAut/">this project</a> use this
post’s comment function, which by the way is a GitHub issue.</p>Albrecht WeinertPi IO and process control with C The natural language for a small Linux controller, like a Raspberry Pi, is C — especially when it comes to process control using Pi’s GPIORaspberry Pi Ein- und Ausgabe mit Java2021-06-08T00:00:00+00:002021-06-08T00:00:00+00:00/raspiGPIOjava_de<p><a href="https://frame4j.de/index_en.html"><img src="/assets/icons_logos/frame4jlogo-02t.png" alt="Frame4J" title="> Frame4J" class="imgonright" height="40px" width="206px" /></a></p>
<h2 id="pi-io-und-prozesssteuerung-mit-c">Pi IO und Prozesssteuerung mit C</h2>
<p>Bei sehr kleinen Linux-Rechnern, wie einem Raspberry Pi, ist die Sprache
der Wahl C — besonders bei Prozesssteueranwendungen, welche z.B.
beim Pi die GPIO <!--more-->(general purpose input and output)
für Sensoren und Aktoren nutzen. So arbeiten wir und Andere mit gutem
Erfolg. Siehe auch die
<a href="https://a-weinert.de/pub/raspberry4remoteServices.pdf" title="Raspberry for remote services">Publikation</a>
oder das
<a href="https://weinert-automation.de/svn/rasProject_01/" title="rasProject_0 (guest:guest)">SVN repo</a>.
Erklecklichen Anteil am guten Gelingen hat die C-Bibliothek
<a href="http://abyz.me.uk/rpi/pigpio/index.html">pigpio</a> von Joan N.N..</p>
<h2 id="java-auf-dem-pi">Java auf dem Pi</h2>
<p>Nichtsdestotrotz möchten manche auf dem Pi auch Java nutzen. Das ist an sich
kein Problem. Man kann ein Java 8 auf einem Pi 3 und sogar mit
<a href="https://frame4j.de/index_en.html" title="frame4j home (en)" class="bbi">Frame4J</a> mit allen seinen
Tools und APIs ergänzen.</p>
<p>Der Spaß mit Java hört — übrigens auf jeder Plattform — auf, wenn
man Prozesssteuerung mit Java machen will. Um dies (d.h. auch die direkte
Ansteuerung von Aktoren und Sensoren mit Java) auf dem Pi zu lernen portierte
ich aus
<a href="https://a-weinert.de/pub/raspberry4remoteServices.pdf" title="Raspberry for remote services">rasProject_01</a>
ein C-Demoprogramm
<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/rdGnPiGpioDBlink.c" title="C GPIO demo">rdGnPiGpioDBlink.c</a>.
“Überraschenderweise” wurde daraus ein wachsendes Projekt
<a href="https://github.com/a-weinert/weAut/">Projekt</a> und eine
<a href="https://a-weinert.de/publication.html">Veröffentlichung</a> im Java Magazin.</p>
<h2 id="native-jni-oder-pure-java">Native (JNI) oder pure Java</h2>
<p>Dieses C-Programm nutzt die Bibliothek
<a href="http://abyz.me.uk/rpi/pigpio/index.html">pigpio</a> in der
Dämon/Server Variante und das Linux/C Standardvorgehen mit Sperrdateien (lock
files; flock()), um einen exklusiven (singleton) Zugang zu Prozess-IO und dem
Pi-watchdog für Steuerprogramme zu gewährleisten. Hinzu kommt immer eine
Abfahr-Routine (shutdown hook), welche die Ein- und Ausgabe in einem sicheren
Zustand hinterlässt. Das kleine Demo-Programm mit drei LEDs als Ausgabe zeigt
(außer dem watchdog) diese professionellen Ansätze. (Siehe hierzu Alles
in der erwähnten
<a href="https://a-weinert.de/pub/raspberry4remoteServices.pdf" title="Raspberry for remote services">Publikation</a>).
<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/rdGnPiGpioDBlink.c" title="C GPIO demo">rdGnPiGpioDBlink.c</a>
wurde mit all diesem Verhalten nach
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/RdGnPiGpioDBlink.html" title="RdGnPiGpioDBlink Doku">RdGnPiGpioDBlink.java</a>
(<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/doc-files/RdGnPiGpioDBlink.java" title="RdGnPiGpioDBlink Quelle">Quelle</a>)
portiert.</p>
<p>Die allererste Portierung nutzte noch Neil Kolbans
<a href="https://github.com/nkolban/jpigpio" title="interface to pigpio[d]">Bibliothek</a>
welche u.a. auch die Socket-Schnittstelle von<br />
<a href="http://abyz.me.uk/rpi/pigpio/sif.html" title="socket interface docu">pigpio</a>
benutzt. So haben wir alle Vorteile des
<a href="http://abyz.me.uk/rpi/pigpio/index.html" title="pigpio library">Ansatzes</a>
von Joan N.N.. Zusätzlich enthält Neil Kolbans
<a href="https://github.com/nkolban/jpigpio" title="interface to pigpio[d]">Bibliothek</a>
u.a. auch eine JNI-Implementierung mit ihrer C-Schicht für die
Nicht-Socket-Schnittstelle von pigpiod. Das macht sie nicht übersichtlicher,
und an keiner Stelle wird versucht Wegwerfobjekte zu vermeiden.</p>
<p>Wegen dieser und anderer Gesichtspunkte wurde eine kompakte reine Java
Lösung zum Anschluss an die pigpioD Socket-Schnittstelle implementiert
und inzwischen in <a href="https://frame4j.de/index_en.html" title="frame4j home (en)" class="bbi">Frame4J</a> integriert. Das heißt,
egal ob auf dem PC, dem Laptop oder einem Pi: Mit
<a href="https://frame4j.de/index_en.html" title="frame4j home (en)" class="bbi">Frame4J</a> hat man dort PI IO mit Java –
sei die IO auf dem betreffenden Pi selbst oder auf einem anderen Pi im selben
(privaten) [W]LAN. Das Programm
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/TestOnPi.html" title="TestOnPi Doku">TestOnPi</a>
testet und demonstriert binäre Ein- und Ausgänge,
<abbr title="Pulsweitenmodulation">PWM</abbr> und Servos an allen IO pins
eines Pi.</p>
<h2 id="probleme-mit-java-gpio-und-prozesssteuerung">Probleme mit Java GPIO und Prozesssteuerung</h2>
<h3 id="nicht-kompatible-dateisperre">Nicht kompatible Dateisperre</h3>
<p>Ein unmittelbar zu lösendes <a href="javaIncompFlock_de.html" title="siehe eigener Beitrag hierzu">Problem</a>
erschien im Lichte von Portieren “mit allem Verhalten” bei der
Linux-üblichen und ja schon eingesetzten
Datei-Sperre (lock file, flock()) für den exklusiven Zugriff auf Prozess-IO
und watchdog. Es stellte sich heraus, dass ein Java lock einer Datei als
“random access file, fully and exclusively” mit java.nio.channels.FileLock
auf einer Linux-Plattform inkompatibel zu dort etablierten Datei-Sperre mit
der Prozedur flock() ist. Mit flock() und FileLock bekommen alle C-Programme
eine Sperre auf eine Datei und alle Java-Anwendungen noch eine.</p>
<p>Zwei volle Sperren auf ein und dieselbe Datei macht den Ansatz kaputt. Dies
kann man als einen Fehler der JDK/JRE-Portierung nach Linux sehen. Nicht nur
bei unseren Anwendungen ist das natürlich nicht akzeptabel. Bevor man
Java-Ports echter Prozessanwendungen auf Linux loslässt.</p>
<p>Die kompatible Lösung sind zwei Methoden (openLock() and closeLock) in
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/PiUtil.html" title="openLock() and closeLock()">Frame4J: de.weAut.PiUtil</a>, welche ein C-Hilfsprogramm
<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/justLock.c">justLock</a> nutzen. Wenn Sie
dieses kleine Programm (<a href="https://github.com/a-weinert/weAut/blob/master/rasProject_01part/justLock.c">justLock</a>) direkt starten und
dann auch gleichzeitig die Java-Applikation
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/JustNotFLock.html" title="de.weAut.demos.JustNotFLock (needs Frame4J installed">JustNotFLock</a> laufen lassen,
demonstriert dies die zweifache Sperre ein und derselben Datei.</p>
<h3 id="wegwerfobjekte">Wegwerfobjekte</h3>
<p>Bei Java oder allgemeiner OO-Sprachen gilt der garbage collector als das
Risiko für ein ansonsten theoretisch und experimentell abgesichertes
Echtzeitverhalten. Es wurde für die Automatisierung kritischer Prozesse
mit objektorientierten Sprachen gefordert, dass im zyklischen Betrieb
keine Objekte mehr erzeugt werden dürfen. Selbst wenn diese Forderung
(für allgemeine Steuerungen) kaum so hart stellen würde, ist dies ein
löbliches Prinzip. Es befreit von den Risiken des Garbage-Collectors
und der Speicherverwaltung.</p>
<p>Und es liegt den hier aufgeführten Beispielen und entsprechenden
Java-Anwendungen zu Grunde. So werden mutable Klassen anstelle der
Neu-Erzeugung unveränderbarer Objekte verwendet, wie StringBuilder
statt String und eigener Container statt Long.</p>
<p>Durch gezielte Wiederverwendung veränderbarer Objekte lässt sich
Garbage-Collection und Speicherverwaltung verhindern. Bei dem verbreiteten
Linux-Ansatz „Gerät als Datei“ (device as file) sieht es dabei aber
schlecht aus. Das Listing (Auszug aus
<a href="https://weinert-automation.de/java/docs/frame4j/de/weAut/demos/Pi1WireThDemo.html" title="de.weAut.tests.Pi1WireThDemo">Pi1WireThDemo</a>)
zeigt das Auslesen eines 1-wire-Thermometers, die es auch edelstahlgekapselt
und geeignet für die üblichen Thermometereinsteckröhrchen gibt.</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">final</span> <span class="nc">String</span> <span class="n">devID</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">];</span> <span class="c1">// 28-02119245cd92 e.g.</span>
<span class="nc">String</span> <span class="n">line1</span><span class="o">;</span>
<span class="nc">String</span> <span class="n">line2</span><span class="o">;</span>
<span class="nc">BufferedReader</span> <span class="n">thermometer</span><span class="o">;</span>
<span class="nc">File</span> <span class="n">thermPath</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">File</span><span class="o">(</span>
<span class="s">"/sys/bus/w1/devices/w1_bus_master1/"</span> <span class="o">+</span> <span class="n">devID</span> <span class="o">+</span> <span class="s">"/w1_slave"</span><span class="o">);</span>
<span class="k">for</span><span class="o">(;</span><span class="n">runningOn</span><span class="o">;)</span> <span class="o">{</span> <span class="c1">// zyklischer Dauerbetrieb</span>
<span class="n">thermometer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="k">new</span> <span class="nc">FileReader</span><span class="o">(</span><span class="n">thermPath</span><span class="o">));</span>
<span class="n">line1</span> <span class="o">=</span> <span class="n">thermometer</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span>
<span class="n">line2</span> <span class="o">=</span> <span class="n">thermometer</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span>
<span class="c1">// Auswertung</span>
</code></pre></div></div>
<p>Der zugehörige Linux-Device-Treiber liefert ein Messergebnis in zwei
Textzeilen [sic!]. Nach deren Einlesen schließt sich die Datei
automatisch. Deswegen muss das Dateiöffnen im Listing in die den
Dauerbetrieb andeutende Endlosschleife. Jede Messung erzeugt also:</p>
<ul>
<li>1 BufferedReader,</li>
<li>1 FileReader und indirekt</li>
<li>1 FileInputStream,</li>
<li>1 FileDescriptor usw.
und schließlich direkt noch</li>
<li>2 String-Objekte.</li>
</ul>
<p>Von diesen mindestens 6 Objekten pro Messung ließen sich mit einem
byte-Array (und verminderter Lesbarkeit) nur die Reader und die Strings
vermeiden. Nun wird man ein Thermometer selten häufiger als einmal
pro Sekunde einlesen. Aber man stelle sich so etwas in einem 10ms-
oder gar 1ms-Zyklus in einem kleinen (embedded) Rechner vor.</p>
<p>Der Pi (BCM) Watchdog, auch als device as file implementiert, ist
hierbei wesentlich besser: Er – das heißt mit Java sein OutputStream –
bleibt die ganze Zeit zum Schreiben geöffnet. Hier ist es zum Glück
besser gemacht. Aber hierauf, sprich auf im System verankerte
Device-Treiber, haben wir keinen Einfluss.</p>
<h2 id="repositories">Repositories</h2>
<p>Finden Sie bitte die meisten Quellen im GitHub repository
<a href="https://github.com/a-weinert/weAut/">weAut</a>. Es spiegelt dieTeile der größeren
<a href="https://weinert-automation.de/svn/" title="guest:guest">SVN Entwicklungs-Repositories</a>,
welche für dieses Projekt essentiell sind. Für Kommentare und Probleme
<a href="https://github.com/a-weinert/weAut/">dieses Projekts</a> nutzen Sie bitte die
Kommentarfunktion dieses Beitrags, die übrigens ein “GitHub issue” ist.</p>Albrecht WeinertPi IO und Prozesssteuerung mit C Bei sehr kleinen Linux-Rechnern, wie einem Raspberry Pi, ist die Sprache der Wahl C — besonders bei Prozesssteueranwendungen, welche z.B. beim Pi die GPIO