<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.hackerspace-bielefeld.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fki</id>
	<title>Hackerspace Bielefeld Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.hackerspace-bielefeld.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fki"/>
	<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Spezial:Beitr%C3%A4ge/Fki"/>
	<updated>2026-06-14T01:49:19Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=719</id>
		<title>Laufschrift Eingangstür</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=719"/>
		<updated>2018-05-23T16:24:52Z</updated>

		<summary type="html">&lt;p&gt;Fki: /* Hardware */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansprechpartner ==&lt;br /&gt;
[[Benutzer:Fki|Fki]]&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
Da die Leuchtdioden des Laufschrift-Panels über der Space-Eingangstür nur noch schwach und unterschiedlich hell glimmen, wird es Zeit für eine Überarbeitung. Bisher wurde lediglich ein statischer Schriftzug angezeigt, da der bisher zur Ansteuerung verwendete Arduino keine Verbindung zum Netzwerk im Hackerspace hatte. Dazu war er so verbaut, daß er nur schwer zugänglich war. Durch den Einsatz eines ESP8266-Moduls soll die neue Steuerung vom Netzwerk aus mit Anzeigedaten gefüttert werden können, ohne daß störende Kabel oder Teildemontagen der Wandverkleidung nötig sind. ;-)&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
* 3 Stk. LED-Matrix-Panel der Fa. Christ Elektronik, 32 x 12 LEDs, rot (Spende, sind älter, vermutlich aus Mitte der &#039;90er Jahre).&lt;br /&gt;
* STM32F072 Discovery-Board zur Ansteuerung&lt;br /&gt;
* Eigenbau-Treiberplatine (Aufbau auf Punkt-Streifenraster)&lt;br /&gt;
* ESP8266-Modul (ESP-01) als WLAN-Bridge zur Verbindung mit und Ansteuerung aus dem Space-Netzwerk.&lt;br /&gt;
&lt;br /&gt;
== Schaltung ==&lt;br /&gt;
=== Die LED-Matritzen ===&lt;br /&gt;
Herzstück des Projekts sind drei LED-Matritzen der Fa. Christ. Jede dieser Matritzen verfügt über 384 LEDs, welche in vier Gruppen organisiert sind. Die Gruppen teilen sich drei Schieberegister mit je 32 Ausgängen, welche die einzelnen LEDs innerhalb der gerade aktiven Gruppe schalten. Jede Gruppe besteht damit aus 96 LEDs. Die LED-Matritzen können einfach hintereinander gesteckt werden, so daß die gesamte Laufschrift aus 1152 LEDs besteht.&lt;br /&gt;
&lt;br /&gt;
Die verwendeten Schieberegister sind vom Typ UCN5833. Eigentlich sind es Schieberegister mit Leistungstreibern und Datenlatch in einem Gehäuse. Man kann also Daten in die Register eintakten, ohne daß das Auswirkungen auf die Anzeige hat. Erst durch Aktivieren des Latches ändern sich die Ausgänge. Zur Ansteuerung der Schieberegister werden die Signale SCLK (Serial Clock), SDI (Serial Data In) und STB (Strobe) benötigt. &lt;br /&gt;
&lt;br /&gt;
Dabei teilen sich alle Register die Clock- und Strobe-Leitung, die Datenleitungen jedes Registers sind separat herausgeführt. Werden an eine LED-Matrix weitere Matritzen angeschlossen, werden SCLK und STB einfach durchverbunden, die SDI-Leitungen der Folgeplatine werden mit den SDO-Pins (Serial Data Out) der vorhergehenden Platine verbunden (Daisy Chain). Bei drei hintereinander gesteckten Platinen versorgt der Mikrocontroller also pro Datenleitung 96 LEDs über drei verschaltete Schieberegister.&lt;br /&gt;
&lt;br /&gt;
== Anleitung ==&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Zugriff ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekt]]&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=718</id>
		<title>Laufschrift Eingangstür</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=718"/>
		<updated>2018-05-23T16:23:18Z</updated>

		<summary type="html">&lt;p&gt;Fki: /* Schaltung */ Untergliederung nach Baugruppe eingeführt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansprechpartner ==&lt;br /&gt;
[[Benutzer:Fki|Fki]]&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
Da die Leuchtdioden des Laufschrift-Panels über der Space-Eingangstür nur noch schwach und unterschiedlich hell glimmen, wird es Zeit für eine Überarbeitung. Bisher wurde lediglich ein statischer Schriftzug angezeigt, da der bisher zur Ansteuerung verwendete Arduino keine Verbindung zum Netzwerk im Hackerspace hatte. Dazu war er so verbaut, daß er nur schwer zugänglich war. Durch den Einsatz eines ESP8266-Moduls soll die neue Steuerung vom Netzwerk aus mit Anzeigedaten gefüttert werden können, ohne daß störende Kabel oder Teildemontagen der Wandverkleidung nötig sind. ;-)&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
* 3 Stk. LED-Matrix-Panel der Fa. Christ Elektronik, 32 x 12 LEDs, rot (Spende, sind älter, vermutlich aus mitte &#039;90er).&lt;br /&gt;
* STM32F072 Discovery-Board zur Ansteuerung&lt;br /&gt;
* Eigenbau-Treiberplatine (Aufbau auf Punkt-Streifenraster)&lt;br /&gt;
* ESP8266-Modul (ESP-01) als WLAN-Bridge zur Verbindung mit und Ansteuerung aus dem Space-Netzwerk.&lt;br /&gt;
&lt;br /&gt;
== Schaltung ==&lt;br /&gt;
=== Die LED-Matritzen ===&lt;br /&gt;
Herzstück des Projekts sind drei LED-Matritzen der Fa. Christ. Jede dieser Matritzen verfügt über 384 LEDs, welche in vier Gruppen organisiert sind. Die Gruppen teilen sich drei Schieberegister mit je 32 Ausgängen, welche die einzelnen LEDs innerhalb der gerade aktiven Gruppe schalten. Jede Gruppe besteht damit aus 96 LEDs. Die LED-Matritzen können einfach hintereinander gesteckt werden, so daß die gesamte Laufschrift aus 1152 LEDs besteht.&lt;br /&gt;
&lt;br /&gt;
Die verwendeten Schieberegister sind vom Typ UCN5833. Eigentlich sind es Schieberegister mit Leistungstreibern und Datenlatch in einem Gehäuse. Man kann also Daten in die Register eintakten, ohne daß das Auswirkungen auf die Anzeige hat. Erst durch Aktivieren des Latches ändern sich die Ausgänge. Zur Ansteuerung der Schieberegister werden die Signale SCLK (Serial Clock), SDI (Serial Data In) und STB (Strobe) benötigt. &lt;br /&gt;
&lt;br /&gt;
Dabei teilen sich alle Register die Clock- und Strobe-Leitung, die Datenleitungen jedes Registers sind separat herausgeführt. Werden an eine LED-Matrix weitere Matritzen angeschlossen, werden SCLK und STB einfach durchverbunden, die SDI-Leitungen der Folgeplatine werden mit den SDO-Pins (Serial Data Out) der vorhergehenden Platine verbunden (Daisy Chain). Bei drei hintereinander gesteckten Platinen versorgt der Mikrocontroller also pro Datenleitung 96 LEDs über drei verschaltete Schieberegister.&lt;br /&gt;
&lt;br /&gt;
== Anleitung ==&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Zugriff ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekt]]&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=715</id>
		<title>Laufschrift Eingangstür</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=715"/>
		<updated>2018-05-18T14:48:39Z</updated>

		<summary type="html">&lt;p&gt;Fki: Text zur Schaltung erweitert.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansprechpartner ==&lt;br /&gt;
[[Benutzer:Fki|Fki]]&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
Da die Leuchtdioden des Laufschrift-Panels über der Space-Eingangstür nur noch schwach und unterschiedlich hell glimmen, wird es Zeit für eine Überarbeitung. Bisher wurde lediglich ein statischer Schriftzug angezeigt, da der bisher zur Ansteuerung verwendete Arduino keine Verbindung zum Netzwerk im Hackerspace hatte. Dazu war er so verbaut, daß er nur schwer zugänglich war. Durch den Einsatz eines ESP8266-Moduls soll die neue Steuerung vom Netzwerk aus mit Anzeigedaten gefüttert werden können, ohne daß störende Kabel oder Teildemontagen der Wandverkleidung nötig sind. ;-)&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
* 3 Stk. LED-Matrix-Panel der Fa. Christ Elektronik, 32 x 12 LEDs, rot (Spende, sind älter, vermutlich aus mitte &#039;90er).&lt;br /&gt;
* STM32F072 Discovery-Board zur Ansteuerung&lt;br /&gt;
* Eigenbau-Treiberplatine (Aufbau auf Punkt-Streifenraster)&lt;br /&gt;
* ESP8266-Modul (ESP-01) als WLAN-Bridge zur Verbindung mit und Ansteuerung aus dem Space-Netzwerk.&lt;br /&gt;
&lt;br /&gt;
== Schaltung ==&lt;br /&gt;
Herzstück des Projekts sind drei LED-Matritzen der Fa. Christ. Jede dieser Matritzen verfügt über 384 LEDs, welche in vier Gruppen organisiert sind. Die Gruppen teilen sich drei Schieberegister mit je 32 Ausgängen, welche die einzelnen LEDs innerhalb der gerade aktiven Gruppe schalten. Jede Gruppe besteht damit aus 96 LEDs. Die LED-Matritzen können einfach hintereinander gesteckt werden, so daß die gesamte Laufschrift aus 1152 LEDs besteht.&lt;br /&gt;
&lt;br /&gt;
Die verwendeten Schieberegister sind vom Typ UCN5833. Eigentlich sind es Schieberegister mit Leistungstreibern und Datenlatch in einem Gehäuse. Man kann also Daten in die Register eintakten, ohne daß das Auswirkungen auf die Anzeige hat. Erst durch Aktivieren des Latches ändern sich die Ausgänge. Zur Ansteuerung der Schieberegister werden die Signale SCLK (Serial Clock), SDI (Serial Data In) und STB (Strobe) benötigt. &lt;br /&gt;
&lt;br /&gt;
Dabei teilen sich alle Register die Clock- und Strobe-Leitung, die Datenleitungen jedes Registers sind separat herausgeführt. Werden an eine LED-Matrix weitere Matritzen angeschlossen, werden SCLK und STB einfach durchverbunden, die SDI-Leitungen der Folgeplatine werden mit den SDO-Pins (Serial Data Out) der vorhergehenden Platine verbunden (Daisy Chain). Bei drei hintereinander gesteckten Platinen versorgt der Mikrocontroller also pro Datenleitung 96 LEDs über drei verschaltete Schieberegister.&lt;br /&gt;
&lt;br /&gt;
== Anleitung ==&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Zugriff ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekt]]&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=714</id>
		<title>Laufschrift Eingangstür</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Laufschrift_Eingangst%C3%BCr&amp;diff=714"/>
		<updated>2018-05-18T11:44:50Z</updated>

		<summary type="html">&lt;p&gt;Fki: Erste Beschreibung und verwendete Hardware hinzugefügt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Ansprechpartner ==&lt;br /&gt;
[[Benutzer:Fki|Fki]]&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
Da die Leuchtdioden des Laufschrift-Panels über der Space-Eingangstür nur noch schwach und unterschiedlich hell glimmen, wird es Zeit für eine Überarbeitung. Bisher wurde lediglich ein statischer Schriftzug angezeigt, da der bisher zur Ansteuerung verwendete Arduino keine Verbindung zum Netzwerk im Hackerspace hatte. Dazu war er so verbaut, daß er nur schwer zugänglich war. Durch den Einsatz eines ESP8266-Moduls soll die neue Steuerung vom Netzwerk aus mit Anzeigedaten gefüttert werden können, ohne daß störende Kabel oder Teildemontagen der Wandverkleidung nötig sind. ;-)&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
* 3 Stk. LED-Matrix-Panel der Fa. Christ Elektronik, 32 x 12 LEDs, rot.&lt;br /&gt;
* STM32F072 Discovery-Board zur Ansteuerung&lt;br /&gt;
* Eigenbau-Treiberplatine (Aufbau auf Punkt-Streifenraster)&lt;br /&gt;
* ESP8266-Modul (ESP-01) als WLAN-Bridge zur Verbindung mit und Ansteuerung aus dem Space-Netzwerk.&lt;br /&gt;
&lt;br /&gt;
== Schaltung ==&lt;br /&gt;
Herzstück des Projekts sind die LED-Matritzen der Fa. Christ.&lt;br /&gt;
&lt;br /&gt;
== Anleitung ==&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Zugriff ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
=== Funktionen ===&lt;br /&gt;
In Arbeit.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekt]]&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=465</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Hardware</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=465"/>
		<updated>2017-05-09T19:55:00Z</updated>

		<summary type="html">&lt;p&gt;Fki: Bild eingefügt, Links zu Hardwaremodulen gesetzt, Navigation hinzugefügt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]]&lt;br /&gt;
&lt;br /&gt;
Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und &#039;&#039;&#039;testen&#039;&#039;&#039; können.&lt;br /&gt;
&lt;br /&gt;
== Der Weg der Daten ==&lt;br /&gt;
[[Datei:WS_Encoder_grob.png|right|thumb]]&lt;br /&gt;
Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein &#039;&#039;&#039;UART-Modul&#039;&#039;&#039; und ein &#039;&#039;&#039;SPI-Modul&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Damit die Datenübertragung zum Encoder die Ausgabe an die LEDs nicht beeinflusst, brauchen wir einen Pufferspeicher zur Entkopplung, in den die empfangenen Daten geschrieben werden. Wir benötigen also ein Modul, daß RAM implementiert und ansteuert, also einen &#039;&#039;&#039;VRAM-Controller&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Aus diesem Video-RAM holt sich der eigentliche &#039;&#039;&#039;WS2812-Encoder&#039;&#039;&#039; die Daten, wandelt sie und gibt sie aus.&lt;br /&gt;
&lt;br /&gt;
== Das Konfigurations-Interface ==&lt;br /&gt;
Dinge ändern sich. Zum Beispiel die Timings von einer Version des WS2812 zur anderen. Oder dein FPGA-Board wird mit einem anderen Takt betrieben als meins. Lange Rede, kurzer Sinn: Wir wollen bestimmte Parameter einstellen können. Und dazu brauchen wir neben der reinen Datenverarbeitung ein Konfigurationsinterface.&lt;br /&gt;
&lt;br /&gt;
Das Konfigurationsinterface besteht aus Registern, der Hardware-Entsprechung zu Variablen in der Programmierung. Hier können wir Parameter hinterlegen, die die Datenverarbeitung steuern, z.B. die Anzahl der LEDs auf einem angeschlossenen Streifen oder die Dauer des Reset-Signals. In meinem aktuellen Entwurf habe ich 12 solcher Register vorgesehen. Es lohnt sich also, darüber nachzudenken, wie man den Zugriff auf diese Register regeln kann, ohne daß die Modulschnittstelle überfrachtet wird. &lt;br /&gt;
&lt;br /&gt;
Ein weiteres Thema ist Wiederverwendbarkeit. Dir passen die seriellen Schnittstellen nicht, du willst lieber ein paralleles Interface? Je nachdem, wie die Schnittstelle des Encoder-Moduls aussieht kann das simpel sein oder zu einem Schreikrampf führen. Ziel ist also eine möglichst einheitliche, übersichtliche Modulschnittstelle. Das führt uns zu Bussen.&lt;br /&gt;
&lt;br /&gt;
== Wir nehmen den Bus ==&lt;br /&gt;
Ein Bus besteht aus Daten-, Adress-, und Steuerleitungen. Die Adresse legt fest, auf welches Register wir zugreifen wollen, die Daten sind die Daten, die wir schreiben oder lesen wollen und die Steuerleitungen sind dafür da, die Abläufe zu koordinieren.&lt;br /&gt;
&lt;br /&gt;
Es gibt eine ganze Menge verschiedenster Busse, parallele, serielle, schnelle für kurze Distanzen, langsamere für groß, whatever. Für uns interessant sind vor allem Busse, die sich dazu eignen, Systeme aus Modulen auf einem FPGA zusammenzuschalten. Da gibt es selbstverständlich auch mehrere, AXI oder AMBA zum Beispiel. Ich favorisiere in diesem Zusammenhang den [http://opencores.org/opencores,wishbone &amp;quot;Wishbone-Bus&amp;quot;], eine offene Busspezifikation, frei verwendbar und sehr leistungsfähig und flexibel.&lt;br /&gt;
&lt;br /&gt;
== Infrastrukturmaßnahmen ==&lt;br /&gt;
[[Datei:WS_Encoder_WB.png|right|thumb]]&lt;br /&gt;
Strukturieren wir das Projekt also nach unseren neuesten Erkenntnissen um:&lt;br /&gt;
* Das WS2812-Encodermodul bekommt ein Wishbone-Slave-Interface.&lt;br /&gt;
* Das Modul umfaßt die Buslogik, den VRAM und den eigentlichen Encoder&lt;br /&gt;
&lt;br /&gt;
Um die Daten von den seriellen Schnittstellen in den Encoder zu bekommen, müssen diese über ein Wishbone-Master-Interface verfügen. Hier könnten wir jetzt jeder Schnittstelle ein solches Interface verpassen oder ein kleines Hilfsmodul bauen, daß Daten von den Schnittstellen abholt und über den Wishbone-Bus an das WS2812-Modul überträgt. Diese Lösung hat darüber hinaus den Vorteil, daß es nur einen Master gibt. Gäbe es mehrere, müssten diese untereinander aushandeln, wer gerade übertragen darf. Diese zusätzliche Komplexität würde ich mir gerne schenken.&lt;br /&gt;
&lt;br /&gt;
Das Abholen der Daten von den externen Schnittstellen kann natürlich auch wieder per Wishbone erfolgen. Ein weiterer Vorteil dabei ist, daß man einfach Schnittstellen austauschen oder hinzufügen kann, in dem man sie an den Bus koppelt.&lt;br /&gt;
&lt;br /&gt;
Erweitern wir unsere Liste von oben also noch ein wenig:&lt;br /&gt;
* Wir bauen einen kleinen Steuercontroller, der das Wishbone-Master-Interface steuert&lt;br /&gt;
* Die seriellen Schnittstellen erhalten, wie das WS-Modul, ein Wishbone-Slave-Interface.&lt;br /&gt;
&lt;br /&gt;
== Die Komponenten im Detail ==&lt;br /&gt;
Da die Besprechung der einzelnen Blöcke umfangreich wird, habe ich entsprechende Unterseiten eingerichtet:&lt;br /&gt;
* Zum [[/Wishbone|Wishbone-Bus -&amp;gt;]]&lt;br /&gt;
* Zum [[/SPI|SPI-Modul -&amp;gt;]]&lt;br /&gt;
* Zum [[/UART|UART-Modul -&amp;gt;]]&lt;br /&gt;
* Zum [[/WS_Encoder|WS2812-Encoder -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]]&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Datei:WS_Encoder_WB.png&amp;diff=464</id>
		<title>Datei:WS Encoder WB.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Datei:WS_Encoder_WB.png&amp;diff=464"/>
		<updated>2017-05-09T19:38:37Z</updated>

		<summary type="html">&lt;p&gt;Fki: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=463</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=463"/>
		<updated>2017-05-09T19:00:06Z</updated>

		<summary type="html">&lt;p&gt;Fki: Navigation am Seitenende eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir schreiben einen WS2812-Encoder-Modul, statten es mit einem UART und einer SPI-Schnittstelle aus und verbinden das Ganze über einen kleinen Steuerautomaten. Daraus erzeugen wir eine Konfiguration für ein FPGA und sind fertig. Soweit die Theorie...&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS_Encoder_top.png|right|thumb]]&lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteile von Softwarelösungen:&#039;&#039;&#039;&lt;br /&gt;
* Die Timings des WS-Protokolls sind sehr eng und dadurch schwierig auf einem Mikrocontroller einzuhalten.&lt;br /&gt;
* Wegen der Timings können keine Interrupts während der Ausgabe auf die LEDs benutzt werden.&lt;br /&gt;
* Hardware-Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. zu langsam (durch Overhead).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile der Hardwarelösung:&#039;&#039;&#039;&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, dadurch hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertige Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle und damit ca. 17 m bzw 8,5 m gesamtlänge der Streifen.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;br /&gt;
&lt;br /&gt;
[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=462</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Hardware</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=462"/>
		<updated>2017-05-09T18:49:35Z</updated>

		<summary type="html">&lt;p&gt;Fki: Text erweitert.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und &#039;&#039;&#039;testen&#039;&#039;&#039; können.&lt;br /&gt;
&lt;br /&gt;
== Der Weg der Daten ==&lt;br /&gt;
[[Datei:WS_Encoder_grob.png|right|thumb]]&lt;br /&gt;
Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein &#039;&#039;&#039;UART-Modul&#039;&#039;&#039; und ein &#039;&#039;&#039;SPI-Modul&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Damit die Datenübertragung zum Encoder die Ausgabe an die LEDs nicht beeinflusst, brauchen wir einen Pufferspeicher zur Entkopplung, in den die empfangenen Daten geschrieben werden. Wir benötigen also ein Modul, daß RAM implementiert und ansteuert, also einen &#039;&#039;&#039;VRAM-Controller&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Aus diesem Video-RAM holt sich der eigentliche &#039;&#039;&#039;WS2812-Encoder&#039;&#039;&#039; die Daten, wandelt sie und gibt sie aus.&lt;br /&gt;
&lt;br /&gt;
== Das Konfigurations-Interface ==&lt;br /&gt;
Dinge ändern sich. Zum Beispiel die Timings von einer Version des WS2812 zur anderen. Oder dein FPGA-Board wird mit einem anderen Takt betrieben als meins. Lange Rede, kurzer Sinn: Wir wollen bestimmte Parameter einstellen können. Und dazu brauchen wir neben der reinen Datenverarbeitung ein Konfigurationsinterface.&lt;br /&gt;
&lt;br /&gt;
Das Konfigurationsinterface besteht aus Registern, der Hardware-Entsprechung zu Variablen in der Programmierung. Hier können wir Parameter hinterlegen, die die Datenverarbeitung steuern, z.B. die Anzahl der LEDs auf einem angeschlossenen Streifen oder die Dauer des Reset-Signals. In meinem aktuellen Entwurf habe ich 12 solcher Register vorgesehen. Es lohnt sich also, darüber nachzudenken, wie man den Zugriff auf diese Register regeln kann, ohne daß die Modulschnittstelle überfrachtet wird. &lt;br /&gt;
&lt;br /&gt;
Ein weiteres Thema ist Wiederverwendbarkeit. Dir passen die seriellen Schnittstellen nicht, du willst lieber ein paralleles Interface? Je nachdem, wie die Schnittstelle des Encoder-Moduls aussieht kann das simpel sein oder zu einem Schreikrampf führen. Ziel ist also eine möglichst einheitliche, übersichtliche Modulschnittstelle. Das führt uns zu Bussen.&lt;br /&gt;
&lt;br /&gt;
== Wir nehmen den Bus ==&lt;br /&gt;
Ein Bus besteht aus Daten-, Adress-, und Steuerleitungen. Die Adresse legt fest, auf welches Register wir zugreifen wollen, die Daten sind die Daten, die wir schreiben oder lesen wollen und die Steuerleitungen sind dafür da, die Abläufe zu koordinieren.&lt;br /&gt;
&lt;br /&gt;
Es gibt eine ganze Menge verschiedenster Busse, parallele, serielle, schnelle für kurze Distanzen, langsamere für groß, whatever. Für uns interessant sind vor allem Busse, die sich dazu eignen, Systeme aus Modulen auf einem FPGA zusammenzuschalten. Da gibt es selbstverständlich auch mehrere, AXI oder AMBA zum Beispiel. Ich favorisiere in diesem Zusammenhang den [http://opencores.org/opencores,wishbone &amp;quot;Wishbone-Bus&amp;quot;], eine offene Busspezifikation, frei verwendbar und sehr leistungsfähig und flexibel.&lt;br /&gt;
&lt;br /&gt;
== Infrastrukturmaßnahmen ==&lt;br /&gt;
Strukturieren wir das Projekt also nach unseren neuesten Erkenntnissen um:&lt;br /&gt;
* Das WS2812-Encodermodul bekommt ein Wishbone-Slave-Interface.&lt;br /&gt;
* Das Modul umfaßt die Buslogik, den VRAM und den eigentlichen Encoder&lt;br /&gt;
&lt;br /&gt;
Um die Daten von den seriellen Schnittstellen in den Encoder zu bekommen, müssen diese über ein Wishbone-Master-Interface verfügen. Hier könnten wir jetzt jeder Schnittstelle ein solches Interface verpassen oder ein kleines Hilfsmodul bauen, daß Daten von den Schnittstellen abholt und über den Wishbone-Bus an das WS2812-Modul überträgt. Diese Lösung hat darüber hinaus den Vorteil, daß es nur einen Master gibt. Gäbe es mehrere, müssten diese untereinander aushandeln, wer gerade übertragen darf. Diese zusätzliche Komplexität würde ich mir gerne schenken.&lt;br /&gt;
&lt;br /&gt;
Das Abholen der Daten von den externen Schnittstellen kann natürlich auch wieder per Wishbone erfolgen. Ein weiterer Vorteil dabei ist, daß man einfach Schnittstellen austauschen oder hinzufügen kann, in dem man sie an den Bus koppelt.&lt;br /&gt;
&lt;br /&gt;
Erweitern wir unsere Liste von oben also noch ein wenig:&lt;br /&gt;
* Wir bauen einen kleinen Steuercontroller, der das Wishbone-Master-Interface steuert&lt;br /&gt;
* Die seriellen Schnittstellen erhalten, wie das WS-Modul, ein Wishbone-Slave-Interface.&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=453</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Hardware</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=453"/>
		<updated>2017-05-07T18:35:10Z</updated>

		<summary type="html">&lt;p&gt;Fki: Bild getauscht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und &#039;&#039;&#039;testen&#039;&#039;&#039; können.&lt;br /&gt;
&lt;br /&gt;
== Der Weg der Daten ==&lt;br /&gt;
[[Datei:WS_Encoder_grob.png|right|thumb]]&lt;br /&gt;
Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein &#039;&#039;&#039;UART-Modul&#039;&#039;&#039; und ein &#039;&#039;&#039;SPI-Modul&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Damit die Datenübertragung zum Encoder die Ausgabe an die LEDs nicht beeinflusst, brauchen wir einen Pufferspeicher zur Entkopplung, in den die empfangenen Daten geschrieben werden. Wir benötigen also ein Modul, daß RAM implementiert und ansteuert, also einen &#039;&#039;&#039;VRAM-Controller&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Aus diesem Video-RAM holt sich der eigentliche &#039;&#039;&#039;WS2812-Encoder&#039;&#039;&#039; die Daten, wandelt sie und gibt sie aus.&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Datei:WS_Encoder_grob.png&amp;diff=452</id>
		<title>Datei:WS Encoder grob.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Datei:WS_Encoder_grob.png&amp;diff=452"/>
		<updated>2017-05-07T18:33:07Z</updated>

		<summary type="html">&lt;p&gt;Fki: Grobe Blockstruktur des Encoders. Eigene Arbeit.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Grobe Blockstruktur des Encoders. Eigene Arbeit.&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=451</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Hardware</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Hardware&amp;diff=451"/>
		<updated>2017-05-07T18:07:05Z</updated>

		<summary type="html">&lt;p&gt;Fki: Den Weg der Daten eingefügt.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:WS_Encoder_top.png|right|thumb]]&lt;br /&gt;
