Pluginprogrammierung DMXC2 Tut

Aus Deutsches DMXC-Wiki
Version vom 4. April 2013, 09:08 Uhr von Phaefele (Diskussion | Beiträge) (Tutorial 2 integriert, alles etwas anderst formatiert)
Plugin
LauflichtDemoPluginMini.jpg
Entwickler DMXControl Team
Aktuelle Version 2.9 (Dezember 2006)
Funktioniert mit ab 2.9
Programmier­sprache VB
Kontakt info@dmxcontrol.de
Homepage http://www.dmxcontrol.de

Hinweise

Für die Benutzung des Tutorialplugins benötigen Sie DMXControl 2.9 oder 2.10

Die Dll-Datei eines Plugins muß in das Unterverzeichnis "plugins" des DMXControl-Installationsverzeichnisses kopiert werden.
Hinweis: Neben den Plugins, die über eine definierte Schnittstelle mit DMXControl kommunizieren und aus technischer Sicht eine Zusatz-dll für DMXControl bilden, gibt es auch eine Reihe von Erweiterungstools, die andere Interfaces zur Kommunikation mit DMXControl verwenden (z.B. MIDI oder Terminal-Schnittstelle).

Der Sourcecode des Tutorialplugins

Sie können den Sourcecode des Demo-Plugins im File DMXC_Demo_Plugin.zip komplett ansehen.

Wer nur die dll benötigt, lädt sich dieses file herunter: TutorLL.dll

Alle APIs finden Sie hier: Pluginprogrammierung DMXC2

Tutorial Teil 1

Dieses Tutorial zeigt Ihnen die Erstellung und praktische Anwendung eines DMXC-PlugIns für eine einfache Lauflichtsteuerung.

Funktionalitätsspezifikation

Wir wollen ein Tool als PlugIn erstellen, dass die Erstellung von Szenen für ein 4-kanaliges Lauflicht sehr einfach über eine grafische Eingabe ermöglichen soll. Die Idee ist, dass jede Sekunde eine Szene ausgegeben wird, dabei sind 60 Szenen möglich und graphisch dargestellt. Die Abarbeitung läuft zyklisch, d.h. nach einer Minute (also Ablauf der 60 Szenen) wird mit der ersten Szenen wieder erneut begonnen.

Die GUI des Tutorial PlugIns


Die 4 Zeilen entsprechen den Kanälen eines Dimmerpacks. Die Spalten stellen die Szenen im Sekundentakt dar. Die gewünschte Szene kann durch Anklicken der Felder mit der linken Maustaste gesetzt werden, wobei in diesem Beispiel zur Vereinfachung jedem Kanal fest eine Farbe in der GUI zugewiesen wurde. Dabei wird mit dem linken Kommando-Button (der zwischen den Modes "Full" und "Dim" wechselt) gewählt, ob halbe oder volle Helligkeit verwendet wird. Ein gedimmter Wert erscheint in der Grafik nur halb gefüllt.

Die Startadresse des Dimmerpacks wird über die Plugin-Konfiguration eingegeben. Mit dem Startbutton wird das Senden der DMX-Werte gestartet. Gleichzeitig wird auch die Ausgabe der Werte an der Oberfläche simuliert, indem die aktuelle Szene in leuchtenden Farben dargestellt wird. Zusätzlich wird die aktuelle Szene durch eine rote Signal-LED dargestellt.


Das Beispiel ist bewußt einfach gehalten, um die Grundkonzepte der PlugIns zu demonstrieren und Sie nicht mit Programmierdetails zu verwirren. Somit wurden alle Funktionalitäten weggelassen, die reine Programmierarbeit sind und nichts mit der unmittelbaren PlugIn-Funktion zu tun haben. Sie können also z.B.

  • nicht die erstellten Lauflichtszenen abspeichern,
  • nicht den Dimmerkanälen über die GUI ihre eigentlichen Farben zuordnen und
  • nicht mehrere Felder gleichzeitig mit der Maus markieren.

Da der Quelltext des Tutorial-PlugIns verfügbar ist, können Sie aber dieses Plugin beliebig erweitern.

