Search

'DMX512'에 해당되는 글 3건

  1. 2012.09.10 DMX-3 (1)
  2. 2012.08.31 DMX512-2
  3. 2012.08.29 DMX512

DMX-3

Protocol 2012.09.10 12:40 Posted by Dwarp

드디어 DMX512 세번째입니다.

 

저번 시간까지는 대략적인 특징과 하드웨어 구성(회로도)에 대해서 보았는데요 -> 2012/08/31 - [Protocol] - DMX512-2

 

이번 시간에는 DMX 프로토콜에 대해서 더 상세히 살펴본 후 소프트웨어 뼈대까지 나아가 봅시다

 

  위 그림이 DMX512의 타이밍 차트입니다. 1990 이라고 씌여 있는 것을 보니 씁쓸하군요. 암튼 DMX512는 크게 보자면 3 파트로

 

이루어져 있습니다. Break, Start Code, 512 Frame입니다.

 

그 외 기타 MAB나 MTBP와 같은 것은 다음 싸이트를 참고하시면 될 것 같습니다.

 

<DMX 타이밍 용어 설명 : http://www.erwinrol.com/dmx512/>

 

 

   1. 먼저 Break는 Frame과 Frame을 구분하기 위한 것이고 우리는 이 Break를 이용해서 Data가 시작한다는 것을 알 수

 

있습니다.

 

   2. Start Code는 DMX512에서는 0x00으로 다른 값에서는 동작하면 안됩니다. RDM이라는 프로토콜은 Start Code가

 

0xCC을 사용하고 Text Packets은 0x17, System Information Packet은 0xCF도 쓰기 때문입니다. 따라서 기본적인

 

DMX512 패킷은 0 만을

받아서 동작하는 것이 좋습니다.

 

   3. 512 Frame은 말 그대로 정보입니다. 512개의 데이터가 250000bps로 연달아 나타납니다.

 

 

   음. 크게 3부분을 나눴는데 이걸 어떻게 프로그램으로 구현하면 될까요? Start Code와 512개의 data는 단순하게 8bit,

 

250000bps, 2 stop bit, no parity bit의 UART 통신과 동일합니다. 그렇죠? ㅎ그럼 데이터의 시작인 Break는 어떻게 구현할까요?

 

 

   Tranceiver 입장에서 보면 UART 핀을 일반 I/O로 변경한 뒤, 88 us가 넘게만 OFF -> ON 시켜주면 될 것 같습니다. 

 

타이밍 차트를 보니 Break의 허용시간은 88us ~ 1s 이니 꽤 여유가 있는 편입니다. 이 후에는 해당핀을 다시 UART로 바꾸고

 

Start Code 0x00을 포함한 총 513개의 데이터를 쏴주면 끝이군요!!!.

 

 

   이번에는 Receiver의 입장해서 볼까요? Receiver에서 Break는 어떻게 알아챌까요? Tranceiver처럼 UART 핀을 일반 IO로

 

변경하고 Low인 시간을 측정해서 88us이상이면 UART로 변경하고 Data를 읽으면 될거에요. but! 더 쉬운 방법을 찾아봅시다.

 

바로 UART의 Error Detection 기능을 이용하는 것인데요. 대부분의 MCU에 있는 UART에는 Frame Error Detection 기능이

 

있습니다. 이 에러는 형식을 맞추지 않은 Data가 들어올 경우 발생합니다. Break 이외에 Frame Error가 발생할 만한 부분이

 

없기 때문에 우리는 이 Frame Error Detection 기능을 사용해서 Break 구간이라는 것을 간편하게 알 수 있습니다.

 

  자! 그럼 실제로 사용하기로 한 stm32f103ze UART 파트 중 Error Detection 부분을 보겠습니다.

 

 

 

   stm32f103zeUART 관련 register 중 Status register부분입니다. 위 표를 보시면 0번 bit부터 3번 bit까지가 Error

 

bit이며 각각 PE(Parity bit error), FE(Frame error), NE(Noise error), ORE(Overrun error) 입니다. 이 에러들은 대부분의

 

MCU에서 Detection이 가능하며 인터럽트 또한 지원하고 있습니다. 따라서 여러분들은 FE 인터럽트가 걸리면 그 때

 

513개의 데이터를 읽어들이면 되는 것이죠. 순서대로 다시한번 생각해보면

 

1. DMX data 입력.

 

2. FE 인터럽트 발생.

 

3. DMX buffer에 데이터 입력 시작.

 

4. Start code == 0 이면 옳바른 DMX512 데이터.

 

5. 나머지 512개 데이터를 주소에 맞게 활용.

 

6. 반복~

 

입니다. 간단하죠? 간단하지 않다구여? -_-+ 간단합니다. 안간단해도 간단하다고 자기최면을 거는 겁니다.

 

그럼 간단하게 샘플 코드를 나열하기 전에!!!! 한가지 더!! DMX512라는 프로토콜은 간단하고 강력합니다. 하지만 무식하다는

 

단점이 있죠. 뭐가 무식하냐구여? 생각해보시면 DMX512라는 프로토콜은 절대 쉬지 않습니다. 항상 512개의 데이터를 뿜고

 

있어야 하고 받을 준비를 하고 있어야 합니다. 받는 입장이라면 250kbps의 UART에 의해 인터럽트가 항상 걸리고 있다는

 

입니다.

 

이 점 때문에 DMX512 리시버는 항상 인터럽트에 시달리는데요. 여기에 여러가지 인터럽트들을 짬뽕시키고 Flash 읽고 하다

 

보면 각종 버그에 시달릴 수 있습니다. 어떻게 하면 이런 문제를 회피할 수 있을까요? 저는 요세 거의 모든 MCU에 있는 DMA

 

라는 기능을 사용합니다. 이게 뭐냐면 Direct Memory Acces의 약어로 주변기기와 메모리의 데이터를 하드웨어적으로

 

연결시켜주는 기능입니다. -_-;; 참 설명 못하죠? 쉽게 말씀드리자면 자동입니다. 자동. 무이가 자동이냐? 예를 들면 UART를

 

통해 데이터가 들어오면 지정된 메모리의 주소를 늘려가며 자동으로 메모리에 데이터가 들어갑니다. 우리는 해당 데이터를

 

읽어 쓰면 그만입니다. 초기 설정 외에 소프트웨어적인 처리(인터럽트따위)가 필요하지 않기 때문에 여러분의 코드는 한결

 

여유로워 집니다.

 

따라서 항상 데이터를 읽고 있어야 하는 DMX512 라는 시스템에는 딱!인 기술이라고 생각됩니다. 코드를 살펴봅시다.

 

void USART2_IRQHandler(void)
{
     FlagStatus flagStatus;
     flagStatus = USART_GetFlagStatus(USART2,USART_IT_FE);
     switch (dmxStatus){
      case Idle:
           if(flagStatus)                        //Break Error Detected!!
           {
                SetTimer1(1000);             //타이머 1초 설정

                dmxStatus = BreakError;    
                DMA_Cmd(DMA1_Channel6,DISABLE);        //DMA 잠깐 쉬기
                DMA_SetCurrDataCounter(DMA1_Channel6,bufferSize);    //DMA 초기화
                DMA_Cmd(DMA1_Channel6,ENABLE);        //DMA 다시 시작!
                USART_ITConfig(USART2,USART_IT_ERR,DISABLE);    //ERR Disable
                USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);    //RXNE Enable
           }
           break;
      case BreakError:
           dmxStatus = ReadyToReceive;    //ReadyToReceive
           break;
      case ReadyToReceive:
           dmxStatus = Idle;                        //Idle
           USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);    //RXNE Disable
           USART_ITConfig(USART2,USART_IT_ERR,ENABLE);        //ERR Enable
           break;
      default:
           dmxStatus = Idle;
           break;
     }
     USART_ClearITPendingBit(USART2,USART_IT_FE|USART_IT_ORE|USART_IT_NE|USART_IT_PE); //에러 클리어
     USART_ClearFlag(USART2,USART_FLAG_FE|USART_FLAG_ORE|USART_FLAG_NE);                //에러 클리어
}

 

   함수 이름이 매우 친숙하죠? 물론 아니실 분들도 있겠죠. UART 인터럽트 핸들러입니다. 인터럽트가 걸리면 호출되는 함수죠.

 

