Unable to get servos to operate on separate MIDI channels at same time

Hi,

I'm running these 6 digital servos from my Arduino Leonardo, using midi cc#7 from my DAW/Logic Pro X 10.4
Description:
High quality robot servo with advanced interior design and precision potentiometers.
Dual-ball Servo which means one is Driving shaft and another is virtual axis (supporting function).
High torque and 270 degree rotation, barely absent and dead zone.
Weight: 60g
Size: 402040.5 mm
Speed:0.16 sec/60°7.4V
Locked-Rotor Torsion:15Kg.cm 6.6V; 17Kg.cm 7.4V
Voltage: 6-7.4V
Unload Current: 100mA

I using 6 volt 6amp ac/dc adapter
I have attached my breadboard schematic
(the black wire goes to the gnd of the Lenardo)

the code does pretty much what I want expect for 1 thing I can't get the servos to operate on different midi channels at the same time, each servo independently from the other each on there own midi channel. if all servos are connected to one midi channel at the same time they all move the same, at the same time but thats not what I want. I can only get one midi channel(or 1 track) in my DAW with cc7 events activated, when engaging other midi channels at the same time with cc7 automation on those channels the servos violently start jerking.
I've only been at this for 2 + months so I know I screwed up the code some where.

Serial Monitor and Midi Monitor app and DAW/Logic Pro X all print out that the the correct event info is being sent from my DAW to the Leonardo for example
Received: B-B0-7-25
Received: B-B0-7-26
Received: B-B0-7-28
Received: B-B0-7-29
Received: B-B0-7-2A
Received: B-B2-7-51
Received: B-B2-7-50
Received: B-B2-7-4F
Received: B-B2-7-4E
Received: B-B2-7-4D
Received: B-B2-7-4B
Received: B-B2-7-4A
Received: B-B2-7-48
Received: B-B2-7-46
Received: B-B2-7-45
Received: B-B2-7-46
Received: B-B3-7-64
Received: B-B3-7-65
Received: B-B3-7-66
Received: B-B3-7-67
Received: B-B3-7-68
Received: B-B3-7-69
Received: B-B3-7-66
Received: B-B3-7-63
Received: B-B3-7-62
Received: B-B3-7-60
Received: B-B3-7-61
Received: B-B3-7-63
Received: B-B3-7-64
Received: B-B3-7-65
Received: B-B3-7-66
Received: B-B3-7-65
Received: B-B4-7-64
Received: B-B4-7-63
Received: B-B4-7-61
Received: B-B4-7-5F
Received: B-B4-7-5C
Received: B-B4-7-59
Received: B-B4-7-58
Received: B-B4-7-56
Received: B-B4-7-57
Received: B-B4-7-58
Received: B-B4-7-59
Received: B-B4-7-5B
Received: B-B4-7-5C
Received: B-B4-7-5D
Received: B-B4-7-5A
Received: B-B5-7-64
Received: B-B5-7-65
Received: B-B5-7-66
Received: B-B5-7-65
Received: B-B5-7-64
Received: B-B5-7-63
Received: B-B5-7-62
Received: B-B5-7-61
Received: B-B5-7-60
Received: B-B5-7-5F
Received: B-B5-7-5E
Received: B-B5-7-5D
Received: B-B5-7-5C
Received: B-B5-7-5B
Received: B-B0-7-2A
Received: B-B0-7-2B
Received: B-B0-7-2C
Received: B-B0-7-2E
Received: B-B0-7-30
Received: B-B0-7-31
Received: B-B0-7-32
Received: B-B0-7-33
Received: B-B0-7-35
Received: B-B0-7-36

I know its probably easy to fix , but I have tried to for days but, can't get it figured out, any help would be much appreciated. and any suggestions on a better way to code , to achieve what I want, I'm all ears!
if this entire post makes no sense, I have mental fatigue from reading so much, on learning how to code!, in the last two months.

[code]


/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

#include "MIDIUSB.h"

#include <Servo.h>

Servo knob1;
Servo knob2;
Servo knob3;
Servo knob4;
Servo knob5;
Servo knob6;
byte prevpos = 0;

const byte ch1 = 0;
const byte ch2 = 2;
const byte ch3 = 3;
const byte ch4 = 4;
const byte ch5 = 5;
const byte ch6 = 6;

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90, pitch, velocity};
  (0x09, 0x90, pitch, velocity);
  (0x09, 0x91, pitch, velocity);
  (0x09, 0x92, pitch, velocity);
  (0x09, 0x93, pitch, velocity);
  (0x09, 0x94, pitch, velocity);
  (0x09, 0x95, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80, pitch, velocity};
  (0x08, 0x80, pitch, velocity);
  (0x08, 0x81, pitch, velocity);
  (0x08, 0x82, pitch, velocity);
  (0x08, 0x83, pitch, velocity);
  (0x08, 0x84, pitch, velocity);
  (0x08, 0x85, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);

}

void setup() {
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(12, OUTPUT);
  Serial.begin(115200);
  

  knob1.attach(7);
  knob2.attach(8);
  knob3.attach(9);
  knob4.attach(10);
  knob5.attach(11);
  knob6.attach(12);

}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0, 0x07, value};
  (0x0B, 0xB1, 0x07, value);
  (0x0B, 0xB2, 0x07, value);
  (0x0B, 0xB3, 0x07, value);
  (0x0B, 0xB4, 0x07, value);
  (0x0B, 0xB5, 0x07, value);
  MidiUSB.sendMIDI(event);
  
}

void loop() {
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {
      Serial.print("Received: ");
      Serial.print(rx.header, HEX);
      Serial.print("-");
      Serial.print(rx.byte1, HEX);
      Serial.print("-");
      Serial.print(rx.byte2, HEX);
      Serial.print("-");
      Serial.println(rx.byte3, HEX);
      servoX(rx.byte1, rx.byte2, rx.byte3);
    }
  } while (rx.header != 0);
}
void servoX(byte x, byte y, byte z) {
  byte servoPos = map(z, 0, 127, 0, 270);
  switch (y) {
    case 7:
      knob1.write(servoPos);
      break;
    case 2:
      knob2.write(servoPos);
      break;
    case 3:
      knob3.write(servoPos);
      break;
    case 4:
      knob4.write(servoPos);
      break;
    case 5:
      knob5.write(servoPos);
      break;
    case 6:
      knob6.write(servoPos);
      break;
  }
}

[/code]

Your image - for everyone to see - although I’m unsure what it shows...

What’s the red part supposed to do?

</sub> <sub>midiEventPacket_t event = {0x0B, 0xB0, 0x07, value};[color=red]   (0x0B, 0xB1, 0x07, value);   (0x0B, 0xB2, 0x07, value);   (0x0B, 0xB3, 0x07, value);   (0x0B, 0xB4, 0x07, value);   (0x0B, 0xB5, 0x07, value);[/color]   MidiUSB.sendMIDI(event);</sub> <sub>

==========

Hi, J-M-L

(0x0B, 0xB1, 0x07, value);

0x0B is control change event
0xB1 is control change with channel #
0x07 controller # CC 7

I could be wrong, my horn is very green!
thanks for the reply!

But the red part is in no array, the compiler gets rid of it.

mine complies and is still there and not in red?

void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = {0x0B, 0xB0, 0x07, value};
(0x0B, 0xB0, 0x07, value);
(0x0B, 0xB1, 0x07, value);
(0x0B, 0xB2, 0x07, value);
(0x0B, 0xB3, 0x07, value);
(0x0B, 0xB4, 0x07, value);
(0x0B, 0xB5, 0x07, value);
MidiUSB.sendMIDI(event);

I put the red stuff for you to see what I’m taking about. Yes it compiles but the compiler just gets rid of these lines, they do not belong in any instructions or data sets. They would be evaluated to the last value in the list but does nothing with it - the optimizer sees it’s useless code and gets rid of it (in my opininion)

like I said still, very new programing, so any suggestions are most welcome, I took that part of code from the MIDIUSB example sketch. I figured that it would work, but you say other wise.

I took that part of code from the MIDIUSB example sketch. I figured that it would work, but you say other wise.

Link To that example?

Regardless of this, what did you expect those red lines to do or define?

