Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: USBmidi Read, OnNoteOn, do something on different channels fails

  1. #1
    Junior Member
    Join Date
    Feb 2018
    Location
    Zurich
    Posts
    5

    USBmidi Read, OnNoteOn, do something on different channels fails

    Dear All

    I got stuck within a code, managing Midi from USB with a Teensy 3.2.
    I want to run two Stepper motors seperatly at the Speed of the Midi Note, coming in from two different channels.
    (Motor 1 runs on Note from Midi Channel 1 and Motor 2 on Midi Channel 2)

    My code is run well, as long only one Midi channel send data.
    As soon the other Midi Channel is sending, data the other channel doesnt work.

    At the moment I have no Idea if its a bug in my code or some RAM Proble or timing isues.

    Hope some of you can help me!



    Here is the complete Code:
    // Two Stepper Motors runs on the Speed from Midi Notes. (Thanks to the Author of MidiMotor for basic example code)

    #include <AccelStepper.h>
    //AccelStepper axis(4, 2, 3, 4, 5); // FULL4WIRE Coil 1 - 4 on pin 2,3,4,5
    AccelStepper axis1(4, 2, 3, 4, 5); //
    //AccelStepper axis(4, 2, 3, 4, 5); // FULL4WIRE Coil 1 - 4 on pin 6,7,8,9
    AccelStepper axis2(4, 6, 7, 8, 9); //

    float notes[] = {
    8.1757989156, // 0
    8.6619572180, // 1
    9.1770239974, // 2
    10.3008611535, // 3
    10.3008611535, // 4
    10.9133822323, // 5
    11.5623257097, // 6
    12.2498573744, // 7
    12.9782717994, // 8
    13.7500000000, // 9
    14.5676175474, // 10
    15.4338531643, // 11
    16.3515978313, // 12
    17.3239144361, // 13
    18.3540479948, // 14
    19.4454364826, // 15
    20.6017223071, // 16
    21.8267644646, // 17
    23.1246514195, // 18
    24.4997147489, // 19
    25.9565435987, // 20
    27.5000000000, // 21
    29.1352350949, // 22
    30.8677063285, // 23
    32.7031956626, // 24
    34.6478288721, // 25
    36.7080959897, // 26
    38.8908729653, // 27
    41.2034446141, // 28
    43.6535289291, // 29
    46.2493028390, // 30
    48.9994294977, // 31
    51.9130871975, // 32
    55.0000000000, // 33
    58.2704701898, // 34
    61.7354126570, // 35
    65.4063913251, // 36
    69.2956577442, // 37
    73.4161919794, // 38
    77.7817459305, // 39
    82.4068892282, // 40
    87.3070578583, // 41
    92.4986056779, // 42
    97.9988589954, // 43
    103.8261743950, // 44
    110.0000000000, // 45
    116.5409403795, // 46
    123.4708253140, // 47
    130.8127826503, // 48
    138.5913154884, // 49
    146.8323839587, // 50
    155.5634918610, // 51
    164.8137784564, // 52
    174.6141157165, // 53
    184.9972113558, // 54
    195.9977179909, // 55
    207.6523487900, // 56
    220.0000000000, // 57
    233.0818807590, // 58
    246.9416506281, // 59
    261.6255653006, // 60
    277.1826309769, // 61
    293.6647679174, // 62
    311.1269837221, // 63
    329.6275569129, // 64
    349.2282314330, // 65
    369.9944227116, // 66
    391.9954359817, // 67
    415.3046975799, // 68
    440.0000000000, // 69
    466.1637615181, // 70
    493.8833012561, // 71
    523.2511306012, // 72
    554.3652619537, // 73
    587.3295358348, // 74
    622.2539674442, // 75
    659.2551138257, // 76
    698.4564628660, // 77
    739.9888454233, // 78
    783.9908719635, // 79
    830.6093951599, // 80
    880.0000000000, // 81
    932.3275230362, // 82
    987.7666025122, // 83
    1046.5022612024, // 84
    1108.7305239075, // 85
    1174.6590716696, // 86
    1244.5079348883, // 87
    1318.5102276515, // 88
    1396.9129257320, // 89
    1479.9776908465, // 90
    1567.9817439270, // 91
    1661.2187903198, // 92
    1760.0000000000, // 93
    1864.6550460724, // 94
    1975.5332050245, // 95
    2093.0045224048, // 96
    2217.4610478150, // 97
    2349.3181433393, // 98
    2489.0158697766, // 99
    2637.0204553030, // 100
    2793.8258514640, // 101
    2959.9553816931, // 102
    3135.9634878540, // 103
    3322.4375806396, // 104
    3520.0000000000, // 105
    3729.3100921447, // 106
    3951.0664100490, // 107
    4186.0090448096, // 108
    4434.9220956300, // 109
    4698.6362866785, // 110
    4978.0317395533, // 111
    5274.0409106059, // 112
    5587.6517029281, // 113
    5919.9107633862, // 114
    5919.9107633862, // 115
    6644.8751612791, // 116
    7040.0000000000, // 117
    7458.6201842894, // 118
    7902.1328200980, // 119
    8372.0180896192, // 120
    8869.8441912599, // 121
    9397.2725733570, // 122
    9956.0634791066, // 123
    10548.0818212118, // 124
    11175.3034058561, // 125
    11839.8215267723, // 126
    12543.8539514160 // 127
    };

    //! Onboard LED
    int ledPin = 13;

    //! Are we currently playing a note
    bool playing = false;

    //! The current motors steps
    float curr_speed1 = 0.0;
    float curr_speed2 = 0.0;

    //! The last note that was recived - used to decide when to turn off the motors
    byte last_note1 = 0;
    byte last_note2 = 0;

    //Define Midi Channel for Motor 1
    int axisMidiChan1 = 1;

    //Define Midi Channel for Motor 2
    int axisMidiChan2 = 2;

    //Bool for running Motor 1
    bool axis1Run = false;

    //Bool for running Motor 2
    bool axis2Run = false;

    //! Convert a midi note to steps per second
    float noteSpeed(byte note)
    {
    return notes[note];
    }

    //! Called when we recieve a MIDI note-on event
    void OnNoteOn(byte channel, byte note, byte velocity)
    {
    // If we're not currently playing, then we should try to accelerate
    // into the requested note
    if(!playing && channel == axisMidiChan1){
    last_note1 = note;
    curr_speed1 = noteSpeed(note);
    Serial.println(String("Note On: ch=") + channel + ", note=" + note); //DEBUG
    axis1.enableOutputs();
    axis1Run = true;
    }

    if(!playing && channel == axisMidiChan2){
    last_note2 = note;
    curr_speed2 = noteSpeed(note);
    Serial.println(String("Note On: ch=") + channel + ", note=" + note); //DEBUG
    axis2.enableOutputs();
    axis2Run = true;
    }

    playing = true;
    digitalWrite(ledPin, HIGH);
    }

    //! Called when we recieve a MIDI note-off event
    void OnNoteOff(byte channel, byte note, byte velocity)
    {
    // Only turn off the last requested note
    // This makes it more comfortable to jam on the keyboard
    if (channel == axisMidiChan1 && note == last_note1){
    axis1Run = false;
    Serial.println(String("Note Off: ch=") + channel + ", note=" + note); //DEBUG
    axis1.disableOutputs();
    }

    if (channel == axisMidiChan2 && note == last_note2){
    axis2Run = false;
    Serial.println(String("Note Off: ch=") + channel + ", note=" + note); //DEBUG
    axis2.disableOutputs();
    }

    if (axis1Run == false && axis2Run == false){
    playing = false;
    digitalWrite(ledPin, LOW);
    }
    }

    void setup() {
    pinMode(ledPin, OUTPUT);

    axis1.setMaxSpeed(2100);
    axis2.setMaxSpeed(2100);

    usbMIDI.setHandleNoteOff(OnNoteOff);
    usbMIDI.setHandleNoteOn(OnNoteOn);
    Serial.println("MIDI Input Test");
    }

    void loop() {
    usbMIDI.read();

    if(playing)
    {
    if (axis1Run == true){
    axis1.runSpeed();
    axis1.setSpeed(curr_speed1);
    }

    if (axis2Run == true){
    axis2.runSpeed();
    axis2.setSpeed(curr_speed2);
    }
    }
    }

  2. #2
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,234
    Shouldn't you have two playing variables, one for each channel?

    You're note-on stuff only works if it's not playing on either channel so you can't play them together.

  3. #3
    Junior Member
    Join Date
    Feb 2018
    Location
    Zurich
    Posts
    5
    Dear Oddson
    Thank you for the quick answer.

    There are two different variables. curr_speed1/2 and axisRun1/2.
    But maybe it would be bether to Split the playing Variable.

    Ah, just to get you right. Cant it played together, because there can only be one if Statement at the Time when a Note On receives?
    Last edited by MikeSound; 02-06-2018 at 10:59 PM. Reason: Gramar and Spelling

  4. #4
    Senior Member oddson's Avatar
    Join Date
    Feb 2013
    Location
    Isle in the Salish Sea
    Posts
    1,234
    There's only one of anything at a time.
    but yes... it looks like you're imposing monophony on both channels instead of each channel because you need a separate variable to keep track of whether each 'voice' is active or not.

    If you're planning to generalize to more voices you may want to switch to arrays to hold values and then you can have a loop within your main loop to run the same code for each voice.

  5. #5
    Junior Member
    Join Date
    Feb 2018
    Location
    Zurich
    Posts
    5
    Okay :-)

    I see now.
    Thank you.

    I will do the changes and post the result here!

  6. #6
    Junior Member
    Join Date
    Feb 2018
    Location
    Zurich
    Posts
    5
    Hei

    So.... I got the Solution now.
    I copy the incoming Midi Values to a global Variables and do the IF Statements within the While task. Now it works

    Thanks again for your help!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •