FreshRSS

🔒
❌ Über FreshRSS
Es gibt neue verfügbare Artikel. Klicken Sie, um die Seite zu aktualisieren.
Vor vorgesternIhre RSS-Feeds

Spiele-Review: Raft, ein Ozean-Survival der anderen Art

Von Liane M. Dubowy

zurück zum Artikel

Wasser soweit das Auge reicht, ein kleines Floß unter den Füßen – und ein Hai: Im Early-Access-Spiel Raft fischt man Treibgut aus dem Meer, um sich über Wasser zu halten und das kleine Floß zu einem veritablen Hausboot auszubauen.

Auf einem kleinen Floß treibt der Spieler im Survival-Game Raft übers Meer. Die Aussichten sind zunächst nicht gut: Wasser bis zum Horizont und ein Hai, der seine Runden um das Floß dreht. Mit einem Haken am Seil fischt man aus dem stetigen Strom an Treibgut das Nötigste – Holzplanken, Plastik, Palmblätter und Fässer, die einiges mehr enthalten. Damit baut man sich erste Werkzeuge und vergrößert das Floß, an dem immer mal wieder der Hai knabbert. Hunger und Durst erinnern ziemlich bald daran, dass Raft ein Survival-Spiel ist.

Offenes Meer statt Open World

Statt weitläufiger Open-World-Landschaften beschränkt Raft die Spielewelt auf ein kleines Floß auf dem weiten Meer. Man wandert nicht herum und erkundet eine Welt, sondern lässt sich einfach treiben. Mit einem Segel und einem Paddel lässt sich immerhin die Richtung etwas beeinflussen.

Gelegentlich kommt man an einer kleinen Insel vorbei, die nicht nur über, sondern auch unter Wasser wertvolle Ressourcen liefert. Bauen kann man hier aber nicht. Für weitere Abwechslung sorgen verlassene Floße, die vorbeitreiben. Beim Hinüberschwimmen ist stets auch der Hai zur Stelle.

Mit der Zeit wird das Spiel komplexer: Mit einer Angel fängt man Fische, die auf den Grill wandern. Eine Destille erzeugt aus Salzwasser Trinkwasser und in unterschiedlich großen Pflanztöpfen lassen sich Rüben, Kartoffeln, Ananas, Mango, Wassermelonen und sogar Kokospalmen anbauen. Ein Anker erleichtert das Plündern der Inseln.

Im Laufe des Spiels kann man das winzige Floß zu einem komfortablen mehrstöckigen Hausboot mit Hütte und bequemer Hängematte zur Erholung ausbauen. Fans von Survival-Spielen finden in Raft typische Elemente wieder: Im Inventar gesammelte Dinge lassen sich im Crafting-Menü zu Werkzeugen, Waffen, Möbeln und anderem zusammensetzen. An einem Forschungstisch schaltet man neue Rezepte frei und erweitert so das Crafting-Menü. Etwas später im Spiel kann man eine Funkanlage bauen und damit ein geheimnisvolles Ziel ansteuern.

Gefahren auf hoher See

Hunger und Durst stellen zunächst die größte Gefahr dar: Wer sich zu lange mit dem Sammeln von Treibgut aufhält, verhungert und verdurstet schnell. Der Destillierapparat zur Meerwasserentsalzung, eine Angel und ein Grill stehen deshalb ganz oben auf der Crafting-Liste.

Raft: Nebel und Wellengang
In Raft kann auch das Wetter mal schlecht werden, Nebel erschwert die Sicht und der Wellengang macht das Fischen nach Treibgut schwieriger.

Schlechtes Wetter, hohe Wellen, Regen, Nebel und Dunkelheit gibt es ebenfalls in Raft. Das verändert zwar die Stimmung, ist aber nur in Ausnahmesituationen gefährlich. Hat man es beispielsweise gewagt, bei Wellengang zu einem vorbeitreibenden Floß zu schwimmen, während Nebel aufzieht, findet man womöglich nicht mehr zurück, bevor der Hai einem den Garaus macht. Für Action sorgt vor allem das Erkunden der Unterwasserwelt, denn der Hai lässt sich nur kurze Zeit von einem selbstgebauten Köder ablenken.

Drei Schwierigkeitsgrade stehen bereit. Wer in Ruhe ohne Ressourcenmangel sein Floß ausbauen will, kann zudem beim Spielstart den Kreativmodus mit unbegrenzten Vorräten und Gesundheit wählen.

Early Access bei Steam

Bereits im Dezember 2016 veröffentlichten drei schwedische Studenten der Universität Uppsala den Prototypen ihres Spiels für Windows und Linux kostenlos auf der Online-Plattform itch.io [3]. Bis Ende Mai 2017 wurde dieser über sieben Millionen Mal heruntergeladen. Aus Zeitgründen stellten die Entwickler die Linux-Version ab Version 1.05 fürs Erste jedoch ein.

Seit dem 23. Mai 2018 bieten die mittlerweile als Redbeet Interactive firmierenden Entwickler ihr Spiel in einer erweiterteten Version mit deutlich mehr Inhalten und einer rundum neuen Grafik auf Steam als Early-Access-Titel für rund 20 Euro [4] an.

Multiplayermodus

Wer sein Spiel für Freunde freigibt, kann gemeinsam im Koop-Modus sein Glück auf hoher See versuchen. Zu zweit oder dritt spielt es sich entspannter, da man nicht ständig das Meer nach vielversprechenden Fässern absuchen, sich um Nahrung und Wasser kümmern oder den Hai abwehren muss.

Raft: Maya und Rouhi
Wahlweise Maya oder Rouhi stehen als Charakter in Raft zur Wahl. Weiter verändern lassen sie sich nicht.

Bislang stehen zwei Charaktere zur Wahl (eine Frau und ein Mann), die sich optisch nicht anpassen lassen. Dass Raft den Spielernamen über einer Figur einblendet, erleichtert immerhin das Unterscheiden gleich aussehender Mitspieler.

Multiplayer in Raft
Ist die entsprechende Option aktiviert, können Steam-Friends in ein Raft-Spiel einsteigen. Soll es nicht der ganzen Freundesliste offen stehen, vergibt man ein Passwort.

Ist die Option "Freunden erlauben beizutreten" angehakt, sehen Steam-Freunde das Spiel unter "Welt beitreten". Mit dem aktuellen Update lieferten die Entwickler die Möglichkeit nach, das Spiel zusätzlich mit einem Passwort zu schützen, sodass nur geladene Gäste mitspielen können.

Das c't-zockt-Team hat Raft bereits ausprobiert; ein Mitschnitt des Live-Streams [5] ist bei YouTube zu sehen (siehe unten).

Viel Potential

Raft hat einen ausgezeichneten Early-Access-Start hingelegt: Das Spiel enthält reichlich Inhalte für etliche Stunden und macht sehr viel Spaß. Fehler gibt es nur wenige und wenn, so stören sie den Spielfluss kaum. Es kann durchaus vorkommen, dass der Hai mal den Kopf durch Felsen oder das Floß steckt. Schon jetzt sorgt das Ozean-Survival-Game dafür, dass man beim Spielen schnell die Zeit vergisst.

Obwohl Raft jetzt schon eine Empfehlung ist, steht es noch am Anfang seiner Entwicklung. Noch ist die Spielzeit überschaubar, irgendwann gibt es einfach nichts mehr zu tun. Auch das Baumenü lässt noch reichlich Raum für Erweiterungen. Weitere Inhalte sind angekündigt, beispielsweise neue Tiere. Einige Updates haben die Entwickler auch schon ausgeliefert. Im Laufe des Spiels deuten die Entwickler bereits eine spannende Storyline im Stil von Waterworld an, die sicher noch ausbaufähig ist. Wer Spaß an Survival-Spielen hat, neue Spielideen sucht und sich vom Early-Access-Status nicht abschrecken lässt, sollte die 20 Euro für Raft unbedingt investieren. ()

Aufzeichnung des c't-zockt-Live-Streams vom 28. Juni 2018: Raft.

URL dieses Artikels:
http://www.heise.de/-4096377

Links in diesem Artikel:
[1] https://www.heise.de/ct/bilderstrecke/bilderstrecke_4086412.html?back=4096377
[2] https://www.heise.de/ct/bilderstrecke/bilderstrecke_4086412.html?back=4096377
[3] https://raft.itch.io/raft
[4] https://store.steampowered.com/app/648800/Raft/
[5] https://youtu.be/5tNnB1YxHqo
[6] mailto:lmd@heise.de

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 05. Juli 2018 um 06:30

c't zockt LIVE: Raft - Hai-Life auf dem Floß

Von Rudolf Opitz

zurück zum Artikel

Wasser, Hunger, Durst und ein nerviger Hai. Raft fügt dem Survival-Genre eine ungewöhnliche Spiel-Idee hinzu: Per Haken fischt man nach Treibgut und baut damit das Floß zum mehrstöckigen Luxus-Segler aus. c't zockt Raft LIVE ab 17 Uhr.

c't zockt LIVE: Raft Donnerstag 28.06.2017 ab 17 Uhr

Bei Raft startet der Spieler in einer scheinbar ausweglosen Situation: Er steht auf einem winzigen Floß, das im Ozean treibt. Um das Floß kreist ein hungriger Hai. Mit dem einzigen Werkzeug, einem Seil mit Haken, zieht man Treibgut wie Planken, Plastik – viel Plastik –, Palmwedel und Fässer zu sich heran.

Mit dem Material baut sich der Spieler weitere Werkzeuge und erweitert das Floß. Letzteres ist auch nötig, da der Hai regelmäßig das Floß angreift und einzelne Segmente davon abbeißt. Das lästige Vieh ist nur durch beherztes Zustechen mit einem Spieß zu vertreiben – den man natürlich auch erst einmal bauen muss.

Da sich Hunger und Durst sehr rasch einstellen, gehört zu den ersten Aufgaben das Herstellen eines Destillierapparates zur Frischwassergewinnung, einer Angel und eines Grills. Wer sich zu lange mit dem Sammeln von Baumaterial oder der Haiabwehr beschäftigt, verhungert und verdurstet schnell: Sicht und Bewegungsfreiheit werden zunächst stark eingeschränkt, dann stirbt man. Ins Wasser springen ist auch keine Lösung, denn der Hai ist schneller – mehr als drei Attacken überlebt der Spieler nicht.

[2]

Raft stammt von drei schwedischen Studenten der Universität Uppsala, die Ende 2016 einen spielbaren Prototypen von Raft über die Plattform itch.io[3] zum freien Download anboten. Der wurde bis Ende Mai 2017 über sieben Millionen Mal heruntergeladen und erntete begeisterte Kritiken. Anfangs gab es Raft für Windows und Linux, doch stellten die nun unter Redbeet Interactive[4] firmierenden Entwickler die Linux-Version ab Version 1.05 aus Zeitgründen fürs Erste ein.

Seit dem 23. Mai gibt es Raft bei Steam[5] als Early-Access-Spiel in einer erweiterten Version für rund 20 Euro zu kaufen. Hinzugekommen sind Inseln, die man besuchen kann, eine Unterwasserwelt, neue Werkzeuge, Materialien, gierige Möwen und der Anfang einer Hintergrund-Story. Ebenfalls neu ist der Multiplayer-Modus: Weitere Spieler im LAN und aus dem Steam-Freundeskreis können laufenden Spielen beitreten.

Am Donnerstag ab 17 Uhr begibt sich das c't-zockt-Team LIVE auf ein wackliges Floß und versucht, nicht zu verdursten und zu verhungern – aber wir hoffen auf ein schönes Hai-Steak! (rop[6])


URL dieses Artikels:
http://www.heise.de/-4093041

Links in diesem Artikel:
[1] https://www.heise.de/ct/bilderstrecke/bilderstrecke_4086412.html?back=4093041
[2] https://www.heise.de/ct/bilderstrecke/bilderstrecke_4086412.html?back=4093041
[3] https://thedev.itch.io/raft-info
[4] http://raft-game.com/presskit.html
[5] https://store.steampowered.com/app/648800/Raft/
[6] mailto:rop@ct.de

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 28. Juni 2018 um 06:30

Tools & Libraries: Kommunikation mit Web-Workern

Von heise online

zurück zum Artikel

Web Worker eignen sich hervorragend dazu, komplexe Berechnungen vom Haupt-Thread einer Webanwendung auszulagern und damit die Performance einer Anwendung zu verbessern. Eine interessante Bibliothek, die die Kommunikation zwischen Worker-Threads und Haupt-Thread vereinfacht, ist Comlink [1].

Die Kommunikation zwischen Worker-Threads und Haupt-Thread erfolgt bekanntermaßen nachrichtenbasiert mit Hilfe der Methode postMessage() (auf Seiten des Senders) und Event-Listenern für das message-Event (auf Seiten des Empfängers). Möchte man Funktionen innerhalb eines Workers aus dem Haupt-Thread heraus im RPC-Stil aufrufen, müssen eventuell noch Antwortnachrichten zu den entsprechenden Anfragenachrichten zugeordnet werden, in der Regel über das Mitschleifen einer Request-ID.

Comlink

Die Bibliothek Comlink vereinfacht diese Kommunikation zwischen Haupt-Thread und Worker-Threads durch eine zusätzliche Abstraktionsschicht: Klassen, Objekte und Funktionen, die innerhalb eines Workers definiert werden, lassen sich mit Hilfe von Comlink direkt innerhalb des Haupt-Threads importieren und wie gewohnt verwenden. Beispielsweise lassen sich Objektinstanzen direkt über die importierte Klasse erzeugen und Objektmethoden direkt aufrufen, ohne dass Entwickler mit den Details der Worker-Kommunikation in Berührung kommen. Technisch realisiert Comlink dies durch Anwendung des Proxy-Patterns: für das jeweilige Objekt (bzw. die Klasse/die Funktion), das innerhalb des Worker-Codes definiert ist, erzeugt Comlink eine Proxy-Instanz im aufrufenden Code.

Dazu stellt Comlink drei Methoden zur Verfügung:

  • Comlink.expose() dient dazu, innerhalb eines Workers das Objekt zu definieren, welches nach außen hin bereitgestellt werden soll.
  • Comlink.proxy() erzeugt für eine Objektinstanz der Typen Worker, Window oder MessagePort ein Proxy-Objekt, welches die gesamte Nachrichtenkommunikation verbirgt und die API des zuvor im Worker über Comlink.expose() definierten Objekts als asynchrone API zur Verfügung stellt.
  • Comlink.proxyValue() funktioniert genau wie Comlink.proxy(), allerdings mit einem kleinen Unterschied: Während Comlink.proxy() eine Kopie des Originalobjekts erzeugt, arbeitet Comlink.proxyValue() wirklich als Proxy: ändert man das Proxy-Objekt im Haupt-Thread, ändert sich auch das ursprüngliche Objekt im Worker-Thread.

Installation und Beispiel

Comlink kann entweder direkt von der Projekt-Website heruntergeladen oder über npm installiert werden:

npm install comlinkjs

Innerhalb des Codes für den Worker definiert man anschließend beliebige Objekte (Klassen, Funktionen, etc.) wie im folgenden Listing die Klasse Calculator (die in der Praxis natürlich etwas Speicherintensiveres als bloß die Summe zweier Zahlen berechnen würde) und übergibt sie der Methode Comlink.expose(). Dies ist notwendig, damit Comlink bei der Definition mehrerer Objekte intern weiß, welches dasjenige ist, für das später das Proxy-Objekt erstellt werden soll.

importScripts("/node_modules/comlinkjs/comlink.global.min.js");
class Calculator {
sum(x = 0, y = 0) {
return x + y;
}
}
Comlink.expose(Calculator, self);

Auf Seiten des Haupt-Threads erstellt man anschließend wie gewohnt eine Instanz von Worker, übergibt diese dann aber der Methode Comlink.proxy(). Im folgenden Beispiel wird auf diese Weise ein Proxy für die im Worker definierten Klasse Calculator erzeugt. Anschließend lassen sich über await new Calculator() neue Objektinstanzen erstellen. Das await ist dabei notwendig, da die Kommunikation zwischen Haupt-Thread und Worker-Thread asynchron abläuft. Dies gilt auch für andere Aufrufe der Proxy-API wie im Beispiel der Aufruf von sum().

<!doctype html>
<script src="/node_modules/comlinkjs/comlink.global.min.js"></script>
<script>
async function init() {
const worker = new Worker('worker.js');
const Calculator = Comlink.proxy(worker);
const calculator = await new Calculator();
const result = await calculator.sum(80, 90);
console.log(result);
};
init();
</script>

Fazit

Comlink versucht die technischen Details der Nachrichtenkommunikation mit Web-Workern zu vereinfachen und ist ein interessantes Beispiel für die Anwendung des Proxy-Patterns. Comlink kann aber nicht nur bei der Kommunikation mit Web-Workern verwendet werden, sondern auch bei der Kommunikation mit anderen Browserfenstern, Frames und generell allem, was das MessagePort-Interface der Channel Messaging API [2] implementiert.


URL dieses Artikels:
http://www.heise.de/-4063928

Links in diesem Artikel:
[1] https://github.com/GoogleChromeLabs/comlink
[2] https://html.spec.whatwg.org/multipage/web-messaging.html#channel-messaging

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 06. Juni 2018 um 07:28

Zyklische Abhängigkeiten – eine Architektur-Todsünde?

Von heise online

zurück zum Artikel

Kaum etwas ist schlimmer bei einer Softwarearchitektur als zyklische Abhängigkeiten. Aber warum eigentlich? Und stimmt das?

Softwarearchitekturen teilen ein System in Module auf und definieren Beziehungen zwischen Modulen. Ziel ist, die Module möglichst unabhängig entwickeln zu können. Bestimmte Abhängigkeiten zwischen Modulen sind erlaubt und andere nicht. Durch die Abhängigkeiten können sich Module nämlich beeinflussen: Wenn das Modul "Rechnung" das Modul "Bestellung" nutzt, dann kann eine Änderung am Modul "Bestellung" eine Änderung an Modul "Rechnung" erzwingen. Das ist beispielsweise der Fall, wenn sich die Schnittstelle ändert. Durch die Abhängigkeit ist also eine unabhängige Entwicklung nicht immer möglich.

Wenn Module unabhängig entwickelt werden sollen, müssen Abhängigkeiten vermieden werden. Aber alle Module sollen ein System ergeben. Das geht nur, wenn Module andere Module nutzen, um so das System zu ergeben. Einige Abhängigkeiten sind also notwendig.

Oft ist die Architektur eines Systems problematisch: Änderungen sind schwierig und ziehen sich durch viele Module. Die Ursache dafür können zyklische Abhängigkeiten sein. Bei einer zyklischen Abhängigkeit würde nicht nur das Modul "Rechnung" das Modul "Bestellung" nutzen, sondern auch "Bestellung" das Modul "Rechnung". Eine Änderung an "Rechnung" oder "Bestellung" kann also das jeweils andere Modul beeinflussen. Aber eigentlich sollten die beiden Module getrennt sein. Deswegen sind sie ja in der Architektur separiert. Durch die zyklische Abhängigkeit sind sie nur gemeinsam änderbar. Daher halten viele zyklische Abhängigkeiten für eine Art Todsünde.

Ein System ohne zyklische Abhängigkeiten ist also sicherlich einfacher änderbar, und daher kann das Beseitigen der zyklischen Abhängigkeiten ein sinnvolles Ziel für eine Architektur-Verbesserung sein.

Zyklische Abhängigkeit – ja, und?

Aber wie schlimm ist die zyklische Abhängigkeit wirklich? Es kann sein, dass Änderungen an Modulen in einer zyklischen Abhängigkeit in der Realität nicht immer dazu führen, dass beide Module gemeinsam geändert werden müssen. Schließlich kann man Glück haben und die Änderung bleibt auf ein Modul beschränkt und beeinflusst kein abhängiges Module. Das kann der Fall sein, wenn die Schnittstelle unverändert bleibt. Eine zyklische Abhängigkeit muss also nicht immer zu einem Problem werden.

Wenn "Bestellung" und "Rechnung" keine zyklische Abhängigkeit haben, können die Abhängigkeiten dennoch ein Problem sein: Wenn fast alle Änderungen von "Bestellung" auch eine Änderung an der Schnittstelle und damit an "Rechnung" erzwingen, dann ist die getrennte Entwicklung praktisch nicht möglich, obwohl es keine zyklische Abhängigkeit gibt. Immerhin kann "Rechnung" noch geändert werden, ohne das "Bestellung" zu ändern ist, weil in diese Richtung keine Abhängigkeit existiert. Aber dass eine Änderung in einem Modul fast immer eine Änderung in einem andere Modul verursacht, kann schlimmer sein als eine zyklische Abhängigkeit, wenn Änderungen in der Realität immer auf ein Modul beschränkt bleiben.

Nur zyklische Abhängigkeiten zu beseitigen, löst also nur einen Teil des Problems und gegebenenfalls noch nicht einmal den wichtigsten Teil.

Keine Zyklen – ein realistisches Ziel?

Kann man Zyklen eigentlich vollständig eliminieren? Selbst vorbildliche Systeme wie das Spring Framework haben zwischen Klassen Zyklen. Nur zwischen Java-Packages erreicht es tatsächlich Zyklenfreiheit. Architektur-Management-Werkzeuge erlauben es, solche Package-Zyklen zu finden und zu eliminieren. Manchmal ist das ganz einfach: Man verschiebt eine Klasse oder ein paar Klassen in ein anderes Package. Wenn nur diese Klassen eine Abhängigkeit in die falsche Richtung hatten, kann die zyklische Abhängigkeit so verschwinden. Oder man führt eine Schnittstelle [1] ein. Aber soll das Verschieben von Klassen oder ein Interface wirklich die unabhängige Entwicklung in einem System ermöglichen?

Diese Ansätze sind rein technisch und setzten kein Wissen über die Domäne voraus. Einige Werkzeuge können sogar eine "perfekte" Struktur automatisiert ermitteln. Aber die Kunst bei der Software-Architektur ist es, die Logik für die Domäne zu strukturieren. Ein solcher, rein technischer Ansatz kann also eigentlich nicht der richtige Weg sein.

Also gilt auch hier wie bei anderen Metriken [2]: Zyklische Abhängigkeiten können ein Hinweis auf ein Problem sein – oder auch nicht. Sie nur zu eliminieren, um den Metrik-Fetischismus zu befriedigen, ist nicht sinnvoll. Man sollte sie nur angehen, wenn die Änderbarkeit des System tatsächlich aufgrund der zyklischen Abhängigkeiten schlecht ist. Und dann ist der richtige Weg, die Domänen-Logik besser zu strukturieren und nicht einfach nur die Metriken zu optimieren.

Am Ende nimmt einem also auch beim Managen der Abhängigkeiten niemand das Denken ab und man muss selbst die richtigen Maßnahmen ergreifen.

tl;dr

Zyklische Abhängigkeiten können die Änderbarkeit einer Software negativ beeinflussen, aber den Ruf, eine Todsünde zu sein, haben sie zu Unrecht.


URL dieses Artikels:
http://www.heise.de/-4061803

Links in diesem Artikel:
[1] http://blog.schauderhaft.de/2011/07/17/breaking-dependency-cylces/
[2] https://www.heise.de/developer/artikel/Mit-Metriken-managen-Mist-3568010.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 04. Juni 2018 um 08:04

Spiele-Review: Stardew Valley Multiplayer

Von Liane M. Dubowy

zurück zum Artikel

Der Erfolg des Indie-Spiels kam überraschend, ein Multiplayermodus und neue Inhalte sollen das Spiel nun noch interessanter machen. Das c't-zockt-Team hat gemeinsam die Betaversion der Landleben-Rollenspiel-Simulation Stardew Valley 1.3 angespielt.

Der große Erfolg des Indie-Games kam ein wenig überraschend: In rund drei Jahren hatte Eric "ConcernedApe" Barone sein Spiel Stardew Valley im Alleingang entwickelt. Publisher Chucklefish veröffentlichte es im Februar 2016; allein auf Steam soll sich das Spiel geschätzt über 3,5 Millionen Mal verkauft haben. Die Bewertungen auf der Online-Plattform: "Äußerst positiv". Stardew Valley gibt es in vielen Sprachen für Windows, Linux und macOS -- alle drei Versionen haben wir erfolgreich ausprobiert. Aber auch für Xbox One, Playstation 4 und Nintendo Switch. Eine Version für PS Vita soll im Mai erscheinen.

Multiplayermodus für Stardew Valley

Stardew Valley Event
In jeder Jahreszeit unterbrechen Feste, Wettbewerbe und andere Veranstaltungen die tägliche Routine.

Was bisher gefehlt hatte, war ein Multiplayermodus, in dem man gemeinsam Opas Farm wieder in Schuss bringen oder den Monstern in den Minen trotzen kann. Version 1.3 soll diesen Mangel beheben. Ganz fertig ist der Multiplayermodus noch nicht, das ist beim Anspielen klar geworden. Den Anspruch erhebt das Spiel aber auch noch nicht: Bislang steht nur eine offene Betaversion bereit. Neben dem Multiplayermodus sind auch für Single Player neue Inhalte hinzugekommen, darunter neue Events, Gegenstände und Rezepte.

Um gemeinsam zu spielen, muss man bislang zur offenen Beta wechseln. Wer das Spiel auf Gog.com gekauft hat, kann die Betaversion dort herunterladen. Auf Steam öffnet man in der Bibliothek über das Kontextmenü die Eigenschaften des Spiels, wechselt in das Tab "Betas". Nachdem man in das Feld "jumpingjunimos" eingetragen und mit "Code überprüfen" bestätigt hat, steht die Beta im Feld darüber zur Auswahl bereit.

Noch hat die Betaversion eine ganze Reihe von Fehlern, auch wenn keiner wirklich den Spielspaß trübt. Erst nach einigen Stunden Spiel traten bei uns kleinere Grafikfehler auf und es fiel auf, dass die Anzeige der Inhalte im Community Center nicht bei allen synchron war. Die Betaversion wurde bereits einige Male aktualisiert, sodass auch diese Bugs bald der Vergangenheit angehören dürften.

Bisherige Spielstände können in die Beta beziehungsweise die neue Version übernommen werden, sollten aber vorher gesichert werden. Gemeinsam spielt man im lokalen Netzwerk, aber auch übers Internet. In der Steam-Version des Spiels tauchen von Freunden gestartete Multiplayer-Spiele automatisch auf. Dank sogenannter Einladungscodes kann man aber auch mit jenen spielen, die Stardew Valley auf Gog.com erworben haben.

Stardew Valley ist auf Steam [3] für 14 Euro erhältlich, für denselben Preis ist es auf Gog.com ohne DRM [4] verfügbar. Die Systemanforderungen sind sehr moderat, das Spiel lässt sich auch auf einem Notebook mit halbwegs aktueller Intel-Grafik noch flüssig spielen. Das haben wir bereits getestet. Ein 2-GHz-Prozessor und 2 GByte RAM sollten allerdings vorhanden sein.

Raus aufs Land

Kurz vor dem Burnout sorgt Opas Testament dafür, dass das c't-zockt-Team dem tristen Büroalltag entflieht und aufs Land zieht. Auf dem von Opa geerbten, verwilderten Hof im Sternentau-Tal wartet derweil einiges an Arbeit auf uns, als Startgeschenk erhält jeder 15 Pastinakensamen. Ein Tutorial in Form eines "Hofbuchs" leitet durch die ersten Schritte.

Multiplayermodus in Stardew Valley
Spielt man Stardew Valley im Multiplayermodus, erledigt man Aufgaben wie das Gießen der Felder gemeinsam.

Bis zum florierenden Bauernhof mit Hühnern, Kühen, Schweinen, Gemüseanbau und einem Gewächshaus ist der Weg allerdings noch weit. Wir legen erste Felder an, lernen zu angeln und sammeln allerlei Wildfrüchte, um ein paar Goldtaler zu erwirtschaften, mit denen wir neue Samen kaufen können. Für Abwechslung sorgen die Monster in den Minen; das Angeln eines Fisches entpuppt sich als kleines Minispiel mit unterschiedlichen Schwierigkeitsgraden.

Neben dem Haupthaus können bis zu drei weitere Häuser auf dem Bauernhof stehen, genauso viele Mitspieler sind möglich. Nicht nur das Land wird geteilt, auch die Kasse ist eine gemeinsame. Allerdings muss jeder selbst ein paar Aufgaben erfüllen, seine Fähigkeiten verbessern und sich im Dorf beliebt machen. Größere Herausforderungen wie die Minen und die Restauration des Gemeindezentrums erledigt man ebenfalls im Team.

Detailverliebt

Winter in Stardew Valley
Mit den Jahreszeiten wechselt nicht nur das Gesicht des Bauernhofs, sondern auch die Aufgaben und Pflanzmöglichkeiten.

Auf den ersten Blick wirkt Stardew Valley wie eine Bauernhof-Simulation, ein Spiel, in dem man stundenlang die immergleichen Tätigkeiten verrichten muss. Doch ehe sich das wie Arbeit anfühlen kann, übernehmen längst Sprinkler und andere Gerätschaften die mühsame Arbeit des Gießens und der Tierfütterung und man hat Zeit für anderes. Ein gutes Verhältnis zu den anderen Dorfbewohnern wird immer wichtiger: Sie geben gute Ratschläge, schicken Rezepte und helfen mit kleinen Geschenken aus. Die Rollenspiel-Elemente treiben die Handlung voran, Quests sorgen für Abwechslung und im Laufe des Spiels werden neue Orte wie die Wüste und Möglichkeiten (Baden im Spa!) freigeschaltet.

Das Spiel ist stark inspiriert von der frühen Harvest-Moon-Reihe, bietet jedoch deutlich mehr Freiheit im Spiel. Die ganz eigene, schicke Retrografik ist bis ins Detail gelungen. Das Spiel lebt vor allem von all den liebevollen Details: Jede Figur im Spiel hat eine eigene Hintergrundgeschichte, hat eigene Vorlieben und Charaktereigenschaften. Und ständig gibt es Neues zu entdecken.

Fazit

Stardew Valley hat nicht ohne Grund eine große Fangemeinde, das Spiel fesselt über viele Stunden. Auch der neue Multiplayer-Modus ist gelungen. Zu Beginn müssen zwar alle die gleichen Quests erledigen und treten damit ein wenig in Konkurrenz, das legt sich aber im Laufe des Spiels, wenn es darum geht, gemeinsam voran zu kommen. An einigen Ecken ist spürbar, dass der Multiplayer-Modus im Nachhinein aufgepfropft wurde, doch gemeinsam zu spielen macht definitiv Spaß. Noch hat die neue Version mit einigen Bugs zu kämpfen, spielbar ist sie trotzdem bereits und keiner der in unserem Spiel aufgetretenen Fehler war wirklich gravierend. ()

Aufzeichnung des Live-Streams vom 17.5.18: c't zockt live den Stardew Valley Multiplayer

URL dieses Artikels:
http://www.heise.de/-4049513

Links in diesem Artikel:
[1] https://www.heise.de/ct/bilderstrecke/bilderstrecke_4049703.html?back=4049513
[2] https://www.heise.de/ct/bilderstrecke/bilderstrecke_4049703.html?back=4049513
[3] https://store.steampowered.com/app/413150/Stardew_Valley/
[4] https://www.gog.com/game/stardew_valley
[5] mailto:lmd@heise.de

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 24. Mai 2018 um 06:30

Im Gespräch: Michael Simons über Spring Boot 2 und sein neues Buch

Von heise online

zurück zum Artikel

Es gibt viele interessante Menschen, die mit ihrer Arbeit, ihrem Engagement in Java User Groups und ihren Vorträgen und Büchern die Java-Community prägen. Einige von ihnen möchte ich hier nach und nach vorstellen und mit ihnen über ihre Projekte sprechen. Dieses Mal habe ich mit Michael Simons über Spring Boot und sein neues Buch [1] gesprochen.

Thorben Janssen: Hallo Michael, erzähle uns doch bitte ein bisschen über dich. Wie bist du zur Softwareentwicklung gekommen, und was machst du heute?

Michael Simons: Ich bin über Umwege und relativ spät zur Softwareentwicklung gekommen. Ich gehöre nicht zu den Menschen, die bereits als Kind programmiert haben. Eigentlich wollte ich nach dem Abitur mal was mit Chemie oder Geschichte studiert haben, fand dann aber eine duale Ausbildung als mathematisch-technischer Assistent mit parallelem Studium Mathematik an der FH irgendwie spannender. Heute arbeite ich als Entwickler und Berater.

Janssen: Was machst du privat, wenn du nicht gerade in der Java-Welt unterwegs bist?

Simons: Ich verbringe viel Zeit mit meiner Familie und versuche, möglichst viel draußen zu sein. Falls ich nicht gerade Fahrrad fahre oder laufe und noch Zeit übrig ist, lese ich gerne.

Janssen: Du hast ein Buch über Spring Boot geschrieben und hältst Vorträge darüber. Für alle, die Spring Boot noch nicht verwendet haben, was sind die Vorteile und warum sollte ich es einsetzen?

Simons: In der Regel sollte man Spring so einsetzen, dass es so wenig wie möglich sichtbar wird. Spring selbst ist immer noch ein System, dessen maßgebliche Rolle Dependency Injection (DI) ist. Spring Boot hilft darüber hinaus, Abhängigkeiten zu verwalten, Dinge zu konfigurieren und vieles andere mehr, aber es ist nur Mittel zum Zweck. Spring und Spring Boot haben natürlich viele Module, die weit über DI hinausgehen, aber auch die sind ebenfalls nur Mittel zum Zweck und sollten nicht im Vordergrund stehen.

Spring Boot ist gleichermaßen einsetzbar für Microservices, monolithische Anwendungen oder auch Batch-Anwendungen. Es kann getrost festgehalten werden, dass eine Entwicklung von Spring-basierten Anwendungen mit Spring Boot erfolgen sollte.

Janssen: Was sind aus deiner Sicht die interessantesten und nützlichsten Neuerungen in Spring Boot 2?

Simons: Ganz im Rampenlicht steht zusammen mit Spring 5 natürlich der reaktive Stack. Basierend auf dem Project Reactor steht nun im selben Programmiermodell eine moderne, nicht blockierende Alternative für Enterprise-Anwendungen zur Verfügung. Konzepte, die seit einigen Jahren schon im Node.js-Umfeld beziehungsweise anderen Frameworks möglich sind, finden so auch ihren Weg an Stellen, die alternativen Technologien eher skeptisch gegenüber stehen.

Darüber hinaus ist die konsequente Pflege des mittlerweile vier Jahre alten Projekts ein persönliches Highlight für mich: Nicht ganz passende Namen, Package-Strukturen und Lücken in der Dokumentation werden konsequent korrigiert, bereinigt und gefüllt. Spring und Spring Boot sind gelungene Beispiele für die Abarbeitung technischer Schuld. Natürlich werden Schulden im Laufe eines Projekts aufgenommen. Wichtig ist, sie wieder abzutragen.

Janssen: Dein Buch "Spring Boot 2 – Moderne Softwareentwicklung mit Spring 5 [2]" ist vor wenigen Tagen im dpunkt Verlag erscheinen. Erzähl uns ein wenig darüber. Was macht das Buch besonders, und wer sollte es lesen?

Simons: Mein Buch greift die Vielfältigkeit des Spring-Ökosystems auf. Das war kein leichtes Unterfangen und spiegelt sich schlussendlich im Umfang wieder. Leserinnen und Leser, die bisher noch keine Erfahrung mit Spring hatten, lernen in einer kurzen Einführung über den Dependency-Injection-Container und die grundlegenden Spring-Ideen. Erfahrene Spring-Entwickler, die sich bisher noch nicht mit Spring Boot beschäftigt haben, werden nach der Lektüre des Buchs verstehen, warum neue Spring-Projekte in der Regel mit Spring Boot aufgesetzt werden sollten. Schließlich gibt es Spring Boot nun seit vier Jahren, aber auch Menschen, die es seit dieser Zeit einsetzen, werden noch viele, interessante Details erfahren.

Janssen: Wie bist du dazu gekommen ein Buch über Spring Boot zu schreiben und wie waren deine Erfahrungen dabei?

Simons: Es mag albern klingen, aber ich wollte schon in meiner Jugend etwas geschrieben haben, damals wohl eher Prosa. Das habe ich nach kurzen Versuchen lieber der Vergessenheit überlassen.

Ende 2015 habe ich auf einem iSAQB-Training Gernot Starke und Peter Hruschka kennen gelernt. Dieses Training hat meine Arbeit sehr zum Positiven verändert, und ich bin beiden sehr dankbar. Ein Ergebnis dieses Trainings war das "arc42 by example [3]" Buch, das Gernot, Stefan Zörner und ich zusammen geschrieben haben. Der Erfolg hat mich sehr überrascht und motiviert, noch mal darüber nachzudenken, was ich vielleicht noch zu sagen hätte. Das Ergebnis kann man nun in den Händen halten.

Mir hat das Schreiben sehr viel Spaß gemacht. Brutto habe ich rund 16 Monate an dem Buch gearbeitet, netto sind es weniger. Die ersten 4 bis 5 Monate habe ich in jeder freien Minute am Thema gearbeitet und mich da über den Support meiner Frau Christina gefreut.

Die wirklich "schlimme" Arbeit fing erst nach den Reviews des fertigen Manuskripts an: Spring Boot 2 Milestone um Milestone, Release Candidate um Release Candidate mussten die Beispiele nachbearbeitet und geschärft werden. Ich habe den Aufwand nach der JAX 2018 mal analysiert und in meinem Blog aufgeschrieben: "Having A Bestselling Book On Amazon [4]".

Janssen: Planst du weitere Bücher zu schreiben?

Simons: Ja, ich hab ein paar Ideen, aber die sind noch nicht spruchreif. Ich würde gerne etwas schreiben, das eine längere Halbwertszeit hat als ein Buch zu einem konkreten Framework.

Janssen: Welche weiteren Projekte verfolgst du?

Simons: Eines meiner Ziele in diesem Jahr ist die Absolvierung eines Triathlons.

Janssen: Wo kann man dich finden?

Simons: Im echten Leben in und um Aachen, online unter michael-simons.eu [5] und als @rotnroll666 [6] auf Twitter.

Janssen: Vielen Dank für das Interview und viel Erfolg mit deinem aktuellen und allen nachfolgenden Büchern.


URL dieses Artikels:
http://www.heise.de/-4038292

Links in diesem Artikel:
[1] https://www.dpunkt.de/buecher/13060/9783864905254-spring-boot-2.html
[2] https://www.dpunkt.de/buecher/13060/9783864905254-spring-boot-2.html
[3] https://leanpub.com/arc42byexample
[4] http://info.michael-simons.eu/2018/04/28/april-recap-jax-2018-and-having-a-bestselling-book-on-amazon/
[5] http://michael-simons.eu
[6] https://twitter.com/rotnroll666

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 08. Mai 2018 um 09:00

Wir brauchen technikfeindliche Techniker!

Von heise online

zurück zum Artikel

Software Engineering ist zwar eine technische Disziplin, aber dennoch misst sie Technologien zu viel Bedeutung bei.

Technologien sind für Software Engineering sehr wichtig. Zumindest einen Überblick über die wichtigsten Technologien sowie ihre Stärken und Schwächen sollten Software-Entwickler haben. Schließlich kann die Wahl der richtigen Technologie dazu führen, dass Projekte Probleme schneller und effizienter lösen. Genauso können Technologien zu einem Projektrisiko werden, weil sie den Ansprüchen nicht genügen.

Sollten sich Software-Entwickler also auf Technologien konzentrieren? Zu tun gibt es genug: Jedes Projekt kann immer noch weiter optimiert werden. Die Code-Qualität kann immer noch besser sein, die Testabdeckung sowieso und neue Technologien gibt es auch andauernd. Irgendwann kann das zu Beschäftigungstherapie werden: Warum nicht noch diese oder jene Technologie einbauen? Oder hier oder da noch optimieren?

Dabei gerät ein wichtiger Faktor in Vergessenheit: Wer Technologien um ihrer selbst willen verwendet, betreibt kein Software Engineering. Engineering ist eine Ingenieurstätigkeit. Das bedeutet, ein Problem mit Technologien zu lösen.

Technologien sind Mittel, nicht Zweck

Technologien sind selbst kein Zweck, sondern ein Mittel, um einen Zweck zu erreichen. Also müssen Software-Entwickler Geschäftsprobleme mit Software lösen. Wenn man ihnen die Chance dazu gibt, eigenverantwortlich an Geschäftsproblemen zu arbeiten, kommen sie oft auf sehr gute Ideen und können die auch gleich umsetzten. Wenn die Software-Entwickler hingegen auf die Technologien begrenzt werden, können sie sich natürlich auch nur in diesem Bereich einbringen, und dann hat das Verhalten oft etwas von Verhaltenstherapie. Statt also die Software-Entwickler stärker zu kontrollieren und Technologie-Entscheidungen zu hinterfragen, sollten technikverliebte Software-Entwickler stärker an den Geschäftsfragen teilhaben und so den Geschäftswert in den Mittelpunkt stellen.

Grundsätzlich sollten Software-Entwickler Technologien nur nutzen, wenn sie Geschäftsprobleme lösen. In gewisser Weise müssen sie also nicht technikverliebt, sondern technikfeindliche Techniker sein: Erst wenn eine neue Technologie wirklich ein Problem löst, dann sollte sie genutzt werden – und nicht etwa, wenn sie cool oder spannend ist.

tl;dr

Software-Entwickler haben eigentlich einen Technik-Schwerpunkt. Aber Software-Projekte sollen Technologien nur einsetzen, wenn sie einen Geschäftsnutzen haben. Also müssen sich Software-Entwickler mehr um Geschäftsprobleme kümmern und Technologien skeptisch gegenüber stehen.


URL dieses Artikels:
http://www.heise.de/-4044291

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 07. Mai 2018 um 18:04

Hibernate-Tipps: Nur ausgewählte Entitäten einer Vererbungshierarchie selektieren

Von heise online

zurück zum Artikel

Die Hibernate-Tipps-Serie bietet schnelle und einfache Lösungen zu verbreiteten Hibernate-Fragen. Dieses Mal geht es um die gezielte Selektion einer einzelnen Entität aus einer Vererbungshierarchie.

Frage:

Ich habe in meinem Domänenmodell eine Vererbungshierarchie [1] modelliert und möchte in einer Abfrage nur eine bestimmte Klasse dieser Hierarchie selektieren. Unterstützt JPQL solche Abfragen?

Lösung:

Mit JPA 2.1 wurde der TREAT-Operator für JPQL [2]- und Criteria-Abfragen eingeführt. Mit diesem können gezielt einzelne Ableitungen einer Superklasse selektiert werden.

Im folgenden Beispiel können Autoren unterschiedliche Arten von Publikationen veröffentlichen, zum Beispiel Bücher oder Blogartikel. Dies lässt sich mit den Entitäten Author und Publication modellieren, die in einer Many-to-many-Beziehung zueinander stehen. Des Weiteren werden die Entitäten Book und BlogPost als Ableitungen der Klasse Publication erstellt.

Hibernate Tipps: Nur ausgewählte Entitäten einer Vererbungshierarchie selektieren

Basierend auf diesem Modell selektiert die folgende Abfrage alle Autoren und ihre Bücher, deren Titel das Wort "Java" enthält. Dazu wird die Superklasse Publication mit Hilfe des TREAT-Operators auf ihre Ableitung Book gecastet.

List<Object[]> result = em.createQuery("SELECT a, p FROM Author a JOIN a.publications p WHERE treat(p AS Book).title LIKE '%Java%'").getResultList();

Hibernate Tips – das Buch

Mehr als 70 solcher Rezepte zu Themen wie einfache und komplexe Mapping-Definitionen, Logging, Unterstützung von Java 8, Caching sowie die statische und dynamische Erzeugung von Abfragen gibt es in meinem Buch "Hibernate Tips: More than 70 solutions to common Hibernate problems". Es ist als Taschenbuch und E-Book auf Amazon [3] und als PDF auf hibernate-tips.com [4] erhältlich.


URL dieses Artikels:
http://www.heise.de/-4038150

Links in diesem Artikel:
[1] https://www.thoughts-on-java.org/complete-guide-inheritance-strategies-jpa-hibernate/
[2] https://www.thoughts-on-java.org/jpql/
[3] https://www.amazon.de/Hibernate-Tips-solutions-common-problems/dp/1544869177
[4] http://www.hibernate-tips.com/

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 01. Mai 2018 um 16:24

Sheeld-Bürgerstreich

Von heise online

zurück zum Artikel

Den Arduino-Shields 1Sheeld und 1Sheeld+ liegt eine simple Idee zugrunde: Was, wenn Maker die zahlreichen Sensoren und Funktionalitäten eines Android- oder iOS-Smartphones durch Arduino-Boards nutzen könnten. Genau das ermöglicht ein 1Sheeld{+}, welches sich deshalb als Mutter aller Shields betrachten lässt.

Eine Frage der Hardware

Während 1Sheeld via Bluetooth mit Android-Geräten kommuniziert, erlaubt das neuere 1Sheeld+ sowohl Android- als auch iOS-Hardware. Beide Shields unterscheiden sich in der Art ihrer Bluetooth-Unterstützung. Während sich das genügsame 1Sheeld mit älteren Bluetooth-Versionen zufrieden gibt, setzt 1Sheeld+ einen BLE-Stack (Bluetooth Low Energy) voraus.

Wir sollten uns aber im wörtlichen Sinne erst einmal ein Bild von beiden Shields machen.

Auf der nachfolgenden Abbildung ist ein konventionelles 1Sheeld zu sehen, das nur Android als Spielkameraden akzeptiert. Es ist zwar schwarz, aber nicht das schwarze Schaf der Familie:

1Sheeld implementiert das Zusammenspiel von Arduino Boards mit Android-Geräten über Bluetooth
1Sheeld implementiert das Zusammenspiel von Arduino Boards mit Android-Geräten über Bluetooth

Im Gegensatz dazu bietet 1Sheeld+ Unterstützung für iOS und Android:

Das modernere 1Sheeld+ verwendet Bluetooth Low Energy und unterstützt die Kooperation von Arduino-Boards mit Android- und iOS-Geräten
Das modernere 1Sheeld+ verwendet Bluetooth Low Energy und unterstützt die Kooperation von Arduino-Boards mit Android- und iOS-Geräten

Das Shield offeriert mehrere Einstellungsmöglichkeiten (siehe nachfolgende Abbildung).

  • Rechts unten im Bild lässt sich 1Sheeld+ per Dip-Switch zwischen 3.3V und 5V umschalten, je nachdem welches Arduino-Board Verwendung findet. Im vorliegenden Fall fällt die Wahl auf die vom UNO vorausgesetzten 5V. Bei anderen Arduino-Boards wie zum Beispiel dem DUE dürfen es nur 3.3V Versorgungsspannung sein.
  • Direkt rechts daneben ist der obligatorische RESET-Schalter platziert.
  • Links oben befindet sich der Serial-Switch, der zwischen Programmiermodus (SW) und Ausführungsmodus (HW) wechselt.
  • Die BT-LED rechts oben im Bild signalisiert, ob sich 1Sheeld+ im Kopplungsmodus befindet (LED blinkt) oder bereits eine Verbindung mit einem Smartphone hergestellt hat (LED leuchtet kontinuierlich).
Das vom Autor benutzte 1Sheeld+ sitzt huckepack auf einem Arduino Uno Board
Das vom Autor benutzte 1Sheeld+ sitzt huckepack auf einem Arduino Uno Board

Ein weiterer Unterschied zwischen 1Sheeld und seinem jüngeren Cousin 1Sheeld+ besteht in der Verwendung des seriellen Ports. Controller wie der Arduino Uno besitzen nur einen (!) seriellen Hardware-Port, weshalb dieser Port nicht mehr für andere Zwecke zur Verfügung steht, sobald ihn 1Sheeld für die Kommunikation mit dem Arduino-Board reserviert. Im Gegensatz dazu besitzt 1Sheeld+ eine eigene Pin-Reihe, die den seriellen Hardware-Port für andere Aufgaben freistellt, falls erwünscht.

Wie in der Abbildung ersichtlich, enthält das 1Sheeld+ dazu zwei Extra-Pinreihen. In der linken lässt sich ein alternativer Pin für TX wählen (5, 7, 9, 11 oder 13) und in der rechten ein alternativer Pin für RX (6, 8, 10 oder 12). Um einen Arduino-Port für RX oder TX zu selektieren, steckt der Maker einen Jumper auf die zwei ISheeld+-Pins für den gewünschten Arduino-Port.

Der Einfachheit halber, bezeichne ich im Rest des Artikel die 1Sheeld-Familie (1Sheeld, 1Sheeld+) als 1Sheeld. Bei direkten Bezüge auf das iOS-fähige Board sage ich explizit 1Sheeld+.

Statt den hardwaremäßigen seriellen Port des Arduino zur Kommunikation zu benutzen, bietet 1Sheeld+ eine Pinreihe, um alternative Pins zu benutzen. Dazu sind die jeweils erwünschten Pins zu jumpern.
Statt den hardwaremäßigen seriellen Port des Arduino zur Kommunikation zu benutzen, bietet 1Sheeld+ eine Pinreihe, um alternative Pins zu benutzen. Dazu sind die jeweils erwünschten Pins zu jumpern.

Damit wären die Details für das Zusammenspiel von 1Sheeld und Arduino-Board erläutert. Wie aber kommen die beiden zu einem Rendezvouz mit dem Smartphone?

Koppeln von 1Sheeld+ und Smartphone

Damit das Arduino-Board über 1Sheeld mit einem iPhone oder Android-Phone zusammenspielen kann, müssen Benutzer die App 1Sheeld aus dem Apple App Store oder Google Play installieren. Nach Start der App erfolgt das Finden und Koppeln von 1Sheeld mit dem Smartphone:

Durch Betätigen von Scan startet der Benutzer die Suche nach dem BLE-basierten 1Sheeld+
Durch Betätigen von Scan startet der Benutzer die Suche nach dem BLE-basierten 1Sheeld+

Sind Smartphone beziehungsweise App mit 1Sheeld verbunden, bietet die App-Bedieneroberfläche zahlreiche virtuelle Shields zur Auswahl an, die sich einzeln oder gemeinsam mit anderen virtuellen Shields selektieren lassen:

Nach erfolgreicher Kopplung kann der Benutzer alle gewünschten virtuellen Shields selektieren. Im vorliegenden Fall sind das die Kamera und ein Barcode Scanner
Nach erfolgreicher Kopplung kann der Benutzer alle gewünschten virtuellen Shields selektieren. Im vorliegenden Fall sind das die Kamera und ein Barcode Scanner

Aufgabe der App ist zum einen die Bereitstellung der Sensoren und Funktionalitäten des Smartphones für den Arduino-Entwickler, und zum anderen die Interaktion mit dem Benutzer.

Shields, Shields, Shields

1Sheeld+ unterscheidet zwischen verschiedenen Kategorien virtueller Shields.

  • Basic I/O Shields dienen zur Ein- und Ausgabe. Darunter fallen das Vibration Shield (nur Android), Pattern Shield (zur Erkennung von Mustern aus einer 3 x 3 Punkte Matrix und Verbindungslinien), Gamepad Shield (Bereitstellung eines virtuellen Gamepads), Slider Shield, Push Button Shield, Toggle Button Shield, Buzzer Shield, 7 Segments Shield, LED Shield, Keypad Shield (virtuelle Tastatur beispielsweise zur Eingabe von Pin-Codes).
  • Sensor Shields erlauben einem Arduino-Sketch Zugriff auf interne Sensoren des Smartphones wie Sensoren für Fingerabdruck (nur iOS), Gesichtserkennung, Farberkennung, NFC (nur Android), Temperatur, Annäherung, Druck, Lage, Magnetfelderr, Licht (nur Android) Gravitation (nur Android), GPS, Mikrofon, Gyroskop, Beschleunigung.
  • Special Shields stellen spezielle Funktionalitäten des Smartphones zur Benutzung durch Arduino bereit. Darunter fallen Spracherkennung, Text-to-Speech, Terminal, Barcode Scanner (nur iOS), grafisches LCD (nur Android), Datenlogger, Music Player, LCD, Tastatur, Uhrzeit, Meldungen, Kamera.
  • Communication Shields bilden Kommunikationsschnittstellen für Arduino-Sketches wie Internet (HTTP), Telefone (nur Android), SMS (nur Android), Skype (nur Android), E-Mails.
  • Social Media Shields wiederum implementieren den Zugriff auf Foursquare, Facebook und Twitter.

Programmierung

Um auf die virtuellen Shields zuzugreifen, installiert der Maker zunächst wie folgt die Onesheeld-Bibliothek. Über den Menüpfad Sketch > Include Library > Manage Libraries ... öffnet sich das Fenster Library Manager. Bei Eingabe von "OneSheeld" im Suchfeld rechts oben taucht die gesuchte Bibliothek auf und lässt sich mit einem Knopfdruck installieren:

Installation der OneSheeld-Bibliothek in der Arduino IDE
Installation der OneSheeld-Bibliothek in der Arduino IDE

Um die Bibliothek zu nutzen, sind am Anfang des Arduino-Codes diverse Definitionen notwendig. Diese legen fest, welche virtuellen Shields zum Einsatz kommen sollen, und binden nur die tatsächlich benötigten Codeteile ein:

#define CUSTOM_SETTINGS
// Alle benötigten virtuellen Shields legt
// der Entwickler über #define fest

#define INCLUDE_TEXT_TO_SPEECH_SHIELD
#define INCLUDE_VOICE_RECOGNIZER_SHIELD

/* Zugriff auf die Bibliothek für 1Sheeld und 1Sheeld+ */

#include <OneSheeld.h>

Würde die 1Sheeld-Bibliothek immer naiv alle virtuellen Shields inkludieren, gerieten ressourcenbeschränkte Boards wie Arduino Uno rasch an ihre (Speicher-)Grenzen.

Das obige Beispiel verwendet die virtuellen Shields Text-to-Speech und Voice Recognition.

In der Methode setup() des Beispiels startet die Kommunikation zwischen Arduino-Firmware und OneSheeld-App via 1Sheeld:

void setup()
{
/* Starte die Kommunikation mit der Smartphone App OneSheeld */

OneSheeld.begin();
...
}

Die eigentliche Zusammenarbeit mit den virtuellen Shields erfolgt überwiegend in loop().

Das soll exemplarisch das unten abgedruckte Beispiel illustrieren. Zunächst spricht der Benutzer mit Hilfe des VoiceRecognition-UI ein Sprachkommando ins Smartphone. In Reaktion auf den jeweils erkannten Sprachbefehl, erzeugt der Arduino-Sketch eine textuelle Antwort, die das Text-to-Speech-Shield in eine Sprachausgabe am Smartphone umwandelt.

void loop()
{
// Neuen Sprachbefehl über Voice Recognition Shield empfangen?
if(VoiceRecognition.isNewCommandReceived())
{
// Was wurde im letzten Sprachbefehl übermittelt?
if(!strcmp("Guten Morgen", VoiceRecognition.getLastCommand()))
{
// Falls es ein "Guten Morgen" war,
// erzeugen wir über das virtuelle Shield
// TextToSpeech eine entsprechende Sprachausgabe

TextToSpeech.say("Guten Morgen liebe Leser");
}

...

}

Sagt der Benutzer am Smartphone zum Beispiel "Guten Morgen", antwortet 1Sheeld im obigen Sketch mit "Guten Morgen liebe Leser".

Zum Aufspielen des Sketches auf das Arduino-Board stellen Entwickler den Serial-Schalter (Serial Switch) nach rechts auf Schalterstellung "SW". Zur Ausführung dient die linke Schalterstellung "HW".

Erst die rechte Schalterstellung des Serial Switch (SW) ermöglicht das Flashen des Arduino-Boards
Erst die rechte Schalterstellung des Serial Switch (SW) ermöglicht das Flashen des Arduino-Boards

Beispiel

Natürlich kann dieser Beitrag nicht Projekte für sämtliche Shields beschreiben. Stattdessen soll ein einzelnes, zugegeben sehr einfaches Beispiel die Verwendung mehrerer Shields aus den verschiedenen Kategorien demonstrieren. Es geht um die sprachgesteuerte Ansteuerung eines Servomotors über 1Sheeld.

Das Schaltungsdiagramm in Fritzing gestaltet sich nicht weiter aufregend:

Ein Servo ist über 5V, GND und Pin 8 (Steuerleitung) an 1Sheeld+/Arduino Uno angeschlossen
Ein Servo ist über 5V, GND und Pin 8 (Steuerleitung) an 1Sheeld+/Arduino Uno angeschlossen

Der Sketch gestaltet sich sehr einfach, weil die meiste Funktionalität auf 1Sheeld und seine APIs fußt. Über das Voice Recognizer Shield formuliert der Benutzer ein Kommando an den Arduino. Kommandos können sein "rechts, "links", "gerade aus", "foto". Bei den ersten drei Kommandos bewegt der Sketch das Ruder (den Aufsatz am Servo-Motor) nach links, rechts oder gerade aus. Im Falle von "foto" löst der Arduino ein Foto am Smartphone aus und meldet dies zusätzlich über eine E-Mail.

///////////////////////////////////////////
//
// Demo von 1Sheeld
// Michael Stal, 2018
//
///////////////////////////////////////////


// Verwendete Shields:

#define CUSTOM_SETTINGS
#define INCLUDE_VOICE_RECOGNIZER_SHIELD
#define INCLUDE_TERMINAL_SHIELD
#define INCLUDE_TEXT_TO_SPEECH_SHIELD
#define INCLUDE_CAMERA_SHIELD
#define INCLUDE_EMAIL_SHIELD

#include <OneSheeld.h>

// Servo angeschlossen über Pin 8

#include <Servo.h>
const byte SERVOPIN = 8;

// Steuerung Servo wie ein Bootsruder
Servo ruder;
const char cmd_links[] = "links";
const char cmd_rechts[] = "rechts";
const char cmd_gerade[] = "gerade aus";
const int gerade = 90;
const int links = 135;
const int rechts = 45;

// Sprachbefehl für Kameraufnahme und email
const char cmd_foto[] = "foto";

// Erfolgreiche Befehlsdurchführung quittiert mit:
const char ready[] = "fertig";

/////////////////////////////////////////////////
//
// setup() initialisiert OneSheeld und
// meldet Servo an Pin SERVOPIN
//
/////////////////////////////////////////////////

void setup() {
OneSheeld.begin(); // initialisieren
ruder.attach(SERVOPIN);
}

/////////////////////////////////////////////////
//
// loop() enthält
// die Befehlsschleife
//
/////////////////////////////////////////////////

void loop() {
// Neues Sprachkommando verfügbar?
if(VoiceRecognition.isNewCommandReceived()) { // ja
const char * cmd = VoiceRecognition.getLastCommand(); // Kommando
Terminal.println(cmd);
if (!strcmp(cmd_links, cmd)) {
// "links" => ruder nach links
ruder.write(links);
}
if (!strcmp(cmd_rechts,cmd)) {
// "rechts" => ruder nach rechts
ruder.write(rechts);
}
if (!strcmp(cmd_gerade,cmd)) {
// "gerade aus" => ruder nach gerade aus
ruder.write(gerade);
}
if (!strcmp(cmd_foto, cmd)) {
// "foto" => Foto machen und email senden
Camera.setFlash(ON);
Camera.rearCapture();
Email.send("michael.stal@gmail.com", "Foto gemacht", "Jemand hat über 1Sheeld+ ein Foto ausgelöst");
OneSheeld.delay(2000);
}
// Bestätigung der Befehls-Ausführung:
TextToSpeech.say(ready);
}
}

Zum Upload des Sketches aus der Arduino IDE stellen wir am 1Sheeld den Serial Switch auf "SW", danach auf "HW".

Im Smartphone stellen wir über die App 1Sheeld die Verbindung zum erkannten 1Sheeld her. Daraufhin wechselt die blaue Bluetooth-LED, wie bereits weiter oben beschrieben, vom Blinken zum kontinuierlichen Leuchten.

Nun stellt der Benutzer in 1Sheeld die von ihm/ihr benötigten virtuellen Shields zusammen:

Schritt 2: Die benötigten Shields (Terminal, EMail, Camera, Voice Recognizer, Text-to-Speech) wurden in der App ausgewählt
Schritt 2: Die benötigten Shields (Terminal, EMail, Camera, Voice Recognizer, Text-to-Speech) wurden in der App ausgewählt

Während der Sketchausführung dient die 1Sheeld-App als Bindeglied zwischen Smartphone und Arduino. Im Voice Recognizer geben wir Sprachbefehle ein, die der Arduino dann direkt umsetzt, indem er zum Beispiel den Servo ansteuert, ein Foto schießt, oder eine Email verschickt.

In der folgenden Abbildung hat der den Sprachbefehl "links" registriert. Daraufhin bewegt sich das Servo nach links. Und am Schluss meldet die Stimme des Text-to-Speech-Shields am Smartphone "fertig".

Schritt 3: Die App hat im Voice Recognizer den Befehl &quot;links&quot; erkannt
Schritt 3: Die App hat im Voice Recognizer den Befehl "links" erkannt

Das nächste Foto des Versuchsaufbaus hat der Sketch auf das Sprachkommando "foto" selbst geschossen:

Foto der Versuchsanordnung, von dem Sketch geschossen
Foto der Versuchsanordnung, von dem Sketch geschossen

Das Beispiel mag trivial sein, verdeutlicht aber die grundsätzlichen Möglichkeiten von 1Sheeld+. So lassen sich RC-Modelle steuern, Roboterbewegungen per Hand dirigieren, Octocoupler steuern, Lampen orchestrieren, soziale Medien einbinden, um nur wenige Beispiele zu nennen. Zahlreiche YouTube-Videos und Instructables zeigen, dass die Fantasie von Makern hier kaum Grenzen kennt.

Fazit

Echte Produkte auf Basis von 1Sheeld dürften eher selten das Ziel von Makern sein, wenn gleich dies nicht völlig auszuschließen ist. Immerhin müssten Erfinder das Smartphone als Bestandteil der Lösung mitliefern oder den Kunden dazu überreden, sein Phone mit der 1Sheeld-App auszustatten und mit der 1Sheeld-Hardware zu koppeln.

In der Abbildung ist eine der Ausnahmen zu sehen, die Schematik eines Amazon Echo Klons. Details zum Umsetzen des Do-it-Yourself-Projekts finden sich auf hackster.io [1].

Ahmed Ismail, einer der 1Sheeld-Erfinder, demonstriert den Bau eines Geräts mit Hilfe von 1Sheeld, das Alexa (Amazon Echo)  &quot;nachbaut&quot;
Ahmed Ismail, einer der 1Sheeld-Erfinder, demonstriert den Bau eines Geräts mit Hilfe von 1Sheeld, das Alexa (Amazon Echo) imitiert (Bild: 1sheeld.com)

Das "Mega-Shield" eignet sich hervorragend dafür, prototypische Lösungen zu erstellen, und mit virtuellen Shields zu experimentieren statt sofort auf reale Shields zu setzen. Preise von knapp über 50 Euro erscheinen für das Produkt daher angemessen. Das gilt um so mehr, als es sich um Open Source Hardware handelt, für die der Maker auf alle Schaltungen, Pläne und den Source Code zugreifen kann.

Weiterer Vorteil sind die von den Erfindern auf YouTube [2] und anderen Kanälen (z.B. auf der 1Sheeld-Website [3]) bereitgestellten Video-Tutorials, weil sie die Funktionalitäten verständlich und in leicht verdaulichen Häppchen präsentieren.

Danksagung

Ich möchte mich bei Ahmed Ismail von 1Sheeld bzw. Integreight, Inc, bedanken, der mir für den Beitrag ein 1Sheeld+ kostenlos zur Verfügung gestellt hat. Ahmed ist Mitschöpfer des Shields und Autor vieler erfrischender YouTube-Tutorials von 1Sheeld. Die Firma selbst – wie gesagt 1Sheeld ist komplett Open Source – stammt aus Ägypten. Was beweist, dass coole Ideen auch aus dem Nahen Osten kommen können, nicht nur aus USA, Europa oder China.


URL dieses Artikels:
http://www.heise.de/-4024353

Links in diesem Artikel:
[1] https://www.hackster.io/ahmedismail3115/arduino-based-amazon-echo-using-1sheeld-84fa6f
[2] https://www.youtube.com/channel/UCDiRrgZ2-ZSL7t6XK0eIjhQ
[3] https://1sheeld.com/tutorials/

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 18. April 2018 um 11:58

Maple Mini - ein weiteres STM32F103-Board

Von heise online

zurück zum Artikel

Nachdem im letzten Teil die Blue Pill im Fokus stand, konzentriert sich der vorliegende Kurzbeitrag auf das Maple Mini Board. Auch dieses enthält einen ARM Cortex M3 mit 72 MHz Taktfrequenz. Im Gegensatz zur Blue Pill lässt das Maple Mini einen Anschluss über Micro-USB zu.

Das Maple Mini Board

Hersteller des Maple Mini war ursprünglich die Firma LeafLabs, die das Board im Jahr 2011 auf den Markt brachte. LeafLabs liefert das Board zwar nicht mehr, hat aber dessen Design als Open Source zur Verfügung gestellt.

Das Maple Mini von LeafLabs gibt es bereits seit 2011
Das Maple Mini von LeafLabs gibt es bereits seit 2011

Das ist der Grund, warum sich heute zahlreiche Klone im Angebot der Online-Händler befinden. Bei ebay ist ein Board für rund 1,87€ aus chinesischer Produktion zu haben. Speziell die Nachbauten von Baite zeichnen sich durch eine sehr gute Qualität aus.

Ein Maple Mini Klon mit guter Qualität
Ein Maple Mini Klon mit guter Qualität

Bezüglich seiner Leistungsdaten entspricht ein Maple Mini der im letzten Beitrag [1] vorgestellten Blue Pill, weshalb sich dieser Artikel die erneute Beschreibung spart. Jedenfalls ist auch das Maple Mini in Sachen Performanz schon rein rechnerisch einem Arduino Uno Board um eine Größenordnung voraus.

Um ein Maple Mini wie ein Arduino Board in der Arduino IDE zu programmieren, gibt es den STM32duino Core, den wir ebenfalls in der letzten Blog-Folge kennengelernt haben. Auch seine Installation war dort schon sehr ausführlich beschrieben.

Aus Programmierersicht liegt im STM32duino Core folgende Pin-Belegung beim Maple Mini vor. Wie bereits bei der Blue Pill erläutert, müssen Cores für Arduino die nativen Pins auf ein neues Mapping abbilden.

Nur die Pins mit grün-weisser oder blau-weisser Beschreibung stellt der STM32Duino Core dem Entwickler zur Verfügung
Nur die Pins mit grün-weisser oder blau-weisser Beschreibung stellt der STM32Duino Core dem Entwickler zur Verfügung

Etwas gewöhnungsbedürftig beim Maple Mini ist das Fehlen eine Power-LED. Es ist also nicht immer ersichtlich, ob das Board läuft. Auf der anderen Seite hat dies den Vorteil, dass eine Schaltung dadurch im laufenden Betrieb ein paar Milliampere spart.

Auf dem Board sind rechts zwei Knöpfe zu sehen, die reset und but=32 heißen. Die Funktion des RESET-Knopfs dürfe eindeutig sein. Mit ihm versetzen Entwickler das Board in den Flashmodus. Nach dem Aufspielen der neuen Firmware beziehungsweise des neuen Sketches führt ein Betätigen des Knopfes das Board in den Ausführungsmodus. Der zweite Knopf lässt sich auch für eigene Anwendungen benutzen.

Im Gegensatz zur Blue Pill entfällt beim Maple Mini das lästige indirekte Verbinden mit einem UART-USB-to-TTL-Adapter. Stattdessen genügt es, das Board über Micro-USB direkt am Entwicklungsrechner anzuschließen.

Programmierung des Maple Mini

Nach Installation des STM32duino Cores (siehe Erläuterungen im letzten Beitrag [2]) steht in der Arduino IDE auch das Maple Mini Board zur Auswahl:

In der Arduino IDE steht das Maple Mini Board nach Installation des STM32duino Core zur Verfügung
In der Arduino IDE steht das Maple Mini Board nach Installation des STM32duino Core zur Verfügung

Bei Linux (siehe hier [3]) und Windows (siehe hier [4]) sind im Gegensatz zu macOS zuvor noch ein paar kleine Schritte notwendig, um mit dem Maple Mini und der Arduino IDE (STM32duino) loslegen zu können. Bei Windows betrifft das zum Beispiel die notwendigen Treiber für USB.

Beispielsanwendung Thermometer

In der Beispielsanwendung ist ein OLED-Display des Typs SSD1306 mit 124 x 64 Auflösung über I2C am Maple Mini angeschlossen. Zudem befindet sich ein DS18B20-Temperatursensor in der Schaltung, den wir mit Pin 2 des Maple Mini verbinden. Zusätzlich hängt ein 4.7KΩ-Widerstand zwischen Signalausgang des Temperatursensors und dem Pluspol der Stromversorgung.

Hier eine Impression vom laufenden System:

Das laufende System auf Basis des Maple Mini von Baite mit Temperatursensor und OLED-Display
Das laufende System auf Basis des Maple Mini von Baite mit Temperatursensor und OLED-Display. Links im Bild ist übrigens eine Blue Pill

Jede Sekunde erfolgt eine Messung der Temperatur und deren Ausgabe am OLED-Display.

Um die Schaltung nachbauen zu können, habe ich wie immer die Schaltung mittels Fritzing auf "Papier" gebannt.. Es ergibt sich folgendes Schaltungsdiagramm:

Fritzing Schaltungsdiagramm für SSD1306 OLED und DS18B20 Temperatursensor an Maple Mini
Fritzing Schaltungsdiagramm für SSD1306 OLED und DS18B20 Temperatursensor an Maple Mini

Zum Glück belohnt das Schicksal die Tüchtigen. Für die Hardwarezugriffe auf die Komponenten der Schaltung haben andere Maker bereits existierende Bibliotheken angepasst. Für den Sketch sind folgende Bibliotheken notwendig:

  • OneWire.h für den Zugriff auf das OneWire-Protokoll
  • DallasTemperature.h für das Auslesen des Temperatursensors
  • Adafruit_GFX.h enthält Grafikroutinen für die Displayausgabe
  • Adafruit_SSD1306_STM32.h ist die Implementierung für STM32-Boards auf SSD1306-OLED-Displays mit Auflösung 128 x 64.

Als Basis für die Implementierung verwenden Sie das über File > Examples > Examples for Maple Mini > Adafruit_SSD1306 > ssd1306_128x64_i2c_STM32 verfügbare Projekt.

Achtung: Meldet der Compiler beim Übersetzen des unten abgebildeten Sketches den Fehler, dass er die Methode swap(x, y) nicht kennt, fügen Sie in die Headerdatei Adafruit_SSD1306_STM32.h vor der Klassendefinition class Adafruit_SSD1306 folgende Definition ein:

#define swap(a, b) { int16_t t = a; a = b; b = t; }

Dann sollte es problemlos funktionieren.

Der Sketch selbst ist nicht weiter aufregend. Im Setup initialisiert das Programm den Dallas 18B20 Sensor und das OLED-Display.

In der Ereignisschleife fragt der Code zunächst jede Sekunde den Sensor ab, und gibt den gemessenen Wert an der Anzeige aus.

//************************************************
// Maple Mini plus OLED SSD 1306 mit 128 x 64
// und DS18B20 Dallas Temperatursensor
// Demonstration zur Verwendung der Bibliotheken
// für Maple Mini in der Arduino IDE
//************************************************

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306_STM32.h>

// Zutaten: 1-Wire Protokoll und Sensor-Bibliothek
#include <OneWire.h>
#include <DallasTemperature.h>

// Der Bus hängt an Port 2 des Maple Mini Boards

#define ONE_WIRE_BUS 2

// 1-Wire-Protokoll initialisieren
OneWire oneWire(ONE_WIRE_BUS);

// ... und Referenz übernehmen
DallasTemperature sensors(&oneWire);

// OLED Display Typ 1306 mit 128 x 64 Pixel
// an I2C-Bus

// Adresse müssen Sie ggf. an Ihr Board
// anpassen !!!

const byte i2cAddress = 0x3C;

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

// Setup von Sensor und Display an I2C
void setup() {
// Bibliothek initialisieren

sensors.begin();

// Display vorbereiten
display.begin(SSD1306_SWITCHCAPVCC, i2cAddress);
display.display();
}

// Unsere Eventloop:
void loop() {
// Alle anwesenden Sensoren um Temperatur bitten
sensors.requestTemperatures();
// Wir nehmen den erstbesten
double temp = sensors.getTempCByIndex(0);
// Temperatur ausgeben
displayTemperature(temp);
// und eine Sekunde warten
delay(1000);
}

// Routine zur Temperaturausgabe:
void displayTemperature(double temperature) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("Temperatur");
display.println();
display.setTextSize(3);
display.println(temperature);
display.display();
}

Sobald die IDE das Programm erfolgreich kompiliert hat, fordert die Ausgabe dazu auf, das Maple Mini Board durch Druck des RESET-Knopfs in den Ausführungsmodus zu setzen. Erst danach beginnt die eigentliche Programmausführung.

Übersetzung in der Arduino IDE. Zum Flash-Upload verwendet die STM32-Werkzeugkette dfu-util
Übersetzung in der Arduino IDE. Zum Flash-Upload verwendet die STM32-Werkzeugkette dfu-util

Programmieralternativen

Im vorangegangenen Teil über die Blue Pill haben wir bereits einige Alternativen zur Arduino IDE kennengelernt, etwa STM32CubeMX oder die OpenSTM32 System Workbench. Daher kann dieser Abschnitt kurz bleiben.

Weitgehend unerwähnt sollen an dieser Stelle kommerzielle IDEs wie Keil bleiben.

Auch die interaktive und Web-basierte mbed-Plattform von ARM lässt sich für den Maple Mini nutzen. Ursprünglich gab es auch noch eine eigene Maple IDE, die aber inzwischen kaum noch jemand verwendet. Heute macht es ohnehin mehr Sinn, die Arduino IDE in Kombination mit dem STM32duino Core einzusetzen.

Fazit

Im letzten und in diesem Artikel lag der Fokus auf zwei Boards aus der STM32F103-Familie, die Blue Pill und das Maple Mini Board. Beide bieten exzellente Leistung zu einem guten Preis. Gerade für rechenintensivere Anwendungen macht der Einsatz dieser Controller Sinn. Dank STM32duino-Unterstützung erscheinen die Boards in der Arduino IDE wie Arduino-Boards, was den Umstieg oder besser Aufstieg spürbar leichter macht.

Auch wenn nicht immer alle (Arduino-)Bibliotheken zur Verfügung stehen, arbeitet die Community kontinuierlich daran, den Leistungsumfang zu erweitern. Für eigene Problemstellungen findet sich daher auch fast immer eine helfende und kompetente Hand. Daher brauchen sich selbst Anfänger nie verloren fühlen. Allerdings sind Blue Pill und Maple Mini nicht mehr ganz so pflegeleicht wie ihre reinen Arduino-Cousins, und erfordern wesentlich mehr Handarbeit und technisches Geschick.

Aus meiner Sicht überwiegen aber die Vorteile den Nachteilen deutlich. Bei einem Preis von wenigen Euros gibt es nicht wirklich etwas zu verlieren. Grund genug, auch in Zukunft immer wieder einen Blick auf die Welt der STM32-Embedded Controller zu werfen.


URL dieses Artikels:
http://www.heise.de/-4010625

Links in diesem Artikel:
[1] https://www.heise.de/developer/artikel/Keine-bittere-Pille-Die-Blue-Pill-mit-ARM-Cortex-M3-4009580.html
[2] https://www.heise.de/developer/artikel/Keine-bittere-Pille-Die-Blue-Pill-mit-ARM-Cortex-M3-4009580.html
[3] https://github.com/rogerclarkmelbourne/Arduino_STM32/wiki/Linux
[4] https://github.com/rogerclarkmelbourne/Arduino_STM32/wiki/Maple-drivers

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 05. April 2018 um 07:00

Keine bittere Pille - Die Blue Pill mit ARM Cortex M3

Von heise online

zurück zum Artikel

Im Arduino-Universum existieren von einigen Herstellern Arduino-kompatible Boards, die mit anderen Prozessoren als denen aus der ATMEL-Microprozessorfamilie aufwarten. Teensy, ESP8266 und ESP32 haben wir bereits kennengelernt. Von STMicroelectronics gibt es das Board STM32F103C8T6, das seine Anhänger Blue Pill nennen - ein Board mit ausgezeichnetem Preis-/Leistungsverhältnis.

Welcome, on Board

Warum die Blue Pill so heißt wie sie heißt, lässt sich dem folgenden Profilbild entnehmen:

Der Microcontroller STM32F103C8T6, oft nur unter seinem Kosenamen Blue Pill bekannt, liefert hohe Leistung für wenig Geld
Der Microcontroller STM32F103C8T6, oft nur unter seinem Kosenamen Blue Pill bekannt, liefert hohe Leistung für wenig Geld (Bild: http://wiki.stm32duino.com)

Mit einer 32Bit ARM-Cortex-M3-Architektur und einer Taktfrequenz von 72 MHz steckt die Blue Pill einen Arduino auf Basis des 8-Bit Prozessors ATMega328P mit 16 MHz Taktfrequenz performanzmäßig locker in die Tasche. 64 KB (manchmal auch 128 KB) Flashspeicher und dazu 20 KB RAM bieten genügend Reserven für viele Aufgabenstellungen. Zudem beinhaltet das Board eine mit einem separaten Quarz auf 32 MHz getaktete Echtzeituhr (RTC). Im Normalbetrieb unterstützt der Mikrocontroller ein Logiklevel von 3.3V. Es sind zwar auch 5V möglich, wobei einige, aber nicht alle Pins 5V vertragen.

Für eine Blue Pill ist beim Dealer ein Obolus zwischen 2 und 5 Euro zu entrichten. Beschaffungskriminalität lohnt sich also nicht. Wie immer gilt: Je kleiner der Preis, desto näher liegt der Händler bei China.

Das Board verfügt über mehrere serielle Ports, und über mehrere SPI- und I2C-Busanschlüsse (siehe nachfolgende Abbildung des Pin-Layouts). Ein ADC mit 12-Bit-Auflösung lässt die genauere Messwerterfassung von Sensoren zu.

Und natürlich darf eine essenzielle Information nicht fehlen: die eingebaute LED der Blue Pill liegt am Pin PC13.

Die Pinbelegung zeigt, dass die Blue Pill einige nützliche Features besitzt, unter anderem mehrere serielle Ports, CAN- SPI- und I2C-Anschlüsse
Die Pinbelegung zeigt, dass die Blue Pill einige nützliche Features besitzt, unter anderem mehrere serielle Ports, CAN- SPI- und I2C-Anschlüsse

Mehr Details erfährt der Entwickler in einem von STMicroelectronics bereitgestellten Dokument[1].

Hinweis

Beim Performanzvergleich zwischen Cortex-M3 und ATMega328P lauern Fallstricke. Ein Beispiel gefällig: In der Arduino IDE gibt es zwar double und float als Datentypen. Beide sind auf Arduino-Boards aber identisch und umfassen jeweils 32 Bit. Auf einem Cortex-M3-Board wie der Blue Pill sind Werte des Typs double aber 64-Bit breit, haben also doppelte Größe. Beim Benchmarking ist daher wichtig, nicht Äpfel mit Birnen zu vergleichen.

Entwicklungshilfen

In dieser Folge konzentriere ich mich darauf, wie sich das Board mit Hilfe der Arduino IDE programmieren lässt. Allerdings ist das nur eine der Möglichkeiten. Die meisten anderen Möglichkeiten für den Entwickler sind teilweise besser geeignet - zumindest für Pros. Leider habe ich an dieser Stelle nicht die Möglichkeit, diese anzusprechen. Wenigstens sollen einige dieser Optionen zur Sprache kommen:

  • Mittels des STM32 Flash Tools[2] können Entwickler ihren Code beispielsweise mit Microsoft Visual Studio erstellen und das Ergebnis über den UART auf das Board laden.
  • Das umfangreiche Werkzeug STM32CubeMX[3] erlaubt die Codegenerierung für Projekte und entsprechende Werkzeugketten, ebenso die Erzeugung von Code für komplexere Embedded-Aufgaben mittels grafischer Wizards. Dabei lassen sich alle möglichen Bibliotheken aus dem STM32Cube importieren.
  • Über ST-Link V2, einen In-Circuit Debugger and Programmer, schließen Entwickler die Blue Pill an ihren Rechner an und nutzen zur Programmierung z.B. die kostenlose OpenSTM32[4] System Workbench auf Basis von Eclipse. Wer ein Nucleo-64-Board von STM besitzt, kann dessen ST-Link-Schnittstelle zum Programmieren benutzen.
  • Natürlich bevorzugen einige Entwickler Bare Metal Programming. Wie das geht, zeigt trebisky auf seiner Github-Seite[5].

Generell zu empfehlen ist auch die Blog-Seite[6], die über mehrere dieser Programmieroptionen schreibt.

Integration in die Arduino IDE

Zum Glück gibt es eine große Community namens STM32duino, die sich um das Integrieren von STM32-Boards in das Arduino-Ökosystem kümmert. Viele Informationen, Tipps und Tricks sind auf deren Website[7] zu finden. Ein Besuch dieser Webseiten ist daher sehr zu empfehlen.

Doch nun in medias res. Um Unterstützung für die Blue Pill in die Arduino IDE zu integrieren, bedarf es mehrere Schritte. Dazu nötig ist mangels ST-Link-Programmer eine serielle Verbindung zu einem FTDI-Board oder einem anderen UART-USB-to-TTL-Adapter.

Schritt 1: Blue Pill mit UART-USB-to-TTL-Adapter verbinden

Zunächst sind die notwendigen Verbindungen zwischen Blue Pill und dem verwendeten UART-USB-to-TTL-Adapter zu etablieren (siehe Abbildung). Nach dem Anschluss des Ganzen per USB an den Computer blinkt normalerweise die LED an PC13, weil der Blink-Sketch bei der Produktion zu Testzwecken aufgespielt wurde.

Was genau zu tun ist:

  • Die Stromversorgung des FTDI-Adapter (Vcc, GND) verbinden wir mit 3.3V und GND an der Blue Pill.
  • An Pin A9 liegt der TX-Ausgang der Blue Pill und ist mit dem RX-Eingang des Adapters zu verdrahten.
  • Pin A10 der Blue Pill entspricht dem RX-Eingang und ist entsprechend mit dem TX-Ausgang des Adapters zu verbinden.
Verbindung von Blue Pill und UART-USB-to-TTL-Adapter
Verbindung von Blue Pill und UART-USB-to-TTL-Adapter

Schritt 2: Board-Manager für Arduino SAM Boards laden

Im nächsten Schritt gehen Sie über Tools > Boards > Boards Manager, suchen nach Arduino SAM Boards (ARM Cortex-M3) und installieren den entsprechenden Board-Manager.

Im zweiten Schritt ist die Installation des Boardmanagers für ARM Cortex M3 Boards notwendig
Im zweiten Schritt ist die Installation des Boardmanagers für ARM Cortex M3 Boards notwendig

Schritt 3: STM32duino Coreinstallieren

Roger Clark ist Master des Githubs für STM32-basierte Arduino Cores. Laden Sie sich über dessen Github-Seite[8] das gesamte Paket als ZIP-Archiv herunter. Damit lassen sich Blue Pills in der Arduino IDE wie native Arduino Boards programmieren.

Auf der Github-Seite von STM32DUINO ist das Zip-Archiv verfügbar
Auf der Github-Seite von STM32DUINO ist das Zip-Archiv verfügbar

Das Archiv gilt es zu entpacken und das daraus resultierende Verzeichnis Arduino_STM32 in das Sketchbook-Verzeichnis der Arduino IDE zu kopieren, zum Beispiel

  • unter Windows als Unterverzeichnis von My Documents\Arduino\Hardware
  • unter macOS als Unterverzeichnis von ~/Documents/Arduino/hardware

Sollte das Hardware-Verzeichnis noch nicht existieren, muss es angelegt werden. Danach verlassen Sie die Arduino IDE und starten die IDE erneut. Jetzt können Sie nicht nur Blue Pill, sondern auch andere Boards von STM unter der Arduino IDE nutzen.

Schritt 4: Blue Pill Einstellungen setzen

Gehen Sie in der Arduino IDE unter Tools und konfigurieren Sie das entsprechende Board (siehe links oben in der Abbildung)..

Für die Blue Pill ist das die Generic STM32F103C8 series die richtige Wahl als Board
Für die Blue Pill ist das die Generic STM32F103C8 series die richtige Wahl als Board

Unter Menüpunkt Variant sollten Sie einstellen: STM32F103C8 (20k RAM. 64k Flash).

Danach als Upload method: "Serial" (es sei denn, Sie verwenden eine andere Variante des Programmers wie etwa ST-LINK).

Unter Port spezifizieren Sie den von dem UART-USB-to-TTL Adapter verwendeten seriellen Port. Nutzen Sie etwas anderes als einen FTDI-basierten Adapter, ist zuvor eventuell das zusätzliche Installieren eines für Ihren Adapter bestimmten USB-Treibers notwendig.

Schritt 5: Testsketch programmieren

Im Menüpfad File > Examples > A_STM32-Examples > Digital können Sie als Testprogramm beispielsweise Blink wählen. Port PB1 ändern Sie dabei in PC13. Oder Sie schreiben einfach einen eigenen Testsketch. Mein simpler Sketch für das LED-Blinken sieht wie folgt aus:

void setup() {
pinMode(PC13, OUTPUT); // OnBoard-LED liegt an PC13
Serial.begin(9600); // Ausgabe am seriellen Monitor
}

void loop() {
digitalWrite(PC13, !digitalRead(PC13)); // LED invertieren
Serial.println(digitalRead(PC13) ? "low" : "high"); // -> ser. Monitor
delay(1000); // Pause einlegen
}

Bevor sich der Sketch auf die Blue Pill laden lässt, ist das Setzen des Blue Pill in den Programmiermodus wichtig. Zu diesem Zweck bewegen Sie den oberen gelben Jumper (BOOT0) von Position 0 auf 1 (im nachfolgenden Bild von links nach rechts), und drücken anschließend die RESET-Taste. Der untere Jumper BOOT1 bleibt dabei stets unverändert.

Den BOOT1-Jumper können Sie übrigens für eigene Anwendungen nutzen. Er hat sonst keine andere Funktion.

Um einen Sketch hochlasden zu können, muss der BOOT0-Jumper (oben) auf 1 gestellt, und anschließend ein Reset durchgeführt werden.
Um einen Sketch hochladen zu können, muss der BOOT0-Jumper (oben) auf 1 gestellt, und anschließend ein Reset durchgeführt werden.

Nun kann die Arduino IDE den kompilierten Sketch auf die Blue Pill laden. Hat das geklappt, passiert folgendes: Die Onboard-LED blinkt. Im seriellen Monitor sehen Sie zeilenweise eine Folge von "low" und "high"-Nachrichten.

Soll der Sketch nach einer Änderung neu auf das Board geladen werden und ist der BOOT0-Jumper immer noch auf Stellung 1 positioniert, genügt ein Reset vor dem Sketch-Upload. Wollen Sie hingegen ein Überschreiben des Sketches verhindern, setzen Sie diesen Jumper auf Position 0 zurück.

Port Mapping

Um die in der Arduino IDE verwendbaren Port-Namen zu kennen, genügt ein Blick auf die Implementierung des STM32duino Core, genauer gesagt auf die Headerdatei board.h:

...Header board.h ....

#define BOARD_NR_USARTS 3
#define BOARD_USART1_TX_PIN PA9
#define BOARD_USART1_RX_PIN PA10
#define BOARD_USART2_TX_PIN PA2
#define BOARD_USART2_RX_PIN PA3
#define BOARD_USART3_TX_PIN PB10
#define BOARD_USART3_RX_PIN PB11

#define BOARD_NR_SPI 2
#define BOARD_SPI1_NSS_PIN PA4
#define BOARD_SPI1_MOSI_PIN PA7
#define BOARD_SPI1_MISO_PIN PA6
#define BOARD_SPI1_SCK_PIN PA5

#define BOARD_SPI2_NSS_PIN PB12
#define BOARD_SPI2_MOSI_PIN PB15
#define BOARD_SPI2_MISO_PIN PB14
#define BOARD_SPI2_SCK_PIN PB13

#define BOARD_NR_GPIO_PINS 35
#define BOARD_NR_PWM_PINS 12
#define BOARD_NR_ADC_PINS 9
#define BOARD_NR_USED_PINS 4

#define BOARD_JTMS_SWDIO_PIN 22
#define BOARD_JTCK_SWCLK_PIN 21
#define BOARD_JTDI_PIN 20
#define BOARD_JTDO_PIN 19
#define BOARD_NJTRST_PIN 18

#define BOARD_USB_DISC_DEV GPIOB
#define BOARD_USB_DISC_BIT 10

// Note this needs to match with the PIN_MAP array in board.cpp
enum {
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13,PA14,PA15,
PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13,PB14,PB15,
PC13, PC14,PC15
};

...

Beim Entwickeln in der Arduino IDE können Programmierer die obigen Bezeichner nutzen.

Demobeispiel

Jetzt soll ein etwas komplexerer Sketch demonstrieren, dass sich durchaus für die Blue Pill Bibliotheken in der Arduino IDE so nutzen lassen als hätten wir ein natives Arduino-Board vor uns. Im Beispiel ist ein Temperatursensor des Typs Dallas DS18B20 angeschlossen. Zu dessen Nutzung hat Maxim (der heutige Name des Herstellers) den OneWire-Bus eingeführt. Den OneWire-Bus und den Sensor hatte ich bereits in einem früheren Beitrag[9] illustriert. Zwischen Dateneingang und Versorgungseingang des Sensors ist ein 4.7 KΩ notwendig.

Das Schaltbild erweitert sich wie folgt:

Blue Pill und DS18B20 gehen gemeinsame Wege
Blue Pill und DS18B20 gehen gemeinsame Wege

Der Sensor (links oben in der Schaltung) ist über Pin PA2 angeschlossen.

Der Sketch ist eher einfach gestrickt. Er soll einfach in jedem Zyklus den Sensorwert des DS18B20 erfassen und am seriellen Monitor ausgeben:

//************************************************
// Blue Pill plus DS18B20 Dallas Temperatursensor
// Demonstration zur Verwendung der Bibliotheken
// fuer Blue Pill in der Arduino IDE
//************************************************

// Zutaten: 1-Wire Protokoll und Sensor-Bibliothek
#include
#include

// Der Bus haengt an Port PA2 des STM32F103CT6 Boards
#define ONE_WIRE_BUS PA2

// 1-Wire-Protokoll initialisieren
OneWire oneWire(ONE_WIRE_BUS);

// ... und Referenz übergeben
DallasTemperature sensors(&oneWire);

// Generelles Setup von seriellem Monitor und der
// Sensor-Bibliothek

void setup(void)
{
Serial.begin(9600); // seriellen Monitor starten
Serial.println("Demo des DS18B20 Sensors an der Blue Pill");

// Bibliothek initialisieren
sensors.begin();
}

// Unser Thermometer dreht sich im Kreis

void loop(void) {
// Alle anwesenden Sensoren um Temperatur bitten
sensors.requestTemperatures();

// Wir nehmen den erstbesten
Serial.println(sensors.getTempCByIndex(0));

delay(1000); // und goennen uns eine Sekunde Pause
}

Wir lernen: Einige Arduino-Bibliotheken funktionieren auch für STM32-Boards. Aber: Speziell Bibliotheken mit direktem Hardwarezugriff oder Einsatz von AVR Inline-Assembler-Code können auf der Blue Pill nicht laufen. Zum Glück arbeitet die STM32duino-Welt kontinuierlich an der Integration von Bibliotheken.

Kommunikation mit der Aussenwelt

Von Natur aus, ist eine Blue Pill ist sehr schweigsam und besitzt keinen IC für WiFi oder Bluetooth. Abhilfe schaffen können Maker zum Beispiel mit dem ESP-01 aus der ESP8266-Familie. Eine Implementierung für den Zugriff auf ein ESP8266-Board im AT-Kommandomodus liefert Steve Strong (siehe hier[10]). Steve hat einen minimalistischen Webserver implementiert, um LEDs über einen Browser zu schalten oder deren Zustand abzufragen (Anm.: In einem vergangenen Beitrag[11] hatte ich das Zusammenspiel von Arduino mit ESP-01 im AT_Kommandomodus beschrieben).

Eine Integration von Websockets [12] stammt vom gleichen Autor.

Problem Child?

Leider haben die meisten Chargen der Blue Pill einen kleinen Fehler eingebaut. An D+ (siehe Abbildung) wäre ein 1.5 KΩ Pull-up-Widerstand notwendig. Stattdessen findet sich dort ein Widerstand mit 4.7 KΩ oder 10 KΩ. Hat der Widerstand die Aufschrift 103, so handelt es sich um einen Widerstand mit 10 KΩ, bei Code 472 indessen um einen 4.7 KΩ Widerstand. Der korrekte Code lautet aber 153 (= 1.5 * 103).

Das bleibt meistens ohne Folgen, oder es macht sich durch sporadische Probleme beim Sketch-Upload bemerkbar. Auf meinem iMac muss ich bei einigen Blue Pills öfters den Upload durchführen bis es klappt.

Wollen Maker das Problem lösen, müssen sie Hand anlegen. Entweder sie entfernen den fehlerhaften SMD-Widerstand und ersetzen ihn durch einen neuen. Oder sie verwenden die ästhetisch nicht ganz astreine Lösung aus folgender Abbildung:

http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html
Um den Fehler auszumerzen, löten Sie den falschen Widerstand in einer Reflow-Station aus und bringen einen geeigneten Widerstand an. Alternativ können Sie das Problem auch so lösen wie in der Abbildung (Bild: http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html)

Als reine Softwarelösung schlägt Amitesh Singh (von ihm stammt auch die obige Abbildung) vor[13], folgende Codesequenz am Anfang eines Programms einzubauen:

// Notwendig bei inkorrektem Pull-up-Widerstand an D+
// Ein Muss für chinesische Boards des Typs stm32f103c8t6, auch bekannt als "Blue Pill"
rcc_periph_clock_enable(RCC_GPIOA);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
gpio_clear(GPIOA, GPIO12);
msleep(5); // Pause

Das klingt zwar etwas nach Dieselabgas-Affäre, funktioniert aber tatsächlich.

Fazit

Eine Blue Pill bietet zu einem günstigen Preis sehr gute Leistung. Dank der Aktivitäten der STM32duino-Community lässt sie sich in der gewohnten Arduino IDE programmieren, wobei einige Bibliotheken funktionieren, aber nicht alle. Die Blue Pill ist nur eine Vertreterin der unterstützten STM32-Boards. Es gibt viele weitere, auf die der Beitrag aus Platzgründen nicht eingehen kann. Diese kommen in zukünftigen Postings zur Sprache, etwa das Maple-Board, das wie die Blue Pill aus der STM32F103-Familie stammt. Beim Entwickeln mit Blue Pills verlassen Programmierer ein wenig ihre Komfortzone, weil die Unterstützung für Arduino-Boards noch viel umfangreicher ist. Auf der anderen Seite bieten sich im STM32-Universum viele unterschiedliche Werkzeugketten an, die Debugging gut unterstützen, sich ebenfalls für Pros eignen, oder sogar die Generierung von Projekten erlauben wie STM32Cube.

Ein Eintauchen in die Welt der Blue Pill und ihrer Verwandten macht jedenfalls Spaß und erweitert den Horizont.


URL dieses Artikels:
http://www.heise.de/-4009580

Links in diesem Artikel:
[1] http://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171190.pdf/files/CD00171190.pdf/jcr:content/translations/en.CD00171190.pdf
[2] http://www.st.com/en/development-tools/flasher-stm32.html
[3] http://www.st.com/en/ecosystems/stm32cube.html?querycriteria=productId=SC2004
[4] http://www.openstm32.org/HomePage
[5] https://github.com/trebisky/stm32f103
[6] https://satoshinm.github.io/blog/171212_stm32_blue_pill_arm_development_board_first_look_bare_metal_programming.html
[7] http://www.stm32duino.com
[8] https://github.com/rogerclarkmelbourne/Arduino_STM32
[9] https://www.heise.de/developer/artikel/Lauschen-mit-Sensoren-3217195.html
[10] https://github.com/stevstrong/STM32_ESP01_WebServer
[11] https://www.heise.de/developer/artikel/Ueberraschungsei-fuer-Wetterfroesche-dank-BME680-ESP8266-Arduino-ThingSpeak-3979158.html
[12] http://www.stm32duino.com/viewtopic.php?f=19&amp;t=3281
[13] http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 03. April 2018 um 10:19

Blue Pill - STM32 ARM Cortex M3 Boards

Von heise online

zurück zum Artikel

Im Arduino-Universum existieren von einigen Herstellern Arduino-kompatible Boards, die mit anderen Prozessoren als denen aus der ATMEL-Microprozessorfamile aufwarten. Teensy, ESP8266 und ESP32 haben wir bereits kennengelernt. Von STMicroelectronics gibt es das Board STM32F103C8, das seine Anhänger Blue Pill nennen - ein Board mit ausgezeichnetem Preis-/Leistungsverhältnis.

Welcome, on Board

Warum die Blue Pill so heißt wie sie heißt, lässt sich dem folgenden Profilbild entnehmen:

Der Microcontroller STM32F103C8, oft nur unter seinem Kosenamen Blue Pill bekannt, liefert hohe Leistung für wenig Geld
Der Microcontroller STM32F103C8, oft nur unter seinem Kosenamen Blue Pill bekannt, liefert hohe Leistung für wenig Geld (Bild: http://wiki.stm32duino.com)

Mit einer 32Bit ARM-Cortex-M3-Architektur und einer Taktfrequenz von 72 MHz steckt die Blue Pill einen Arduino auf Basis des ATMega328P performanzmäßig locker in die Tasche. 64 KB (manchmal auch 128 KB) Flashspeicher und dazu 20 KB RAM bieten genügend Reserven für viele Aufgabenstellungen. Zudem beinhaltet das Board eine mit 32 MHz getaktete Echtzeituhr (RTC). Im Normalbetrieb unterstützt der Mikrocontroller ein Logiklevel von 3.3V. Es sind zwar auch 5V möglich, wobei einige, aber nicht alle Pins 5V vertragen.

Für eine Blue Pill ist beim Dealer ein Obolus zwischen 2 und 5 Euro zu entrichten. Wie immer gilt: Je kleiner der Preis, desto näher liegt der Händler an China.

Das Board verfügt über mehrere serielle Ports, und über mehrere SPI- und I2C-Busanschlüsse (siehe nachfolgende Abbildung des Pin-Layouts). Ein ADC mit 12-Bit-Auflösung lässt die genauere Messwerterfassung von Sensoren zu.

Und natürlich darf eine essenzielle Information nicht fehlen: die eingebaute LED der Blue Pill liegt am Pin PC13.

Die Pinbelegung zeigt, dass die Blue Pill einige nützliche Features besitzt, unter anderem mehrere serielle Ports, CAN- SPI- und I2C-Anschlüsse
Die Pinbelegung zeigt, dass die Blue Pill einige nützliche Features besitzt, unter anderem mehrere serielle Ports, CAN- SPI- und I2C-Anschlüsse

Mehr Details erfährt der Entwickler in einem von STMicroelectronics bereitgestellten Dokument[1].

Hinweis

Beim Performanzvergleich zwischen Cortex-M3 und ATMega328P lauern Fallstricke. Ein Beispiel gefällig: In der Arduino IDE gibt es zwar double und float als Datentypen. Beide sind auf Arduino-Boards aber identisch und umfassen jeweils 32 Bit. Auf einem Cortex-M3-Board wie der Blue Pill sind Werte des Typs double aber 64-Bit breit, haben also doppelte Größe. Beim Benchmarking ist daher wichtig, nicht Äpfel mit Birnen zu vergleichen.

Entwicklungshilfen

In dieser Folge konzentriere ich mich darauf, wie sich das Board mit Hilfe der Arduino IDE programmieren lässt. Allerdings ist das nur eine der Möglichkeiten. Die meisten anderen Möglichkeiten für den Entwickler sind teilweise besser geeignet - zumindest für Pros. Leider habe ich an dieser Stelle nicht die Möglichkeit, diese anzusprechen. Wenigstens sollen einige dieser Optionen zur Sprache kommen:

  • Mittels des STM32 Flash Tools[2] können Entwickler ihren Code beispielsweise mit Microsoft Visual Studio erstellen und das Ergebnis über den UART auf das Board laden.
  • Das umfangreiche Werkzeug STM32CubeMX[3] erlaubt die Codegenerierung für Projekte und entsprechende Werkzeugketten, ebenso die Erzeugung von Code für komplexere Embedded-Aufgaben mittels grafischer Wizards. Dabei lassen sich alle möglichen Bibliotheken aus dem STM32Cube importieren.
  • Über ST-Link V2, einen In-Circuit Debugger and Programmer, schließen Entwickler die Blue Pill an ihren Rechner an und nutzen zur Programmierung z.B. die kostenlose OpenSTM32[4] System Workbench auf Basis von Eclipse. Wer ein Nucleo-64-Board von STM besitzt, kann dessen ST-Link-Schnittstelle zum Programmieren benutzen.
  • Natürlich bevorzugen einige Entwickler Bare Metal Programming. Wie das geht, zeigt trebisky auf seiner Github-Seite[5].

Generell zu empfehlen ist auch die Blog-Seite[6], die über mehrere dieser Programmieroptionen schreibt.

Integration in die Arduino IDE

Zum Glück gibt es eine große Community namens STM32duino, die sich um das Integrieren von STM32-Boards in das Arduino-Ökosystem kümmert. Viele Informationen, Tipps und Tricks sind auf deren Website[7] zu finden. Ein Besuch dieser Webseiten ist daher sehr zu empfehlen.

Doch nun in medias res. Um Unterstützung für die Blue Pill in die Arduino IDE zu integrieren, bedarf es mehrere Schritte. Dazu nötig ist mangels ST-Link-Programmer eine serielle Verbindung zu einem FTDI-Board oder einem anderen UART-USB-to-TTL-Adapter.

Schritt 1: Blue Pill mit UART-USB-to-TTL-Adapter verbinden

Zunächst sind die notwendigen Verbindungen zwischen Blue Pill und dem verwendeten UART-USB-to-TTL-Adapter zu etablieren (siehe Abbildung). Nach dem Anschluss des Ganzen per USB an den Computer blinkt normalerweise die LED an PC13, weil der Blink-Sketch bei der Produktion zu Testzwecken aufgespielt wurde.

Was genau zu tun ist:

  • Die Stromversorgung des FTDI-Adapter (Vcc, GND) verbinden wir mit 3.3V und GND an der Blue Pill.
  • An Pin A9 liegt der TX-Ausgang der Blue Pill und ist mit dem RX-Eingang des Adapters zu verdrahten.
  • Pin A10 der Blue Pill entspricht dem RX-Eingang und ist entsprechend mit dem TX-Ausgang des Adapters zu verbinden.
Verbindung von Blue Pill und UART-Usb-to-TTL-Adapter
Verbindung von Blue Pill und UART-Usb-to-TTL-Adapter

Schritt 2: Board-Manager für Arduino SAM Boards laden

Im nächsten Schritt gehen Sie über Tools > Boards > Boards Manager, suchen nach Arduino SAM Boards (ARM Cortex-M3) und installieren den entsprechenden Board-Manager.

Im zweiten Schritt ist die Installation des Boardmanagers für ARM Cortex M3 Boards notwendig
Im zweiten Schritt ist die Installation des Boardmanagers für ARM Cortex M3 Boards notwendig

Schritt 3: STM32duino Coreinstallieren

Roger Clark ist Master des Githubs für STM32-basierte Arduino Cores. Laden Sie sich über dessen Github-Seite[8] das gesamte Paket als ZIP-Archiv herunter. Damit lassen sich Blue Pills in der Arduino IDE wie native Arduino Boards programmieren.

Auf der Github-Seite von STM32DUINO ist das Zip-Archiv verfügbar
Auf der Github-Seite von STM32DUINO ist das Zip-Archiv verfügbar

Das Archiv gilt es zu entpacken und das daraus resultierende Verzeichnis Arduino_STM32 in das Arduino IDE Sketchbook Verzeichnis auf den Computer zu kopieren, zum Beispiel

  • unter Windows als Unterverzeichnis von My Documents\Arduino\Hardware
  • unter macOS als Unterverzeichnis von ~/Documents/Arduino/hardware

Sollte das Hardware-Verzeichnis noch nicht existieren, muss es angelegt werden. Danach verlassen Sie die Arduino IDE und starten die IDE erneut. Jetzt können Sie nicht nur Blue Pill, sondern auch andere Boards von STM unter der Arduino IDE nutzen.

Schritt 4: Blue Pill Einstellungen setzen

Gehen Sie in der Arduino IDE unter Tools und konfigurieren Sie das entsprechende Board (siehe links oben in der Abbildung)..

Für die Blue Pill ist das die Generic STM32F103C8 series die richtige Wahl als Board
Für die Blue Pill ist das die Generic STM32F103C8 series die richtige Wahl als Board

Unter Menüpunkt Variant sollten Sie einstellen: STM32F103C8 (20k RAM. 64k Flash).

Danach als Upload method: "Serial" (es sei denn, Sie verwenden eine andere Variante des Programmers wie etwa ST-LINK).

Unter Port spezifizieren Sie den von dem UART-USB-to-TTL Adapter verwendeten seriellen Port. Nutzen Sie etwas anderes als einen FTDI-basierten Adapter, ist zuvor eventuell das zusätzliche Installieren eines für Ihren Adapter bestimmten USB-Treibers notwendig.

Schritt 5: Testsketch programmieren

Im Menüpfad File > Examples > A_STM32-Examples > Digital können Sie als Testprogramm beispielsweise Blink wählen. Port PB1 ändern Sie dabei in PC13. Oder Sie schreiben einfach einen eigenen Testsketch. Mein simpler Sketch für das LED-Blinken sieht wie folgt aus:

void setup() {
pinMode(PC13, OUTPUT); // OnBoard-LED liegt an PC13
Serial.begin(9600); // Ausgabe am seriellen Monitor
}

void loop() {
digitalWrite(PC13, !digitalRead(PC13)); // LED invertieren
Serial.println(digitalRead(PC13) ? "low" : "high"); // -> ser. Monitor
delay(1000); // Pause einlegen
}

Bevor sich der Sketch auf die Blue Pill laden lässt, ist das Setzen des Blue Pill in den Programmiermodus wichtig. Zu diesem Zweck bewegen Sie den oberen gelben Jumper (BOOT0) von Position 0 auf 1 (im nachfolgenden Bild von links nach rechts), und drücken anschließend die RESET-Taste. Der untere Jumper BOOT1 bleibt dabei stets unverändert.

Den BOOT1-Jumper können Sie übrigens für eigene Anwendungen nutzen. Er hat sonst keine andere Funktion.

Um einen Sketch hochlasden zu können, muss der BOOT0-Jumper (oben) auf 1 gestellt, und anschließend ein Reset durchgeführt werden.
Um einen Sketch hochladen zu können, muss der BOOT0-Jumper (oben) auf 1 gestellt, und anschließend ein Reset durchgeführt werden.

Nun kann die Arduino IDE den kompilierten Sketch auf die Blue Pill laden. Hat das geklappt, passiert folgendes: Die Onboard-LED blinkt. Im seriellen Monitor sehen Sie zeilenweise eine Folge von "low" und "high"-Nachrichten.

Soll der Sketch nach einer Änderung neu auf das Board geladen werden und ist der BOOT0-Jumper immer noch auf Stellung 1 positioniert, genügt ein Reset vor dem Sketch-Upload. Wollen Sie hingegen ein Überschreiben des Sketches verhindern, setzen Sie diesen Jumper auf Position 0 zurück.

Port Mapping

Um die in der Arduino IDE verwendbaren Port-Namen zu kennen, genügt ein Blick auf die Implementierung des STM32duino Core, genauer gesagt auf die Headerdatei board.h:

...Header board.h ....

#define BOARD_NR_USARTS 3
#define BOARD_USART1_TX_PIN PA9
#define BOARD_USART1_RX_PIN PA10
#define BOARD_USART2_TX_PIN PA2
#define BOARD_USART2_RX_PIN PA3
#define BOARD_USART3_TX_PIN PB10
#define BOARD_USART3_RX_PIN PB11

#define BOARD_NR_SPI 2
#define BOARD_SPI1_NSS_PIN PA4
#define BOARD_SPI1_MOSI_PIN PA7
#define BOARD_SPI1_MISO_PIN PA6
#define BOARD_SPI1_SCK_PIN PA5

#define BOARD_SPI2_NSS_PIN PB12
#define BOARD_SPI2_MOSI_PIN PB15
#define BOARD_SPI2_MISO_PIN PB14
#define BOARD_SPI2_SCK_PIN PB13

#define BOARD_NR_GPIO_PINS 35
#define BOARD_NR_PWM_PINS 12
#define BOARD_NR_ADC_PINS 9
#define BOARD_NR_USED_PINS 4

#define BOARD_JTMS_SWDIO_PIN 22
#define BOARD_JTCK_SWCLK_PIN 21
#define BOARD_JTDI_PIN 20
#define BOARD_JTDO_PIN 19
#define BOARD_NJTRST_PIN 18

#define BOARD_USB_DISC_DEV GPIOB
#define BOARD_USB_DISC_BIT 10

// Note this needs to match with the PIN_MAP array in board.cpp
enum {
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13,PA14,PA15,
PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13,PB14,PB15,
PC13, PC14,PC15
};

...

Beim Entwickeln in der Arduino IDE können Programmierer die obigen Bezeichner nutzen.

Demobeispiel

Jetzt soll ein etwas komplexerer Sketch demonstrieren, dass sich durchaus für die Blue Pill Bibliotheken in der Arduino IDE so nutzen lassen als hätten wir ein natives Arduino-Board vor uns. Im Beispiel ist ein Temperatursensor des Typs Dallas DS18B20 angeschlossen. Zu dessen Nutzung hat Maxim (der heutige Name des Herstellers) den OneWire-Bus eingeführt. Den OneWire-Bus und den Sensor hatte ich bereits in einem früheren Beitrag[9] illustriert.

Das Schaltbild erweitert sich wie folgt:

Blue Pill und DS18B20 gehen gemeinsame Wege
Blue Pill und DS18B20 gehen gemeinsame Wege

Der Sensor (links oben in der Schaltung) ist über Pin PA2 angeschlossen.

Der Sketch ist eher einfach gestrickt. Er soll einfach in jedem Zyklus den Sensorwert des DS18B20 erfassen und am seriellen Monitor ausgeben:

//************************************************
// Blue Pill plus DS18B20 Dallas Temperatursensor
// Demonstration zur Verwendung der Bibliotheken
// fuer Blue Pill in der Arduino IDE
//************************************************

// Zutaten: 1-Wire Protokoll und Sensor-Bibliothek
#include
#include

// Der Bus haengt an Port PA2 des STM32F103C Boards
#define ONE_WIRE_BUS PA2

// 1-Wire-Protokoll initialisieren
OneWire oneWire(ONE_WIRE_BUS);

// ... und Referenz übergeben
DallasTemperature sensors(&oneWire);

// Generelles Setup von seriellem Monitor und der
// Sensor-Bibliothek

void setup(void)
{
Serial.begin(9600); // seriellen Monitor starten
Serial.println("Demo des DS18B20 Sensors an der Blue Pill");

// Bibliothek initialisieren
sensors.begin();
}

// Unser Thermometer dreht sich im Kreis

void loop(void) {
// Alle anwesenden Sensoren um Temperatur bitten
sensors.requestTemperatures();

// Wir nehmen den erstbesten
Serial.println(sensors.getTempCByIndex(0));

delay(1000); // und goennen uns eine Sekunde Pause
}

Wir lernen: Einige Arduino-Bibliotheken funktionieren auch für STM32-Boards. Aber: Speziell Bibliotheken mit direktem Hardwarezugriff oder Einsatz von AVR Inline-Assembler-Code können auf der Blue Pill nicht laufen. Zum Gluck arbeitet die STM32duino-Welt kontinuierlich an der Integration von Bibliotheken.

Kommunikation mit der Aussenwelt

Von Natur aus, ist eine Blue Pill ist sehr schweigsam und besitzt keinen IC für WiFi oder Bluetooth. Abhilfe schaffen können Maker zum Beispiel mit dem ESP-01 aus der ESP8266-Familie. Eine Implementierung für den Zugriff auf ein ESP8266-Board im AT-Kommandomodus liefert Steve Strong(siehe hier[10]). Steve hat einen minimalistischen Webserver implementiert, um LEDs über einen Browser zu schalten oder deren Zustand abzufragen. In einem vergangenen Beitrag[11] hatte ich das Zusammenspiel von Arduino mit ESP-01 im AT_Kommandomodus erläutert.

Eine Integration von Websockets [12] stammt vom gleichen Autor.

Problem Child?

Leider haben die meisten Chargen der Blue Pill einen kleinen Fehler eingebaut. An D+ (siehe Abbildung) wäre ein 1.5 KΩ Pull-up-Widerstand notwendig. Stattdessen findet sich dort ein Widerstand mit 4.7 KΩ oder 10 KΩ. Hat der Widerstand die Aufschrift 103, so handelt es sich um einen Widerstand mit 10 KΩ, bei Code 472 indessen um einen 4.7 KΩ Widerstand. Der korrekte Code lautet aber 152 (= 1.5 * 102).

Das bleibt meistens ohne Folgen, oder es macht sich durch sporadische Probleme beim Sketch-Upload bemerkbar. Auf meinem iMac muss ich bei einigen Blue Pills öfters den Upload durchführen bis es klappt.

Wollen Maker das Problem lösen, müssen sie Hand anlegen. Entweder sie entfernen den fehlerhaften SMD-Widerstand und ersetzen ihn durch einen neuen. Oder sie verwenden die ästhetisch nicht ganz astreine Lösung aus folgender Abbildung:

http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html
Um den Fehler auszumerzen, löten Sie den falschen Widerstand in einer Reflow-Station aus und bringen einen geeigneten Widerstand an. Alternativ können Sie das Problem auch so lösen wie in der Abbildung (Bild: http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html)

Als reine Softwarelösung schlägt Amitesh Singh (von ihm stammt auch die obige Abbildung) vor[13], folgende Codesequenz am Anfang eines Programms einzubauen:

// Notwendig bei inkorrektem Pull-up-Widerstand an D+
// Ein Muss für chinesische Boards des Typs stm32f103c8t6, auch bekannt als "Blue Pill"
rcc_periph_clock_enable(RCC_GPIOA);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
gpio_clear(GPIOA, GPIO12);
msleep(5); // Pause

Das klingt zwar etwas nach Dieselabgas-Affäre, funktioniert aber tatsächlich.

Fazit

Eine Blue Pill bietet zu einem günstigen Preis sehr gute Leistung. Dank der Aktivitäten der STM32duino-Community lässt sie sich in der gewohnten Arduino IDE programmieren, wobei einige Bibliotheken funktionieren, aber nicht alle. Die Blue Pill ist nur eine Vertreterin der unterstützten STM32-Boards. Es gibt viele weitere, auf die der Beitrag aus Platzgründen nicht eingehen kann. Diese kommen in zukünftigen Postings zur Sprache, etwa das Maple-Board, das wie die Blue Pill aus der STM32F103-Familie stammt. Beim Entwickeln mit Blue Pills verlassen Programmierer ein wenig ihre Komfortzone, weil die Unterstützung für Arduino-Boards noch viel umfangreicher ist. Auf der anderen Seite bieten sich im STM32-Universum viele unterschiedliche Werkzeugketten an, die Debugging gut unterstützen, sich ebenfalls für Pros eignen, oder sogar die Generierung von Projekten erlauben wie STM32Cube.

Ein Eintauchen in die Welt der Blue Pill und ihrer Verwandten macht jedenfalls Spaß und erweitert den Horizont.


URL dieses Artikels:
http://www.heise.de/-4009580

Links in diesem Artikel:
[1] http://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171190.pdf/files/CD00171190.pdf/jcr:content/translations/en.CD00171190.pdf
[2] http://www.st.com/en/development-tools/flasher-stm32.html
[3] http://www.st.com/en/ecosystems/stm32cube.html?querycriteria=productId=SC2004
[4] http://www.openstm32.org/HomePage
[5] https://github.com/trebisky/stm32f103
[6] https://satoshinm.github.io/blog/171212_stm32_blue_pill_arm_development_board_first_look_bare_metal_programming.html
[7] http://www.stm32duino.com
[8] https://github.com/rogerclarkmelbourne/Arduino_STM32
[9] https://www.heise.de/developer/artikel/Lauschen-mit-Sensoren-3217195.html
[10] https://github.com/stevstrong/STM32_ESP01_WebServer
[11] https://www.heise.de/developer/artikel/Ueberraschungsei-fuer-Wetterfroesche-dank-BME680-ESP8266-Arduino-ThingSpeak-3979158.html
[12] http://www.stm32duino.com/viewtopic.php?f=19&amp;t=3281
[13] http://amitesh-singh.github.io/stm32/2017/05/27/Overcoming-wrong-pullup-in-blue-pill.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 03. April 2018 um 10:19

Welt-Spar-Tag

Von heise online

zurück zum Artikel

Wer IoT-Geräte in freier Wildbahn, also an Orten ohne Steckdose, betreiben möchte, stößt bald auf ein Problem. Ohne entsprechende Vorkehrungen saugen Schaltungen mit Mikrocontrollern in kürzester Zeit Batterien oder Akkus leer. Um möglichst sparsam mit der verfügbaren Energie umzugehen, gibt es einige Möglichkeiten.

Tipps und Tricks

Dieses Posting entstand deshalb, weil ein Leserkommentar dazu angeregt hat. Allerdings gilt: Auch der Autor dieses Blogs hat die Weisheit nicht mit Löffeln gefressen. Daher betrachten Sie bitte die folgende Liste lediglich als unvollständige Sammlung. Ihre Tipps und Erfahrungen sind daher willkommen, um diese Liste auszubauen.

Das Problem

Bereits im Leerlauf mit dem BareMinimum-Beispiels-Sketch aus der Arduino IDE verbraucht ein Arduino Uno rund 15mA. Verwendet die Schaltung einen 9V-Block aus Zink-Kohle als Energiequelle, so hat die Batterie nach rund 22 Stunden das Ende ihrer Kapazität erreicht. Fügt jemand der Schaltung noch einen 220Ω Widerstand und eine LED hinzu, reduziert sich die ohnehin sehr geringe Laufzeit nochmals. Zusatzhardware wie ein Kohlenmonoxid-Gassensor oder eine Wetterstation könnte auch diese eingeschränkte Batterie-Lebensdauer verringern. Ganz zu schweigen von Situationen, in denen Kommunikationstechnologien wie WiFi, Bluetooth oder LoRa ins Spiel kommen. Gerade bei autark arbeitenden oder mobilen IoT-Geräten wiegt diese Herausforderung besonders schwer, weil die erwarteten Batterie-Kapazitäten oft für Tage, Monate oder sogar Jahre reichen müssen. Bei stationären Geräten mit Netzanschluss erwarten Nutzer mittlerweile einen energiesparenden Betrieb. Was nun, Herr und Frau Maker?

"Wer misst, misst Mist" - was nicht immer richtig ist

Vorweg möchte ich kurz auf das Thema Werkzeuge für Maker zu sprechen kommen. Ohne Diagnosewerkzeug lassen sich Schaltungsfehler oft nur schwer aufspüren.

Um dem Energieverbrauch auf dem Grund zu gehen, empfiehlt sich der Einsatz eines guten Multimeters. Damit können Maker gezielt überprüfen, an welchen Stellen welche Energieverbräuche entstehen. Es gibt hierfür recht preisgünstige Messtechnik (etwa das sehr gut bewertete Ragu 17B für 29,99 Euro[1]), aber selbst für ernsthaftere Hobbyisten sei auf lange Sicht Qualitätshardware empfohlen. Diese messen genauer, reagieren schneller, und arbeiten zuverlässiger. Die Geräte von Fluke gehören sicher zum Nonplusultra, was Preis und Qualität betrifft, lassen sich aber schon in kleineren Varianten für unter 200 Euro erwerben. Etwa ein Fluke Multimeter 113 für um die 120 Euro oder ein 117 für unter 200 Euro.

amazon.com
Ein Fluke 117 Multimeter geht schon für unter 200 Euro über den Ladentisch (Bild: amazon.com)

Ein Multimeter ist selbstredend nicht nur sinnvoll, um den Energiekillern auf die Spur zu kommen, sondern auch für die Fehlersuche oder Diagnose bei Schaltungen.

DiY für Messtechnik

Der konsequente Maker baut sogar seine Messgeräte selbst, wobei hier natürlich die Geschichte von Huhn und Ei in den Sinn kommt.

  • In seiner Instructable-Anleitung [2]stellt Milen den Bau eines Arduino-Multimeter-Shields vor
  • Das Design eines Strommessers findet sich zum Beispiel auf dieser Seite[3]
  • Mittels Sensor-Breakout-Boards auf Basis von ICs wie MAX471, INA219, ACS712 lassen sich Strommessungen in Schaltungen durchführen
  • Auch Voltmeter, Ohmmeter und Arduino-Schaltungen zur Erfassung weiterer physikalischer Größen finden sich im Internet zuhauf

Natürlich gibt es einige andere Geräte, die in Zukunft noch im Blog zur Sprache kommen. (Logik-Analysatoren für die Diagnose digitaler Logik - etwa zur Buskommunikation mit SPI, I2C, PWM - hatte ich bereits in einem früheren Beitrag[4] vorgestellt).

Zur Messung des Energieverbrauchs verwendet der Maker eine 9V-Blockbatterie oder eine andere Konfiguration. Zu diesem Zweck ist ein Multimeter (Amperemeter) mit der zu überprüfenden Elektronik in Serie zu schalten.

Suchen Sie den Punkt im Schaltkreis, an dem Sie die Stromstärke messen möchten. An diesem Punkt unterbrechen Sie den Schaltkreis und verbinden ein Ende mit dem COM-Port des Multimeters und das andere Ende mit dem mA/A-Port des Multimeters. Das Multimeter fungiert nun als Teil der Leitung, sodass der Stromkreis wieder geschlossen ist. Bei Spannungsmessungen schalten Sie hingegen das Multimeter parallel zum gemessenen Teil der Schaltung.

Insgesamt ergibt sich also folgendes Bild:

Serienschaltung von Multimeter und dem zu messenden Schaltkreis
Serienschaltung von Multimeter und dem zu messenden Schaltkreis

Die angezeigten mA-Werte zeigen den zu einem Zeitpunkt benötigten Energiebedarf der Schaltung. Die Spannung am Arduino-Board beträgt bekanntlich stets 5V (beziehungsweise 3.3V). Und die Leistung beträgt immer P = U * I = 5V * I.

Mit diesem Aufbau ist folglich die (Un-)Wirksamkeit der diversen Power-Save-Maßnahmen überprüfbar.

Übrigens lässt sich der Arduino mit Hilfe eines Spannungsteilers mit Widerständen sogar dazu verwenden, um seinen eigenen Stromverbrauch per Selbstreflektion zu ermitteln. Sie sind daran interessiert? Dann empfehle ich das entsprechende YouTube-Video von Matteo Corti[5].

MCU- und IC-Overkill vermeiden

Einen Arduino Mega oder einen Raspberry Pi einzusetzen, nur um regelmäßig einen schlichten Temperatursensor auszulesen, heißt mit Kanonen auf Spatzen schießen. Je leistungsfähiger der Mikrocontroller und je umfangreicher die auf dem Board verbauten Komponenten, desto höher der Verbrauch.

Schließlich konsumiert auch jeder nicht benötigte IC in einer Schaltung oder auf einem Mikrocontroller-Board Energie. Ein gutes Beispiel ist der UART-USB-TTL Adapter, der ständig rund 10 mA "verbrennt". Nur als Beispielsrechnung: Einen 9V-Block aus Alkali-Mangan mit 600 mAh würde allein der UART in maximal 60 Stunden völlig entleeren.

Arduino-MCUs wie Pro Mini besitzen keinen UART. Ihre Programmierung erfolgt über einen temporär angeschlossenen externen UART-USB-TTL-Adapter oder über eine Programmer-Hardware. Erwähnenswert an dieser Stelle ist, dass der Arduino Pro Mini im Prinzip ein um den UART-USB-TTL-Adapter abgespeckter Arduino Nano ist.

Zu den Stromfressern gehört des Weiteren die Power-on-LED, die mit rund 4 mA zu Buche schlägt. Eine drastische Massnahme besteht daher im Auslöten dieser LED beziehungsweise ihrem Aushebeln mittels Zange.

Auf der anderen Seite ver(sch)wenden lineare Spannungsregulatoren ebenfalls Energie und zwar abhängig davon, wie groß der Unterschied zwischen Eingangsspannung und Ausgangsspannung ist. Je höher dieser Wert, desto mehr Energie kommt durch Wärmeverluste abhanden. Die Formel hierfür lautet:

P = (Vout-Vin) * I.

Hier lässt sich entweder der Regulator ganz entfernen, und/oder ein effizienterer Regulator verwenden. Wer den Regulator entfernt, muss aber dafür sorgen, dass genau die notwendige Betriebsspannung (5V oder bei einigen Boards 3.3V) in Vin anliegt. Daher ist es zum Teil praktikabler, den internen Regulator zu deaktivieren und durch einen sparsamen, externen Regulator zu ersetzen. Experimentierfreudige Zeitgenossen haben hin und wieder den internen linearen Regulator auf dem Arduino-Board ausgelötet und durch einen effizienteren Regulator ersetzt. Es gibt zum Glück Arduino-Boards wie das Sparkfun Pro Mini, die das Deaktivieren des internen Regulators per Jumper erlauben.

Der Blogartikel [6]empfiehlt zum Beispiel Regulatoren von Microchip wie MCP1700 und MCP1703, die es jeweils in Varianten für 3.3V und 5V zu kaufen gibt.

Richtigen Logik Level und richtige Frequenz wählen

Der Energieverbrauch steigt quadratisch mit der Spannung und linear mit der Frequenz. Kleinere Logik-Level reduzieren den Energieverbrauch, etwa Verwenden von 3.3V statt 5V. Zur Erinnerung, die Formel für die Leistung lautet

P = U2 / R.

Dann aber müssen Mikrocontroller wie der Atmel 328P herunter-getaktet werden. Laut Datenblatt verträgt der Prozessor bei 3.3V Versorgungsspannung keine 16MHz, weshalb Boards wie das Arduino Pro Mini im 3.3V-Betrieb unter 8 MHz laufen.

Der optimale Logik-Level hängt aber natürlich auch von den benützten Sensoren, Aktuatoren, Breakout-Boards oder Shields ab. Benötigen diese 5V, macht es eventuell nur wenig Sinn, mit einem 3.3V-Mikrocontroller-Board zu arbeiten. Und einige Bibliotheken könnten bei geänderter Taktfrequenz nicht oder nur eingeschränkt funktionieren.

Solarzellen

In Zeiten der Nachhaltigkeit kann das Thema alternative Energien natürlich nicht fehlen. Nur mit einer Solarzelle lässt sich eine Schaltung allerdings nicht betreiben, weil normalerweise tagsüber gerade einmal zwischen 10.00h und 14:00h optimale Sonneneinstrahlung herrscht. Die Solarzelle sollte also dazu dienen, NiMH-Akkus aufzuladen, von denen sich wiederum die Schaltung speist. Beispielsweise lässt sich ein 2 x 1.2V AA Doppel-Akkupack (gesamt 2.4V mit NiMh-Akkus) in Kombination mit einem Baustein (Voltage Booster, zum Beispiel XL6009) nutzen, der die Spannung auf die von den meisten Arduino-Boards benötigten 5V erhöht. Als Faustregel gilt: Die Spannung des Solarpanels muss ungefähr anderthalb (bis doppelt) so hoch sein. Im Falle eines Arduino Pro Mini mit 3.3V Spannung bietet sich ein >= 6V-Panel an. Beträgt die Kapazität der Akkus 1300mAh, sollte ihr Aufladen maximal mit einem Zehntel erfolgen (= 130 mA), aber mit 100 mA im Idealfall, sodass die Ladezeit rund 10-16 Stunden beträgt.

Mehr ist nicht immer besser: Je höher die Ladestrom, desto schneller zwar das Laden, aber auch desto geringer die Lebenszeit der Akkus. Empfehlenswert ist der Einsatz einer Diode (zum Beispiel Typ LN4148) zwischen positivem Terminal von Solarpanel und positivem Terminal des NiMh-Batteriepacks, wobei der positive Port des Batteriepacks mit der Plus-Seite der Diode verbunden ist, und das negative Ende der Diode mit dem positiven Potenzial des Batteriepacks. Negative Ports von Solarpanel und Batteriepack sind hingegen direkt verbunden. Für NiMh-Akkus gestaltet sich die Schaltung also recht pflegeleicht.

Wer stattdessen LiIon-Akkus wie ein 18650 nutzen möchte, hat ein bisschen mehr Aufwand, weil dafür ein LiIon-Ladecontroller benötigt wird, zum Beispiel ein TP4056. Das Überschreiten oder Unterschreiten gewisser Ladungsschwellwerte kann die Batterie zerstören, und nicht nur die.

Mehr Details zum Anschluss von Solarpanels liefert folgender guter Beitrag auf instructables[7].

Ewig schläft das Murmeltier

Schon aus den bisherigen Ausführungen ergibt sich die Schlussfolgerung, dass es Energieverbrauch für nicht benötigte Komponenten tunlichst zu vermeiden gilt. Dafür gibt es bei Embedded Controllern die Möglichkeit der Schlafmodi, d.h. die Komponenten laufen nur zu bestimmten Zeitpunkten. Ausserhalb dieser Zeitpunkte befinden sie sich in einem Schlafmodus, der weniger Energie benötigt. Nicht verwendete Komponenten wie ADC verbrauchen aber auch unter Umständen in einem Schlafmodus viel Strom, und lassen sich bei vielen Mikrocontrollern daher auch komplett abschalten.

Ein paar Worte speziell zu Arduino-Boards, bei denen die meisten einen ATMega328P oder einen ATMega168P beinhalten: Laut Datenblatt des ATMega328P[8] (Kapitel 9) sind besonders folgende Komponenten Stromverbrauch-Kandidaten:

  • Der ADC (Analog-Digital Converter) sollte generell oder vor dem Schlafmodus deaktiviert werden. ADCs verbrauchen sonst eine gehörige Portion Strom.
  • Der Analog Comparator vergleicht positive Spannung an einem Pin mit der negativen Spannung an einem anderen Pin und setzt entsprechende Registerwerte oder kann einen Interrupt auslösen. Bis auf Idle-Mode und Noise-Reduction-Mode legt der Prozessor den Analog Comparator in allen Schlafmodi automatisch schlafen. In den vorgenannten beiden Modi empfiehlt es sich, falls möglich, den Baustein manuell zu deaktivieren.
  • Der Brown-out-Detector (BoD) sorgt für ein Herunterfahren des Systems, sobald die Ist-Spannung die Soll-Spannung für einen bestimmten Zeitraum unterschreitet. Der BoD hat auch in diversen Schlafmodi großen Stromhunger, weshalb es eine gute Idee ist, ihn zu deaktivieren.
  • Von der Internal-Voltage-Reference sind BoD, ADC, und Analog Comparator abhängig. Deaktiviert der Entwickler diese Bausteine, so bleibt auch die Internal-Voltage-Reference außer Betrieb
  • Im Schlafmodus sollten die Port Pins ebenfalls nur minimale Energie verbrauchen. Gerade analoge Pins haben Umständen großen Appetit. Das lässt sich zum Beispiel bewerkstelligen, indem der Sketch alle nicht benötigten digitalen Pins im Set-up als Output-Pins deklariert und/oder Pull-Down-Widerstände aktiviert.
  • Das On-Chip-Debug-System muss nur im Bedarfsfall aktiv sein, weil es im Betrieb substanziellen Energieverbrauch aufweist.

Der Watchdog Timer (WDT) hingegen darf im Normalfall nicht deaktiviert werden, auch wenn er einige wenige (Bruchteile von) mA verspeist. Ihn benötigt die MCU als externen Wecker, um den Schlafmodus aufzuheben. Allerdings lässt der WDT maximal 8 Sekunden (Tief-)Schlaf zu, weshalb er bei längeren Schlafzeiten mehrfach hintereinander zu nutzen ist.

Interrupts wie Interrupt 0 (Arduino-Port 2) oder Interrupt 1 (Arduino-Port 3) heben den Schlafmodus ebenfalls auf. Sie lassen sich durch externe Ereignisse triggern, etwa dem Betätigen eines an diesen Eingängen anliegenden Push-Buttons oder einer RTC-Uhr. Das macht Sinn, wenn das Gerät ohnehin nur bei bestimmten externen Ereignissen loslaufen sollte, etwa bei Benutzerinteraktion

Der ATMega328P besitzt einige Fuses und Register, die das Verhalten und den Energieverbrauch in den diversen Schlafmodi steuern. An dieser Stelle habe ich nicht genug Raum, um auf Fuses einzugehen. Jedenfalls ist bei Nutzung derselben zur Konfiguration des Prozessors Vorsicht die Mutter der Porzellankiste. Bei einem Fehler ist der Arduino sonst gegebenenfalls nicht mehr oder nur mit großem Aufwand in Betrieb zu nehmen.

Auch das Schreiben von Register-Bit-Manipulationen bei Registern und Inline-Assemblerinstruktionen zum Initialisieren der Schlafmodi gestaltet sich eher mühevoll und fehlerträchtig. Wer sich trotzdem dafür interessiert und dabei viel über Schlafmodi der AVR-Prozessorfamilie lernen will, sei auf das exzellente, englischsprachige YouTube-Video von Kevin Darrah[9] verwiesen.

Rocket Scream LowPower Bibliothek

Statt sich mühsam und systemnah mit dem Sleep-Modi auseinanderzusetzen, empfiehlt sich die sehr gute Low-Power-Bibliothek von Rocket Scream. Sie macht auch das Verwenden der in der Arduino bereitgestellten sleep-API (sleep.h) überflüssig.

Die Bibliothek gibt es hier unter GitHub[10] zum Download als ZIP-Datei. Nach dem Herunterladen fügen Sie über den Menü-Pfad Sketch > Include Library > Add .ZIP Library... die Bibliothek der Arduino IDE zu. In einem Sketch müssen Sie dann nur noch die Headerdatei LowPower.h inkludieren ...

... und die entsprechende Routine für den Tiefschlaf nutzen, die auch vom Typ des Mikrocontroller abhängt, wie Sie der Klassendefinition für LowPowerClass (siehe Headerdatei) entnehmen können. Beim Uno liegt ein ATMega328P vor, weshalb der nachfolgende Sketch folgenden Aufruf nutzt:

LowPower.idle(SLEEP_1S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, 
SPI_OFF, USART0_OFF, TWI_OFF);

Die MCU wird für einen Zeitraum bis zu 8 Sekunden (Parameter SLEEP_xS) schlafen gelegt. Für eine Sekunde gibt es zum Beispiel SLEEP_1S. Währenddessen deaktiviert die Bibliothek ADC, Timer 0 bis 2, SPI-Bus, I2C-Bus (TWI), und den USART0 (serieller Ausgang 0).

Als Beispiel fungiert das Auslesen eines TMP36-Temperatursensors an einem Arduino Uno. Alle 8 Sekunden liest ein Sketch den aktuellen Sensorwert. Über den Einsatz dieses Sensors hatte ich bereits in einem vergangenen Beitrag[11] geschrieben.

Gleichzeitig zeigen sowohl die eingebaute LED des Arduino-Boards als auch die am selben Pin liegende externe LED an, sobald die Messung erfolgt (LED an) und abgeschlossen ist (LED aus). Die LEDs dienen lediglich als zusätzliche Last.

Das Schaltungsdiagramm für das Experiment strukturiert sich wie der unteren Abbildung zu entnehmen ist. Der Sketch liest die Temperatur über den Analogport A0 aus, und steuert die LEDs am Digitalport 13 an, also sowohl die im Arduino-Board integrierte als auch die extra auf dem Breadboard hinzugefügte LED.

Schaltung mit TMP36-Temperatursensor und zusätzlicher LED als Last
Schaltung mit TMP36-Temperatursensor und zusätzlicher LED als Last
Sketch

Der Sketch zum Versuchsaufbau gestaltet sich sehr einfach und ist selbsterklärend. Interessant ist vor allem die Methode measure() mit den Aufrufen von LowPower.idle().

Die Ermittlung der Temperatur erfolgt ebenfalls in dieser Methode.

Durch Verstellen der boole'schen Variablen powerSave ist steuerbar, ob delay() oder der Tiefschlafmodus zum Einsatz kommt.

/******************************************************
*
* Auslesen eines TMP36 Temperatursensors
*
*
*****************************************************/

#include "LowPower.h" // Low-Power Bibliothek nutzen
bool powerSave = true; // Power-Save-Betrieb an oder aus

int tmp36Pin = 0; // TMP36 liegt am Analog-Port A0
int extraLED = 13; // Extra LED an Digitalport D13

void setup() {
// Alle Pins als Ausgänge setzen:
for (int pin = 0; pin < 20; pin++)
pinMode(pin, OUTPUT);
}

// Im Betrieb erfolgt eine kontinuierliche Messung:
void loop() {
measure();
}

void measure() {
// Extra LED an, weil Messung beginnt:
digitalWrite(extraLED, HIGH);

// Wert am analogen tmp36Pin auslesen
// und in Temperatur umrechnen:

int whatIRead = analogRead(tmp36Pin);
float voltage = whatIRead * 5.0 / 1024;
float celsius = (voltage - 0.5) * 100;

// Statt delay() echter 1 Sekunden Tiefschlaf

if(powerSave)
LowPower.idle(SLEEP_1S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
SPI_OFF, USART0_OFF, TWI_OFF);

else
delay(1000);

digitalWrite(extraLED, LOW); // Messung beendet

// Statt delay() echter 8 Sekunden Tiefschlaf
if(powerSave)
LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
SPI_OFF, USART0_OFF, TWI_OFF);

else
delay(8000);
}

Wem das zu aufwändig erscheint, kann auch einfach einen "leeren" Sketch (BareMinimum.ino) nutzen, und dort die Wirkung der Aufrufe von LowPower.idle() im Leerlauf untersuchen.

Arduino Pro Mini statt Arduino Nano

Wie bereits erwähnt, gibt es als Alternative zum Arduino Nano den Arduino Pro Mini, der rund ein Sechstel der Größe eines Arduino Uno aufweist, und über keinen USB-Adapter verfügt. Die Pro Minis gibt es in mehreren Varianten mit ATMega168P oder ATMega328P, sowie mit 3.3V bei 8MHz Taktfrequenz oder 5V bei 16MHz Taktfrequenz. Diese Arduino-Boards kamen ursprünglich von Sparkfun. Mittlerweile gibt es eine ganze Menge von geklonten chinesischen Pro Mini Boards zu Preisen von weit unter 2 Euro bei Alibaba.

Vorderseite eines Pro Mini. Über die Programm Header (rechts) lässt sich ein FTDI-Board anschließen
Vorderseite eines Pro Mini. Über die Programm Header (rechts) lässt sich ein FTDI-Board anschließen (Bild: sparkfun.com)

Billigboards machen oft keine Angabe darüber, um welche Variante es sich handelt, im Gegensatz zum nachfolgend abgebildeten Board von Sparkfun (3.3V, 8MHz).

Um die bei Ihnen vorliegende Variante festzustellen, legen Sie am Raw-Eingang eine Spannungsquelle mit 5V an, zum Beispiel ein auf 5V gejumpertes FTDI-Board (oder einen anderen UART-USB-to-TTL-Adapter). GND des UART-USB-to-TTL-Adapters verbinden Sie mit einem GND-Pin des Pro Mini. Nun lesen Sie mit einem Multimeter die am VCC-Ausgang des Pro Mini anliegende Spannung aus. Sind es 3.3V, handelt es sich um einen Pro Mini mit 3.3V und 8MHz. Sind es hingegen 5V, liegt ein Pro Mini mit 5V und 16MHz vor.

sparkfun.com
Die Rückseite des Pro Mini Boards. Zu beachten sind die ungewöhnlich positionierten Analogports A4, A5, A6, A7, von denen A4 und A5 als I2C-Bus dienen (Bild: sparkfun.com)

Hier noch ein hilfreicher Überblick über die Pinbelegung eines Arduino Pro Mini.

Die Pinbelegung des Pro Mini
Die Pinbelegung des Pro Mini

Am besten, Sie nehmen einen FTDI-USB-TTL-Adapter und schließen daran den Pro Mini an, um ihn zu programmieren. Für den Betrieb können Sie dann eine Batterieversorgung statt des Adapters verwenden.

bx4.com
Der Arduino Pro Mini lässt sich in Verbindung mit einem FTDI-Adapter gur programmieren (Bild: bx4.com)
Arduino-kompatible Low-Power Boards

Wer auf Nummer sicher gehen möchte, greift gleich zu Arduino-kompatiblen Boards, die Hersteller auf niedrigen Energieverbrauch getrimmt haben.

Der Moteino von LowPowerLab verbraucht beim üblichen Blink-Sketch rund 8 mA. Daneben gibt es auch den Moteino Mega mit ähnlichem Energieverbrauch. Im kleinsten Energieverbrauchsmodus sind es nur um die 6.5 µA.

LowPowerLap
Das energiesparende Moteino-Board kosten um die 10 Euro (Bild: LowPowerLap)

Der Mini Ultra 8 MHz von Rocket Scream verbraucht im extremen Low-Power-Modus nur rund 1.6 bis 1.7 µA. Die Pro-Variante bietet einen Anschluss für eine Lithium-Ionen-Batterie.

Mini Ultra 8 MHz Board von Rocket Scream
Mini Ultra 8 MHz Board von Rocket Scream (Bild: Rocket Scream)
Arduino Raw Iron

Alternativ könnten Maker auch auf die Idee kommen, ihr eigenes Arduino-Board zusammenzuschustern, also eine Bare-Bone-Lösung. Wie das geht, hatte bereits mein Beitrag über einen Selbstbau-Arduino[12] beschrieben. Einige der dort verwendeten Bauteile lassen sich dann gezielt durch weniger stromhungrige Varianten ersetzen oder ganz weglassen wie zum Beispiel die Onboard-LED.

ESP8266

Auch ESP8266-Boards wie NodeMCU und ESP32-Boards verfügen über die Möglichkeit des Tiefschlafs. Beispielsweise enthielt die Schaltung in der Folge über die Wetterstation mit dem Sensor BME680[13] einen ESP-01 für die Kommunikation über WiFi mit dem Dienst Thingspeak. Die ESP-MCUs verprassen reichlich Energie, auch wenn sie gerade nichts zu tun haben, weshalb der Maker die Controller schlafen legen sollte, sobald sie zur Untätigkeit verdammt sind. Dummerweise funktioniert beim ESP-01 das Schlafen legen weder über die Arduino-Core-Firmware noch über die dafür vorhandenen AT-Kommandos. Der Grund dafür ist, dass der externe RESET-Pin nicht mit dem XPD_DCDC-Pin (Deep Sleep Wake-up = GPIO16) verbunden ist.

Das Layout des ESP8266. Der XPD_DCDC-Pin befindet sich links unten im Bild
Das Layout des ESP8266. Der XPD_DCDC-Pin befindet sich links unten im Bild

Daher empfiehlt sich für diejenigen, die sich das Löten zutrauen, folgende Hardwaremodifikation (Hack). Man verbinde den RESET-Pin mit dem XPD_DCDC-Pin wie auf der folgenden Abbildung als blaue Linie illustriert.

In einem Hack verbindet der Maker REST-Pin des ESP-01 mit XPD_DCDC-Pin, um den Schlafmodus zu ermöglichen
In einem Hack verbindet der Maker REST-Pin des ESP-01 mit XPD_DCDC-Pin, um den Schlafmodus zu ermöglichen

Da ein ESP-01 nur Briefmarkengröße hat, muss das Löten sehr vorsichtig erfolgen. Dass der XPD_DCDC-Pin weit von der Antenne entfernt ist, erweist sich als Glück im Unglück.

Ist die Modifikation abgeschlossen, lässt sich der ESP-01 bei Firmwareprogrammierung oder im AT-Betriebsmodus zeitweise (bis etwa 71 Minuten) in den Tiefschlaf versetzen. Das entsprechende AT-Kommando lautet:

AT+GSLP=

Wer noch mehr sparen will, kann auch beim ESP-01 wagemutig die Power-LED eliminieren (rote LED, ganz oben rechts neben der Antenne).

Fazit

Im Gegensatz zu stationären Embedded Geräten mit Netzanschluss sind autonom arbeitende oder mobile Geräte auf eine unabhängige Energieversorgung angewiesen. Bei naiver Hardware-/Software-Konfiguration und -Programmierung kommt spätestens dann keine Freude mehr auf, sobald alle paar Tage oder sogar schon alle paar Stunden die Batterien ersetzt werden müssen. Das lässt sich nur durch geschickte Wahl der Hardwarekomponenten und durch programmatische Massnahmen vermeiden, wodurch sich der Verbrauch von 25mA im idealen Fall auf unter 5µA reduzieren lässt. Wem auch das noch zu hoch erscheint, nutzt Arduino-kompatible Varianten wie Moteino oder Mini Ultra {Pro}, die speziell auf Low-Power-Operation getrimmt sind.

Alle beschriebenen Maßnahmen bestehen wie bei jeder Art von Energiesparen darin, den Verbrauch spürbar zu senken, und zusätzlich regenerative Energiequellen wie die Sonne zu nutzen.

Es genügt aber nicht, nur den verwendeten Mikrocontroller zu betrachten. Auch komplexere Sensoren wie ein BME680 oder Zusatzhardware wie zum Beispiel Kommunikationshardware (ESP-01) besitzen Sleep-Funktionalität, da sie sonst im Standby-Betrieb signifikant Strom ziehen würden. Der verbrauchssensitive Maker sollte daher stets die Datenblätter all seiner Hardwarekomponenten zur Hand haben.

Stromverbrauch ist übrigens eines der Gebiete, in denen sich in der Regel normale Softwareentwicklung von der Entwicklung von Embedded Systemen unterscheidet. Entwickler von Smart Phones, Watches und Tablets können ein Lied davon singen.


URL dieses Artikels:
http://www.heise.de/-4002306

Links in diesem Artikel:
[1] https://www.amazon.de/RAGU-17B-Diodendurchlauftest-Hintergrundbeleuchtung-Messbereichserkennung/dp/B06W5G1VND/ref=sr_1_4?ie=UTF8&amp;qid=1521808476&amp;sr=8-4&amp;keywords=multimeter
[2] http://www.instructables.com/id/Digital-multimeter-shield-for-Arduino/
[3] http://wiki.happylab.at/w/Arduino_voltammeter
[4] https://www.heise.de/developer/artikel/Logic-Analyzer-3287114.html
[5] https://www.youtube.com/watch?v=W9X_DnGufO0
[6] http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/
[7] http://www.instructables.com/id/SOLAR-POWERED-ARDUINO-WEATHER-STATION/
[8] http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
[9] https://www.youtube.com/watch?v=urLSDi7SD8M
[10] https://github.com/rocketscream/Low-Power
[11] https://www.heise.de/developer/artikel/Lauschen-mit-Sensoren-3217195.html
[12] https://www.heise.de/developer/artikel/Do-it-Yourself-Projekt-iXduino-Arduino-on-a-Breadboard-3198567.html
[13] https://www.heise.de/developer/artikel/Ueberraschungsei-fuer-Wetterfroesche-dank-BME680-ESP8266-Arduino-ThingSpeak-3979158.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 26. März 2018 um 10:52

Gutes Echo mit ESP8266 oder ESP32

Von heise online

zurück zum Artikel

Intelligente Sprachassistenten à la Apple Homepod, Google Home oder Amazon Echo verkaufen sich zur Zeit wie warme Semmeln, und bilden das Zentrum so mancher Smart-Home-Lösung. Wie aber kann der Maker Geräte bauen, die sich dort relativ einfach integrieren lassen?

Warum Amazon Echo

In diesem Beitrag liegt der Fokus auf Amazon Echo. Diese Wahl soll keine negative Bewertung der Lösungen von Google oder Apple assoziieren. Die Entscheidung für Amazon fällt einzig aus dem Grund, weil deren Produkte mittlerweile am meisten verbreitet sind. Demzufolge haben sich auch schon einige Open-Source.Entwickler auf diesem Gebiet engagiert. Grund genug, ein Auge auf die Möglichkeiten zu werfen, die sich dem Maker bieten.

Do the Wemo Dance

Jetzt wäre es natürlich die naheliegendste Möglichkeit, sich als Amazon-Entwickler zu registrieren, um entsprechende Skills und Echo-kompatible Hardware bereitzustellen. Für viele sehr einfache Anwendungsfälle ist das aber gar nicht notwendig. Damit sind solche Beispiele gemeint, bei denen sich die Steuerung eines IoT-Geräts auf das Ein- und Ausschalten reduzieren lässt. Die Killerapplikation sind in diesem Zusammenhang Lampen oder Steckdosen, die sich von einem Microcontroller aus über Relais schalten lassen.

Findige Entwickler haben deshalb die Wemo-Lösung von Belkin unter die Lupe genommen. Wie jedes in Echo integrierbare Gerät, enthält eine Wemo-Steckdose Funktionalität, um sich über WLAN mit einem Echo, Echo Dot, Echo Spot, oder Echo View zu koppeln. Was liegt also näher als dieses Protokoll nachzubauen und in einer Bibliothek bereitzustellen. Damit können Maker ihre eigene Lösung als Belkin Wemo ausgeben.

Funktion von Amazon Echo

Wie funktioniert überhaupt das Zusammenspiel zwischen Echo-Produkt und Geräten wie zum Beispiel einer Belkin Wemo Steckdose?

Fordert der Benutzer ein Echo-System zum Auffinden neuer Geräte auf, schickt es per UDP-Broadcast eine Meldung an alle Geräte im vorliegenden WLAN. Kopplungswillige, neue Geräte antworten mit ihrer URL-Adresse, worauf Echo sie um ihre Service-Beschreibung bittet. Daraufhin schickt das jeweilige Gerät die Gerätebeschreibung (setup.xml) zurück. Diese Zuordnung (Gerät, Name, Charakteristik, ...) merkt sich Echo in einer Geräteliste. Fordert der Nutzer per Sprache oder App ein bekanntes Gerät zu einer von diesem Gerät unterstützten Aktion auf, bittet Echo das Gerät per TCP/Webservice-Aufruf um entsprechende Zustandsänderung (SetBinaryState), was das angesprochene Gerät bestätigt.

Eine schlichte Steckdose des Typs Belkin Wemo beispielsweise kennt nur zwei alternierende Zustände, an und aus. Demzufolge hören sie auf sehr einfache Kommandos.

ESP32 und ESP8266

Um eine einfache Integrationsmöglichkeit in das Amazon-Echo-Universum zu illustrieren, ist ein ESP8266 oder ein ESP32 Board notwendig. In meiner Serie gab es zu beiden MCUs schon Artikel (ESP8266 Teil 1[1] und Teil 2[2], ESP32[3]).

Empfehlenswert als Boards sind beispielsweise die NodeMCU-Varianten mit ESP32 oder ESP8266 (ESP-12e oder ESP 12-f). Prinzipiell sollte sich aber jedes Board eignen.

Arduino Core

Für unsere Zwecke ist die Arduino IDE notwendig. Damit sie mit ESP-Boards umgehen kann, existieren sogenannte Arduino Cores für ESP8266- beziehungsweise ESP32-Boards. Deren Installation in die IDE ist auf den Implementierungsseiten beschrieben.

  • ESP8266: siehe github[4]
  • ESP32: siehe github[5]

Die Boards mit ESP8266 oder ESP32 verwenden üblicherweise andere UART-Hardware, sodass die Installation zusätzlicher Treiber notwendig ist, typischerweise die UART-to-USB-Treiber von SiLabs für CP210x-Chips [6]oder die Treiber für CH34x-Chipsets[7].

Haben die Installationen von Arduino Core und USB-Driver geklappt, können Sie in der Arduino IDE unter dem Menü Tools den COM-Port und das jeweils verwendete Board spezifizieren, wobei es bei ESP8266-Boads meistens im Falle von NODEMCU das NODEMCU 1.0 (oder sonst Generic ESP8266 Module) tut, und bei ESP32-Boards ESP32 Dev Module. In meinem Fall lag ein Board des Typs Wemos Lolin vor.

Fauxmo statt Wemo

Wir nutzen den Arduino Core für ESP32 und ESP8266. Dadurch lassen sich die Boards im gewohnten Stil mit der Arduino IDE programmieren.

Allerdings sind zwei Bibliotheken notwendig, zum einen fauxmoESP, und zum anderen eine Bibliothek für asynchrone Kommunikation.

Die essenzielle Bibliothek für unser "trojanisches Pferd" firmiert unter dem Namen fauxmoESP[8]. Der Ursprung von fauxmoESP ist eine entsprechende Python-Bibliothek[9], die von Maker Musings stammt. Die C/C++- Umsetzung haben wir Bibi Blocksberg (der Name ist hoffentlich ein Pseudonym), Xose Pérez (ESP8266) und Frank Hellmann (ESP32) zu verdanken. Zudem benötigt fauxmoESP eine C++-Bibliothek zur asynchronen Kommunikation, entweder AsyncTCP[10] für ESP32-Boards oder ESPAsyncTCP[11] für ESP8266-Boards.

Beide Bibliotheken sollten Sie sich von Github holen und jeweils über das Menü Sketch > Include Library > Add .ZIP Library der IDE bekannt machen.

In der Amazon Alexa App tauchen nach dem Koppeln die LEDs Merkel und Schulz auf
In der Amazon Alexa App tauchen nach dem Koppeln die LEDs Merkel und Schulz auf

Falls Sie es interessieren sollte: Warum fauxmo funktioniert wie es funktioniert, erläutert der Ur-Vater von fauxmo in einem interessanten Artikel[12].

Kleine Warnung vorweg: Die Lösung scheint in Kombination mit ESP8266-Core und ES32-Core noch nicht für alle Generation beziehungsweise Typen von Echo-Hardware zu funktionieren - so soll es in Geräten der zweiten Generation unter Umständen zu Problemen kommen. Ich hatte beispielsweise damit zu kämpfen, dass Alexa beim Sprachbefehl "Alexa, suche neue Geräte!" meine Selbstbau-Fauxmos nicht finden konnte, diese sich aber hinterher trotzdem auf der Alexa App aufgelistet befanden, und über Sprache steuerbar waren. Generell scheint die Verwendung mit ESP8266 momentan weniger Zicken zu machen als mit einem ESP32-Board.

Nutzung der Bibliothek

Die Verwendung der Bibliothek in eigenen Programmen ist äußerst simpel.

  • Eine Variable des Typs fauxmoESP definieren.
  • Über diese Variable im Setup alle gewünschten Geräte anmelden, und fauxmo einschalten.
  • In den Callback-Routinen Aktionen ausführen. Letzteres wird weiter unten eine Demoanwendung veranschaulichen.

Damit lautet das prinzipielle Gerüst eines fauxmo-basierten Sketches:

#include // Headerdatei inkludieren

fauxmoESP fauxmo; // Zugriff auf fauxmo

voidsetup() {

Serial.begin(115200);

... Mit WLAN verbinden...

fauxmo.addDevice("Gerät Eins"); // Zwei Geraete anmelden
fauxmo.addDevice("Gerät Zwei");

fauxmo.enable(true); // Jetzt fauxmo aktiv schalten

fauxmo.onSetState([](unsignedchar device_id, constchar* device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) state: %s\n", device_id, device_name, state ? "ON" : "OFF");
});
fauxmo.onGetState([](unsignedchar device_id, constchar* device_name) {
return true; // Status zurückmelden
});

}

