2×15 loudpeakers midi controller

2 rows of 15 small loudspeakers via relays controlled by MIDI devised by Boštjan Leskovšek

 

Two rows of loudspeakers (1 each meter) were mounted on wooden  lengths – on two opposite walls. So: 15 meter long lines.

15 pins on arduino UNO were used with  transistor switches to open one of 15 relays.  15 relays’ outputs were connected to power amplifier output – to switch the amplifier  to the selected loudspeaker (we decided to switch on only one loudspeaker at any moment – to not to overload the amplifier). This is parallel connection of  loudspeakers.

MIDI control:

– define a MIDI channel to distinguish between the various controllers on MIDI cable

– 15 notes  (0 to 14) define each loudspeaker. Any note velocity value above zero switches the relay on

– notes 15, 16, 17 define the three functions: single step forward, single step backward, single step forward-backward (palindrome). Velocity received with these notes is the measure of speed of progression. This is not in the code below.

Boštjan Čadež provided this arduino program (SpeakerRelayMidi.txt):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
include arduino MIDI library found here http://arduinomidilib.fortyseveneffects.com/a00025.html
*/
#include "Structs.h"
#include "MIDI.h"
#include "midi_Defs.h"
#include "midi_Message.h"
#include "midi_Namespace.h"
#include "midi_Settings.h"
 
//#define DEBUG
 
#define MIN_SPEED 100
#define MAX_SPEED 10000
#define MIDI_CHANNEL 4
 
#define PINS 15
int pinArray[] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 14, 15, 16};
 
int timer = 100;
int currentSpeaker=0;
boolean goingBack=false;
 
Timer change;
unsigned long currentTime;
 
MIDI_CREATE_DEFAULT_INSTANCE();
 
void startTimer(Timer* timer,long interval,boolean repeat,void (*callbackFunction)());
 
void handleNoteOn(byte inChannel, byte inNote, byte inVelocity)
{
  if(inNote0)stepDown();
     else 
     {
       goingBack=false;
       stepUp();
     }
   }
}
 
void rnd()
{
   int nextSpeaker=random(PINS);
    digitalWrite(pinArray[currentSpeaker], LOW);
    digitalWrite(pinArray[nextSpeaker], HIGH);
    currentSpeaker=nextSpeaker;
}
 
void startTimer(Timer* timer,long interval,boolean repeat,void (*callbackFunction)())
{
  // Serial.println("timer started");
  timer->startTime=currentTime;
  timer->interval=interval;
  timer->repeat=repeat;
  timer->callbackFunction=*callbackFunction;
  timer->running=true;
}
 
void checkTimer(Timer* timer)
{
 
  //Serial.println("timer check");
  if(timer->running && (currentTime - timer->startTime > timer->interval))
  {
    timer->callbackFunction();
    //Serial.println("timer step");
 
    if(timer->repeat)
    {
      //resetTimer
      timer->startTime=currentTime;
      // Serial.println("timer reset");
    }
    else
    {
      //stopTimer
      timer->running=false;
    }
  }
}
 
void stopTimer(Timer* timer)
{
  timer->running=false;
}