[Solved!] Problem with MIDI input to PWM Output for dc-motor control

Hello everyone,

I'm working on an Art project and would like to pilot 24v-Motors from Logic Pro X using a Midi-connection via an Arduino Mega 2560 Rev3.
I have got a total of 7 motors that I would like to control individually, moving in both directions.
I have built a MIDI-Input-Circuit for the Arduino, of which I am pretty certain it works correctly. (I set up a test script, which make the builtin LED blink whenever midi is received). The midi-input is connected to the RX0-pin of the arduino.
On the output-Side, I have 4x L298N Dual H-Bridge Motor Drivers, which are connected to a 24v-Power-Supply each. Also, they are connected to the arduino's 5v-power-out and ground, because they need 5v-power to operate. (All jumpers on the Driver are removed, as indicated for 24v-input-use).
The Arduino is connected to the drivers as follows: PWM-Pins 2 to 8 to the corresponding enable-pins (1-7) of the drivers, and Pins 22 - 35 to the direction-control-pins of the drivers.
In Logic, I have a file delivering MIDI-notes, which correspond to the notes A#1 to F#3 (Midi-numbers 34 to 54).
Here's my Code:

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();

int velo;

void setup() {
  pinMode (2, OUTPUT); // PWM Motor 1
  pinMode (22, OUTPUT); // direction motor 1
  pinMode (23, OUTPUT); // direction motor 1
  pinMode (3, OUTPUT); //PWM Motor 2
  pinMode (24, OUTPUT); // direction motor 2
  pinMode (25, OUTPUT); // direction motor 2
  pinMode (4, OUTPUT); // PWM MOtor 3
  pinMode (26, OUTPUT); // direction motor 3
  pinMode (27, OUTPUT); // direction motor 3
  pinMode (5, OUTPUT); // PWM Motor 4
  pinMode (28, OUTPUT); // direction motor 4
  pinMode (29, OUTPUT); //direction motor 4
  pinMode (6, OUTPUT); // PWM Motor 5
  pinMode (30, OUTPUT); // direction motor 5
  pinMode (31, OUTPUT); //direction motor 5
  pinMode (7, OUTPUT); // PWM Motor 6
  pinMode (32, OUTPUT); // direction motor 6
  pinMode (33, OUTPUT); // direction motor 6
  pinMode (8, OUTPUT); // PWM Motor 7
  pinMode (34, OUTPUT); // direction motor 7
  pinMode (35, OUTPUT); // direction motor 7

  MIDI.begin(MIDI_CHANNEL_OMNI);

  MIDI.setHandleNoteOn(MyHandleNoteOn);
  MIDI.setHandleNoteOff(MyHandleNoteOn);
}

void loop() { //
  MIDI.read(); // Read Midi


}


void MyHandleNoteOn(byte channel, byte pitch, byte velocity)
{
  digitalWrite(LED_BUILTIN, HIGH)
  
  velo = map(velocity, 0, 127, 0, 255);

  //MOTOR1
  if (pitch == 34)
    analogWrite(2, velo);
  if (pitch == 35)
    digitalWrite(22, HIGH);
  if (pitch == 36)
    digitalWrite(23, HIGH);
 
  //MOTOR2
  if (pitch == 37)
    analogWrite(3, velo);
  if (pitch == 38)
    digitalWrite(24, HIGH);
 
  if (pitch == 39)
    digitalWrite(25, HIGH);


  //MOTOR3
  if (pitch == 40)
    analogWrite(4, velo);
  if (pitch == 41)
    digitalWrite(26, HIGH);
 
  if (pitch == 42)
    digitalWrite(27, HIGH);
  
  //MOTOR4
  if (pitch == 43)
    analogWrite(5, velo);
  if (pitch == 44)
    digitalWrite(28, HIGH);
  
  if (pitch == 45)
    digitalWrite(29, HIGH);
 

  //MOTOR5
  if (pitch == 46)
    analogWrite(6, velo);
  if (pitch == 47)
    digitalWrite(30, HIGH);

  if (pitch == 48)
    digitalWrite(31, HIGH);

  //MOTOR6
  if (pitch == 49)
    analogWrite(7, velo);
  if (pitch == 50)
    digitalWrite(32, HIGH);

  if (pitch == 51)
    digitalWrite(33, HIGH);


  //MOTOR7
  if (pitch == 52)
    analogWrite(8, velo);
  if (pitch == 53)
    digitalWrite(34, HIGH);

  if (pitch == 54)
    digitalWrite(35, HIGH);



}

