externe Live Titles

Was nützt einem die tollste Notification per Badge, Kachel oder Toast, wenn keiner hinschaut. Nun gut, man kann auch noch Sound abspielen um die Aufmerksamkeit des Benutzers auf sein Windows 8.1 Device zu lenken. Oder man kann sich ein USB Gadget auf den Schreibtisch stellen. In diesem Fall das Dream Cheeky USB LED Message Board.

usbppedv

Das Produkt

Man sollte sich von der Abbildung auf der Website nicht täuschen lassen. Das Display hat eine Auflösung von sagenhaften 21x7 Pixeln in nur laut Dokumentation 3 “Graustufen”. Die roten LED’s sind allerdings im Erscheinungsbild rechteckig angeordnet.

image

Das USB Led Board kommt in einem schwarzen Gehäuse, mit schmalem integrierten Standfuss. Die Abmessung des Leuchtbereiches sind rund 8x1,5 cm.

Installation braucht es keine, einfach mit dem integrierten 1 m USB Kabel einstecken und Betriebsbereit. Das USB Device erscheint dann als HID (Human Interface Device) im Gerätemanager.

Die Preisspanne liegt von 20-29 €.

Programmierung

Wie man ein HID Device mit der WInRT Api anprogrammiert folgt etwas später.  Faktisch schickt man Bit Sequenzen an das Device. Das LED Board wertet diese per Microcontroller aus und steuert die Matrix an. Die Anzeige erlischt nach 400ms. Das bedeutet, das man regelmäßig ein refresh durchführen muss. Nun gibt es nichts was man braucht, wie Zeichensatz oder Display Treiber. Muss alles selbst entwickelt werden. Die Dokumentation dazu ist einfach und kurz. Was länger dauert, ist einen Zeichensatz zu definieren und eine Umrechenlogik zu coden.

Ich habe mit Excel eine Matrix verfasst, x gemalt und eine einfache Hexformel hinterlegt. Um ein komplettes Display zu beschreiben müssen vier mal 9 Bytes gesendet werden. Byte 1 ist immer 0, Byte 2 die Helligkeit von 0-2. Byte 3 die Displayzeile (0,2,4,6) Byte 3 bis 5 stellen die erste Zeile dar. 6 bis 9 die Zweite Zeile. Dunkel ist 1 Hell ist 0.

Wer bist Du

In den seltensten Fällen gibt es bei einem USB Gimmick eine Developer Dokumentation für Windows RT.

Die wichtigsten vier Parameter sind Vendor ID, Product ID, Usage Page und Usage ID. Alles im Integer Bereich, aber üblicherweise als Hex verwendet. Das gratis Programm HIDTest liefert die nötigen Daten.

image

Wir wissen nun für das USB LED Messageboard

  • VendorID: 1D34
  • DeviceID: 0016
  • UsagePage: FF00
  • UsageID: 0001

Windows 8 (METRO) App und HID

Als nächstes wird mit Visual Studio 2013 eine Windows Store App angelegt. Um ein HID Gerät verwenden zu können muss man im Manifest die Rechte definieren. Da der default Visual Studio Editor für das package.appxmanifest  keine UI bietet, bleibt nur der Weg über den XML Editor um die Capability (Funktion) für ein HID Device zu erstellen.

   1:   <Capabilities>
   2:      <Capability Name="internetClient" />
   3:      <m2:DeviceCapability Name="humaninterfacedevice">
   4:        <m2:Device Id="vidpid:1D34 0013">
   5:          <m2:Function Type="usage:FF00 0001"/>
   6:        </m2:Device>
   7:      </m2:DeviceCapability>
   8:    </Capabilities>
   9:  </Package>

Visual Studio zeigt diese dann auch nicht an.

image

Beim ersten Start erhält der Benutzer einen Dialog, mit dem er die Nutzung des Gerätes durch die APP erlaubt.

image

Der Benutzer kann diese in den Settings über die Berechtigungen jederzeit verändern. Folglich muss der Programmiercode (VB.NET oder C#) bei jedem Aufruf dies prüfen.

image

Jetzt sind wir bereit, das Device zu initialisieren. Da es eine beliebige Anzahl von identen LED Lichtleisten in meinem Windows Computer geben kann, als Liste. Mit dem ersten Device wird einen Lese und Schreib Kommunikation aufgebaut. Da es nur Read oder ReadWrite gibt, die passende Option auch wenn nichts gelesen wird.

   1:  Private Async Sub MainPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
   2:          Dim deviceSelector = HidDevice.GetDeviceSelector(&HFF00, &H1, &H1D34, &H13)
   3:          Dim devices = Await DeviceInformation.FindAllAsync(deviceSelector)
   4:          Dim device = devices.Item(0)
   5:          devicehandler = Await HidDevice.FromIdAsync(device.Id, FileAccessMode.ReadWrite)
   6:          report = devicehandler.CreateOutputReport(0) 'nothing Manifest   
   7:  End Sub

Es existieren zwei Arten von Kommunikation mit dem HID Kanal. Der FeatureReport setzt das Gerät in einen bestimmten Zustand und der Outputreport löst eine konkrete Funktion aus. Der Parameter 0 wurde geraten und definiert die ReportID. Diesem USB Device ist das egal, andere fordern spezifische ID’s für eine spezifische Funktion.

Nun müssen nur noch Daten über den USB Draht. Wie vorhin ausgeführt sind das vier Kommandos mit selbst berechneten HEX Werten. Außerdem werden diese nur kurz angezeigt.

   1:   Public Async Function feedDisplay() As Task
   2:          Dim daten() As Byte = {&H0, &H2, &H0, &HEB, &H24, &H83, &HEA, &HB2, &H4F}
   3:          sendDaten(daten)
   4:          daten = {&H0, &H2, &H2, &HEA, &HB2, &H4F, &HEA, &HA4, &H8A}
   5:          sendDaten(daten)
   6:          daten = {&H0, &H2, &H4, &HEA, &HB6, &HDE, &HF6, &HB6, &HDE}
   7:          sendDaten(daten)
   8:          daten = {&H0, &H2, &H6, &HF7, &H26, &HD8, &HEF, &HFF, &HFF}
   9:          sendDaten(daten)
  10:          Await Task.Delay(400)
  11:  End Function

Das eigentliche senden kopiert das Array in den Report Buffer.  Die auskommentierte Zuweisung erzeugt keinen Laufzeitfehler, aber das Display leuchtet dann auch nicht.

   1:   Public Async Function sendDaten(daten() As Byte) As Task
   2:          'report.Data = daten.AsBuffer   klappt nicht
   3:          daten.CopyTo(0, report.Data, 0, daten.Length)
   4:          Await devicehandler.SendOutputReportAsync(report)
   5:   End Function

Am Ende noch die deklarierten VB.NET Variablen des WinRT Code und der Timer der alle 400 Millisekunden die Funktion aufruft die mit dem Display kommuniziert.

 Dim devicehandler As HidDevice
    Dim report As HidOutputReport
    Dim _timer As DispatcherTimer
    Private Async Function Button_Click(sender As Object, e As RoutedEventArgs) As Task
        _timer = New DispatcherTimer()
        _timer.Interval = New TimeSpan(0, 0, 0, 0, 400)
        AddHandler _timer.Tick, AddressOf feedDisplay
        _timer.Start()
End Function

Schwierigkeiten treten immer auf, wenn man die vier Parameter nicht kennt, vertauscht oder auch falsch anwendet. Es passiert dann schlicht nichts oder eine nichtssagende Exception.

Wie üblich der Hinweis, das dies ist ein Prototyp Beispiel.

Kommentare sind geschlossen