In einer zweiten Stufe wird das Plugin mit einen "Rückkanal" erweitert, d.h. es werde nicht nur DMX-Signale gesendet, sondern auch empfangen. Diese Werte können dann vom Plugin ermittelt und ausgewertet werden. Die Signale können durch parallele Ausgabe anderer Tools oder Plugins auftreten.

Das Grundgerüst des PlugIn-Programms

Der Programmcode besteht im wesentlichen aus drei Teilen, siehe auch Abb. 2.:

  • die GUI (hier: frmTutorMain)
  • der PlugIn-Logikmodule (DMXCTutorLL.bas)
  • die PlugIN driver Klasse (clsDMXCPlugin)

Entsprechend unserer Konvention haben wir natürlich auch ein Hilfefenster, damit andere Nutzer erste Hinweise zur Funktionalität erhalten können.

Abbildung 2 zeigt im Projektfenster alle Bestandteile unseres Plugins.


Entwicklung in VB6.JPG

Abbildung 2: Entwicklung in VB6

Die GUI

In diesem Abschnitt werden nur Grundzüge der Oberfläche dargestellt, da die eigentliche Basic-Programmierung als bekannt vorausgesetzt wird bzw. genügend Literatur dazu existiert. Mit Hilfe des GUI-Editors sind die Buttons und der Timer schnell erstellt (siehe Abbildung 2). Diesen Elementen sind über VB entsprechende callback-Routinen zugeordnet. (Hinweis: Dazu hat Microsoft GUI-Design-Regeln veröffentlicht.)

Ab DMX-Control V2.9 müssen Plugins, die eine graphische Oberfläche haben, in der GUI die Klasse IDMXCTool implementieren. Diese Klasse enthält Funktionen, die die Reaktion des Plugins auf Projektwechsel und die Änderung der Ansicht steuern.

Private Function IDMXCTool_AskToSaveProjectData() As Boolean
 'should the plugin be asked to save data or configuration when
 'the project is changed.
 'Debug.Print "[frmTutorMaim] IDMXCTool_AskToSaveProjectData()"
 IDMXCTool_AskToSaveProjectData = False
End Function

Private Sub IDMXCTool_ClearProjectData()
 'function is called, when the user makes a new project
 'msgbox ("[frmTutorMaim] IDMXCTool_ClearProjectData()")
End Sub

Private Sub IDMXCTool_LoadProjectData()
 'function is called, when the user loads an other project
 'MsgBox ("[frmTutorMaim] IDMXCTool_LoadProjectData()")
End Sub

Private Sub IDMXCTool_SaveProjectData()
 'function is called, when the user saves the project
 'MsgBox ("[frmTutorMaim] IDMXCTool_SaveProjectData()")
End Sub

Private Property Let IDMXCTool_ViewMode(ByVal RHS As DMXCTypeLib.View)
 'Property, which controls the ViewMode of the plugin (Edit-Mode or Execute-Mode)
 'Debug.Print "[frmTutorMaim] IDMXCTool_ViewMode"
 myViewmode = RHS
End Property


Die Grafik des Matrixfeldes wird zur Laufzeit erzeugt. Innerhalb des Matrixfeldes werden die Mauskoordinaten beim Klick in der Prozedur "Form_MouseDown" ausgewertet und die Nummer der zugehörigen LED-Zelle in der Prozedur "ComputeCellNumber" bestimmt. Alles weitere ist nur noch Zuordnen eines entsprechenden Status der LED-Zelle in Abhängigkeit vom ursprünglichen Status, z.B. LED_On wechselt immer bein Anklicken nach LED_Off.

Über die Plugin-Konfiguration wird die Startadresse des Dimmerpacks zugeordnet. Hier gehört es zum guten Stil, dass Sie jede Eingabe soweit wie möglich prüfen, um spätere Laufzeitfehler auszuschliessen. Sie sollten mindestens den Wertebereich und den Typ des Eingabefeldes prüfen.


Public Sub readTutorLLConfigurationData()
' read only configuration data - start address
' no special form is required for this demo plugin
Dim AddressText As String
Dim ok As Boolean
While Not ok
AddressText = InputBox$("Start Address:", "Demo Plugin Configuration")
   ok = True
   'make plausibility test
   If IsNumeric(AddressText) = False Then
     MsgBox Prompt:="Please enter an integer for start address!"
     ok = False
   End If
    If AddressText > 252 Then
     MsgBox Prompt:="Please insert a value lower than 252"
     ok = False
   End If
Wend
   For i = 0 To 3
      mDimmerAddr = Int(AddressText)
      If Not mHelper.DMXC_Channel_IsDimmer(mDimmerAddr + i) Then
          MsgBox ("Warning : Channel " & mDimmerAddr + i & " not dimmable")
      End If  
   Next
End Sub

In der For-Schleife wird zusätzlich geprüft, ob die 4 Kanäle auch verwendet werden und die Helligkeit regeln können (is_Dimmer), also wirklich zu einem Dimmerpack gehören (der mHelper-Mechanismus wird im nächsten Kapitel erklärt). Später werden über die DMXC_PluginHelper-class weitere Methoden verfügbar sein, die zusätzliche Plausibilitätstests erlauben.

Der Start-Button, der Stop-Button und das Timer Control interagieren untereinander über das Setzen des "Enabled"-Attributes des Timers ("timLLTimer"). Der Timer ist auf die Reaktionszeit von 1000ms = 1 sec. gesetzt und weckt nach Ablauf dieser Zeit seine zugehörige Routine timLLTimer_Timer().

Mit dem linken Kommando-Button wird lediglich der Editiermodus über die globale Variable mblnHalfDensity" umgeschaltet. Je nach Wert, der bis zur nächsten Ändereung permanent eingestellt bleibt, bekommen die Matrixfelder beim Anklicken den Zustandswert LED_on oder LED_dimmed. Sie sehen also, dass sich dieser Modul wirklich weitestgehend nur mit dem Verhalten der Oberfläche beschäftigt. Hier erfolgt keine direkte Steuerung der DMX Signale.

Tipps: - Redraw-Eigenschaft des Fensters auf True setzen, sonst verschwinden Teile der laufzeit-generierten Oberfläche, wenn ein anderes Fenster überlappt

Der DMX Logikmodul

Dieser Modul dient dazu, die wesentlichen Algorithmen zur DMX Steuerung zu implementieren. Unser einfaches Tutorial-Beispiel ist diesbezüglich vom Umfang etwas eingeschränkt, aber bei funktionell hochwertigen PlugIns werden sich viele Funktionen wie Filterung, Korrelation, Auswertung und algorithmische Berechnungen finden.

Außerdem gehören in diesen Modul alle Geräte-spezifischen Operationen. Der Modul stellt eine Referenz zum eigentlichen DMXC-Interface mit der Klasse mHelper zur Verfügung.

Public mHelper

Diese Referenz wird im Interfacemodul clsDMXCPlugIn initialisiert (und muss beim Terminieren auch wieder aufgelöst werden!).

Zwecks Implementierung der DMX Logik wird hier auch die "DMXSignalmatrix" , also das eigentliche PlugIn-spezifische Szenenrepository gehalten. Dazu werden im Array "gLED_matrix" die Beschreibungen der Szenen gespeichert. Sie werden in Ihrem PlugIn analoge Mittel benötigen.

Public Enum LED_status
   LED_off       'LED cell is off - zero signal for this scene
   LED_dimmed    'LED cell is dimmed - any mid value for this scene
   LED_on        'LED cell is on - maximum signal for this scene
End Enum
Public LED_matrix(1To60, 1To4)As LED_status 'storage of LED statis

Unser DMX-Logigmodul muss nun für die LED-Status-Werte die geeigneten DMX-Werte berechnen. Natürlich ist das in unserem Fall kein Problem, weil wir hier mit einer fixen Zuordnung auskommen, z.B.

LED_off  ->   0
LED_dim ->  128
LED_on  ->  255

Aber man kann sich leicht kompliziertere Beispiele mit komplizierten Algorithmen ausdenken, in denen man wirklich Intelligenz benötigt, insbesondere wenn man zusätzlich empfangene Signale auswerten will.

Wir stellen in diesem Modul eine TutorLLSetDMXValue-Routine bereit, die vom Timer gerufen wird, "wenn es was zu tun gibt":


Public Sub TutorLLSetDMXvalue(ByVal scenenb As Integer)
Dim i As Integer
Dim dmxv As Long

