renebiemans.nl

Elektronica · 1 april 2006

DMX met PIC

In deze tutorial ga ik beschrijven hoe je DMX kunt verzenden. Je hebt hiervoor nodig:
1 PIC16F628A
2 75176 (ic)
3 5 Volt gestabiliseerde voeding

Een script dat werkt met een Atmel AVR Atmega 88 is hier te vinden.

Wat is DMX?

DMX is de afkorting voor Digital MultipleXed. Standaard is DMX 5 polige XLR maar je ziet DMX heel vaak ook 3 polig. Dit komt omdat de twee extra polen die worden gebruikt om informatie terug te sturen haast nooit gebruikt worden. Een enkele keer worden de twee extra polen gebruikt om bijvoorbeeld een foutmelding te versturen als bijvoorbeeld een dimmer stuk is. DMX verstuurd maximaal 512 kanalen over 1 kabel waarbij de apparaten in serie achterelkaar staan.

Waarvoor word het gebruikt?

DMX word gebruikt voor de besturing van dimmers, scanners, moving-heads en andere lichteffecten.

Voordelen DMX

1 Alle 512 kanalen gaan over 1 kabel en niet zoals vroeger dat voor elk kanaal 1 kabel nodig was.
2 Makkelijk aan te sluiten, je kunt dmx doorlussen van het ene apparaat naar het andere.

Nadelen DMX

Er zitten natuurlijk ook enkele nadelen aan dmx en dat is bijvoorbeeld:
Wanneer 1 kabel stuk gaat dan werken alle apparaten die na die kabel zitten niet meer omdat het stuursignaal dan weg is.

Hoe is het DMX signaal opgebouwt?

Hieronder staat een plaatje waarop is aangegeven hoe het DMX signaal ongeveer werkt.

Het DMX signaal is hoog(1) als er een signaal van +2.5Volt uit komt en laag(0) zodra het signaal -2.5Volt is. Omdat een PIC alleen een 5 volt uitgang heeft moet er een component komen die het signaal omzet. Dat is bijvoorbeeld het ic: sn75176b. Die zet het signaal van de PIC om in het DMX signaal of andersom.

Het DMX signaal begint dus met een break van 88Us. Daarna komt een Mark After Break(MAB) van 8Us. Dan word er eerst een Startbyte verzonden die voor dimmers altijd 0 is. Na deze startbyte komen maximaal 512 bytes stuurinformatie met een waarde van 0-255. En daarna begint het weer van voren af aan.

Een bit duurt altijd 4Us. Een byte begint met een "startbit" en eindigd met twee een "stopbits". Een startbit is altijd laag en een stopbit altijd hoog. Tussen de start en stopbits zit de data voor de dimmer of een ander apparaat die DMX gestuurt is. Deze data kan een waarde hebben van 0 tot 255 en zegt hoeveel de dimmer moet dimmen. Dus bij 0 gaat de lamp op de dimmer uit en bij 255 volledig aan.

De waarde 0-255 wordt verzonden volgens het binaire stelsel met eentjes en nulletjes oftwel hoog of laag. Een binair getal maak je door een eentje te zetten bij de getallen die je nodig hebt voor het getal te maken en een nulletje bij het getal die je niet nodig hebt. Bij DMX is de informatie 8 Bits waardoor je de volgende getallen reeks dan krijgt: 128-64-32-16-8-4-2-1. Dus bijvoorbeeld 0 is binair(8 bits) 00000000, 255 is 11111111 en bijvoorbeeld 211 is 11010011. Bij bijvoorbeeld 10 bits heb je dan nog 512 en 256 erbij maar aangezien DMX dus met 8 bits werkt gebruikt je die niet. Mocht je dit allemaal niet snappen is hier een converter voor decimaal naar binair en van binair naar decimaal.

DMX ontvangen met een PIC

Om DMX te ontvangen met een PIC(bijvoorbeel de pic16f628a) heb je een stabiele 5 volt voeding nodig en een sn75176b chip. Het beste en het makkelijkste is de UART van de PIC te gebruiken om DMX te ontvangen.

9 Bit data

De UART werkt echter met 1 startbit(laag) en 1 stopbit(hoog) terwijl DMX 2 stopbits heeft. Om te zorgen dat de PIC het signaal dus wel ziet moet je 9 bit ontvangst instellen op de PIC. Dan ziet de PIC de eerste stopbit als de 9de bit waardoor hij de data wel ontvangt en geen error aangeeft.

De Break

De break samen met de Mark After Break van het DMX signaal ziet de PIC eigenlijk als een framingerror en een byte. Een framing error houd in dat de pic wel een startbit ontvangt maar geen stopbit ontvangt. Wat dus eigenlijk gebeurt bij het begin van de break namelijk 44Us laag. Daarna ziet de PIC een byte met data 0. Hiermee kan de PIC redelijk nauwkeurig de Break en de Mark After Break detecteren.

