Rhythmic lighting for musical performance

Hi all,

I’m trying to see if I can create a lighting display for a musical composition using Arduino. I’m very inexperienced with Arduino so please excuse my ignorance—the performance is coming up soon so I thought I’d ask here!

There are four performers on stage. The idea is to have them play their parts in the dark and use four small lights (strobe lights or LED lights, etc.) to “light them up” every time they play a note. All the notes in the piece are short attacks, so it would be a matter of “blinking” on and off according to the rhythms in the musical score. They will be synchronized to the beat with a click track, which is already needed for video and audio cues.

I know that turning a light on and off is very easy to do in Arduino, but my question is how I can map MIDI data (note-on, note-off) for four instrumental parts to four separate lights on stage, large enough to light up a person.

Another question is how I can connect it over a long distance? I will need the laptop by me in the audience, some distance from the stage. My composition teacher suggested using Bluetooth to send the control data, but I’m not sure how that will work with my project.

Do you have any ideas for how to get started? (Which Arduino parts will I need, and how might I implement the code?) Again, apologies if this is a simple question—if I decide to add lighting as an element to my piece, I’ll need to get started soon and looking for any advice to dive in.

Thanks!
J

How will your Arduino receive the midi data stream? Do you know what to look for in that data stream?

1 Like

Not Blue Tooth, maybe ESP-NOW.

1 Like

I know a little about MIDI but not much... My quick search found some Arduino MIDI controllers but you want to make a MIDI "instrument", which in your case will actually be a light. You may have to dig a bit to find some examples.

It's all MIDI? Usually if there are live performers (keyboard players?) each performer would have their own MIDI setup...

That's always a bad thing when you're inventing something new. :frowning:

DMX is the theatrical lighting standard and although they aren't directly compatible they are "similar" and there are off-the-shelf MIDI to DMX solutions.

I found something about the MIDI hardware interface spec here. It says the maximum recommended cable length is 50-feet. There is also USB MIDI but USB connections are usually shorter than that.

The MIDI message includes the instrument ID so 4 instruments from a single MIDI file wouldn't be a problem.

Or built 4 devices. Or 5 so you'll have a spare...

Why not backstage? Or is it with the lighting director?

That's added complexity and you're got time constraints. Save that for version 2.0. :stuck_out_tongue:

I'd say this is an "intermediate" Arduino project. It would be OK for a beginner if you've got lots of time.

2 Likes

I'm sorry that no-one has been honest with you so far. But someone needs to, so I'll play the 'bad cop' this time.

You are taking about a very complex project which would involve learning many different techniques and technologies, and experimenting and testing to find out which combinations work well, or will enough, for what is needed. And then building the final circuit.

If you were an expert at Arduino, in terms of coding and electronics, had all the tools, components and lots of free time, this project could still take weeks.

As a beginner, we are talking at least months, probably a year, to learn and gain the level of experience needed to attempt something like this.

Sorry to be negative and bring you down with a bump. Your idea is good, but you need to be realistic about what you, as a beginner, can achieve "soon".

Is this performance annual? Maybe next year? This forum will be happy to help you gain experience with simpler projects and discuss and explore all the options for the performance.

3 Likes

I’d agree it’s not a project for the inexperienced and is pretty complex and you would need circuit boards and other hardware. Making up.

You could look at commercially available “ disco” lighting systems .

BTW flashing lights at the performers maybe very distracting and needs warnings to the audience ( there maybe be recommendations for this )

Example BBC code of practice .

“ Control Measures

General Controls

  • Where it is not practical to avoid using strobe lighting, minimise the risk of inducing photosensitive epileptic seizures by:
  • Only competent persons should be allowed to set up and operate stroboscopic lights.
  • Keep the flash rate at/or below 4 flashes per second
  • All staff, crew and freelancers must be warned prior to the use of stroboscopic lights that they are to be included in the programme/event.
  • Staff, crew or freelancers who are concerned about being present during the use of these effects must be allowed to absent themselves from the area whilst they are in use.
  • Where necessary audiences and viewers must be informed, in advance, when there is a risk of flickering light or high contrast image changes precipitating a seizure, see the guidance in Editorial Policy.
  • The floor manager, senior producer or warm up artist must remind the audience before the start of the show.
  • Warnings should be posted at the Studio entrance doors “WARNING: Strobe lights are used during this performance”
  • Where more than one strobe light is used, the flashes must be synchronised.
  • Use bespoke controllers
  • Keep light intensity as low as practical.
  • Maximise distance between lighting source and those present – mount the strobe lights as high above head height as possible.
  • Where possible, the lights should be bounced off walls and ceilings or diffused by other means so that glare is reduced.
  • They should not be used in corridors or on stairs.
  • Continuous operation of strobe lighting for long periods should be avoided.
  • Stepping onto or off of platforms or walking up or down steps and stairs should be kept to an absolute minimum whilst the strobing effect is taking place.”

If you need to cover a long distance you will need a circuit like this:-

Mind you the stage would be covered by wires, so I would go for some sort of wireless interface, Bluetooth is one of them but perhaps would not cover the distance so well.

Here's a better suggestion for "now": Have "spots" trained on the players. You stand at a switchboard and "flip" the switches to "spot" the player. Low tech. Works every time.

You do not have a realistic timeline for a high-tech solution, but... "ESP-NOW" is a DIY wireless network that you can build and power with a few AA batteries. Use one initiator (you) and (as many as you need) responders (the remotes with LEDs to blink).

For the non-wireless tech-solution where everyone sticks to the same music page, here are two projects which allow you to create timing.

The first one is a sequencer that you determine the exact time and when each "note" hits. No remote. Everyone is on the rhythm of the sequence that you have created. Here is the file that you would create, computer start/stop time in milliseconds, the effect to be displayed, and the effect described:

unsigned long interval[] {
  //START (ms)   EFFECT  EVENT START   STOP
       0,   3990,  0, //  0 0:00.00 - 0:04.00 black
    4000,   6900,  1, //  1 0:04.00 - 0:06.90 white
    7000,  10660,  2, //  2 0:07.00 - 0:10.66 rainbow
   10670,  32590,  1, //  3 0:10.67 - 0:32.59 white
   32600,  33020,  3, //  4 0:32.60 - 0:33.02 fade white to black
   33030,  35290,  4, //  5 0:33.03 - 0:35.29 fade black to white
   35300,  40490,  1, //  6 0:35.30 - 0:40.49 white
   40500,  62690,  0, //  7 0:40.50 - 1:02.69 black
   62700,  81460,  5, //  8 1:02.70 - 1:21.46 red (255, 0, 0)
   81470,  88560,  6, //  9 1:21.47 - 1:28.56 blue (0, 0, 255)
   88570, 108340,  1, // 10 1:28.57 - 1:48.34 white
  108350, 109000,  3, // 11 1:48.35 - 1:49.00 fade white to black
  109010, 111000,  4, // 12 1:49.01 - 1:51:00 fade black to white
  111010, 116530,  1, // 13 1:51.01 - 1:56.53 white
  116540, 124030,  6, // 14 1:56.54 - 2:04.03 blue (0,0,255)
  124040, 131260,  7, // 15 2:04.04 - 2:11.26 purple (160,32,240)
  131270, 138960,  8, // 16 2:11.27 - 2:18.96 light blue (143,217,251)
  139970, 145290,  9, // 17 2:19.97 - 2:25.29 orange (255,102,0)
  145300, 149490, 10, // 18 2:25.30 - 2:29.49 pink (255,2,141)
  149500, 153530,  5, // 19 2:29.50 - 2:33.53 red (255,0,0)
  153540, 155260, 11, // 20 2:33.54 - 2:35.26 yellow (255,245,0)
  155270, 157220, 12, // 21 2:35.27 - 2:37.22 green (0,255,0)
  157230, 164360,  4, // 22 2:37.23 - 2:44.36 fade black to white // fade to white from green or black?
  164370, 166160,  0, // 23 2:44.37 - 2:46.16 black
  166170, 184160,  1, // 24 2:46.17 - 3:04.16 white
  184170, 184690,  3, // 25 3:04.17 - 3:04.69 fade white to black
  184700, 186640,  4, // 26 3:04.70 - 3:06.64 fade black to white
  186650, 191940,  3, // 27 3:06:65 - 3:11.94 fade white to black
  191950, 199530,  0, // 28 3:11.95 - 3:19.53 black
  199540, 216030,  6, // 29 3:19.54 - 3:36.03 blue
  216040, 232260,  1, // 30 3:36.04 - 3:52.26 white
  232270, 234160,  8, // 31 3:52.27 - 3:54.16 light blue (143,217,251)
  234170, 235830,  6, // 32 3:54.17 - 3:55.83 blue
  235840, 236410, 14, // 33 3:55.84 - 3:56.41 fade blue to black
  236420, 238190,  4, // 34 3:56.42 - 3:58.19 fade black to white
  238200, 245460,  1, // 35 3:58.20 - 4:05.46 white
  245470, 251530,  2, // 36 4:05.47 - 4:11.53 rainbow
  251540, 253290,  0, // 37 4:11.54 - 4:13.29 black
  253300, 255080, 15, // 38 4:13.30 - 4:15.08 fade red to white // fade to white from red or black?
  255090, 260000,  3, // 39 4:15.09 - 4:20.00 fade white to black
};

This other simulation is a simple "sequencer" which you build a "flash" sequence (vertical) over time (horizontal).

This is an example of a sequence with 10 "LEDs"... you would build your own sequence

const char sequence[] PROGMEM = { // single-dimension array of sequenced elements
  //12345...1.........2.........3.........4.........5.........6.........7.........8.........9.........1  // elements or columns
  "...******...........*.......*..........*...*...*.........*..*.......*...*...*...............*..........******...........*.......*..........*...*...*.........*..*.......*...*...*...............*......." // LED[0]... sequence[0][0..n]
  "...*********.......*.........*.........*...*...*........*....*.....*....*.....*..........*.....*.......*********.......*.........*.........*...*...*........*....*.....*....*.....*..........*.....*...." // LED[1]... sequence[1][0..n]
  "...************...*...........*........*...*...*.......*......*...*.....*.......*.....*...........*....************...*...........*........*...*...*.......*......*...*.....*.......*.....*...........*." // LED[2]... sequence[2][0..n]
  "...******...........*.......*..........*...*...*.........*..*.......*...*...*...............*..........******...........*.......*..........*...*...*.........*..*.......*...*...*...............*......." // LED[3]... sequence[3][0..n]
  "...*********.......*.........*.........*...*...*........*....*.....*....*.....*..........*.....*.......*********.......*.........*.........*...*...*........*....*.....*....*.....*..........*.....*...." // LED[4]... sequence[4][0..n]
  "...************...*...........*........*...*...*.......*......*...*.....*.......*.....*...........*....************...*...........*........*...*...*.......*......*...*.....*.......*.....*...........*." // LED[5]... sequence[5][0..n]
  "...************...*...........*........*...*...*.......*......*...*.....*.......*...........*..........************...*...........*........*...*...*.......*......*...*.....*.......*...........*......." // LED[6]... sequence[6][0..n]
  "...******...........*.......*..........*...*...*.........*..*.......*...*...*............*.....*.......******...........*.......*..........*...*...*.........*..*.......*...*...*............*.....*...." // LED[7]... sequence[7][0..n]
  "...*********.......*.........*.........*...*...*........*....*.....*....*.....*.......*...........*....*********.......*.........*.........*...*...*........*....*.....*....*.....*.......*...........*." // LED[8]... sequence[8][0..n]
  "...************...*...........*........*...*...*.......*......*...*.....*.......*.....*...........*....************...*...........*........*...*...*.......*......*...*.....*.......*.....*...........*." // LED[9]... sequence[9][0..n]
};

... Oh. That's a 1 dimensional PROGMEM character array/string to be accessed by a computed 2d->1d index. Sneaky.

I like it. (but yes, I tried a two-dimension nightmare that beat me up, so 1d, flat was my only choice).

Each row is one LED. Each "*" is ON, "." is "OFF." Each column is read and used before the next column. Timing is controlled by a "speed" variable and "resolution" increases with lengthening the array.

This "V4" allows for pasting multiple arrays together, as long as number of LEDs is the same, allowing for separate sub-sequences.

The fun of the project is the sequencer() function doing the parallel reading and displaying. The rest is filler.

The nightmare of 2D PROGMEM c-strings was my first thought, and then I thought the 1d alternative was a cool workaround.

https://docs.arduino.cc/language-reference/en/variables/utilities/PROGMEM/

1 Like

Hi all,
Thanks for the great ideas, and the code! I will look into it and see what I can do, though I'm leaning towards @xfpd's "low-tech" solution for now.

Best,
J

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.