- 12V Akku mit 280 Ah bauen         
Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 41

Thema: DMX512 empfangen

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.05.2007
    Beiträge
    329

    DMX512 empfangen

    Anzeige

    Praxistest und DIY Projekte
    Hallo NG,

    nachdem ich bereits DMX-512 Signale senden kann, kommt nun der Empfang dran.
    Folgender erster Ansatz:

    Code:
    $regfile = "m8def.dat"
    $crystal = 16000000
    $baud = 250000
    
    Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 2 , Databits = 8
    
    Dim Buffer(513)as Byte
    Dim Kanal As Word
    
    On Urxc Empfang
    Enable Urxc
    Enable Interrupts
    
    Do
    Loop
    
    Empfang:
       If ucsra.Fe = 1 Then
          Kanal = 0
       Else
          If Kanal > 0 Then
             Buffer(kanal) = Udr
          End If
          Incr Kanal
       End If
    Return
    Ist der Code vom Ansatz her korrekt?

    Günter

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.09.2005
    Beiträge
    276
    Senden mag ja 'einfach' sein weil das andere Gerät ja bereit sein muss.

    Empfangen geht wohl nur per IRQ & ASM.

    Hier im Forum fand ich mal auch Bascomcode mit ASM dazu.

    Gento

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.05.2007
    Beiträge
    329
    Hallo Gento,

    Interrupt hab ich doch:

    On Urxc Empfang

    Das Abspeichern des Kanals müsste doch zu schaffen sein, bis das nächste Byte ansteht.

    Wo soll hier Basic zu langsam sein?

    Günter

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.09.2005
    Beiträge
    276
    so Code gefunden.
    Quelle steht drin.

    Code:
    '--------------------------------------------------------------------
    ' Original von:
    ' DMX - Dimmer 512 / by DW-Soft
    ' Dirk Wegener - 2004 - the_clown@web.de
    '--------------------------------------------------------------------
    ' Bearbeitet von Jochen Steinmann
    ' DMX - SwitchPack
    ' AVR-Bascom
    '--------------------------------------------------------------------
    ' "Deklaration" m³sste klar sein
    $regfile = "m32def.dat"                                     'AT90S2313
    $crystal = 16000000                                         '8MHz Quarz
    $baud = 250000                                              'Baudrate 250Kbaud
    
    ' ben÷tigete Variablen
    Dim Dmx_count As Word                                       'Pakete die auf Ausgõnge zielen
    Dim Dmx_count_temp As Byte                                  'Gesendete Pakete
    Dim Dmx_byte As Byte                                        'DMX Wert
    Dim Dmx_clock As Byte                                       'Spielerei
    Dim Dmx_adr As Word                                         'DMX-Adresse
    Dim Dmx_adr_temp As Byte                                    'DMX-Adresse (Temp)
    Dim Dmx_adr_c As Word                                       'DMX-Adresse (Counter)
    Dim Dmx_off As Byte                                         'DMX-Signal noch da?
    
    ' UART initialiesieren
    Print "Start"
    On Urxc Rec_isr
    Enable Urxc
    
    ' Ports setzen und configurieren
    Config Pind.6 = Output                                      'StatusLED
    Config Portb = Output                                       'Schaltausgõnge
    Set Portd.6
    
    ' Anfangsvariablen Festlegen
    Dmx_count = 0                                               'kein Paket empfangen
    Dmx_clock = 16                                              '
    Dmx_adr = 2                                                 'DMX_Adresse 2
    
    Enable Interrupts
    
    ' ******************************************************************************
    ' Hauptschleife
    ' ******************************************************************************
     Do
        Waitms 10
        Decr Dmx_off
        If Dmx_off = 0 Then
           Set Portd.6
        End If
     Loop
    
    ' ******************************************************************************
    ' Funktion: DMX-Signal emfangen und auswerten
    '           Dieser Interupt wird beim eintreffen von seriellen Daten ausgef³hrt
    Rec_isr:
       $asm                                                     'Programmteil f³r das Auswerten der
          .def Uart_status = R16                                'emfangenen Daten
          .def Uart_byte = R17
          .def Uart_temp1 = R18
    
                IN Uart_status,USR
                IN Uart_byte,UDR
    
                SBRC Uart_status,FE                             'Auswertung ob Datenbyte OK
                RJMP  Asm_reset                                 'bei ³berlõnge des Datenbyte = DMX Reset
                RJMP  Asm_Loop1                                 'Daten OK--->
    
          Asm_reset:
                LDI Uart_temp1,$00                              'Adesszõhler zur³cksetzen
                STS {Dmx_count_temp} , Uart_temp1               'Daten dem Basicvariablen ³bergeben
                STS {Dmx_byte} , Uart_byte
                RJMP Asm_exit
          Asm_loop1:
                STS {Dmx_byte} , Uart_byte
          Asm_exit:
       $end Asm
    
       If Dmx_count_temp <> 0 Then                              'emfangene Daten im "Dmx_buf" ablegen
          Incr Dmx_count                                        'und den jeweiligen Kanal zuordnen
          If Dmx_adr_c = Dmx_count Then
             If Dmx_adr_temp < 9 Then
                Select Case Dmx_adr_temp
                   Case 1:
                      If 127 <= Dmx_byte Then : Reset Portb.0 : Else : Set Portb.0 : End If
                   Case 2:
                      If 127 <= Dmx_byte Then : Reset Portb.1 : Else : Set Portb.1 : End If
                   Case 3:
                      If 127 <= Dmx_byte Then : Reset Portb.2 : Else : Set Portb.2 : End If
                   Case 4:
                      If 127 <= Dmx_byte Then : Reset Portb.3 : Else : Set Portb.3 : End If
                   Case 5:
                      If 127 <= Dmx_byte Then : Reset Portb.4 : Else : Set Portb.4 : End If
                   Case 6:
                      If 127 <= Dmx_byte Then : Reset Portb.5 : Else : Set Portb.5 : End If
                   Case 7:
                      If 127 <= Dmx_byte Then : Reset Portb.6 : Else : Set Portb.6 : End If
                   Case 8:
                      If 127 <= Dmx_byte Then : Reset Portb.7 : Else : Set Portb.7 : End If
                End Select
                Incr Dmx_adr_temp
                Incr Dmx_adr_c
             End If
          End If
       Else                                                     'bei DMX Reset Variablen setzen
          Dmx_count = 0 : Dmx_count_temp = 1
          Dmx_adr_c = Dmx_adr : Dmx_adr_temp = 1
          Decr Dmx_clock
          'nur eine Spielerei Toggelt eine LED am PortD.6 beim eintreffen von korrekten DMX Daten
          If Dmx_clock = 0 Then : Toggle Portd.6 : Dmx_clock = 16 : End If
       End If
       Dmx_off
    DMX ist recht Zeitkritisch wegen der hohen Baudrate.

    Gento

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.05.2007
    Beiträge
    329
    Hallo Gento,

    im Interrupt Rec_ISR wird erst mit ASM superschnell das Byte abgeholt um dann mit Basic im selben Interrupt superlangsam das Byte auszuwerten. Also wenn DAS läuft, dann kann ich beruhigt den ersten Prototyp zusammenlöten...

    danke für deine Hilfe!

    Günter

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    ach was ... asm brauchts nicht unbedingt ...
    hab mir nen 4-Kanaligen Dimmer für DMX512 gebastel, der
    läuft in Bascom einwandfrei ... gar kein Thema
    selbst bei 250000 Baud hat der AVR bei 16MHz noch mächtig
    zeit für anderes.
    Du brauchst den URXC Interrupt, den haste ja und das
    Framing Error Flag der UART
    Über das Flag setzt Du dann Deinen Bytezähler auf 0 und
    im URXC Int zählste dann diesen wieder hoch und schreibst
    auf den entsprechenden Platz Deinen Wert ... fertig ist die Laube
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.05.2007
    Beiträge
    329
    Hallo Vitis, hallo Gento,

    jetzt hab ich mal nachgerechnet:

    ein Frame des DMX-Signals dauert kürzestenfalls 44µs.
    Das bedeutet, mein Interrupt darf maximal 44µs dauern denn dann könnte das nächste Byte anstehen. Bei 16MHz dauert:

    $asm
    .def Uart_status = R16
    .def Temp_var = R17

    IN Uart_status,USR
    SBRC Uart_status,FE0
    RJMP Asm_reset
    RJMP Asm_kanal

    Asm_reset:
    ldi temp_var, $00
    sts {Kanal}, temp_var
    RJMP Asm_exit

    Asm_kanal:
    $end Asm
    Buffer(kanal) = Udr
    Incr Kanal
    $asm
    Asm_exit:

    $end Asm

    fast genau so lange wie:

    If Ucsr0a.fe0 = 1 Then
    Kanal = 0
    Elseif Kanal > 0 Then
    Buffer(kanal) = Udr
    Incr Kanal
    End If

    nämlich ca. 10,875µs. Darum verbleiben 33µs pro Frame für weiteres.

    Gespeichert werden alle Werte aller Kanäle in einem riesigen Array ob sie gebraucht werden oder nicht. Das hält den Interrupt kurz und Platz ist ja genug.
    Der Rest kommt jetzt in die Mainloop

    Günter

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    sag ich ja ... es bleibt noch massig Zeit.
    Zumal das DMX ja meist nicht permanent läuft
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.08.2004
    Beiträge
    197
    @Vitis
    kannst du den Bascom-Empfänger-Dimmer-Code veröffentlichen, dann kann Guenter und Andere ihn ev. für sich umstricken.
    Vielen Dank dafür!

  10. #10
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.05.2007
    Beiträge
    329
    Hallo Stromi,

    sobald ich Hardwaretechnisch soweit bin, werde ich meine Fortschritte melden. Es geht mir dabei in erster Linie darum einen sauberen Code hinzulegen, nicht um einen Code der irgendwie läuft.
    Bis jetzt sieht das so aus:
    Code:
    $regfile = "m88def.dat"
    $crystal = 16000000
    $baud = 250000
    
    Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 2 , Databits = 8
    
    Dim Buffer(513)as Byte
    Dim Dmx_byte As Byte
    
    Dim Kanal As Word
    
    On Urxc Empfang
    Enable Urxc
    Enable Interrupts
    
    Do
    'Hier werden die Ausgänge von Buffer() bestückt
    Loop
    
    Empfang:                                                    
       If Ucsr0a.fe0 = 1 Then
          Kanal = 0                        
       Else
          If Kanal = 0 Then
             Incr Kanal
          Else
             Buffer(kanal) = Udr
             Incr Kanal
          End If
       End If
    Return

Seite 1 von 5 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen