-
Notifications
You must be signed in to change notification settings - Fork 0
/
leonardo_plucked_string.ino
115 lines (108 loc) · 3.8 KB
/
leonardo_plucked_string.ino
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "MIDIUSB.h"
#include "settings.h"
#include <Servo.h>
// Servo object
Servo myservo;
void setup() {
// Attach Servo to SERVO_PIN
myservo.attach(SERVO_PIN);
// Set STRUMMING_PIN and MUTE_PIN as outputs
pinMode(STRUMMING_PIN, OUTPUT);
pinMode(MUTE_PIN, OUTPUT);
// Set NOTES_PIN as outputs and deactivate them
for (int i = 0; i < sizeof(NOTES)/sizeof(int); i++) {
pinMode(NOTES_PIN[i], OUTPUT);
digitalWrite(NOTES_PIN[i], LOW);
}
// Set initial Servo position to SERVO_CENTER
myservo.write(SERVO_CENTER);
}
bool mute_active=true;
void loop() {
// Check for MIDI messages
if (MidiUSB.available()) {
//***********************************************************************************
// Read the MIDI message
midiEventPacket_t midiEvent = MidiUSB.read();
// CHECK if we'r using only one channel
byte status = midiEvent.header & 0xF0; // Le statut (Note On, Note Off, etc.)
byte channel = midiEvent.header & 0x0F; // Le canal MIDI
byte note = midiEvent.byte1; // La note MIDI
byte velocity = midiEvent.byte2; // La vélocité (pour les messages Note On/Off)
if (MIDI_ON){
// Check if the MIDI channel does not match MIDI_CHANNEL
if (channel != MIDI_CHANNEL) {
// Ignore the MIDI message
return;
}
}
//************************************************************************************
// Check if the message is a Pitch Bend
if (status == MIDI_PITCH_BEND) {
// Map the Pitch Bend value to the Servo position
int pitchBendValue = velocity * 128 + note;
int servoPos = map(pitchBendValue, 0, 16383, SERVO_MIN, SERVO_MAX);
// Set the Servo position
myservo.write(servoPos);
}
//*************************************************************************************
// Check if the message is a Note On
else if (status == MIDI_NOTE_ON) {
// Check if the Note is in the NOTES array
int noteIndex = -1;
for (int i = 0; i < sizeof(NOTES)/sizeof(int); i++) {
if (note == NOTES[i]) {
noteIndex = i;
break;
}
}
// If the Note is in the NOTES array
if (noteIndex >= 0) {
// Activate the Mute if it's not already active
if(mute_active){
digitalWrite(MUTE_PIN, HIGH);
mute_active=false;
}
// Activate the Note pin
digitalWrite(NOTES_PIN[noteIndex], HIGH);
// maybe add some time here to get the time to hit the note before strumming
// set velocity
int pwmValue = map(velocity, 0, 127, MIN_PWM, 255);
// Activate the Strumming magnet for a certain amount of time
analogWrite(STRUMMING_PIN, pwmValue);
delay(TIME_HIT_DEFAULT);
analogWrite(STRUMMING_PIN, 0);
}
}
//********************************************************************************************
// Check if the message is a Note Off
else if (status == MIDI_NOTE_OFF) {
// Check if the Note is in the NOTES array
int noteIndex = -1;
for (int i = 0; i < sizeof(NOTES)/sizeof(int); i++) {
if (note == NOTES[i]) {
noteIndex = i;
break;
}
}
// If the Note is in the NOTES array
if (noteIndex >= 0) {
// Desactivate the Note pin
digitalWrite(NOTES_PIN[noteIndex], LOW);
// Check if all the Note pins are deactivated
bool allNotesOff = true;
for (int i = 0; i < sizeof(NOTES)/sizeof(int); i++) {
if (digitalRead(NOTES_PIN[i]) == HIGH) {
allNotesOff = false;
break;
}
}
// If all the Note pins are desactivated, activate the Mute
if (allNotesOff) {
digitalWrite(MUTE_PIN, LOW);
mute_active=true;
}
}
}
}
}