├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── examples ├── .gitkeep ├── DMXUSB_DmxSimple │ └── DMXUSB_DmxSimple.ino ├── DMXUSB_FastLED │ └── DMXUSB_FastLED.ino └── DMXUSB_Simple │ └── DMXUSB_Simple.ino ├── extras └── .gitkeep ├── keywords.txt ├── library.properties └── src ├── DMXUSB.cpp └── DMXUSB.h /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | 5 | # Short duration job, use the container/without sudo image as it boots faster 6 | sudo: false 7 | # Use the latest Travis images since they are more up to date than the stable release. 8 | dist: trusty 9 | group: edge 10 | 11 | cache: 12 | directories: 13 | - "~/.platformio" 14 | 15 | env: 16 | global: 17 | - PLATFORMIO_CI_SRC=examples/DMXUSB_Simple 18 | matrix: 19 | - BOARD=uno 20 | - BOARD=megaatmega2560 21 | - BOARD=diecimilaatmega328 22 | - BOARD=leonardo 23 | - BOARD=micro 24 | - BOARD=nanoatmega328 25 | - BOARD=pro16MHzatmega328 26 | - BOARD=teensy2 27 | - BOARD=teensy2pp 28 | - BOARD=teensylc 29 | - BOARD=teensy30 30 | - BOARD=teensy31 31 | - BOARD=teensy35 32 | - BOARD=teensy36 33 | - BOARD=nodemcu 34 | - BOARD=nodemcuv2 35 | - BOARD=huzzah 36 | # - BOARD=lenny # This is a PIC32 board. Travis doesn't have pic32-g++ 37 | - BOARD=genuino101 38 | - BOARD=due 39 | # - BOARD=dueUSB 40 | - BOARD=zero 41 | - BOARD=zeroUSB 42 | - BOARD=mzeroUSB 43 | - BOARD=mzeropro 44 | - BOARD=mzeroproUSB 45 | 46 | matrix: 47 | fast_finish: true 48 | 49 | before_install: 50 | - pip install -U platformio 51 | 52 | install: 53 | # Libraries from PlatformIO Library Registry: 54 | # http://platformio.org/lib/show/1002/elapsedMillis 55 | - platformio lib -g install 1002 56 | # http://platformio.org/lib/show/898/DmxSimple 57 | - platformio lib -g install 898 58 | # http://platformio.org/lib/show/126/FastLED 59 | - platformio lib -g install 126 60 | 61 | script: 62 | - platformio ci --lib="." --board=$BOARD 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DMXUSB 2 | ======== 3 | [![License](https://img.shields.io/github/license/DaAwesomeP/dmxusb.svg?style=flat-square)](https://github.com/DaAwesomeP/dmxusb/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/DaAwesomeP/dmxusb.svg?style=flat-square)](https://github.com/DaAwesomeP/dmxusb/releases/latest) [![Github Releases Downloads](https://img.shields.io/github/downloads/DaAwesomeP/dmxusb/latest/total.svg?style=flat-square)](https://github.com/DaAwesomeP/dmxusb/releases/latest) [![build status](https://img.shields.io/travis/DaAwesomeP/dmxusb.svg?maxAge=2592000&style=flat-square)](https://travis-ci.org/DaAwesomeP/dmxusb) 4 | --- 5 | DMXUSB implements the ENTTEC DMX USB Pro Widget API Specification 1.44 on any serial port. DMXUSB can emulate a single DMX port/universe device like the DMXKing USB ultraDMX Micro, a two port/universe device like the DMXKing ultraDMX Pro, or an n-universe DMXUSB device. All devices are compatible with the ENTTEC standard. DMXUSB works with the Open Lighting Architecture (OLA) as a usbserial device. 6 | 7 | ## Installation 8 | DMXUSB is regularly tested on the Arduino Mega 2560 and the PJRC Teensy 3.2. Compilation tests for many more boards are [completed via Continuous Integration](https://travis-ci.org/DaAwesomeP/dmxusb). 9 | 10 | ### Via Arduino IDE Library Manager 11 | In the Arduino IDE, go to `Sketch > Tools > Include Library > Manage Libraries` and search and install the latest release version DMXUSB. **If you are not using a PJRC Teensy board, then you will also need to install the elapsedMillis library.** 12 | 13 | ### Via the ZIP archive 14 | Download the latest release ZIP from [here](https://github.com/DaAwesomeP/dmxusb/releases/latest) or the latest testing release from [here](https://github.com/DaAwesomeP/dmxusb/archive/master.zip). Then go to `Sketch > Tools > Include Library > Add ZIP Library`. **If you are not using a PJRC Teensy board, then you will also need to download and install the [elapsedMillis library](https://github.com/pfeerick/elapsedMillis/releases/latest).** 15 | 16 | ## Usage 17 | Currently, the library only receives DMX messages from a PC over USB. Please take a look at the [`Simple_Test` sketch](examples/Simple_Test/Simple_Test.ino) for a complete example. 18 | 19 | ### DMXUSB (serial, baudrate, mode, callback, outUniverses, serialNum) 20 | The DMXUSB class initializes a new instance of the library. The `outUniverses` argument is only required for mode 2. The `serialNum` argument is also not required. Example: 21 | ```cpp 22 | DMXUSB myDMXUsb(Serial, 115200, 0, myDMXCallback); 23 | ``` 24 | 25 | #### serial (Stream) 26 | Any Stream-based serial port. On my Arduino-like boards, `Serial` is the USB serial port. If multiple classes are initialized, then multiple serial ports can be used. 27 | 28 | #### baudrate (int) 29 | The baudrate of the serial port or stream. The library assumes that the serial port or stream is opened with this baudrate in `setup()`. 30 | 31 | Note that one raw DMX port runs at 250 kbps (250,000 baud). It is recommended to use the maximum available reliable baudrate for your device. Set the `mode` setting below accordingly with consideration for the error rates of your device. 32 | 33 | Also note that the USB serial on Teensy boards always operate at 12 mbps regardless of setting. You should always set the baudrate to 12,000,000 baud for Teensy devices. 34 | 35 | #### mode (int) 36 | The type of device to emulate: 37 | 38 | | value | description | 39 | |-------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 40 | | 0 | A standard ENTTEC-compatible device with one universe output that emulates the UltraDMX Micro (ESTA ID: 0x6A6B, Device ID: 0x3) | 41 | | 1 | A DMXKing two-universe device that emulates the UltraDMX Pro (0x6A6B, Device ID: 0x2) | 42 | | 2 | A DMXUSB n-universe device similar to the DMXKing two-universe device (requires the `outUniverses` argument) **that is in development and not yet supported by OLA** (0x7FF7, Device ID: 0x32) | 43 | 44 | The following table shows which universes receive callbacks when different commands are sent to DMXUSB. When label 6 is received in all modes, the callback will be called multiple times and output to all universes as per the DMXKing specification. 45 | 46 | | mode | label (command type) | universe 0 | universe 1 | universes 2 through n | 47 | |------|----------------------|-------------|------------|-----------------------| 48 | | 0 | 6 | Yes | No | No | 49 | | 0 | 100 | No | No | No | 50 | | 0 | 101 | No | No | No | 51 | | 0 | 102 through n | No | No | No | 52 | | 1 | 6 | Yes | Yes | No | 53 | | 1 | 100 | Yes | No | No | 54 | | 1 | 101 | No | Yes | No | 55 | | 1 | 102 through n | No | No | No | 56 | | 2 | 6 | Yes | Yes | Yes | 57 | | 2 | 100 | Yes | No | No | 58 | | 2 | 101 | No | Yes | No | 59 | | 2 | 102 through n | No | No | Yes | 60 | 61 | Note that mode 0 only responds to ENTTEC label 6 and outputs to universe 0 in the callback. When mode is 1 or 2, label 6 outputs to either universe 0 and 1 for mode 1 and universes 0 through n for mode 2 (the callback is called multiple times). This mimics the DMXKing specification. With mode 1, label 100 outputs to only universe 0 and label 101 outputs to only universe 1. 62 | 63 | #### callback (void) 64 | A callback function to call when a DMX transmission is received. This function should have three parameters: 65 | 66 | | parameter | description | 67 | |--------------------|-------------------------------------------------------------------------| 68 | | int universe | An integer starting at `0` with which universe received the DMX message | 69 | | char buffer[512] | The array of 512 DMX values starting at 0 | 70 | 71 | Example function that lights an LED with channel 1 on universe 0: 72 | ```cpp 73 | void myDMXCallback(int universe, char buffer[512]) { 74 | for (int index=0; index < 512; index++) { // for each channel, universe starts at 0 75 | int channel = index + 1; // channel starts at 0, so index 0 is DMX channel 1 and index 511 is DMX channel 512 76 | int value = buffer[index]; // DMX value 0 to 255 77 | if (universe == 0 && channel == 1) analogWrite(LED_PIN, value); // LED on channel 1 on universe 0 78 | } 79 | } 80 | ``` 81 | 82 | #### outUniverses (int) 83 | The number of output universes. This parameter is required only when the mode is 2. **The number of output universes defaults to 0 if mode 2 is used and this parameter is not set.** This argument is ignored for modes 0 and 1. 84 | 85 | The maximum number of theoretical universes is found with the following equation: 86 | ``` 87 | (maximum universes) = [(device baud rate) / (250,000 baud)] - 1 88 | ``` 89 | You must subtract one as seen above because there are a few extra bytes in every DMX packet when sent over USB with this library. This equation does not take into account CPU time and load or how long it takes to process the data or run the rest of your program. **With this math, the Teensy can theoretically achieve 47 universes!** 90 | 91 | #### serialNum (uint32_t) 92 | If you are using multiple devices on one computer, then you should use unique serial numbers. Unique serial numbers will be applied by default for Teensy LC/3.0/3.1/3.2/3.5/3.6 devices when this argument is not included or it is set to `0xFFFFFFFF`. The default serial number is `0xFFFFFFFF` for non-Teensy devices. This should be a `uint32_t`. 93 | 94 | ### DMXUSB.listen () 95 | A function of the class that causes the library to check for messages. This function is typically called at the top of `loop()`. Example: 96 | ```cpp 97 | void loop() { 98 | myDMXUsb.listen(); 99 | } 100 | ``` 101 | 102 | ## DMXUSB Device Specification (mode 2) 103 | The DMXUSB Device extends the DMXKing UltraDMX Pro specification in the following ways: 104 | 105 | ### Labels 100 through 100 + n 106 | Label 100 will send to universe 0, label 101 will send to universe 1, label 102 will send to universe 2, etc. Sending to more universes than are configured in `out_universes` or are responded with the Extended Parameters message is simply ignored. 107 | 108 | ### Label 53 Extended Parameters 109 | Sending an empty message with label 53 will respond with the label 53 Extended Parameters Message with the following data: 110 | 111 | 1. Number of output universes (one byte) 112 | 2. Number of input universes (one byte) 113 | 114 | More data may be added to this packet in the future. 115 | 116 | ## References 117 | This library was built using the following sources: 118 | 119 | - [ENTTEC DMX USB Pro Widget API Specification 1.44](https://dol2kh495zr52.cloudfront.net/pdf/misc/dmx_usb_pro_api_spec.pdf) 120 | - [DMXKing ultraDMX Pro User Manual](https://www.pjrc.com/teensy/td_uart.html) 121 | - [Open Lighting Protocol USB Protocol Extensions Reference](https://wiki.openlighting.org/index.php/USB_Protocol_Extensions#Device_Manufacturer.2C_Label_.3D_77.2C_no_data) 122 | - [Open Lighting Project Mailing List Help Thread](https://groups.google.com/forum/#!topic/open-lighting/SIMMzwRcxPY) 123 | - [Basic Proof-of-Concept of ENTTEC device emulation](https://github.com/PaulStoffregen/Lighting_Controller/blob/master/electronics/CorePlay/CorePlay.ino) 124 | 125 | ## License 126 | Please see the [LICENSE file](LICENSE) 127 | -------------------------------------------------------------------------------- /examples/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaAwesomeP/dmxusb/70d4ae3dfafdc91a9b7d6e4a9c4b730d281e0667/examples/.gitkeep -------------------------------------------------------------------------------- /examples/DMXUSB_DmxSimple/DMXUSB_DmxSimple.ino: -------------------------------------------------------------------------------- 1 | /* DMXUSB_DmxSimple.ino 2 | * Originally created 11/25/2017 by Perry Naseck (DaAwesomeP) 3 | * This is an example sketch for the DMXUSB Arduino/Teensy library to create a USB to DMX device. 4 | * https://github.com/DaAwesomeP/dmxusb/ 5 | * 6 | * Copyright 2017-present Perry Naseck (DaAwesomeP) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | // NOTE: This code has not been tested. I do not own the hardware required to test it. 22 | // More information about DmxSimple here: https://github.com/PaulStoffregen/DmxSimple 23 | 24 | #include "DMXUSB.h" 25 | #include 26 | 27 | // DMXUSB should receive and transmit data at the highest, most reliable speed possible 28 | // Recommended Arduino baud rate: 115200 (limits maximum framerate and/or number of channels 29 | // Recommended Teensy USB baud rate: 12000000 (12 Mb/s) 30 | // DMX baud rate: 250000 31 | // MIDI baud rate: 31250 32 | #define DMXUSB_BAUDRATE 115200 33 | 34 | // Pin that DMX port is on 35 | // DmxSimple uses pin 3 by default. 36 | #define DMX_PIN 3 37 | 38 | // Max DMX channels to output 39 | // From the DmxSimple README: 40 | // "Timer 2 is used. Due to the small amount of RAM on 168 and Mega8 Arduinos, only 41 | // the first 128 channels are supported. Arduinos with processor sockets can easily 42 | // be upgraded to a 328 to control all 512 channels." 43 | // This code has not been tested, so the performance is unknown. Please report your 44 | // findings to https://github.com/DaAwesomeP/dmxusb/issues 45 | #define DMX_MAX_CHANNELS 128 46 | 47 | // receive a DMX transmission 48 | void sendDMX(int universe, char buffer[512]) { 49 | for (int index=0; index < 512; index++) { // for each channel, universe starts at 0 50 | int channel = index + 1; // channel starts at 0, so index 0 is DMX channel 1 and index 511 is DMX channel 512 51 | int value = buffer[index]; // DMX value 0 to 255 52 | if (universe == 0 && channel <= DMX_MAX_CHANNELS) DmxSimple.write(channel, value); // Send universe 0 to the DMX port if in specified channel range 53 | } 54 | } 55 | 56 | DMXUSB DMXPC( 57 | // Stream serial, 58 | Serial, 59 | // int baudrate, 60 | DMXUSB_BAUDRATE, 61 | // int mode, 62 | 0, 63 | // void (*dmxInCallback)(int universe, unsigned int index, char buffer[512]) 64 | sendDMX 65 | ); 66 | 67 | void setup() { 68 | Serial.begin(DMXUSB_BAUDRATE); 69 | 70 | // DMX port 71 | DmxSimple.usePin(DMX_PIN); 72 | 73 | // Number of channels to output on 74 | DmxSimple.maxChannel(DMX_MAX_CHANNELS); 75 | } 76 | 77 | void loop() { 78 | DMXPC.listen(); 79 | } 80 | 81 | -------------------------------------------------------------------------------- /examples/DMXUSB_FastLED/DMXUSB_FastLED.ino: -------------------------------------------------------------------------------- 1 | /* DMXUSB_FastLED.ino 2 | * Originally created 11/25/2017 by Perry Naseck (DaAwesomeP) 3 | * This is an example sketch for the DMXUSB Arduino/Teensy library to drive adressable LEDs with the FastLED library. 4 | * https://github.com/DaAwesomeP/dmxusb/ 5 | * 6 | * Copyright 2017-present Perry Naseck (DaAwesomeP) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | // The example uses code from the FastLED Blink example here: 22 | // https://github.com/FastLED/FastLED/blob/master/examples/Blink/Blink.ino 23 | // More information about FastLED here: https://github.com/FastLED/FastLED 24 | 25 | #include "DMXUSB.h" 26 | #include 27 | 28 | // DMXUSB should receive and transmit data at the highest, most reliable speed possible 29 | // Recommended Arduino baud rate: 115200 (limits maximum framerate and/or number of channels 30 | // Recommended Teensy USB baud rate: 12000000 (12 Mb/s) 31 | // DMX baud rate: 250000 32 | // MIDI baud rate: 31250 33 | #define DMXUSB_BAUDRATE 115200 34 | 35 | // Number of LEDs on the strip 36 | #define NUM_LEDS 1 37 | 38 | // For LED chips like Neopixels, which have a data line, ground, and power, you just 39 | // need to define DATA_PIN. For LED chipsets that are SPI based (four wires - data, clock, 40 | // ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN 41 | #define DATA_PIN 3 42 | #define CLOCK_PIN 13 43 | 44 | // Define the array of LEDs 45 | CRGB leds[NUM_LEDS]; 46 | 47 | // receive a DMX transmission 48 | void showLEDs(int universe, char buffer[512]) { 49 | for (int index=0; index < 512; index++) { // for each channel, universe starts at 0 50 | int value = buffer[index]; // DMX value 0 to 255 51 | int LEDchannel = (universe*510) + index; // Find the LED number; can't fit a 3-channel fixture on the remaining two channels 52 | if (LEDchannel <= (NUM_LEDS*3)-1) { // If DMX channel (LEDchannel starts at 0) is in range of LEDs (3 channels per LED for RGB) 53 | int colorChannel = LEDchannel % 3; // Find the color channel of the LED addressed 54 | int ledID = (LEDchannel - colorChannel) / 3; // Find the FastLED index of the LED addressed 55 | if (colorChannel == 0) leds[ledID].r = value; // If the channel is red, write the red value of the LED 56 | if (colorChannel == 1) leds[ledID].g = value; // If the channel is green, write the red value of the LED 57 | if (colorChannel == 2) leds[ledID].b = value; // If the channel is blue, write the blue value of the LED 58 | } 59 | } 60 | FastLED.show(); // Display the frame after processing all channels 61 | } 62 | 63 | DMXUSB DMXPC( 64 | // Stream serial, 65 | Serial, 66 | // int baudrate, 67 | DMXUSB_BAUDRATE, 68 | // int mode, 69 | // With mode==1, the library processes two universes for a total of 1024 DMX channels 70 | 1, 71 | // void (*dmxInCallback)(int universe, unsigned int index, char buffer[512]) 72 | showLEDs 73 | ); 74 | 75 | void setup() { 76 | Serial.begin(DMXUSB_BAUDRATE); 77 | 78 | // Uncomment/edit one of the following lines for your leds arrangement. 79 | // FastLED.addLeds(leds, NUM_LEDS); 80 | // FastLED.addLeds(leds, NUM_LEDS); 81 | // FastLED.addLeds(leds, NUM_LEDS); 82 | // FastLED.addLeds(leds, NUM_LEDS); 83 | // FastLED.addLeds(leds, NUM_LEDS); 84 | // FastLED.addLeds(leds, NUM_LEDS); 85 | FastLED.addLeds(leds, NUM_LEDS); 86 | // FastLED.addLeds(leds, NUM_LEDS); 87 | // FastLED.addLeds(leds, NUM_LEDS); 88 | // FastLED.addLeds(leds, NUM_LEDS); 89 | // FastLED.addLeds(leds, NUM_LEDS); 90 | // FastLED.addLeds(leds, NUM_LEDS); 91 | 92 | // FastLED.addLeds(leds, NUM_LEDS); 93 | // FastLED.addLeds(leds, NUM_LEDS); 94 | // FastLED.addLeds(leds, NUM_LEDS); 95 | // FastLED.addLeds(leds, NUM_LEDS); 96 | // FastLED.addLeds(leds, NUM_LEDS); 97 | // FastLED.addLeds(leds, NUM_LEDS); 98 | } 99 | 100 | void loop() { 101 | DMXPC.listen(); 102 | } 103 | 104 | -------------------------------------------------------------------------------- /examples/DMXUSB_Simple/DMXUSB_Simple.ino: -------------------------------------------------------------------------------- 1 | /* DMXUSB_Simple.ino 2 | * Originally created 11/21/2017 by Stefan Krüger (s-light) 3 | * This is a simple example sketch for the DMXUSB Arduino/Teensy library. 4 | * https://github.com/DaAwesomeP/dmxusb/ 5 | * 6 | * Copyright 2017-present Stefan Krüger (s-light) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #include "DMXUSB.h" 22 | 23 | const byte LED_PIN = 13; 24 | 25 | // DMXUSB should receive and transmit data at the highest, most reliable speed possible 26 | // Recommended Arduino baud rate: 115200 (limits maximum framerate and/or number of channels 27 | // Recommended Teensy USB baud rate: 12000000 (12 Mb/s) 28 | // DMX baud rate: 250000 29 | // MIDI baud rate: 31250 30 | #define DMXUSB_BAUDRATE 115200 31 | 32 | // receive a DMX transmission 33 | void myDMXCallback(int universe, char buffer[512]) { 34 | for (int index=0; index < 512; index++) { // for each channel, universe starts at 0 35 | int channel = index + 1; // channel starts at 0, so index 0 is DMX channel 1 and index 511 is DMX channel 512 36 | int value = buffer[index]; // DMX value 0 to 255 37 | if (universe == 0 && channel == 1) analogWrite(LED_PIN, value); // LED on channel 1 on universe 0 38 | } 39 | } 40 | 41 | DMXUSB myDMXUsb( 42 | // Stream serial, 43 | Serial, 44 | // int baudrate, 45 | DMXUSB_BAUDRATE, 46 | // int mode, 47 | 0, 48 | // void (*dmxInCallback)(int universe, unsigned int index, char buffer[512]) 49 | myDMXCallback 50 | ); 51 | 52 | void setup() { 53 | pinMode(LED_PIN, OUTPUT); 54 | Serial.begin(DMXUSB_BAUDRATE); 55 | } 56 | 57 | void loop() { 58 | myDMXUsb.listen(); 59 | } 60 | -------------------------------------------------------------------------------- /extras/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DaAwesomeP/dmxusb/70d4ae3dfafdc91a9b7d6e4a9c4b730d281e0667/extras/.gitkeep -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For DMXUSB 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | DMXUSB KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | listen KEYWORD2 16 | 17 | ####################################### 18 | # Instances (KEYWORD2) 19 | ####################################### 20 | 21 | ####################################### 22 | # Constants (LITERAL1) 23 | ####################################### 24 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=DMXUSB 2 | version=0.0.4 3 | author=DaAwesomeP 4 | maintainer=DaAwesomeP 5 | sentence=DMXUSB emulates an ENTTEC-compatible DMXKing USB to DMX serial device with one, two, or n universes. 6 | paragraph=DMXUSB implements the ENTTEC DMX USB Pro Widget API Specification 1.44 on any serial port. DMXUSB can emulate a single DMX port/universe device like the DMXKing USB ultraDMX Micro, a two port/universe device like the DMXKing ultraDMX Pro, or an n-universe DMXUSB device. All devices are compatible with the ENTTEC standard. DMXUSB works with the Open Lighting Architecture (OLA) as a usbserial device. This library requires the elapsedMillis library for all boards except the PJRC Teensy. 7 | category=Communication 8 | url=https://github.com/DaAwesomeP/dmxusb 9 | architectures=* 10 | includes=DMXUSB.h 11 | license=Apache-2.0 12 | bugs=https://github.com/DaAwesomeP/dmxusb/issues 13 | -------------------------------------------------------------------------------- /src/DMXUSB.cpp: -------------------------------------------------------------------------------- 1 | /* DMXUSB.cpp 2 | * Originally created 11/20/2017 by the Perry Naseck (DaAwesomeP) 3 | * This is the source file to the DMXUSB Arduino/Teensy library. 4 | * https://github.com/DaAwesomeP/dmxusb/ 5 | * 6 | * Copyright 2017-present Perry Naseck (DaAwesomeP) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #include "Arduino.h" 22 | #include "DMXUSB.h" 23 | 24 | // Byte order for Enttec/DMXKing protocol 25 | #define STATE_START 0 26 | #define STATE_LABEL 1 27 | #define STATE_LEN_LSB 2 28 | #define STATE_LEN_MSB 3 29 | #define STATE_DATA 4 30 | #define STATE_END 5 31 | 32 | // Initialize DMXUSB serial port 33 | DMXUSB::DMXUSB(Stream &serial, int baudrate, int mode, void (*dmxInCallback)(int universe, char buffer[512]), int outUniverses, uint32_t serialNum) { 34 | _serial = &serial; 35 | _baudrate = baudrate; 36 | _mode = mode; 37 | _dmxInCallback = dmxInCallback; 38 | if (_mode == 0) _outUniverses = 1; 39 | else if (_mode == 1) _outUniverses = 2; 40 | else if (_mode == 2) _outUniverses = outUniverses; 41 | #if defined(AUTO_SERIAL_AVAILABLE) 42 | if (serialNum == 0xffffffff) { 43 | DMXUSB::teensySerial(); 44 | } else _serialNum = serialNum; 45 | #else 46 | _serialNum = serialNum; 47 | #endif 48 | } 49 | 50 | // Get Teensy Serial Number for LC, 3.0, 3.1/3.2, 3.5, and 3.6 51 | // Taken from TeensyMAC, modified to modify a uint8_t instead of return a uint32_t: 52 | // https://github.com/FrankBoesing/TeensyMAC/blob/a5b394bd91a0740bc4d974f7174eb426853a9ddd/TeensyMAC.cpp 53 | #if defined(AUTO_SERIAL_AVAILABLE) 54 | #define MY_SYSREGISTERFILE ((uint8_t *)0x40041000) // System Register File 55 | uint32_t DMXUSB::_getserialhw(void) { 56 | uint32_t num; 57 | __disable_irq(); 58 | #if defined(HAS_KINETIS_FLASH_FTFA) || defined(HAS_KINETIS_FLASH_FTFL) 59 | FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL; 60 | FTFL_FCCOB0 = 0x41; 61 | FTFL_FCCOB1 = 15; 62 | FTFL_FSTAT = FTFL_FSTAT_CCIF; 63 | while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait 64 | num = *(uint32_t *)&FTFL_FCCOB7; 65 | #elif defined(HAS_KINETIS_FLASH_FTFE) 66 | // Does not work in HSRUN mode : 67 | FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL; 68 | *(uint32_t *)&FTFL_FCCOB3 = 0x41070000; 69 | FTFL_FSTAT = FTFL_FSTAT_CCIF; 70 | while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait 71 | num = *(uint32_t *)&FTFL_FCCOBB; 72 | #endif 73 | __enable_irq(); 74 | return num; 75 | } 76 | #if defined(HAS_KINETIS_FLASH_FTFE) && (F_CPU > 120000000) 77 | extern "C" void startup_early_hook(void) { 78 | #if defined(KINETISK) 79 | WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; 80 | #elif defined(KINETISL) 81 | SIM_COPC = 0; // disable the watchdog 82 | #endif 83 | *(uint32_t*)(MY_SYSREGISTERFILE) = DMXUSB::_getserialhw(); 84 | } 85 | #endif 86 | 87 | void DMXUSB::teensySerial(void) { 88 | uint32_t num; 89 | #if defined(HAS_KINETIS_FLASH_FTFE) && (F_CPU > 120000000) 90 | num = *(uint32_t*)(MY_SYSREGISTERFILE); 91 | #else 92 | num = DMXUSB::_getserialhw(); 93 | #endif 94 | // add extra zero to work around OS-X CDC-ACM driver bug 95 | // http://forum.pjrc.com/threads/25482-Duplicate-usb-modem-number-HELP 96 | if (num < 10000000) num = num * 10; 97 | _serialNum = num; 98 | } 99 | #endif 100 | 101 | // Poll for incoming DMX messages 102 | // Modified basic Enttec emulation code from Paul Stoffregen's code to include labels 77, 78, 100, and 101 103 | // https://github.com/PaulStoffregen/Lighting_Controller/blob/master/electronics/CorePlay/CorePlay.ino 104 | void DMXUSB::listen() { 105 | if (_serial->available()) { 106 | byte state = STATE_START; 107 | byte label = 0x00; 108 | unsigned int index = 0; 109 | unsigned int count = 0; 110 | byte b; 111 | _timeout = 0; 112 | 113 | while (1) { 114 | while (!_serial->available()) { 115 | // 0.5 seconds without data, reset state 116 | if (_timeout > 500) state = STATE_START; 117 | } 118 | _timeout = 0; 119 | b = _serial->read(); 120 | 121 | switch (state) { 122 | // first bit: start of message 123 | case STATE_START: 124 | if (b == 0x7E) state = STATE_LABEL; // if start bit, move to second bit 125 | break; 126 | 127 | // second bit: message label 128 | case STATE_LABEL: 129 | label = b; // record the message label 130 | if (label == 6 || (label >= 100 && label < 100 + _outUniverses)) for (int i = 0; i < 512; i++) _buffer[i] = (byte)0x00; // set buffer to all zero values if receiving DMX data 131 | state = STATE_LEN_LSB; // move to next bit 132 | break; 133 | 134 | // third bit: data length LSB (0 to 600) 135 | case STATE_LEN_LSB: 136 | count = b; // record the message length 137 | state = STATE_LEN_MSB; // move to next bit 138 | break; 139 | 140 | // fourth bit: data length MSB 141 | case STATE_LEN_MSB: 142 | count |= (b << 8); 143 | index = 0; 144 | if (count > 0) { 145 | state = STATE_DATA; 146 | } else { 147 | state = STATE_END; 148 | } 149 | break; 150 | 151 | // starting at fifth bit: data 152 | case STATE_DATA: 153 | if (index <= sizeof(_buffer)) { // include 512 154 | if (index > 0) { 155 | _buffer[index - 1] = b; // record the data, DMX channels start at 1 but array of channels starts at 0 156 | } 157 | index++; 158 | } 159 | count = count - 1; // decrease the data count 160 | if (count == 0) { 161 | state = STATE_END; // if no more data, move on to last bit 162 | } 163 | break; 164 | 165 | // final bit 166 | case STATE_END: 167 | if (b == 0xE7) { // if final bit 168 | state = STATE_START; 169 | if (label == 77) { // if message is of label 77 (ETSA ID request), then send ETSA ID 170 | int len = 8; 171 | _serial->write(0x7E); // message header 172 | _serial->write(0x4D); // label 77 173 | _serial->write(len & 0xff); // data length LSB: 2 + MSB 174 | _serial->write((len + 1) >> 8); // data length MSB 175 | if (_mode == 0 || _mode == 1) { // DMXKing device 176 | _serial->write(0x6B); 177 | _serial->write(0x6A); 178 | } else if (_mode == 2) { // DMXUSB device 179 | _serial->write(0xF7); // Uses ETSA prototype ID 180 | _serial->write(0x7F); // Uses ETSA prototype ID 181 | } 182 | _serial->write("DMXUSB"); 183 | _serial->write(0xE7); // message footer 184 | } 185 | 186 | else if (label == 78) { // if message is of label 78 (device ID request), then send device ID 187 | int len = 2; 188 | if (_mode == 0) len += 23; 189 | if (_mode == 1) len += 21; 190 | if (_mode == 2) len += 28; 191 | _serial->write(0x7E); // message header 192 | _serial->write(0x4E); // label 78 193 | _serial->write(len & 0xff); // data length LSB: 2 194 | _serial->write((len + 1) >> 8); // data length MSB: 0 195 | if (_mode == 0) { // DMXKing ultraDMX Micro (one universe, Enttec compatible) 196 | _serial->write(0x03); // id 3 197 | _serial->write((byte)0x00); 198 | _serial->write("Emulated ultraDMX Micro"); 199 | } else if (_mode == 1) { // DMXKing ultraDMX Pro (two universes, Enttec compatible with label 6) 200 | _serial->write(0x02); // id 2 201 | _serial->write((byte)0x00); 202 | _serial->write("Emulated UltraDMX Pro"); 203 | } else if (_mode == 2) { // DMXUSB device (many universes, Enttec compatible with label 6) 204 | _serial->write(0x32); // id 50 (high to avoid possible collisions since ETSA ID isn't reserved) 205 | _serial->write((byte)0x00); 206 | _serial->write("DMXUSB Multi-universe Device"); 207 | } 208 | _serial->write(0xE7); // message footer 209 | } 210 | 211 | else if (label == 10) { // if message is of label 10 (serial number request), then send device serial number 212 | int len = 4; 213 | _serial->write(0x7E); // message header 214 | _serial->write(0x0A); // label 10 215 | _serial->write(len & 0xff); // data length LSB: 4 216 | _serial->write((len + 1) >> 8); // data length MSB: 0 217 | _serial->write((byte*)&_serialNum, 4); 218 | _serial->write(0xE7); // message footer 219 | } 220 | 221 | else if (label == 3) { // if message is of label 3 (widget parameters request), then send widget parameters 222 | int len = 5; 223 | _serial->write(0x7E); // message header 224 | _serial->write(0x03); // label 3 225 | _serial->write(len & 0xff); // data length LSB: 4 226 | _serial->write((len + 1) >> 8); // data length MSB: 0 227 | _serial->write((byte)0x03); // firmware version LSB: 3 (v0.0.4) 228 | _serial->write((byte)0x00); // firmware version MSB: 0 229 | _serial->write(0x09); // DMX output break time in 10.67 microsecond units: 9 (TODO: CALCUALTE WITH BAUDRATE) 230 | _serial->write(0x01); // DMX output Mark After Break time in 10.67 microsecond units: 1 (TODO: CALCUALTE WITH BAUDRATE) 231 | _serial->write(0x28); // DMX output rate in packets per second: 40 (TODO: CALCUALTE WITH BAUDRATE) 232 | _serial->write(0xE7); // message footer 233 | } 234 | 235 | else if (label == 53 && _mode == 2) { // if message is of label 203 (extended widget parameters request), then send extended widget parameters 236 | int len = 2; 237 | _serial->write(0x7E); // message header 238 | _serial->write(0x35); // label 53 239 | _serial->write(len & 0xff); // data length LSB: 2 240 | _serial->write((len + 1) >> 8); // data length MSB: 0 241 | // _serial->write((byte)0x00); // out universes 242 | _serial->write((byte)_outUniverses); // out universes 243 | _serial->write((byte)0x00); // in universes (not implemented) 244 | _serial->write(0xE7); // message footer 245 | } 246 | 247 | else if (label == 6 || (label >= 100 && label < 100 + _outUniverses)) { // receive DMX message to all universes 248 | //if (index > 1) { 249 | if (label == 6 && _mode == 0) this->DMXUSB::_dmxInCallback(0, _buffer); // receive label==6 DMX message to first universe for Enttec-like ultraDMX Micro device 250 | else if (label == 6 && _mode == 1) { // receive label==6 DMX message to both universes for ultraDMX Pro device 251 | this->DMXUSB::_dmxInCallback(0, _buffer); 252 | this->DMXUSB::_dmxInCallback(1, _buffer); 253 | } else if (label == 6 && _mode == 2) { // receive label==6 DMX message to all universes for DMXUSB device 254 | for (int i = 0; i < _outUniverses; i++) this->DMXUSB::_dmxInCallback(i, _buffer); 255 | } else if (label == 100 && _mode == 1) this->DMXUSB::_dmxInCallback(0, _buffer); // receive label==100 DMX message to first universe for ultraDMX Pro device 256 | else if (label == 101 && _mode == 1) this->DMXUSB::_dmxInCallback(1, _buffer); // receive label==101 DMX message to second universe for ultraDMX Pro device 257 | else if (_mode == 2) this->DMXUSB::_dmxInCallback(label - 100, _buffer); // receive labels 100 through 107 DMX message to each universe for DMXUSB device 258 | //} 259 | } 260 | } 261 | break; 262 | 263 | default: 264 | state = STATE_START; 265 | break; 266 | } 267 | } 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /src/DMXUSB.h: -------------------------------------------------------------------------------- 1 | /* DMXUSB.h 2 | * Originally created 11/20/2017 by the Perry Naseck (DaAwesomeP) 3 | * This is the header file to the DMXUSB Arduino/Teensy library. 4 | * https://github.com/DaAwesomeP/dmxusb/ 5 | * 6 | * Copyright 2017-present Perry Naseck (DaAwesomeP) 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #ifndef DMXUSB_h 22 | #define DMXUSB_h 23 | 24 | #include "Arduino.h" 25 | #if !defined(CORE_TEENSY) 26 | #include 27 | #endif 28 | 29 | #if defined(__MK20DX128__) // Teensy 3.0 30 | #define AUTO_SERIAL_AVAILABLE "3.0" 31 | #elif defined(__MK20DX256__) // Teensy 3.1 or 3.2 32 | #define AUTO_SERIAL_AVAILABLE "3.2" 33 | #elif defined(__MKL26Z64__) // Teensy LC 34 | #define AUTO_SERIAL_AVAILABLE "LC" 35 | #elif defined(__MK64FX512__) // Teensy 3.5 36 | #define AUTO_SERIAL_AVAILABLE "3.5" 37 | #elif defined(__MK66FX1M0__) // Teensy 3.6 38 | #define AUTO_SERIAL_AVAILABLE "3.6" 39 | #endif 40 | 41 | class DMXUSB { 42 | public: 43 | DMXUSB(Stream &serial, int baudrate, int mode, void (*dmxInCallback)(int universe, char buffer[512]), int outUniverses = 0, uint32_t serialNum = 0xffffffff); 44 | void listen(); 45 | #if defined(AUTO_SERIAL_AVAILABLE) 46 | // Must be public to always run 47 | static uint32_t _getserialhw(void); 48 | #endif 49 | private: 50 | char _buffer[512]; 51 | elapsedMillis _timeout; 52 | Stream *_serial; 53 | int _baudrate; 54 | int _mode; 55 | void (*_dmxInCallback)(int universe, char buffer[512]); 56 | int _outUniverses; 57 | #if defined(AUTO_SERIAL_AVAILABLE) 58 | void teensySerial(void); 59 | #endif 60 | uint32_t _serialNum; 61 | }; 62 | 63 | #endif 64 | 65 | --------------------------------------------------------------------------------