[code]
/*
   MIDIUSB_test.ino

   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/

#include "MIDIUSB.h"

// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial.begin(115200);
}

// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number number (0-119).
// Fourth parameter is the control value (0-127).

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  midiEventPacket_t rx;
  do {
    rx = MidiUSB.read();
    if (rx.header != 0) {
      Serial.print("Received: ");
      Serial.print(rx.header, HEX);
      Serial.print("-");
      Serial.print(rx.byte1, HEX);
      Serial.print("-");
      Serial.print(rx.byte2, HEX);
      Serial.print("-");
      Serial.println(rx.byte3, HEX);
    }
  } while (rx.header != 0);
}

[/code]

noizeypot:
GitHub - arduino-libraries/MIDIUSB: A MIDI library over USB, based on PluggableUSB

well I don't see in there all the lines I highlighted in red in your code...

[color=purple]midiEventPacket_t[/color] [color=blue]event[/color] = [color=red]{[/color][color=teal]0x0B, 0xB0, 0x07, value[/color][color=red]}[/color];

--> this defines a variable called [color=blue]event[/color], which type is [color=purple]midiEventPacket_t[/color] and initialized with the stuff that is in between the [color=red]{}[/color] brackets

MidiUSB.sendMIDI([color=blue]event[/color]);

--> This line of code sends that specific [color=blue]event[/color]

so again, what did you expect those red lines to do when you typed them in? they don't define events, they are not sent anywhere and the way they are written are ignored. If you want to send those events out, you need to initialize your

event

variable sequentially with the right content and send it out.

makes sense?

so I haven't had a chance to test this at home but its hopefully going to allow me to have each servo on its own midi channel each being independently controlled by cc7

[code]
#include <MIDI.h>

#include <frequencyToNote.h>
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_RingBuffer.h>
#include <midi_Settings.h>
#include <midi_UsbDefs.h>
#include <midi_UsbTransport.h>
#include <MIDIUSB.h>
#include <pitchToFrequency.h>
#include <pitchToNote.h>
#include "MIDIUSB.h"
#include <Servo.h>




#define MIDI_CHANNEL_OMNI   0

#define MIDI_CHANNEL_OFF   17



/*
   MIDIUSB_test.ino
   Created: 4/6/2015 10:47:08 AM
   Author: gurbrinder grewal
   Modified by Arduino LLC (2015)
*/


//************LIBRARIES USED**************
// include the ResponsiveAnalogRead library for analog smoothing
//usbMIDI.h library is added automatically when code is compiled as a MIDI device

// MIDI Data:
// First parameter is the event type (0x0B = control change).
// Second parameter is the event type, combined with the channel.
// Third parameter is the control number (0-119).
// Fourth parameter is the control value (0-127).


void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90, pitch, velocity};
  (0x09, 0x90, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
  MidiUSB.read();
  MidiUSB.flush();
  (0x09, 0x91, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
  MidiUSB.flush();
  (0x09, 0x92, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
  MidiUSB.flush();
  (0x09, 0x93, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
  MidiUSB.flush();
  (0x09, 0x94, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
  MidiUSB.flush();
  (0x09, 0x95, pitch, velocity);
  MidiUSB.sendMIDI(noteOn);
  MidiUSB.flush();
}
void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80, pitch, velocity};
  (0x08, 0x80, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);
  MidiUSB.flush();
  (0x08, 0x81, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);
  MidiUSB.flush();
  (0x08, 0x82, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);
  MidiUSB.flush();
  (0x08, 0x83, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);
  MidiUSB.flush();
  (0x08, 0x84, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);
  MidiUSB.flush();
  (0x08, 0x85, pitch, velocity);
  MidiUSB.sendMIDI(noteOff);
  MidiUSB.flush();
}
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;

const byte ch1 = 0;
const byte ch2 = 1;
const byte ch3 = 2;
const byte ch4 = 3;
const byte ch5 = 4;
const byte ch6 = 5;
byte prevPos = 0;


void setup() {
  Serial.begin(115200);

  while (!Serial);
  servo1.attach(7);
  servo2.attach(8);    //Servo for channel_1 on PIN 8
  servo3.attach(9);    //Servo for channel_2 on PIN 9
  servo4.attach(10);   //Servo for channel_3 on PIN 10
  servo5.attach(11);   //Servo for channel_4 on PIN 11
  servo6.attach(12);
  MidiUSB.flush();      //Servo for channel_5 on PIN 12
}
void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | 0x07, control, value};
  MidiUSB.sendMIDI(event);
  MidiUSB.read();
  MidiUSB.flush();
  (0x0B, 0xB0 | 0x07, control, value);
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
  (0x0B, 0xB1 | 0x07, control, value);
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
  (0x0B, 0xB2 | 0x07, control, value);
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
  (0x0B, 0xB3 | 0x07, control, value);
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
  (0x0B, 0xB4 | 0x07, control, value);
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
  (0x0B, 0xB5 | 0x07, control, value);
  MidiUSB.sendMIDI(event);
  MidiUSB.flush();
  MidiUSB.read();
}

void loop() {
  midiEventPacket_t rx;
  rx = MidiUSB.read();
  Serial.print("Received: ");
  Serial.print(rx.header, HEX);
  Serial.print("-");
  Serial.print(rx.byte1, HEX);
  Serial.print("-");
  Serial.print(rx.byte2, HEX);
  Serial.print("-");
  Serial.println(rx.byte3, HEX);
  servopos(rx.byte1, rx.byte2, rx.byte3);
  MidiUSB.flush();
}

void servopos(byte x, byte y, byte z) { //Input DATA as Unknown,CHANNEL,MIDI_Value
  prevPos = z;
  int servoPos = map(z, 0, 127, 0, 270);
  switch (y) {
    case ch1:
      servo1.write(servoPos);
      MidiUSB.read();
      break;
      MidiUSB.flush();
    case ch2:
      servo2.write(servoPos);
      MidiUSB.read();
      break;
      MidiUSB.flush();
    case ch3:
      servo3.write(servoPos);
      MidiUSB.read();
      break;
      MidiUSB.flush();
    case ch4:
      servo4.write(servoPos);
      MidiUSB.read();
      break;
      MidiUSB.flush();
    case ch5:
      servo5.write(servoPos);
      MidiUSB.read();
      break;
      MidiUSB.flush();
    case ch6:
      servo1.write(servoPos);
      MidiUSB.read();
      break;
      MidiUSB.flush();

  }
}

/code]

No you still have useless data such as in

  [b][color=green]midiEventPacket_t noteOn = {0x09, 0x90, pitch, velocity};[/color][color=blue]// [b]defining noteOn and setting values[/b][/color]
  [color=red](0x09, 0x90, pitch, velocity);[/color] //[b][color=blue]That’s garbage![/b]
  MidiUSB.sendMIDI(noteOn); [color=blue]// [b]sending noteOn[/b][/color]
  MidiUSB.read();
  MidiUSB.flush();
  [color=red](0x09, 0x91, pitch, velocity);[/color]//[b][color=blue]That’s garbage![/b]
  MidiUSB.sendMIDI(noteOn);[b] //[color=blue] WHAT DO YOU THINK IS IN noteON HERE?[/b]
...

Data need to be assigned into a variable to stick in memory and be able to do something with it... again read my explanation above about creating a variable, initializing the variable with relevant values and then taking action using the variable....

Perhaps I missed or misunderstood something in your explanation but why do you want to make all those changes to noteOn(), noteOff() and controlChange() that are only intended to SEND MIDI data out from the Arduino to the DAW? You only want to READ incoming MIDI data don't you?

All the action is in loop() and servopos(). You have far too many sends and reads and flushes. The one read() in main loop() code is all you need.

You read a MIDI event. Then you should be checking if it is a CC7 (the only events you're interested in?) and only then calling servopos().

All the reads and flushes in servopos are useless. All you really need to do in there is check the channel and write a value to the appropriate servo (you'll already know that it's a CC7 event). Then you will automatically return to the top of loop to do the next read() and sort out the next message, which may or may not be another CC7 on a different channel. If it's anything other than a CC7 you just ignore it and read the next event.

What am I not understanding?

Steve

@slipstick - that was going to be my next question, seems there are simple programming rules that OP needs to understands first probably