Category Archives: Arduino

Timing and jitter in DMX512 signals

My previous post on building an Art-Net to DMX interface using an ESP8266 seems to be getting a lot of attention. However, from the comments it is clear that a lot of people that build it themselves have difficulties to get it to work, or don’t get it to work at all. This post investigates this in more detail.

We have not been using these interfaces in our performances for quite some time, and started wondering whether there is something wrong my firmware. My implementation goes back to April 2017. Over the course of time there have been some updates to my code. Furthermore, the Arduino IDE has been updated, as well as the ESP8266 core for Arduino.

Recently I received all three interfaces back that I had built for my 1+1=3 collaborators and decided to update the firmware and to test them. One of them did not work at all due to a broken connection between the power supply and the Wemos D1 mini; two of them started just fine. After fixing the broken wire and updating the firmware on all three of them; they started up just fine, showing the green light (indicating a connection to the WiFi network) and on the monitor page of the web interface I cold see that Art-Net packets were being received. However, with my DMX controlled light it did not work at all.

Testing and initial diagnosis

Using an Enttec Open DMX interface and the very nice JV Lightning DmxControl software (which supports both Art-Net and the Enttec Open DMX), I set out to debug the issue. Since DMX is all about timing, I connected my DS203 mini oscilloscope to pin 2 and 3 of the DMX connector.

I found detailed schematic information about the timing of the DMX protocol on this page. Searching for oscilloscope images of DMX signals, I also found this page with information.

Comparing the output voltage with the DMX512 schematics, it became clear that something was wrong in the signal. To make it easier to see the full signal on the oscilloscope, I configured only three DMX output channels, all set to zero. The oscilloscope shows 5 similar blocks; changing the value for DMX channel 1, I see that the 3rd block changes – that is apparently the first channel. Prior to that should be a “start code” with value 0, so the last 4 blocks make sense. But the first block is too short; there is also a very short pulse all the way at the start which does not match the specification.

Output voltage with the initial firmware:

By connecting the Enttec Open DMX to my DMX controlled light, I could confirm that the combination works and that the DMX interface to my light is not broken. Connecting the Enttec Open DMX to the oscilloscope, I see that it has a much longer 1st block which is the “space for break” (labeled 1 according to this), and slightly different 2nd block which is the slot with the “start code”. Following is a whole series of blocks/slots corresponding to the DMX channels. In this case I cannot limit the number of DMX channels, so the series contains a full universe of 512 channels, each of them set to zero. Changing the values of the first few channels in Lighting DmxControl, I can see the corresponding change in the signal on the oscilloscope.

Since a static photo of the oscilloscope screen does not show that there is quite some jitter, especially in the first part of the signal, I uploaded a short video recording of the Enttec Open DXM signal.

Output voltage of the Enttec Open DMX:

As the initial “break” signal was apparently not correctly implemented in my firmware, I changed the code to use the low-level implementation of the break that was contributed here. Using 3 DMX channels again, this results in a good DMX signal.

Output voltage with the firmware, using the low-level break:

I investigated the problem with the original code, which consists of switching to a slower baud rate, sending a single byte as the break signal, and switching back to the original baud rate of 250000. Given that the “break” appears just as long as the other bytes, the switching of the serial port speed apparently fails. On the Arduino forum I found a post that suggested to flush the serial port prior to and after changing the speed; I implemented this and now the break signal looks fine again.

I think that the reason that it broke is due to updates in the Arduino version that I am using, and/or updates to the ESP8266 Arduino core. I guess I must have been lucky with my buggy initial implementation; this may explain why it failed for some people and worked for others.

Output voltage with the firmware, using the slow serial break:

DMX512 universe size

Connecting my Art-Net to DMX512 adapter with updated firmware to the DMX controlled light initially did not work; increasing the size of the DMX universe that is is passed on by my Art-Net to DMX512 adapter solved this. After some trial and error it turned out that – although I had configured the DMX light for three channels (R, G, B) – it would not work if it would receive less than 8 channels. I suppose this is because the light has a 3, 4, and 8-channel DMX mode, and that 8 channels is apparently the minimum for DMX input to be properly handled.

Comparing the timing of the three systems

Looking back at the videos, I see that the timing of the Enttec Open DXM controller is the worst, especially in the space for break and the mark after break (MAB). This is actually a known characteristic of the Open DMX, since timing is controlled by the serial (USB) port of the computer rather than by a dedicated microprocessor; that is also the reason why it is not recommended for serious applications.

My own EXP8266 firmware with the low-level code for the break shows less jitter for the break. Using the “slow serial byte” the jitter is totally gone for the break itself, but there is still some jitter in the duration of the MAB.

Regardless of the jitter, all three are working fine with my DMX controlled light! Having seen the timing of the signals in detail, I am also more confident that they should work with other DMX equipment. One thing I noticed however and don’t have a solution for right now, is that the differential voltage of the Max485 modules that I am using is considerably lower at ~3.5V than that of the Enttec at nearly 8V.

Summary

To summarize, I was glad to have the Enttec Open DMX USB adapter for testing, and especially for having the DS203. If you are doing electronics like this, I can really recommend to get an oscilloscope!

Besides testing with the Lightning DmxController software, I was also able to confirm that it all works smoothly again with our EEGsynth, using a patch consisting of the redis, inputcontrol and outputartnet modules.

Restoring the AT firmware on the ESP8266

Most of the time I am using Wemos D1 mini development boards in combination with the Arduino IDE to make my own firmware to run directly on the ESP8266 chip. But I also have some bare ESP-01 and ESP-12 modules lying around, and recently I came up with the plan to use one of them.

The specific project requires very well controlled timing of an ADC, for which I will use a regular ATmega328P-based Arduino board. In this project the ESP8266 will only be used to transmit the data over WiFi. Neither my ESP-01, not my ESP-12 still have the original AT firmware, since I have been experimenting with various other firmwares.

This is where the challenge starts, since my plan required restoring my ESP-12 to the AT firmware and use a library like ESP8266wifi or WiFiEsp. I realize that I have been struggling with different firmwares before, hence this post to give a short review and to keep some notes for my own future reference.

Module form factor

The ESP8266 microchip comes on various development boards that include an USB interface, such as the Wemos D1 Mini and the NodeMCU board, but also as bare modules such as the ESP-01, 02, etc. This page on the ESP8266 wiki has an overview of all modules and this page has comparison of some of the raw modules with some of the development boards.

ESP-01 module:

ESP-12 module:

Flash memory capacity

Besides the number of GPIO pins that is exposed by each of the modules, another important feature is their flash memory capacity. The AI-Thinker website has a module list table that includes this. The ESP-01 module comes with 4Mbit, i.e. 1MB of flash. The ESP-12 module comes with 4MB. Note that there are development boards such as the Wemos D1 mini pro that even have more.

Firmware

As the ESP8266 is nowadays fully supported in the Arduino IDE, I prefer to develop my own custom firmware for the ESP8266 using C/C++ and the Arduino IDE and libraries. So the most confusing aspect of the ESP8266 for me is that there are multiple “standard” firmwares available for it, which I often accidentally confuse. These include

  • The AT firmware, comparable to the Hayes command set on old modems.
  • The NodeMCU firmware, which includes a LUA interpreter.
  • The MicroPython firmware, which includes a Python interpreter.
  • The Espruino firmware, which includes a JavaScript interpreter.

For the firmware options that include a Python or a JavaScript interpreter it should be mentioned that there are other versions from other companies/projects.

The NodeMCU project is more centrally managed/organized and includes a website where you can compile customized firmwares with support for specific hardware add-ons.

Restoring the AT firmware

To flash the firmware to an ESP8266, you will need to wire it up and get it in the right boot loader mode. There are many online tutorials for this and I won’t elaborate here. You will also need software to write the new firmware, I am exclusively using esptool.py.

I tried various options to flash my ESP-12 with the original firmware, most of which failed. The challenge is to figure out which firmware is compatible with my specific module, and to which flash memory locations to write the different pieces of the firmware. In the next section I will describe three things that worked, going from the oldest to most recent firmware versions.

Following the instructions here and using a rather obscure version of the firmware contained in a single binary file from here, I had success with:

esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x00000 v0.9.2.2\ AT\ Firmware.bin

Subsequently I was able to connect in a terminal program with 9600 bps and got

[System Ready, Vendor:www.ai-thinker.com]
AT+GMR

0018000902

OK

Using the old AT firmware from Espressif itself with the “Offical ESP8266 AT+ Commands” from their old GitHub repository I was also able to get it to work with:

esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x00000 boot_v1.1.bin
esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x01000 newest/user1.bin
esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x7C000 esp_init_data_default.bin
esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x7E000 blank.bin

Subsequently I was able to connect in a terminal program with 115200 bps and got

ready
AT+GMR

00200.9.4

OK

The Espressif ESP8266 SDK Getting Started Guide contains the most recent information about the layout of the flash memory. Using the 2.2.1 release from the Espressif NONOS_SDK repository and

esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x00000 boot_v1.2.bin
esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x01000 at/512+512/user1.1024.new.2.bin
esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x7C000 esp_init_data_default_v05.bin
esptool.py --port /dev/tty.usbserial-FTG54BPS --baud 115200 write_flash --flash_mode dio 0x7E000 blank.bin

I also had success and was able to connect in a terminal program with 115200 bps. This resulted in the following response

ready
AT+GMR
AT version:1.6.2.0(Apr 13 2018 11:10:59)
SDK version:2.2.1(6ab97e9)
compile time:Jun 7 2018 19:34:26
Bin version(Wroom 02):1.6.2

I did not have success with the 3.0 release from the Espressif NONOS_SDK repository. That one does not have the “512+512” directory, only the “1024+1024” directory, which I could not get to work on my ESP-12. Suggestions to make this work are welcome.

Motion capture system

For the EEGsynth project I have developed a full-body 8-channel motion capture system. It is based on the MPU9250 9-DOF inertial motion unit, which contains a three-axis accelerometer, gyroscope and magnetometer. I have combined this with the Madgwick AHRS algorithm, which takes the raw sensor data and computes the yaw, pitch and roll.

The design is based on one battery operated main unit that is worn for example in a Fanny pack around the waist, and up to 8 sensors that are attached to the arms, legs, etc.

The main unit contains a Wemos D1 mini, which is based on the ESP8266 module. It uses the TCA9548 I2C multiplexer to connect a maximum of 8 MPU9250 sensors.

The data from the IMU sensors is streamed using the Open Sound Control (OSC) format. The sampling rate that can be achieved with one sensor is around 200 Hz, the sampling rate for 8 sensors is around 60 Hz.

For initial configuration of the WiFi network it uses WiFiManager. After connecting to my local WiFi network, it has a web-server through which the configuration can be set, which includes the number of sensors and the destination host and port for the OSC UDP packets.

For the IMUs I am using MPU9250 modules that I purchased on Ebay for about 3 USD each.The MPU9250 units fit very nicely in a Hammond 1551MINI enclosure.

I designed the enclosure for the main unit in Fusion360 and printed it on my Prusa I3 MK3 3-D printer. I made two motion capture systems so far, one with black and one with white PLA filament.

The Arduino sketch and more technical documentation can be found here on GitHub.

Configuring Multitech MDOT for TTN

I have a Multitech MDOT-BOX for testing. Configuring it for TTN requires the following connection to a computer, after which AT commands can be used to probe and set parameters. The following resets the MDOT to factory defaults and shows the configuration overview.

AT&F
AT&V

Firmware: 		2.0.0
Library : 		0.0.9-14-g4845711
Device ID:		00:80:00:00:00:00:b3:76
Frequency Band:		FB_868
Public Network:		off
Network Address:	00000000
Network ID:		6c:4e:ef:66:f4:79:86:a6
Network ID Passphrase:	MultiTech
Network Key:		1f.33.a1.70.a5.f1.fd.a0.ab.69.7a.ae.2b.95.91.6b
Network Key Passphrase:	MultiTech
Network Session Key:	00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00
Data Session Key:	00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00
Network Join Mode:	OTA
Tx Data Rate:		SF_7
Tx Power:		11
Log Level:		6
Maximum Size:		242
Minimum Size:		11
Maximum Power:		20
Minimum Power:		2
Data:			0

After adding a device to application page on the TTN console with OTA activation, the following identifiers/keys are listed on the TTN console page for the device

Device EUI
Application EUI
App Key
Device Address
Network Session Key
App Session Key

From the Multitech documentation: In OTA mode, the device only needs to be configured with a network name (+NI=1,name) and network passphrase (+NK=1,passphrase). The network session key, data session key, and network address are all automatically configured.

Continue reading

Art-Net to DMX512 with ESP8266

Update 1 August 2019 – added the connectors to the list of components

Update 4 July 2019 – You may also want to check out this instructable, which describes a more sophisticated ESP8266-based solution.

Update 6 April 2019 – I wrote a follow up post on the timing and jitter in DMX512 signals and fixed a bug in the firmware.

Update 26 May 2017 – added photo’s of second exemplar and screen shots of web interface for OTA.

Professional stage and theatre lighting fixtures are mainly controlled over DMX512. To allow a convenient interface between the EEGsynth and this type of professional lighting systems, I built an Artnet-to-DMX512 converter. It quite closely follows the design of my Artnet-to-Neopixel LED strip module.

Let me first show the finished product. It has a 5 pin XLR connector, a 2.1 mm power connector, and a multi-color status LED:

Continue reading

GPS-enabled LoRaWAN temperature sensor

Together with the TTN Nijmegen community we are discussing possible applications of remote sensing nodes in Nijmegen. To get a better view on the TTN coverage in Nijmegen and to get a feel for what works (and what not), we are working on the implementation of some nodes.

The PoC2 TTN gateway will soon be installed by Michiel Nijssen at Maptools in Molenhoek. To help Michiel get started, we agreed that I would give him a fully functional node to play with. Michiel came up with a very concrete idea: it consists of a GPS-enabled temperature sensor that sends the data over LoRaWAN/TTN. Below you can find some details of a very fist implementation.

The node consists of

  • Teensy 3.2 MCU board
  • Dorji LoRa module
  • DS18b20 temperature sensor
  • Ublox NEO-M8N GPS module
  • 4k7 ohm resistor
  • small LED and 200 ohm resistor (not on photo)

I estimate that the material costs amount to 50 euro. It still needs to be soldered in a more sturdy form-factor and a battery and enclosure need to be added.

Continue reading

ESP-8266 Art-Net NeoPixel module

As explained in a previous post, for the EEGsynth we want to use a neopixel array that can be controlled wirelessly using the DMX512 protocol. I purchased a number of Adafruit neopixel rings with 12, 16 and 24 elements respectively. Each RGBW pixel contains a red, green, blue and white LED. For the 24-pixel ring that means that there are in total 4*24=96 LEDs of which the intensity can be set.

The ESP-8266 module is a versatile WiFi module that comes in many versions. During development I especially like the NodeMCU version, which mounts the ESP-12 module on a development board with USB connection, and the even smaller Wemos D1 mini board. The Wemos D1 mini is hardly more expensive on Ebay than the simpler bare-bone ESP-8266 modules.

The hardware connection is simple: I connected Vcc and GND directly to the Wemos D1 mini board, and connected pin D2 to the data-in of the first pixel. Although the Neopixels are specified for 5V, in my experience the Adafruit rings also work fine at 3.3V, both for power and for the serial control signal. Each LED can take up to 20 mA when fully bright, which means that all LEDs of the 24-pixel RGBW ring can take up to 24*4*20 = 1920 mA, or close to 2 A. However, not all LEDs will be at full intensity at the same time, and driving them with 3.3V rather than 5V further reduces the current. I encountered no issues powering them over the USB port of my MacBook.

For the EEGsynth we want to map a small number of control signals to aesthetically pleasing light effects. E.g. it can control the hue, the frequency with which the array flashes, or the speed with which a bright bar rotates along the ring.

Continue reading

Scalable lighting systems

The X-mass holiday is always a nice time of the year to spend studying and tinkering on electronics projects. In the EEGsynth project we have identified that it would be cool to control light with brain and body signals, besides controlling modular synthesizers which we have focussed on so far. As it is not yet clear what kind of light and what kind of control will conceptually and aesthetically work well on the EEGsynth control signals, I have been studying both small and large lighting systems. We might for example want to use small and wearable lights on a performer, or control the stage light, or use a LED strip as indicator of the EEG-extracted control signals.

In theatrical and stage performance lighting there is a clearly dominant standard: DMX512. For lighting setups there are many fixtures (i.e. lamps rigged on ceiling mounted truss) that can be remotely controlled over DMX512, not only on-off, but they can be dimmed, the color can be changed, spotlights can be moved, etc. If you look on for example on Thomann, you’ll see that many light fixtures support DMX.

The Disco Biscuits – City Bisco – 10/5/12 – The Mann Center for the Performing Arts – Philadelphia, PA – Photo © Dave Vann 2012

Going to the smallest systems, I considered individual LEDs. Neopixels are a very interesting type of RGB LEDs, which combine a red, green and blue (and sometimes white) LED in a single few-mm small housing together with a controller chip. The controller chip allows the individual LED intensities of the neopixels to be addressed over a serial controller by a microcontroller such as an Arduino. Furthermore, multiple Neopixels can be daisy-chained, where each pixel in the array can be addressed. LED strips consisting of 30, 60 or even 144 pixels per meter can be purchased per meter, for example on Ebay.

Adafruit NeoPixel Ring with 16 x 5050 RGB LEDs with integrated drivers

For the the EEGsynth it is desirable to have a single control module that provides a uniform interface between ExG control signals and light control. An individual neopixel can be considered as an RGB lamp, just like a theatrical stage light. The intensity of the red, green and blue can be controlled, just like the DMX channels of a stage light. Controlling a small LED jewel worn by the performer should not be different than controlling the light of the stage on which the performer acts.

