DMX

In an earlier article we attempted to connect the JNIOR to a DMX512 network in a way that would allow a theatre stage crew to control relays and other outputs through their main lighting control panel. Here with the programmable facet of the JNIOR we could help create complex special effects that can be triggered in-sync with lighting. In fact, DMX channel data can be used by the JNIOR application to trigger and manipulate activity on a LAN segment and thereby update computer screens and TV displays on stage. This can all occur with precise timing in concert with other lighting changes.

The DMX512 protocol and interface was developed over 50 years ago as a means to reduce wiring cost and to improve the mobility needed to support major concert tours in the music industry. It incorporated serial data transmission formats that were state-of-the-art at the time and that are still relevant today. Unfortunately the protocol employed a baud rate much higher than would be later recognized as standard in the computer industry. Also the limited capabilities for data synchronization and lack of error checking make interfacing difficult. Even though the JNIOR Model 410 is able to handle the RS-485 signals and was upgraded to receive 250 Kbaud data triggered on the specified serial Break Condition, we could not achieve reliable operation as a fixture through programming alone.

The issue relates to the design of the standard computer hardware component called the UART. The Break Condition that the DMX protocol uses to identify the start of a frame of data is not handled by the UART in a fashion that can be reliably used to synchronize data reception. At least it is not possible in a purely software implementation as we discussed previously. The answer lies in a simple hardware adapter that alters the DMX512 signals just enough to work correctly through the UART. We will see what that entails in the rest of this article.

 

 

DMX512 Fundamentals

Today DMX is defined by official standards. On the wire DMX512 uses EIA-485 differential signaling. We often refer to it as RS-485. You are probably more familiar with the term RS-232. As serial digital communications became more prevalent the distance limitations and noise susceptibility of RS-232 became more and more of concern. The solution, designated as RS-422, used balanced transmission lines over twisted pair which extended the distances that signals can traverse as well as the communication rates that can reliably be achieved. RS-422 connections however are point to point and as computer systems grew so did the need for networking. Soon RS-485 came along and added functionality that created a multi-drop environment where one talker can communicate with a number of listeners. RS-485 is what DMX512 needed where one (or more) lighting control panel must communicate with multiple lighting fixtures.

This basically amounts to a 3-wire network where there is one DATA+ (positive) data line and one DATA- (negative) data line along with a GND ground. The DMX standard details specific connectors (5-pin XLR) and wiring of sufficient gauge and quality. The world also wants to utilize 3-pin XLR connectors for DMX as these are prevalent in the industry through their use in audio applications. You will find a mixture of fixtures some with 3-pin and some with 5-pin connectors. Thankfully 3-pin to 5-pin adapters are readily available.

On the protocol side it was necessary to standardize. This would encourage lighting manufacturers to incorporate the technology. Over the years the protocol itself had been handled by different standardization groups and now is:

 

American National Standard
ANSI E1.11-2008 (R2008)
Entertainment Technology – USITT DMX512-A
Asynchronous Serial Digital Data Transmission Standard
for Controlling Lighting Equipment and Accessories.

 

In order to understand where we have difficulty we need to look deeper into the specifics of what is sent across the wires. You recall that DMX was invented to reduce wiring costs. Each channel in the protocol replaces a single power cable. The protocol allows for up to 512 channels and all of those multiplexed onto a single 3-wire network cable. That is a significant savings.

Each channel digitizes an analog signal into one 8-bit value. These can represent numbers from 0 to 255 and for lamps that is used to sufficiently cover the range from 0% to 100% brightness in 256 steps. Where once one channel controlled one lighting fixture, today multiple channels are assigned to each fixture to define attributes such as color and positioning in the case of motorized fixtures. In the serial world each channel is transmitted just as a byte of character data would with a start bit, 8 data bits and one or two stop bits. For DMX512 two stop bits are used. That is a total of 11 bits per channel.

 

 

The DMX protocol allows for the transmission of up to 512 channels. These are sent in sequence starting with channel 1 and up to channel 512. A Start Code is defined as channel 0 and the typical value for that is zero. The complete set of channels 0 through 512 (513 channels) is called a Frame. Frames are transmitted repeatedly one right after another with the start bit immediately following the prior stop bits at the defined rate of 250 Kbaud. We can now do some math. With 11 bits per channel and 513 channels that is a total of 5,643 bits. A bit at 250 Kbaud requires 4 microseconds and so the data part of the frame takes a total of 22.6 milliseconds. We can fit a little over 44 frames in a each second.

Now with a constant flow of channels each looking the same on the wire how do we know which one is channel 0 and which might be the one we need for our fixture? If we connect to an active DMX network we need a way to synchronize ourselves. For this the standard defines the use of a Break Condition to signal the beginning of a frame. In old days this was called an Attention Signal and it was used to wake up remote teletype equipment and there was actually a key on the Teletype for this. So back in those days this was a natural choice for DMX synchronization. A Break Condition amounts to a period of time where the signalling is held at the level of a Start Bit (Space) long enough to violate the normal byte format and cause a reception error. The receiver simply fails to see the Stop Bits where they are expected and raises a flag. This is intended to signal the beginning of a frame.

 

 

By this definition a Break Condition need only last long enough to mask the expected Stop Bits (11 bits, 44 microseconds). This causes a UART to signal a Framing Error indicating that the data it received was not properly formatted and followed by the expected Stop Bits. This error can then be used for Break detection and the synchronization of the DMX Frame. The current DMX512 specification defines the minimum time for this Break Condition to be 88 microseconds which is exactly the transmission time of two channels. The timing of this Break Condition has been reduced from prior versions of DMX512 and it is unclear if there is any risk that existing lighting fixtures may fail to operate when presented with the shorter pulse. The specification does not specify a maximum duration for the Break Condition and states only a “typical” duration of 176 microseconds.

After the Break Condition terminates there must be a brief period of time before the Channel 0 (Start Code 0x00) can be transmitted. This period is called Mark After Break and the current specification defines a minimum of 8 microseconds the time period of two bits. This too has been reduced from prior versions of the specification. A maximum duration of 1 second is defined for Mark After Break and no typical value is given.

This defines the entire sequence. First a Break Condition of sufficient duration is issued. This is followed by a Mark After Break also of sufficient duration. After this each of 513 Channels is sent with proper serial formatting. The first is the START CODE which for normal DMX is always 0x00. Following the final Stop Bits for the last Channel there can be a gap before the next Break Condition. These Frames are sent continuously and according to the specification at least one Frame needs to be sent every 1.25 seconds.

Here is what this looks like in reality. The wider pulse in the center is a Break Condition and Frame data can be seen to the right and left of it. Note that in this case all Channels are set to 0x00 and so we see only the Stop Bits for each.

 

 

One side note is that shown above are the CMOS logic signals observed after the RS-485 receivers. This signal is typically fed to the receiving hardware or UART. This image is consistent with our prior diagrams where the Marking condition is a HIGH or 1 and the Spacing condition a LOW or 0. The signals on the actual wire demonstrate the same timing but would involve dramatically different voltage levels.

There is one point that I have not mentioned. The total number of Channels included in a Frame is a maximum of 513 but that number is optional. A lighting controller may decide to only send 128 Channels in addition to the START CODE assuming that others are unused and thereby increasing the number of Frames per second. The specification defines a maximum Frame rate of around 836 Hz (Frames per second). This can accommodate fixtures that need higher Refresh Rates. The Refresh Rate for a DMX512 Universe of a full 512 Channels is around 44 Hz.

In the previous article we alluded to there being some difficulty in receiving these signals with standard computer hardware. We now have enough technical detail to understand what that reception problem might be. This is the topic for the next section.

 

The Issue with the DMX Break Condition

Now let’s look at the task of receiving a frame of DMX data from a software point of view. We will assume that you have configured the hardware to receive RS-485 signals. The JNIOR Model 410 AUX port has RS-485 capability when properly wired and configured. INTEG can provide those details and those are mentioned in other articles. The JANOS operating system has also been enhanced to accommodate DMX and includes the 250 Kbaud rate setting as standard.

In the previous article JNIOR as a DMX Fixture we covered both the proper hardware configuration for the JNIOR Model 410 and the simple Java application software that might be used to receive a frame of channel data. We took that a step further and let the JNIOR activate relays in response to changing channel levels. It is here that we noticed a reliability issue and then spent time to understand it. We discovered that it is a limitation in the design of the standard UART and not something specific to our software or even the design of the JNIOR. Here we will review those findings and then in the balance of this article present a solution.

As you can imagine it would not be acceptable for the JNIOR to receive an incorrect channel value and act upon it. On stage you might create a flicker and distract the audience or worse trigger some elaborate effect at a totally inappropriate moment. Neither contribute to receiving good performance reviews. Well our first attempt at having the Model 410 serve as a fixture worked but occasionally there was a glitch. A relay toggled inappropriately and this lead to an investigation.

We started by attempting to validate the frame of channels. We know that the START CODE should be 0x00. So we decided to first test the START CODE. Well, 0x00 was not what we were seeing and this led us to understand that the UART is not able to properly receive data immediately following a Break Condition. Let’s look deeper into it.

Every description of the inner workings of the UART describes the reception of data beginning with the detection of the Start Bit. They state that “A Start Bit is detected as the falling edge of the signal” (which at that point is moving from a Mark condition to a Space condition from HIGH to LOW). This makes sense since this can be used to synchronize the baud rate and the UART once detecting the falling edge delays 1/2 bit time to begin sampling. The first reading is then LOW (0) since it is a start bit.

The UART then can proceed to receive data bits one after another starting with the LSB (Least Significant Bit or D0). Let’s assume that we are configured for 8 data bits and no parity as is the case for DMX. Once all 8 Data Bits are collected and the byte of data fully accumulated then next bit sampled is expected to be HIGH (1) as this is the necessary Stop Bit. The UART sees the Stop Bit and pushes the data to the output buffer and notifies the system that data can be read from the port. You can see how this follows from the first figure in this article repeated here.

 

Logically then you can see how the UART might go back into some ‘Start Bit Search Mode‘  in order to pass over any number of remaining Stop Bits and dead time between character transmissions.

We mentioned previously that in the case of a Break Condition the Stop Bits are missing. Here the UART receives 8 Data Bits or what it hopes are 8 Data Bits and then fails to detect the Mark condition signalling the presence of a Stop Bit. The typical UART then pushes the data to the output buffer and signals the processor that data can be read from the port. It also sets a Framing Error flag and well-written serial drivers handle the error accordingly.

Here is where your logical thinking might fail you. Once the UART signals a framing error you would like to think that it reenters the aforementioned ‘Start Bit Search Mode’. This would take the UART through the balance of the Break Condition and past whatever Mark After Break is present to the very next falling edge of the signal. This then allowing it to reliably and properly receive the very next valid byte of data. Well, surprise, it does not work that way.