De Startbyte

De startbyte geeft aan voor wat voor apparaat de data bestemd is, voor dimmers is de data van de byte 0. Voor andere apparaten zou je asndere startbytes kunnen geven dit word echter haast nooit toegepast. De startbyte is een data byte die altijd achter de Mark After Break komt. Je moet dus kijken als de byte na de Mark After Break dus 0 is zo niet moet hij de data die daarna komt negeren totdat er weer een break langs komt.

Data

De data komt achter de startbyte aan. Bij DMX zijn er maximaal 512 data bytes achter de startbyte aan. Om te zorgen dat het ene kanaal wat je wilt ontvangen goed ontvangen word moet elke binnenkomende byte ontvangen worden en geteld worden. Zodra de pic dan bij het kanaal is wat hij moet ontvangen moet hij de data opslaan en verwerken. Zodra dit gedaan is moet hij weer helemaal van vooraf aan beginnen.

Hardware

Als hardware gebruik een PIC16F628A, met daaraan een RS485 driver chip de sn75176b, een paar ledjes, een stabiele 5 volt voeding en een 20mhz kristal. De 20mHz kristal kan niet vervangen worden door de interne kristal of door een 4mHz kristal omdat dan het ontvangen verkeert loopt.

De code

Hieronder staat de code die ik voor het ontvangen van DMX heb geschreven. De fuses voor de pic zijn: HS osc, MCLR OFF en alle andere fuses mogen ook uit. Je kunt de code ook hier downloaden. Wat schuin gedrukt staat of naar ; staat is commentaar.

;Hier staat welke PIC er word gebruikt.
    list    P=16F628A
    #INCLUDE <P16F628a.INC>
    __CONFIG    _CP_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC  &    _LVP_OFF    & _MCLR_OFF

;hier krijgen de poorten een naam
#Define ErrLed          PORTB,7
#Define DataLed         PORTB,6
#Define BreakLed        PORTB,5
#Define ProgramLed      PORTB,4
#Define OUT1            PORTB,3

;hier geef je de geheugen plaatsen een naam
#DEFINE Framing         DMX_data,0
#DEFINE Break           DMX_data,1
#DEFINE Startcode       DMX_data,2
#DEFINE Klaar           DMX_data,3

;hier geef je de geheugen plaatsen een naam
DMX_data        EQU     020h
Kanaal          EQU     021h
Teller          EQU     022h
Reg1            EQU     023h

        ;met startcode 00h begint de code
        ORG 00h
        goto    INIT            ;ga naar init

        ORG 04h
        goto    main
;hier word de pic ingesteld

;hier worden de kanalen op digitaal gezet en de in en uitgangen ingesteld
INIT    movlw   0x07
        movwf   CMCON           ;zet alles digitaal
        CLRF    PORTA           ;maak porta laag
        CLRF    PORTB           ;maak portb laag

        BSF     STATUS,RP0      ;Select Bank1
        MOVLW   B'00000000'     ;maak van poort A uitgangen
        MOVWF   TRISA       

        MOVLW   b'00000000'     ;maak van poort B uitgangen
        MOVWF   TRISB
        BSF     TRISB,1         ;op poortb,1 na

;hier word de baudrate ingesteld voor de uart deze moet op 04h staan en op highspeed zodat er met 20mHz een 250KBaud baudrate is.
        MOVLW   04h             ;waarde voor baudrate
        MOVWF   SPBRG           ;in het register setten
        BSF     TXSTA,BRGH      ;high speed
        BCF     TXSTA,SYNC      ;Async connection

        BCF     STATUS,RP0      ;ga terug naar bank 0

;9bit data word aangezet voor de tweede stopbit
        BSF     RCSTA,RX9       ;9bit data
        BSF     RCSTA,CREN      ;ontvangen aanzetten

;de aurt word aangezet
        BSF     RCSTA,SPEN      ;Enable UART

;de registers worden leeg gehaald
        MOVF    RCREG,W         ;clear RCREG
        MOVF    RCREG,W         ;clear RCREG
        MOVF    RCREG,W         ;clear RCREG

        CLRF    DMX_data        ;file legen
        CLRF    Kanaal          ;file legen
        CLRF    Teller          ;file legen
        CLRF    Reg1            ;file legen

;er word een kanaal nummer ingesteld
        MOVLW   02h             ;kanaal nummer instellen
        MOVWF   Kanaal          ;naar kanaal zetten
        MOVF    Kanaal,W        ;kanaal naar w      
        MOVWF   Teller          ;w naar teller

        BSF     ProgramLed      ;programmaled aan


        goto    main            ;begin programma