위를 보시면 아시겠지만 DMA 덕분에 데이터를 다루는 구문이 한곳도 없습니다. 다만 "DMA 시작합시다~"라는 구문이 있죠.

 

또 1초 타이머를 설정해 놓았는데요. 그 이유는 DMX의 최대 지연이 1초이기 때문입니다.

 

그럼 어디에 데이터가 들어가냐!! 하실 분들이 있으실텐데요. 그 DMA는 초기화 함수에 이미 초기화되어 있죠.

 

아래 코드 처럼요. 주변기기 주소는 USART2_DR_Address이고 메모리 주소는 Buffer 이군요. Buffer는 물론 주소를 나타냅니다.

 

 DMA_DeInit(DMA1_Channel6);                                                          //DMA1 채널 6의
 DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_DR_Address;    //주변기기 어드레스는 UART의 데이터 레지스터다
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;                 //메모리 어드레스는 Buffer다.(물론 포인터)
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                       //방향은 주변기기 -> 메모리 이다.
 DMA_InitStructure.DMA_BufferSize = bufferSize;                                  
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;     //주변기기 주소 증가 금지
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;            //메모리 주소 증가할 것.
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    //1 Byte
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;           //1 Byte
 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                //노멀 모드
 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                    //DMA도 인터럽트 처럼 우선순위가 있습니다.
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                           //M2M: memory to memory disable
 DMA_Init(DMA1_Channel6, &DMA_InitStructure);                                //설정~

 

   Buffer는 적절하게 선언만 해 두었다면 어느 시점에라도 읽어올 수 있습니다. Buffer를 이용해서 모터를 굴리던 LED

 

디밍을 하던 자유롭게 할 수 있습니다. 어떠신가요?

 

   DMX512 Receiver만 하고 Tranceiver는 왜 안하냐구요? Tranceiver는 난이도가 낮다고 생각해서 후배에게 맡겨

 

진행했거든요. 그래서 Tranceiver 파트는 제가 실제로 구현한 것이 한개도 없습니다. 실제로 크게 난이도가 높이 않으므로

 

여러분들이라면 금세 하실 수 있으실 거에요. 참고로 말씀드리자면 후배가 만든 DMX Tranceiver는 천원짜리 cortex m0로

 

순식간에 만들어졌습니다.

 

   코드 전체를 올리지는 않겠습니다. 회사 것이기도 하고 제가 짰지만 지금 보니깐 코드에 의심스러운 구석이 있네요. -_-;;;

 

쪽팔.. 그럼 이것으로 DMX512에 대한 글은 끝마치겠습니다. 제가 글 솜씨가 부족하고 해서 이해가 안가시는 분들이 계시면

 

언제든 물어보셔도 됩니다. 그리고 제가 틀린 것도 분명 있을 텐데 지적해 주시면 감사하겠습니다.

 

언제나 힘내시구요. 아는 한 최대한 돕겠습니다. 화이팅~~~

 

- Dwarp -

저작자 표시
신고

'Protocol' 카테고리의 다른 글

USB.03  (0) 2012.10.05
USB.02  (0) 2012.10.04
USB.01  (2) 2012.09.28
DMX-3  (1) 2012.09.10
DMX512-2  (0) 2012.08.31
DMX512  (0) 2012.08.29
TAG DMX, DMX512

DMX512-2

Protocol 2012.08.31 10:24 Posted by Dwarp

