1. Home
  2. Chat
  3. Forum
  4. Kalender
    1. Termine
    2. Karte
  5. Lexikon
    1. Letzte Änderungen
  6. Marktplatz
    1. Bewertungen
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Artikel
  • Forum
  • Termine
  • Lexikon
  • Marktplatz-Eintrag
  • Seiten
  • Erweiterte Suche
  1. PA-Forum
  2. Forum
  3. Selbstbau
  4. Selbstbau und Reparatur Technik

[Tutorial] DMX Empfang mit AVRs / Strobe Interface

  • Henne
  • 21. Juni 2009 um 11:40
  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 16:19
    • #21

    @PMN: Hat denn die LED vorher mit ~16Hz geblinkt. Wenn nicht, hast Du die Fuse Bits vergessen.

    Hier mein derzeitiges Projekt:
    http://www.hoelscher-hi.de/hendrik/forum/anastrobe.zip

    Henne's Sites

    Einmal editiert, zuletzt von Henne (21. Juni 2009 um 16:22)

  • PMN-Concepts
    Reaktionen
    1
    Beiträge
    1.452
    • 21. Juni 2009 um 16:21
    • #22

    Passt jetzt.... Frequenz passte, lediglich DIP-Switch defekt

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 16:24
    • #23

    Daniel, Jaegermeister:
    Warten oder weitermachen?

    Henne's Sites

  • Dominik Herderich
    Verifiziert
    Reaktionen
    24
    Beiträge
    209
    • 21. Juni 2009 um 16:28
    • #24

    Kannst gerbe weitermachen. Den Code hab ich bisher im AVR-Studio "mitgemacht", aber noch nicht auf den atmega übertragen.

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 16:29
    • #25

    Um eine schöne hohe Auflösung zu bekommen, wollen wir für die Strobes den 16bit-Timer (T1) nutzen.
    Dieser zählt von 0 bis 2^16 und fängt dann wieder von vorn an. Jeder Timer eines AVRs hat einen eigenen Vorteiler (Prescaler), um den Zähltakt dem Systemtakt anzupassen.

    Nun zur Berechnung:

    PMN möchte einen Frequenzbereich von 1..15Hz.
    Wir wollen nun herausfinden, wie weit der Timer von 0 an zählen muss, um auf 1Hz oder 15Hz zu kommen. (Nach Erreichen der Zahl resetten wir den Timer und zählen erneut...)

    Die Formel lautet:
    Y= f_quarz/(f_pmn * Prescale)

    Unser Quarz hat 8MHz. Die möglichen Vorteiler findet Ihr auf S.122 im Datenblatt. Was ist der kleinste Vorteiler, damit wir mit unserem Wertebereich (2^16 = 65536) hinkommen?

    Henne's Sites

    Einmal editiert, zuletzt von Henne (21. Juni 2009 um 16:41)

  • PMN-Concepts
    Reaktionen
    1
    Beiträge
    1.452
    • 21. Juni 2009 um 16:31
    • #26

    könnte man die auswertung nicht einfach über eine Ganzzahldivision/Multiplikation durchführen?

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 16:43
    • #27

    @PMN: inverse Multiplikation wird nichts. Unser Problem ist vom Typ 1/n - also Tabelle...

    Henne's Sites

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 16:51
    • #28

    Wenn Ihr das datenblatt nicht habt:

    Zur Auswahl stehen: 1; 8; 64; 256; 1024

    Keiner eine Idee? :wink:

    Auflösung: Wir müssen bei der langsamsten Frequenz am weitesten zählen -> 1Hz interessant

    also: Y_max= 8*10^6/Prescale, wobei Y_max < 65536 und Prescale möglichst klein

    -> 64 reicht nicht, 256 passt.

    Somit lautet die Formel für den Timer, um auf PMNs Frequenzen zu kommen:
    Y= 8*10^6/(256*f_pmn), wobei f_pmn= 1..15Hz.

    Henne's Sites

    Einmal editiert, zuletzt von Henne (21. Juni 2009 um 17:03)

  • Dominik Herderich
    Verifiziert
    Reaktionen
    24
    Beiträge
    209
    • 21. Juni 2009 um 17:01
    • #29

    Hmm, irgendwie häng ich da grad beim ausrechen. Liegt wohl dran, dass ich keine 2h nach nem 27h tag geschlafen hab... :?

    Die Formel Y= f_quarz/(f_pmn * Prescale) hätte ich nach Prescale aufgelöst:
    Prescale = f_quarz/(f_pmn * Y)
    f_quarz = 8000Hz

    für Y hätte ich ausm kontext raus 65536 genommen, und für f_pmn bin ich noch unschlüssig ob ich 1 Hz oder 15Hz nehmen soll.
    So kommen, meiner meinung nach, nur unsinnige Ergebnisse raus.

    edith ist der meinung, dass 8MHz keine 8000Hz sind, sondern 8000000Hz sind. Ich sag ja, ich war zu lange wach.

    Einmal editiert, zuletzt von Dominik Herderich (21. Juni 2009 um 17:27)

  • PMN-Concepts
    Reaktionen
    1
    Beiträge
    1.452
    • 21. Juni 2009 um 17:03
    • #30

    ich war gestern zu lange auf der kieler woche *g*

    komme auf die Formel

    Pre=F_quartz/(f_pmn*y)

    sinnvoll wäre Vorteiler 1?!

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 17:07
    • #31

    Eure Herangehensweise ist super, wenn man den Prescaler beliebig aussuchen kann.
    Wenn man sich auf einen von 6 (?) möglichen Werten festlegen muss, geht ausprobieren schneller :D


    Ach ja: Wenn ich die Formel durch Matlab jage, erhalte ich folgende Tabelle:

    Code
    const uint16_t FreqTable[] PROGMEM = {
    29206, 27412, 25826, 24414, 23148, 22007, 20973, 20032, 19172, 18382, 17655, 16984, 16361, 15783, 15244,
    14741, 14269, 13827, 13412, 13021, 12652, 12303, 11973, 11660, 11364, 11082, 10813, 10557, 10314, 10081,
    9858, 9645, 9441, 9246, 9058, 8878, 8705, 8538, 8378, 8224, 8075, 7931, 7793, 7659, 7530, 7405, 7284,
    7167, 7054, 6944, 6838, 6735, 6635, 6538, 6443, 6352, 6263, 6176, 6092, 6010, 5930, 5852, 5776, 5703,
    5631, 5560, 5492, 5425, 5360, 5297, 5235, 5174, 5115, 5057, 5000, 4945, 4890, 4837, 4786, 4735, 4685,
    4636, 4589, 4542, 4496, 4452, 4408, 4365, 4322, 4281, 4240, 4200, 4161, 4123, 4085, 4048, 4012, 3976,
    3941, 3906, 3872, 3839, 3806, 3774, 3743, 3711, 3681, 3651, 3621, 3592, 3563, 3535, 3507, 3480, 3453,
    3427, 3400, 3375, 3349, 3324, 3300, 3276, 3252, 3228, 3205, 3182, 3160, 3138, 3116, 3094, 3073, 3052,
    3031, 3011, 2990, 2971, 2951, 2932, 2912, 2894, 2875, 2856, 2838, 2820, 2803, 2785, 2768, 2751, 2734,
    2717, 2701, 2685, 2669, 2653, 2637, 2622, 2606, 2591, 2576, 2561, 2547, 2532, 2518, 2504, 2490, 2476,
    2463, 2449, 2436, 2422, 2409, 2396, 2384, 2371, 2358, 2346, 2334, 2322, 2310, 2298, 2286, 2274, 2263,
    2251, 2240, 2229, 2218, 2207, 2196, 2185, 2175, 2164, 2154, 2143, 2133, 2123, 2113, 2103, 2093, 2083
    };
    Alles anzeigen

    Diese Tabelle wird als Konstante direkt im Flash (PROGMEM) abgelegt und belastet so nicht das RAM.

    Henne's Sites

    Einmal editiert, zuletzt von Henne (21. Juni 2009 um 17:12)

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 17:11
    • #32

    @PMN:
    Die Formel ist richtig umgestellt ->
    8*10^6/(1Hz*2^16)= 122

    also Vorteiler 256 (s.o.)

    Eigentlich habt Ihr Recht: Umstellen ist doch besser...


    Edit:
    Ich bereite jetzt mal den Code vor...

    Henne's Sites

  • Dominik Herderich
    Verifiziert
    Reaktionen
    24
    Beiträge
    209
    • 21. Juni 2009 um 17:32
    • #33

    also mit umstellen bin ich schneller als mit ausprobieren. vor allem, wenn ich weiß, wie es geht. :)

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 17:40
    • #34

    so...

    Sorry für die Verzögerung - ich hatte aus Versehen das falsche Universum angestöpselt und habe mich bis eben gewundert, warum nichts funktionierte...

    Da wir Timer1 als Frequenzgenerator nutzen und möglichst genau arbeiten wollen, nutzen wir ihn im CTC mode. Das bedeutet, dass wir ihn automatisch bei Erreichen von unserem Zielwert (abgelegt im Vergleichsregister OCR1A) zurücksetzen.

    Die Initialisierung gehört in die Funktion init_system() und lautet:

    Code
    TCCR1B = (1<<CS12)|(1<<WGM12);	//set T1 @clk/256, CTC mode
    TIMSK  = (1<<OCIE1A);
    OCR1A  = 5000;

    Die erste Zeile setzt Prescaler und mode. Die Zweite aktiviert einen Interrupt bei Erreichen des Zielwertes und die dritte lädt schon einmal eine Dummy-Frequenz, damit was blinkt...

    Henne's Sites

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 17:43
    • #35

    Nun zur neuen main:

    Wir möchten Werte direkt aus dem Flash lesen und benötigen dafür die Lib:
    #include <avr/pgmspace.h>

    Wir brauchen eine neue globale Variable:
    uint8_t DmxBuf;

    Der Code lautet:

    Code
    int main(void)
    {
    cli();
    init_system();
    sei();
    for(;;)
    {
    wdt_reset();  					//reset watchdog (evtl durch Fuse Bits aktiv)
    get_dips();
    if (DmxRxField[0] != DmxBuf)
        {
    	DmxBuf= DmxRxField[0];
        uint16_t TimeBuf;
    	TimeBuf= pgm_read_word(&FreqTable[DmxBuf]);
    	if (TCNT1 >= TimeBuf) TCNT1= TimeBuf -5; 
    	cli();
    	OCR1A= TimeBuf;
    	sei(); 
    	}
    }
    }
    Alles anzeigen

    Kann mir jemand erklären, was ich wohl gemacht habe?


    ach ja:
    Die Interrupt Service Routine (ISR) zum Blinken lautet:

    Code
    ISR (TIMER1_COMPA_vect)
    {
    PORTD ^= (1<<PD7);
    }

    Hier mein derzeitiges Projekt:
    http://www.hoelscher-hi.de/hendrik/forum/anastrobe.zip

    Henne's Sites

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 18:36
    • #36

    Wenn sich unser DMX-Wert geändert hat, lade ich die neue Frequenz aus der Tabelle.
    Wenn der Timer schon weiter gezählt hat, als unser Vergleichswert groß ist, müssten wir für den nächsten Blitz so lange warten, bis der Timer nach dem Überlauf das nächste Mal wieder vorbeikommt. Da wir solche Aussetzer nicht wollen, setzen wir in diesem Fall den Timer kurz vor unseren Vergleichswert.
    Abschließend aktualisieren wir den Vergleichswert. Da dieser eine Größe von 16bit hat, müssen wir darauf achten, dass keine ISR dazwischen funken kann und sperren deshalb kurz alle Interrupts.

    Die Timer-ISR selbst lässt nur die rote LED blinken.

    Henne's Sites

  • Henne
    Beiträge
    1.580
    • 21. Juni 2009 um 18:42
    • #37

    Der DMX-Bereich sollte in drei Felder aufgeteilt werden: Aus, normal, Einzelblitz
    Zusätzlich wollen wir kein Blinken sondern ein kurzes Flashen.
    Deshalb nehme ich das zweite Vergleichsregister (OCR1B) und nutze es, um kurz vor dem anderen Interrupt mit dem Blitz zu beginnen. Über das alte Vergleichsregister (OCR1A) wird dann der Blitz nur noch abgeschlossen.

    C
    /* DMX Stroboskop Interface
    Version: 0.1
    Datum: 21.06.09
    Autor: H.Hölscher (www.hoelscher-hi.de)
    Target: DMX Transceiver @8MHz
    Lizenz: GPLv2
    */
    
    
    
    
    #include "lib_dmx_in.h"
    #include <avr/wdt.h>
    #include <avr/pgmspace.h>
    
    
    
    
    
    
    
    uint8_t	DmxBuf;
    
    
    
    
    
    
    
    const uint16_t FreqTable[] PROGMEM = {
    29206, 27412, 25826, 24414, 23148, 22007, 20973, 20032, 19172, 18382, 17655, 16984, 16361, 15783, 15244,
    14741, 14269, 13827, 13412, 13021, 12652, 12303, 11973, 11660, 11364, 11082, 10813, 10557, 10314, 10081,
    9858, 9645, 9441, 9246, 9058, 8878, 8705, 8538, 8378, 8224, 8075, 7931, 7793, 7659, 7530, 7405, 7284,
    7167, 7054, 6944, 6838, 6735, 6635, 6538, 6443, 6352, 6263, 6176, 6092, 6010, 5930, 5852, 5776, 5703,
    5631, 5560, 5492, 5425, 5360, 5297, 5235, 5174, 5115, 5057, 5000, 4945, 4890, 4837, 4786, 4735, 4685,
    4636, 4589, 4542, 4496, 4452, 4408, 4365, 4322, 4281, 4240, 4200, 4161, 4123, 4085, 4048, 4012, 3976,
    3941, 3906, 3872, 3839, 3806, 3774, 3743, 3711, 3681, 3651, 3621, 3592, 3563, 3535, 3507, 3480, 3453,
    3427, 3400, 3375, 3349, 3324, 3300, 3276, 3252, 3228, 3205, 3182, 3160, 3138, 3116, 3094, 3073, 3052,
    3031, 3011, 2990, 2971, 2951, 2932, 2912, 2894, 2875, 2856, 2838, 2820, 2803, 2785, 2768, 2751, 2734,
    2717, 2701, 2685, 2669, 2653, 2637, 2622, 2606, 2591, 2576, 2561, 2547, 2532, 2518, 2504, 2490, 2476,
    2463, 2449, 2436, 2422, 2409, 2396, 2384, 2371, 2358, 2346, 2334, 2322, 2310, 2298, 2286, 2274, 2263,
    2251, 2240, 2229, 2218, 2207, 2196, 2185, 2175, 2164, 2154, 2143, 2133, 2123, 2113, 2103, 2093, 2083
    };
    
    
    
    
    
    
    
    void init_system(void)
    {
    DDRA=   0xFF;                 	//low outputs
    PORTA=  0;
    DDRD=   0b10000110;       		//DMX, spare, LED1
    PORTD=  0b01111010;
    DDRE=	0b001;
    
    
    
    
    TCCR1B = (1<<CS12)|(1<<WGM12);	//set T1 @clk/256, CTC mode
    TIMSK  = (1<<OCIE1A);
    OCR1A  = 5000;
    
    
    
    
    init_DMX();          			//initialisiere DMX-Empfang
    } 
    
    
    
    
    
    
    
    
    
    
    
    
    
    int main(void)
    {
    cli();
    init_system();
    sei();
    for(;;)
    {
    wdt_reset();  								//reset watchdog (evtl durch Fuse Bits aktiv)
    get_dips();
    if (DmxRxField[0] != DmxBuf)
        {
    
    	if (DmxRxField[0] < 11)
    		{
    		TIMSK &= ~(1<<OCIE1B);				//disable firing ISR
    		}
    	else if (DmxRxField[0] < 211 )
        	{
    		uint16_t TimeBuf;
    		TimeBuf= pgm_read_word(&FreqTable[DmxRxField[0] -11]);
    		if (TCNT1 >= (TimeBuf -310)) TCNT1= TimeBuf -310; 
    		cli();
    		OCR1A= TimeBuf;						//set quench time
    		OCR1B= TimeBuf -300;				//set time to start firing
    		sei();
    		if (!(TIMSK &(1<<OCIE1B)))
    			{
    			TIFR   = (1<<OCF1B);
    			TIMSK |= (1<<OCIE1B);			//enable firing ISR
    			TCNT1= 0;
    			}
    		}
    	else
    		{
    		if (DmxBuf < 211)
    			{
    			TIMSK &= ~(1<<OCIE1B);			//disable firing ISR
    			TCNT1  = 0;
    			PORTD &= ~(1<<PD7);				//enable strobe
    			PORTA |= (1<<PA0);
    			OCR1A  = 300;					//set on time
    			}
    		}
    	DmxBuf= DmxRxField[0]; 
    	}
    }
    } 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    ISR (TIMER1_COMPA_vect)
    {
    PORTD |= (1<<PD7);							//disable strobe
    PORTA &= ~(1<<PA0);
    }
    
    
    
    
    
    
    
    ISR (TIMER1_COMPB_vect)
    {
    PORTD &= ~(1<<PD7);							//enable strobe
    PORTA |= (1<<PA0);
    }
    Alles anzeigen

    Henne's Sites

  • PMN-Concepts
    Reaktionen
    1
    Beiträge
    1.452
    • 22. Juni 2009 um 10:36
    • #38

    Sorry, bin gestern Abend geflogen, da meine Sync vom DSL immer wieder nach ca. 30 Sekunden Onlinezeit abriss... Werde mal versuchen, das gestern erarbeitete zu begreifen und umzusetzen.

    Schon mal vielen Dank für deine Mühe, Hendrik!

  • PMN-Concepts
    Reaktionen
    1
    Beiträge
    1.452
    • 22. Juni 2009 um 20:56
    • #39

    Sodenn... das Modul macht schon mal annähernd was es soll. Proband war bei mir ein Eurolite Superstrobe 2700.

    Zu unserem Glück ist der Eingang an dem Strobo mittels eines 4N35 ausgeführt, also können wir uns schon mal weitere Optokoppler sparen, da ja bereits eine saubere Trennung vorliegt. Der 4N35 erwartet am Eingang ca. 6 Volt, die 5 Volt die unser Transceiver liefert sind also durchaus angemessen.

    Einziges Problem hier: Die vom Transceiver gelieferten Impulse scheinen zu kurz zu sein, da der Blitz nicht immer zuverlässig auslöst...

  • Henne
    Beiträge
    1.580
    • 22. Juni 2009 um 23:25
    • #40

    Dann setz die Länge doch von 300 auf zB. 500...

    VG,
    Hendrik

    Henne's Sites