;Het instellen van de PIC is nu klaar nu moet de data nog verwerkt worden. Daarom gaat hij nu naar main waar de data word verwerkt.

;kijken als er data is zo ja gaat hij de data verwerken.
main    BTFSS   PIR1,RCIF   ;kijken als er data is
        goto    main        ;zo niet steeds weer

;hij gaat nu kijken als er er een overrun error is zo ja naar overrun
        BTFSC   RCSTA,OERR  ;als er een overrun error is
        goto    overrun     ;dan naar overrun           
;hij gaat nu kijken als er een framing error is(misschien break) zo ja naar framing.    
        BTFSC   RCSTA,FERR  ;kijken als er een framing error is 
        goto    frame       ;zo ja ga naar break

;de data word tijdelijk in Reg1 gezet
        MOVF    RCREG,W     ;zet de inkomnde data 
        MOVWF   Reg1        ;in Reg1

;Als er een framing error is geweest en data is binnengekomen gaat hij kijken bij break als er een break is geweest.
        BTFSC   Framing     ;kijken als er een framing error is geweest
        goto    break   

        BTFSS   Break       ;kijk als er een break is geweest
        goto    err         ;ga naar err er klopt iets niet

        BSF     DataLed     ;data led aan

        BTFSC   Klaar       ;kijk als hij al klaar is
        goto    main        ;al klaar dan terug naar main
                            ;anders verder met programma
;Hij gaat nu kijken als hij bij het goede kanaal is door een teller met 1 te verlagen en als hij op 0 is een regel over te slaan Zodra de teller 0 is, is hij op het goede kanaal en gaat hij de data verwerken.
        DECFSZ  Teller      ;kijk als het kanaal is bereikt
        goto    main        ;ga naar main

;Het gewenste kanaal is bereikt de PIC gaat nu kijken als het laatste bitje van de data een 1 of een 0 is. Als dat laaste bitje een 1 is dan staat hij voor meer dan 50% open en gaat een led aan. Als hij een 0 is dan gaat het ledje uit dan staat het kanaal voor minder dan 50% aan.
        BTFSS   Reg1,7      ;kijk als de waarde hoger is als 128
        BCF     OUT1        ;lager dan 128 out1 uit
        BTFSC   Reg1,7      ;kijk als de waarde hoger is als 128
        BSF     OUT1        ;hoger dan 128 out1 aan

        BSF     Klaar       ;set klaar
        goto    main        ;oneindige loop


;zodra er een error optreed gaat hij weer opnieuw beginnen
err     BSF     ErrLed      ;error led aan
        BCF     Framing     ;framing uit
        BCF     Break       ;geen break
        BCF     DataLed     ;geen data
        BCF     BreakLed    ;geen break
        BCF     Klaar       ;niet klaar
        goto    main        ;ga naar main

;bij een overrun error gaat hij de overrun error uitzetten en weer opnieuw beginnen met data ontvangen.
overrun BSF     ErrLed      ;Error led aan
        BCF     RCSTA,CREN  ;error uitzetten
        NOP                 ;even wachten
        BSF     RCSTA,CREN  ;error uitzetten
        MOVF    RCREG,W     ;clear RCREG
        MOVF    RCREG,W     ;clear RCREG
        MOVF    RCREG,W     ;clear RCREG
        BCF     RCSTA,CREN  ;error uitzetten
        NOP                 ;even wachten
        BSF     RCSTA,CREN  ;error uitzetten
        BCF     Break       ;nog geen break
        BCF     Framing     ;geen framing
        BCF     DataLed     ;geen data
        BCF     BreakLed    ;geen break
        BCF     Klaar       ;niet klaar
        goto    main        ;terug naar main

;zodra er een framing error is zou het kunnen zijn dat er een break is. Hij moet echter hierna wel een byte data ontvangen met data = 0 dat gaat hij hierna detecteren.
frame   BSF     Framing     ;er is een framing error 
                            ;dus misschien een break!
        MOVF    RCREG,W     ;zet de error uit
        BCF     Break       ;nog geen break
        MOVF    Kanaal,W    ;kanaal naar w      
        MOVWF   Teller      ;w naar teller
        BCF     Klaar
        goto    main        ;ga naar main

;Er is data binnengekomen na de een framing error hij gaat nu kijken als die data ook 0 is zo ja is er een break.
break   BCF     Framing     ;framing uitzetten
        MOVF    Reg1,W
        BTFSS   STATUS,Z    ;kijken als w 0 is
        goto    err         ;ga naar error
        BSF     BreakLed    ;breakled aan
        BSF     Break       ;er is een break
        goto    main        ;ga naar main
        END

©ReneBiemans.nl