Main Loop Function advice - Receiving MIDI/Blocking Code

Hey there

I have written some code for an Arduino Mega 2560 that controls a Stepper Motor (NEMA23) and a Servo (SG90) with MIDI messages. See below.

The code works as it should in part. The stepper motor starts and when MIDI messages are received the stepper and servo are controlled. I would like some advice on the loop function and how to implement the following:

  1. Loop function doesn't start until the 1st MIDI message is received

(channel == 1 && pitch == 62) //D3 MIDI Channel 1

I've tried a while loop at the end of the setup

'while(MIDI.Read()==0){}'

but the code still jumps into loop.

  1. When the MIDI message (channel==1&&pitch==65) //F3 MIDI Channel 1 is received I'd like the program to jump out of the main loop and return to Setup. I've tried an if statement:

'if (handleNoteOn(byte Channel==1&&pitch==65)){'

but the error "status 1 channel is not declared in this scope" is returned. I'm not sure how to place this within the main Loop.

EDIT 3. is sorted:
*3. The delay() within the statement *

'if (channel==1&&pitch==65) //F3 MIDI Channel 1'

in the handleNoteOn function seems to happen after the servo has moved even though the delay is before, what would be the reason for this?

Thanks in advance for any help and/or advice.

[code]
#include <Servo.h>
#include <AccelStepper.h>
#include <MIDI.h>

//stepper variables
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

long stepsPerRev = 3200; //steps per revolution at 1/16

//Lead In
int leadInSteps = 2 * stepsPerRev;
int leadInMaxSpeed = 1000;
int leadInAcceleration = 500;

//Wind On
float windOnSteps = stepsPerRev / 4; //800 steps
int windOnMaxSpeed = 1000;
int windOnAcceleration = 500;

//SERVO
Servo myServo;
int servoPin = 4;
int pos = 0;
int pos1 = 0;

void moveTo(int position, int speed) {
  int mapSpeed = map (speed, 0, 30, 30, 0);
  if (position > pos) {
    for (pos = pos1; pos <= position; pos += 1) {
      myServo.write(pos);
      pos1 = pos;
      delay(mapSpeed);
    }
  }
  else {
    for (pos = pos1; pos >= position; pos -= 1) {
      myServo.write(pos);
      pos1 = pos;
      delay (mapSpeed);
    }
  }
}

//STEPPER SPEED;
int minSpeed;

//MIDI Function
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI); //using RX1
void handleNoteOn(byte channel, byte pitch, byte velocity)
{
  if (channel == 1 && pitch == 60) //Middle C [C3] MIDI Channel 1 - Wind On
  {
    stepper.setCurrentPosition(0);
    stepper.setMaxSpeed(3000);
    stepper.setAcceleration(3000);
    stepper.moveTo(-windOnSteps);
    stepper.runToPosition();

  }

  else if (channel == 1 && pitch == 62) //D3 MIDI Channel 1 - Servo down & Lead In
  {

    moveTo(90, 15); //servo move
    stepper.setCurrentPosition(0);
    stepper.setMaxSpeed(stepsPerRev);
    stepper.setAcceleration(6400);
    stepper.moveTo(-leadInSteps);
    stepper.runToPosition();
  }

  else if (channel==1&&pitch==65) //F3 MIDI Channel 1 - Lead Out & Servo Up
    {
    stepper.setCurrentPosition(0);
    stepper.setMaxSpeed(2*stepsPerRev);
    stepper.setAcceleration(2000);
    stepper.moveTo(-2*stepsPerRev);
    stepper.runToPosition();
    delay(1000)
    moveTo(-180,15); //servo move
    }

  else {}
}

void setup() {
  // put your setup code here, to run once:

  myServo.attach(servoPin);

  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.turnThruOff();

  minCuttingSpeed = 1000; 

}

void loop() {

  while (MIDI.read() == 0) {

    stepper.setMaxSpeed(1000);
    stepper.setSpeed(-minSpeed);
    stepper.runSpeed();
  }
}

[/code]

I could say something about millis() and blocking code…

but just for now…
What happens if you// comment out the longer delay(1000) ?

I don’t think AccelStepper is blocking, so that’s the most obvious potential for being a problem.

Thanks for your reply.

I've tested again and the delay actually works fine within the function. In my code I had a variable within delay that did not have a value attached to it. I'm really sorry it's been a long day :sweat_smile:

  1. and 2. are still valid

Thanks