Midi and servo code problem

Hello, I have a piece of code adapted from a single button to control two positions on a single servo.
My intention is to control three servos with incoming midi notes. Each servo is positioned to pluck one guitar string. Each servo responds to an assigned midi note so that each time the same midi note is played that same servo will alternate between two chosen positions. I have three servos in total. My problem is that the servos don't respond to the first note played but they will with each consecutive note assigned to them.
The next problem occurs when changing between servos. When I alternate between midi notes consecutively, none of the servos move. They appear to need the same midi note at least twice before the next servo will operate. I'm sure there's a problem in the loop function but then maybe this code doesn't suit what I'm trying to achieve? Thank you for your help :slight_smile:

#include <MIDI.h>
#include <Servo.h>
boolean toggle = true;

MIDI_CREATE_DEFAULT_INSTANCE();
byte servoPos1 = 120;
byte servoPos2 = 160;
Servo servo1;
Servo servo2;
Servo servo3;

void setup() {
  servo1.attach(8);
  servo2.attach(9);
  servo3.attach(10);

  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.setHandleNoteOn(Note);
  digitalWrite(13, LOW);
  servo1.write(servoPos1);
  servo2.write(servoPos1);
  servo3.write(servoPos1);


}

void loop() {
  MIDI.read();
}

void Note(byte channel, byte note, byte velocity) {

  if (note == 60)
  {
    if (toggle)
    {
      servo1.write(servoPos1);
      toggle = !toggle;
    }
    else
    {
      servo1.write(servoPos2);
      toggle = !toggle;
    }
    {
    }
  }     else if (note == 62)
  {
    if (toggle)
    {
      servo2.write(servoPos1);
      toggle = !toggle;
    }
    else
    {
      servo2.write(servoPos2);
      toggle = !toggle;
    }

  }    else  if (note == 64)
  {
    if (toggle)
    {
      servo3.write(servoPos1);
      toggle = !toggle;
    }
    else
    {
      servo3.write(servoPos2);
      toggle = !toggle;
    }

  }
}

If your MIDI output is connected to the hardware serial pins, you need to get it connected to some other pins, so that you can use Serial to debug your program. You need to know when Note() gets called. You need to know what value is in note when Note() gets called.

You have three servos and one toggle variable. Is that the correct ratio? IMHO, it is not.

Thanks massively PaulS :slight_smile: I created the extra variables and she now works like a charm! Here it is for anyone that may need it :slight_smile:

#include <MIDI.h>
#include <Servo.h>
boolean toggle1 = true;
boolean toggle2 = true;
boolean toggle3 = true;

MIDI_CREATE_DEFAULT_INSTANCE();
byte servoPos1 = 120;
byte servoPos2 = 160;
Servo servo1;
Servo servo2;
Servo servo3;

void setup() {
  servo1.attach(8);
  servo2.attach(9);
  servo3.attach(10);

  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.setHandleNoteOn(Note);
  digitalWrite(13, LOW);
  servo1.write(servoPos1);
  servo2.write(servoPos1);
  servo3.write(servoPos1);


}

void loop() {
  MIDI.read();
}

void Note(byte channel, byte note, byte velocity) {

  if (note == 60)
  {
    if (toggle1)
    {
      servo1.write(servoPos2);
      toggle1 = !toggle1;
    }
    else
    {
      servo1.write(servoPos1);
      toggle1 = !toggle1;
    }
    {
    }
  }     else if (note == 62)
  {
    if (toggle2)
    {
      servo2.write(servoPos2);
      toggle2 = !toggle2;
    }
    else
    {
      servo2.write(servoPos1);
      toggle2 = !toggle2;
    }

  }    else  if (note == 64)
  {
    if (toggle3)
    {
      servo3.write(servoPos2);
      toggle3 = !toggle3;
    }
    else
    {
      servo3.write(servoPos1);
      toggle3 = !toggle3;
    }

  }
}
boolean toggle1 = true;
boolean toggle2 = true;
boolean toggle3 = true;

I see many variables with numeric suffixes. That usually means that using arrays would be more effective and cut down the amount of code.

byte servoPos1 = 120;
byte servoPos2 = 160;

Why no servoPos3 ?

  servo1.write(servoPos1);
  servo2.write(servoPos1);
  servo3.write(servoPos1);

Looks wrong to me. At the very least the variable names are confusing.

An array probably is the best way UKHeliBob. This code though spawned from another piece that actually did start working for me so I ran with it. The reason there is no sevoPos3 is because I'm only using two servo positions to alternate between, upwards and downwards picking on a guitar string.

Also

 servo1.write(servoPos1);
  servo2.write(servoPos1);
  servo3.write(servoPos1);

This is necessary to set the position of the servos at the beginning otherwise they start off uncalibrated

The reason there is no sevoPos3 is because I'm only using two servo positions to alternate between, upwards and downwards picking on a guitar string.

As I said, the variable names are confusing. Why not give them meaningful names ?

Yeah, one of them could be called "pluckYou"

:slight_smile: Ha! and I'll name the other one pluckYou2 :slight_smile: