RGB Touch Matrix
von Conny G.
Es soll eine RGB Touch Matrix entwickelt werden, die z.B. für RGB-Touch-Tische eingesetzt werden kann. Beispiel für einen Touch-Tisch: http://www.it-gecko.de/100pixel-rgb-led-tisch-interaktiv-touch.html Dieser ist jedoch vom Hardware-Konzept sehr aufwändig gelöst, deshalb ist das Ziel des Projekts als Kern der Lösung zwei Dinge möglichst effizient zu lösen:
- die einzelnen RGB & Touch Pixel
- die Verbindung der Pixel auf Basis eines Busses
Effizient heisst: geringe Bauteilkosten, einfache Herstellung der Pixel und einfach Verkabelung, idealerweise nur ein Bus von 1-2 Leitungen (zzgl. GND).
Einleitung
Eine RGB-Touch-Matrix besteht aus folgenden Komponenten:
- Steuereinheit (Master), die die Touch-Werte auswertet und entsprechend RGB-Werte an die Pixel (Slave) zurücksendet
- eine größere Zahl (10x10 = 100 oder 10x20 = 200) RGB & Touch-Pixel, die jede Zelle beleuchten und für jede Zelle ein Touch-Sensing durchführen
- einem Bus zwischen diesen Komponenten
Bus
Die RGB-Touch-Pixel sollen über einen Bus verbunden werden. Das könnte entweder ein sternförmiger Bus sein oder eine Daisy-Chain wie die WS2811-Chips ihn bilden.
Ein Szenario mit Daisy Chain
Es sei eine CLK-Leitung vorausgesetzt, diese könnte jedoch auch implizit durch festes Timing gelöst werden (wie WS2811).
Ablauf:
Zunächst in Richtung MOSI, also Master sendet eine Chain von Daten an den ersten Slave.
- durch eine vorhergehende Pause ist der "LATCH & RESET"-Zustand eingetreten, d.h. alle Slaves wissen: wenn jetzt was kommt, dann ist das der Anfang
- Der Master sendet Bit für Bit an den ersten Slave
- der erste Slave nimmt sich die ersten 8x3=24 Bits und schreibt sie in seinen Zwischenspeicher für den RGB-Wert
- der erste Slave schreibt jedes weitere Bit direkt an den Ausgang ohne es weiter anzusehen
- dasselbe tut jeder weitere Node
- Pause: LATCH & RESET
Das ist die Richtung "RGB an Slaves", von den WS2811 bekannt.
Die Rückrichtung: es müsste also jetzt beim Master an MISO nach und nach, Bit für Bit die Chain an Daten aus den Slaves ankommen, also muss sich hier das ganze Spektakel umgekehrt abspielen. Während also die Bits in der "hin"-Richtung durchschieben, müssten ebenfalls die Bits in der Rück-Richtung durchshiften.
- Pause = LATCH & RESET setzt alle Slaves in Startzustand.
- wenn jetzt der erste Slave seine Daten bekommt, dann müsste er einfach gleichzeitig am Ausgang entweder seine oder die Daten des nächsten Node setzen
- er erhält also das erste Bit vom Master. Jetzt setzt er das erste Bit seiner Sensordaten
- nach den ersten 24 Bits (= seine RGB-Daten) sind seine Sensordaten durch (24 Bit Sensor-Daten)
- ab dann lauscht er auf seinem Eingang für Sensordaten vom nächsten Node und er reicht jedes Bit, das dort ankommt direkt an den Master weiter
- spannenderweise passiert es genau zum selben Zeitpunkt, dass er seine 24 Bit RGB-Daten durchhat und dann die weiteren Bits weiterreicht wenn er die Daten des nächsten Node für Rück weiterreichen soll, das läuft also 100% parallel
- der 2. Slave tut genau dasselbe
Nun kommen beim Hinsenden der RGBs genau der Strom an Sensordaten wieder zurück.
Vorteile:
- Die Datenübertragung dauert genauso lange wie es dauert die Daten seriell auf einen Bus zu schicken, da ist keine Zeitverzögerung
- es müssen vom Master keine Nodes addressiert und abgefragt werden, also maximal effizient
- für die bidirektionale Übertragung brauche ich keine Extrazeit, die Rückdaten kommen gleichzeitig
- es ist völlig egal, wieviele Slaves ich habe, solange die Gesamtübertragungrate noch die gewünschte Framerate hergibt. Danach kann man den Bus splitten und z.B. die ganze Kette in 2 Teile trennen und einfach 2x einspeisen, dann kann man mit selber Framerate doppelt soviele Slaves abdecken
- die Übertragung ist maximal Stör-un-anfällig, weil die Distanz zwischen den Clients kurz ist und das Signal jedesmal neu gesendet wird
- man braucht keine Tranceiver, die Attiny sind gleichzeitig die Tranceiver
- man braucht nur 2 Leitungen mit GND, wenn es mit implizitem Takt läuft
Idealerweise hängen alle Slaves einfach an einem Strang als einfachstmögliche Konstellation - einfache Verkabelung, keine mehrfach-Einspeisung in der Software. Für einen 10x10 RGB-Touch-Tisch sind das 100 Slaves. Jeder hat 24 Bits zu bekommen, ergibt 2400 Bits. Mal Framerate von 25 ergibt 25 x 2.400 Bits = 60.000 Bits pro Sekunde. Vorsichtshalber betreiben wir den Bus mit 100 kBit, dann sind wir nicht in einem technisch kritischen Bereich und brauchen nur einen Strang. (Die WS2811 machen 800 kBit, also das 8-fache). 250 kbit sollten noch ebenso einfach machbar sein, dann kann auch ein 10x20 Tisch in einem Strang betrieben werden
Das Protokoll wäre auch mit nur einer Leitung denkbar, wenn noch einbaut, dass man den Slaves mitteilt: jetzt gehört die Leitung Euch! Zum Beispiel: man sendet eine Chain von 0xffffff an alle (d.h. der RGB-Wert 0xffffff steht nicht zur Verfügung) und weiss: jetzt kommen als nächstes solange Bits zurück (Mode: MISO), bis mindestens eine Pause von xx Millisekunden da ist, dann ist der Mode wieder MOSI. Man müsste gezielt RGB-Frames dafür ausfallen lassen, d.h. es reduziert die Framerate ein wenig und die Abtastrate der Touches ist auf 5-10/Sekunde begrenzt (das ist ausreichend). Zum Beispiel: grundsätzliche Framerate 35 FPS, jeder 5. fällt aus für Touch-Sensing, dann habe ich 7x Touch pro Sekunde und 28 RGB-Frames. Ein Problem mit unregelmässiger Refreshrate gibt es hier nicht, da alle Slaves beim letzten RGB-Wert bleiben und weiterleuchten, nur die Aktualisierung "stockt" für eine 35stel Sekunde, das ist nicht wahrnehmbar.
RGB & Touch Pixel
Ein Pixel soll die Abmaße von 45x45mm bis maximal 50x50mm haben. Um Trennwände zwischen den Pixeln verwenden zu können, sollte auf die Maximalgröße verzichtet werden.
Für die Beleuchtung ist eine RGB vorgesehen, welche über drei verschiedene PWM-Kanäle angesteuert wird. Hierbei sollten mindestens 8bit oder besser 10bit Auflösungen angestrebt werden, um flüssige Übergänge zu erhalten.
Die Idee zur Erkennung ist eine Infrarot-LED zu verwenden, welche eine Wellenlänge von ca. 940-950nm bedient, um einen IR-Strahl auszusenden. Wenn sich ein Objekt über dem Pixel befindet, wird dieser Strahl reflektiert und eine Fotodiode (inkl. Arbeitsbereich 940-950nm) im Pixel erkennt diese Infrarotstrahlen. Dabei muss darauf geachtet werden, dass die IR-LED möglichst nach "oben" strahlt, um nicht direkt die Fotodiode zu beeinflussen. Somit kann die Fotodiode nur eine Reflektion erkennen. Diese Reflektion kann an der Diode mittels Spannungsabfall über einen ADC ausgewertet werden.
Um die Touch-Erkennung etwas zu "tunen" können Filter verwendet werden. Als Beispiel sei das Umgebungslicht kurz erwähnt. Denn je nach Helligkeit der Umgebung verändert sich die Charakteristik des Touch. Wenn also dies nicht berücksichtigt wird, könnte im zweifelsfall eine Erkennung bei Sonnenschein schwer werden. Ebenso kann die RGB im eigenen Pixel die Helligkeit entschieden verändert, sodass die Fotodiode andere Verhaltensweise vorweist. Um für die Filterung keine zusätzlichen Hardwarekomponenten und Kosten zu erhalten bietet sich eine Softwarelösung an. Beispielsweise könnte die Fotodiode (RGB aus) einen Wert messen und abspeichern. Nun hat man einen Parameter für die Umgebungshelligkeit. Anschließend kann eine Messung (RGB an) einen Parameter liefern wenn auch der Pixel von innen beleuchtet wird.
Bauteil-Kandidaten
- RGB-LED 21USD/1000
- IR-LED 21USD/1000
- IR-Photodiode 50USD/2000
- ATtiny841 ab 1 € (csd-electronics.de, guloshop.de)
Siehe auch
- Forumsthread Projektidee RGB Pixel mit Touch (aktueller Thread für "ein Pixel pro Platine")
- Forumsthread LED Tisch mit Berührungs-/Gegenstandserkennung (ursprünglicher Thread)
- Forumsthread Schwierigkeiten passenden Bus zu finden