Jump to content

LPC17 DMX ?


Poivrelec

Recommended Posts

Hi Everyone,

 

Its my first post, so first of all thank you all for being such a great community.

I built a simple Core LPC17 module a few month ago and I already had a lot of fun with it (given the amount of free time a have), thanks to all the answers i could find in this forum :smile:

 

But there is one answer i'am currently unable to find, and because i'm quite new to C programming, i am not sure on how to get that information from the SVN.

Forgive me if it has been discussed before somewhere else, but it seems not to me ^^

 

Is it possible to generate (only generation is interesting me for now) DMX  straight from some pins (or directly through MIDI ports) ?

I read stuff about uart, but could not figure how it works

 

Thanks in advance :smile:

Forgive my english (im french ^^)

Link to comment
Share on other sites

      Thanks latigid on !

 

  I was asking about the MIDI ports because I understood they were uart, so maybe some reconfiguration could get me somewhere since I think DMX requieres a certain baud rate...

But i think other pins can be used as uart too, I'm quite new to that stuff, so I'm a bit lost ^^

 

  Sadly the research for 'dmx' in this forum does not give anything, thats why I dared to create a new post ^^

 

      Thank you Thorsten !

 

  I hope Philetaylor will read this post too... The only previous work on DMX i could find was on a old core, and that got me even more lost in my understanding of MIOS :smile:

 

Best Regards

Edited by Poivrelec
Link to comment
Share on other sites

Cortex M3 Production started  in 2004. 

 

I was talking about Midiboxes based on LPC17 core ^^, it seems that they outed in 2010

 

I would really like to try some stuff with the dmx module written by philetaylor, but I didn't get how to route the out to the correct ports...

Edited by Poivrelec
Link to comment
Share on other sites

  • 8 months later...

Hello again everyone,

 

I haven't had a lot of free time since last time, but I was able to figure out some things about dmx and midiboxes. But i'm still unable to start working on my project, since I'm really new to microcontrollers programming.

 

Apparently, the dmx.c module written by PhileTaylor is using commands that are not part of the hardware abstraction layer of MIOS32, and it is written for the old STM32 core module.

 

I read on the internet about GPIOs, baudrate and such, not figuring everything out, but that allowed me to have a global vision of Phil's module.

What I am looking for now is help for translating that module for LPC17 cores.

 

Looking at the files on the SVN, it seems that the way uart ports are configured for LPC17 is way different from old STM32. Maybe one of you can give me a hint on where to look if I want to manually configure UART port(s) of LPC17 using MIOS32. I tried to figure it out by myself, looking at the com and the midi_uart modules, but sadly my knowledge and understanding reached their limits before I could start trying to code anything...

 

Sorry if I missed a page where everything is already explained, I looked all the places I know without success, and now that I have some free time again, I would love to work on a working dmx module for LPC17 cores :)

 

Thanks in advance to you all !
Poivrelec

Link to comment
Share on other sites

Hi ilmenator,

 

Thanks for your reply, but I already have mounted a basic LPC17 + SCS about 8 months ago, and I haven't planned on buying and mounting a STM32F4 core yet.

I hope I can get my LPC17 core to deal with sending dmx from UART writing a dedicated module

 

In the future I will probably try the STM32F4, it seems to be a very interesting and versatile core module

Link to comment
Share on other sites

Hello again,

 

First of all, sorry for the very long post

 

I managed to understand some things since last time. I think I might have found a way of making this work, but there is something I still can't figure out.

 

What I'm doing in my module is initializing UART1 with the same commands in mios32_uart.c :

 

  // TX MIDI1: P2.0
  MIOS32_SYS_LPC_PINSEL(2, 0, 2);
  MIOS32_SYS_LPC_PINMODE(2, 0, 2);
  MIOS32_SYS_LPC_PINMODE_OD(2, 0, 1);
  // RX MIDI1: P2.1 w/ pull-up enabled
  MIOS32_SYS_LPC_PINSEL(2, 1, 2);
  MIOS32_SYS_LPC_PINMODE(2, 1, 0);
 
