Category Archives: Arduino

Low-cost 8 channel MIDI controller

In one of the recent presentations with Per Hüttner we used TouchDesigner for live visuals. The gradual transitions between scenes were implemented using (invisible) sliders in TouchDesigner. However, making a full and smooth transition just having the MacBook touchpad to slide from one to the other side on screen was not so comfortable. Hardware-based MIDI controllers would have much better tactile feedback, like the Novation LaunchControlXL, the Midi Fighter Twister and the Intech controllers. Looking for more affordable options, we found a nicely looking ParksTool 8P on Etsy.

This triggered me to look into DIY options, and I found the M5Stack 8Angle interface, which consists of 8 knobs that connect over a Grove I2C connection to a microcontroller. I ordered the 8Angle interface online for only €15.00 and a matching M5NanoC6 microcontroller for €8.00 which I used to construct a simple 8-potentiometer MIDI interface.

M5NanoC6 microcontroller connected with a 4-wire grove cable to an 8Angle potentiometer controller

MIDI controller based on M5NanoC6+8Angle

The USB interface of the ESP32-C6 does not (yet) allow to do MIDI over USB, but the Control Surface library for Arduino does support MIDI over Bluetooth for the ESP32-C6. To connect it to your macOS computer, you have to start the “Audio MIDI Setup” application.

In the upper right corner you have to click on the Bluetooth symbol to initiate a connection.

The M5NanoC6 shows up as “Control Surface MIDI” and you can connect.

Subsequently it shows in the main panel of the Audio MIDI Setup panel as a Bluetooth device.

Using the excellent MIDI monitor application you can check that the MIDI signals are arriving, and you can assign them to the controls in TouchDesigner or in Ableton Live.

In my Arduino firmware I mapped the 8 knobs of the controller onto Control Change (CC) messages 0 to 7. The small switch on the controller allows switching between MIDI channel 1 and 2. The individual RGB LEDs on the controller change color along with the respective MIDI values.

12 Volt trigger for audio amplifier – PCB version

Previously I wrote how I designed and implemented a 12 Volt trigger for an NAD audio amplifier. Some time ago I also designed a PCB version of it. Here you can find some photos and the Eagle schematic.

There is one error in the design: the GND pin of the Wemos D1 mini board is not connected to the ground plane. I solved it with an air wire.

Some of the differences to the previous version are that it now has a button, a 12V input trigger, and a status LED. The button allows to manually switch it on and off without having to use my mobile phone. The 12 V input trigger allows the amplifier to be switched on by and off by the Sonos Port that is also connected to the amplifier.

I am using Tasmota as the firmware which – besides the button to switch it on and off – allows control over a web interface and over MQTT. The Tasmota template for the configuration is the following: {"NAME":"12V trigger", "GPIO":[1,1, 1,1,32,288,0,1,256,1,160,1,1,1], "FLAG":0, "BASE":18}.

The MQTT interface makes it easy to implement some automation with Node-RED that I have running on a Raspberry Pi. The automation is the following: whenever the smart TV or the MacMini (used for music) are switched on, as detected by them returning a network ping on their IP address, then the amplifier switches on, and vice versa.

I also have it configured using Homebridge in my Apple Home environment, which allows the Home application on my iPhone or iPad to manually control it, besides the Tasmota web interface.

Combining all of these, the NAD amplifier is switched on and off by either

  • the manual button
  • the smart TV (detected by an IP ping)
  • the MacMini (detected by an IP ping)
  • the Sonos Port (detected by its 12V output trigger)
  • the Apple Home application on my iPhone/iPad
  • the Tasmota web interface

However, the automation is not perfect: when after an afternoon of listening to Sonos we switch on the TV and switch off the Sonos Port, the Sonos Port only falls asleep after a minute or so. Consequently, the last action happens to be the Sonos Port 12V output going low; the amplifier therefore switches off after a minute or so, whereas we just switched the TV on. A quick press on the manual button switches it on again. Also, whenever we switch between MacMini, TV, or Sonos, we still have to walk to the amplifier to toggle it to the right audio input. An idea for the future is to mount an IR blaster that switches between the audio inputs automatically.

Wireless classroom conference microphone system – #5

This post is part of a series on designing a wireless microphone system for hybrid online meetings, i.e. with some people present in person and others present online. See also the previous post in this series.

So far I have built and experimented with 4 wifi microphones, including an on/off switch and a rechargeable LiPo battery. I also added a magnetic name tag holder like this to the back of each of the microphones, allowing them to be mounted on a shirt or the the lapel of a jacket. The most relevant parts comprise an INMP441 microphone connected to a Lolin32 lite board. I have a few more wired up with just the Lolin32 board and the microphone to allow testing a larger number.

I have also implemented a Python based server that is running on a Raspberry Pi zero W, which also functions as Wifi access point. The audio server buffers and mixes the incoming signal from the different microphones and plays it on a HifiBerry DAC+ zero audio card. The output is a line level voltage, strong enough to drive a headphone, and with some attenuation also suitable to feed into the microphone input of a low-cost USB headset adapter. The whole system works as expected, although the noise level of the microphones is higher than I had hoped. My guess is that it is in part due to the microphone being so close to the ESP8266 antenna. Also, the wires between the microcontroller and the microphone run over the Lolin32 board without any shielding, probably picking up EM interference.

The Arduino source code, the Python audio server code, and the Fusion360 CAD design files are available from the wifimic repository on Github.

The fact that it works with an USB headset adapter like this, i.e. a miniature external sound card, demonstrates that the device can also be connected to the standard Windows laptop “pink” microphone input.

My MacBook has a TRRS combined audio input/output and the TRS (stereo) cable that comes from the HifiBerry DAC audio card is not recognized as microphone when I plug it in, but over the USB headset adapter it works fine. There are Y-adapters to split the TRRS input into TRS for the headphone and a TS for the microphone that would allow connecting it. However, the Python audio server also works fine on macOS, which has the advantage that I can investigate the microphone audio signals in full quality. Rather than first converting the sound to a analog line-out on the Raspberry Pi, and then back into a digital representation by the USB headset adapter, I can use BlackHole or Soundflower to get the digital audio stream as it is generated by the microphone. A cool feature of BlackHole and Soundflower is that they support many channels. With some modifications to the Python server script, it will also be possible to stream the audio output of each microphone to each own channel, and record them with Audacity.

12 Volt trigger for NAD-D3020 amplifier

Update 3 January 2021 – mention that I am now using Tasmota firmware.

Update 26 February 2023 – I have followed this up with a PCB version that also includes a button and a 12 Volt input trigger for switching the 12 Volt output trigger.

The NAD D3020 is a hybrid digital audio amplifier with a combination of analog and digital inputs. I have been using it for quite some years now to play the sound of my Samsung smart TV over the living room speakers and for digital radio, iTunes and Spotify from my Mac mini. The Samsung is connected with an optical Toslink cable, the Mac mini is connected with a USB cable.

In the way the D3020 is placed in our media cabinet, its on/off button is not so easy to access. The D3020 remote control is really crappy and I find it anyway annoying to have to use multiple remotes to switch the power of all devices. Also, the status LEDs of the D3020 are dim and got considerably worse over time, especially for the OPT1 and the USB inputs that are for the TV and the Mac mini, and hence on most of the time. I guess that it uses OLEDs, which have degraded over time. Consequently, it happened quite often that we forgot to switch the amplifier off for the night.

However, the D3020 features a 12V trigger input port which allows the amplifier to be switched automatically on/off along with other gear. Of course, neither TV nor the Mac mini has a 12V output port, but both are connected to my home network; hence it is possible to detect over the network whether these are powered on.

Continue reading

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:

Continue reading

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 512kB flash (old modules) or 1MB (now more common). 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.

Update 3 Sept 2022 – the code has moved to its own esp8266_artnet_dmx512 repository to improve the timing and jitter with I2S (following this comment).

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