Instead the UART continues to sample bits based upon its internal baud rate clock. It accepts the very next LOW (0) bit as a Start Bit and proceeds to process the following 10 or 11 bit times as another byte of data. This is why from the software side a Break Condition usually presents itself as more than one 0x00 byte each with an associated Framing Error. By itself this is not an issue as you can accept one or more Framing Errors as an indication of the Break Condition. In fact you could use this to detect a short Break from a long Break. But let’s look closer at what happens at the very end of the Break.

At the conclusion of an arbitrarily long Break Condition the signal returns to a Marking state. We have reached the Mark After Break but it is highly likely that the UART is still accumulating hopeful data bytes. Eventually it sees the Mark as a valid Stop Bit. The result is that a byte is then output by the port and there is no Framing Error. There is no way for software to determine if this is the first valid data byte (START CODE) or a bogus trailing byte formed out of the end of the Break Condition.

In testing we can see that this indeed is occurring. Since data bits are transmitted from least significant to the most significant, depending on signal timing this bogus byte can be seen to contain any one of the following: 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE or 0xFF. Perhaps you can see that this result depends on just what Data Bit the UART thinks it is receiving at the point when the Mark After Break begins. There is actually one additional case and that being when the data is actually the first valid data byte after the Break. This effect depends highly on the duration of the Mark After Break as well.

Matters can be even worse. In DMX512 the Mark After Break can be as short as two bit times or 8 microseconds. That means that it is possible that the UART does not even look for a Stop Bit until the signal is deep into the START CODE byte. Since the START CODE is itself 0x00 the UART might then grab one of those data bits as a Start Bit and, well, fail to receive several channels of data. How can this be? Are UART designs defective?

Well let’s not jump to that conclusion just yet. Let’s give the hardware developers the benefit of the doubt at least initially. First we should understand that once the computer industry embraced serial data communications use of the Break Condition fell by the wayside. Protocols used Start of Header (SOH) bytes and other means for synchronizing data blocks. These tended to include byte counts, error checking and even error correction. These days there is even data compression and data encryption. The Break Condition not only fell out of use but also started to disappear from serial communications documentation.

Meanwhile the industry started to look into the reliability of data transmission lines. In the early days RS-232 cabling was not what it is today and it was very susceptible to external electrical noise. Also remember that we were still using machines developed in the early half of the 20th century. These were power hungry electro-mechanical contrivances that spewed out electrical noise with reckless abandon. RS-232 signals often experienced data disruptions some as brief as an incorrect value of a single bit up to the loss of entire blocks of bytes. There were even situations where communications were completely blocked out for lengthy periods of time. Perhaps for as long as the nearby noisy equipment remained in use. This led to better cabling. It led to improved communications standards like RS-422. It prompted the need for error detection and motivated a lot of creativity on the error correction front. Simultaneously the Federal Communication Commission (FCC) put forth standards for controlling RF and electrical noise emissions and prompted certifications making new equipment meet the stringent requirements.

A UART design that utilized a “Start Bit Search Mode” fails to perform properly in a noisy environment. In the case when a Stop Bit is damaged by noise and thereby missed by the UART, an approach that accepts the very next falling edge as a start bit falls on its face. It fails to re-synchronize quickly. Many bytes of data then are lost even though electrically the signals are undamaged. Error correcting schemes just could not handle it. They determined that the current UART approach performed much better and, well, what is this Break Condition anyway?

We can only guess at how we got to where we are today. It is actually a surprise that a 50-year old protocol would still be as active today and it would still rely on synchronization techniques like the Break Condition. Of course it is not a really issue as DMX fixtures are developed to properly receive these signals. We are just a bit hampered in trying to use standard computer hardware. So what can we do about it? That is our next topic.

 

Correcting the DMX512 Protocol

We stand little chance of “correcting” the DMX512 protocol. With over 50 years worth of legacy DMX equipment out there a change in the design of the protocol is just not an option. The ability for DMX to inter-operate with standard computer hardware is just not that critical of a need. We have also exhausted any possible software solution to this issue. So what can we do? Some kind of hardware solution will be needed if we want to develop a JNIOR that can be used as a DMX fixture. What form will that take?

Obviously lighting fixtures all over the world read DMX channels seemingly without difficulty. So we know we can do it. Does this require a custom UART implementation in some FPGA component? Do we have to dedicate some PIC processor or other device to process incoming DMX bit by bit? Are there standard DMX chip level devices out there to make it easy? It certainly all cries out for some research. But first let’s see if there is some simple and creative way to address the issue.

The problem breaks down into two separate issues:

  1. The UART is unable to synchronize after a Break condition and reliably read the first START CODE byte.
  2. The trailing edge of the Break Condition can generate unexpected data not identified with a Framing Error.

Clearly if we use a Framing Error indication to signal the reception of a Break Condition and we are 100% assured that the next valid data byte is accurately representing the START CODE we are good to go. We assume then that the processor has enough horsepower to receive and buffer all 513 channels (if they are present) without error. This can be done with low-level interrupt routines avoiding any dependence on the processing load in the JNIOR. In fact all of this has already been implemented in JANOS and deployed into the field. Those techniques were tested in the prior article.

The Mark After Break condition specified by the DMX512 protocol is a minimum of 8 microseconds. That is just two bit times. This is unfortunate. If this Mark After Break condition were to be held at least 11 bit times (44 microseconds) then any UART would be assured of seeing some part of the condition as valid Stop Bits. The UART then would be guaranteed ready to receive the very next data byte which is the START CODE.

If we somehow could extend the Mark After Break that would insure the reliable reception of the channel data. That by itself is not enough since we know that the trailing edge of the Break Condition can generate a data byte that is not flagged with a Framing Error. This would confuse us as there is no real way to determine if this is the START CODE or a bogus addition to the stream.

Now if we could somehow limit the Break Condition to a single byte we would receive one and only one byte flagged with a Framing Error. The UART would not see an additional Start Bit and thereby insure that the next byte we see is in fact the START CODE. We know that the Break Condition is at least 88 microseconds at its shortest. That is exactly two data byte times (each of 11 bits = 1 start bit + 8 data bits + 2 stop bits). So if we truncated the Break Condition at exactly 44 microseconds which would generate 1 byte with a Framing Error, there is another whole byte’s worth of time that could be added to the Mark After Break. This would satisfy our interest in extending the Mark After Break for at least a byte time. At a minimum it would then be 52 microseconds (44 borrowed from the Break + 8 original microseconds).

 

The Hardware Solution

Our hardware needs to truncate the Break Condition. We need only hold it long enough to mask the first Stop Bit and thereby force the Framing Error. This needs to be achieved without risk of causing other Framing Errors. With a little thought we developed the following logic.

 

This circuit is inserted in the CMOS logic stream after the RS-485 receivers and before input to the UART. The RXD signal from the receiver enters at the left. We will use the OR gate (U7) to truncate the Break Condition. This will pull the signal HIGH at the appropriate time but otherwise allow the normal serial stream through. The output then is TXD to be delivered to the UART on the right.

The CD4024B (U6) is a 7-stage counter and it is reset (RST) or restarted with any HIGH Marking condition on the incoming data. This means that the count is not allowed to progress very far except during the Break Condition where there is no reset (RST). This in essence times the duration of the Break Condition. Note that when the output of the 7th stage goes high (count >= 64) the OR gate then pulls the TXD signal high effectively truncating the Break Condition. The signal output is then held HIGH until the Mark After Break arrives and resets the counter. At this point the incoming signal is HIGH and we have effectively transferred time from the Break Condition to the Mark After Break. This is exactly what we want.

The UART will throw the Framing Error as soon as the first Stop Bit is not detected. We don’t want it to see any potential Start Bit after that. To be safe then we truncate the Break Condition after the 10th bit time right after the first Stop Bit. This means that we must truncate the Break Condition precisely after 40 microseconds and this must occur at the 64th count when the 7th stage goes high. As it turns out 40 microseconds divided by 64 is 0.625 microseconds the precise period of a 1.600 MHz clock. Those are readily available. So we clock the counter with a 1.600 MHz signal using oscillator U4.

One last detail to consider. There is no upper bound on the duration of the Break Condition. That means that once we truncate the Break Condition we need to hold it for potentially a very long time. So we cannot allow the counter to continue to run. Once the 7th stage goes HIGH we need to hold it there. A second OR gate (U5) masks the incoming 1.600 MHz clock signal at that point effectively stopping the counting. And, miraculously, we’ve got it covered.

To test this we created a prototype adapter which implements an isolated DMX512 standard port. The signal passes through our circuit and then a standard RS-232 transceiver is used to communicate with the JNIOR AUX port. One advantage this has is that any Model JNIOR with an AUX port can be used as a DMX fixture. Whereas only the Model 410 supports RS-485 directly and can be used as described in the prior article.

 

 

Here the few components involved sit in the lower lefthand corner. These Surface Mount devices take up almost no real estate and this is perfect for a new model of the JNIOR sporting a DMX512 input. Okay, so does the circuit work?

 

 

Here we see another oscilloscope trace. The yellow signal is RXD as received from the RS-485 receiver. This is what enters the schematic from the left. The blue signal is TXD and what we will supply to the UART. This exits on the right of our schematic. The wider pulse in the center is our Break Condition.

On the yellow trace we see that the Break Condition supplied by the DMX network is about 100 microseconds and it is followed by a brief Mark After Break which looks to be somewhat less than 50 microseconds. We know that this signal is problematic as it is from the same source used in the prior article. Note here that the START CODE and all channels happened to be 0x00. So those high pulses are Stop Bit pairs.

Now the blue trace is the result. The Break Condition has indeed been truncated. The vertical cursor lines are positioned to measure the duration of the new Break Condition. On the right we see the delta-t to be the precise 40 microseconds we had hoped for. We can also see that the balance of the time in the Break Condition has now been added to the Mark After Break.

Does this allow the JNIOR to be used as a DMX fixture? In fact it does and there is absolutely no glitch or reliability concern. Here is a short video showing relays responding to a DMX channels. A channel value greater than 127 is used to signal closure of a relay. The JNIOR’s 8 relays are mapped to consecutive channels.

Success!

Of course this would need to be evaluated with a wide range of DMX512 signal sources. The Java application on that JNIOR in the video is essentially that discussed in the previous article. It would be useful to reiterate its operation but that is beyond the scope of this article. If you should be interested in using a JNIOR as a DMX fixture just let us know. We can likely supply you with one of these prototype adapters and the application programming is open source from us. If you already have a JNIOR then your are almost there.

Now we have everything that we need to create another JNIOR Model with its own Isolated DMX512 input!

We should note that not all UARTs are created equal. There are likely UART implementations that do properly handle synchronization after the Break Condition. If you have one of those then you are golden. In the case of the JNIOR we were not so lucky. While the adapter was described above as prototype we do have several that we can supply. It is not clear that there would be any long term demand for this. A model of the JNIOR directly providing a DMX512 electrically isolated input is now feasible and would likely include the circuit as described here. Contact INTEG to find out more.

The Model 412DMX generates a DMX512 Universe and allows the JNIOR to control DMX fixtures like those used in stage lighting. What if you needed a fixture with relays that can be controlled by DMX? Perhaps you need to output channels over a 4-20ma loops. Maybe you need a 10 VDC output signal to control LED house lighting. Can the JNIOR receive DMX? Can the JNIOR be a DMX Fixture?

