DMX - kein Empfang

OP #7680955

Hallo zusammen,

ich bin seit Tagen am verzweifeln. Ich möchte per ATmega644P DMX empfangen (ganzes Uni) und danach UART an den PC senden. Die Verbindung PC <-> MC funktioniert. Allerdings erkennt der MC kein DMX Break und somit empfänger er nichts. Das DMX Pult ist ein kleines 6 Kanal und funktioniert bei Lampen entsprechend.

Im Anhang der Schaltplan. Was ich schon versucht habe: Pins am Stecker getauscht (A-B), Signal mit ~DATA inventiert, Baud Einstellungen überarbeitet, etc. Bislang ohne Erfolg. Leider sieht man manchmal den Wald vor lauter Bäume nicht. F_CPU 16000000UL

1
void init_DMX_RX(void)
2
{ 
3
UBRR1L  = ((F_CPU/16000000UL)-1);          //250kbaud, 8N2
4
  UBRR1H = 0;
5
  //UBRR1L = ((16000/4000)-1);
6
  //UBRR1 = ((F_CPU)/((250000)*16)-1);
7
  //((F_CPU)/((250000)*16)-1); //  
8
  //UCSR1C  = (3<<UCSZ10)|(1<<USBS1);
9
  UCSR1C = (1<<USBS1)|(1<<UCSZ12)|(1<<UCSZ10);
10
  UCSR1B  = (1<<RXEN1)|(1<<RXCIE1);
11
  
12
  gDmxState= IDLE;
13

14
  uint16_t i;
15
  for (i=0; i<sizeof(DmxRxField); i++)
16
  {
17
    DmxRxField[i]= 0;
18
  }
19
  DmxAddress = 1;
20
}
21

22
ISR (USART1_RX_vect)
23
{
24
  uint8_t USARTstate= UCSR1A;            //get state
25
  uint8_t DmxByte= (UDR1);              //get data
26
  uint8_t DmxState= gDmxState;          //just get once from SRAM!!!
27

28
  IndFlags |= (1<<SIGNAL_COMING);
29
 
30
  if (USARTstate & (1<<0xFE))            //check for break
31
    {
32
      UCSR1A &= ~(1<< 0xFE);              //reset flag
33
      DmxCount=  DmxAddress;            //reset frame counter
34
      gDmxState= BREAK;
35
      DMXStateOPT = 0x01;
36
    }
37

38
  else if (DmxState == BREAK)
39
    {
40
      if (DmxByte == 0) 
41
      {
42
        gDmxState= STARTB;            //normal start code detected
43
        gDmxPnt= ((uint8_t*)DmxRxField +1);
44
        DMXStateOPT = 0x01; //Gültiger DMX Wert empfangen
45
      }
46
      else gDmxState= IDLE;
47
    }
48
  
49
  else if (DmxState == STARTB)
50
    {
51
      PORTD |= ( 1 << PD7 ); //PORTD ^= ( 1 << PD7 );
52
      if (--DmxCount == 0)            //start address reached?
53
      {
54
        gDmxState= STARTADR;
55
        DmxRxField[0]= DmxByte;
56
      }
57
    }
58

59
  else if (DmxState == STARTADR)
60
    {
61
      uint8_t *DmxPnt;
62
      DmxPnt= gDmxPnt;
63
      *DmxPnt= DmxByte;
64
      if (++DmxPnt >= (DmxRxField +sizeof(DmxRxField)))   //all ch received?
65
      {
66
        gDmxState= IDLE;
67
        IndFlags |= (1<<VALID_DMX);
68
      }
69
      else gDmxPnt= DmxPnt;
70
      //PORTD &= ~( 1 << PD7 );
71
    }
72
    //PORTD |= ( 1 << PD7 );    
73
  uart_putc(DmxByte);   //send to PC        
74
}

In Main wird die Schleife solange durchlaufen, bis ein gültiges Signal anliegt:

1
//FIXME
2
dev_mode = 0;
3
  if (dev_mode == 0)
4
  {
5
    //DMX Start Rec
6
    init_DMX_RX();
7
    dmx_set_receive(1);
8
  } else if (dev_mode == 1)
9
  {
10
    //DMX Start Trasmit
11
    init_DMX_TX();
12
    dmx_set_receive(0);
13
  }
14
  mytimer_wait_MS(200);
15
  led_status(1);
16
  while(DMXStateOPT != 0x01) //Warte auf erstes DMX Paket
17
  {
18
    led_status(1);
19
    for (i=0; i < 150; i++)
20
    {
21
      service_uart_read(subuf);
22
      mytimer_wait_MS(1);
23
      scheduler();
24
    }
25
    led_status(0);
26
    for (i=0; i < 150; i++)
27
    {
28
      service_uart_read(subuf);
29
      mytimer_wait_MS(1);
30
      scheduler();
31
    }
32
  }
33

34
led_status(0);
35
  
36
  for (;;)
37
  {
38
    led_status(0);
39
    scheduler();
40
    service_uart_read(subuf);
41
  }
42
  while(1);

Ich kann den Fehler im Code einfach nicht finden. Oder ist es vielleicht ein Hardwareproblem? Ich wäre über Hilfe sehr dankbar. Grüße

Angehängte Dateien:
OP #7680991

Monk schrieb:

Die beiden Versorgungspins auf der rechten Seite des AVR sind nicht angeschlossen.

Außerdem fehlen auf beiden Seiten die Abblock-Kondensatoren der Stromversorgung.

Warum benutzt du zur Einstellung der Baudrate nicht die Makros azs der libc? https://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html

Hast den Taktteiler per Fuse oder CLKPR Register auf 1 geändert?

Stimmt! Werde ich nochmal probieren!

OP #7681130

Kai schrieb:

1
> ISR (USART1_RX_vect)
2
> {
3
>   uint8_t USARTstate= UCSR1A;            //get state
4
>   uint8_t DmxByte= (UDR1);              //get data
5
>   uint8_t DmxState= gDmxState;          //just get once from SRAM!!!
6
>   IndFlags |= (1<<SIGNAL_COMING);
7
> 
8
>   if (USARTstate & (1<<0xFE))            //check for break
9
>     {
10
>       UCSR1A &= ~(1<< 0xFE);              //reset flag
11
>       DmxCount=  DmxAddress;            //reset frame counter
12
>       gDmxState= BREAK;
13
>       DMXStateOPT = 0x01;
14
>     }

Der Fehler liegt im DETAIL:

1
 if (USARTstate & (1<<0xFE))            //check for break

muss heißen:

1
 if (USARTstate & (1<<FE1))            //check for break

Jetzt wird der Break wohl erkannt, die Werte sind allerdings unbrauchbar. Ich probiere morgen nochmal Leitung A-B zu tauschen.

OP #7681224

Lothar M. schrieb:

Kai schrieb:

Ich probiere morgen nochmal Leitung A-B zu tauschen.

Du hast doch ein Oszi, dann musst du doch nichts probieren. Einfach messen, was an uC-Pin ankommt.

Es ist leider ein altes Oszi. Es hat keine Speicherung und somit sind Daten daraus schlecht auszulesen. Das was am mc ankommt ist klar... nur ob die Daten korrekt sind ist unklar.

OP #7681385

Ich habe A-B getauscht und zusammen mit dem Softwarefehler in der Break Erkennung funktioniert das System nun endlich.

Eine Frage ist mir aber noch geblieben: Wieso: Monk schrieb im Beitrag #7680985:

Rx und Tx würde ich nicht so völlig ungeschützt auf die Sub-D Buchse legen. Packe da wenigstens zwei 100 Ohm Widerstände zwischen.

?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 2 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.