DMX - Empfängerbau mit PIC - erste Schritte

#746703
Lesenswert?

Hallo zusammen,

ich bin rellativ neu hier im Forum und habe grade ein bißchen gestöbert. 
Leider hab ich nicht so wirklich das gefunden, was ich suche.
Ich habe mir ein EasyPic4 von MicroE zugelegt und würde nun gerne mal 
einen DMX-Empfänger auf nem PIC programmieren. Aber ich stehe da leider 
noch ein bisserl wie der Ochs vorm Berge.

Wie implementiere ich den DMX-Empfang am Besten auf dem PIC. Kann ich 
dafür nen Usart nutzen oder muß ich das von Hand mit Timern machen? Bin 
da für jeden Hinweis dankbar! Wenn jemand Beispielquelltexte für mich 
hat, wäre das echt super!!!

Beste Grüße
#747017
Lesenswert?

@Uboot-Stocki
Sorry ich habs vielleicht nicht richtig ausgedrückt. Ich möchte ganz 
gerne das DMX-Protokoll, mit Hilfe von einem PIC-Mikrocontroller 
dekodieren, um dann andere Sachen ansteuern zu können (Dimmer, Servos, 
etc)

@Tracelrec
Die Seite hab ich schon gesehen, leider gehts da mehr um AVRs als um 
PICs und mit denen kenn ich nu leider nicht so aus.

Aber trotzdem erstmal DANKE
#747354
Lesenswert?

@ Stefan Hänsch (dj-duck)

>Mit fehlt nur noch die zündende Idee zur Implementierung. Brauche
>einfach mal n Beispielquelltext

Im Prinzip so.

RS232 mit UART im Interrupt empfangen.

Wenn Zeichen ==0 und Frame Error (Stop Bit =0) -> Break, Zähler 
rücksetzen
Wenn keine Frame Error -> empfangenes Byte speicher in einem Array
   my_array[zähler]=UART_Data
  Zähler +1

Thats it. Mit den Daten im Array kanst du machen was du willst.

MfG
Falk
Gast #750925
Lesenswert?

Na, das wichtigste hat Falk ja schon geschrieben.

Wenn ein Framing Error detektiert wird, war das das Break. Typisch >= 
88µs. Danach folgt das Mark after Break (>= 8 µs). Dann, sehr wichtig, 
das Startbyte; das muss den Wert 0 haben. Und dann kommen die Daten von 
mindestens einem Kanal bis max. 512 Kanäle. Üblicherweise musst du auf 
deinem Board aber noch ein Mäuseklavier, oder aber besser, 3 
BCD-Schalter haben, die die Startadresse deines Gerätes setzen.

Wichtig: 250000 Baud 8N2 ohne Parity

Fast vergessen: immer das Data Overrun-Flag abfragen. Wenn das gesetzt 
ist hast du ein Datum verpasst. Dann kannst du Kaffe trinken gehen, bis 
der nächste FE-Fehler kommt und dann den Zähler neu aufsetzen.


Ich denke mal die PICs werden eine ähnliche Funktionalität haben wie die 
AVRs.

MW
Persönliche Seite #762450
Lesenswert?

Hallo,

anbei mal der Ausschnitt aus meinem DMX-8-Kanal-Lichteffektgerät in 
welchem das DMX Protokoll dekodiert wird (für PICs). Ist eigentlich 
verständlich, wenn man eine Weile drüber nachdenkt. Wenn Interesse 
besteht, kann ich das komplette Programm (mehrere 1000 Prog.Zeilen) und 
den Schaltplan hier posten. Ist allerdings ein recht Umfangreiches 
Projekt gewesen.
1
;-----------------------------------------------------------------------
2
;immer wenn ein DMX-Datenbyte über die ser.SS empfangen wurde, lößt der
3
;USART einen Interupt aus. 
4
;In dieser Routine wird der DMX Datenstrom verarbeitet und die uns interessierenden
5
;8 Kanalwerte werden in den RAM kopiert. 
6
IH_Check_USART
7
  bcf   PIR1,RCIF      ;UART Interupt Flag löschen
8
      
9
IH_Check_HW_Overrun
10
  btfss   RCSTA,OERR        ;wurde ein HW Überlauf entdeckt?
11
  goto   IH_Check_9th_bit  ;Nein, nächster Test
12
    bcf    RCSTA,CREN          ;Ja, UART rücksetzen
13
    bsf    RCSTA,CREN          ;
14
  bsf    Data_Error_LED    ;DMX Error LED einschalten
15
    bsf    Dflag,dmx_error     ;DMX-Error-Flag einschalten
16

17
IH_Check_9th_bit
18
  clrf  IH_Timer_Count    ;löschen des Timer counters
19
  btfss   RCSTA,RX9D      ;Ist das 9. Daten-Bit=0? (Breaksignal)
20
  goto   IH_Wait_Break    ;Ja, dann starte den Zustandsautomaten
21

22
IH_Check_SW_Overrun        ;nein, also wurden Daten empfangen
23
  btfss   RCSTA,FERR           ;Wurde ein Framing Error entdeckt?
24
  goto    IH_Test_Flags    ;Nein, dann zum Test der Flags
25
  bcf     RCSTA,CREN          ;Ja, resette UART
26
    bsf     RCSTA,CREN          ;
27
  bsf    Data_Error_LED    ;DMX Error LED einschalten
28
  bsf    Dflag,dmx_error    ;DMX-Error-Flag einschalten
29

30
IH_Test_Flags
31
  btfsc   Iflag,Valid_Channel    ;Test ob schon Kanaldaten empfangen wurden
32
  goto  IH_Valid_Channel    ;Ja, dann nächsten Kanal empfangen
33
  btfsc  Iflag,Start_Detected  ;Test ob schon das Startbyte empfangen wurde
34
  goto  IH_Wait_Channel      ;Ja, dann warte auf die Kanaldaten
35
  btfsc  Iflag,Break_Detected  ;Test ob schon ein Break empfangen wurde
36
  goto  IH_Wait_Start      ;Ja, dann warte auf das Startbyte
37

38
IH_Wait_Break
39
  clrf  Iflag          ;lösche Iflag
40
  movfw  RCREG          ;empfangenes Datenbyte nach W
41
  btfsc  RCSTA,RX9D        ;wurde ein Break empfangen?
42
  goto  IH_Interrupt_Poll    ;Nein, Break nicht empfangen
43

44
  btfsc  STATUS,Z        ;Ja, war das Byte auch 0?
45
  bsf   Iflag,Break_Detected  ;Ja, dann Flag Break_Detected einschalten
46
  goto  IH_Interrupt_Poll    ;und auf das nächste Byte warten
47

48
IH_Wait_Start
49
  clrf  IH_Channels_Recieved  ;lösche Zähler für Anzahl empfangener Kanalwerte
50
  clrf  IH_Channel_Count_L    ;lösche Kanalnummerzähler
51
  bsf    Iflag,Start_Detected  ;Flag für Start Byte gefunden einschalten 
52

53
  movfw  RCREG          ;Ist der Startcode = 0?
54
  btfss  STATUS,Z        ;
55
  clrf  Iflag          ;wenn nicht, dann löschen die Flags und warte auf den nächsten DMX-Break
56
  goto  IH_Interrupt_Poll    ;Ja, dann warten auf das 1. Byte
57

58
IH_Wait_Channel            ;auf das erste Byte warten, welches der DMX-Startadresse entspricht 
59
  movfw  RCREG          ;empfangenes Byte nach IH_Temp sichern
60
  movwf  IH_Temp
61
  incf  IH_Channel_Count_L,f  ;inkrementiere channel count
62

63
  movfw  IH_Channel_Count_L    ;Vergleiche IH_Channel_count_L mit der 
64
  xorwf  DMX_Start_Addr_L,w    ;DMX-Start Adresse
65
  btfss  STATUS,Z        ;wenn ungleich, dann weiter warten
66
  goto  IH_Interrupt_Poll
67

68
  bsf    Iflag,Valid_Channel    ;wenn gleich, dann setze Flag Valid_Channel    
69
  movfw  IH_Temp