DMX512 두 번째 입니다.

직장일을 병행하다 보니 생각보다 글 쓰기가 쉽지가 않네요. 일단 아닥하고 시작! 하려니 생각 정리도 잘 안되네요. ^^;;

아무튼 시작!

DMX512에 관해 대략적인 면을 살펴보았는데요. -> 2012/08/29 - [Protocol] - DMX512

오늘은 회로도를 완성해볼까 합니다. 일단 준비물이 필요한데 사용하려는 MCU와 75176의 데이터시트입니다.

MCU는 8051, AVR, PIC, Cortex M0, Cortex M3 등등 종류야 다양하죠? 요세는 M4도 나오고 있습니다.

개인적으로는 8비트 8051, AVR과 PIC을 사용하는 것을 전혀 권장하지 않습니다. 가성비가 너무 좋지 않습니다.

(MCU 고르는 방법은 따로 포스팅하겠습니다.)

제가 선택한 MCU는 STM32F103ZE인데요. Cortex M3입니다. -> http://www.st.com/internet/mcu/product/164495.jsp

네이버에 검색해보니 싸고 상당히 많이 사용하고 계시더군요. 스팩에 관한 내용은 따로 설명드리지 않겠습니다.

75176은 표준 IC라서 많은 회사에서 판매하고 있습니다. 검색해보니 SN75176BDR이 있군요 TI 제품입니다.

그럼 주요 IC 두개는 끝났군요. 기타 회로에 들어가는 IC들은 DMX512에 집중하기 위해 패스하겠습니다.

자, 그럼 MCU는 MCU고 75176이 뭐냐? 라고 하는 분들이 있을 수 있겠죠?

75176 데이터 시트를 보시면 DIFFERENTIAL BUS TRANSCEIVERS라고 설명이 되어 있습니다.

 

보통 차동차동 많이 거리는데 그냥 A와 B의 차이로 데이터의 0과 1을 결정한다는 뜻입니다. 이렇게 하는 이유는

데이터 선에 끼어 들 수 있는 외부 노이즈 때문인데요. 이론상 설명드리면

A와 B의 전압차로 0과 1을 결정한다고 했으니 A-B라고 하겠습니다. 같은 선상이니깐 같은 노이즈가 끼어들테고

그 노이즈를 N이라고 부르겠습니다. 그럼 원래 시그널 A에 노이즈 N이 합쳐지면 B도 마찬가지겠죠?

공식으로 만들면 (A+N) - (B+N) 가 되는데 풀면 A-B가 되죠. 결국 노이즈가 없어졌네요.

아래 테이블에서 보면 A-B의 차이가 0.2 볼트 이상이거나 -0.2볼트 이하일 때, H나 L가 결정되는 군요!!

RS-485가 이런 방식으로 데이터를 주고 받기 때문에 232보다 노이즈에 강하고 멀리 전달할 수 있는 거죠.

그럼 다시 DMX회로로 넘어가서 75176에 있는 8핀에 대한 걸 볼까요? VCC와 GND는 다 아실거에요? 그쵸? 제발...

그리고 A랑 B도 위에서 설명했으니 Output이나 Input이 되겠죠? 그럼 나머지 R,D,RE,DE를 보겠습니다.

R은 Receive, D는 Data input, RE는 Receive Enable, DE는 Data input Enable입니다. 참고로 RE에 윗줄

반대라는 뜻입니다. 즉, RE가 0이면 Enable이라는 뜻이고, 1이면 Disable이라는 뜻입니다.

 

R은 받는 거니깐 MCU의 UART RX에 연결하면 되겠고, D는 주는 놈이니깐 MCU의 TX에 연결하면 되겠습니다.

그리고 RE하고 DE는 어떻게 할까요? Receive 동작만 하고 싶다면 RE는 0에 DE는 0로 해버리면 될거에요. 반대면

