DALI Slave Code Beispiel

  • Ich wollte mal ein bisschen experimentieren . . . :/


    Hat / Kennt jemand funktionierende Code Beispiele für einen DALI Slave?

    Ich habe schon mit einigen aus den APP-Notes diverser Hersteller rumgespielt aber entweder sind mir die zu komplex oder ich kriege sie erst gar nicht lauffähig bzw. die Programme sind total verbugt.


    Minimal:

    Broadcast Ein / Aus


    Optional

    Dimmung natürlich ;)

    Adressierung

    mehrere Kanäle


    Am liebsten was direkt für µC Atmel Atmega.

  • Habe das Thema mal verschoben, siehe Beschreibung dieses Forums, hier geht‘s um fertige Sachen, keine Fragen....


    was für ein Interface nutzt Du denn...? Seriell auf DALI, so Tridonic oder Lunatone o.ä.?


    wir steuern in der Arbeit oft DALI-Leuchten mit AMX-Controllern an, eben über solche Gateways...


    Das Protokoll auf dem Bus ist eigentlich recht simpel, zwei Bytes, Adresse und Wert...


    irgendsowas mit LSB gesetzt ist Gruppenadresse, nicht gesetzt Dimmwert o.ä. - ich kann mal in einer unserer Programmierungen nachschauen...

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • also hier auf Seite 5 die Beschreibung des Protokolls....


    sieht vielleicht kompliziert aus, aber bei uns in der Programmierung ist das ganz easy:


    //Befehls-Strings für Button-Nr.

    CHAR DALI_COMMAND[][] = {

    {$81,$00},{$81,$01},{$81,$02},{$81,$05},{$81,$06}, //1...5 - Spots Leinwand Off/Up/Down/Max/Min

    {$83,$00},{$83,$01},{$83,$02},{$83,$05},{$83,$06}, //6...10 - Gr. Raum KW Off/Up/Down/Max/Min

    {$85,$00},{$85,$01},{$85,$02},{$85,$05},{$85,$06}, //11...15 - Gr. Raum WW Off/Up/Down/Max/Min

    {$87,$00},{$87,$01},{$87,$02},{$87,$05},{$87,$06}, //16...20 - Kl. Raum KW Off/Up/Down/Max/Min

    {$89,$00},{$89,$01},{$89,$02},{$89,$05},{$89,$06}, //21...25 - Kl. Raum WW Off/Up/Down/Max/Min

    {$8B,$00},{$8B,$01},{$8B,$02},{$8B,$05},{$8B,$06}, //26...30 - Gr. Raum Insg. Off/Up/Down/Max/Min

    {$8D,$00},{$8D,$01},{$8D,$02},{$8D,$05},{$8D,$06} //31...35 - Kl. Raum Insg. Off/Up/Down/Max/Min

    }


    CHAR DALI_ADRESS[] = {$80,$82,$84,$86,$88,$8A,$8C}


    d.H.: "ungerade" Adressen ($81, etc.) sind so Sachen wie ON/OFF/UP/DOWN etc. (also was man z.B. über so Taster dimmt, so lange man drückt wird es heller, etc.)


    "gerade" Adressen ($80, etc.) sind direkte Dimmwerte, also $80,$xx setzt Kreis 1 auf Wert xx. Adressen unter $80 sind "specials", auch die Werte gehen normal nicht bis 0 runter. Muss man ggfs. je nach Aktor rumprobieren


    Je nach Gateway reicht es, diese zwei Bytes hin zu schicken (also z.B. $80,$FE, um Kreis 1 auf Maximalwert zu setzen), oder man muss davor noch ein herstellerspezifisches "Kommando-Byte" (Siehe PDF) schicken und danach ne Checksumme...

    Dateien

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • P.S.: Ich rede hier vom ansteuern fertig konfigurierter Aktoren. Diese zu konfigurieren ist wohl per Atmel-µC nicht so pralle. Dafür gibt es (die arbeitet dann mit entsprechenden Gateways zusammen) z.B. die SW "Master Configurator" https://www.tridonic.com/com/d…re-masterconfigurator.asp

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • Nur mal so aus Neugier, haben die Infos geholfen, oder war das zu sehr Kauderwelsch...? :-D


    Ich habe hier übrigens auch noch was Interessantes gefunden: https://www.mouser.de/applicat…ng-digitally-addressable/


    Also wenn Du das eh' mit nem Mikrocontroller ansteuern willst, kannst Du Dir auch den Aufwand mit fertigem RS-232-Interface und dann TTL/RS-232-Pegelkonverter am µC sparen, und gleich die dort abgebildete Schaltung an den ATMega klöppeln... ;-)

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • Die Hardware ist nicht das Problem, das läuft.


    Allerdings verzweifel ich an der Software <X

    Senden kriege ich ja noch hin - ist aber sekundär - aber empfangen ist zu hoch für mich.

    Bin halt programmiertechnisch echt aus der Übung =O


    Sollte halt wenn es irgendwie geht ein Dali-Slave werden oder wie du schreibst ein "Aktor".

  • Ah, sorry, das hatte ich falsch verstanden, dachte, Du hast Slaves und willst die ansteuern...


    programmierst Du in C oder Assembler...?

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • Eigentlich konnte ich mal Assembler besser als C . . .


    Aber mittlerweile bin ich so was von aus der Übung . . . =O


    Einfache Sachen verstehe ich in beiden Sprachen, Assembler wird schneller unübersichtlich und in C stehe ich mit Arrays und Pointern auf Kriegsfuß.

  • Hm, die Erklärung der Empfangsroutine und das Codebeispiel auf der verlinkten Seite hilft auch nicht weiter...? Pointer usw. brauchst Du da ja gar nicht.


    Ist zwar für PIC, aber das Prinzip bei ATMega das selbe: Eingehendes Signal löst einen Status change Interrupt aus, in diesem wird ein Timer gestartet. Wenn der abläuft (Timer Interrupt) wird geguckt, ob die Leitung high oder low ist...


    Ich programmiere zwar inder Arbeit mittlerweile recht viel in C, aber bei µC immer noch nicht geschafft... wenn Du alles in asm machen willst, könnte ich mal gucken, die Empfangsroutine zu basteln... aber erst am WE, bin jetzt dann paar Tage auf Montage unterwegs...

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!

  • OK, ich geb's zu, die Erklärung auf der Seite ist tatsächlich bisschen verwirrend... :-D


    Im Codebeispiel, mit diesem Switch_Case, da steht bei "Start" gar nix drin, und der Case "Data" fehlt dann (wobei das das selbe Prinzip wie bei "Adress" ist, nur dass ein anderes Byte befüllt wird...


    Das hier:



    ist auch bisschen verwirrend, das erste Bit kann da gar nicht ausgelesen werden, weil da noch gar kein Timer läuft...


    Besser sieht man das hier, dafür gibt's ja das Startbit:




    Die erste Flanke startet den Empfänger - da passiert erst mal nix, außer dass Du ein Flag setzt "jetzt geht's los". (Das wäre dann der Case "Start", für den im Code-Beispiel nix drin steht).


    Bei der nächsten Flanke wird dann der Timer gestartet, der für 3/4 der Bitzeit läuft. Wichtig: während der Timer läuft, wird der Pin change Interrupt deaktiviert, weil ja während der Laufzeit des Timers wieder eine Flanke auftreten kann, die aber nicht relevant ist für's Timing.


    Wenn der Timer abgelaufen ist, wird nachgeschaut, ist die Leitung high oder low, und das entsprechende Bit im entsprechenden Byte gesetzt. Und der Pin Change Interrupt wieder aktiviert für das nächste Bit.


    auf die Art 2x 8 Bits einlesen und in zwei Bytes schreiben (Bit setzen und Shiften) - kann man ja statt diesem Swith Case (also insb. in asm, da gibt's sowas ja nicht) mit nem Zähler machen, 0 heißt warten, 1 heißt Startbit ist empfangen, 2-9 Adress-Byte beschreiben, 10-17 Daten-Byte beschreiben.


    Auf die zwei Stopp-Bits kann man dann sch***, oder halt Timer noch zwei mal starten und schauen, ob die Leitung wirklich auf idle ist... bzw. einmal läuft der eh' noch "nach", weil er beim letzten Bit ja noch mal gestartet wird... also ein Stop-Bit kann man auf jeden Fall ohne Aufwand auswerten.


    Dann Flag setzen für "Frame empfangen", und die zwei Bytes in der Main Loop auswerten: Bin ich angesprochen (Adresse)? und wenn ja, was soll ich machen (Data)? - und den Zähler natürlich auf 0, für den nächsten Frame... je nach Geschmack noch Rückmeldung ausgeben, oder halt bleiben lassen, wenn nicht nötig...


    Im Prinzip also zwei ISRs, die folgendes machen:


    Pin Change: Je nach Zählerstand diesen nur weiter zählen (beim Startbit), oder zusätzlich Pin Change Interrupt deaktivieren und Timer starten


    Timer Interrupt: nachschauen, ob high oder low, je nach Zählerstand entsprechendes Bit im entsprechenden Byte setzen, Timer deaktivieren, Pin Change Interrupt wieder aktivieren. Wenn alle Bits empfangen sind, entsprechendes Flag setzen.


    P.S.: Wegen "unübersichtlich": In asm ist das A und O viel kommentieren! - Sonst blickt man bei eigenen Sachen nach einer Woche nicht mehr durch. Bei mir steht fast in jeder Zeile ein Kommentar - fast mehr Arbeit als die asm-Befehle, aber das ist die "eigentliche Programmierung", also wo man nachvollziehen kann, was passiert. Und auch hier Subroutinen nutzen. Ich habe inzwischen eine Bibliothek aus oft gebrauchten Sachen, jeweils in Subroutinen verpackt. Die eigentliche Programmierung ist dann oft nur noch diese Subs aufzurufen, das ist dann fast wie Hochsprache programmieren mit selbst gebastelten Befehlen... ;-)

    It's only light - but we like it!


    Da es sich in letzter Zeit häuft: Ich beantworte keine PNs mit Fragen, die sich auch im Forum beantworten lassen!
    Insbesondere solche von Mitgliedern mit 0 Beiträgen, die dann meist auch noch Sachen fragen, die bereits im entsprechenden Thread beantwortet wurden.
    Ich bin keine private Bastler-Hotline, technische Tipps etc. sollen möglichst vielen Lesern im Forum helfen!