DMX - kein Empfang

OP #7680955
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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 #7681385
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren