Hello!
I'm trying to get midi input from DAW or Pure Data to control a stepper motor location using a Teensy 4.0.
I'm just a hacker with this kind of thing, trying to make code from a couple of different examples work together at the moment. I probably don't understand something simple.
Currently, my sketch will take midi control messages from the computer and print them to the serial bus and sometimes the stepper motor will move into position but more often it will not. My guess is that I'm not updating the passed variable correctly...
Any advice here would be much appreciated!
This is the code I'm working with now:
/* Receive Incoming USB MIDI by reading data. This approach
gives you access to incoming MIDI message data, but requires
more work to use that data. For the simpler function-based
approach, see InputFunctionsBasic and InputFunctionsComplete.
Use the Arduino Serial Monitor to view the messages
as Teensy receives them by USB MIDI
You must select MIDI from the "Tools > USB Type" menu
This example code is in the public domain.
*/
/* /////////////////////////////////////////////////////////////////////////////////////// */
/* Motor Homing code using AccelStepper and the Serial Monitor
Created by Yvan / https://Brainy-Bits.com
This code is in the public domain...
You can: copy it, use it, modify it, share it or just plain ignore it!
Thx!
*/
/* /////////////////////////////////////////////////////////////////////////////////////// */
#include "AccelStepper.h"
// Library created by Mike McCauley at http://www.airspayce.com/mikem/arduino/AccelStepper/
// AccelStepper Setup
AccelStepper stepperX(1, 3, 2); // 1 = Easy Driver interface
// NANO Pin 2 connected to STEP pin of Easy Driver
// NANO Pin 3 connected to DIR pin of Easy Driver
// Define the Pins used
#define home_switch 9 // Pin 9 connected to Home Switch (MicroSwitch)
// Stepper Travel Variables
long TravelX; // Used to store the X value entered in the Serial Monitor
int move_finished=1; // Used to check if move is completed
long initial_homing=-1; // Used to Home Stepper at startup
//MIDI input variable
int MIDIin=0;
/* /////////////////////////////////////////////////////////////////////////////////////// */
void setup() {
Serial.begin(115200);
pinMode(home_switch, INPUT_PULLUP);
delay(5); // Wait for EasyDriver wake up
// Set Max Speed and Acceleration of each Steppers at startup for homing
stepperX.setMaxSpeed(100.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(100.0); // Set Acceleration of Stepper
// Start Homing procedure of Stepper Motor at startup
Serial.print("Stepper is Homing . . . . . . . . . . . ");
while (digitalRead(home_switch)) { // Make the Stepper move CCW until the switch is activated
stepperX.moveTo(initial_homing); // Set the position to move to
initial_homing--; // Decrease by 1 for next move if needed
stepperX.run(); // Start moving the stepper
delay(5);
}
stepperX.setCurrentPosition(0); // Set the current position as zero for now
stepperX.setMaxSpeed(100.0); // Set Max Speed of Stepper (Slower to get better accuracy)
stepperX.setAcceleration(100.0); // Set Acceleration of Stepper
initial_homing=1;
while (!digitalRead(home_switch)) { // Make the Stepper move CW until the switch is deactivated
stepperX.moveTo(initial_homing);
stepperX.run();
initial_homing++;
delay(5);
}
stepperX.setCurrentPosition(0);
Serial.println("Homing Completed");
Serial.println("");
stepperX.setMaxSpeed(1000.0); // Set Max Speed of Stepper (Faster for regular movements)
stepperX.setAcceleration(1000.0); // Set Acceleration of Stepper
// Print out Instructions on the Serial Monitor at Start
Serial.println("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): ");
}
void loop() {
// usbMIDI.read() needs to be called rapidly from loop(). When
// each MIDI messages arrives, it return true. The message must
// be fully processed before usbMIDI.read() is called again.
if (usbMIDI.read()) {
processMIDI();
}
/* midi version??? VVVVVVVVV */
while (usbMIDI.read()>0) { // Check if values are available in the MIDI Buffer?
move_finished=0; // Set variable for checking move of the Stepper
//TravelX= MIDIin; // Put numeric value from buffer in TravelX variable
if (TravelX < 0 || TravelX > 1350) { // Make sure the position entered is not beyond the HOME or MAX position
Serial.println("");
Serial.println("Please enter a value greater than zero and smaller or equal to 1350.....");
Serial.println("");
} else {
Serial.print("Moving stepper into position: ");
Serial.println(TravelX);
stepperX.moveTo(TravelX); // Set new moveto position of Stepper
delay(100); // Wait 1 seconds before moving the Stepper
}
}
if (TravelX >= 0 && TravelX <= 1350) {
// Check if the Stepper has reached desired position
if ((stepperX.distanceToGo() != 0)) {
stepperX.run(); // Move Stepper into position
}
// If move is completed display message on Serial Monitor
if ((move_finished == 0) && (stepperX.distanceToGo() == 0)) {
Serial.println("COMPLETED!");
Serial.println("");
Serial.println("Enter Travel distance (Positive for CW / Negative for CCW and Zero for back to Home): ");
move_finished=1; // Reset move variable
}
}
}
void processMIDI(void) {
byte type, channel, data1, data2, cable;
// fetch the MIDI message, defined by these 5 numbers (except SysEX)
//
type = usbMIDI.getType(); // which MIDI message, 128-255
channel = usbMIDI.getChannel(); // which MIDI channel, 1-16
data1 = usbMIDI.getData1(); // first data byte of message, 0-127
data2 = usbMIDI.getData2(); // second data byte of message, 0-127
cable = usbMIDI.getCable(); // which virtual cable with MIDIx8, 0-7
// uncomment if using multiple virtual cables
//Serial.print("cable ");
//Serial.print(cable, DEC);
//Serial.print(": ");
// print info about the message
//
switch (type) {
case usbMIDI.ControlChange: // 0xB0
Serial.print("Control Change, ch=");
Serial.print(channel, DEC);
Serial.print(", control=");
Serial.print(data1, DEC);
Serial.print(", value=");
Serial.println(data2, DEC);
break;
default:
Serial.println("Opps, an unknown MIDI message type!");
}
TravelX = data2;
}
void printBytes(const byte *data, unsigned int size) {
while (size > 0) {
byte b = *data++;
if (b < 16) Serial.print('0');
Serial.print(b, HEX);
if (size > 1) Serial.print(' ');
size = size - 1;
}
}