&lt;br /&gt;
Unser Grobkonzept steht, jetzt geht es in die Details. Dazu machen wir uns zuerst Gedanken darüber, wie unser Encoder-System grundsätzlich arbeiten soll. Daraus ergeben sich erste Funktionsblöcke, die zur Gesamtschaltung verbunden werden. Bei Bedarf werden diese Blöcke noch weiter unterteilt, bis wir auf einem Level angekommen sind, daß wir gut beschreiben und &#039;&#039;&#039;testen&#039;&#039;&#039; können.&lt;br /&gt;
&lt;br /&gt;
== Der Weg der Daten ==&lt;br /&gt;
Beginnen wir bei den Eingabedaten und verfolgen ihre Verarbeitung. Im einfachsten Fall werden wir ein RGB-Farbtripel an den Encoder schicken, daß in das WS-Protokoll überführt und ausgegeben wird. Egal, welche unserer seriellen Schnittstellen wir benutzen, das übertragene Datum steht nach dem erfolgreichen Empfang in einem Register und kann parallel weiter verarbeitet werden. Unsere ersten Funktionsblöcke werden also einmal ein &#039;&#039;&#039;UART-Modul&#039;&#039;&#039; und ein &#039;&#039;&#039;SPI-Modul&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Damit die Datenübertragung zum Encoder die Ausgabe an die LEDs nicht beeinflusst, brauchen wir einen Pufferspeicher zur Entkopplung, in den die empfangenen Daten geschrieben werden. Wir benötigen also ein Modul, daß RAM implementiert und ansteuert, also einen &#039;&#039;&#039;VRAM-Controller&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Aus diesem Video-RAM holt sich der eigentliche &#039;&#039;&#039;WS2812-Encoder&#039;&#039;&#039; die Daten, wandelt sie und gibt sie aus.&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=450</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=450"/>
		<updated>2017-05-07T16:49:50Z</updated>

		<summary type="html">&lt;p&gt;Fki: /* Das Grobkonzept */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir schreiben einen WS2812-Encoder-Modul, statten es mit einem UART und einer SPI-Schnittstelle aus und verbinden das Ganze über einen kleinen Steuerautomaten. Daraus erzeugen wir eine Konfiguration für ein FPGA und sind fertig. Soweit die Theorie...&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS_Encoder_top.png|right|thumb]]&lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteile von Softwarelösungen:&#039;&#039;&#039;&lt;br /&gt;
* Die Timings des WS-Protokolls sind sehr eng und dadurch schwierig auf einem Mikrocontroller einzuhalten.&lt;br /&gt;
* Wegen der Timings können keine Interrupts während der Ausgabe auf die LEDs benutzt werden.&lt;br /&gt;
* Hardware-Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. zu langsam (durch Overhead).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile der Hardwarelösung:&#039;&#039;&#039;&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, dadurch hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertige Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle und damit ca. 17 m bzw 8,5 m gesamtlänge der Streifen.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=449</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=449"/>
		<updated>2017-05-07T16:48:38Z</updated>

		<summary type="html">&lt;p&gt;Fki: Bild eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir schreiben einen WS2812-Encoder-Modul, statten es mit einem UART und einer SPI-Schnittstelle aus und verbinden das Ganze über einen kleinen Steuerautomaten. Daraus erzeugen wir eine Konfiguration für ein FPGA und sind fertig.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS_Encoder_top.png|right|thumb]]&lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteile von Softwarelösungen:&#039;&#039;&#039;&lt;br /&gt;
* Die Timings des WS-Protokolls sind sehr eng und dadurch schwierig auf einem Mikrocontroller einzuhalten.&lt;br /&gt;
* Wegen der Timings können keine Interrupts während der Ausgabe auf die LEDs benutzt werden.&lt;br /&gt;
* Hardware-Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. zu langsam (durch Overhead).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile der Hardwarelösung:&#039;&#039;&#039;&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, dadurch hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertige Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle und damit ca. 17 m bzw 8,5 m gesamtlänge der Streifen.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Datei:WS_Encoder_top.png&amp;diff=448</id>
		<title>Datei:WS Encoder top.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Datei:WS_Encoder_top.png&amp;diff=448"/>
		<updated>2017-05-07T16:44:50Z</updated>

		<summary type="html">&lt;p&gt;Fki: Eigene Arbeit.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eigene Arbeit.&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=447</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=447"/>
		<updated>2017-05-07T16:42:48Z</updated>

		<summary type="html">&lt;p&gt;Fki: Kleinere Textüberarbeitungen&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir schreiben einen WS2812-Encoder-Modul, statten es mit einem UART und einer SPI-Schnittstelle aus und verbinden das Ganze über einen kleinen Steuerautomaten. Daraus erzeugen wir eine Konfiguration für ein FPGA und sind fertig.&lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? &lt;br /&gt;