Anstehende Termine

  • Kombiseminar Sachkundiger für Anschlagmittel und Traversensysteme (AnschlägerPlus)

    Mittwoch, 23. September 2026 – Freitag, 25. September 2026
  • Kombiseminar Sachkundiger für Anschlagmittel und Traversensysteme (AnschlägerPlus)

    Dienstag, 29. September 2026 – Donnerstag, 1. Oktober 2026
  • Sachkunde für Fliegende Bauten

    Dienstag, 29. September 2026 – Donnerstag, 1. Oktober 2026
  • Virtueller Stammtisch im Chat

    Dienstag, 29. September 2026, 21:00 – 23:00
  • PA-Forum Stammtisch LeatCon

    Dienstag, 6. Oktober 2026, 13:00 – 14:00

Letzte Themen

  1. 17. - 18. November | PA Rigging & Truss Safety mit Tom Greber

    Soundchecker
    23. September 2026 um 10:33
  2. 13. - 14. Oktober | Live Mixing Workshop mit Jörn Müller in Köln

    Soundchecker
    23. September 2026 um 10:30
  3. können das hier (Foto) die original Weichen der KMT CS215 / CM215 sein ?

    phattomatic
    23. September 2026 um 09:12
  4. RCF: "Bass Motion Control" vs. "XBoost" => Ähnliche Funktionalität unter zwei verschiedenen Etiketten oder relevante Unterschiede?

    Hanseat
    21. September 2026 um 22:21
  5. Suche Lichteffekt

    Schreddl
    21. September 2026 um 12:22
  6. QLC+4 in MagicQ Visualsieren - wie richtig einstellen?

    metal-shot
    19. September 2026 um 17:44
  7. Verschiedene Verteiler mit Powercon Anschluss bzw. Ausgang kompatibel?

    tenderboy
    19. September 2026 um 12:22
  8. Suche Optocore Spezialisten - trouble shooting eines SANE Verbunds

    georg.h
    19. September 2026 um 10:21
  9. Quick & dirty reverse engineering - wie gehts weiter?

    phlownd
    19. September 2026 um 10:13
  10. DSP Preset für The Box Pro TP218 MKIII

    dxnny074
    18. September 2026 um 15:16
  1. Datenschutzerklärung
  2. Impressum
Community-Software: WoltLab Suite™