Call mHelper.MyStream.UserInteraction   ' new for DMXControl 2.9, 
                                        ' enables the plugin to send values, independent
                                        ' from the active program module
For i = 1 To 4
   Select Case gLED_matrix(sceenb, i)
   Case LED_off
       dmxv = 0
   Case LED_dimmed
       dmxv = 128
   Case LED_on
       dmxv = 255
   End Select

   Call mHelper.MyStream.SetChannel(mDimmerAddr + i - 1, dmxv, True) ' sends the DMX-values to             
                                                                     ' DMXControl
Next
End Sub

Diese Prozedur berechnet für alle 4 Kanäle die aktuell auszugebenden DMX-Werte und sendet sie mit der SetChannel-Methode.

Bevor ein Plugin DMX-Werte an DMXControl senden kann, muss dieses noch zum gerade aktive Modul erklärt werden. Dies geschieht mit dem Aufruf der UserInteraction-Methode. Dies hängt zusammen mit dem Wegfall der Prioritäten in DMXControl V2.9, wo das gerade vom Anwender benutzte Modul jetzt die Kontrolle hat.

Call mHelper.MyStream.UserInteraction

Beim Senden der DMX-Werte könnte eine Optimierung durchgeführt werden. Eigentlich müssten die Werte nur dann neu gesendet werden, wenn sie sich verändert haben. Dies kann natürlich die DMXLogik im Plugin einfach überprüfen.

Die Kernfunktion hierbei ist die SetChannel Methode der Klasse mHelper:

SetChannel(Channel As Long, Value As Long, IgnoreChange As Boolean)

Bitte achten Sie hier auf die erforderlichen Parametertypen (Long), da es sonst zu Laufzeitfehlern kommt.

Der erste und zweite Parameter "Channel" und "Value" sind selbsterklärend.

Der dritte Parameter "IgnoreChange" hat Einfluß auf die Änderungsmarkierungen bei der Szenenspeicherung in DMXControl. Dort wird im Fenster "Speicherung einer Szene" bekanntlich angezeigt, welche Werte sich geändert haben. Mit dem Parameterwert „True“ wird dieses Verhalten ignoriert, d.h. es wird so getan, als ob es eigentlich keine Änderung gegeben hätte.

Die DMXControl Interface Klasse

Hier erfolgt die eigentliche Einbindung des PlugIns in DMXControl, d.h. es werden verschieden Methoden zur Aktivierung, namentliche Bekanntmachung, Konfiguration und Deaktivierung ausimplementiert. Die Interfaces sind in in zwei Modulen definiert, daher importieren wir diese mit

Implements IDMXCPlugin
Implements IDMXCModule

Die benötigten Typdefinitionen befinden sich in DMXCTypeLib.dll. Daher muss dieser Modul sowohl im Programmverzeichnis von DMXControl als auch in Ihrer VB6-Umgebung bekannt gemacht werden. Dazu müssen Sie in VB6 unter dem Projektmenü den Punkt "References" aufrufen und die Verknüpfung zu DMXCTypeLib.dll herstellen. Man kann sich z.B. eine lokale Kopie im VB6-Arbeitsverzeichnis erstellen.

Die erforderlichen Implementierungsaufgaben in diesem Modul werden am Tutorialbeispiel sehr deutlich. Die GET-Methode IDMXCModule_ModuleInfo liefert DMXControl Informationen über das neue Plugin, z.B. Daten die in den Menüs oder Dialogen eingeblendet werden. Die meisten Attributnamen sind selbsterklärend, bitte paasen Sie die Attributwerte entsprechend an.

Private Property Get IDMXCModule_ModuleInfo() As DMXCTypeLib.Type_Module_Info
 Set IDMXCModule_ModuleInfo = New Type_Module_Info: With IDMXCModule_ModuleInfo
 .Guid = "{b61b4c42-17ed-11da-94c3-00e08161165f}"  'adapt this line with unique GUID
 .Name = "Lauflicht Demo Plugin"            
 .Description = "GUI für Lauflichter"       
 .Author = "Frank Burghardt"                
 .Experimental = True
 .ProvidesToolWindow = True
 .Category = CAT_Control
 .FormName = "frmTutorMain"                      
 Set .Frm = frmTutorMain
 .ProvidesCommand = False
 .ProvidesSceneType = False
 .UsesProvidedOutput = True
 .UsesMessaging = True
 With .Messages
  .Add MSG_Channel_Set
  .Add MSG_Channel_Send
 End With