We showed you how you could control DMX fixtures with a standard Model 410 in a White Paper available here:

http://www.integpg.com/downloads/docume … tation.pdf

Now we have the 412DMX JNIOR designed for that purpose. Can the Model 410 also serve as a DMX fixture? Yes, it can. I’ll show you how here and we’ll see how we manage to accommodate some of the unique aspects of the DMX512 format with the JNIOR.

Cabling

We can use the JNIOR Model 410 because the AUX port is compatible with RS-485. In the white paper explaining how the 410 can be used to control DMX fixtures we described an adapter cable taking the DB9 output from the JNIOR and presenting the proper female XLR connector for DMX. Now since a DMX fixture always has both a male and female 5-pin XLR connectors, our cabling has to be slightly different. Note that you can do this with the 3-pin XLR (as I have) if that is appropriate for your situation.

Here is an example of one that we put together.

This can be constructed by splicing into a standard DMX extension cable. A number of DB9 adapters with screw terminals like the one pictured can be found on Amazon. Note that you will want one with large screws compatible with larger wire sizes. DMX wiring is typically of a larger diameter and you will need to successfully clamp two wires in each of three positions on the adapter.

Here is the pin numbering. Note that wire colors vary.

        Signal           XLR      DB-9 Male
--------------------  ---------  -----------
Signal Ground (GND)       1          5
Data (D-)                 2          3
Data (D+)                 3          7
Not Used (NC)            4,5     1,2,4,6,8,9

This cable allows the JNIOR to be a DMX FIXTURE.

THE RESULTING DMX CONNECTION IS NOT ISOLATED. We recommend using an isolated power supply for the JNIOR and not sharing that voltage with other circuits. Take great care in making ground connections. Note that the JNIOR relay outputs are naturally isolated.

Serial Connection

Connect the adapter to the Model 410 AUX serial port as I have in this photo and connect this to the DMX network. Note that the 412 and 414 are not RS-485 compatible and cannot be used for this purpose.

The serial port parameters should be set as follows. This is done through the Dynamic Configuration Pages (DCP) that should come up when accessing the JNIOR using your browser. You enable the RS-485 mode here so the AUX port output doesn’t disrupt the DMX communications before you have a chance to run the DMXFIXTURE application that I will describe. That application will also configure the AUX port just to make sure that all is well.

If you encounter “Applets” instead of the DCP then your Series 4 needs to be updated or you have a Series 3. The latter also cannot be used for this application. You will need to update your JNIOR to JANOS v1.6.6 or later for the functionality to be described here.

Data

With the JNIOR Model 410 wired to the DMX network and the AUX serial port properly configured the unit should be receiving data. There is a simple way to check that. You can see data without any application running just by using the IOLOG command. Here we enter the Console (or Command Line Interface) and use this command.

CODE: SELECT ALL

InfoComm_LED /> help iolog
IOLOG

Options:
 -T             Indicate transitions
 -R             Reset logs
 -A             AUX Serial log
 -S             Sensor Port log
 -O             Output to stdout

Generates jniorio.log file from available logs.

InfoComm_LED /> iolog -ao
--  07/02/18 15:42:46.098
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--80--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--FF--00--FF--80--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--83--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--80--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--FF--00--FF--80--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--83--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--80-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--FF--00--FF--80-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--83--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-80--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--FF--00--FF-    ................
-80--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--83--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-    ................
-00--00--00--00--00--00--00--00--00--00--00--00--00--00--00-        ...............

InfoComm_LED />

If you scan down in the above output and look through the data you will see that there are a couple of channels at 100% (0xFF) and a couple near half (0x80’ish). There are two pretty major issues in trying to read these bytes with standard library read() functions.

  1. How do we know how to find Channel 1? There are many more than 512 bytes shown here. If you read 512 bytes what you get could start anywhere.
  2. The data rate at 250 Kbaud supplies 44 complete channel sets per second! That absolutely will overrun the buffer before you can process any of it. The overrun would likely further obfuscate the data.

The fact is that the standard serial communications routines that you may be used to are just not usable here. JANOS will come to the rescue. But first let’s take a look at the data stream so we understand how this is to be resolved.

DMX Format

The DMX data on the RS-485 lines conforms to standard asynchronous serial data with 8 data bits, 2 stop bits and no parity. The bits are marched out from least significant (LSB) D0 to the most significant (MSB) D7. Each byte is called a “Slot”. The standard implementation transfers a START CODE and 512 channels in a total of 513 slots. The START CODE for normal DMX data is 0x00.

The beginning of the sequence is signaled with a Break Condition. This BREAK can be detected by the fixtures which allows them to synchronize with the stream. After the BREAK comes the START CODE (0x00 – NULL START) followed by the value for Channel 1 on through to Channel 512. Not all 512 channels need to be part of the transmission. The number of channels may vary by DMX controller. The complete implementation provides all 512.

On the oscilloscope the BREAK looks like this. Here all of the channels are 0X00 and so you see only the STOP BITS. That long low puilse is the BREAK.

TEK0002.JPG
TEK0002.JPG (100.6 KiB) Viewed 66 times

The issue is that the BREAK is difficult to handle with the standard serial port. It results in a FRAMING ERROR. During the break the signal is held at a low level. When the receiving serial UART expects the STOP BITS and they aren’t there it throws a FRAMING ERROR. While that can be detected and your application can be notified there still is no way to insure that the next bytes read from the port are those that follow the break. They may have been buffered some time before. They may be overrun by oncoming data.