void MyHandleNoteOff(byte channel, byte pitch, byte velocity)
{
  
  //MOTOR1
  if (pitch == 34)
    analogWrite(2, LOW);
    
  if (pitch == 35)
    digitalWrite(22, LOW);
  if (pitch == 36)
    digitalWrite(23, LOW);
 
  //MOTOR2
  if (pitch == 37)
    analogWrite(3, LOW);
  if (pitch == 38)
    digitalWrite(24, LOW);
 
  if (pitch == 39)
    digitalWrite(25, LOW);


  //MOTOR3
  if (pitch == 40)
    analogWrite(4, LOW);
  if (pitch == 41)
    digitalWrite(26, LOW);
 
  if (pitch == 42)
    digitalWrite(27, LOW);
  
  //MOTOR4
  if (pitch == 43)
    analogWrite(5, LOW);
  if (pitch == 44)
    digitalWrite(28, LOW);
  
  if (pitch == 45)
    digitalWrite(29, LOW);
 

  //MOTOR5
  if (pitch == 46)
    analogWrite(6, LOW);
  if (pitch == 47)
    digitalWrite(30, LOW);

  if (pitch == 48)
    digitalWrite(31, LOW);

  //MOTOR6
  if (pitch == 49)
    analogWrite(7, LOW);
  if (pitch == 50)
    digitalWrite(32, LOW);

  if (pitch == 51)
    digitalWrite(33, LOW);


  //MOTOR7
  if (pitch == 52)
    analogWrite(8, LOW);
  if (pitch == 53)
    digitalWrite(34, LOW);

  if (pitch == 54)
    digitalWrite(35, LOW);

}

Today I could connect everything for the first time (it is an art installation, setup only finished today..). I tried to make motor 1 move. What happened was, that motor 5 moved in one direction, but didn't stop anymore (until it was physically restrained (from the installation) and burnt one of my drivers), even though the midi-note had stopped playing long time ago.

Any help/ideas/thoughts would be largely appreciated, as usual time is short and the project should be up and running this weekend.
THANKS!
cheers,
jay.

I'm not going to try and analyze your code and I've never used MIDI...

I have built a MIDI-Input-Circuit for the Arduino, of which I am pretty certain it works correctly. (I set up a test script, which make the builtin LED blink whenever midi is received).

So, the next thing to do would be to add some Serial.println() statements and send the decoded MIDI values to the serial monitor to make sure the MIDI message is getting decoded properly. (Look at the Analog Read Serial Example if you don't know how to do that.)

Once you've got the MIDI decoding figured-out, set the MIDI aside and make a little test sketch to run ONE motor (forward, backward, fast, slow, etc.).

Now, stick some of the MIDI variables into the motor control sketch and "hard code" some trial values for velo & pitch (so you can test without actually reading a MIDI messages).

Then, add the actual MIDI decoding to control ONE motor.

Then, add the code for more motors.

**...Don't try to write the whole program at once!**Work on the input & output separately and "develop" your code one or two lines at a time, always test-compiling and test-running every time you make a small change/addition.

So you have to send 3 noteOns to start a motor and then NoteOffs for the same 3 notes to stop it? Seems a bit odd but there's probably some reason I haven't thought of.

  MIDI.setHandleNoteOff(MyHandleNoteOn);

Anyway I imagine this is why your motor doesn't stop when you get a NoteOff.

Steve

Thanks Doug & Steve for your thoughts.

Steve, I need to send one note On for the rotation (mapping the velocity for speed), and either one or the other note on for the rotating direction.
I’ll correct that code error and retest asap, otherwise I think it’s a good idea to go through the whole set step by step.

One other thought I had: Does anyone know if my Pitch-Byte selection (pitch == 34) needs to be in HEX to be properly read?
So ‘22’ instead if 34 and so on? might this have caused the wrong motor to move?

Thanks,
Jay.

slipstick:

  MIDI.setHandleNoteOff(MyHandleNoteOn);

Anyway I imagine this is why your motor doesn't stop when you get a NoteOff.

Steve

Thanks Steve, that did the trick! Now everything is up and running! Lovely!
If anyone needs further information on this project, like wiring plans etc, please give me a shout, I'll be happy to help!
cheers,
Jay.