End With
End Property

Hier noch einige zusätzliche Erklärungen. Der GUID (Global Unique Identifier) liefert eine eindeutige Modul-Id. Die GUID können sie z.B. von http://www.guidgen.com/Index.aspx beziehen. Die Attribute ProvidesCommand / ProvidesScenetype sind für zukünftige Erweiterungen vorgesehen, wenn DMXControl neue dynamische Befehle und Szenetypen unterstützen wird. Unter benutzten Messagetypen müssen Sie vereinbaren, auf welche Nachrichten das Plugin reagieren soll. Bisher wird das Senden von DMXSignalen ("MSG_Channel_Send") und das Empfangen ("MSG_Channel_Set") unterstützt.

Weiterhin müssen folgende Methoden angepasst werden:

  • IDMXCPlugin_Enable() - Aktion beim Aufruf des Plugins (aus der Menüliste)
  • IDMXCPlugin_Disable() - Aktionen beim Deaktivieren des Plugins (Schließen des Fensters)
  • PlugInName 'Liefert den Namen des Plugins zurück, der im Pluginmanager angezeigt wird

Mit der Methode Configure() kann man einstellen, ob ein Konfigurationsdialog/GUI existiert und welche Aktion dazu auszuführen ist. In userem Beispiel wird die oben erwähnte Funktion Call frmTutorMain.readTutorLLConfigurationData aufgerufen.


IDMXCPlugin_Init definiert allgemeine einmalige Aktionen beim Laden des Plugins, z.B. Setzen der Referenzen zum DMXControl-Interface-Objekt. (Das Plugin ist dann aber noch nicht aktiv, sondern erst mit dem Aufruf aus der Menüliste) Hier können Sie normalerweise den vorgegebenen Code komplett übernehmen. Die Methode liefert drei Werte:

  • Name der Aufrufenden Applikation, wird bei Registryeinträgen benutzt
  • Mein Dateiname, wird vom Caller geliefert (Dateiname der aktuellen Instanz, wichtig wenn es mehrere Kopien eines Plugins gibt, damit jedes seine eigenen Einstellungen speichern kann. Zukünftig werden aber Funktionen zum Lesen/Schreiben von Registry-Einstellungen in der HelperClass exportiert werden, die dann gleich den richtigen Pfad verwenden) und schließlich
  • als wichtigste Information die Referenz mHelper auf die DMXCPluginHelper-Klasse, die sämtliche benötigten Methoden im Logikmodule bereitstellt.

IDMXCPlugin_Term() wird immer aufgerufen, wenn DMXC beendet wird, hier können Sie z.B. geteilte Resourcen mit anderen Tools freigeben.

Die Funktion IDMXCPlugin_MessageHandle legt fest, was das Plugin tut, wenn eine ( DMXControl-Nachricht) eintrifft, z.B. zur Übermittlung eines DMX-Signals, also dass irgendein Kanal seinen Wert geändert hat. Dies ist sozusagen die “call back”-Funktion von DMXControl, um dem Plugin die Wertänderung mitzuteilen. Man beachte, dass diverse Messagetypen existieren.

In unserem Falle werden nur die "Message_Channel_Send"-Nachrichten ausgewertet (falls der Receivemode) aktiviert ist) und die Methode TutorLLGetDMXValue aus dem Logikmodul aufgerufen. Letztere Methode entscheidet dann, ob die Wertänderungen Auswirkung auf die GUI hat und initiiert gegebenenfalls entsprechende Aktivitäten.

Private Function IDMXCPlugin_MessageHandle(Msg As DMXCTypeLib.MSGs, Arg1 As Long, Arg2 As Long) As Long
Select Case Msg
 Case MSG_Channel_Send
  If gblnReceiveMode Then
   TutorLLGetDMXvalue Arg1, Arg2
  End If
End Select
End Function


Die Erzeugung der DLL

Eine Übersicht über mögliche Entwicklungsumgebungen enthält der Artikel Plugin_Entwicklungsumgebung. In diesem Tutorial bleiben wir bei VB6.

Zu Beginn bietet es sich an, das PlugIn als normales Projekt in VB6 zu entwickeln und somit "offline (von DMXControl)" die GUI und die DMXLogik zu testen.

Spätestens mit der Einbindung der SetChannel-Methode hat man ein Problem, weil man natürlich ohne DMXControl kein Object von DMXCPluginHelper zur Verfügung hat. Also müssen wir nachdem das PlugIn eine gewisse Reife hat, nun die dll erzeugen.

Als erstes müssen wir der Entwicklungsumgebung mitteilen, dass wir eine dll erzeugen wollen. Dies passiert mit folgenden Einstellungen: (hier das Beispiel aus Visual Basic 6)


Plugin Projekt Konfiguration.JPG

Abbildung 3: Projekt Konfiguration


Weiterhin sollten angegeben sein:

  • im Registerblatt "Compile": Compile to native code
  • im Registerblatt "Component": No Compatibility oder Project Compatibility

Die Eigenschaft "Instancing" von clsDMXCPlugin muss unbedingt auf "5 - MultiUse" stehen, sonst wird keine dll erzeugt.

Nun muss man nur noch darauf achten, dass die Compilierung jetzt über das Datei-Menü gestartet wird: Dort gibt es jetzt den Eintrag "Make TutorLL.dll".


Bitte beim Speichern auf die Namenskonvention achten und den Dateinamen der dll auf "TutorLL.dll" ändern (was dauerhaft gespeichert wird).


Plugin Make Projekt.jpg

Abbildung 4: Make Projekt

Tipps: Weitere Fallen, die man beachten muss: - Man muss unbedingt ein Sub Main() vereinbart haben (kann leer sein)

Es ist theoretisch auch möglich, zum Testen des Plugins im Debugger_mode zu arbeiten. Dazu geben Sie in der Registerkarte "Debugging" unter der Option "Start Program" den Pfad von DMXControl.exe an und fügen den Kommandoparameter

-debugdll:TutorLL.dll

an (bzw. natürlich den Namen der neuen dll)

Plugin debug dll.jpg

Hinweis: Die Meldung "Not registered DLL xxx.dll for debug purposes!" ist keine Fehlermeldung und sollte nicht vom Debuggen abschrecken. Man sollte auch dringend vermeiden, alte Versionen des Plugins (z.B. ) unter einem anderen Namen im Plugin-Verzeichnis zu haben. In der Praxis gibt es aber dennoch leider manchmal Probleme mit externen Referenzen, so dass der Debug-Mode nicht immer funktioniert.


Die Integration in DMXControl

Nachdem die dll erzeugt wurde, muss sie nun noch in das Unterverzeichnis „plugins“ von DMXControl kopiert werden (Wenn es noch nicht vorhanden ist, muss das Unterverzeichnis erst händisch erstellt werden: C:\Programme\DMXControl\plugins ).

Nach dem Aufruf von DMXControl können Sie die erfolgreiche Einbindung überprüfen, indem Sie die Einträge unter Konfiguration->Plugins... überprüfen.

Pluginverwaltung.JPG

Abbildung 5: Erfolgreich erkanntes Plugin "Tutorial Lauflicht PlugIn"

Nachdem das Plugin aktiviert wurde, erscheint es in DMXControl im Menü "Fenster" und kann über den entsprechenden Menüpunkt aufgerufen werden (Falls das Plugin nicht im Menü "Fenster" erscheint, dann muss wahrscheinlich in DMXControl im Menü "Konfiguration" noch der Punkt "experimentelle Programmteile anzeigen" aktiviert werden).

Die erfolgreiche Arbeitsweise unseres Plugins kann man z.B. auch im Tool "Kanalübersicht" überprüfen, wo die ausgegebenen Lauflichtwerte angezeigt werden.

Plugin in DMXC de Umgebung.jpg

Abbildung 6: Das Tutorial plugin arbeitet in der DMXC-Umgebung

Die Konfiguration des Plugins

