Jul 10 2009

Rev13 of the Arduino DMX Reception Software Released

New in this version:

  • Tested and working with IDE version 0016.
  • The number of channels to receive is now easily user-configurable.
  • Replaced static variables with #define statements for RAM optimization (+48 bytes, woot!).

You can grab it here or mosey on over to the original post for the instructions.


Jun 20 2009

Arduino Theremin/Synth Final Walkthrough

P1000478DNG

It’s Done! I gave it to my sister last weekend and she really liked it.  If you’re just tuning in now, I have posts about the hardware development, waveform crafting, an early demonstration, and the software algorithm.  The final version has the following features:

  • Four octaves of continuous pitch variation by moving your hand nearer or farther from an ultrasound sensor
  • Digital volume control
  • Continuous waveform variation–can generate a pure sine tone like a classic theremin, or one with overtones, which sounds like an 80’s synth organ.
  • Spectral glide–similar to a Wah pedal or the instrument used in Peter Frampton’s ‘Do You Feel Like I Do’
  • Decay/Sustain–envelope shaping to play notes
  • Distortion–sounds like the guitar effect.

Listen to the Tone of the Future:

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

  1. 0:00-0:00 Pure tone, no effects
  2. 0:45 Waveform selection– no overtones
  3. 1:05 Decay effects
  4. 1:37 Wah
  5. 2:45 Distortion

And here is a video with me demonstrating the operation (and also explaining several key features completely incorrectly):


Keep reading for a walkthrough of the hardware and software…


Jun 4 2009

Arduino Theremin/Synth Update II

The Hardware, Oh the Hardware. I’ve been making some great progress on shaping the generated tone and getting some more musicality — I’ve programmed a decay function and that’s made a huge difference, depending on the input values I’ve got a pretty good harp simulacrum, and also something that sounds like an early 1980’s analog synth piano, which I <3.  I’ll try to get a demo up of where I’m at with tonality.  Mainly, I’ve been trying to figure out the analog inputs to control the tone sensing, as well as volume, attack, decay, echo, etc.  This is really two separate problems.  For the frequency control, I want to detect distance from 2″-3′ with good precision, stability, and ideally linearity.  For the volume and effects control, I want a 0-5V analog input over about 1-1.5″ of travel, that can be operated with a single finger.  Here’s what I’ve looked at:

  • Capacitance Sensing, which is what’s shown in the demo video from my last post.  One digital output pin on the Arduino charges up a foil plate, and then discharges it.  Another high-impedance input pin detects how long it takes for the plate voltage to cross the threshold from HIGH to LOW, or vice versa.  As you move your hand towards the plate, it increases the capacitance of the system, increasing the charge/discharge time.  My original plan was to use this method, but it wasn’t stable or accurate, and also since my enclosure is a metal box, the capacitance between the enclosure and the plate was much larger than that introduced by my hand, so I scrapped it.
  • Heterodyne Sensing, like a traditional Theremin.  In this getup, you have two RC oscillator circuits.  The capacitor part of one oscillator is connected to an antenna, and as you bring your hand nearer it increases the capacitance of the system, which reduces the oscillation frequency minutely.  Then, you use a NAND gate to heterodyne, or subtract out the matching frequencies of the two oscillators, leaving the mismatch.  From what I’ve gathered, there’s a lot of art involved in building a good Theremin sensor circuit, and in any case it’s not linear.  I played around with this some, but I couldn’t really get it to do what I wanted it to.
  • Light Detection with a Phototransistor. An infrared LED bounces light off your hand, which is detected by a phototransistor of matched spectrum sensitivity.  I tried this, but I couldn’t get much more than a binary sense input a few inches away from the sensor.  Sharp makes a line of infrared rangefinders (the GP2D12, e.g.) that use a linear ccd sensor to do angle detection rather than amplitude sensing, which can apparently detect objects accurately up to 6′ away.  Plus, they’re cheap and they output a simple 0-3V output.  However, I couldn’t source one locally.
  • Ultrasound. After trying and failing with the above, I ponied up $35 for a Parallax Ping.  They output distance as pulse length.  Not cheap, but I can’t argue with the results– It’s accurate, stable, and even linear.  I’m using it for the frequency control, as it can go out to 3′ without breaking a sweat.
  • Light Detection with a CDS Photoresistor. This is what I’m using for the volume and effects sensors, detailed below.

Goddamn Photoresistors: CDS photoresistors are cheap and easily available, but getting them to go through their resistance range smoothly is a real challenge.  Early on, I discovered that if I moved a green LED closer or farther away from the sensor, it gave a much smoother response than if I tried to modulate the ambient light.  So in my first attempt at creating a control, I used the humble toggle bolt.  I mounted it up with the led on top and the photoresistor on the bottom, like so:

toggle-boltlever1lever2lever3

This worked okay in near or complete darkness, but not so much during the day–even ambient skylight is larger than the LED output by a few orders of magnitude.  Which is a pity, because it would have looked cool, with all four levers mounted on the box and the wires coming out of them it had sort of a steampunk prosthetic hand look.  It’s possible that I could have improved it by mounting the photocell on the lever and the LED below, but it had other problems as well– the levers needed some kind of extension on them to keep your fingers from slipping off them, and the whole assembly was kind of fussy.

Next, I tried the hollow expansion bolts, with the LED and photocell mounted inside, like so:

push-buttonpush-button-2push-button-3push-button-4

This works smoothly over a dynamic range of about 700 with the default analogRead() function.  I’m thinking that I can put a tab on top of them to make them look like organ stops, which would be hot.  I’m going to try manually configuring the Arduino ADC for 8-bit mode to try and squeeze a little more speed out of them– five sensors x 100μS + processing time with the default analogRead() function may make the loop too slow, and an 8-bit data format would be more convenient for processing anyway.  The mechanism is going to be good for set-and-hold controls, but for the volume control I wanted something a little more dynamic, so prototype #3:

dome-sensor-1dome-sensor-2

The ping pong ball does a excellent job of diffusing the ambient light so that the response is smooth.

I’ve made a number of unneccesary holes in the enclosure, and also scratched it up some.  I’m not happy about that, and the lesson here is when you do a project that’s this complex, do a prototype.  But I’m kind of enjoying working fast and sloppy, too.


May 29 2009

Generate Real-time Audio on the Arduino using Pulse Code Modulation

TEK-434 1973-2009 RIP :(

TEK-434 1973-2009 RIP :(

So. There are a bewildering variety of options for generating sound via the Arduino, but I’m trying to make a real-time synthesizer, with the following features:

  • Arbitrary waveform shape, including the ability to add harmonics for a more musical sound
  • Generate any frequency dependent on sensor input
  • Efficient processor usage to allow for effects such as reverb, echo, envelope shaping, etc.
  • A minimum of external hardware

Audio output for the Arduino is pretty well-tilled soil, but surprisingly most of the previously published options are geared towards canned sound playback, or tone generation without a focus on musicality.  I’ve implemented an algorithm called Pulse Code Modulation, and I think it has a lot of potential.  Keep reading for an explanation of how it works and why it’s awesome.

Continue to page 2…


May 26 2009

Arduino Theremin/Synthesizer Update

Banana bread and chips were vital to the DAC processing

Banana bread and chips were vital to the DAC processing

An Update: I’ve made considerable progress in improving the quality of the audio output.  In the prior post, I was generating a square wave with the pulse frequency determined by an input from a capacitive sensor.  It sounded, to put it succinctly, awful.  Since I was generating it through the main loop() code, it was also susceptible to processor load problems, i.e. when an analogRead() was done, it would stop the waveform generation and start it again for ~100mS.  I’m now using interrupt-driven Pulse Code Modulation to generate an arbitrary waveform, and it sounds surprisingly decent, actually.

It’s Like This, Y’all: Since with this setup I can generate an arbitrary waveform, I first spent some time investigating what makes a tone sound musical, or not.  I started by taking a recorded piano key and doing a frequency spectrum analysis of it in Audacity.  Here’s what that looks like:

piano-waveform

The waveform of a middle C (261.626Hz) piano key

And the accompanying spectrum analysis:

piano-spectrum

You can see that the strongest tone is at the fundamental frequency of middle C, 261Hz.  But there are also spikes at the harmonics of that frequency, e.g. 523Hz, 784Hz, 1046Hz.  Interestingly enough, the strongest harmonics are those corresponding to powers of 2, i.e. f * 2n.  I’ve read that even-numbered harmonics are more pleasant-sounding than odd-numbered harmonics, and this would seem to support that idea.  Also, as you add in the odd-numbered harmonics, the waveform approaches a triangle wave, which is definitely less pleasant to listen to than a sine wave.

Thus Informed, I started working to create a waveform of my own.  I set up a frequency and a bunch of multiples of it in Audacity, and played around with increasing or decreasing the amplitude of specific overtones, until I had a sound I was happy with, like so:

middle-c-tone

On the left, you can see that I've varied the amplitude of the various overtones

From this I discovered that the undertone (1/2 * f) and other partials make a huge difference in the quality of the tone.  I wanted to post this file up so other people can play around with it, but apparently with the associated sample files it’s around 50Mb, so you’ll have to recreate it yourself.  I highly recommend it, it’s interesting.  For comparison, here is a recording of a piano, middle c tone:

grand-piano-fazioli-major-c-middle1

And here’s my generated tone:

middle-c-generated-rev1

The generated version sounds different because there’s no envelope shaping on it– it’s just a constant amplitude.  However, I if you listen to both a few times the tone is somewhat similar.

Next, I started working at digitizing a single waveform.  I couldn’t figure out an easy way to do this directly from my generated tone, so instead I built the values in Excel:


handcrafted!

handcrafted!

I then copied the summed values (column N) into a 48 element char array in my Arduino sketch.  If you want this spreadsheet, here ya go.  Finally, here’s another Unintended Comedy Amateur Hour video of me playing around with the generated sound in the Arduino:

I’m going to talk a little more about the specific programming techniques I used to make the Arduino do this in a separate post.


May 20 2009

Arduino audio output from a capacitive input

2009-05-20-210118

Lookee Lookee What I Did Today: So my sister is currently pursuing a PHD in music (theory) at the University of Chicago, and for her birthday, I thought I’d make her a sort-of theremin instrument.  Her birthday was three months ago, but whatever, right?  Today, I started playing around with how that would work using an Arduino.  In lieu of 1,000 words, here’s a YouTube video showing the setup (and also saying um a lot.  Web 3.0!):

And demonstrating the operation:

Right now I’m investigating capacitance for the input, but I may go for the authentic heterodyne sensing, if I can get it done in time (I’m visiting her in three weeks).

I based the sensor code off Paul Badger’s example here.  He documents it pretty well, and this is just a starting point anyway, so I’m not going to put up a schematic or example code right now.



May 12 2009

Rev12 of the Arduino DMX Reception Software Released

p1000328

New in this Version:

  • In-the-field addressing via two tact switches (works with the previously released I/O Shield, here).
  • Address is stored in non-volatile EEPROM, so it is retained when power is lost to the Arduino.
  • Addressing hardware allows full use of the pins (which is why I didn’t use the more conventional dip switch setup).
  • Some of the variables were localized, since the sketch is now getting pretty complex.

The latest software can be downloaded here, you may also want to check out the release notes here.

How to Set the Address:

I’m going to assume you’ve built yourself a DMX I/O shield, if not, you can take a gander at the schematic and set it up on breadboard.

There are two tact switches on the shield, a ‘1′ switch and a ‘0′ switch.

If you press and hold both switches, then hit the reset button, the starting DMX address will be reset to dimmer 1.  The pin 13 LED (marked as ‘ERR’ on the shield) will flash a few times in confirmation.

For other addresses, you’ll hold down either the 1 or 0 switch (but not both), then hit the reset switch.  The pin 13 LED will light up and stay on.  Then you’ll enter your desired address in binary, least significant digit first, by alternately hitting the 0 and 1 switch.  As you enter each bit, the LED will turn off for a moment to confirm that bit was set.  When all 9 bits are received, the ERR LED will flash a few times.  If you make a mistake, just start over by holding down one of the switches and hitting reset.

An Example: let’s say we want a starting address of 246.  246 in binary is 011110110.  You can get this number in couple of ways.

  • Mathematically,
    246 = 0*256+1*128+1*64+1*32+1*16+0*8+1*4+1*2+0*1
      =  29 + 28+27+26+25+24+23+22+21+20 = 011110110
    (Depending on how well you know your powers of 2, the above will be obvious or complete gibberish)
  • In Windows, by firing up the calculator, going to View>Scientific, entering “246″, and hitting the “BIN” radio button
  • In Google, by entering “246 in binary” in the search box
  • By looking it up in your familiar DMX dip switch chart, like this one here.

So thus far, the same process as addressing any other piece of equipment.  Now, hold down the 1 or the 0 switch, and hit reset.  The ERR LED will come on, signifying that we’re in addressing mode.

Now enter the above binary sequence, starting with the smallest number: hit the 0 switch, then the 1 switch, then 1, 0, 1, 1, 1, 1, 0.  The LED will briefly turn off every time you hit a switch.

After all 9 bits are entered, the LED will flash several times.  The board is now addressed to 246.

Another Example: Channel 131.  Hold down the 0 or 1 switch, hit reset, enter 1, 1, 0, 0, 0, 0, 0, 1, 0.

Note: Once the address is set, the pins 11 and 12 may be re-assigned for any other use.  That’s why I did it this way, rather than using a conventional dip switch, which would have taken up 9 pins on the board (I’d be lying if I said I wasn’t a little impressed by my own cleverness here).  The pins are configured with internal pull-ups in setup() as:

digitalWrite(pin0, HIGH);       //turns on the internal pull-up resistor for pin 11
pinMode(pin0, INPUT);           //sets pin 11 to input
digitalWrite(pin1, HIGH);       //turns on the internal pull-up resistor for pin 12
pinMode(pin1, INPUT);           //sets pin 11 to input

Pressing the switches grounds them, setting the pin to LOW.  So, exercise caution when using the pins for anything that doesn’t like to be grounded, is the only caveat.

Known Bug: for some reason, sometimes when you hit the 0 or 1 switch it doesn’t take.  I’ve programmed the LED to turn off briefly if the bit was successfully entered, so if you don’t see it go off, you’ll have to hit the switch again until it takes.  I don’t know why it’s doing this, if you have some time to wade through the logic let me know why and I’ll update the code.

The Astute Reader Will Wonder: why we don’t enter 000000000 for the first address.  True, DMX addresses actually run from 0 to 511, so dimmer 1 is actually listening to dmx address 0.  I’ve seen gear that takes this into account and automatically adds 1 to your desired address, and gear that you subtract 1 from your desired address.  Since there doesn’t seem to be any standard, I’ve opted to let the software do it for you because it’s easier.


Apr 29 2009

Arduino DMX-512 I/O Shield

p1000325

Breadboard is Great and All, But it’s not going to survive a six week run with actors tripping over it and that kid’s show that runs on Sunday mornings.  So here’s a shield that can fit onto your Arduino and securely hold all your connections in place.  It is tested and working with the dmx reception software I wrote for the Arduino.

Features:

  • Same hardware be used to receive or send DMX, so you only have to build one shield.
  • Onboard termination switch.
  • Reset switch brought to top of shield for easy access.
  • Pin 13 LED brought to shield for status/error messages.
  • Two tact switches allow in-the-field addressing, without permanently disabling any pins.
  • Header sockets for easy prototyping.
  • Solder through-holes for permanent installations.

Note: I changed the pin assignments slightly from early versions of the software to allow easier routing.  Pins 3 and 4 in the software are now pins 2 and 3, respectively.  As of Rev11 this change has been made, get the latest version here.

Continue reading for the parts and instructions…


Apr 1 2009

Rev10 of the Arduino DMX Receiver Code Released

New in this Release:

  • Cleaned up and improved code commenting.
  • Adjusted HardwareSerial.cpp (included) so the code will compile on Arduino software release 0015. If you’re still using 0014 or 0013, you’ll replace wiring_serial.c instead (also included).
  • Replaced manual register configuration of the USART with the Arduino function Serial.Begin(250000), which apparently works just as well and reduces the number of Atmega168-specific register calls considerably.
  • Moved the action() loop (what you want the Arduino to do with the received values) to its own tab, to make the code easier to use.

I’ve updated the instructions, or you can download the updated code directly here.

As always, let me know how works for you, or doesn’t.


Mar 20 2009

Receive DMX-512 with an Arduino

arduino

Shiny and new out of the box!

Prologue: For Christmas, I received an Arduino.  If you’re not familiar with them, they’re like a little computer with a lot of pins to which you can connect outputs like LEDs, servos, relays, triacs, or anything you’d want to control, as well as photosensors, switches, anything you’d want to take an input from.  You write your program in the easy-to-learn Arduino environment, upload it to the Arduino board, and it’ll run your program automagically.  I’m not a programmer, but less than an hour after taking it out of the box I had it blinking an LED for me.  Buy one, they’re perfect for all of us who are trying to create some Theater Magic with no money or hope of getting any.

Well, Almost Perfect.  There’s been a way to send DMX with an Arduino for awhile, but when I started poking around for DMX reception code, I came up with zilch.  If you’re already savvy with microcontrollers and assembly code and avrdude and whatever-the-fuck-else, you probably know about this solution.  Me, I look at assembly code and I just hear a dull screaming in my head, nevermind all that other stuff that I don’t know how to do either.

So I figured that a great first project would be to remedy this situation, and write a program to receive DMX on the Arduino platform.  In the way of all Works in this Vale of Tears, this ended up being much more difficult and taking much longer than I initially anticipated.  But eventually I figured it all out, and so here it is!

Features:

  • In-the-field addressing from 1 to 512 via two tact switches (works with the previously released I/O Shield, here).
  • Address is stored in non-volatile EEPROM, so it is retained when power is lost to the Arduino.
  • Addressing hardware allows full use of the pins.
  • Number of addresses to receive is configurable.
  • Works with controllers that send less than the full 512 address set.
  • Break detection is done correctly by detecting a Low value of >88μS per ANSI E1.11-2008, rather than the frame error hack used by many devices.
  • Uses interrupt-based subroutines to eliminate processor-load related timing problems.
  • If the DMX data signal is lost, the Arduino will maintain the current state until new values are received.
  • The reception and user code run sequentially rather than at the same time, so they won’t interfere with each others’ timing.

Continue to Page 2 for Download and Instructions…