voidloop() {
fauxmo.handle(); // Eigentliche Event-Loop
}

Portzuordnung

In der Arduino IDE haben die verschiedenen Ports einfache Zuordnungen, etwa D1 = 1 oder D2 = 2, was der Tatsache geschuldet ist, dass die IDE sich ursprünglich stark an Arduino-Boards angelehnt hat. Für ESP2866- oder ESP32-Boards mit Arduino Core verhält sich die Angelegenheit ein wenig schwieriger, da sie ein anderes Layout ihrer Ausgänge besitzen. Die BUILTIN_LED lautet bei einem NODEMCU 1.0 16 (= D0). Hier gibt es folgende Portzuordnungen:

ESP8266  Arduino IDE
D0       16
D1 5
D2 4
D3 0
D4 2
D5 14
D6 12
D7 13
D8 15
D9 3
D10 1
Schaltungsbeispiel

Als Beispielsanwendung sollen zwei schlichte LEDs zum Einsatz kommen. Beide meldet der Sketch als Wemo-Geräte bei Amazon Echo an, sodas sie sich mittels Alexa ein- und ausschalten lassen. Das Beispiel nutzt einen Baustein des Typs NodeMCU (Wemos Lolin) auf Basis des ESP8266. Stattdessen kann auch ein ESP32-Board zum Einsatz kommen, aber für das simple Beispiel ist bereits der ESP8266 unterfordert.

Die Schaltung verwendet lediglich die Ports D0, D1 des Boards zur Ansteuerung der LEDs
Die Schaltung verwendet lediglich die Ports D0, D1 des Boards zur Ansteuerung der LEDs

In der Schaltung sind zwei LEDs (rot und blau) jeweils über 220Ω Widerstände an die Ports D0 (= Pin 16 des Wemos Lolin v3 / NodeMCU Boards) und D1 (= Pin 5 des Wemos Lolin v3 / NodeMCU Boards) angeschlossen. GND des Boards wird mit den beiden LEDs gemeinsam über das Breadboard geerdet (blaue Verbindung).

In einem anwendungsnäheren Szenario würden die Ausgänge keine LEDs ansteuern sondern Relais, über die sich größere Lampen in einem 12V-Stromkreis ein- oder ausschalten lassen.

Fauxmo Sketch

Der zugehörige Sketch folgt ganz dem Muster, das wir oben kennengelernt haben. Das Programm gaukelt dem Echo-System zwei Wemo-Geräte namens "Merkel" und "Schulz" vor. Wir hätten bis zu gut einem Dutzend Geräte einführen können.

Hinweis: Bei den meisten Boards mit ESP8266 oder ESP32 existiert eine Flash- beziehungsweise Boot-Taste neben einer Reset-Taste. Um das Board mit einem neuen Sketch bespielen zu können, muss beim Reset die Flash-Taste gedrückt sein. Das liegt daran, dass ein Sketch zusammen mit dem Arduino Core in Wirklichkeit eine Firmware bildet. Zwar führt die IDE beziehungsweise die Werkzeuge für ESP8266/ESP32-Programmierung eines Reset aus, aber es empfiehlt sich, die Reset-Taste selbst manuell bei gedrückter Flash-Taste zu betätigen. Dann klappt es mit dem Aufspielen des Sketches. Ohne Betätigen der Flash-Taste geht das Board einfach in den Ausführungsmodus und verweigert sich jedem Upload.

//***********************************************************
//
// Demoanwendung um mittels eines ESP32- oder ESP8266-Boards
// eine Belkin Wemo Steckdose zu simulieren
// Michael Stal, 2018
// Creative Commons
//
//************************************************************

#include

#ifdef ESP32 // Im Falle eines ESP32-Boards
#include
#else // bei einem ESP8266-Board
#include
#endif

// Die wichtigste Bibliothek ist fauxmoESP
#include "fauxmoESP.h"

// Zwei Lampen
#define MERKEL_LED 5
#define SCHULZ_LED 16

// Volle Kanne am seriellen Port
#define SERIAL_SPEED 115200

#define WL_SSID "StalWLAN"
#define WL_PASS "4242424242"

#define LAMPE1 "Merkel"
#define LAMPE2 "Schulz"

fauxmoESP fauxmo; // Objekt zum Zugriff auf fauxmo

//***********************************************************
//
// wifiSetup dient zur Verbindung ins WLAN >>WL_SSID<<
//
//************************************************************

void wifiSetup() {
// Das ESP-Board wird zur Station gemacht:
WiFi.mode(WIFI_STA);

// Verbindungsaufbau
Serial.printf("[WIFI] Verbinden zu %s ", WL_SSID);
WiFi.begin(WL_SSID, WL_PASS);

// Warten bis Verbindungsaufbau erfolgt ist
while (WiFi.status() != WL_CONNECTED) {
Serial.print(">");
delay(100);
}
Serial.println();

// Verbunden!
Serial.printf("[WIFI] Client Modus, SSID: %s, IP Adresse: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());
}

//***********************************************************
//
// setup initiiert den WLAN setup,
// schaltet beide Lampen aus,
// aktiviert fauxmo,
// meldet beide Lampen an,
// und definiert dafür Callbackhandler
//
//************************************************************

void setup() {
// Seriellen Port initialisieren
Serial.begin(SERIAL_SPEED);
Serial.println();
Serial.flush();

// Hier erfolgt der Verbindungsaufbau zum WLAN
wifiSetup();

// Die beiden LEDs
pinMode(MERKEL_LED, OUTPUT);
digitalWrite(MERKEL_LED, LOW);

pinMode(SCHULZ_LED, OUTPUT);
digitalWrite(SCHULZ_LED, LOW);


// Die Bibliothek lässt sich aktivieren und deaktivieren.
// Im deaktivierten Modus lassen sich Geraete weder finden noch schalten

fauxmo.enable(true);

// Alexa virtuelle Geraete unterjubeln
fauxmo.addDevice(LAMPE1);
fauxmo.addDevice(LAMPE2);

// Callback, sobald Lampe von Alexa geschaltet wird:
fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state) {
Serial.printf("[MAIN] Device #%d (%s) Zustand: %s\n", device_id, device_name, state ? "AN" : "AUS");
if ( (strcmp(device_name, LAMPE1) == 0) ) {
Serial.println("Merkel wird geschaltet");

if (state) { // Abhaengig vom Zustand Lampe ein-/ausschalten
digitalWrite(MERKEL_LED, HIGH);
} else {
digitalWrite(MERKEL_LED, LOW);
}
}
if ( (strcmp(device_name, LAMPE2) == 0) ) {
Serial.println("Schulz wird geschaltet");
if (state) { // Abhaengig vom Zustand Lampe ein-/ausschalten
digitalWrite(SCHULZ_LED, HIGH);
} else {
digitalWrite(SCHULZ_LED, LOW);
}
}
});
}

//***********************************************************
//
// loop ist die Ereignisschleife unseres Fake Wemo
//
//************************************************************

void loop() {
// Asynchron auf Echo-Kontaktaufnahmen warten, und darauf reagieren
fauxmo.handle();
}

Nach dem Koppeln über Sprachbefehl "Alexa, suche neue Geräte" oder über die Alexa App (Android, iOS), finden sich die neuen Lampen als Wemo-Steckdosen in der Geräteliste, und lassen sich entweder von der App oder mit Sprachbefehlen steuern, etwa mit "Alexa, schalte Merkel an!". So einfach kann das Leben sein.

In der Amazon Alexa App tauchen nach dem Koppeln die LEDs Merkel und Schulz auf
In der Amazon Alexa App tauchen nach dem Koppeln die LEDs Merkel und Schulz auf
Fazit

In der vorliegenden Folge haben wir kennengelernt, wie sich an einem ESP32- oder ESP8266-Board angeschlossene Geräte über Amazon Echo ansteuern lassen. Das funktioniert allerdings nur, sofern diese Geräte wie eine Lampe oder Steckdose nur zwei Zustände kennen, nämlich ein und aus. Der Trick besteht darin, dass die Bibliothek fauxmoESP dem Echo-Gerät vorspielt, es verkörpere eine Belkin Wemo Steckdose. Wer einen Raspberry Pi, eine Synology-Workstation oder einen Linux/Mac-Computer nutzt, kann dort die Python-Version von fauxmo zum gleichen Zweck nutzen. Siehe die erweiterte Version von n8henrie[13] oder die ursprüngliche Version von makermusings[14].

Für komplexere Interaktionen und Geräte müssen Maker wohl oder übel auf der Amazon-Plattform (Amazon Lambda) Hand anlegen und komplexere Skills implementieren.


URL dieses Artikels:
http://www.heise.de/-3991889

Links in diesem Artikel:
[1] https://www.heise.de/developer/artikel/Arduino-goes-ESP8266-3240085.html
[2] https://www.heise.de/developer/artikel/Make-your-own-ESP8266-WiFi-Shield-3246107.html
[3] https://www.heise.de/developer/artikel/ESP32-Neuer-IoT-Chip-von-Espressif-3506140.html
[4] https://github.com/esp8266/Arduino
[5] https://github.com/espressif/arduino-esp32
[6] https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
[7] http://www.wch.cn/download/CH341SER_ZIP.html
[8] https://bitbucket.org/xoseperez/fauxmoesp
[9] https://github.com/makermusings/fauxmo
[10] https://codeload.github.com/me-no-dev/AsyncTCP/zip/master
[11] https://codeload.github.com/me-no-dev/ESPAsyncTCP/zip/master
[12] http://www.makermusings.com/2015/07/13/amazon-echo-and-home-automation/
[13] https://github.com/n8henrie/fauxmo
[14] https://github.com/makermusings/fauxmo

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 14. März 2018 um 07:00

FreshRSS 1.10.2

Von Alkarex

This version is only relevant for Docker.

Changelog:

  • Bug fixing
    • Fix Docker image for OPML import #1819
    • Fix Docker image for CSS selectors #1821
    • Fix Docker other missing PHP extensions #1822
  • 09. März 2018 um 11:08

Überraschungsei für Wetterfrösche dank BME680, ESP8266, Arduino & ThingSpeak

Von heise online

zurück zum Artikel

In der heutigen Folge soll eine von einem Arduino-Board betriebene Wetterstation periodisch Umweltdaten erfassen, und diese Daten mittels WiFi über HTTP in eine Cloud-Plattform übertragen. Interessierte Zeitgenossen können dann live am mobilen oder stationären Gerät die Entwicklung der Messdaten in der Cloud verfolgen. Um dieses Ziele zu erreichen, müssen wir uns mehreren Herausforderungen stellen. Welche das sind und wie sie sich lösen lassen, zeigt der vorliegende Artikel. Seien Sie aber unbesorgt - es gibt ein Happy End!

Alles in der Cloud

Wenn wir Sensor-Daten der Wetterstation in der Cloud speichern wollen, können wir PasS/IaaS-Plattformen wie Amazon AWS oder Microsoft Azure nutzen. Einfacher und preisgünstiger gestaltet sich die Aufgabe mit einer speziell für Datenanalytik konzipierten Lösung. ThingSpeak ist eine solche IoT-Plattform und ermöglicht das Ablegen von Sensordaten. Sie integriert darüber hinaus MATLAB-Werkzeuge von MathWorks für komplexere Datenvisualisierungen. Ein freier Account stellt eine kostenlose Möglichkeit dar, um Daten-Kanäle einzurichten, die der Nutzer allerdings höchstens alle 16 Sekunden aktualisieren darf. Kanäle können dabei privat oder öffentlich zugänglich sein. Der Charme von ThingSpeak liegt in seiner einfachen Nutzbarkeit dank schlichtem HTTP, das es für das Lesen oder Schreiben von Daten verwendet. Die Kanäle lassen sich über Webbrowser oder Apps beobachten.

Zum Registrieren eines neuen Kontos gehen Interessierte auf die ThingSpeak-Webseite[1].

Anmeldung als neuer Nutzer auf der ThingSpeak
Anmeldung als neuer Nutzer auf der ThingSpeak

Nach der erfolgreichen Erstellung eines neuen Kontos kann die neue Nutzerin sich in das eigene anmelden.

Erstellen eines neuen Benutzerkontos auf ThingSpeak
(Bild: Erstellen eines neuen Benutzerkontos auf ThingSpeak)

Ist das Konto fertig eingerichtet, kann der Nutzer durch einfachen Knopfdruck einen neuen Kanal erstellen: siehe hier[2]. Der Kanal braucht zumindest einen Namen, und zwischen eins und acht Daten-Feldern. Nur wer will, kann zusätzlich weitere Information wie geographische Position, eine externe Webseite oder Metadaten angeben.

Teilnehmer können ihre eigenen Kanäle anmelden
Teilnehmer können ihre eigenen Kanäle anmelden

Der neue Kanal taucht jetzt in der Hauptseite des Nutzers auf. Über die Registerkarte API Keys lassen sich die vertraulichen Zugriffsschlüssel zum Lesen und Schreiben abrufen.

Auf der Registerkarte erfährt der IoT-Maker seine API-Schlüssel, die er später in seinen Programmen benötigt
Auf der Registerkarte erfährt der IoT-Maker seine API-Schlüssel, die er später in seinen Programmen benötigt

In der Registerkarte Sharing ist das eingeschränkte Freigabe des Kanals für bestimmte Personen oder sogar die öffentliche Freigabe des Kanals möglich. In letzterem Fall kann jeder Nutzer weltweit den Kanal beobachten, etwa durch Eingabe der öffentlichen Channel ID. Der von mir für dieses Postings benutzte Kanal besitzt übrigens die Kennung 438188 und lässt sich über die Seite[3] lesen. Das ist auch programmatisch möglich, wie der Artikel noch später illustriert. Die ersten fünf Diagramme zeigen den zeitlichen Verlauf der Sensordaten-Felder, das sechste eine MATLAB-Analyse über die Häufigkeiten bestimmter Temperaturwerte.

ThingSpeak erlaubt die Erstellung privater Kanäle.

Einen privaten Datenkanal kann nur dessen Ersteller nutzen
Einen privaten Datenkanal kann nur dessen Ersteller nutzen

Alternativ ist auch die Kreierung eines öffentlich zugänglichen Kanals möglich. Öffentliche Kanäle haben eine eindeutige Kennung. Sie lassen sich über Web-Browser beobachten, oder auch von mobilen Geräten aus. Etwa von einem Tablet

Kanalbeobachtung für die Wetterstation auf einem iPad
Kanalbeobachtung für die Wetterstation auf einem iPad

Oder auch über Apps:

Eine der Apps zum Beobachten von öffentlichen ThingSpeak-Kanälen
Eine der Apps zum Beobachten von öffentlichen ThingSpeak-Kanälen
Umweltsensor BME680

Die Datenablage wäre also jetzt geklärt. Nur woher kriegen wir eigentlich unsere physikalischen Messwerte?
Der Sensor BME680 von Bosch Sensortec[4] misst Umweltgrößen und adressiert speziell kleinere und mobile Geräte. Er erweitert den bekannten Sensor BME280 aus gleichem Hause. Zu seinen Messgrößen gehören Temperatur (-45...85°) , Luftfeuchtigkeit (0...100%), Luftdruck (300...1100hPa), Höhe, und Luftqualität im Raum (Indoor Air Quality). Dabei liegt sein Stromverbrauch bei wenigen Micro-Ampere. Mit Ausmaßen von 3.0mm x 3.0mm x 0.93mm zeigt sich der Sensor gut gewappnet, um eine kleinere Wetterstation oder ein Wearable zu betreiben. Die Luftbelastung ermittelt der BME680 in Form eines Widerstandswerts in der Einheit KOhm. Je niedriger dieser Widerstand ausfällt, desto mehr Teilchen sind in der Luft. Bosch berechnet daraus den Indoor Air Quality Index. Das funktioniert aber nur mit einer speziellen Bibliothek des Herstellers (https://github.com/BoschSensortec/BME680_driver), da dazu auch einige Betriebswerte des Sensors ins Spiel kommen. Wollen Sie den Index berechnen, müssen Sie folglich diese Bibliothek in Ihren Sketch integrieren. Weitere Details über den Sensor können sie dessen Datasheet [5]entnehmen.

Der Sensor BME680 misst verschiedene Umweltgrößen
Der Sensor BME680 misst verschiedene Umweltgrößen (Bild: Bosch Sensortec)

Natürlich erwerben Maker den Sensor üblicherweise nicht “nackt”, sondern in Form eines Breakout-Boards. Die Produkte stammen von Herstellern wie BlueDot, Adafruit, Watterott, MikroElektronika, Octopus oder Pimeroni. Die meisten Breakout-Boards stellen eine I2C- und als Alternative eine SPI-Schnittstelle zur Verfügung, und haben einen Logic Level Konverter onboard, sodass der Nutzer den Sensor mit Spannungen von 3V-5V betreiben kann.

Für den vorliegenden Beitrag findet ein entsprechendes Board von Watterott[6] zu preisgünstigen 15,95 Euronen Verwendung (siehe Abbildung).

Watterott
BME680-Breakout-Board von Watterott (Bild: Watterott)

Beim Anschluss habe ich mich für I2C (auch bezeichnet mit IIC, I2C, TWI) entschieden, um mit zwei Leitungen für die Kommunikation zwischen Arduino und BME680 auszukommen. Nähere Details zu I2C hat dieser Blog bereits früher vorgestellt[7].
Unter I2C/TWI besitzt der Sensor entweder die eindeutige I2C-Kennung 0x76 oder 0x77, je nachdem ob der Pin SDO auf 0 liegt oder auf 1. Letzteres sofern gleichzeitig Pin CS auf 1 liegt. Jedenfalls verbinden Maker IIC-Takt und Datenleitungspins von Arduino und Breakout-Board abhängig vom gewählten Arduino-Board.

Auf der Arduino IDE ist für die Ansteuerung des BME680 eine Bibliothek von Adafruit verfügbar. Da die BME680-Boards direkten Zugriff auf den Sensor implementieren, ist die Adafruit-Bibliothek wie auch zum Beispiel die Bibliothek von BlueDot für das Watterott-Breakout-Board ebenfalls nutzbar. Suchen Sie also im Bibliotheksmanagement der Arduino IDE nach dem Begriff BME680 und installieren Sie die entsprechende Bibliothek von Adafruit. Zwecks manueller Installation lässt sich die Bibliothek auch über GitHub beziehen: hier geht es zur Bibliothek[8].

Die Programmierung ist selbsterklärend. bme.setup() startet den Sensor, bme.performReading() führt die Messung durch. Danach lassen sich über die Variable bme die Messwerte auslesen. Die Initialisierung am Anfang von setup() habe ich der Dokumentation von Bosch Sensortec entnommen.

// Adafruit-Bibliothek für BME680
#include
#include
#include "Adafruit_BME680.h"

// Luftdruck auf Meereshoehe:
#define SEALEVELPRESSURE_HPA 1013.25

Adafruit_BME680 bme; // Zugriff ueber I2C

double humidity = 0.0; // Feuchtigkeit
double temperature = 0.0; // Temperatur
double pressure = 0.0; // Druck
double gas = 0.0; // Gas/Luftqualitaet
double est_altitude= 0.0; // Ungefaehre Hoehe

void setup()
{
Serial.begin(9600); // seriellen Monitor starten

if (!bme.begin()) {
Serial.println("Keinen BME680 Sensor gefunden!");
while (1);
}

// Initialisierung von Oversampling und Filter
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop()
{
measurement(); // Messwerte erfassen
}

void measurement(void)
{
// Erst den bme680 auslesen
if (! bme.performReading()) {
Serial.println("Fehler beim Messen ");
return;
}

// Werte ermitteln:
temperature = bme.temperature;
pressure = bme.pressure / 100.0;
humidity = bme.humidity;
gas = bme.gas_resistance / 1000.0;
est_altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);

// und am seriellen Monitor ausgeben
Serial.print("Temperatur = ");
Serial.print(temperature);
Serial.println(" *C");

Serial.print("Luftdruck = ");
Serial.print(pressure);
Serial.println(" hPa");

Serial.print("Feuchtigkeit = ");
Serial.print(humidity);
Serial.println(" %");

Serial.print("Gas = ");
Serial.print(gas);
Serial.println(" KOhms");

Serial.print("Ungefaehre Hoehe = ");
Serial.print(est_altitude);
Serial.println(" m");

Serial.println();
delay(2000);
}

Die Ausgabe schaut bei einem Testlauf meiner Schaltung wie folgt aus:

Temperatur = 24.13 *C
Luftdruck = 939.03 hPa
Feuchtigkeit = 31.02 %
Gas = 60.68 KOhms
Ungefaehre Hoehe = 636.94 m

Temperatur = 24.13 *C
Luftdruck = 939.05 hPa
Feuchtigkeit = 31.00 %
Gas = 61.08 KOhms
Ungefaehre Hoehe = 636.94 m

Bosch empfiehlt, den Sensor längere Zeit einzubrennen, damit er stabile Messwerte liefert. Speziell am Anfang ist sonst zum Beispiel der gemessene Luftwiderstand zu ungenau. Lassen Sie Ihre Schaltung daher ruhig initial für 24-48 Stunden laufen.

Arduino Nano

Für die Messwerterfassung und die Integration aller Komponenten kommt, wie nicht anders zu erwarten, ein Original-Arduino zum Einsatz.

Reichelt
Ein Arduino Nano ist kompakt und preisgünstig, aber trotzdem elistungsfähig (Bild: Reichelt)


Als Board verwendet der Beitrag den Arduino Nano mit 5V-Logik, der unter seiner Motorhaube einen ATmega328 beherbergt. Mit 2 KB SRAM und 32 KB Flashspeicher sowie 16 Mhz Frequenz ist das kompakte Board ideal für eine kleine Wetterstation geeignet. Pin Layout auf der Seite[9] verfügbar.

Das Pin-Layout eines Arduino Nano. Rechts im Bild sind die I2C-Pins A4 und A5 zu sehen
Das Pin-Layout eines Arduino Nano. Rechts im Bild sind die I2C-Pins A4 und A5 zu sehen

Für die Kommunikation über I2C mit dem BME680-Breakout-Board dienen beim Nano die Pins A4 und A5 (Daten über SDA, Takt über SCL).
Selbstverständlich können Sie statt des Nano auch ein anderes Arduino-Board einsetzen, das I2C oder SPI implementiert, etwa einen Leonardo, Uno oder Mega. Dann müssen Sie statt A4 und A5 die jeweils dort zuständigen Pins für I2C verwenden.

Kommunikation über ESP8266

Wir haben inzwischen die Cloudplattform, den Sensor und als zentrale Steuerung einen Arduino Nano. Das letzte Puzzlestück besteht aus der Kommunikation des Arduino-Boards mit der Cloud. Wer kein Arduino-Board mit integriertem (W)LAN-Anschluss sein eigen nennt (Arduino MKR1000, Yun, Arduino plus Ethernet-Shield oder WiFi-Shield …), muss sich anderweitig behelfen. Den dafür prädestinierten Chip von Espressif namens ESP8266 hatte dieser Blog schon ausführlich adressiert: siehe hier[10]. Ihn gibt es in verschiedenen Varianten für eine Handvoll Euro. Allgemein steht ESP8266 für einen Microcontroller mit zusätzlicher WiFi-Komponente. Soll ein Arduino Board günstig ins Internet, bietet sich daher der ESP8266 geradezu an. Größere ESP8266-Varianten wie nodemcu (ESP-12e oder ESP-12f) kann der Entwickler auch standalone einsetzen, also ganz ohne Arduino.

Für die Kommunikation der Wetterstation kommt ein ESP-01 aus der Produktfamile ESP8266 zum Einsatz
Für die Kommunikation der Wetterstation kommt ein ESP-01 aus der Produktfamile ESP8266 zum Einsatz

Wir nutzen trotzdem die einfachste Bauform, den ESP-01, um unsere Arduino-basierte Schaltung für lau mit WiFi-Kommunikation auszustatten.

Die Pinbelegung eines ESP-01 (ESP8266)
Die Pinbelegung eines ESP-01 (ESP8266)

Da der ESP-01 nur 3,3V verträgt, braucht die Wetterstation allerdings einen Logik Level Konverter zwischen den 3,3V des ESP-01 und der 5V Logik des Arduino Nano. Für unseren Zweck sollte der Konverter-Baustein neben den Stromanschlüssen Vcc und GND auf jeder Seite über 4 Kanäle verfügen. Beispielsweise tut es folgendes Produkt von SparkFun: Logic-Level-Konverter[11].

Ein Logic Level Converter vermittelt zwischen 3,3V und 5V Bausteinen
Ein Logic Level Converter vermittelt zwischen 3,3V und 5V Bausteinen (Bild: SparkFun)


Seinen “Saft” kann der ESP-01 von verschiedenen Seiten erhalten. In der vorliegenden Schaltung habe ich mich für ein FTDI-TTL-to-USB-Modul entschieden, da sich der ESP-01 damit auch direkt am Computer, beispielsweise über die Arduino IDE betreiben lässt.

Exemplarisch ein FTDI-Board von SparkFun. Damit können Entwickler den ESP-01 mit einem PC verbinden
Exemplarisch ein FTDI-Board von SparkFun. Damit können Entwickler den ESP-01 mit einem PC verbinden (Bild: SparkFun)

Das ist beispielsweise nötig, um ihn zu konfigurieren oder mit neuer Firmware zu flashen.
Es ergibt sich somit folgende Schaltung:

Um den ESP-01 standalone zu programmieren,  erfolgt eine Verbindung mit dem Computer über ein FTDI-USB-to-TTL Board
Um den ESP-01 standalone zu programmieren, erfolgt eine Verbindung mit dem Computer über ein FTDI-USB-to-TTL Board

Der ESP-01 hat standardmäßig einen AT-Kommandointerpreter als Firmware an Bord, und ist auf hohe Baudraten eingestellt. Da viele Arduino-Boards leider nur einen einzigen UART-Eingang besitzen, den sie per USB zum Laden von Firmware, Bootloadern und Sketches nutzen, müssen wir jeden weiteren seriellen Kanal per Software simulieren. Dazu gibt es die Bibliothek SoftwareSerial, dank der sich zwei beliebige Pins des Arduino als RX (Eingang) und TX (Ausgang) nutzen lassen, was aber nur bei niedrigeren Baudraten funktioniert. Daher besteht die erste Aufgabe darin, den ESP-01 entsprechend zu konfigurieren. Beispielsweise benötigen wir eine Rekonfiguration des ESP-01 auf eine Baudrate von 9600.
Zu diesem Zweck schließen wir den ESP-01 über einen FTDI-USB-to-TTL-Adapter direkt an den Desktop oder Notebook an, und rufen die Arduino IDE auf. Unter dem Menü Tools stellen wir den richtigen COM-Port des FTDI-Adapters ein. Wir wechseln in den seriellen Monitor (ebenfalls im Tools-Menü). Als Baudrate funktioniert zunächst dank Werkseinstellung meistens 112500 oder 57600 Baud (rechts unten im Fenster). Als Modus sollte Both NL and CR selektiert sein (links neben der Baudrate).

Die Verwendung der Arduino IDE ist nicht alternativlos. Anstelle der IDE erlauben Terminal-Werkzeuge wie putty, ssh einen Dialog mit dem ESP-01.

Sitzung mit dem AT-Kommandointerpreter des ESP-01. Für die Wetterstation sind Baudrate und ZUgang/Verbindung mit einem WLAN einzurichten
Sitzung mit dem AT-Kommandointerpreter des ESP-01. Für die Wetterstation sind Baudrate und ZUgang/Verbindung mit einem WLAN einzurichten

Um die Funktionstüchtigkeit des ESP-01 zu prüfen, gibt der Nutzer im Textfeld AT, gefolgt von der Eingabetaste ein, worauf die Rückmeldung Ok erscheinen müsste. Der Befehl AT+UART_DEF=9600,8,1,0,0 konfiguriert die Baudrate dauerhaft auf 9600 Baud.
Mit AT+CWMODE=1 lässt sich der ESP-01 als WLAN-Client einstellen.
Der AT-Befehl für die Verbindung zu einem existierenden WLAN lautet: AT+CWJAP=“SSID”,”PASSWORD”
Anschließend müsste der ESP-01 die erfolgreiche Verbindung zum WLAN bestätigen. Es sollte sich hierbei um das WLAN handeln, in die sich die Wetterstation später einloggt. Alternativ können Sie diese Verbindung aber auch aus dem Arduino-Sketch heraus bewerkstelligen.
Mittels Eingabe von AT+CIFSR erfährt der Entwickler dann unter anderem die IP, die der Access Point dem ESP-01 zugewiesen hat. Nun kennen Sie die Adresse der Wetterstation im eigenen Netz.
Nach dieser Konfiguration ist der ESP-01 für den Zugriff über den Arduino Nano gerüstet. Ein Arduino-Sketch sendet AT-Befehle über einen SoftwareSerial-Anschluss an den ESP-01, und kann diesen durch Ansteuerung des RESET-Eingangs sogar neustarten.

Kleiner Zwischen-Ausflug in Sachen ESP8266

Arduino Core für ESP8266

Der ESP8266 lässt sich übrigens auch wie ein Arduino Board innerhalb der Arduino IDE nutzen.
Dazu geben Sie im Sub-Menü Voreinstellungen (beziehungsweise Preferences) zusätzliche die URL folgenden Boardsmanagers ein:

 http://arduino.esp8266.com/stable/package_esp8266com_index.json 

Steht dort schon ein Eintrag, geben Sie an dessen Ende ein Komma ein, gefolgt von der genannten URL.
Anschließend können Sie im Tools > Board Menü die esp8266-Plattform installieren. Danach ist noch im Tools-Menü die Auswahl des richtigen COM-Ports und im Boards-Menü das Selektieren des Generic ESP8266 Module notwendig. Jetzt lassen sich Arduino-Sketches auf dem ESP-Modul hochladen und ausführen. Achtung: Dadurch wird auch eine neue Firmware (Arduino Core) auf den ESP-01 übertragen. Die AT-Firmware, die wir für die Wetterstation benötigen, geht damit verloren, und Sie müssen diese Firmware demzufolge bei Bedarf neu auf den ESP-01 flashen.

Zwei Modi

An dieser Stelle ist noch der Hinweis wichtig, dass ein ESP8266 zwei Laufzeitmodi kennt. Das eine ist der Programmausführungsmodus, also der Normalbetrieb, bei dem der ESP-01 ein Programm ausführt. Das andere ist der Flash-Modus bzw. Bootloader-Modus, der dem Entwickler gestattet, eine neue Firmware aufzuspielen. Wie bereits erwähnt, ist das Hochladen eines neuen Sketches über die Arduino IDE auf ein ESP8266-Board gleichbedeutend mit einem Flashen. Kurz und prägnant: Kein Flashmodus => Kein Sketchupload.
In welchem Modus der ESP läuft, entscheidet sich beim Boot/RESET des Chips. Ist während des Resets der Pin GPIO0 mit LOW belegt, startet der ESP8266 im Flashmodus, ansonsten im Ausführungsmodus.

Flashen des ESP8266

Es führen mehrere Wege nach Rom. Zum einen erlaubt das ESP8266 Flasher Werkzeug unter Windows ein relativ bequemes interaktives Flashen.
Dieses Tool erhalten Sie kostenlos unter der URL[12].
Die AT-Firmware ist über eine Webseite[13] downloadbar.
Mit dem kommandozeilenorientierten Python-Werkzeug esptool.py auf GitHub (siehe hier[14]) ist das Firmware-Flashen auch unter Windows, MacOS oder Linux möglich.

Schaltung

Nun liegen alle Teile der Wetterstation unserer Stückliste vor:

  • Breadboard
  • ESP-01 (ESP8266)
  • Arduino Nano
  • FTDI USB-to-TTL Adapter
  • BME680 Sensor
  • Logic Level Converter (3,3V und 5V) mit 4 Datenkanälen
  • Mehrere Steckverbindungsdrähte (male-male und female-male)
  • Zwei USB-Kabel, eines für Arduino Nano und eines für das FTDI-Board

Der Aufbau der Schaltung kann beginnen. Insgesamt ergibt sich folgendes Bild:

Auf dem Bild ist die komplette Schaltung mit allen beteiligten Komponenten zu sehen
Auf dem Bild ist die komplette Schaltung mit allen beteiligten Komponenten zu sehen

Fehlt nur noch die Software. Beachten Sie auch die Variable esp01, hinter der sich die serielle Verbindung vom Arduino Nano zum ESP-01 verbirgt:

  • Pin D6 des Nano fungiert als virtueller RX-Kanal und ist mit dem TX-Pin des ESP-01 verbunden
  • Pin D7 des Nano fungiert als virtueller TX-Kanal und ist mit dem RX-Pin des ESP-01 verbunden
  • Pin D8 des Nano ist mit dem RESET-Eingang des ESP-01 verbunden
Mit Hilfe der Bibliothek SoftwareSerial erhalten wir:

SoftwareSerial esp01(6,7)

Über diese serielle Verbindung sendet der Arduino-Sketch AT-Befehle zum ESP-01 beziehungsweise erhält von dort Rückmeldungen.

Das komplette Programm für die Wetterstation

Der Sketch verbindet sich bei setup() mit ESP-01, seriellen Monitor und BME280-Sensor. In der Ereignisschleife loop() fragt der Arduino Nano nach mindestens 16 Sekunden die Messwerte des BME680 ab (measurement()) und versendet diese über den ESP-01 an ThingSpeak (sendMeasurement()). sendMeasurement() verbindet sich mit der HTTP-basierten ThingSpeak-API (connectToThingSpeak()) und liefert dann über HTTP GET einen Update der Messwerte ab (writeToThingSpeakChannel()).

resetESP01() dient - nomen est omen - zum programmatischen RESET des ESP-01.

In der Vereinbarung für CHANNEL_WRITE_KEY hinterlegen Sie ihren Schlüssel zum Updaten des Kanals (im Listing rot markiert).

/************************************************** 
*
* Mini-Wetterstation
* mit Sensor BME380
* Arduino Nano und
* ESP8266
* (c) Michael Stal, 2018
* Creative Commons License
*
**************************************************/


/****** Nur wenn nicht Hardware-Serial ******/

#include
#define ESP_RX 6 // Nutzung der Pins D6
#define ESP_TX 7 // ... und D7
// Anschluss des ESP01 ueber ESP_RX und ESP_TX

SoftwareSerial esp01(ESP_RX, ESP_TX);
/********************************************/

/******** Adafruit BME680 Bibliothek ********/</span>

// Adafruit-Bibliothek für BME680

#include
#include
#include "Adafruit_BME680.h"

// Luftdruck auf Meereshoehe:
#define SEALEVELPRESSURE_HPA 1013.25

Adafruit_BME680 bme; // Zugriff ueber I2C

double humidity = 0.0; // Feuchtigkeit
double temperature = 0.0; // Temperatur
double pressure = 0.0; // Luftdruck
double gas = 0.0; // Gas/Luftqualitaet
double est_altitude= 0.0; // Ungefaehre Hoehe

/********************* THINGSPEAK ********************/
#define CHANNEL_WRITE_KEY ""
#define THINGSPEAK_IP "184.106.153.149"
#define THINGSPEAK_PORT 80
/******************* ESP spezifisch ******************/
#define ESP_SPEED 9600 // ESP-01 auf 9600 Baud eingestellt!
#define ESP_RESET 8 //Arduino D8 pin <-> RESET pin ESP-01

#define ESP_AT_COMMAND_CIPSTART "AT+CIPSTART=\"TCP\",\""
#define ESP_AT_COMMAND_CIPSEND "AT+CIPSEND="
#define ESP_AT_COMMAND_CIPCLOSE "AT+CIPCLOSE"
/********************** Timing ************************/
// Alles was mit Zeitintervallen zu tun hat
long sampleTime = 16; // Mindestzeit zwischen Datenversand
// ist 16 Sekunden
long startInterval = 0; // Start des Intervals
long delta = 0; // Zeit seit Start des Intervals

/****************** Fehlerbedingung *******************/
boolean errorCondition;

/**************************************************
*
* setup()
* initialisiert BME680 Sensor
* resetted ESP-01
* und stellt Verbindung zu ESP-01 her
*
**************************************************/

void setup()
{
Serial.begin(9600); // seriellen Monitor starten

if (!bme.begin()) {
Serial.println("Keinen BME680 Sensor gefunden!");
while (1);
}

// Initialisierung von Oversampling und Filter
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320°C für 150 msec

pinMode(ESP_RESET,OUTPUT);

esp01.begin(ESP_SPEED); // Mit ESP01 reden
resetESP01(); // Resetten des ESP01
startInterval = millis(); // Aktuelle Zeit erfassen
}

/**************************************************
*
* loop()
* Misst alle 16 Sekunden (sampleTime) die
* Unweltwerte, und sendet diese an ThingSpeak
*
**************************************************/

void loop()
{
errorCondition=false; // erst mal optimistisch sein

delta = millis()-startInterval; // Zeit seit Start

if ((delta / 1000) > sampleTime) // Zeit seit Zugriff > Sampling Zeit?
{
measurement(); // Messwert erfassen
sendMeasurement(); // Daten schreiben

// jetzt wird startInterval mit aktueller Zeit besetzt
startInterval = millis();
}

if (errorCondition)
{
Serial.println("Fehler aufgetreten");
delay (2000); // warten und dann wieder weiter
}
}

/**************************************************
*
* measurement()
* Liest den BME680 aus und speichert die Werte
* in Variablen, gibt diese auch am seriellen
* Monitor aus
*
**************************************************/

void measurement(void)
{
// Erst den bme680 auslesen
if (! bme.performReading()) {
Serial.println("Fehler beim Messen ");
return;
}

// Werte ermitteln und merken:
temperature = bme.temperature;
pressure = bme.pressure / 100.0;
humidity = bme.humidity;
gas = bme.gas_resistance / 1000.0;
est_altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);

// und am seriellen Monitor ausgeben
Serial.print("Temperatur = ");
Serial.print(temperature);
Serial.println(" *C");

Serial.print("Luftdruck = ");
Serial.print(pressure);
Serial.println(" hPa");

Serial.print("Feuchtigkeit = ");
Serial.print(humidity);
Serial.println(" %");

Serial.print("Gas = ");
Serial.print(gas);
Serial.println(" KOhms");

Serial.print("Ungefaehre Hoehe = ");
Serial.print(est_altitude);
Serial.println(" m");

Serial.println();
delay(2000);
}

/**************************************************
*
* sendMeasurement()
* verbindet sich mit ThingSpeak-Kanal
* und sendet eine HTTP GET, um die gemessenen
* Werte im Kanal zu speichern
*
**************************************************/

void sendMeasurement(void)
{

connectToThingSpeak(); // Verbindungsaufbau

if (!errorCondition) { // nur wenn Verbindung geklappt hat
String update = "GET /update?api_key=";
update += CHANNEL_WRITE_KEY;
update +="&field1=";
update += String(temperature);
update +="&field2=";
update += String(humidity);
update +="&field3=";
update += String(gas);
update +="&field4=";
update += String(pressure);
update +="&field5=";
update += String(est_altitude);
update += "\r\n\r\n";

writeToThingSpeakChannel(update); // Messwerte schreiben
}
if (errorCondition)
Serial.println("Verbindung hat nicht geklappt");
}

/**************************************************
*
* resetESP01()
* startet den angeschlossenen ESP-01 neu
*
**************************************************/

void resetESP01(void)
{
Serial.println("Reset des ESP01");
digitalWrite(ESP_RESET, LOW);
delay(1000);
digitalWrite(ESP_RESET, HIGH);
delay(10000);
Serial.println("ESP01 RESET beendet");
}

/**************************************************
*
* connectToThingSpeak()
* verbindet sich mit ThingSpeak-Kanal
*
**************************************************/

void connectToThingSpeak(void)
{
esp01.flush(); // Buffer leeren

String espCommand = ESP_AT_COMMAND_CIPSTART;
espCommand += THINGSPEAK_IP; // IP
espCommand += "\","; // PORT
espCommand += THINGSPEAK_PORT;
Serial.print("Verbindungsaufbau mit thingspeak ueber ");
Serial.println(espCommand);
esp01.println(espCommand);

if(esp01.find("error")) // Fehler aufgetreten?
{
Serial.println("Verbindungsfehler");
errorCondition=true;
}
}

/**************************************************
*
* writeToThingSpeakChannel()
* sendet einen Update-Befehl an den Kanal
* Uebergabe der Parameter mit command
*
**************************************************/

void writeToThingSpeakChannel(String command)
{
int len = command.length();
String specifyLengthCommand = ESP_AT_COMMAND_CIPSEND;
specifyLengthCommand += String(len);
Serial.print("Paketlaenge: ");
Serial.println(len);
// Mitteilen der Paketlaenge an ESP-01:
esp01.println(specifyLengthCommand);

if(esp01.find('>')) // Nach Nutzlast suchen
{
Serial.print("Kommando = ");
Serial.println(command);
esp01.print(command); // Eigentliches Update der Messdaten anfordern

delay(1000); // Warten auf ESP

while (esp01.available()) // Daten liegen Zeile fuer Zeile an
{
String line = esp01.readStringUntil('\n'); // Zeile lesen
if (line.length() == 1) // es war eine Leerzeile
{ // Inhalt nach Leerzeile lesen
line = esp01.readStringUntil('\n');
// ... und ausgeben:
Serial.print("Antwort: ");
Serial.println(line);
}
}
}
else
{
esp01.println(ESP_AT_COMMAND_CIPCLOSE); // Verbindung schliessen
Serial.println("Sendefehler");
errorCondition=true;
}
} // this is the end, my friend

Fazit

Wir haben in dieser Folge aus Arduino, ESP-01, BME680, Logic-Level-Konverter in Kombination mit der Cloud-Plattform ThingSpeak eine Wetterstation als IoT-Lösung zusammengebaut. Natürlich ließe sich diese Wetterstation relativ problemlos um weitere Sensoren erweitern. Einige andere Arten von Sensoren für dieses Einsatzgebiet (Regensensoren, Helligkeit, UV-Strahlung, Radioaktivität, Gewittererkennung, Bodenfeuchtigkeit, Feinstaub-Belastung) haben wir in früheren Artikeln bereits kennengelernt. Schön wäre des Weiteren ein wasserfestes Gehäuse sowie Batterie- oder LiPo-Betrieb, damit wir die Station auch ausserhalb von Wohnung oder Haus betreiben können. Oder ein GSM/GPRS-Modul, um das System sogar in abgelegeneren Gefilden autonom zum Einsatz zu bringen. Mittels SD-Kartenschreiber könnten wir die Wetterdaten auch temporär lokal speichern, sollte eine Verbindung einmal nicht möglich sein. Nötig ist auch ein ansprechendes Gehäuse. Die Wunschliste wächst bei längerem Nachdenken. Oder aber wir sind bereits mit der einfachen Lösung wunschlos glücklich.

Viel Spaß beim Experimentieren.


URL dieses Artikels:
http://www.heise.de/-3979158

Links in diesem Artikel:
[1] https://thingspeak.com/users/sign_up
[2] https://thingspeak.com/channels/new
[3] https://thingspeak.com/channels/438188
[4] https://www.bosch-sensortec.com/bst/products/all_products/bme680
[5] https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680-DS001-00.pdf
[6] http://www.watterott.com/de/BME680-Breakout
[7] https://www.heise.de/developer/artikel/Anschluss-von-LCD-Displays-ueber-den-IIC-Bus-3217991.html
[8] https://github.com/adafruit/Adafruit_BME680
[9] http://www.pighixxx.com/test/pinouts/boards/nano.pdf
[10] https://www.heise.de/developer/artikel/Arduino-goes-ESP8266-3240085.html
[11] https://www.sparkfun.com/products/12009
[12] https://www.espressif.com/sites/default/files/tools/flash_download_tools_v3.6.3_0.rar
[13] https://www.espressif.com/sites/default/files/ap/esp8266_at_bin_v1.6.1.zip
[14] https://github.com/espressif/esptool

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 05. März 2018 um 12:40

FreshRSS 1.10.1

Von Alkarex

Changelog:

  • Deployment
    • New Docker image, smaller (based on Alpine Linux) and newer (with PHP 7.1) #1813
  • CLI
    • New command ./cli/prepare.php to make the needed sub-directories of the ./data/ directory #1813
  • Bug fixing
    • Fix API bug for EasyRSS #1799
    • Fix login bug when using double authentication (HTTP + Web form) #1807
    • Fix database upgrade for FreshRSS versions older than 1.1.1 #1803
    • Fix cases of double port in FreshRSS public URL #1815
  • UI
    • Add tooltips on share configuration buttons #1805
  • Misc.
    • Move ./data/shares.php to ./app/shares.php to facilitate updates #1812
    • Show article author email when there is no author name #1801
    • Improve translation tools #1808
  • 04. März 2018 um 18:04

Wo bin ich?

Von heise online

zurück zum Artikel

Für die meisten mobilen Geräte ist das Ermitteln der geographischen Position eine grundlegende Funktion. GNSS-Dienste wie GPS, Galileo, GLONASS, Beidou erlauben es, den aktuellen Ort mittels Satelliten zu bestimmen. Hierbei steht GNSS für Global Navigation Satellite System. Entsprechende Empfänger befinden sich inzwischen standardmäßig in Fahrzeugen, Smartphones, Kameras, Tablets, Drohnen oder Industriesteuerungen. Wie aber lässt sich eigene Hardware um diese Funktionalität erweitern?

GPS Faktencheck

