I wonder if anyone could help me with code written for one controller and adapt it for two?
The original code takes midi input and rotates one servo to a set position for each midi note received whilst a second servo with a beater attached plays a note on a glockenspiel. Everything runs fine with this setup but I wish to employ a second set of servos to share the load so to speak. Left servo will handle 5 notes and so will the right servo.
This is the original code below for a single set of servos.
// include MIDI library
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// include libraries for controlling servos and debouncing buttons
#include <Servo.h>
#include <Bounce2.h>
// declare objects to represent the two servos
Servo bigServo;
Servo littleServo;
// declare object to represent the button
Bounce button = Bounce();
// set global variables
int notePositions[] = {109,104,99,94,89,85,79,75};
int beaterRestAngle = 100;
int beaterHitAngle = 117;
int postHitDelay = 50;
int ledPin = 2;
void setup() {
bigServo.attach(8);
littleServo.attach(9);
bigServo.write(90);
littleServo.write(beaterRestAngle);
pinMode(ledPin, OUTPUT);
MIDI.setHandleNoteOn(moveToMidiNote);
MIDI.setHandleNoteOff(hitBeater);
MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop() {
MIDI.read();
}
int moveToMidiNote(byte channel, byte midiNote, byte velocity) {
int noteNum = getGlockNoteFromMidiNote(midiNote);
if(noteNum >= 0) {
digitalWrite(ledPin, HIGH);
bigServo.write(notePositions[noteNum]);
} else {
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
int hitBeater(byte channel, byte midiNote, byte velocity) {
int noteNum = getGlockNoteFromMidiNote(midiNote);
if(noteNum >= 0) {
digitalWrite(ledPin, LOW);
littleServo.write(beaterHitAngle);
delay(postHitDelay);
littleServo.write(beaterRestAngle);
} else {
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
delay(50);
}
}
int getGlockNoteFromMidiNote(int midiNote) {
switch(midiNote) {
case 60:
return 0;
case 62:
return 1;
case 64:
return 2;
case 65:
return 3;
case 67:
return 4;
case 69:
return 5;
case 71:
return 6;
case 72:
return 7;
}
return -1;
}
And below is my attempt to double up the code for two sets of servos. However, only four notes from the right servo function and they don't correspond to the correct keys. Can anyone point me in the right direction? Possibly I need to use a different method altogether?
Thanks in advance!
// include MIDI library
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// include libraries for controlling servos and debouncing buttons
#include <Servo.h>
// declare objects to represent the two servos
Servo bigServoLeft;
Servo littleServoLeft;
Servo bigServoRight;
Servo littleServoRight;
// declare object to represent the button
// set global variables for left servo
int notePositionsLeft[] = {60, 75, 90, 105, 120};
int beaterRestAngleLeft = 126; // (68)
int beaterHitAngleLeft = 115; // (85) 117
int postHitDelayLeft = 50; // (100) 50
// set global variables for right servo
int notePositionsRight[] = {85, 100, 116, 134, 150};
int beaterRestAngleRight = 66; // (68)
int beaterHitAngleRight = 76; // (85) 117
int postHitDelayRight = 100; // (100) 50
void setup() {
// left servo
bigServoLeft.attach(8);
littleServoLeft.attach(9);
bigServoLeft.write(120);
littleServoLeft.write(beaterRestAngleLeft);
// right servo
bigServoRight.attach(10);
littleServoRight.attach(11);
bigServoRight.write(100);
littleServoRight.write(beaterRestAngleRight);
// left servo
MIDI.setHandleNoteOn(moveToMidiNoteLeft);
MIDI.setHandleNoteOff(hitBeaterLeft);
// right servo
MIDI.setHandleNoteOn(moveToMidiNoteRight);
MIDI.setHandleNoteOff(hitBeaterRight);
MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop() {
MIDI.read();
}
int moveToMidiNoteLeft(byte channel, byte midiNoteLeft, byte velocity) {
int noteNumLeft = getGlockNoteFromMidiNoteLeft(midiNoteLeft);
if (noteNumLeft >= 0) {
bigServoLeft.write(notePositionsLeft[noteNumLeft]);
} else {
}
}
int hitBeaterLeft(byte channel, byte midiNoteLeft, byte velocity) {
int noteNumLeft = getGlockNoteFromMidiNoteLeft(midiNoteLeft);
if (noteNumLeft >= 0) {
littleServoLeft.write(beaterHitAngleLeft);
delay(postHitDelayLeft);
littleServoLeft.write(beaterRestAngleLeft);
} else {
}
}
int moveToMidiNoteRight(byte channel, byte midiNoteRight, byte velocity) {
int noteNumRight = getGlockNoteFromMidiNoteRight(midiNoteRight);
if (noteNumRight >= 0) {
bigServoRight.write(notePositionsRight[noteNumRight]);
} else {
}
}
int hitBeaterRight(byte channel, byte midiNoteRight, byte velocity) {
int noteNumRight = getGlockNoteFromMidiNoteRight(midiNoteRight);
if (noteNumRight >= 0) {
littleServoRight.write(beaterHitAngleRight);
delay(postHitDelayRight);
littleServoRight.write(beaterRestAngleRight);
} else {
}
}
// left servo
int getGlockNoteFromMidiNoteLeft(int midiNoteLeft) {
switch (midiNoteLeft) {
case 60:
return 0;
case 62:
return 1;
case 64:
return 2;
case 65:
return 3;
case 67:
return 4;
}
return -1;
}
// right servo
int getGlockNoteFromMidiNoteRight(int midiNoteRight) {
switch (midiNoteRight) {
case 69:
return 0;
case 71:
return 1;
case 73:
return 2;
case 75:
return 3;
case 77:
return 4;
}
return -1;
}