Then I pre calculate the baudrate (copy/paste of mois32_uart. again), and store both fast and slow value :
 
[... copy from mios32_uart.c with baudrate 250000]
  // Store for fast changes
  dmx_br_diviserOptimal = diviserOptimal;
  dmx_br_mulFracDivOptimal = mulFracDivOptimal;
  dmx_br_dividerAddOptimal = dividerAddOptimal;
 

[... copy from mios32_uart.c with baurdate 40000]

  // Store for fast changes
  break_br_diviserOptimal = diviserOptimal;
  break_br_mulFracDivOptimal = mulFracDivOptimal;
  break_br_dividerAddOptimal = dividerAddOptimal;
 
So I can easily configure ports using dmx_br_ or break_br_
 
  // Setup to DMX
  DMX->LCR = 0x87; // 8 bits, no Parity, 2 stop bit, no break, DLAB=1
  DMX->DLM = (dmx_br_diviserOptimal >> 8) & 0xff;
  DMX->DLL = dmx_br_diviserOptimal & 0xff;
  DMX->LCR = 0x03; // disable access to divisor latches
  DMX->FDR = ((dmx_br_mulFracDivOptimal&0xf) << 4) | (dmx_br_dividerAddOptimal&0xf);
  DMX->FCR = 0x07; // Enable and reset TX and RX FIFO
 
Then I configure the interrupt as in mios32_uart.c
 
  DMX->IER = (1 << 1) | (1 << 0); // enable RBR and THRE (receive/transmit buffer) interrupt
  MIOS32_IRQ_Install(DMX_IRQ_CHANNEL, MIOS32_IRQ_UART_PRIORITY);
 
As in Phil Taylor's module
 
// Create timer to send DMX universe.
vSemaphoreCreateBinary(xDMXSemaphore);
  xTaskCreate(TASK_DMX, (signed portCHAR *)"DMX", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_DMX, NULL);
 
In the task, I copied Phil's module, but using break_br_ variables to setup the port and send the break when in IDLE state
 
static void TASK_DMX(void *pvParameters)
{
  portTickType xLastExecutionTime;
 
  // Initialise the xLastExecutionTime variable on task entry
  xLastExecutionTime = xTaskGetTickCount();
  while( 1 ) {
    vTaskDelayUntil(&xLastExecutionTime, 35 / portTICK_RATE_MS);
if (dmx_state==DMX_IDLE)
{
 if (xSemaphoreTake(xDMXSemaphore, 10)==pdTRUE) { // Stop the universe from being changed while we are sending it.
        // Setup to break Baudrate
        DMX->LCR = 0x87; // 8 bits, no Parity, 2 stop bit, no break, DLAB=1
        DMX->DLM = (break_br_diviserOptimal >> 8) & 0xff;
        DMX->DLL = break_br_diviserOptimal & 0xff;
        DMX->LCR = 0x03; // disable access to divisor latches
        DMX->FDR = ((break_br_mulFracDivOptimal&0xf) << 4) | (break_br_dividerAddOptimal&0xf);
        DMX->FCR = 0x07; // Enable and reset TX and RX FIFO
        // break code
        DMX->THR = 0x00;
        // State
        dmx_state=DMX_BREAK;
 }}}}
 
And finally in the interrupt, I deal with end of transmissions (THRE) : If we were in DMX_BREAK state, I switch to DMX_SEND. If we are in DMX_SEND, I upadate the register with the next channel byte. Until there is no channel left, then switch to IDLE state, which will allow the task to send a new break and so on...
 