Spezielle Parameter, die nicht ständig an der Oberfläche benötigt werden, sollten über die Plugin-Konfiguration administriert werden. Dieses wird über den Button "Gewähltes Plugin konfigurieren" aufgerufen. In unserem Falle erscheint ein einfaches Input-Fenster für die Dimmerpack-Startadresse.

Hier kann man sich beliebige Erweiterungen vorstellen, z.B. für die Konfiguration von Signalpegel und Farbe.

Tutorial Teil 2

In diesem Teil des Tutorials wird auch die Rückrichtung realisiert, d.h. auch die von DMXControl gesendeten DMX Werte können empfangen werden.

Auch hier gilt, dass das Plugin in die gleichen drei Teile dekomponiert werden sollte, d.h. wir unterscheiden wieder in

  • GUI
  • Logik des Plugins
  • Interface zu DMXControl.

Diese werden im folgenden beispielhaft beschrieben. Dazu wird unser Plugin aus dem ersten Teil um den Empfang von DMX-Signalen erweitert. Diese Signale, die z.B. vom Submaster oder Sound Analyzer für die 4 Dimmerkanäle ausgelöst werden können, werden dann im GUI-Matrixfeld in einer Art Lichtorgel visualisiert. Wie schon im ersten Teil wird hier im Sinne der Einfachheit und Übersichtlichkeit die einfachste Variante demonstriert, indem je nach Signalwert die Zellen eines Kanals in drei Stufen gefärbt werden. Natürlich können Sie dieses Beispiel erweitern, indem z.B. RGB-Werte zur Darstellung einzelner Kanäle oder der gesamten Matrix verwendet werden.

GUI Administration

In der Plugin-Oberfläche gibt es nur eine Änderung, ein zusätzlicher Kommando-Button wurde eingeführt, der als Umschaltbutton zwischen Sendemode (unveränderter erster Teil des Tutorials) und Empfangsmode (dieser Teil) fungiert. Das Tutorialbeispiel ist zur besseren Klarheit so konstruiert, dass entweder Signale gesendet oder empfangen werden können (Umschalten mit dem Send/Receive-Button). Diese Einschränkung ist nicht zwingend. Sie können also in Ihrem Plugin beide Modes kombinieren.

Den anderen Pluginteilen wird über die Variable "gblnReceiveMode" mitgeteilt, welcher Mode gerade aktiviert ist.

Tutorial Plugin output.jpg

Abbildung 7: DMX-Receive Mode für das Plugin


Interface zu DMXControl

Die Methode "IDMXCPlugin_MessageHandle" im Modul clsDMXCPlugIn wird von DMXControl jedesmal aufgerufen, wenn ein DMX-Kanal einen neuen Wert erhält. Da dieser Modul nur das Interface zu DMXControl implementieren sollte, wird hier lediglich anhand des Wertes der Variable "gblnReceiveMode" geprüft, ob die empfangenen Signale an die Logik weitergeleitet werden sollen. Im Falle des Sendemodus werden die Signale einfach ignoriert, ansonsten wird die Routine "TutorLLGetDMXValue" im Modul DMXCTutorLL aufgerufen, weil dort die Logik implementiert ist, was mit dem empfangenen Signal zu geschehen hat. Natürlich können Sie in Ihrem Plugin die Signale feiner filtern oder auch andere Messages empfangen.

Private Function IDMXCPlugin_MessageHandle(Msg As DMXCTypeLib.MSGs, Arg1 As Long, Arg2 As Long) As Long
 Select Case Msg
  Case MSG_Channel_Send
   If gblnReceiveMode Then
    TutorLLGetDMXvalue Arg1, Arg2
   End If
 End Select
End Function


Logik

Im Modul DMXCTutorLL (Routine "TutorLLGetDMXValue") müssen also alle Operationen gestartet werden, die sich mit der Auswertung und Analyse der emfangenen Werte beschäftigen.