70
  movwf  MessK0L          ;und speichere empfangenen Wert im ersten Kanal
71
  incf  IH_Channels_Recieved,f  ;den Counter erhöhen
72
  goto  IH_Interrupt_Poll
73

74
IH_Valid_Channel          ;alle weiteren 7 Bytes werden hier verarbeitet
75
  movlw  MessK0L          ;Adresse von MessK0L laden
76
  addwf  IH_Channels_Recieved,w  ;den Offset hinzuaddieren
77
  movwf  FSR            ;und in FSR speichern
78
  movfw  RCREG          ;empfangenes Byte in das entsprechende Kanalbyte kopieren   
79
  movwf  INDF          
80

81
  incf  IH_Channels_Recieved,f  ;Counter erhöhen
82
  btfss  IH_Channels_Recieved,3  ;sind 8 Werte empfangen wurden? 
83
  goto  IH_Interrupt_Poll    ;Nein, dann auf das nächste Byte warten
84
    
85
  clrf  Iflag          ;Ja, dann Flags löschen und auf das nächste DMX-Break warten
86
  bsf    Dflag,DMX_Data      ;neue DMX-Daten empfangen
87
  bcf    Data_Error_LED      ;lösche DMX Error LED
88
  goto   IH_Interrupt_Poll        
89

90
;----------------------------------------------------------------------------

Falls noch Fragen sind stehe ich gern zur Verfügung.

Gruß Sven

PS: Ach ja, den DMX-Programmteil fand ich irgendwo im iNet und hab es 
dann auf meine Zwecke angepasst bzw. erweitert.
#788678
Lesenswert?

Nabend zusammen!

Vielen Dank erstmal allen, die hier gepostet haben. Hab viele 
interessante Ideen bekommen und werde nun versuchen da mal ein bisserl 
was umzusetzen. Hab mir jetzt auch ne Testumgebung gebaut, so dass ich 
direkt testen kann.

Hab da noch mal ne Frage:
Ich will das ganze mit Hilfe des USARTs empfangen. Welche Bautraute muss 
ich da einstellen. Ein Baut ist doch immer ein Symbol, oder? DMX hat 
250K/Bit pro Sekunde - das ist mir klar. Aber wie rechne ich das nun in 
Baut um? Wäre nett, wenn ihr mir da nochmal auf die Sprünge helfen 
könntet.

Danke schon mal im Voraus :-)

Schönen Abend noch!
#788693
Lesenswert?

Super ... das ging ja mal sehr schnell!!!
Hab da folgende Formel gefunden für nen PIC 16F877A:

Baut-Rate = Fosc / ( 64 * ( x + 1 ))   <-   für den  Low-Speed-Mode
Baut-Rate = Fosc / ( 16 * ( x + 1 ))   <-   für den High-Speed-Mode

Bei nem 8MHz Quarz muss ich also in den HIGH-Speed-Mode wechseln und 
dann das SPBRG = 1 setzen. Ich hoffe das ist korrekt, oder??!
Persönliche Seite #788725
Lesenswert?

1
;UART initialisieren
2
  Bank1
3
    movlw   .3
4
    movwf   SPBRG    ;Datenrate=250000 Bit/s
5
    bsf     TXSTA,BRGH  ;Hohe Datenrate
6
    bcf     TXSTA,SYNC  ;asynchroner Modus
7
    Bank0
8
    bsf     RCSTA,RX9  ;Bit9 wird mit ausgewertet
9
    bsf     RCSTA,CREN  ;keine Pause zwischen den Bytes

Die Formeln hast du ja schon gefunden. Nun musst du nur noch die 
richtigen Werte setzen. Mein PIC läuft mit 16MHz. Hab gerade mal 
nachgerechnet, deine errechneten Werte sind korrekt.
#793724
Lesenswert?

Also irgendwie bekomme ich nur Framing-Errors und das neunte Dantenbit 
ist auch durchgängig Null ... habt ihr da spontan ne Lösung oder ist 
Euch das vielleicht auch schon mal untergekommen?
Ich glaube irgendwie, daß die Bautrate nicht stimmt, hab aber eigentlich 
alles richtig eingestellt ...

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