Midi to motors polyphony

Status
Not open for further replies.
Hi there, I was successfully able to control 5 motors using midi notes sequenced with a midi sequencer using the teensy lc board. The only problem I'm having is that when 2 or more midi notes are transmitted to the teensy at the same time they seem to cancel each other out and 0 voltage is sent to the motors. It seems like a polyphony problem in the code. I was wondering what else I need to add to the code and where I need to add it to fix this problem.

Code

// use PWM pins 3, 4, 6, 9, 10
int pins[] = {3, 4, 6, 9, 10};
#define numNotes 5

// motor channel 0 will be triggered by lowNote
// motor channel 1 will be triggered by lowNote + 1 etc.
int lowNote = 60; // MIDI note 60 (C-2) // change to use different note triggers

// Teensy MIDI callbacks
void OnNoteOn(byte channel, byte note, byte velocity);
void OnNoteOff(byte channel, byte note, byte velocity);

// initialization
void setup() {
// output pins
for (int i = 0; i < 5; i++) {
pinMode(pins, OUTPUT);
}

// init MIDI callbacks
usbMIDI.setHandleNoteOn(OnNoteOn);
usbMIDI.setHandleNoteOff(OnNoteOff);
}

// main loop
void loop() {
while (usbMIDI.read()) {
}

// nothing to do here...

}

// OnNoteOn() callback
// When a new "note on" message is recieved
void OnNoteOn(byte channel, byte note, byte velocity) {

// check if the note is in range for our possible motor outputs
if (note >= lowNote && note < lowNote + numNotes) {
// adjust for note # offset
int notePin = note - lowNote;
// linear map from MIDI's 7 bits of resolution to Teensy's 12
analogWrite(pins[notePin], velocity << 5 );
}

}

// OnNoteOff() callback
// When a new "note off" message is received
void OnNoteOff(byte channel, byte note, byte velocity) {

// check that it is in the range
if (note >= lowNote && note < lowNote + numNotes) {
int notePin = note - lowNote; // offset
analogWrite(pins[notePin], 0); // turn it off
}
}
 
+1 with the exact same sort of set up and notes cancelling...any advice appreciated. Did you figure out a solution to this Joyfultalk?
 
Because I'm not expert with C I would never leave a conditional in a state like that where you are relying on default precedence of logical and arithmetical operators; so I was hopeful your problem might be there... its not.

I've looked this code over a few times and cannot see an obvious bug. From the description it sounds like the analogWrite() commands are being reset by something other than the OnNoteOff() code.

Could it be usbMIDI.read() is resetting the analogWrite() to zero somehow?

You can eliminate this as a suspect by sending other midi (non-note values would be best so the noteOn and noteOff handles are not fired) and seeing it shuts your motors off.

(If this is the problem the write commands would be reset without the off-note code firing. So you can also eliminate this possibility by including a serial.print() to show you whenever a note-off is processed. If the motors stop without a note-off then the problem is not with your code.)

If it does you would have to track note states in an array and fire the analogWrite() for each pin in a for loop from the stored state values on every MIDI event from within the main loop (inside the while(usbMIDI.read()) braces.



If it doesn't... then there must be a bug here we're not seeing and some print commands and/or MIDI printout should help you find it by giving you visual feedback on the internal workings.

Seeing the output on a MIDI utility package like Ox would also help.

If you still need help to find it then you'll need to provide better details.

It's not entirely clear if the problem occurs when new notes are played after the first note but before the first note-off is received?; i.e. if motor on notePin == 0 is running does it stop when notePin == 1 is played? (or when it's released?).

A more precise description of the buggy behaviour is required as otherwise someone looking to help would have to wire-up some sort of hardware to display analogWrite output to debug your code for you (or be a lot better at spotting bugs by scanning than I am).

If you can exactly describe the unwanted behaviour it is likely someone else finding it from scanning the code would be much easier. MIDI-ox printout or similar utility output might also help.
 
Code:
// output pins
for (int i = 0; i < 5; i++) {
pinMode(pins[i], OUTPUT);
}
You don't need to do this for analog output pins. I don't know if it will cause a problem though.

Pete
 
Status
Not open for further replies.
Back
Top