To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / CollidoscopeTeensy / CollidoscopeTeensy_new.ino @ 5:75b744078d66

History | View | Annotate | Download (10.2 KB)

1 1:b5bcad8e7803 f
2
/******************************************************************************
3 5:75b744078d66 f
 *  Copyright (C) 2015  Ben Bengler (mail@benbengler.com)
4
 *  Copyright (C) 2016  Queen Mary University of London
5
 *  Authors: Ben Bengler, Fiore Martin
6 1:b5bcad8e7803 f
 *
7 5:75b744078d66 f
 *  This file is part of Collidoscope.
8
 *
9
 *  Collidoscope is free software: you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation, either version 3 of the License, or
12
 *  (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 1:b5bcad8e7803 f
 *
22 5:75b744078d66 f
 ****************************************************************************
23
 *
24 1:b5bcad8e7803 f
 *  Teensy 2 ++ pinout: https://www.pjrc.com/teensy/card4b.pdf
25
 *
26
 *  ANALOG INPUTS:
27
 *  Wavejet   -> F0 (38) [Horizontal rail 1]
28
 *  Wavejet   -> F1 (39) [Horizontal rail 2]
29
 *  Filter 1  -> F2 (40) [Vertical rail 1]
30
 *  Filter 2  -> F4 (42) [Vertical rail 2]
31
 *
32
 *  DIGITAL INPUTS [INTERRUPTS]:
33
 *  Sel. length 1  -> INT0/INT1 (0, 1)  [Encoder 1]
34
 *  Sel. length 2  -> INT2/INT3 (2, 3)  [Encoder 2]
35
 *  Duration 1     -> INT4/INT5 (36, 37)[Encoder 3]
36
 *  Duration 2     -> INT6/INT7 (18, 19)[Encoder 4]
37
 *
38
 *  DIGITAL INPUTS:
39
 *  Play1 toggle  -> B0 (20)
40
 *  Record1       -> B1 (21)
41
 *  Play2 toggle  -> B3 (22)
42
 *  Record2       -> B4 (24)
43
 *
44
 *  DIGITAL OUTPUTS:
45
 *  Record Button 1 Led -> D4 (4)
46
 *  Record Button 2 Led -> D5 (5)
47 5:75b744078d66 f
 *
48 1:b5bcad8e7803 f
 ******************************************************************************/
49
50
51
#include <Encoder.h>
52
#include <Bounce.h>
53
54
///////////////////////////////////////////////////
55
//MIDI settings
56
const int midi_chan_inst1 = 1; // MIDI channel for Instrument 1
57
const int midi_chan_inst2 = 2; // MIDI channel for Instrument 2
58
59
const int cc_length = 1;    // MIDI cc controlling selection length
60
const int cc_duration = 2;  // MIDI cc controlling duration
61
const int cc_filter = 7;    // MIDI cc controlling LP filter
62
const int cc_play = 4;      // MIDI cc controlling PLAY
63
const int cc_record = 5;    // MIDI cc controlling RECORD
64
//const int cc_reset = 100; // MIDI cc controlling instrument RESET
65
66
///////////////////////////////////////////////////
67
//Default Values:
68
const int  Enc_def = 64; //default selection length
69
int MIDI_led_state = LOW;
70
//boolean reset1 = true;
71
//boolean reset2 = true;
72
73
///////////////////////////////////////////////////
74
// Interface Inputs
75
76
//Buttons:
77
78
const int Pin_play1 = 20;       //B0
79
const int Pin_record1 = 21;     //B1
80
const int Pin_play2 = 23;       //B3
81
const int Pin_record2 = 24;     //B4
82
const int Pin_record1_led =  4; //D4
83
const int Pin_record2_led =  5; //D5
84
const int Pin_MIDIled =  6;
85
86
//const int Pin_reset1 = 22;    //B2, not in use
87
//const int Pin_reset2 = 25;    //B5, not in use
88
89
Bounce button1 = Bounce(Pin_play1, 5);
90
Bounce button2 = Bounce(Pin_record1, 5);
91
Bounce button3 = Bounce(Pin_play2, 5);
92
Bounce button4 = Bounce(Pin_record2, 5);
93
94
95
//Encoder
96
Encoder Enc1 (0, 1);  //Encoder for section length on Wavejet 1
97
Encoder Enc2 (2, 3);  //Encoder for section length on Wavejet 2
98
Encoder Enc3 (36, 37);  //Encoder for duration of Wavejet 1 [granularisation effect]
99
Encoder Enc4 (18, 19);  //Encoder for duration of Wavejet 2 [granularisation effect]
100
101
// Variables
102
const int jitter_thresh = 10; //7threshold value for analog INs to suppress sending MIDI due to input jitter
103
const int jitter_thresh_short = 5;
104
105
void setup() {
106
107
pinMode(Pin_play1, INPUT_PULLUP);
108
pinMode(Pin_record1, INPUT_PULLUP);
109
pinMode(Pin_play2, INPUT_PULLUP);
110
pinMode(Pin_record2, INPUT_PULLUP);
111
112
113
pinMode(Pin_MIDIled, OUTPUT);
114
pinMode(Pin_record1_led, OUTPUT);
115
pinMode(Pin_record2_led, OUTPUT);
116
}
117
118
//Store recent values to detect parameter change
119
long Enc1_old = -999;
120
long Enc2_old = -999;
121
long Enc3_old = -999;
122
long Enc4_old = -999;
123
124
uint16_t Jet1_old = 0;
125
int16_t Jet1_old_MIDI = -1;
126
uint16_t Jet2_old = 0;
127
int16_t Jet2_old_MIDI = -1;
128
uint16_t filter1_old = 0;
129
int16_t filter1_old_MIDI = -1;
130
uint16_t filter2_old = 0;
131
int16_t filter2_old_MIDI = -1;
132
133
void loop() {
134
135
  digitalWrite(Pin_MIDIled, LOW);
136
  digitalWrite(Pin_record1_led, HIGH);
137
  digitalWrite(Pin_record2_led, HIGH);
138
  button1.update();
139
  button2.update();
140
  button3.update();
141
  button4.update();
142
143
144
  uint16_t Jet1_new = analogRead(0); //read Wavejet/Rail 1
145
  uint16_t Jet2_new = analogRead(1); //read Wavejet/Rail 2
146
  uint16_t filter1_new = analogRead(2);   //read filter Instrument 1; ADJUST INPUT RANGE ACCORDING TO SENSOR
147
  uint16_t filter2_new = analogRead(4);   //read filter Instrument 2; ADJUST INPUT RANGE ACCORDING TO SENSOR
148
149
150
151
  //Encoder 1 [Controls selection length of wave 1]
152
  long Enc1_new = Enc1.read();
153
  Enc1_new = constrain(Enc1_new, 0, 127); //constrain to 7-bit MIDI range
154
155
  //Dynamic reset of counter to MIDI range
156
  if (Enc1_new <= 0){
157
    Enc1.write(0);
158
  }
159
  else if (Enc1_new >= 127){
160
    Enc1.write(127);
161
  }
162
163
  //Encoder 2 [Controls selection length of wave 2]
164
  long Enc2_new = Enc2.read();
165
  Enc2_new = constrain(Enc2_new, 0, 127); //constrain to 7-bit MIDI range
166
167
  //Dynamic reset of counter to MIDI range
168
  if (Enc2_new <= 0){
169
    Enc2.write(0);
170
  }
171
  else if (Enc2_new >= 127){
172
    Enc2.write(127);
173
  }
174
175
  //Encoder 3 [Controls duration of wave 1]
176
  long Enc3_new = Enc3.read();
177
  Enc3_new = constrain(Enc3_new, 0, 127); //constrain to 7-bit MIDI range
178
179
  //Dynamic reset of counter to MIDI range
180
  if (Enc3_new <= 0){
181
    Enc3.write(0);
182
  }
183
  else if (Enc3_new >= 127){
184
    Enc3.write(127);
185
  }
186
187
  //Encoder 4 [Controls duration of wave 2]
188
  long Enc4_new = Enc4.read();
189
  Enc4_new = constrain(Enc4_new, 0, 127); //constrain to 7-bit MIDI range
190
191
  //Dynamic reset of counter to MIDI range
192
  if (Enc4_new <= 0){
193
    Enc4.write(0);
194
  }
195
  else if (Enc4_new >= 127){
196
    Enc4.write(127);
197
  }
198
199
200
 //Instrument 1 Controls//////////////////////////////////////
201
202
 //Loop/Keymode Switch Instrument 1
203
204
 if (button1.risingEdge()) {
205
   //Serial.println("Loop mode");
206
   usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst1);
207
 }
208
209
 if (button1.fallingEdge()) {
210
   //Serial.println("Keyboardmode mode");
211
   usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst1);
212
 }
213
214
215
 //Record Instrument 1
216
 if (button2.fallingEdge()) {
217
   //Serial.println("RECORD! Instrument 1");
218
   usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst1);
219
 }
220
221
 //send MIDI Wavejet 1 [Position Instrument 1]
222
 if (Jet1_new > Jet1_old+jitter_thresh || Jet1_new < Jet1_old-jitter_thresh) {
223
224
    int16_t midiVal = constrain( map(Jet1_new, 988, 121, 0, 149), 0, 149 );
225
    // int16_t midiVal = constrain( map( Jet1_new, 23, 928, 0, 149 ), 0, 149 ); old collidoscope
226
    if( midiVal != Jet1_old_MIDI ){
227
      Jet1_old_MIDI = midiVal;
228
      usbMIDI.sendPitchBend( midiVal, midi_chan_inst1 );
229
    }
230
231
    Jet1_old = Jet1_new;
232
    digitalWrite(Pin_MIDIled, HIGH);
233
 }
234
235
236
 //send MIDI Filter 1 [Filter Instrument 1]
237
238
 if ( filter1_new > filter1_old+jitter_thresh_short || filter1_new < filter1_old-jitter_thresh_short ) {         // maybe adding jitter threshold needed, see Jet1_new
239
240
    int16_t midiVal = constrain( map(filter1_new, 145, 756, 0, 127), 0, 127 );
241
    if( midiVal != filter1_old_MIDI){
242
      //Serial.println( midiVal );
243
      filter1_old_MIDI = midiVal;
244
      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst1);
245
    }
246
247
    filter1_old = filter1_new;
248
    digitalWrite(Pin_MIDIled, HIGH);
249
  }
250
251
  //send MIDI Encoder 1 [Selection length Instrument 1]
252
  if (Enc1_new != Enc1_old) {
253
    Enc1_old = Enc1_new;
254
    //Serial.println("Encoder 1: ");
255
    //Serial.println(Enc1_new);
256
    usbMIDI.sendControlChange(cc_length, Enc1_new, midi_chan_inst1);
257
    digitalWrite(Pin_MIDIled, HIGH);
258
  }
259
260
  //send MIDI Encoder 3 [Duration Instrument 1]
261
  if (Enc3_new != Enc3_old) {
262
    Enc3_old = Enc3_new;
263
    //Serial.println("Encoder 3: ");
264
    //Serial.println(Enc3_new);
265
    usbMIDI.sendControlChange(cc_duration, Enc3_new, midi_chan_inst1);
266
    digitalWrite(Pin_MIDIled, HIGH);
267
  }
268
269
270
  //Instrument 2 Controls//////////////////////////////////////
271
272
  //Loop/Keymode Switch Instrument 2
273
274
  if (button3.risingEdge()) {
275
    //Serial.println("Loop mode");
276
    usbMIDI.sendControlChange(cc_play, 1, midi_chan_inst2);
277
  }
278
279
  if (button3.fallingEdge()) {
280
    //Serial.println("Keyboardmode mode");
281
    usbMIDI.sendControlChange(cc_play, 0, midi_chan_inst2);
282
  }
283
284
  //Record Instrument 2
285
  if (button4.fallingEdge()) {
286
    //Serial.println("RECORD! Instrument 2");
287
    usbMIDI.sendControlChange(cc_record, 1, midi_chan_inst2);
288
  }
289
290
  //send MIDI Wavejet 2 [Position Instrument 2]
291
292
  if (Jet2_new > Jet2_old+jitter_thresh || Jet2_new < Jet2_old-jitter_thresh) {
293
    //Serial.println("RECORD! Instrument 2");
294
    int16_t midiVal = constrain( map( Jet2_new, 109, 992, 149, 0 ), 0, 149 );
295
    if( midiVal != Jet2_old_MIDI ){
296
      Jet2_old_MIDI = midiVal;
297
      usbMIDI.sendPitchBend( midiVal, midi_chan_inst2 );
298
    }
299
300
    Jet2_old = Jet2_new;
301
    digitalWrite(Pin_MIDIled, HIGH);
302
  }
303
304
 //Serial.println(filter2_new);
305
   if ( filter2_new > filter2_old+jitter_thresh_short || filter2_new < filter2_old-jitter_thresh_short ) {         // maybe adding jitter threshold needed, see Jet1_new
306
    int16_t midiVal = constrain( map(filter2_new, 132, 700, 0, 127), 0, 127 );
307
    if( midiVal != filter2_old_MIDI){
308
      //Serial.println( midiVal );
309
      filter2_old_MIDI = midiVal;
310
      usbMIDI.sendControlChange(cc_filter, midiVal, midi_chan_inst2);
311
    }
312
313
    filter2_old = filter2_new;
314
    digitalWrite(Pin_MIDIled, HIGH);
315
  }
316
317
318
  //send MIDI Encoder 2 [Selection length Instrument 2]
319
  if (Enc2_new != Enc2_old) {
320
    Enc2_old = Enc2_new;
321
    //Serial.println("Encoder 2: ");
322
    //Serial.println(Enc2_new);
323
    usbMIDI.sendControlChange(cc_length, Enc2_new, midi_chan_inst2);
324
    digitalWrite(Pin_MIDIled, HIGH);
325
  }
326
327
  //send MIDI Encoder 4 [Duration Instrument 2]
328
  if (Enc4_new != Enc4_old) {
329
    Enc4_old = Enc4_new;
330
    //Serial.println("Encoder 4: ");
331
    //Serial.println(Enc4_new);
332
    usbMIDI.sendControlChange(cc_duration, Enc4_new, midi_chan_inst2);
333
    digitalWrite(Pin_MIDIled, HIGH);
334
  }
335
336
}