&lt;br /&gt;
Nachteile von Softwarelösungen:&lt;br /&gt;
* Die Timings des WS-Protokolls sind sehr eng und dadurch schwierig auf einem Mikrocontroller einzuhalten.&lt;br /&gt;
* Wegen der Timings können keine Interrupts während der Ausgabe auf die LEDs benutzt werden.&lt;br /&gt;
* Hardware-Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. zu langsam (durch Overhead).&lt;br /&gt;
&lt;br /&gt;
Vorteile der Hardwarelösung:&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, dadurch hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertige Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle und damit ca. 17 m bzw 8,5 m gesamtlänge der Streifen.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)&amp;diff=446</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)&amp;diff=446"/>
		<updated>2017-05-07T16:15:20Z</updated>

		<summary type="html">&lt;p&gt;Fki: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:Projekt]]&lt;br /&gt;
&lt;br /&gt;
Dieses Projekt ist in seiner Entstehung begriffen und wird mit der Zeit erweitert! Bei Fragen oder Anregungen bitte auf meiner [[Benutzer Diskussion:Fki|Diskussionsseite]] melden!&lt;br /&gt;
&lt;br /&gt;
== Projektbeschreibung ==&lt;br /&gt;
Ziel dieses Projektes ist es, eine Schaltung in VHDL für einen WS2812(b) Encoder zu erstellen. Das Protokoll der WS2812-Controller ist relativ einfach, stellt jedoch einige Anforderungen an das Timing und ist daher schwierig auf Mikrocontrollern zu implementieren.&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke ist nun, den zeitkritischen Codiervorgang auf ein FPGA auszulagern und den Zugriff darauf über verbreitete Schnittstellen nach Außen zur Verfügung zu stellen. Da bieten sich serielle Schnittstellen wie UART oder SPI an, parallele Schnittstellen sind ebenfalls möglich, brauchen aber mehr IO-Ports am Controller.&lt;br /&gt;
&lt;br /&gt;
== [[/Einleitung|Einleitung]] ==&lt;br /&gt;
Hier geht es um Vorüberlegungen zu dem Hardware-Encoder. Taktraten, Timings und die Codierung des WS2812 werden betrachtet.&lt;br /&gt;
&lt;br /&gt;
== [[/Hardware|Hardware]] ==&lt;br /&gt;
In diesem Abschnitt geht es um die zu beschreibende Hardware, Features, Schnittstellen und Blockdiagramme. Unterkapitel widmen sich den einzelnen Schaltungsblöcken im Detail.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/UART|UART]] ===&lt;br /&gt;
Dieses Kapitel ist der seriellen asynchronen Kommunikation gewidmet. Hier geht es um das Protokoll sowie die Implementierung eines entsprechenden Schnittstellenmoduls.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/SPI|SPI]] ===&lt;br /&gt;
Im Gegensatz zum UART befassen wir uns hier mit synchroner Datenübertragung und der Implementierung des passenden Moduls.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/VRAM|VRAM]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/LED-Encoder|LED-Encoder]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/Steuerung|Ablaufsteuerung]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/BUI|Bussteuerung]] ===&lt;br /&gt;
&lt;br /&gt;
== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Protokoll|Protokoll und Software]] ==&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=445</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=445"/>
		<updated>2017-05-07T16:14:12Z</updated>

		<summary type="html">&lt;p&gt;Fki: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir nehmen einen FPGA, statten ihn mit einem UART und einer SPI-Schnittstelle aus, basteln einen Transmitter für das WS2812-Protokoll und hängen das Ganze mit einem kleinen Steuerautomaten aneinander. &lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? Aus mehreren Gründen:&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, also hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Das Timing des Protokolls mit seinen 800kHz Bit-Takt ist schon wieder so eng, daß grade in kleineren µControllern, wie den ATMegas, ein sehr hoher Aufwand betrieben werden muss, um die Timings einzuhalten.&lt;br /&gt;
* Das bedeutet häufig, daß Interrupts abgeschaltet werden müssen.&lt;br /&gt;
* Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. haben zu viel Overhead.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertigste Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=444</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=444"/>
		<updated>2017-05-07T16:13:18Z</updated>

		<summary type="html">&lt;p&gt;Fki: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir nehmen einen FPGA, statten ihn mit einem UART und einer SPI-Schnittstelle aus, basteln einen Transmitter für das WS2812-Protokoll und hängen das Ganze mit einem kleinen Steuerautomaten aneinander. &lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? Aus mehreren Gründen:&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, also hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Das Timing des Protokolls mit seinen 800kHz Bit-Takt ist schon wieder so eng, daß grade in kleineren µControllern, wie den ATMegas, ein sehr hoher Aufwand betrieben werden muss, um die Timings einzuhalten.&lt;br /&gt;