Public Sub TutorLLGetDMXvalue(ByVal Ch As Integer, ByVal Value As Long)
Dim i, Channel As Integer
If Ch >= mDimmerAddr And Ch < mDimmerAddr + 4 Then
   Channel = Ch - mDimmerAddr + 1 'map to 1..4
   If Value >= 128 Then
       If mcurDMXValues(Channel) < 128 Then
           Call frmTutorMain.enlightChannel(Channel, LED_on)
       End If
       mcurDMXValues(Channel) = Value
       Exit Sub 'ready
   Else
       If Value >= 25 Then
           If mcurDMXValues(Channel) > 128 Or mcurDMXValues(Channel) < 25 Then
               Call frmTutorMain.enlightChannel(Channel, LED_off) 'reset cell
               Call frmTutorMain.enlightChannel(Channel, LED_dimmed)
           End If
       mcurDMXValues(Channel) = Value
       Exit Sub 'ready
       Else
           ' Value < 25
           If mcurDMXValues(Channel) >= 25 Then
               Call frmTutorMain.enlightChannel(Channel, LED_off)
           End If
           mcurDMXValues(Channel) = Value
       End If
   End If
End If
End Sub


Die Logik ist in unserem Beispiel wieder extrem einfach. Das empfangene Signal wird auf 3 Zustände abgebildet:

Wert 0-25  		-> entsprechender Kanal wird logisch auf "aus" gesetzt
Wert 26-127      	-> entsprechender Kanal wird logisch auf "dimmed" gesetzt
Wert 128-255    	-> entsprechender Kanal wird logisch auf "on" gesetzt


Daher prüft diese Prozedur, in welcher der drei Kategorien der aktuellen Wert liegt. In unserem Beispiel ist es erneut nicht nötig, dem GUI Modul einen DMX-Wert zu übergeben, sondern es werden wiederum die drei bekannten Zustände verwendet. Dieser berechnete Zustand wird dem GUI-Teil mitgeteilt, indem die Routine "enligthChannel" gerufen wird.


Es gibt einer zweiten Weg. DMX-Werte zu empfangen, nämlich durch explizite Abfrage, z.B.

dmxValue = mHelper.ChannelGetValue(currentChannel) 

Ursprünglich war diese Methode dazu gedacht, bei der Initialisierung des Plugins die aktuellen Werte zu übernehmen.Es gibt aber auch Anwendungsfälle, wo das zielgerichtete Abfragen ("polling") viel effektiver und weniger Performance-fressend ist, als ständig auf alle "push"-Werte von DMXControl zu reagieren.


GUI Anzeige

Schliesslich bleibt die Aufgabe, anhand des übermittelten Zustandes eine Visualisierung in der Matrix vorzunehmen. Hierzu werden die bereits bekannten Methoden "colorizeCell" wiederverwendet.

Public Sub enlightChannel(ByVal ch As Integer, ByVal Status As LED_status)
Dim i As Integer
       For i = 1 To 60
           LED_matrix(i, ch) = Status
           Call ColorizeCurrentCell(i, ch, True)
       Next
End Sub

Auch für dieses Tutorialbeispiel gilt, dass vieles optimierter programmiert werden könnte, z.B. Änderung der Zellfarbe nur, wenn sich wirklich der Wert ändern. Aber das würde die Verständlichkeit des Beispiels verringern.

Integration in DMXControl

Da sich an der Modul-Struktur des Plugins nichts geändert hat, gilt hier alles, was im Kapitel 3.6 und 3.7 (Plugin Tutorial 1) beschrieben wurde. Vergessen Sie beim Ausprobieren nicht, die Startadresse des Dimmerpacks einzustellen und den "Receive"-Mode zu aktivieren.

Mit Hilfe des Submasters können Sie die Änderung der DMX-Werte auf den Dimmerpack-Kanälen vornehmen und dann die visuelle Anzeige in unserem Plugin bestaunen. Es ergibt sich auch tatsächlich ein Lichtorgel-Effekt bei der Benutzung des Sound Analyzers.

Wir wünschen Ihnen nun viel Spaß und Erfolg bei der Erstellung Ihres eigenen Plugins.


DMXControl Pluginschnittstellen Test

DMXC-Plugin-Tutorial.jpg

  • Datum/Zeit: Oktober 2008
  • Autor: Frank Brüggemann
  • Status: für DMXControl 2.10 (wird fortlaufend aktualisiert)
  • Dateien:
  • Beschreibung: Dieses Plugin demonstriert alle Funktionen der Pluginschnittstelle