signed portBASE_TYPE x=pdFALSE;
DMX_IRQHANDLER_FUNC
{
  u32 iir_intid = DMX->IIR & 0xe; // IIR will be released with this access
  if( iir_intid == 0x2 ) { // IntId = 0x1 (THRE) End of transmission
    // If we were sending break
    if(dmx_state == DMX_BREAK) {
      // Reset Channel
      dmx_current_channel=0;
      // Setup to DMX baudrate
      DMX->LCR = 0x87; // 8 bits, no Parity, 2 stop bit, no break, DLAB=1
      DMX->DLM = (dmx_br_diviserOptimal >> 8) & 0xff;
      DMX->DLL = dmx_br_diviserOptimal & 0xff;
      DMX->LCR = 0x03; // disable access to divisor latches
      DMX->FDR = ((dmx_br_mulFracDivOptimal&0xf) << 4) | (dmx_br_dividerAddOptimal&0xf);
      DMX->FCR = 0x07; // Enable and reset TX and RX FIFO
      // start code
      DMX->THR = 0x00;
      // State
      dmx_state=DMX_SENDING;
    }
    // If we were sending a channel
    if(dmx_state == DMX_SENDING) {
      // If not all channels sent
      if( dmx_current_channel<DMX_UNIVERSE_SIZE ) {
        // Get current channel byte
        s32 b = DMX_GetChannel(dmx_current_channel);
        // If unable to get channel byte
        if( b < 0 ) {
          // Send zero in case of doubt
          b = 0x00;
        }
        // Transmit channel byte
        DMX->THR = b;
        // Next channel
        dmx_current_channel++;
      }
      // All channels have been sent
      else {
        // State
        dmx_state=DMX_IDLE;
        xSemaphoreGiveFromISR(xDMXSemaphore,&x);
      }
    }
  }
}
 
The program is running fine, with no hangs or error messages. But when I wire a dmx led bar to the uart, nothing expected happens (random blinking or blackout, but the bar says some DMX is entering, not sure if proper DMX though). I dont have an oscilloscope (but will probably be able to use one tomorrow). So I pluged a LED and it lighted and blinked rapidly, so something is going out of that UART ^^
 
My question is (after all this text ^^) how would one be sure that the UART pins are correctly configured ? I read in Phil's module that they're supposed to be push-pull outputs, but I couldn't find how to check that on a LPC1769. Also I'm not sure I 'copied' right the part where the baudrate are set.
 
Edit : On the LPC17 core sheet, it says that J12 (MIDI Out 1) is : TXD1 / GND / 3.3V, that's my main concern actually, as I am not sure it can match DMX+ / GND / DMX-
 
I know it's a lot to read, probably not very clear, but if someone has a hint on how to check that (code-side), or knows better how to do pin configuration on a LPC17, I would be very happy :smile:
 
I'll continue my tests anyway, and and of course share my results with you when/if I succeed
 
Thanks in advance,
Poivrelec
Edited by Poivrelec
Link to comment
Share on other sites

That's too much code for a quick check (and I'm also no DMX expert...)

 

However, you wanted to setup Push Pull mode, but actually you activate Open Drain Mode:

   MIOS32_SYS_LPC_PINMODE_OD(2, 0, 1);

 

Write (2, 0, 0) instead to ensure that Push-Pull is configured.

(Sidenote: due to a LPC1769 silicon bug, it will be push pull anyhow, but just to ensure...)

 

For the baudrate and pin behaviour, I'm sure that the scope will help to debug this! :)

 

Best Regards, Thorsten.

Link to comment
Share on other sites

Thank you TK for your quick answer !

 

I am aware that there is a lot to read, I put it all in case something was obviously wrong to any of you, i'm really new to microcontrollers, i probably missed something.

I still hope Phil Taylor will stumble upon this thread, as he is probably very aware of DMX specifications

I will change the line as you suggested, as you say, it's best to ensure

 

I'll keep you posted as soon as there is anything new, thank you again for your help :)

Link to comment
Share on other sites

Is it possible to generate (only generation is interesting me for now) DMX  straight from some pins (or directly through MIDI ports) ?

This quote was from your first post.  I was wondering what your physical layer looks like going to the light bar you talked about.  Are you trying to connect it directly to the LPC17 ???? 

 

The DMX specification states that it needs a dual-differential signal EIA-485 compatible.  This would mean the voltages should be +5volt signals.  It also specifies a termination on the line with a 120 ohm resistor.  With short lines I don't think the terminator is that important, but the +5v diferential signal would be very important to work reliably. 

Link to comment
Share on other sites

Hi kpete,

Thank you for your answer :smile:

I was trying to connect it directly to the LPC17, because I thought that Phil achieved that possibility in his module for the STM32.

My only doubt was about how to do it on a LPC17.
Then I read about EIA-485, and checked the Midibox motherboard (LPC17 core) sheet and started to doubt more ^^

I wasnt really sure that Phil managed to completely get rid of the hardware layer, but he seemed so when he wrote the module for the STM32 () :

Hi.

Yes sorry I haven't updated the wiki for quite a while....

Using a CORE32, I have created a software module that sends DMX using the built-in UART's of the CORE32 so yes it replaces at least one of the physical MIDI ports on the CORE32.

Thanks

Phil

(And now that I read it again, I realize it might still need a SN75176 differential bus transceiver but no a IIC anymore)

I found this morining that on the pdf from NXP about the LPC1769 :

8.16 UARTs
The LPC17xx each contain four UARTs. In addition to standard transmit and receive data
lines, UART1 also provides a full modem control handshake interface and support for
RS-485/9-bit mode allowing both software address detection and automatic address
detection using 9-bit mode.
The UARTs include a fractional baud rate generator. Standard baud rates such as
115200 Bd can be achieved with any crystal frequency above 2 MHz.

I'll try to figure out if I can achieve UART1 to be configured as RS-485 and if its compatible with the midibox motherboard :smile:

I coulnd't use the scope yesterday, maybe today, I'll keep you posted !

Again, thanks for your help :smile:

Edited by Poivrelec
Link to comment
Share on other sites

I just found that aboud DMX on http://www.pangolin.com/LD2000/dmx-about.htm

 

Data is transmitted in serial format asynchronously with the transmission speed of 250 Kbps. Voltage on both pins ("+" and "-") should be between +12 volts and -7 volts (measured to ground). EIA485 defines that the signal voltage between the two wires should be at least 200 millivolts. Higher voltage on the "+" pin and lower voltage on the "-" pin results in a digital "1". Higher voltage on the "-" pin and lower voltage on the "+" pin results in a digital "0". The ground wire is only a reference point and often used for shielding.


So maybe the fact that LPC17 doesn't provide more than 3.3V won't be a problem after all

Edited by Poivrelec
Link to comment
Share on other sites

Thanks for your replay about you trying to connect it directly to the LPC17.  I do think it can be connected to the LPC17 directly but it wouldn't be able to support 32 devices and you won't be able to go over a very long cable.  The 200mv value is the value that the Receiver hardware is to be able to receive the data and is not the spec for the transmitter.  When you connect to the cable, it looks like an inductor with capacitance to ground and a specific resistance that changes as the cable gets longer and the speed of the transmission increases.  At 250Kbaud this can be fairly lossy.  Also with you connecting the cable directly to the LPC17 any static or power disturbances between the LPC and the light fixture is focused into the LPC pin which can blow up the part.  To get it working without the buffer you can connect 2 resistors in series and connect them between ground and your 3.3v supply.  Then connect the - side of the cable to the center of the resistors.   You might even want to put a capacitor between this 1.65 volt reference to help stablize this reference.  This might get you started but I wouldn't work with this as a final solution.

 

Here is a link to the official DMX specification.  http://tsp.plasa.org/tsp/documents/docs/E1-11_2008R2013.pdf

 

Here is another link to a design that works with the PIC processor.  http://ww1.microchip.com/downloads/en/AppNotes/01076A.pdf

 

The PIC design will show you other timing parameters that have to be adheared to if it is to work with all light fixtures.  One of these is the "Mark After Break" time.  This should be at least 8us or 12us depending on which spec is shown.  I don't know where this timing is implemented in your LPC17 code or hardware.  BREAK signals are usually fairly long and the receiver of the break might be in the middle of receiving a frame when the break condition ends.  If the first character is sent immediatly after the break condition, the first character can be lost.  Thats why this is specified.  Just a guess here but this might be why your light bar is flashing because it is missing the first NULL character or the slots are being missalligned from one message to the next.

Link to comment
Share on other sites