GPS (Global Positioning System, ursprünglich NAVSTAR GPS, gibt es inzwischen schon seit den Siebziger Jahren. Insgesamt 24 Satelliten mit mittlerem Orbit von 20.200 km über der Erdoberfläche umkreisen unseren Planeten zweimal täglich. Je mindestens vier Satelliten bewegen sich dabei auf einer von sechs Bahnebenen, die 55 Grad gegen die Äquatorlinie geneigt sind. Dadurch sollen GPS-Empfänger zu jedem Zeitpunkt wenigstens vier Satelliten empfangen können. Nur mit Hilfe von vier Satelliten ist eine exakte Messung mit einer Fehlerabweichung von unter 10 Metern möglich.

Alle Satelliten senden diverse Information auf verschiedenen Frequenzen. Sie enthalten Atom- beziehungsweise Cäsium-Uhren, um eine genaue Zeit zusätzlich zur eigenen Position verschicken zu können. Diese Zeit berücksichtigt keine Schaltsekunden und weicht daher inzwischen rund 18 Sekunden von der koordinierten Weltzeit UTC ab, weshalb GPS-Empfänger die eigene Zeit entsprechend berechnen müssen. Aus den erhaltenen Daten kann der GPS-Empfänger unter anderem seine eigene Position, Bewegungsrichtung, Höhe und Geschwindigkeit ermitteln. Wissenswert am Rande ist die Tatsache, dass die GPS-Komponente wegen der hohen Geschwindigkeit von Satelliten relativ zum GPS-Empfänger relativistische Effekte berücksichtigen muss, weil sonst die Abweichung erheblich wäre.

Bewegung der GPS-Satelliten um die Erde. Schwarze Punkte haben Kontakt zum blauen Bezugspunkt auf der Erdoberfläche. Quelle: Wikipedia
Die Abbildung zeigt Bewegung der GPS-Satelliten um die Erde. Schwarze Punkte haben Kontakt zum blauen Bezugspunkt auf der Erdoberfläche. (Bild: wikipedia.org)
GPS-Module

Bei der Suche nach dem Stichwort „GPS module“ im Internet ergeben sich zahlreiche Treffer. Für Elektronikprojekte mit Arduino oder Raspberry Pi bieten die Neo 6M (oder 7M) - Bausteine des Schweizer Herstellers u-blox ein gutes Preis-/Leistungsverhältnis. Fertige Boards mit integriertem Neo6M-GPS-Baustein und brauchbarter passiver Keramik-Antenne schlagen mit Preisen ab 10-15€ zu Buche, wobei sich in den unteren Preisregionen überwiegend Nachbauten aus chinesischer Produktion tummeln. Zwar führen die billigen Klone nur serielle RX/TX-Pins nach außen, während die teureren Modelle zum Beispiel auch über einen I2C-Anschluss verfügen. Das tut dem Spaß aber keinen Abbruch.

Der Standard NMEA 183

Kommerzielle GPS-Module unterstützen den Standard NMEA 183 der National Marine Electronics Association, und senden typischerweise mit 8 Bit Datenbreite (inklusive einem Stop-Bit) ASCII-basierte Nachrichten über eine 4800 Baud-Verbindung.

Die Nachrichten sind wie folgt strukturiert, wobei jede Zeile eine separate Nachricht enthält:

$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76 $GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A $GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70 $GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79 $GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76 $GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43 $GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75 $GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A $GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70 $GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77 $GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76 $GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45

So beinhaltet das $GPGGA in der ersten Nachrichtenzeile Fix-Information, ob genügend Satelliten zum Positionieren zur Verfügung stehen.

$GPRMC stehen für eine Positionsbestimmung mit dem empfohlenen Minimum an Information (required minimum).

$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

wobei hier

  • RMCbedeutet Recommended Minimum Sentence C - die minimale Menge an Information, die ein GPS-Modul liefern muss
  • 123519 Verbindung zu ausreichender Zahl an Satelliten erfolgte um 12:35:19 UTC
  • A Status (A= Active, V= Void)
  • 4807.038,N geographische Breite 48° 07.038' North
  • 01131.000,E die geographische Länge 11° 31.000' East
  • 022.4 Geschwindigkeit über Boden (in Knoten)
  • 084.4 Positionierungswinkel in Grad
  • 230394 das Datum - 23. März 1994
  • 003.1,W Magnetische Streuung
  • *6A die Checksumme (beginnt immer mit *)
darstellt.
Drum prüfe, wer sich ewig bindet

Zum ersten Aufwärmen lassen sich die GPS-Module von u-blox mit einer Windows-Software namens u-center[1] auslesen. Das ist insofern interessant, als sich dadurch die Funktion des GPS-Moduls veranschaulichen und prüfen lässt:

Wo bin ich?
Das kostenlose Programm u-center im Betrieb (Microsoft Windows only). Auf dem Fenster sind die empfangbaren Satelliten grün markiert

Um das Modul an einen USB-Port des PCs anzuschließen, bietet sich ein FTDI-USB-to-TTL-Adapter an:

Wo bin ich?
Zum direkten Anschluss des GPS-Empfängers an einen Computer, nutzt die Schaltung einen FTDI-Adapter (USB to TTL)

In der Schaltung existieren folgende Verbindungen:

FTDI TX mit NEO RX

FTDI RX mit NEO TX

FTDI Vcc mit NEO Vcc

FTDI GND mit NEO GND

Das USB-to-TTL-Adapterboard (FTDI) muss dabei auf 3,3V Betrieb gejumpert sein. Natürlich können Sie alternativ auch preisgünstige USB-TTL-Adapter mit Chipsets der Typen CP2102 oder CH340 nutzen, sofern Sie den entsprechenden Treiber installieren.

Nach Anschluss der Schaltung über USB (FTDI-Adapter) an den Windows-PC, und der Einstellung des verwendeten GPS-Produkts sowie des richtigen USB-Ports in u-center dauert es eine Weile bis der GPS-Empfänger Verbindungen zu genügend vielen Satelliten aufbauen konnte. Mindestens vier müssen es sein, wie bereits an anderer Stelle beschrieben. Danach ist die Position fixiert (fixed), eine grüne LED am NEO blinkt, und im Anwendungsfenster erscheinen die erfassten Satelliten und die festgestellte Position, nebst umfangreicher weiterer Information. Aus Platzgründen kann ich an dieser Stelle nicht auf die komplette Funktionalität der Software eingehen.

Schaltung mit Arduino

Für die Beispielsschaltung kommt ein Arduino Nano mit 5V-Logik zum Einsatz, der über die digitalen Pins D3 und D4 als Software-basierten seriellen Port mit dem GPS-Modul verbunden ist. Allerdings darf die Verbindung der beiden Komponenten nicht direkt erfolgen, da ein NEO 6M oder 7M Modul mit 3,3V-Logik arbeitet. Deshalb ist ein Logic-Level-Konverter nötig, der zwischen den beiden Logik-Welten adaptiert. Einige Maker im Internet halten den direkten Anschluss von GPS-Modul an den Arduino zwar für unproblematisch. Das mag kurzfristig gelten, aber bei langem Dauerbetrieb ist ein Abrauchen des GPS-Moduls definitiv nicht auszuschließen.

Folgende Zutaten (Bill of Material) sind notwendig, um die Schaltung aufzubauen:

  • Breadboard
  • Arduino Nano MCU
  • Logic Level Converter (zwischen 3,3V- und 5V-Logik) mit mindestens zwei Kanälen
  • GPS Modul wie z.B. NEO 6M oder 7M GPS
  • 10 Jumper Wires (male to male)
  • 2 Jumper Wires (male to female)
Wo bin ich?
In der Schaltung sind das GPS-Modul (links oben), der Logic Level Konverter (roter Baustein), der Arduino Nano (Mitte) und das FTDI-Board (rechts) zu sehen

Die Schaltung implementiert folgende Verbindungen:

  • Der FTDI-Adapter dient nur zur Versorgung des GPS-Empfängers mit Strom. Dementsprechend laufen von den Ausgängen VCC und GND des Adapters jeweils ein Kabel zu den entsprechenden Stromschienen am Breadboard.
  • Der RX-Eingang des GPS-Moduls wird über den Logic Level Konverter mit dem TX-Ausgang des Arduino Nano verbunden. Im Beispiel fungiert der digitale Pin D4 als TX-Ausgang des Arduino-Boards.
  • Der TX-Ausgang des GPS-Moduls wird über den Logic Level Converter mit dem RX-Eingang des Arduino Nano verbunden. Im Beispiel fungiert der digitale Pin D3 als RX-Eingang des Arduino Boards.

Noch ein Wort zum verwendeten Arduino-Board. Wer ein Board mit seriellen Hardwareports einsetzt wie zum Beispiel einen Arduino Mega, sollte einen seriellen Hardware-Port (Serial1, Serial2, Serial3, ...) für die Verbindung verwenden. Das ist die schnellste und beste Lösung.

Bei Boards wie Arduino Uno, Leonardo, Nano muss stattdessen eine Software-basierte Lösung zum Einsatz kommen, etwa die Standard-Lösung SoftwareSerial. Leider führt SoftwareSerial betriebsbedingt zu hohen Latenzzeiten und kann deshalb nur geringere Baudraten unterstützen. Das können Alternativen wie AltSoftSerial deutlich besser. Für die Geschwindigkeiten der GPS-Module von 4800 Baud oder 9600 Baud erweist sich aber SoftwareSerial als mehr mehr als ausreichend.

Das GPS-Modul zeigt eine grüne, blinkende LED sobald ihm genügend viele Satelliten für die Positionsbestimmung zur Verfügung stehen:

Wo bin ich?
Die Schaltung im Betrieb. Die grün blinkende LED zeigt an, dass der NEO-6m mit mindestens vier Satelliten in Kontakt steht
Programmierung

Es macht keinen Spaß, systemnah mit einem GPS-Modul beziehungsweise mit den Rohdaten im NMEA 183 Standardformat zu arbeiten. Daher existieren diverse Bibliotheken für Arduino, um diese Aufgabe zu erleichtern, darunter die Bibliotheken NEOGPS, GPS-NEO-6m-master und TinyGPSPlus. Eine Suche mit dem Begriff GPS im Menü der Arduino IDE unter Sketch > Include Library > Manage Libraries liefert die entsprechenden Bibliotheken.

Für den Artikel nutze ich TinyGPSPlus. Nach Installation von TinyGPSPlus lässt sich das Beispiel FullExample.ino über den Menüpfad File > Examples > TinyGPSPlus > FullExample öffnen.

Der Anfang des Sketches muss ein Programm den entsprechenden Header inkludieren:

#include 
#include ++.h>

Der Einfachheit halber benutzt der Sketch in unserem Fall SoftwareSerial. Ohnehin steht beim Arduino Nano kein eigener serieller Hardwareport für diesen Zweck zur Verfügung.

Die Pins des Nano-Boards für den Software-Port lauten im obigen Beispiel D3 (als RX) und D4 (als TX):

static const int RXPin = 3, TXPin = 4;
static const uint32_t GPSBaud = 9600;

// Das Objekt zum Zugriff auf die Bibliothek:

TinyGPSPlus gps;

// Software-basierter Serieller Port
SoftwareSerial ss(RXPin, TXPin);

Die Baudrate beträgt in dem von mir verwendeten NEO-6m-Modul 9600 Baud. Üblicherweise kommen auch 4800 Baud recht häufig vor. Dem Datenblatt Ihres GPS-Moduls sollten Sie daher den für Ihr Modul jeweils richtigen Wert entnehmen.

Im setup() des Sketches erfolgt die Verbindung mit dem integrierten seriellen Monitor (der für die Verbindung von PC/Mac mit dem Arduino-Board) über Serial.begin(), und die mit der emulierten seriellen Verbindung vom Arduino-Board zum GPS-Modul über ss.begin();

void setup()
{
Serial.begin(115200); // Serieller Monitor für print-Ausgaben
ss.begin(GPSBaud); // Serieller Software-Port zum GPS-Modul
// ...
}

Im eigentlichen Hauptprogramm loop() ist der Zugriff auf die vom GPS-Modul gelieferte Information möglich:

void loop()
{
while (ss.available() > 0) // Daten liegen an der Leitung an
if (gps.encode(ss.read())) // Lese Daten und enkodiere sie
{
... // Nutzung der gelesenen Daten
}

if (millis() > 10000 && gps.charsProcessed() < 10) // Timeout nach 10 secs
{
Serial.println(F("Kein GPS-Modul gefunden"));
while(true); // Fini, das Ende der Welt
}
}

Information lässt sich über die Variable gps auslesen:

gps.satellites.value() // falls gps.satellites.isValid()
gps.hdop.value() // falls gps.hdop.isValid()
gps.location.lat() // falls gps.location.isValid()
gps.location.lng() // falls gps.location.isValid()
gps.location.age() // falls gps.location.isValid()
gps.date // falls gps.date.isValid()
gps.time // falls gps.time.IsValid()
gps.altitude.meters() // falls gps.altitude.isValid()
gps.course.deg() // falls gps.course.isValid()
gps.speed.kmph() // falls gps.speed.isValid()

Das funktioniert immer nach dem selben Schema: Zuerst ist zu überprüfen, ob überhaupt ein gültiger Datenwert vorliegt wie zum Beispiel bei gps.location.isValid(). Ist dies der Fall, enthalten Variablen wie gps.location.lat() (= geographische Breite) gültige Werte.

Arduino IDE: Sketch, der TinyGPSplus nutzt
Das Bild zeigt die Arduino IDE und den seriellen Monitor. Auf den Arduino läuft ein Beispielsprogramm, das die TinyGPSPlus-Bibliothek mitliefert
Learning by Doing

Die unten abgedruckte Quelldatei beinhaltet ein sehr einfaches Beispiel, bei dem das Arduino-Board den seriellen Monitor zur Ausgabe nutzt und einen Software-emulierten Port zur Kommunikation mit dem GPS-Modul. In der Regel dauert es nach Inbetriebnahme des GPS-Moduls etwas bis es genügend Satelliten zur Positionsbestimmung lokalisieren konnte. Der Einfachheit halber geht die Demo-Anwendung davon aus, dass das Modul betriebsbereit ist und gültige Daten liefert (grüne LED blinkt).

In der Hauptschleife loop bestimmt das Programm in jeder Sekunde die Position, und gibt die entsprechende Information zeilenweise am seriellen Monitor aus.

Die Daten werden im CSV-Format (Comma Separated Values) ausgegeben. Dieses Format hat Vorteile, wenn Benutzerinnen später die Daten weiterverarbeiten wollen. Dazu unten mehr.

/*******************************************************
*
* Demo-Anwendung zur Nutzung eines GPS-Moduls des
* Typs u-blox NEO 6m oder 7m
* (c) Michael Stal, 2018
* frei verwendbar gemaess Creative Commons
*
*******************************************************/

#include ++.h>

#include

// Verwendete digitale Pins für SoftwareSerial
static const int RX = 3, TX = 4;
// !!! Baudrate des GPS-Moduls: Anpassung an eigene HW notwendig
static const uint32_t GPSBaud = 9600;

// Zugriff auf TinyGPS++ ueber gps
TinyGPSPlus gps;

// Emulierter Port zum GPS Geraet
SoftwareSerial gpsPort(RX, TX);

/*******************************************************
*
* setup baut alle Verbindungen auf
* zum seriellen Monitor und zum GPS-Modul
*
*******************************************************/

void setup()
{
// Verbindung zum seriellen Monitor
Serial.begin(115200);
// Verbindung mit GPS-Modul
gpsPort.begin(GPSBaud);

// Header Zeile ausgeben (Format ist .csv)
Serial.println();
Serial.println("utc_t, lat, lon, elevation");
Serial.println("#name, latitude, longitude, elevation");
}

/*******************************************************
*
* Im Hauptprogramm wird jede Sekunde die aktuelle
* Position vom GPS-Geraet gelesen inklusive
* Datum und Zeit, geo. Breite, geo. Laenge, Hoehe
*
*
*******************************************************/

void loop()
{
while (gpsPort.available() > 0) // Daten vorhanden?
if (gps.encode(gpsPort.read())) {
showPositionData(); // ja, dann Ausgabe am ser. Monitor
delay(1000); // 1 Sekunde warten
}

if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println("Fehler: GPS Modul nicht gefunden");
while(true);
}
}

/*******************************************************
*
* showPositionData liest die aktuelle Position
* und gibt die Daten als Zeile (im .csv-Format) aus
*
*******************************************************/

void showPositionData()
{
// Erst Datum ...
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print("/");
Serial.print(gps.date.day());
Serial.print("/");
Serial.print(gps.date.year());
}

Serial.print(" ");

// ... und Zeit
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print("0");
Serial.print(gps.time.hour());
Serial.print(":");
if (gps.time.minute() < 10) Serial.print("0");
Serial.print(gps.time.minute());
Serial.print(":");
if (gps.time.second() < 10) Serial.print("0");
Serial.print(gps.time.second());
}

// Jetzt 2D-Position als geo. Breite, Laenge
if (gps.location.isValid())
{
Serial.print(" , ");
Serial.print(gps.location.lat(), 6);
Serial.print(" , ");
Serial.print(gps.location.lng(), 6);
}

// Und dann noch Hoehe
if (gps.altitude.isValid())
{
Serial.print(" , ");
Serial.print(gps.altitude.meters(), 6);
}

Serial.println();
}

Die Ausgabe des Sketches am seriellen Monitor schaut bei einem sehr einfachen Beispiel wie folgt aus:

utc_t, lat, lon, elevation
#name, latitude, longitude, elevation
2/25/2018 14:33:06 , 48.126541 , 11.571980 , 523.500000
2/25/2018 14:33:07 , 48.126533 , 11.571964 , 523.500000
...
WYSIWYG

Statt auf dem Monitor könnte die obige Anwendung alle Positionsdaten auch als CSV-Datei (zum Beispiel auf einer SD-Card) speichern. In einem früheren Posting [2]hatte ich das dazu notwendige Vorgehen bereits beschrieben.

Dadurch können Maker die erzeugte Datei weiter verarbeiten, um die Tracking-Daten zum Beispiel in Google Earth oder Maps zu visualisieren.

Ein Programm von Format wie Google Earth erwartet allerdings .KML-Dateien (Keyhole Markup Language) oder .KMZ-Dateien. Woher also nehmen und nicht stehlen? Zum Glück gibt es genau zu diesem Zweck einen Online-Dienst namens GPS Visualizer[3].

Die obige Daten-Ausgabe des GPS-Empfängers habe ich in einer Datei arduinotrack.csv gespeichert und den Dienst GPS Visualizer dafür genutzt, um eine Google Map zu erzeugen.

Wo bin ich?
Der freie Online-Dienst GPS Visualizer erlaubt es, GPS-Daten von/nach verschiedenen Formaten zu konvertieren

Die erzeugte Map ist aber zugegebenermaßen eher unspektakulär, weil sich der Testaufbau immer an derselben Stelle meines Büros befunden hat:

Jetzt wissen die Leser wo ich wohne.
GPS Visualizer kann die Daten des GPS-Tracking z.B. über Google Earth oder Google Maps visualizieren
Fazit

In dieser Folge ging es um Ortung der aktuellen Position über GPS. Ein Microcontroller (MCU), in unserem Fall ein Arduino Nano, kommuniziert via serieller Leitung mit der verwendeten GPS-Hardware. Die Einsatzmöglichkeiten sind vielfältig, etwa die Steuerung einer Drohne, das Tracking eines Kraftfahrzeugs oder die Positionsbestimmung eines Containers, um nur einige Beispiele zu nennen.

Wer GPS in seinem Arduino-Projekt integrieren möchte, ist mit den preisgünstigen Komponenten wie dem NEO 6M oder 7M aus der Produktfamilie von u-blox bestens bedient.

Der weiter oben beschriebene Versuchsaufbau gibt lediglich die GPS-Daten aus. Es gibt wie immer unzählige Erweiterungsmöglichkeiten:

  • Mittels eines SD-Card-Shields könnte das Programm auch eine GPS-Datei erzeugen, beispielsweise im KML- oder GPX-Format, die sich über Webdienste wie Google Maps visualisieren lässt.
  • Für mobile Geräte sollte die Stromversorgung über Akkus oder Batterien erfolgen.
  • Statt eines Arduino-Boards bietet sich natürlich auch an, ein kompatibles Board zu nutzen wie ESP32, Teensy, oder STM32F103C8T6 . Diese Boards laufen unter 3,3V, sodass der im Beitrag benutzte Logic Level Konverter entfallen kann.

Jetzt bleibt mir nur noch, Ihnen viel Spaß beim Experimentieren zu wünschen.


URL dieses Artikels:
http://www.heise.de/-3976281

Links in diesem Artikel:
[1] https://www.u-blox.com/en/product/u-center-windows
[2] https://www.heise.de/developer/artikel/Spuren-hinterlassen-Datenlogging-mit-Arduino-3348205.html
[3] http://www.gpsvisualizer.com

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 26. Februar 2018 um 10:00

FreshRSS 1.10.0

Von Alkarex

Changelog:

  • API
  • Features
    • Ability to pause feeds, and to hide them from categories #1750
    • Ability for the admin to reset a user’s password #960
  • Security
    • Allow HTTP Auth login with REDIRECT_REMOTE_USER when using Apache internal redirect #1772
  • UI
    • New icons for marking as favourite and marking as read in the Reading View #603
    • Add shortcuts to switch views #1755
  • Bug fixing
    • Fix login bug when HTTP REMOTE_USER changes (used by YunoHost) #1756
    • Fix warning in PHP 7.2 #1739
  • Extensions
    • Allow extensions to define their own reading view #1714
  • I18n
  • Misc.
    • More sites in force-https.default.txt #1745
    • Trim URLs when adding new feeds #1778
  • 24. Februar 2018 um 12:03

MicroProfile unter der Lupe, Teil 3: JWT Security

Von heise online

zurück zum Artikel

Das Thema Security stellt in einer stark verteilten, Microservices-basierten Umgebung eine besondere Herausforderung dar. Im Umfeld von RESTful-Services hat sich in den letzten Jahren der auf OpenID Connect (OIDC) basierende Standard JSON Web Tokens (JWT) für rollenbasierte Zugriffskontrolle etabliert. Auf diesen Stack setzt auch die Spezifikation MicroProfile JWT RBAC Security (MP-JWT).

Ein Microservice kommt selten allein. Das ist kein Geheimnis, sondern Teil des Erfolgsrezepts. Ziel einer Microservice-basierten Architektur ist es, durch ein passendes Servicedesign, eine möglichst große Unabhängigkeit der einzelnen Services untereinander zu erreichen. Wie sieht es aber mit dem Thema Sicherheit aus? Gilt auch hier das Prinzip der größtmöglichen Unabhängigkeit? Und wenn ja, muss sich ein Client dann bei jedem Service oder gar bei jedem Service-Aufruf separat mit seinen User Credentials (z.B. Username und Passwort) authentifizieren und autorisieren?

JWT Quick Guide

Im Umfeld verteilter Services hat sich in den letzten Jahren der auf OpenID Connect basierende JSON-Web-Tokens-Standard [1] (siehe auch JWT.io Introduction [2]) als der Standard etabliert.

Vereinfacht gesprochen authentifiziert sich bei diesem Verfahren ein Client einmalig bei einem Authentication-Server (Issuer) und erhält im Gegenzug ein zeitlich begrenztes, personalisiertes und in der Regel signiertes Token (JWT mit JWS [3]). Personalisiert bedeutet in diesem Zusammenhang, dass das Security-Token sogenannte Claims enthält, also Key-Value-Paare, welche unter anderem . Informationen zu dem authentifizierten Nutzer (Subject) beinhalten.

Mit Hilfe des Tokens kann sich der Client nun gegenüber externer Services (Resource Server) mittels Bearer Authentication authentifizieren. Dazu schickt er einfach in jedem Request das Token im Authorization-Header mit:

GET /resource/123 HTTP/1.1
Host: openknowledge.com
Authorization: Bearer mF_9.B5f-4.1JqM

Dank Signatur können die aufgerufenen Services das Token auf Echtheit und Unverfälschtheit verifizieren. Da das Token Informationen über den Client enthält, sind die aufgerufenen Service zusätzlich in der Lage, eine rollenbasierte Zugriffskontrolle (RBAC; role based access control) – Autorisierung - durchzuführen.

Der Vorteil dieses Verfahrens liegt klar auf der Hand. Dank Token und den darin enthaltenen Informationen kann ein Service sowohl Authentifizierung als auch Autorisierung durchführen, ohne zusätzlich Informationen von einer dritten Partei wie einem User-Management oder Identity-Service erfragen zu müssen. Dies erspart unnötige Roundtrips. Dies gilt übrigens auch dann, wenn der aufgerufene Service einen weiteren Service aufruft (Service Chaining). In diesem Fall reicht der ursprünglich aufgerufene Service das Token inklusive der enthaltenen Nutzerinformation einfach im Request-Header weiter (Security Context Propagation).

MicroProfile und JWT

Seit Version 1.2 unterstütz auch das MicroProfile mit der Spezifikation MP-JWT 1.0 JWT-basierte Security. Die Spezifikation setzt dabei gleich an mehreren Punkten an und versucht folgende Aufgaben zu unterstützen:

  1. Token aus dem Request extrahieren,
  2. Token verifizieren und validieren,
  3. Claims des Token zugreifbar machen und
  4. JavaEE-Security-Context erzeugen und setzen.

Zu diesem Zweck definiert die MP-JWT Spezifikationen einen Satz von „non-optional“ Claims, also Pflichtfeldern, die ein spezifikationskonformes Token beinhalten muss:

  • typ: Header-Parameter für das Token-Format („JWT“)
  • alg: Header-Parameter für den Verschlüsselungsalgorithmus („RS256“)
  • kid: Header-Parameter mit Hinweis für die eindeutige Key ID
  • iss: Token-Issuer
  • sub: Subject des Tokens (Principle/User)
  • aud: angedachte Empfängergruppe
  • exp: Gültigkeit
  • iat: Ausstellungszeitpunkt
  • jti: eindeutiter Identifier
  • upn: eindeutiger Principle Name (für java.security.Principle)
  • groups: Liste von Gruppennamen für das Mapping mit Application-Roles

Ein minimales Beispiel eines MP-JWT in JSON-Format könnte wie folgt aussehen:

{ 
"typ": "JWT",
"alg": "RS256",
"kid": "abc-1234567890"
}
{
"iss": "https://auth.openknowledge.com",
"aud": "kNowLedGe",
"jti": "ok-12345",
"exp": 1311281970,
"iat": 1311280970,
"sub": "13579",
"upn": "lars.roewekamp@auth.openknowledge.com",
"groups": ["first-group", "second-group", "admin"],
}

Damit eine automatische Extraktion des Tokens aus dem Authorization-Header des Request erfolgen kann, muss der JAX-RS-Anwendung zunächst signalisiert werden, dass zur Authentifizierung und Autorisierung der MP-JWT JASPI (Java Authentication SPI for Containers) verwendet werden soll. Das erfolgt mit der Annotation LoginConfig aus dem Package org.eclipse.microprofile.jwt.


import org.eclipse.microprofile.auth.LoginConfig;

// Sets the authentication method to the MP-JWT for the MicroProfile JWT.
// The optional parameter realName is only needed, if authMethod
// is set to "BASIC" or for vendor specific configurations.
@LoginConfig(authMethod = "MP-JWT", realName="...")
@ApplicationScoped
@ApplicationPath("/myapi")
public class MyJaxrsApp extends Application { }

Anmerkung: Die Annotation LoginConfig wurde eingeführt, da das MicroProfile keinerlei Aussagen zu möglichen Deployment-Formaten trifft und somit auch nicht von dem Vorhandensein eines Servlet Containers bzw. einer web.xml ausgegangen werden kann. Ist eine web.xml vorhanden, kann alternativ zur Verwendung der Annotation auch der gleichnamige Eintrag login-config innerhalb der web.xml-Datei genutzt werden.

Die anschließende Verifizierung des Tokens erfolgt automatisch im Hintergrund. Zu diesem Zweck muss lediglich der Public Key des Token-Issuers in der Konfiguration des MicroProfile-Runtime-Container hinterlegt sein. Damit ein Token als gültiges MP-JWT angesehen wird, muss es zusätzlich mindestens die folgenden Bedingungen erfüllen:

  • JOSE (JavaScript Object Signing and Encryption) Header, der angibt, dass das Token via RS256 signiert wurde
  • iss-Claim, der denselben Token-Issuer beinhaltet, wie im MicroProfile-Runtime-Container konfiguriert

CDI Integration

Einmal extrahiert und verifiziert kann innerhalb des Microservice via CDI auf das Token beziehungsweise auf einzelne Claims des Tokens zugegriffen werden. Der Zugriff kann dabei via Raw-Typen, ClaimValue-Wrapper, javax.enterprise.inject.Instance oder JSON-P-Typen erfolgen:

@Path(/endpoint) 
@DenyAll
@RequestScoped
public class SomeEndpoint {

// 1) JWT object with @RequestScoped scoping
@Inject
private JsonWebToken callerPrincipal;

// 2) JWT as raw String
@Inject
@Claim(standard = Claim.raw_token)

private String rawToken;

// 3) IAT claim as Long value
@Inject
@Claim(standard=Claims.iat)

private Long issuedAt;

// 4) ISS claim as ClaimValue of type String
@Inject
@Claim(standard=Claims.iss)

private ClaimValue<String> issuer;

// 5) JTI claim as optional ClaimValue of type String
@Inject
@Claim(standard=Claims.jti)

private ClaimValue<Optional<String>> optJti;

// 6) JTI claim as JsonString
@Inject
@Claim(standard=Claims.jti)

private JsonString jsonJti;

// 7) custom claim "roles" as JsonArray
@Inject
@Claim("roles")

private JsonArray jsonRoles;

// 8) custom claim "customObject" as JsonArray
@Inject
@Claim("customObject")

private JsonObject jsonCustomObject;
...
}

Anmerkung: Die im obigen Listing gezeigte Klasse SomeEndpoint muss zwingendermaßen vom Scope @ReqiestScoped sein, das in ihr non-proxyable Typen (String und Long) aus dem Token injected werden.

Der aktuell angemeldete Caller bzw. das zugehörige Token kann mittels @lnject JsonWebToken mit dem Scope @RequestScoped injected werden (1). Das von Principal abgeleitete Interface JsonWebToken bietet eine Reihe von Convenient-Methoden, um gezielt und typenssicher auf die wichtigsten Claims des Tokens (Name, Issuer, Audience, Subject, TokenID, ExperiationTime, IssuedAtTime, Groups) zugreifen zu können.

Alternativ können die Claims aber auch direkt injected werden. Geschieht dies als non-proxyable Raw Typ, wie zum Beispiel String (2) oder Long (3), muss die umliegende Bean vom Scope @RequestScoped sein. Statt den Claim als Raw-Typen zu injecten, können alternativ auch ClaimValue- und/oder Optional-Wrapper verwendet werden (4 und 5). Und auch ein Zugriff via in JSON-P definierter Typen ist möglich (6, 7 und 8).

Um Tippfehler zu verhindern, sollte bei dem Zugriff auf Standard-Claims immer die Claims-Enumeration verwendet werden. Für den Zugriff auf Custom-Claims dagegen, können Strings oder eigene Enumerations genutzt werden.

JAX-RS Container Integration

Nachdem wir nun in der Lage sind, das JSON Web Token automatisch aus dem Request zu extrahieren und im Anschluss zu verifizieren, wäre es natürlich schön, wenn wir innerhalb der JAX-RS Ressourcen auf gewohnte JavaEE-Security-Mechanismen zurückgreifen könnten. Und auch das sieht die MP-JWT Spezifikation vor.

Ein Aufruf der Methode getUserPrinciple() der Klasse javax.ws.rs.core.SecurityContext liefert uns eine Instanz des aktuellen JsonWebToken zurück. Entsprechend können wir mit einem Aufruf der Methode isUserInRole(someRole) testen, ob die angegebene Rolle in dem Claim groups des Tokens enthalten ist oder nicht. Zusätzlich lässt sich mit Hilfe der Annotation @RollesAllowed(…) der Zugriff auf einzelne Methoden entsprechend der angegebenen Rolle(n) sperren bzw. freigeben.

Fazit und Ausblick

Wer schon einmal das „Glück“ hatte, die notwendigen Schritte zum Extrahieren, Validierung und Verifizieren eines JSON Web Tokens - inkl. der Überführung in einen JavaEE Security Context - implementieren zu dürfen, der weiß die Vorteile einer integrierten und standardisierten Lösung zu schätzen. Dies gilt insbesondere auch für die innerhalb des Tokens zu erwartenden Claims.

Das ganze Konzept steht und fällt allerdings damit, dass es am Ende hinreichend Identity Provider und Service Provider geben wird, die sich auf das MP-JWT Format einlassen. Um die Wahrscheinlichkeit zu erhöhen, hat man bei der Auswahl der „non-optional“ Claims bewusst darauf verzichtet, das Rad neu zu erfinden und stattdessen ein Subset von fünf der im IANA JWT Assignement [4] standardisierten Claims gewählt. Lediglich die zwei der "non-optional" Claims - upn (user principle name) und groups (Token Subject‘s Gruppen, welche auf JavaEE Security-Rollen gemappt werden) - sind proprietär.

Für zukünftige Versionen sind noch einige weitere Claims angedacht. So sollen mit Hilfe des Claims resouce_access servicespezifische Rollen angegeben werden können. Weiterhin wird darüber nachgedacht, neben dem bereits vorhanden Claim groups auch einen Claim roles einzuführen. Während groups dafür gedacht ist, dass die enthaltenen Werte auf das Rollenmodell der Ziel-Ressource gemappt werden, sollen die in roles enthaltenen Werte eins zu eins weitergereicht und in @RolesAllowed verwendet werden können.

Was ein wenig verwundert ist die Tatsache, dass die Art und Weise der Konfiguration, also zum Beispiel der Zurgiff auf den Public Key, den jeweiligen Runtime-Container-Herstellern überlassen wird, anstatt auf die MP Config API [5] zurückzugreifen. Entsprechende Überlegungen zur Vereinheitlichung gibt es aber bereits. Man darf gespannt sein.


URL dieses Artikels:
http://www.heise.de/-3973746

Links in diesem Artikel:
[1] https://tools.ietf.org/html/rfc7519
[2] https://jwt.io/introduction
[3] https://tools.ietf.org/html/rfc7515
[4] https://www.iana.org/assignments/jwt/jwt.xhtml
[5] https://www.heise.de/developer/artikel/MicroProfile-unter-der-Lupe-Teil-1-Config-API-3928886.html

Copyright © 2018 Heise Medien

Let's block ads! (Why?)

  • 20. Februar 2018 um 14:38
❌