An important difference in the requirements for fixed stage lighting and a small wearable LED jewel is that the first must hook up to existing DMX512 cabling systems, whereas the second should be wireless. This is where Art-Net and the ESP-8266 come in. Art-Net is a protocol for sending the DMX control protocol over a network. The ESP-8266 is a small and low-cost microcontroller combined with a WiFi chip that is compatible with Arduino.

Further details on the hardware and firmware design for the actual light controller modules will come in a series of follow-up posts.

ESP-12 bootloader modes and GPIO state at startup

Since I encountered some initial difficulties in programming the ESP-12 version of the ESP8266 module using the Arduino IDE, let me here summarise some findings based on information from [1,2,3].

esp12-pinout

The ESP-12 module exposes 11 GPIOs. Three of them are especially relevant, as they determine the bootloader mode at startup or following reset.

                                  | GPIO 0 | GPIO 2 | GPIO 15
----------------------------------|--------|--------|---------
Flash Startup (Normal)            |   1    |   1    |   0
UART Download Mode (Programming)  |   0    |   1    |   0
SD-Card Boot                      |   0    |   0    |   1

Furthermore, CHPD should be pulled up and RESET should be pulled up or should be floating. If you connect RESET to ground, the module resets.

I have not yet figured out what the SD-Card boot means, so in my applications GPIO 2 should always be pulled up and GPIO 15 should always be pulled down. I am using 10k resistors, but smaller values (e.g. 3.3k) should also work.

To facilitate development, I connected two push button switches to the GPIO 0 and RESET pins, shorting them to ground when pressed. When the buttons are not pressed, they are both pulled up to 3.3V using a 10k resistor.

This allows me to do the following two-finger-action to restart in programming mode and allow the Arduino IDE to upload a new firmware:
– press reset button
– press programming button
– release reset button
– release programming button

References

[1] https://zoetrope.io/tech-blog/esp8266-bootloader-modes-and-gpio-state-startup
[2] http://www.instructables.com/id/Getting-Started-with-the-ESP8266-ESP-12/
[3] http://www.instructables.com/id/ESP8266-Using-GPIO0-GPIO2-as-inputs/

TTN/LoRa using Dorji DRF1272F module

Teensy connected to DRF1272f

Sofar I have been experimenting with LoRa and TTN using a Multitech MDot board and with a HopeRF RFM95W module connected to a Teensy, but I decided to try something else. Franz, one of the members of the TTN Nijmegen community, started experimenting with node-to-node communication using Dorji DRF1278F 433MHz modules. I’d like to support him in converting to 868MHz, so that he can post data to TTN once a gateway become available in his range.

The Dorji modules are currently among the cheapest LoRa modules available on Ebay. So some weeks ago I ordered a DRF1272F 868MHz module for about $8, which arrived this week.

The first surprise is that it has a 1.27 mm pitch header connector. The module has 13 contacts, but not all are required for the LMIC Arduino library. To make it more easy to handle, I made a custom break-out board that connects the required pins to a 2.54 mm pitch 8-pin header. Soldering the wires at 1.27 mm pitch was quite a challenge; you may want to use a magnifying glass, as those pads are tiny!

DFR1272f module adapter board

Based on the DRF1272F datasheet, the LMIC Arduino library documentation, and the Teensy pinout I connected it as follows:

 DRF1272F  |   Teensy 3.2
--------------------------
 RESET     |   nc
 DIO0      |   2
 DIO1      |   5
 DIO2      |   nc
 DIO3      |   nc
 DIO4      |   nc
 DIO5      |   nc
 3.3V      |   3.3V
 GND       |   GND
 SCK       |   13 - SCK
 MISO      |   12 - DIN 
 MOSI      |   11 - DOUT
 NSS       |   10 - CS

Please note that I did not connect the RESET and the DIO2 pin, which would be needed for FSK.

I used the following snippet of code in my Arduino sketch to specify the pin mapping:

// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 10,
.rxtx = LMIC_UNUSED_PIN,
.rst = 9,
.dio = {2, 5, 6},
};

On the software side I am using Arduino 1.6.9, the LMIC library and the same sketch that I have been using with the RFM95W module.

I had to change the Semtech radio from SX1276 to SX1272 in the arduino-lmic/src/lmic/config.h:

#define CFG_eu868 1
//#define CFG_us915 1
// This is the SX1272/SX1273 radio, which is also used on the HopeRF
// RFM92 boards.
#define CFG_sx1272_radio 1
// This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on
// the HopeRF RFM95 boards.
//#define CFG_sx1276_radio 1

Following all of this, this node is nicely sending packets to my TTN application.