* Das bedeutet häufig, daß Interrupts abgeschaltet werden müssen.&lt;br /&gt;
* Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. haben zu viel Overhead.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertigste Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=443</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)/Einleitung</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)/Einleitung&amp;diff=443"/>
		<updated>2017-05-07T16:12:27Z</updated>

		<summary type="html">&lt;p&gt;Fki: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Hardware-Encoder für NeoPixel (WS2812)|Zurück zum Inhaltsverzeichnis]] | [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware| Weiter zu Hardware -&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Das Grobkonzept ==&lt;br /&gt;
Wir nehmen einen FPGA, statten ihn mit einem UART und einer SPI-Schnittstelle aus, basteln einen Transmitter für das WS2812-Protokoll und hängen das Ganze mit einem kleinen Steuerautomaten aneinander. &lt;br /&gt;
&lt;br /&gt;
=== Wofür das Ganze? ===&lt;br /&gt;
Wozu nun dieser Aufwand, es gibt doch bereits fertige Software-Bibliotheken? Aus mehreren Gründen:&lt;br /&gt;
* Das Protokoll ist nicht sehr kompliziert, also hat man ein relativ gut durchschaubares Beispiel für die Beschäftigung mit VHDL.&lt;br /&gt;
* Das Timing des Protokolls mit seinen 800kHz Bit-Takt ist schon wieder so eng, daß grade in kleineren µControllern, wie den ATMegas, ein sehr hoher Aufwand betrieben werden muss, um die Timings einzuhalten.&lt;br /&gt;
* Das bedeutet häufig, daß Interrupts abgeschaltet werden müssen.&lt;br /&gt;
* Timer mit entsprechenden Routinen sind bereits zu ungenau bzw. haben zu viel Overhead.&lt;br /&gt;
* Die Verwendung von Hardware-Schnittstellen wie SPI oder UART kann Interrupt-gesteuert ablaufen.&lt;br /&gt;
* Je nach Controller auch unter Verwendung von DMA.&lt;br /&gt;
* Die Entkopplung der LEDs vom Host ermöglicht, alles als Host zu benutzen, was eine serielle Schnittstelle hat: PCs, Raspberry Pi usw.&lt;br /&gt;
&lt;br /&gt;
== Der LED-Controller ==&lt;br /&gt;
Wie arbeitet dieser ominöse WS2812 jetzt eigentlich? Der WS2812 steuert eine RGB-LED an und zwar mit 8 Bit pro Farbe bzw. 24 Bit Farbtiefe pro LED. Die Reihenfolge der Farbbytes unterscheidet sich dabei vom gewohnten RGB: Die LEDs erwarten ein GRB-Format, also erst das Byte für Grün, dann Rot und zum Schluss Blau. Das höchstwertigste Bit wird zuerst übertragen.&lt;br /&gt;
&lt;br /&gt;
Wenn mehrere NeoPixel hintereinander geschaltet werden, übernimmt der Controller der ersten LED in der Kette die ersten 24 Bit in sein Farbregister, alle weiteren Bits gibt er über seinen Datenausgang an den nächsten Pixel weiter. Angezeigt werden die Farben jedoch erst nach einem RESET-Signal.&lt;br /&gt;
&lt;br /&gt;
[[Datei:WS2812_Timing.png|right|thumb]]&lt;br /&gt;
Das Übertragungsprotokoll sieht so aus: Ein Bit wird innerhalb von 1,25µs übertragen. Innerhalb dieser Zeit geht die Signalleitung für eine gewisse Zeit auf High- und anschließend auf Low-Pegel. Für ein &amp;quot;1&amp;quot;-Bit sind es 0,8µs High und 0,45µS Low, für ein &amp;quot;0&amp;quot;-Bit 0,4µs High und 0,85µs Low. Pro Phase sind bis zu 0,15µs Abweichung erlaubt. Liegt die Signalleitung für mehr als 50µs auf Low, wird das als Reset-Signal interpretiert und die übertragenen Farbwerte werden angezeigt.&lt;br /&gt;
&lt;br /&gt;
Hier gibt es das ausführliche Datenblatt[https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Takte, Timings, LEDs ===&lt;br /&gt;
Ein paar Eckdaten sind noch zu klären: &lt;br /&gt;
* Wie viele LEDs kann ich (sinnvoll) hintereinander schalten? &lt;br /&gt;
* Wie knapp sind die Timings wirklich?&lt;br /&gt;
&lt;br /&gt;
Rechnen wir mal ein bisschen:&lt;br /&gt;
* Für flüssig erscheinende Animationen brauchen wir mindestens 24 Bilder/Sekunde. Dabei flackert es aber noch sichtbar.&lt;br /&gt;
* Moderne Computermonitore arbeiten mit 60 Bildern/Sekunde.&lt;br /&gt;
&lt;br /&gt;
In Anlehnung an Monitore werde ich auch hier von FPS (Frames Per Second - Bilder pro Sekunde) sprechen, wenn ich vollständige Übertragungszyklen zu den NeoPixeln meine, auch wenn das vielleicht nicht ganz korrekt ist.&lt;br /&gt;
&lt;br /&gt;
Die erste Frage können wir damit schon mal beantworten: Technisch gesehen können wir beliebig viele LEDs hintereinander schalten, je mehr es werden, desto niedriger wird unsere Bildrate. Interessant ist also vielmehr, wie viele LEDs bei 30 oder 60 FPS hintereinander gehängt werden können. Betrachten wir das Ganze einmal für 60 FPS:&lt;br /&gt;
&lt;br /&gt;
* Wir haben für einen Durchlauf 1/60s Zeit, also 16,7ms.&lt;br /&gt;
* Um einen Pixel mit 24 Bit zu übertragen, brauchen wir 24 * 1,25µs = 30µs.&lt;br /&gt;
* Pro Durchlauf kommt noch ein Reset mit 50µs dazu.&lt;br /&gt;
&lt;br /&gt;
In eine Formel gegossen könnte das so aussehen:&lt;br /&gt;
* T_FRAME = x * T_LED + T_RESET.&lt;br /&gt;
Dabei ist x die gesuchte Anzahl der LEDs, T_LED = 30µs und T_RESET = 50µs. T_FRAME = 16,7ms ist die Zeitspanne für einen Durchlauf. Umgestellt nach x erhalten wir:&lt;br /&gt;
* x = (T_FRAME - T_RESET) / T_LED&lt;br /&gt;
Mit eingesetzten Werten:&lt;br /&gt;
* (16700µs - 50µs) / 30µs = 555 LEDs&lt;br /&gt;
Die nächstkleinere Zweierpotenz wären 512 LEDs. Halten wir also fest: Mit 512 LEDs erreichen wir unsere 60 FPS, 1024 LEDs können wir immer noch mit 30 FPS ansteuern. Zum Vergleich: Die gängigen LED-Streifen auf Rolle haben 30 oder 60 LEDs / Meter, das wären dann 150 bzw. 300 LEDs pro 5m-Rolle.&lt;br /&gt;
&lt;br /&gt;
==== Bleiben noch die Timings ====&lt;br /&gt;
Wie knapp wird es denn jetzt wirklich? Nehmen wir als Beispiel einen ATMega mit 20 MHz Takt, wie er von den Arduinos bekannt ist. Diese Mikrocontroller benötigen für die meisten Befehle einen Takt, für Sprünge zwei.&lt;br /&gt;
&lt;br /&gt;
* Bei 20 MHz dauert ein Takt 1 / 20.000.000 Hz = 0,000.000.050 s oder 50 ns.&lt;br /&gt;
* Die kürzeste Schaltdauer sind 400 ns (T0H).&lt;br /&gt;
* Diese Zeitspanne entspricht 400 ns / 50 ns = 8 Takten (+-3 Takte Toleranz).&lt;br /&gt;
* Ein ganzes Bit entspricht 25 Takten.&lt;br /&gt;
&lt;br /&gt;
Das ist unter Einsatz von taktoptimiertem Assemblercode gerade noch machbar. Wenn wir mit höheren Takten arbeiten können, entspannt sich die ganze Situation ein wenig, allerdings nicht in einem Maße, als daß es uns von handoptimiertem Code erlösen würde.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
          20MHz 40MHz 60MHz 80MHz 100Mhz&lt;br /&gt;
   T1H      16    32    48    64    80&lt;br /&gt;
   T1L       9    18    27    36    45&lt;br /&gt;
   T0H       8    16    24    32    40&lt;br /&gt;
   T0L      17    34    51    68    85&lt;br /&gt;
 &#039;&#039;&#039;Sequenz    25    50    75   100   125&#039;&#039;&#039;&lt;br /&gt;
   RST     1000  2000  3000  4000  5000&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)&amp;diff=442</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)&amp;diff=442"/>
		<updated>2017-05-07T16:11:28Z</updated>

		<summary type="html">&lt;p&gt;Fki: Projektbeschreibung verändert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:Projekt]]&lt;br /&gt;