In order to handle this and properly capture a reliable channel set, there must be a special function for that purpose in the AUX port class (AUXSerialPort). Of course, being the author of JANOS, I have implemented exactly what we need. And, those details are next…

Packet Capture

To read the DMX Packet (START CODE plus up to 512 Slots/Channels) we need to detect the Break Condition and then reliably collect as many as 513 serial bytes that immediately follow. Under many other RTOS implementations we would need to write an interrupt driven routine both to detect the Break condition and then also to collect the data. The JNIOR executes application programs written in a managed language (Java) and one does not have low level access to write things like serial interrupt routines. That is actually a good thing as the user generally does not have the programming experience. Such low level user programming often leads to unstable/unpredictable operation.

Here we rely on JANOS to maintain reliable operation. Low level interrupt routines have already been implemented to buffer incoming serial data and otherwise issue a notification of errors. Recall that the Break Condition manifests itself and one or more FRAMING ERRORS. But we have already established that reading buffered serial data and receiving asynchronous notifications is not going to be sufficient for capturing a DMX packet. This is where we benefit from having developed JANOS in-house and having authored 100% of it. Here we identify a need and are able to promptly and correctly implement a solution.

AUXSerialPort.readAfterBreak(byte[] buffer)

I have added the readAfterBreak() method to the AUXSerialPort class in the JANOSClasses.jar library. From the naming its use is self-explanatory. Here you create a buffer as a byte array and pass it to JANOS. The operating system enables the capture and then blocks the thread until the data collection completes. At the low-level JANOS sets up the buffer with a pointer and goes into a kind of ‘armed’ state. The interrupt routine that detects FRAMING errors has a tiny bit of code that checks for an armed capture and ‘triggers’ the collection of data. The interrupt routine that collects and buffers serial bytes from the port has code to set each byte aside into the buffer that you have provided. Once triggered the capture passes into the a ‘collection’ mode. When the buffer is full (or when another Break Condition is detected) the capture is ‘complete’ and the application program can proceed now with a byte array containing the DMX data.

Now to benefit from this new feature, you will need to update your Series 4 to run JANOS v1.6.6 or later. At the moment this is Beta code. We would make it available if you were to want to try this before its release. All you need do is ask.

Next we need to try it out…

DMX Capture Test

Here we create a project in Netbeans (making the few settings needed to target it for JANOS) and create the following test program. This merely takes control of, and fully configures, the AUX port in case it has not been configured through the DCP. Lines 23 and 24 test our new method. The rest merely dumps the byte array content for review.

package dmxfixture;
 
import com.integpg.comm.AUXSerialPort;
import com.integpg.comm.SerialPort;
 
public class Dmxfixture {
 
    public static void main(String[] args) throws Throwable {
 
        // AUX port access and configuration. We need to open the port to gain exclusive access and
        //  set the proper baud rate and format. We enable RS-485 mode and make sure that the receivers
        //  are enabled. With normal RS-485 you would disable the transmit drivers. Our adapter doesn't
        //  bridge the transmit and receive lines anyway and the DCP configuration automatically disables
        //  the drivers. It is here for clarity.
        AUXSerialPort aux = new AUXSerialPort();
        aux.open();
        aux.setSerialPortParams(250000, 8, 1, SerialPort.PARITY_NONE);
        aux.setRS485(true);
        aux.enableReceivers(true);
        aux.enableDrivers(false);
        
        // capture a complete frame using our new method
        byte[] data = new byte[513];
        aux.readAfterBreak(data);
        
        // The remainder here is a fancy dump (skipping the START CODE). Note how JANOS implements the
        //  printf formatting for us.
        for (int i = 1; i < data.length; i++) { 
            if (i % 10 == 1)
                System.out.printf("%04d  ", i);
            System.out.printf("%4d ", data[ i ] & 0xff);
            if (i % 10 == 0)
                System.out.println("");
        }
        System.out.println("");
    }
    
}

To run this we first build it in Netbeans. Then using the DCP we open the Folders tab and select the /flash folder. We then drag the dmxfixture.jar file from the project to the /flash folder (it can be executed from the root too). Then under the Console tab we log in and execute the application. The following is the result.

CODE: SELECT ALL

InfoComm_LED /> dmxfixture
0001     0    0    0    0    0    0    0    0    0    0 
0011     0    0    0    0    0    0    0    0    0    0 
0021     0    0    0    0    0    0    0    0    0    0 
0031     0    0    0    0    0    0    0    0    0    0 
0041     0    0    0    0    0    0    0    0    0    0 
0051     0    0    0    0    0    0    0    0    0    0 
0061     0    0    0    0    0    0    0    0    0    0 
0071     0    0    0    0    0    0    0    0    0    0 
0081     0    0    0    0    0    0    0    0    0    0 
0091     0    0  255    0  255  128    0    0    0    0 
0101     0    0    0    0    0    0    0    0    0    0 
0111     0    0    0    0    0    0    0    0    0    0 
0121   131    0    0    0    0    0    0    0    0    0 
0131     0    0    0    0    0    0    0    0    0    0 
0141     0    0    0    0    0    0    0    0    0    0 
0151     0    0    0    0    0    0    0    0    0    0 
0161     0    0    0    0    0    0    0    0    0    0 
0171     0    0    0    0    0    0    0    0    0    0 
0181     0    0    0    0    0    0    0    0    0    0 
0191     0    0    0    0    0    0    0    0    0    0 
0201     0    0    0    0    0    0    0    0    0    0 
0211     0    0    0    0    0    0    0    0    0    0 
0221     0    0    0    0    0    0    0    0    0    0 
0231     0    0    0    0    0    0    0    0    0    0 
0241     0    0    0    0    0    0    0    0    0    0 
0251     0    0    0    0    0    0    0    0    0    0 
0261     0    0    0    0    0    0    0    0    0    0 
0271     0    0    0    0    0    0    0    0    0    0 
0281     0    0    0    0    0    0    0    0    0    0 
0291     0    0    0    0    0    0    0    0    0    0 
0301     0    0    0    0    0    0    0    0    0    0 
0311     0    0    0    0    0    0    0    0    0    0 
0321     0    0    0    0    0    0    0    0    0    0 
0331     0    0    0    0    0    0    0    0    0    0 
0341     0    0    0    0    0    0    0    0    0    0 
0351     0    0    0    0    0    0    0    0    0    0 
0361     0    0    0    0    0    0    0    0    0    0 
0371     0    0    0    0    0    0    0    0    0    0 
0381     0    0    0    0    0    0    0    0    0    0 
0391     0    0    0    0    0    0    0    0    0    0 
0401     0    0    0    0    0    0    0    0    0    0 
0411     0    0    0    0    0    0    0    0    0    0 
0421     0    0    0    0    0    0    0    0    0    0 
0431     0    0    0    0    0    0    0    0    0    0 
0441     0    0    0    0    0    0    0    0    0    0 
0451     0    0    0    0    0    0    0    0    0    0 
0461     0    0    0    0    0    0    0    0    0    0 
0471     0    0    0    0    0    0    0    0    0    0 
0481     0    0    0    0    0    0    0    0    0    0 
0491     0    0    0    0    0    0    0    0    0    0 
0501     0    0    0    0    0    0    0    0    0    0 
0511     0    0 

InfoComm_LED />  

We note that channels are correct. Here we go over to the 412DMX controlling this DMX network and check Kevin's DMX panel page for comparison.

Putting it to Work

Now we can receive a DMX frame and read the individual channels what can we do with it? I mean other than dump it?

Well Kevin has defined an eight channel fixture starting at DMX channel 121. The idea being that each channel would correspond to a JNIOR Relay Output. Channel settings from 0-127 would result in an open/off relay and values in the range 128-255 would close the relay. You can imagine any use that you would want given the flexibility that you now have in JNIOR programming. Let's implement this particular fixture.

The approach will be to sample a DMX packet periodically and set the relays appropriately. There is no need to catch every DMX packet and in fact we are not likely going to be able to do that. We are also going to be considerate of the JNIOR CPU and anything else that the unit might want to be doing. We will sample say every 1/4 second and sleep in between.

Here is the program. This uses an infinite loop to sample the DMX stream about 4 times a second. The starting address must be defined in the Registry. This could be cached. With this implementation you can change the starting address without rebooting or restarting the DMXFIXTURE program. It is presume that you would start the DMXFIXTURE program automatically at boot with a Registry Run key.

package dmxfixture;
 
import com.integpg.comm.AUXSerialPort;
import com.integpg.comm.SerialPort;
import com.integpg.system.JANOS;
 
public class Dmxfixture {
 
    public static void main(String[] args) throws Throwable {
 
        // AUX port access and configuration. We need to open the port to gain exclusive access and
        //  set the proper baud rate and format. We enable RS-485 mode and make sure that the receivers
        //  are enabled. With normal RS-485 you would disable the transmit drivers. Our adapter doesn't
        //  bridge the transmit and receive lines anyway and the DCP configuration automatically disables
        //  the drivers. It is here for clarity.
        AUXSerialPort aux = new AUXSerialPort();
        aux.open();
        aux.setSerialPortParams(250000, 8, 1, SerialPort.PARITY_NONE);
        aux.setRS485(true);
        aux.enableReceivers(true);
        aux.enableDrivers(false);
 
        // here we create an infinite loop to continuously process the DMX data
        byte[] data = new byte[513];
        for (;;) {
            
            // capture a complete frame
            aux.readAfterBreak(data);
            
            // Obtain the starting address. If it is invalid or not defined no action is taken.
            int addr = JANOS.getRegistryInt("DMX/Address", 0);
            if (addr > 0 && addr < 505) {
                
                // Although we don't have to we are going to collect all of the relay states
                //  and set them simultaneously. This will also take advantage of signed values
                //  in Java. Values in the range 128-255 will appear to be negative if we don't
                //  mask them with 0xff.
                int bits = 0;
                for (int i = 0; i < 8; i++) {
                    if (data[addr++] < 0)
                        bits += (1 << i);
                }
                JANOS.setOutputStates(bits, 0xff);
            }
            
            // sleep for a quarter second
            System.sleep(250);
        }        
    }
    
}

This program should be pretty easy to follow. Let's test it.

Demonstration

A video can best demonstrate the operation of this program. Here we have a DMX application running on a 412DMX (10.0.0.242) allowing us to vary the channels that we associate with our 410 fixture. A separate Model 410 running our DMXFIXTURE (10.0.0.250) program can be monitored remotely through its DCP page. Here we overlap the two browser entities and we can see how modifying the channel fader results in the relay status change out across the DMX network.

Reliability

Let's look into potential error conditions and the reliability of this approach. The DMX format typically supplies nearly 44 frames per second. If there is a communications error, due to electrical noise for instance, one and possibly up to a few frames might be in error. For a light fixture this might cause a minute flicker or some small flinch in pointing. But, given the frame rate it is quickly corrected and might not be even noticeable. If we are interpreting a frame with our program we need to be extra careful not to trigger a chain of events based upon an error packet.

Typically in data protocols we would have some form of checksum or CRC which we can use to identify an erroneous transmission so it can be ignored. There is no such thing in the DMX512 protocol. So what steps can we take?

Well to start we should verify that the START CODE is the expected NULL START 0x00 and ignore any frame with a different code. The controller might actually be inserting those and we must ignore them. I will adjust the program to check this.

Well... The START CODE is returning 128 (0x80) and the channels appear to be properly registered (e.g. in the right place). Now to look into this.

Synchronization After Break

The DMX512 specification defines the width of the Break Condition as something greater than 92 microseconds. It is important to note that it is something greater than twice that of a single slot time (the time to receive a single byte) of 44 microseconds (11 bit times - start bit, 8 data bits and 2 stop bits). It is not a precise multiple of slot times or even bit times. This forces the receiver to synchronize with each and every packet.

Given this I could make the argument that the Mark After Break should be at least one slot time of 44 microseconds in order to insure that the leading start bit of the first slot is successfully interpreted. The DMX512 specification however specifies the minimum Mark after Break of 12 microseconds. This puts us at the mercy of the UART design and its ability to synchronize following a Break Condition of arbitrary length. There are a number of possible outcomes that depend on what the UART decides is the first STOP BIT once the Break Condition passes.

  • For example, if the beginning of the Mark After Break is seen as a valid STOP BIT then a 0x00 byte is received AHEAD OF the normal NULL START code 0x00. This extra 0x00 can be interpreted as a valid START CODE but all of the channel slots are off by 1. Channel 2 would have the value for Channel 1. This is an ERROR!
  • If the Mark condition just slightly into to Mark After Break is interpreted as a valid start bit then an extra 0x80 is received AHEAD of the START CODE. This might be seen as a bad packet if the START CODE is verified. Channels are also shifted if values are used. This is a ERROR!
  • The above continues with each bit time advance into the Mark After Break generating an initial extra byte of 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE and 0xFF depending on the length of the Mark After Break. In each case the START CODE would then be considered the Channel 1 value. ERRORs result!
  • With a short Mark After Break the UART might look at a low bit value in the START CODE as a missing STOP BIT and generate yet another FRAMING ERROR. Again depending on the timing the START CODE might be returned as 0x80 with the first STOP BIT actually being interpreted as the MSB. In this case the Channel data is properly positioned. This is actually the most common mode I am seeing in the current set up. It is timing sensitive. This is also an ERROR!

If you follow this logic you might see that it is possible that it may take a couple of regular slot times before the UART grabs something it is happy about. It is all about the synchronization aspect of the hardware design.

The question is how to know when you are receiving valid data and properly aligned slots? Is there a solution to this?

A UART that requires a Marking Condition before attempting to detect a START BIT (falling edge) would function properly. Apparently they don't work this way. At least not all of them.

UART Issue

The problem that we run into is an ancient design flaw in serial ports.

A Framing Error results when the UART (RX SCI) expects a Stop Bit and none is detected. A Stop Bit is a high (1 Marking) and during a Break Condition the signal is held low (0 Space) so a Framing Error is quickly encountered. Now most descriptions of UART logic suggest that after a Break the UART locates the next Start Bit (0 Marking) and that this is detected by a high to low transition of signal (1 -> 0). Logically it is done that way for asynchronous reception as the UART clock needs to synchronize and then sample the middle of each bit period.

In reality after a Framing Error the UART seems to see the next low (0 Space) as a Start Bit and continues to read bit data. As a result Framing Errors are repeated throughout the break period. A bogus byte value might appear to be properly read if the tail end of the Break Condition aligns with the UART in a way to make the high (1 Marking) after the Break look like a Stop Bit.

The likelihood of this bogus data byte and its content can vary depending on the length of the Break and the length of the Marking after the Break and before actual data is present. Since bytes are serialized LSB first these extra bytes look like one of 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 and even 0x00.

If the Marking after Break is brief (only a few bit times) and the alignment falls such that the UART looks at bits in the first byte of data for that magic Stop Bit, you will receive an incorrect value for the fist byte. It is conceivable that the UART might take several bytes before synchronizing and providing real data.

If the UART simply fell into a mode whereby it actually did search for the next Start Bit by looking for a valid high to low transition (1 -> 0), you would get a single Framing Error followed by the proper collection of data. But no... after 50+ years we have not addressed this issue. I half recall struggling with this exact thing maybe 30 or so years back now. The fact that it is still an problem is not impressive.

I guess I shouldn't be surprised in that these hi-tech MCU processors all still include the Real Time Clock (RTC) circuit first designed for the very first digital watches in the late 1960's. This forces us to parse time into Day, Month , Year, Hour, Minute and Seconds as if setting a watch on your wrist. In fact Seconds can only be reset to 00 and not directly set. On boot we have to read the time and reassemble it into Linux or Internet time as a tally of milliseconds since some epoch. Lots of work that causes loss of precision. And the ideal would be a non-volatile battery-backed 64-bit millisecond counter. Sometimes silicon space is limited and this counter would save lots of that. But no... these integrated circuit companies aren't as swift as we would like to think.

Since DMX512 signals can have different lengths of Break and Marking after Break and these can vary depending on source, and since the protocol has no leading header that can be used in identifying valid frames, we are NOT ABLE to reliably receive data. Note that if the DMX512 Standard had forced the Mark After Break to be at least one data Slot long (> 44 microseconds) then UARTs would likely properly synchronize and reliably present the first byte of data. But the spec does not and the problem is that changing the standard now does not correct all of the DMX controllers already in use all over the world. So it is what it is.

So for us to insure that we read a valid frame, we need to resort to some trickery, filtering and indeed AI. While that can be fun, it's unfortunate.