scieee AI-readable full text Open interactive document viewer

Ethernet Stage Lightning Protocol: An Alternative System for professional Lightning Equipment with Legacy DMX Compatibility

Pedro Emanuel Fernandes Magalhães

Full text

FACULDADE DE ENGENHARIA DA UNIVERSIDADE DO PORTO Ethernet Stage Lighting Protocol: An Alternative System for Professional Lighting Equipment with Legacy DMX Compatibility Pedro Emanuel Fernandes Magalhães Mestrado Integrado em Engenharia Eletrotécnica e de Computadores Supervisor: Prof. Dr. Paulo Portugal March 1, 2015 i ii Abstract This document introduces an alternative to the current stage lighting protocols, presenting a flexible and reliable solution that, by studying the previous technologies and taking in consideration their advantages, explores new and intuitive features that are part of an architecture developed for this Dissertation. The architecture of the system is not only based on current technologies that allow its expandability, but it also follows the principles that defined stage lighting, therefore increasing the complexity of the network without affecting the overall performance and limiting the rigging process. It also allows the inclusion of devices compatible with the previous protocols, embedding them seamlessly into the new system. A working prototype using standard development tools has been developed implementing the basic features described by the system architecture, using standard development hardware and software platforms, therefore easily portable. iii iv Acknowledgements I would like to thank Professor Paulo Portugal at Faculdade de Engenharia da Universidade do Porto for accepting me as a Dissertation student, and for all the help and support throughout its planning and realization. I would also like to thank Sirilanka Espetáculos, Lda for the chance to work as a lighting technician for them for the past five years. It was this opportunity that led me to work with lighting equipment in the first place and eventually led to the proposition of this Dissertation. Lastly, but not less importantly, I would like to thank my family for their continued support during the years spent in this course, and my friends, inside and outside the academic and musical environment, for all the help and encouragement. To all the mentioned entities, thank you. Pedro Magalhães v vi “What is the purpose of knowledge if it lays abandoned in dead shelves?” Cidália Fernandes vii xiv LIST OF TABLES Abbreviations DMX Digital MultipleX AMX Analog MultipleX LED Light-Emitting Diode PAR Parabolic Aluminized Reflector RGB Red Green Blue MAB Mark After Break RDM Remote Device Monitoring Art-Net Artistic Network TCP Transmission Control Protocol UDP User Datagram Protocol IP Internet Protocol DHCP Dynamic Host Configuration Protocol MAC Media Access Control xv Chapter 1 Introduction Intelligent Lighting is the usage of controllable light fixtures to illuminate a stage or theatre, differing from the traditional stationary lighting which relied on simple static lighting positioning. Today, the concept of lighting has evolved with the technology in a way that it is used in almost every outdoor or indoor concert, theatres and even in home lighting. Figure 1.1: Avolites Sapphire Touch controlling the lighting equipment. [1] The various types of lighting equipment, such as moving heads, LED spots, washes, etc, have the ability of changing colour, shape and movement of their output to create different environments, or focus the audience into a specific spot, actor or performer. The programming of a show is crucial to the application of these concepts, so all of the effects and cues have to be created by the programmer, lighting engineer or technician responsible for the show. Overall, their performance defines the visual experience, which is a vital part of the show. 1 2Introduction Lighting systems require a high level of control, so different technologies were created over the years to accommodate the increasing complexity of lighting equipment, cabling and rigging. However, the manufacturers were creating their own proprietary control solutions, not compatible with products from other companies, so it was necessary to have multiple controllers to handle the different types of machines. In 1986 an universal protocol was developed to prevent the manufacturers to diverge, and to ensure that all the devices could be controlled by one single endpoint, using the same communication standard. This protocol is the DMX512, or simply DMX, and it is, even today, the standard for lighting equipment. [4] Figure 1.2: Pink Floyd, The Division Bell tour, 1994, the greatest show in the history of mankind. The complexity of these systems has been increasing since the development of moving heads, which is leading the the DMX technology to a limit. The limitations of the standard DMX512 protocol are becoming more obvious, which imposes more restrictions in its usage. 1.1 Framework and Motivation During the Summer of 2009 and until 2013, I have worked with a small band as a lighting technician for their shows, where various DMX devices were used. The experience and problem-solving skills gained with working with the fixtures and the controllers directly led to the realization of the limitations within this system, so the search for a flexible alternative combining the robustness of the previous solutions and Ethernet technology began at least two years before the realization of this Dissertation. 1.2 Objectives 3 1.2 Objectives The first objective of this Dissertation is the development of an Ethernet based alternative to replace the DMX standard to control lighting equipment. That system should be able to handle the technological evolution and offer new advantages and solutions for common problems present in the current protocol. However, most of the existing lighting equipment has the DMX interfaces as standard, so this new system also has to allow to communicate with those legacy devices, integrating them seamlessly into the new system. The second objective is the creation of a working prototype implementing part of the developed system that concerns the compatibility with legacy devices. 1.3 Document Structure This document is structured as following: •Second chapter: State-of-the-art and study of the technologies to be used in the developed system; •Third chapter: Complete description of the system requirements and architecture; •Fourth chapter: Development of a working prototype for proof of concept; •Fifth chapter: Achieved results and conclusions. 4Introduction Chapter 2 Technologies This section will introduce the intelligent lighting systems and the current technologies used, including their advantages and issues. 2.1 Introduction A lighting system is constituted by two basic elements types, controllers and devices. The controllers, or consoles, are the interface with the user, or lighting technician. This controller is widely programmable, and it is connected to the devices on stage through one or more cables. The devices have a variety of control parameters which the console controls. The devices receive the signals from the controller and change their parameters accordingly. In a basic set-up, one controller can control a multitude of devices with different control parameters. In more advanced set-ups, several controllers can be used, but they are never connected between themselves, they only affect the devices each one is connected to. The lighting crew, technicians and engineers are responsible for assembling all the devices and connecting them to a controller, programming and execution of the show. The controller and the devices are part of a master-slave system, where the controller is the master, sending commands to the devices, which are the slaves. 2.1.1 Fixtures Figure 2.1: Different types of stage lighting devices. [2] 5 6Technologies Figure 2.2: Examples of a standard PAR and LED PAR lights. The fixtures, or lighting instruments, are the part of the system that creates light. They vary in size, shape, weight, light power output and technology, which determines their purpose on stage. These are the slaves of the system, receiving the signals from the controller and changing their outputs as requested by the programmer. Most of these fixtures can be divided in two major categories, although some of them belong to both: Spot lights and Wash lights. The spot lights are focused lights that allow the controlled projection of shapes across a surface, with the aid of filters positioned in front of the light source. The wash lights are less controllable, and can be used, for example, as colour fillers, although they are not limited to this application. [5] Every device has a number of control parameters. For example, a moving head usually has parameters to control the movement, the colours and shapes, which usually amounts to 8 to 16 control parameters or variables. 2.1.1.1 Parabolic aluminized reflector Th classic fixtures used in stage lighting are the PAR lamps. These are easy and straightforward to use as they usually only have one control variable, the Dimmer, which is the basic intensity control, varying from completely off to fully on. Several filters, such as colour filters and gobos, or projection filters, can be placed in front of the PAR in order to change the light output, which is usually white by default. [6] LED PAR lights are most commonly used to replace classic lamps as they can dynamically change the colour output, a feature that was only achievable with the aid of filters in regular PAR lights. They also allow a wide variety of colours in one single device, which previously required the use of a large number of classic PAR lamps, each one with different filters. 2.1.1.2 Scanners/Moving mirrors and Moving heads Moving mirrors or scanners are devices that rely on a motorized mirror to project the light, which is generated and filtered in a stationary casing. The moving heads use larger motors to move 2.1 Introduction 7 the entire fixture around, allowing a wider projection angle, whereas the scanners have limited movement range. These devices have their own advantages and disadvantages, which limits the application and usage. For example, the scanners have a limited range of movement, but they are extremely fast since the motors only need to move a small mirror. The moving heads are heavier and therefore slower, but the movement range is expanded. LED technology and more energy and size efficient discharge lamps allowed the moving heads to become smaller and faster, so these are the preferred types of devices used in intelligent lighting for their flexibility and weight. Figure 2.3: Sharpy and A-Leda Wash K20, moving heads manufactured by Clay Paky. [3] The concept of LED PAR lights has been applied to moving heads, which results in a moving wash set-up, with RGB capabilities, as seen in figure 2.3. 2.1.1.3 Other devices Other devices used with this system are, for example, the smoke or fog machines, that can use regular smoke, or ice for a low height haze effect. These are usually controlled the same way a PAR lamp is, with only one parameter that controls the intensity of the output. Figure 2.4: A smoke machine and a laser. 14 Technologies 2.2.3 Art-Net Art-Net stands for Artistic Network, and it is an implementation of the DMX512 and RDM protocols in an Ethernet network. It is an encapsulation of those technologies and allows the flexibility of any Ethernet network. [11] Figure 2.11: Art-Net to DMX with support for 8 universes. It addresses the problem of expandability by allowing multiple universes through a single ArtNet system. It is possible to have up to 32768 universes in the current version.[12] Since it transmits using UDP packets, it has the typical Ethernet and IP functions, as a DHCP server. In this protocol, each device has an IP and MAC address to which the controller uses to communicate. 2.2.4 Protocol The ArtDMX packet consists of a header added to the DMX data packet (not considering the start and stop bits). It is formed by: •8 bytes with the characters to form the string “Art-Net0”; •4 bytes with the OpCode; •4 bytes with the protocol version; •2 bytes with the even data length up to 512; •DMX data with the defined length. 2.3 Conclusion After introducing the technologies referred in the section 2.2, State-of-the-art, there are a few conclusions that can be made regarding the advantages and disadvantages of their use: 2.3 Conclusion 15 •DMX512: It includes a robust differential physical layer with large resistance to electromagnetic noise, which is usually high in stage environments, and it is easy to understand. It is, however, limited to 512 channels and 32 devices in a normal network, and the configuration process, although simple, takes time since on the lighting technician to manually insert the addresses into each device. •RDM uses a DMX line to allow a two-way communication with the controller and the devices, providing automatic configuration for those devices. But, as the predecessor, relies on a network with limits in size and parameters, and needs specific hardware in order to expand it. •Art-Net is an encapsulation of the DMX protocol and increases the quantity of universes up to a few thousand in a single Ethernet cable, requiring specific hardware to achieve it. Having these technologies, the purpose of re-developing a system to control these lighting devices is to include all the advantages those protocols offer, and go beyond it, offering new and more advanced functions, and have one single protocol that can travel from the controller directly into the device without any gateways, with the only exception being the legacy compatibility for DMX devices. By using standard Ethernet as a base to develop the network, it is possible to expand the network and implement more advanced features to control the lighting equipment. This gives the users a possibility to focus more on the design and programming rather than in configuration, wiring and hardware assembly. 16 Technologies Chapter 3 System Architecture 3.1 Introduction This section will define the proposed system, beginning with a full description of the architecture, a list of hardware and software requirements, and use-case scenarios. Then, a full description of the solution found will be presented, along with the explanation for the decisions made regarding the choice of technologies. 3.1.1 Use case scenarios In order to understand the concept of this system, it was necessary to describe its behaviour with fictional scenarios exemplifying its use. By using the following scenarios, plus the general idea of the system, it was also possible to further specify the requirements of the system. 3.1.1.1 Scenario: Physical connections and configuration “A lighting technician has a lighting console, new and old devices and the respective DMX interfaces. After the initial rigging is complete and all the devices are positioned, the technician begins the wiring process: •A single Ethernet cable is connected to the output of the console and the input of a network switch, positioned anywhere on stage; •Another cable is connected to one of the outputs of the switch and into the first device, that has two connectors, one for input and output; this last one is connected to the next device, daisy-chaining them; •One or more devices are DMX, so they are connected to a small interface with the standard Ethernet in and out and a DMX output, that connects to the DMX device, which are configured for the first DMX address; •The technician finishes connecting the devices in a star/daisy-chain topology around the central switch; 17 18 System Architecture •The system is then booted up, and the technician assumes the position behind the controller, where the configuration takes place. Assuming the controller is not programmed, the automatic configuration stage takes place and the controller communicates with the devices, detecting them automatically and requesting their control parameters; •If a configuration does not exist in a DMX interface, the technician receives a notification and a request to upload the configuration file for that device, which includes the DMX addressing; •After the detection of all devices is completely, they automatically switch to the normal operation mode. The controller is now ready to be programmed, and the devices are now in its database; •The technician programs the devices for the show to be presented as standard; •After the programming is completed, the stage is ready to be used as normal. The controller and the devices can be shut down; •After starting up for the second time, the controller will detect the configuration in the database and will wait for the requests from the devices, confirming their presence in the database, therefore with no need of reconfiguration; •The lighting system is once again ready to be used.” 3.1.1.2 Scenario: Errors and warnings •“A warning message is generated in the device with an overheating lamp, and sent to the controller; the technician receives the warning and decides to ignore the temperature, since it does not constitute any danger; •The device then reports one of the motors is failing to respond to the command, so the device fails to change that parameter; The technician decides to send a command to the device to disable that parameter, which means any programmed orders that affect that parameter will be ignored (assuming the console programming cannot be changed); •The device now reports to the technician a fatal error when the temperature of the lamp is dangerously high, shutting itself off, to prevent more damage. “ The decision of implementing the self-protection mechanisms is entirely up to the manufacturers, and it does not constitute a part of this Dissertation. In this case, the only purpose of this system is to report the warnings and errors to the user. 3.1.2 Requirements Based on the use-case scenarios in the previous section, the system has the following main requirements: 3.2 System Description 19 •Allow flexible network communication; •Guarantee compatibility with existent DMX devices; •Minimize the configuration process of all of the devices; •Allow new functions and system operations; •Allow the reading of various sensors and reports of exhausted hardware parts (for example, lamps and motors). These requirements can be expanded and be further divided in hardware and software requirements. 3.1.2.1 Hardware requirements •Allow multiple network topologies, such as star and daisy-chain; •Ethernet to DMX interfaces to communicate with these devices; •Compatible with standard Ethernet switches and devices; 3.1.2.2 Software requirements •Create a protocol to handle the communications between the devices; •Automatic device configuration with no need for used interference; •Configure DMX devices through the implemented interface; •Synchronized actions for multiple devices with minimal network delay; •Minimize amount of information sent for continuous actions (controlled movements); •Possibility to implement advanced functions and system operations in a device; 3.2 System Description This system is similar to the concept of the DMX and other classic solutions, where a controller and a number of devices are connected hierarchically in a network. This concept has been ported to the current architecture, but has been expanded in a way that allows flexible connections. Similarly to the DMX ideology, this system consists of a tree topology with a controller on top and the devices hierarchically distributed in the lower levels. The controller is the master of the system, as the operations are originated from there. However, the communication is bidirectional, because the devices can also send information to the controller without being asked. it is the case of two different services, such as the read/write operations, and the notifications and warnings. It is a system that respects the master-slave hierarchy, but has multiple bidirectional services. 20 System Architecture Figure 3.1: Simplified software and hardware layers The controller and the devices are consist of a hardware layer, operating system and application, as seen on figure 3.1. This architecture has been developed as an application, on top of standard hardware and software. On the controller side, an API is provided with functions to access the variables in each device, functions as the read/write and more complex operations, such as interpolations and custom shapes. Those complex operations are determined by a set of parameters and are executed independently by each device, which distributes the computation instead of centralizing it in the controller. 3.3 Hardware This section introduces the hardware solutions found to meet the requirements defined in section 3.1.2.1. 3.3.1 Network Topologies The DMX systems are connected through a shared bus, daisy-chaining the devices, as described in chapter 2.2. This set-up has, in a way, defined the way the fixtures are positioned in a stage, by keeping the cables between devices as short as possible, to reduce its length and cost. Designing a system that replaces the DMX communication with an Ethernet based alternative and with the classic star topology would imply the use of switches with enough outputs for each device, which mean that each device would connect to that central switch. This solution would be ideal because it minimizes the number of connections between the controller and the fixtures, but the number of Ethernet cables necessary to connect the numerous devices would largely increase. Facing this problem, the adopted solution is to follow the one that already exists in the DMX wiring system, allow a daisy-chain connection through every device by embedding a switch with two ports, one for input from the controller or the previous device, and another for the output to other device. 3.3 Hardware 21 The daisy-chained devices can also be connected to a tree topology network using standard switches, as seen on figure 3.2. The central switch pictured is the one connecting directly to the controller, and all the other switches and devices connect to the network through it. Other switches can be further added to expand the network, always following the tree hierarchy. Figure 3.2: Connection diagram with one central switch and multiple devices daisy-chained. In the previous diagram, the devices in the lowest level are not considered switches, although they are embedded in every device. These, however, only have two external ports, so they simply redirect the packets to the other port if the destination IP does not belong to the device they are embedded in. This topology also implies that the failure of a device in the middle of a chain would isolate the devices further connected to it from the rest of the network. To find a solution for this problem, it is necessary to study the general network topologies and adapt them for this specific need, which hasn’t been achieved in this Dissertation. A relatively simple solution would be to close the daisy chained connections in a ring using an additional switch, but it wouldn’t completely solve the problem of islanding. 3.3.2 Physical Interfaces This section will describe the physical interfaces that connect to the Ethernet network. One of the requirements of this system is to replace the DMX cabling with a reliable solution that will stand 22 System Architecture the environment variables such as humidity, heat, and several connections and disconnections. Since this Dissertation is focusing on the architecture of the system, the physical cabling will not be discussed in the next sections. It is recommended the usage of, at least, a cable protected against dust and water splashing, complying with an IP54 rating at least. However, an analysis is required to select the best cabling and connectors, which has not been performed in this project. 3.3.2.1 Embedded Ethernet The new devices that comply with the new system have an embedded Ethernet switch with two exterior ports, for input and output to the next device. 3.3.2.2 Ethernet - DMX To meet the DMX compatibility requirement, it is necessary to create a device that behaves as an interface between the Ethernet and DMX protocols, and that can be installed close to the DMX fixture. However, the new protocol is different from DMX, as it will be explained in section 3.5. It requires computational power to support new functions and variables, so this interface is a fully functional microprocessor with a DMX server that behaves as any other device, completely transparent to the user, and translates the new functions and variables into DMX channels. This device has the following requirements: •A microprocessor compatible with the developed application; •Support network communication by either: –having two Ethernet shields and implement the necessary switch, in the microprocessor, or –have one Ethernet shield and one separate 3-port switch to connect to it and the external input and output; 3.3.3 Controller As mentioned in chapter 2.2, the controller is a device located at the top of the hierarchic tree, similarly to the new system. These are usually regular computers with an outside shell to create the console and a software running on top of a common operating system. Therefore, the requirements for the controllers are easily met: •Standard computer with a Gigabit network card; •Operating system capable of network communication; 3.4 Software 23 3.4 Software This system is almost exclusively software-driven, given that it is based in common hardware solutions. This section will cover the networking services, the protocol and the API developed. 3.4.1 Variables Before going into the details of the network communication and the protocol, it is necessary to address the variables used within this system. Until now, each device had a specific set of parameters allocated in different channels programmed exclusively by the manufacturer. Similar devices from different manufacturers often have similar sets of variables, but they are often positioned in different channels and can also have different names according to the data sheet. Some of those devices also have different working modes to allow a different number of parameters to be controlled, allowing advanced working modes with extra channels for 16 bit pan and tilt movements, for example. This is not limited to the normal control variables, some devices include system operations in separated DMX channels to allow the controller to reset or switch off the lamps. To solve the issues of similar variables with different designations, and since similar devices (moving heads, moving washes, LEDs, etc) share the same variable types, it was possible to organize them in three major classes: Figure 3.3: Class diagram of the device types. •Light: Any form of light generation in the fixture; –ColorLED: Adds RGB colour mixing; •Filter: Applied in front of the light to change it shape, color, or any other way; –ColorWheel: Rotative colour wheel that changes the colour of the projection; 30 System Architecture 3.5.3.1 Embedded Ethernet devices The process consists of: •Search for a controller by attempting a TCP connection to the default controller IP; •Reply from the controller which may or may not request the configuration of the device; •Send configuration; •Receive acknowledge. The first message contains the device type, MAC address, name and manufacturer. After receiving it, the controller searches its database for the MAC address, which is the unique identifier. If the configuration is already present, an acknowledgement message is sent to enable the device’s normal operation mode. If not, the controller will send a request to the device to send the configuration, which will then be inserted in the controller’s database and an acknowledge message sent to finish the configuration phase. The configuration requests and acknowledges have null data, so the messages are only the header with the specific function code. The discovery and configuration packets can be seen in tables 3.4 and 3.5. Figure 3.5: Diagram of the configuration steps for an embedded device. Table 3.4: Discovery packet, short version of table B.7 MAC Name Len. Name Manufacturer Len. Manufacturer Model Len. Model Table 3.5: Configuration packet, short version of table B.2 Number of variables ID 1 Class 1 Index 1 ID 2 Class 2 Index 2 3.5 Protocol 31 3.5.3.2 Ethernet - DMX interfaces for legacy devices The Ethernet - DMX devices are configured with a host configuration file, interfacing the normalized variables with the DMX channels. The configuration steps are similar to the previous ones, but depend on the existence of such file in the device: •If configuration file exists: –Send discovery message with the device type (DMX), mac address, name and manufacturer; –Reply from the controller which may request the configuration; –Configuration is send if requested; –Controller acknowledges. •If configuration file does not exist: –Send discovery message with device type (DMX), mac address but no other details; –Controller sends the DMX configuration the user has selected; –Device resends discovery message with the MAC address, name and manufacturer; –Controller acknowledges. Figure 3.6: Diagram of the configuration steps for an DMX interface device. The packets for these operations are similar to the mentioned above for Embedded Ethernet devices. The only differences are in the function code and the direction of the configuration. Before, the controller requested the configuration of the device, but in this case, the controller is the one defining that configuration. The configuration packet for these devices is in table 3.6. The DMX channel goes up to 512, so two bytes will be used to represent it in the packet. In case a DMX device has one or more parameters with a 16 bit resolution, the configuration will assign the two channels when converting into DMX signals. To define this in the configuration, it is necessary to send two variables with the same class and index codes. The most significant byte should be first, followed by the least significant byte. 32 System Architecture Table 3.6: Configuration packet for DMX interfaces, short version of table B.6 Number of variables Class 1 Index 1 Channel 1 Class 2 Index 2 Channel 2 The full packets can be consulted in the Appendix B, 3.5.4 Read/Write operations By using the function codes 0x0101 and 0x0102, it is possible to request to a device to write and read variables, respectively. It is also possible to send multiple variables to read or write to a specific device. To identify a variable, two parameters are necessary, the variable code and the index. For the write message, the number of variables to write is specified, followed by the first variable code, index and value. For each variable to write, the variable code and index are sent. The write operation is similar, adding the value to write after the identifiers. The packet construction can be seen in tables 3.7 and 3.8. More detailed versions of those tables can be seen in the Appendix B, specifically the tables B.9 and B.8. Table 3.7: Read packet, short version of table B.9 TID Type Function Length Num. Var Class 1 Index 1 Class 2 Index 2 Table 3.8: Write packet, short version of table B.8 TID Type Function Length Number of Variables Class 1 Index 1 Val 1 3.5.5 System operations The DMX devices allow the usage of specific channels to access system operations, such as resetting the device, shutting down the lamp, reversing the pan or tilt, and others defined by the manufacturers. In this system, those operations are divided from the common read/write functions and have specific codes to access those special functions. 3.5.6 Interpolation This system allows the usage of distributed computing to perform interpolations and advanced operations that require precision and timing. Previously, all the computing power was located in the controller, and the instructions were sent to the device with the refresh rate of the DMX message. With the new system, it is possible to send a single instruction to a device to perform an interpolation or spline with timed precision. For example, a slow tilt movement in a common DMX moving head is possible by either continuously updating the position from the controller, or setting the speed through a specific 3.5 Protocol 33 channel. The first option, though, lacks precision and the second does not guarantee that the position will vary from one point to the other in the required time. This system, however, does. The interpolation capabilities within this system have not been entirely studied, and it has not been implemented within the network. But, since the protocol was developed with the intuit of easily implementing new functions, it will be possible to do so in the nearby future. It is recommended that the interpolation commands remain as short-timed as possible, since the clocks of the controller and the devices may not be synchronized, which could lead to the operations ending sooner or later than expected. However, the difference in modern microprocessors is minimal, and should not make a visible difference. A few different interpolations can be implemented: •Timed linear interpolation with three parameters: Start position, end position and time. The device should then calculate the speed of the motor to reach from the first to the end positions within the given time; •Timed cubic interpolation with three or more points, to give the possibility of advanced movements and shapes. An interpolation can be stopped by sending a write command to the same variable, or by another interpolation. Any operation that implies the change of the variable under an interpolation will stop it. An extra parameter can be added to repeat the process after it is finished, allowing, for example, a looping “wave” effect, or a continuous shutter blink. This parameter should be used carefully, because, as mentioned above, the differences in clock synchronization may lead to different results if a number of devices is executing the same code. By using this feature, the user does not have any automatic feedback of the state of the interpolation, only knowing the defined points and time. To solve this, the software within the controller can periodically send requests to read the variable being affected by the operation. This period does not need to be too short if it is only for the user to see the current values. 3.5.7 Synchronized operations Another feature of this system is the possibility to declare a certain operation as synchronized. This allows the user to send an operation packet with the normal functions, but instead of the device executing them as soon as they are received, they are stored and will wait for a synchronization signal, which will deploy that operation. This feature is useful for situations where a large number of devices is in use and they are required to execute a command at the same time. The commands are sent to each device as synchronized, and will stay stored along with the transaction ID. To deploy them, the controller simply broadcasts the transaction ID, and the devices only need to verify if there is a suspended operation with the same identifier as the received. For this feature, a few requirements are necessary: 34 System Architecture •The transaction ID must identify the same operation across all devices, so only one broadcast is necessary; •Each device should be able to hold multiple synchronized operations and should deploy them in order of arrival of the respective broadcasts that trigger them. This bypasses the previous rule that uses the transaction ID to identify the operation with the highest priority; •Every synchronized operation has a timeout, otherwise it can be stored indefinitely, which can cause memory leaks; •Acknowledge messages are sent after the device successfully stores the synchronized operation, not after the same operation is triggered. 3.5.7.1 Network and Protocol Figure 3.7: Storing and deploying a synchronizing an operation The synchronization requires that all the devices receive a broadcast message with the transaction ID. This is achieved by sending the transaction ID to the default IP broadcast address, 255.255.255.255. This is the fourth service mentioned in section 3.4.2 and it consists of a clientserver connection between the controller as server and all of the devices as clients. The connection diagram can be seen in figure 3.7. The header of a synchronized operation is the only difference from a normal operation, by using the field Message type and changing it to 0x01, as shown in table 3.9. The received Acknowledge message is the header of the operation, and confirms that it has been received and stored, waiting to be triggered. 3.6 Conclusion 35 Table 3.9: Header of the synchronized TCP packet Header Message Size Example Transaction ID 8 bytes 0x42616420576F6C66 Message type 1 byte 0x01 Function 2 bytes 0x0001 Data length 2 bytes 0x0001 Since the purpose of this communication is to transmit the transaction ID, which is already an unique value, the packet configuration does not have a header and data configuration, it is simply the eight bytes that represent the transaction ID. 3.6 Conclusion This concludes the section of the system architecture. Although the requirements are fully met, the system is still far from being able to be implemented in a real stage situation, which would require a deeper study of the hardware specifications and the device classes. It is, however, a system that offers many advantages in comparison with the previous protocols. Since the base has been developed, the missing parts should be easy to develop and implement. The network topology proposed demonstrated the flexibility of the network if used with a star or daisy-chain models. However, the best topology for such a system would be a purely star model, having the switches connecting to a single device, without any daisy chaining to avoid islanding. For some cases this solution wouldn’t be possible due to the spacial requirements. The devices are, therefore, prepared to handle multiple network topologies. 36 System Architecture Chapter 4 Implementation 4.1 Introduction The second part of this Dissertation was the implementation of the developed system into a prototype. This section will cover the development platforms, the implementation, and the final results. The developed prototype is an Ethernet/DMX Interface, which is the most obvious choice, given that there are no devices at the moment that comply with the new system. 4.2 Development Platforms Initially, this project was expected to be equally hardware and software driven. But, since the requirements defined the use of standard Ethernet based solutions, the hardware became less specific and complex, which allowed the development of more advanced software functions. The prototype developed is, therefore, a proof-of-concept that has been developed on standard platforms, but it should be easily portable to others, more specific for a commercial application of this system. 4.2.1 Hardware This section will describe the hardware used and its respective assembly to create the final prototype. Since this prototype is a DMX interface, it needs to be able to generate the DMX signal to feed a standard DMX device. Therefore, the requirements are as follows: •Standard development board with Ethernet; •Serial port capable of generating a signal at 250 kBaud; 4.2.1.1 Selected hardware and its requirements The hardware used for the development is a standard Raspberry Pi model B, with a Linux based operating system. This board already has a fully functional Ethernet port with network support from the operating system. 37 38 Implementation Since the DMX protocol uses the RS-485 physical layer, and the Pi has a serial port, it was necessary to use a MAX485 to create the differential signal. Therefore, the circuit in figure 4.1 was proposed. Figure 4.1: RS-232 to RS-485 circuit. The input of the MAX485 is connected to the UART TX pin 8 of the Raspberry Pi, and the value of the resistor is 100 Ω. Since the DMX protocol is unidirectional, so only the transmission pin was used. The final assembled prototype can be seen in figure 4.10. 4.2.2 Software The prototype was developed using a Raspberry Pi with a Linux image for the development board. Java was the language selected for this application for its compatibility with sockets and general network services provided by the operating systems. However, the pin and serial support for this hardware was not working as expected, so an additional application was developed in C to allow the usage of the UART ports from the Raspberry Pi. 4.3 Protocol Layers The software of the controller and the device was organized with protocol layers, which allows the presence of an API in the highest level providing the basic access functions to the user. This API is meant to be used directly with the controller’s software. For this prototype, only two of the four services were implemented: the operations and configuration. The layer organization is similar in both ends, the controller side and the device side: •Configuration: –Configuration; –Configuration wrapper; –Network; •Operations: –API; 4.4 Threads and synchronization 39 Figure 4.2: General protocol layer diagram. –Functions; –Packet wrapper; –Network. The protocol layers, in the system, represent the different classes running in separated threads. This method provides the concurrent execution of the operations. In the next sections it will be explained how these layers communicate and what is their purpose in the system. 4.4 Threads and synchronization Each protocol layer represents a different thread in the system, which means that for a single operation, three threads are created to accommodate the bidirectional communication. These threads, however, do not execute at the same time. Similarly to a token-passing system, only one is executing code at a time. This was achieved by taking advantage of the Java’s interrupted exceptions during a thread sleep. For example, a Runnable class that sleeps by default such as: public class ExampleSleeping implements Runnable { public void run() { while(true) { try { Thread.sleep(1000); }catch (InterruptedException e) 46 Implementation } public class Write implements Runnable { public Write(byte[] input, int[] ids, int[] indexes, int[] vars); } The arrays are passed by reference, so it is guaranteed that their value does not change across the threads, which requires a precise synchronization between the threads as they execute. The variables are then inserted into the database, which the device will then use to update its outputs. 4.8 DMX Module Figure 4.7: The DMX Module. The DMX module was implemented partially in Java, partially in C, because the required libraries for Java serial communication using the Raspberry Pi did not prove to work. The DMX channel updater was implemented in Java, and the packet generation and serial communication was implemented in C, communicating through a localhost socket connection. 4.8.1 DMX packet generation The DMX packet generation was expected to be exactly like the standard mentioned in chapter 2.2, with the minimal values as also seen in figure 4.8. However, after the initial testing, by enabling the four channels addressed to the Lightmaxx, it has been discovered that the LEDs were blinking randomly. With further testing, the problem 4.8 DMX Module 47 Figure 4.8: Representation of the DMX packet with the minimal values. was addressed to the values of the Break and the MAB, Mark-After-Break, which proved to not be enough to stabilize the connection. The minimal Break time is at least 22 bits long, but has been set to 80, and the MAB time has been set to 24. This obviously creates more delay on the packet transmission time, but has proven to stabilize the connection. Plus, since there are only four channels occupied, the packet renewal time is minimal, and the effect does not affect the final performance. 4.8.2 Serial communication in C with the Raspberry Pi The DMX communication occurs at a baud rate of 250 kBaud. However, the Raspberry Pi only supported, with an alteration to the UART clock, the values of 230400 Baud, or 500000 Baud, both not supported by the DMX devices. Using this UART also would create another issue: it has only one static stop bit, where the DMX protocol requires two. In order to achieve the 250000 Baud, the clock of the UART was changed to 2 MBaud, which is exactly eight times greater than the desired rate. By doing so, theoretically, the transmission time of a byte, 8 bits, at 2 MBaud is exactly the same time one single bit was read at 250 kBaud. By using this method, and reducing the number of bits to 6 to compensate for the extra start and stop bit, therefore creating the single byte, it was possible to transmit the DMX packet. Every time a byte was sent, a byte that was composed by the start bit, six data bits and the stop bit, only one single bit was being read from the DMX fixture. With this, it was possible to create the desired start and stop bits that the DMX packet needed, but it also required the manual construction of the entire packet. The clock of the UART was modified to achieve its speed by adding this line to the file “/boot/- config.txt”: init_uart_clock=16000000 48 Implementation The UART was then initialized to 2 MBaud with the following function: int openUart(int uart) { uart = open("/dev/ttyAMA0", O_RDWR | O_NDELAY); struct termios options; tcgetattr(uart, &options); options.c_cflag = B2000000 | CS6; options.c_iflag = IGNPAR; options.c_oflag = 0; options.c_lflag = 0; tcflush(uart, TCIFLUSH); tcsetattr(uart, TCSANOW, &options); return uart; } The packet was generated byte by byte, according to the number of available channels: unsigned char tx_buffer[1024]; unsigned char *p_tx_buffer; (...) // BREAK for (i = 0; i < 80; i++) *p_tx_buffer++ = ZERO; // MAB for (i = 0; i < 24; i++) *p_tx_buffer++ = ONE; for (int l = 0; l < allocated_channels; l++) { int tempbuf = channelBuffer[l]; // Start bit *p_tx_buffer++ = ZERO; // 8 Data bits for (i = 0; i < 8; i++) if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; // Stop bits *p_tx_buffer++ = ONE; *p_tx_buffer++ = ONE; 4.9 Partially and Not Implemented Methods 49 } Where “ZERO” and “ONE” are equal to 0 and 63, respectively, which is the integer value of six bits. This method was possible because the DMX protocol does not offer bidirectional communication, so the prototype only needed to send the DMX messages without expecting a response. However, the Raspberry was used only as a development board, and its UART was used for testing purposes, so it is not meant to be implemented in a final prototype. 4.9 Partially and Not Implemented Methods This section describes some of the functions that have been proposed on chapter 3, but only have been partially implemented or have not been implemented at all. 4.9.1 Interpolation The interpolations are part of the advanced features that distribute the computation among the devices in the system, rather than focusing them on the controller, relying on the communication network to update the device states periodically. This feature has been partially implemented as a linear, two points interpolation running on the device prototype, with support for one variable only. The prototype to the implemented function can be seen below, and the complete version can be consulted in Appendix C: public class LinearTwoValueSimpleSpline { public LinearTwoValueSimpleSpline(int id, int index, int val1, int val2, int period); } It consists of a thread created to change the value of a specific variable, and takes as parameters the variable code and index, the initial value, final and period. Once started, it will create the given interpolation going from the initial value to the final in the specified period. This method was implemented in the Device side only. It has, however, proven to work, although the period had a deviation of a few milliseconds. For this reason, the recommendation is to keep the period as low as possible, to reduce the deviations and to prevent devices from running out of sync if executing the same interpolations. 4.9.2 Notifications The notifications are part of a service that has not been implemented in the prototype. It would have had two different purposes: To notify the controller of errors and warnings, and to read a variable periodically. Simply put, it would act as a publisher-subscription system, sending to the controller the state of a variable or variables. 50 Implementation Figure 4.9: Raspberry Pi and Fame Lightmaxx. To enable this subscription, the same principle of the synchronized write would be used, but the device would have to interpret it as a subscription, and it would send the read packets with the variables requested to the controller periodically. This would also need a function to terminate the subscription, which the controller would send 4.9.3 Synchronized Operations The synchronized writing function has been implemented, as it can be consulted in section 4.7.1.1. It has been implemented to work with that function only, but should support every kind of operation destined to change variables, hence the need to change only the header of the packet. This would allow the presence of synchronized interpolations, for example, which could be deployed simultaneously. 4.10 Tests and Validation To test the concept, a Fame LightMaxx LED strip was used with the prototype. This is a DMX device with four channels: Shutter, Red, Green and Blue. The DMX input was connected to the UART output of the PI through a MAX485 circuit, as seen in figure 4.10. To test the concept, a Fame LightMaxx LED strip was used with the prototype. This is a DMX device with four channels: Shutter, Red, Green and Blue. The DMX input was connected to the UART output of the PI through a MAX485 circuit, as seen in figure 4.10. Figure 4.10: Raspberry Pi connected to the LightMaxx DMX prototype. 4.10 Tests and Validation 51 The system responded as expected by sending the read/write commands from the controller, such as: String[] names = new String[]{"RGBLED.1.Shutter.0","RGBLED.1.Red.0", "RGBLED.1.Green.0","RGBLED.1.Blue.0"}; int[] values1 = new int[]{255, 255, 0, 0}; int[] values2 = new int[]{255, 0, 255, 255} Write.WriteMultipleInstant(names, values1); long delayedOperation = Write.WriteMultipleSynced(names, values2); Thread.sleep(1000); Sync.DeploySyncedAction(delayedOperation); The code above sends two commands to the device, changing the colour output to Red instantaneously (figure 4.11), and sending the synchronization command after sleeping for one second to enable the second command, therefore changing the output colour to cyan (figure 4.12). Figure 4.11: LED powered by the DMX interface (Red). 52 Implementation 4.11 Conclusion This concludes the chapter of the implementation of the system into a working prototype based on standard development tools. It has been proven to work with the implemented functions, which effectively shows that the system is viable. Figure 4.12: LED powered by the DMX interface (Cyan). Chapter 5 Conclusion This is the fifth and final chapter of this Dissertation, and concludes the work developed during this project. 5.1 Achieved Results The purpose of this Dissertation was to develop and implement an alternative to replace the DMX protocol in stage lighting environments with support for new functions in order to simplify the configuration process and to add advanced functions that the previous protocol could not support out-of-the-box. The study of such a system is important not only due to the increasing need of expandability and flexibility that is saturating the current technologies, which is limiting the development of new devices and controllers, but also to allow the users to focus more time on stage programming, rather than spending it on configuring it. This system’s architecture has been developed and it has been implemented in a standard development board with success, which allows it to be easily transported to other platforms. Although not all of the proposed objectives were met, the basic functions were implemented and tested, which proved that it can be further developed and used in a stage lighting environment. 5.2 Future Work The architecture of the system has been developed to a point that would allow the continuation of the work in this area, and its possible implementation and use in a real stage environment. However, such continuation would have to be extensively studied and the requirements and specifications would have to be further developed to guarantee the viability of this project. For example, the further study of the best network topology would be necessary to ensure the accessibility of all the devices within the network, the hardware and software requirements of the microprocessors to use as interfaces and the embedded devices to allow the increased computation needs. 53 54 Conclusion Appendix A Glossary •Moving Head: A device used in lighting equipment that has a movable body controllable by at least two motors to move the direction of the light beam. •Rigging: Process of mounting the light equipment and the cable in the stage structures. •Console: Device responsible for controlling the fixtures and other lighting instruments. •Light Engineer/Technician: Person or group responsible for the rigging, programming and controlling the lighting equipment. •Master-Slave: Model of communication where one device has the control over the other. •Spot light: Controllable, focused light. •Wash light: Uncontrollable focused light. •Gobo: Filter applied in front of a light to project a form on a surface or the air, with smoke. •Dimmer: Intensity of a light, also referred to the dimmer lights that only have one control parameter, the intensity. •Moving Mirror/Scanner: Device used in lighting equipment that has a fixed body and which light is projected onto a mirror with at least two motors to control the direction of the beam. •Channel (DMX): Each parameter of a DMX device is assigned to one channel, which is an 8 bit value, ranging from 0 to 255. •Universe (DMX): Network generated by a DMX console, to which the slave devices connect. •Daisy-Chain: Method of connecting the devices in a network. The first has an output port which connects to the input of the second device, which also has an output to connect to the third device, and so on. •RS-485: Differential RS-232, which is a serial communication interface. 55 62 Additional Source Code }catch (IOException e) { running = false; } } } C.1.1.2 ClientHandler.java public class ClientHandler implements Runnable { int state = 0; // State machine status static int maxBufferSize = 1024; byte[] rawOutput = new byte[maxBufferSize]; byte[] input = new byte[maxBufferSize]; // Socket initialization int[] result = new int[2]; Socket client = null; DataInputStream in = null; DataOutputStream out = null; boolean initialized = false; Thread thisThread; Thread nextThread; public ClientHandler(Socket client) { this.client = client; initialized = true; } public void run() { while (!initialized); thisThread = Thread.currentThread(); byte[] raw = new byte[maxBufferSize]; while (state < 5) { if (state == 0) // { try { in=new DataInputStream(client.getInputStream()); int i = 0; C.1 Controller prototype 63 do raw[i++] = in.readByte(); while (in.available() != 0); for (int l = 0; l < i; l++) input[l] = raw[l]; result[1] = i; // To store the length of the input String ip = client.getInetAddress().toString().substring(1); // Create thread to detect configuration in the next layer nextThread = new Thread(new PackConfigDetect(input, result, rawOutput, ip, thisThread)); nextThread.start(); state = 1; } catch (IOException e) { e.printStackTrace(); } } else if (state == 1) { try { Thread.sleep(1000); }catch (InterruptedException e) { if (result[0] == Codes.sys_slip_request) state = 2; else state = 4; } } else if (state == 2) { try { in=new DataInputStream(client.getInputStream()); out = new DataOutputStream((client.getOutputStream())); byte[] output = new byte[result[1]]; for (int i = 0; i < result[1]; i++) output[i] = rawOutput[i]; 64 Additional Source Code // Write the output to th socket out.write(output); int i=0;// iterador raw = new byte[maxBufferSize]; while(in.available() == 0) // Wait until response arrives Thread.sleep(1); do raw[i++] = in.readByte(); // Read response while (in.available() != 0); for (int l = 0; l < i; l++) input[l] = raw[l]; result[1] = i; }catch (IOException e) { e.printStackTrace(); }catch (InterruptedException e1) { e1.printStackTrace(); } nextThread.interrupt(); state = 3; } else if (state == 3) { try { Thread.sleep(1000); }catch (InterruptedException e) { state = 4; } } else if (state == 4) { try { byte[] output = new byte[result[1]]; for (int i = 0; i < result[1]; i++) output[i] = rawOutput[i]; // Send Acknowledge C.1 Controller prototype 65 out = new DataOutputStream((client.getOutputStream())); out.write(output); out.close(); }catch (IOException e) { e.printStackTrace(); } state = 5; } } try { in.close(); out.close(); client.close(); client = null; }catch (IOException e) { e.printStackTrace(); } nextThread.interrupt(); } } C.1.1.3 PackConfigDetect.java public class PackConfigDetect implements Runnable { int headerLen = 13; int maxBufferSize = 1024; byte[] rawInput; int[] result; byte[] output; Thread thisThread; Thread lastThread; boolean initialized; int state = 0; String ip, mac; long transID = 0; public PackConfigDetect(byte[] input, int[] result, byte[] output, String ip, Thread lastThread) { this.rawInput = input; 66 Additional Source Code this.result = result; this.output = output; this.ip = ip; this.lastThread = lastThread; this.initialized = true; } public void run() { while(!initialized); thisThread = Thread.currentThread(); while(state < 12) { if (state == 0) { byte[] input = new byte[result[1]]; for (int l = 0; l < result[1]; l++) input[l] = rawInput[l]; int i = 0; int dataLength = input.length; for (int c = 0; c < 8; c++) transID = (transID << 8) + (input[i++] & 0xff); int protVersion = input[i++]; result[0] = input[i++] << 8 | input[i++]; int dataSize = input[i++] << 8 | input[i++]; StringBuilder sb = new StringBuilder(); for (int t = 0; t < 6; t++) sb.append(String.format("%02X", input[i++])); mac = sb.toString(); int nameSize = input[i++] << 8 | input[i++]; byte[] nameBytes = new byte[nameSize]; for (int l = 0; l < nameSize; l++) nameBytes[l] = input[i++]; int brandSize = input[i++] << 8 | input[i++]; byte[] brandBytes = new byte[brandSize]; for (int l = 0; l < brandSize; l++) C.1 Controller prototype 67 brandBytes[l] = input[i++]; int modelSize = input[i++] << 8 | input[i++]; byte[] modelBytes = new byte[modelSize]; for (int l = 0; l < modelSize; l++) modelBytes[l] = input[i++]; String name = new String(nameBytes); String brand = new String(brandBytes); String model = new String(modelBytes); if (dataSize == dataLength - headerLen) // First check if data is complete { new Thread(new DeviceCheck(ip, mac, name, brand, model, result, thisThread)).start(); state = 1; } else { result[0] = Codes.e_unspecified; state = 12; } } else if (state == 1) { try { Thread.sleep(1000); }catch (InterruptedException e) { if (result[0] == Codes.sys_slip_request) state = 2; else if (result[0] == Codes.sys_slip_ack || result[0] == Codes.sys_dmx_valid || result[0] == Codes.sys_dmx_invalid) state = 6; else state = 20; } } else if (state == 2) { int i = 0; // Create header 68 Additional Source Code byte[] header = new byte[headerLen]; // Transaction ID header[i++] = (byte) ((transID >> 56) & 0xFF); header[i++] = (byte) ((transID >> 48) & 0xFF); header[i++] = (byte) ((transID >> 40) & 0xFF); header[i++] = (byte) ((transID >> 32) & 0xFF); header[i++] = (byte) ((transID >> 24) & 0xFF); header[i++] = (byte) ((transID >> 16) & 0xFF); header[i++] = (byte) ((transID >> 8) & 0xFF); header[i++] = (byte) ((transID) & 0xFF); // Mode header[i++] = (byte) 1; // Function header[i++] = (byte) ((result[0] >> 8) & 0xFF); header[i++] = (byte) ((result[0]) & 0xFF); // Data size header[i++] = (byte) ((0 >> 8) & 0xFF); header[i++] = (byte) ((0) & 0xFF); result[1] = i; for (i = 0; i < headerLen; i++) { output[i] = header[i]; } state = 3; lastThread.interrupt(); } else if (state == 3) { try { Thread.sleep(1000); }catch (InterruptedException e) { state = 4; } } else if (state == 4) { byte[] input = new byte[result[1]]; for (int l = 0; l < result[1]; l++) input[l] = rawInput[l]; int i = 0; int dataLength = result[1]; C.1 Controller prototype 69 for (int c = 0; c < 8; c++) transID = (transID << 8) + (input[i++] & 0xff); int protVersion = input[i++]; result[0] = input[i++] << 8 | input[i++]; int dataSize = input[i++] << 8 | input[i++]; if (dataSize == dataLength - headerLen) { if ( result[0] == Codes.sys_slip_config) { int numberOfValues = input[i++] << 8 | input[i++]; int[] idsToConfig = new int[numberOfValues]; int[] codesToConfig = new int[numberOfValues]; int[] indexesToConfig = new int[numberOfValues]; for (int l = 0; l < numberOfValues; l++) { idsToConfig[l] = input[i++] << 24 | input[i++] << 16 | input[i++] << 8 | input[i++]; codesToConfig[l] = input[i++] << 24 | input[i++] << 16 | input[i++] << 8 | input[i++]; indexesToConfig[l] = input[i++] << 24 | input[i++] << 16 | input[i++] << 8 | input[i++]; } new Thread(new ConfigSLIP(mac, idsToConfig, codesToConfig, indexesToConfig, result, thisThread)).start(); state = 5; } } else { result[0] = Codes.e_unspecified; state = 12; } } else if (state == 5) { try { Thread.sleep(1000); }catch (InterruptedException e) { state = 6; } 70 Additional Source Code } else if (state == 6) { int i = 0; byte[] header = new byte[headerLen]; header[i++] = (byte) ((transID >> 56) & 0xFF); header[i++] = (byte) ((transID >> 48) & 0xFF); header[i++] = (byte) ((transID >> 40) & 0xFF); header[i++] = (byte) ((transID >> 32) & 0xFF); header[i++] = (byte) ((transID >> 24) & 0xFF); header[i++] = (byte) ((transID >> 16) & 0xFF); header[i++] = (byte) ((transID >> 8) & 0xFF); header[i++] = (byte) ((transID) & 0xFF); header[i++] = (byte) 1; header[i++] = (byte) ((result[0] >> 8) & 0xFF); header[i++] = (byte) ((result[0]) & 0xFF); header[i++] = (byte) ((0 >> 8) & 0xFF); header[i++] = (byte) ((0) & 0xFF); result[1] = i; // Tamanho for (i = 0; i < headerLen; i++) { output[i] = header[i]; } state = 12; lastThread.interrupt(); } } } } C.1.2 Operations C.1.2.1 Write.java public class Write { public static void WriteMultipleInstant(String[] names, int[] vals) { handleWriteThreads(names, vals, false); } public static long WriteMultipleSynced(String[] names, int[] vals) { return handleWriteThreads(names, vals, true); } C.1 Controller prototype 71 private static long handleWriteThreads(String[] names, int[] vals, boolean sync) { long transactionID = Database.getNewTransactionID(); int length = names.length; ArrayList<Integer> id = new ArrayList<Integer>(); ArrayList<Integer> id_var = new ArrayList<Integer>(); ArrayList<Integer> index = new ArrayList<Integer>(); ArrayList<Integer> values = new ArrayList<Integer>(); int devidtemp = 0, paridtemp = 0; for (int i = 0; i < length; i++) { String[] nameParts = names[i].split("\\."); int partLen = nameParts.length; devidtemp = Database.getIdDeviceFromDesig(nameParts[0]); if (devidtemp > 0) id.add(devidtemp); else { ErrorHandler.throwError(Codes.op_write, Codes.e_var); return 0; } paridtemp = Database.getParamID(nameParts[1]); if (paridtemp >= 0 && Database.deviceHasParameter(devidtemp, paridtemp)) id_var.add(paridtemp); else { System.out.println("Dev " + devidtemp + "par"+ paridtemp + ""+ Database.deviceHasParameter(devidtemp, paridtemp)); ErrorHandler.throwError(Codes.op_write, Codes.e_par); return 0; } index.add(Integer.parseInt(nameParts[2])); values.add(vals[i]); } ArrayList<Integer> p_id = new ArrayList<Integer>(); ArrayList<Integer> p_id_var = new ArrayList<Integer>(); ArrayList<Integer> p_index = new ArrayList<Integer>(); ArrayList<Integer> p_values = new ArrayList<Integer>(); int c = 0, ind = 0; while (!id.isEmpty()) { p_id.clear(); p_id_var.clear(); 78 Additional Source Code // 8 Data bits if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; if (tempbuf % 2 == 0) { *p_tx_buffer++ = ZERO; } else *p_tx_buffer++ = ONE; tempbuf = tempbuf >> 1; // Stop bits *p_tx_buffer++ = ONE; *p_tx_buffer++ = ONE; *p_tx_buffer++ = ONE; } for (r = l; r < available_channels; r++) { // Populate remaining empty channels *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ZERO; *p_tx_buffer++ = ONE; *p_tx_buffer++ = ONE; *p_tx_buffer++ = ONE; } reading = false; } C.2 Device prototype 79 if (uart0_filestream != -1) { int count = write(uart0_filestream, &tx_buffer[0], 1024); if (count < 0) printf("UART TX error\n"); } clock_gettime(CLOCK_MONOTONIC, &tend); nanosleep((struct timespec[]){{0, 600000 - (tend.tv_nsec - tstart.tv_nsec)}}, NULL) // Sleep enough time to allow the transmission of the packet } return 0; } 80 Additional Source Code References [1] Avolites Ltd. Avolites portal. http://www.avolites.com/portals/0/Images/ Content/The-Script-O21636_Jamie_FOH_best.jpg. Last checked on January 5, 2015. [2] Abigail Raney. Types of stage lighting. http://www.ehow.com/about_5347272_ types-stage-lighting.html. Last checked on January 5, 2015. [3] Clay Paky. Clay Paky. http://www.claypaky.it/. Last checked on January 5, 2015. [4] USITT. DMX512 FAQ. http://www.usitt.org/content.asp?contentid=373, 2008. Last checked on April 2, 2014. [5] Wikipedia. Stage Lighting. http://en.wikipedia.org/wiki/Stage_lighting. Last checked on January 5, 2015. [6] Wikipedia. Parabolic aluminized reflector light. http://en.wikipedia.org/wiki/ Parabolic_aluminized_reflector_light. Last checked on January 5, 2015. [7] Ujjal Kar. What is DMX512? http://www.dmx512-online.com/whats.html. Last checked on January 6, 2015. [8] Wikipedia. RS-485. http://en.wikipedia.org/wiki/RS-485. Last checked on January 16, 2015. [9] Ujjal Kar. The DMX512 packet. http://www.dmx512-online.com/packt.html. Last checked on January 7, 2015. [10] Wikipedia. RDM (lightning). http://en.wikipedia.org/wiki/RDM_(lighting), 2014. Last checked on January 9, 2015. [11] Wikipedia. Art-Net. http://en.wikipedia.org/wiki/Art-Net. Last checked on January 7, 2015. [12] Artistic Licence Holdings. Specification for the Art-Net 3 Ethernet Communication Protocol. 81