I don't understand why this "Mark After Break" time minumum value of 8us is so short.  I would think that it should be the time to receive 1 character.  This would make the value: 1 start bit + 8 data bits + 2 stop bits.  I would add 1 just to be sure.  This would make the time 12 * 4us = 48us. 

Link to comment
Share on other sites

Hi kpete,

 

You answer is very interesting and helpful, thanks a lot !

 

I have been able to quickly use a scope yesterday, and will continue today on my free time (I don't have much lately).

What I got is a signal that seemed more or less stable, but there were some interrogations. I think I'll have to test it in much more proper conditions and a bit longer if I want to find out what's going on :) At least, I got something looking like bytes...

 

Reading your post and the links you provided, I will probably use a buffer to generate a good 5V symmetrical signal.

For now I will focus on getting the software part right (generating the break and sending the universe correctly), and when this is done, I'll switch to the hardware part and probably order some parts, maybe use other pins of the motherboard to be able to use MIDI Uarts along with DMX sending... there is a lot of work ahead of me :)

 

I will think about what you said about the MAB, and try it as soon as I can, it might help the fixture to understand what I'm trying to tell it.

 

I'll keep you posted as soon as I get results,

Thanks again !

Link to comment
Share on other sites

I was re-reading the thread and realized I didn't answer to your question, sorry :

 

The PIC design will show you other timing parameters that have to be adheared to if it is to work with all light fixtures.  One of these is the "Mark After Break" time.  This should be at least 8us or 12us depending on which spec is shown.

 

I understood that Phil achieved this with the two stop bits of the break signal. Because the baud rate was slower, it seemed to be long engouth. So I did the same :)

 

        // Setup to break Baudrate
        DMX->LCR = 0x87; // 8 bits, no Parity, 2 stop bit, no break, DLAB=1
        DMX->DLM = (break_br_diviserOptimal >> 8) & 0xff;
        DMX->DLL = break_br_diviserOptimal & 0xff;
        DMX->LCR = 0x03; // disable access to divisor latches
        DMX->FDR = ((break_br_mulFracDivOptimal&0xf) << 4) | (break_br_dividerAddOptimal&0xf);
        DMX->FCR = 0x07; // Enable and reset TX and RX FIFO
        // break code
        DMX->THR = 0x00;
        // State
        dmx_state=DMX_BREAK;

Then the interrupt deals with end of transmission, switches to DMX_SEND, sets up the higher baud rate, sends the universe...

Link to comment
Share on other sites

Very engenious to just select a very slow speed and send the NULL value.  Just as long as you can make sure the 2 stop bits are sent before changing the speed back to 250k baud again.

 

We had a DMX lighting demo done at work and they had problems with a group of fixtures flashing ON and OFF.  It was fixed by properly terminating the end fixture.  And the cables were only about 30 meters long.

 

That post I sent about 2 previous back really doesn't pertain to anything in this thread.  I was just curious as to how they detect the end of the break in the light fixtures..  I can see where a framing error would be seen if they were using the ASYNC receiver, but maybe they just switch the receiver OFF and read the IO pin directly and look for the end of the break using a bit bang process.  When the IO pin goes high at the end of the break, then switch the pin back to ASYNC receive mode within this 8us time and start receiving the universe data.  That is only 2 bit times which is extremely fast.

Link to comment
Share on other sites

  • 2 weeks later...

Hello again,

 

Sorry for the absence. I purchased two days ago a rs-485 transciever, in order to symmetrize the signal, and to have it +5V.

I followed this schematic :
 

http://playground.arduino.cc/DMX/DMXShield

 

Again, with a LED, I have some blinking (at least I guess its blinking and not continuous), but I can't try it on the scope for now. I hope I will be able to do so soon.
This time, nothing at all happens with the fixture, not even random blinking...

 

Maybe I missed something while following the schematic, do you guys see anything abviously wrong about it ?

Thanks again !

Link to comment
Share on other sites

Do you have your connectors wired right?  The pin sequence for the Midi Din connector is 1, 4, 2, 5, 3 where the connector shown in in the Arduino shows the sequence as 1, 2, 3, 4, 5.  There is a picture at the bottom of the Arduino link you posted earlier.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...