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.
Code:
;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
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
LET OP DEZE TUTORIAL IS NOG NIET AF!! ER KUNNEN NOG FOUTEN INZITTEN!
Voor op- en of aanmerkingen kun je altijd mailen naar info (at) renebiemans (punt) nl
©ReneBiemans.nl