&lt;br /&gt;
Dieses Projekt ist in seiner Entstehung begriffen und wird mit der Zeit erweitert! Bei Fragen oder Anregungen bitte auf meiner [[Benutzer Diskussion:Fki|Diskussionsseite]] melden!&lt;br /&gt;
&lt;br /&gt;
== Projektbeschreibung ==&lt;br /&gt;
Ziel dieses Projektes ist es, eine Schaltung in VHDL für einen WS2812(b) Encoder zu erstellen. Das Protokoll der WS2812-Controller ist relativ einfach, stellt jedoch einige Anforderungen an das Timing und ist daher schwierig auf Mikrocontrollern zu implementieren.&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke ist nun, den zeitkritischen Codiervorgang auf ein FPGA auszulagern und den Zugriff darauf über verbreitete Schnittstellen nach Außen zur Verfügung zu stellen. Da bieten sich serielle Schnittstellen wie UART oder SPI an, parallele Schnittstellen sind ebenfalls möglich, brauchen aber mehr IO-Ports am Controller.&lt;br /&gt;
&lt;br /&gt;
== [[/Einleitung|Einleitung]] ==&lt;br /&gt;
Hier geht es um Vorüberlegungen zu dem Hardware-Encoder. Taktraten, Timings und die Codierung des WS2812 werden betrachtet.&lt;br /&gt;
&lt;br /&gt;
== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware|Hardware]] ==&lt;br /&gt;
In diesem Abschnitt geht es um die zu beschreibende Hardware, Features, Schnittstellen und Blockdiagramme. Unterkapitel widmen sich den einzelnen Schaltungsblöcken im Detail.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/UART|UART]] ===&lt;br /&gt;
Dieses Kapitel ist der seriellen asynchronen Kommunikation gewidmet. Hier geht es um das Protokoll sowie die Implementierung eines entsprechenden Schnittstellenmoduls.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/SPI|SPI]] ===&lt;br /&gt;
Im Gegensatz zum UART befassen wir uns hier mit synchroner Datenübertragung und der Implementierung des passenden Moduls.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/VRAM|VRAM]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/LED-Encoder|LED-Encoder]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/Steuerung|Ablaufsteuerung]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/BUI|Bussteuerung]] ===&lt;br /&gt;
&lt;br /&gt;
== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Protokoll|Protokoll und Software]] ==&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
	<entry>
		<id>https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)&amp;diff=441</id>
		<title>Hardware-Encoder für NeoPixel (WS2812)</title>
		<link rel="alternate" type="text/html" href="https://wiki.hackerspace-bielefeld.de/index.php?title=Hardware-Encoder_f%C3%BCr_NeoPixel_(WS2812)&amp;diff=441"/>
		<updated>2017-05-07T16:05:37Z</updated>

		<summary type="html">&lt;p&gt;Fki: /* Einleitung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:Projekt]]&lt;br /&gt;
&lt;br /&gt;
Dieses Projekt ist in seiner Entstehung begriffen und wird mit der Zeit erweitert! Bei Fragen oder Anregungen bitte auf meiner [[Benutzer Diskussion:Fki|Diskussionsseite]] melden!&lt;br /&gt;
&lt;br /&gt;
== Projektbeschreibung ==&lt;br /&gt;
Ziel dieses Projektes ist es, eine Schaltungsbeschreibung in VHDL für einen WS2812(b) Encoder zu erstellen. Das Protokoll der WS2812-Controller ist relativ einfach, stellt jedoch einige Anforderungen an das Timing und ist daher hakelig auf Mikrocontrollern, gerade kleineren, zu implementieren.&lt;br /&gt;
&lt;br /&gt;
Der Grundgedanke ist nun, eine gut unterstützte Schnittstelle an einem beliebigen Mikrocontroller zu nutzen, z.B. UART oder SPI, um die Daten zu den Konverter zu schicken, der dann den passenden Datenstrom an die NeoPixel schickt.&lt;br /&gt;
&lt;br /&gt;
== [[/Einleitung|Einleitung]] ==&lt;br /&gt;
Hier geht es um Vorüberlegungen zu dem Hardware-Encoder. Taktraten, Timings und die Codierung des WS2812 werden betrachtet.&lt;br /&gt;
&lt;br /&gt;
== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware|Hardware]] ==&lt;br /&gt;
In diesem Abschnitt geht es um die zu beschreibende Hardware, Features, Schnittstellen und Blockdiagramme. Unterkapitel widmen sich den einzelnen Schaltungsblöcken im Detail.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/UART|UART]] ===&lt;br /&gt;
Dieses Kapitel ist der seriellen asynchronen Kommunikation gewidmet. Hier geht es um das Protokoll sowie die Implementierung eines entsprechenden Schnittstellenmoduls.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/SPI|SPI]] ===&lt;br /&gt;
Im Gegensatz zum UART befassen wir uns hier mit synchroner Datenübertragung und der Implementierung des passenden Moduls.&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/VRAM|VRAM]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/LED-Encoder|LED-Encoder]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/Steuerung|Ablaufsteuerung]] ===&lt;br /&gt;
&lt;br /&gt;
=== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Hardware/BUI|Bussteuerung]] ===&lt;br /&gt;
&lt;br /&gt;
== [[Projekt:Hardware-Encoder für NeoPixel (WS2812)/Protokoll|Protokoll und Software]] ==&lt;/div&gt;</summary>
		<author><name>Fki</name></author>
	</entry>
</feed>