둘다 1로 묶어버리면 되겠네요. 둘다 하고 싶다면 RE와 DE를 한 라인에 묶어서 MCU의 일반 IO에 연결해주면

프로그램으로 양쪽동작 모두 할 수 있겠네요. IC마다 케페시터는 버릇처럼 붙여줍시다. ^^

A와 B는 일반 커넥터를 사용해도 무방하지만 FM으로 갑시다. DMX에는 XLR 커넥터라는 것이 사용됩니다.

 

<출처: http://www.neutrik.com >

위에 보이는 것들이 XLR 커넥터 들입니다. 오프라인으로 국내에서 구하려면 상당히 고가입니다. 마우저 등을 이용하시는게

정신건강에 좋습니다. 

<출처: https://commons.wikimedia.org/wiki/File:XLR5_pinouts.svg#globalusage>

XLR은 3 Pin 또는 5Pin으로 사용하고 있습니다. 현재 규정은 XLR 5Pin으로 3Pin은 예전 규격입니다.

Pin description

1: Shield : 쉴드 라인입니다.

2: Data - : 데이터 -라인입니다. 75176 B에 연결합니다.

3: Data + : 데이터 +라인입니다. 75176 A에 연결합니다.

4: Spare - : 스페어 라인입니다.

5: Spare + : 스페어 라인입니다.

그럼 마저 회로도를 완성해 보도록 하죠.

XLR 커넥터가 두개가 있네요? 그리고 단순히 같은 라인끼리 연결만 되어 있을 뿐이네요. DMX 장비는 두개의 XLR 커넥터를

가지고 있어야 합니다. DMX Male 커넥터는 input이고 DMX Female 커넥터는 output인데 첫번째 장비의 Input에 DMX

컨트롤러로부터 시그널이 들어왔다면 두번째 장비의 시그널은 첫번째 장비의 XLR Female output으로부터 받는 거죠.

아래 그럼처럼 말이죠.

 

DMX 장비는 어떤 전송이나 증폭을 할 수 없게 되어 있습니다. 링크되어 있는 중간의 장비가 고장나버리면 뒤에 있는

장비들에게는 신호가 하나도 가지 않게 되기 때문이죠. 그래서 단순하지만 강력한 링크가 완성되는 것입니다.

그리고 간혹 2번과 3번 핀 사이에 120옴을 넣어두는 분들이 계신데 절대 넣으시면 안됩니다. 120옴을 넣는 이유는 보통

터미네이션의 용도인데 터미네이션이라는 것은 신호가 라인 끝에서 저항을 통해 소모되어 반사되지 않도록 하는 것입니다.

만약 터미네이션이 장비마다 들어가 있고 병렬로 120이 주륵주륵 붙는다고 생각해보시면 어떻게 될지는 뻔할 것이라고

생각됩니다. 또 Shield를 GND에 붙이는 회로도 많은데 절대 권장하고 싶지 않습니다.

장비들간의 거리가 길면 장비들 간의 전위차로 인해 GND를 통해 전류가 흐를 수 있습니다. 그라운드 루프라는 것인데요.

보통 음향장비에서 쉴드를 통해 그라운드가 붙어 있으면 심한 노이즈를 들을 수 있는데 같은 이유입니다. 또한,

장비간 연결하는 케이블의 커넥터에 납땜이 잘 못 되어있다면 장비들은 계속 리셋이 될 수도 있는 일입니다.

따라서 저는 쉴드를 어스에 붙이는데요. 위 회로도의 커넥터에서 각각 6번과 7번은 볼트를 통해 케이스와 접촉되는 부분인데

이 부분을 통해 쉴드로 어스로 붙입니다.

결국은 가장 간단하게 연결하는 것이 DMX 시스템에 있어서 가장 중요한 포인트인 것이죠!! -_-+

쓰다보니 상당히 길어졌군요. MCU는 따로 언급을 하지 않았습니다. UART RX와 TX에만 붙이면 되는 일이니까요.

더 자세한 문의 사항이 있으면 댓글 달아 주시구요. 다음에는 DMX 프로토콜과 프로그램 뼈대, 그리고 샘플 코드까지!

진행해보도록 하겠습니다.

긴글 읽어 주셔서 감사합니다. 많은 도움이 되었으면 좋겠습니다.

(추가)

한 가지 더 말씀드릴게 있는데요.

4번,5번 스페어 라인은 뭐에다 쓰는 거냐! 라고 하실 분들이 있을 것 같아서 말씀드립니다.

4번5번 핀은 DMX512 프로토콜의 추후 업데이트 버전에 사용될 예정이었으나 DMX장비 제조사들이 해당 핀을 데이터 리턴

이나 전원으로 사용하는 등 임의로 써버렸습니다. 그래서 4번핀과 5번핀은 이러지도 저러지도 못하고 있는 실정이라고

어딘가에서 읽은 기억이 있습니다. 따라서 저의 결론은 사용하지 않겠다!!!! 입니다. ^^ 감사합니다.

신고

'Protocol' 카테고리의 다른 글

USB.03  (0) 2012.10.05
USB.02  (0) 2012.10.04
USB.01  (2) 2012.09.28
DMX-3  (1) 2012.09.10
DMX512-2  (0) 2012.08.31
DMX512  (0) 2012.08.29
TAG DMX, DMX512

DMX512

Protocol 2012.08.29 17:36 Posted by Dwarp

첫 번째 시작은 DMX512로 할까 합니다.

생소하신 분들도 있겠지만 내용이 간단하고 구현이 매우 쉽습니다. 그럼 시작~

여러분들이 많이 가시는 클럽 천장에 붙어 있는 수많은 싸이키(?)가 바로 DMX512 프로토콜을 사용합니다.

[해외]Amazon American DJ DJ Spot 250-250 Watt halogen DMX512 or Stand Alone Moving Head Fixture

무대 조명에 많이 사용하는데요. 간단하게 특징을 보면

 

1. RS-485 인터페이스를 사용한다.

2. 512개의 주소를 가진다. 즉, 512개 주소의 장비들을 컨트롤할 수 있다. 또한 장비의 주소는 겹쳐도 상관없다.

3. 연결이 매우 간단하고 단방향이다.

 

이 정도 입니다.

표준은 "E1.11 - 2008, USITT DMX512-A" 이지만 40$... ㅠㅠ 뭐 싸다면 싸지만... 어쨌든!

일단 RS-485 인터페이스를 사용하기 때문에 하드웨어는 간단하겠죠?

DMX 표준에도 친절하게 SN75176 혹은 ISO485P중 하나를 사용하라고 되어 있습니다. 결국 485로 데이터를 보내주면 되니깐

Baud rateStop bitParity bit라던지가 있겠죠? 봅시다.

 

1. Baud rate: 250000bps. 25만 bps입니다. 쪼금 빠르죠?

2. Stop bit: 2. 스탑비트가 두개군요.

3. Data bit: 8. 데이터 비트는 노멀하게 8bit입니다.

4. Parity bit: None. 페리티 비트 없습니다!

 

음 이정도면 된 것 같네요. 감이 오시는 분들도 계시겠지만 이 정도 설정하면 일반 MCU의 UART 기능을

사용할 수 있겠군요!!

맞습니다. 결론부터 말씀드리면 특별한 하드웨어 구성없이 일반 MCU+75176 으로 충분히 구현 가능합니다.

물론 언급하지 않은 부분이 약간 있지만 자세한 사항은 조금씩 조금씩 알아 나가기로 하겠습니다.

신고

'Protocol' 카테고리의 다른 글

USB.03  (0) 2012.10.05
USB.02  (0) 2012.10.04
USB.01  (2) 2012.09.28
DMX-3  (1) 2012.09.10
DMX512-2  (0) 2012.08.31
DMX512  (0) 2012.08.29
TAG DMX, DMX512