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

Thread: Midi, Windows, USB, Teensy and Synths

  1. #1
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16

    Midi, Windows, USB, Teensy and Synths

    Hi All.

    First up to Paul Stoffregen and the crew of PJRC and all who have put creative energy into Teensy. Thank you, Teensy rocks!

    I know windows may not be the best platform but I think I've finally got it licked. BIOS reflash etc, disabled VIA USB3 host essential!
    Midisport 2x2 and 4x4, Tascam US-144, Roland UM-ONE and MIO-10 interfaces seem to be co-operating..

    A noob to Midi 2 years ago, Arduino a little over half of that, so I'm here on a quest for my particular Midi controller.

    I put one of these - https://cs.gmu.edu/~sean/projects/gizmo/ -together, a veritable Midi "Swiss army knife". Loads of fun. Pretty soon have ended up with a bunch of them so a Teensy 3.5 for it's 6 uarts is gonna get the job as a dedicated controller / USB interface and will end up in the box with them. Most of the metal work is done, holes installed, boards with the 18 pots, one encoder and forty something R/S latch debounced buttons, squeezed into barely enough panel space.

    So far, starting with one Gizmo, using a T_3.2 have got the first one working enough to see the end result. The rest is a formality.

    Have had a few questions which so far have been answered just by exploring the forum so a big thanks to all as have learned loads of other stuff along the way.

    Keep up the great work!

  2. #2
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16
    Er, help I'm stuck.. Here's the deal.
    Running two PC's, Win 7 64, One with Arduino 1.8.5 - Teensyduino 1.45, the other, Arduino 1.8.8 - Teensyduino 1.45.
    Issue is same on both setups.

    First time I've tried this so here goes:-

    Code:
    #include <MIDI.h>
    #include "Controller.h"
    /*************************************************************
      MIDI CONTROLLER 1.2
      by Notes and Volts
      www.notesandvolts.com
     
      With some  mods by Pat
      
      Added per element value map / constrain for Pots - not yet for multiplex
      Useful for pots whose wiper does not reach either end of the resistance track
      eg. joysticks or optical expression pedals using an LDR.
       
      Added option to direct per element output to alternative serial ports for pots
      tho is not used in this code iteration 
    
      Originally, this code was for UNO, however was usually used on a MEGA without multiplexers.
      The aim is to shoehorn this code into a Teensy 3.5, the end result being:-
    
      A class compliant USB - Midi interface / control surface for 5 Gizmos.
    
      In this iteration of the code, the multiplexer handling has been extended so we're 
      outputting bits 0 - 5. A 74LS138 is used to point to 3 x 4067's.
      
      Debounce is set to zero coz we're using R/S latch hardware debounce.
      Why? Coz the chosen press button switches are SPDT and I happened to have a bag of 4093's and
      er well, a carryover from radio days - reject out of band crap before movin to the next stage. 
      
      
     *************************************************************/
    
    //************************************************************
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
    //************************************************************
    //***SET THE NUMBER OF CONTROLS USED**************************
    //************************************************************
    //---How many buttons are connected directly to pins?---------
    byte NUMBER_BUTTONS = 3;
    //---How many potentiometers are connected directly to pins?--
    byte NUMBER_POTS = 2;
    //---How many buttons are connected to a multiplexer?---------
    byte NUMBER_MUX_BUTTONS = 43;
    //---How many potentiometers are connected to a multiplexer?--
    byte NUMBER_MUX_POTS = 0;
    //*******************************************************************
    
    //*** MULTIPLEXERS? *************************************************
    //MUX address pins must be connected to Arduino MEGA pins 22,23,24,25,26,27
    //A0 = PIN22, A1 = PIN23, A2 = PIN24, A3 = PIN25 A4 = PIN26, A5 = PIN27
    //*******************************************************************
    
    //Mux NAME (OUTPUT PIN, , How Many Mux Pins?(8 or 16) , Is It Analog?);
    
    Mux M1(30, NUMBER_MUX_BUTTONS, false); //Digital multiplexer on Mega pin 30
    Mux M2(3, NUMBER_MUX_POTS, true); //Analog multiplexer on MEGA pin 3
    
    //*******************************************************************
    
    //***DEFINE DIRECTLY CONNECTED POTENTIOMETERS************************
    //Pot (Pin Number, Command, CC Control, MidiPortNumber, Channel Number, MapInLow, MapInHigh, MapOut Low, MapOutHigh)
    //**Command parameter is for future use**
    
    //Pot PO1 (Pin Number, Command, CC Control, MidiPort, Channel Number, inLow, inHigh, outLow, outHigh)
    
      Pot PO1(A0,  0, 14,  1, 16, 10, 1010, 0, 127);
      Pot PO2(A1,  0, 15,  1, 16, 10, 1010, 0, 127);
    //Pot PO3(A14, 0, 1,   1, 1,  0, 1023, 0, 127);
    //Pot PO4(A13, 0, 11,  1, 1,  0, 1023, 0, 127);
    //Pot PO5(A0,  0, 5,   1, 1,  0, 1023, 0, 127);
    //Pot PO6(A1,  0, 91,  1, 1,  0, 1023, 0, 127);
    //Pot PO7(A2,  0, 93,  1, 1,  0, 1023, 0, 127);
    //Pot PO8(A3,  0, 7,   1, 1,  0, 1023, 0, 127);
    
    //*******************************************************************
    //Add pots used to array below like this->  Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6};
    Pot *POTS[] {&PO1, &PO2};
    //*******************************************************************
    
    //***DEFINE DIRECTLY CONNECTED BUTTONS*******************************
    //Button (Pin Number, Command, Note Number, Channel, Debounce Time)
    //** Command parameter 0=NOTE  1=CC  2=Toggle CC **
    
      Button BU1(4,   1, 102, 16, 5 );
      Button BU2(3,   1, 103, 16, 5 );
      Button BU3(2,   1, 104, 16, 5 );
    //Button BU4(35,  2, 69,  16, 0 );
    //Button BU5(53,  2, 64,  16, 0 );
    //Button BU6(51,  2, 66,  16, 0 );
    //Button BU7(49,  0, 43,  16, 0 );
    //Button BU8(47,  0, 44,  16, 0 );
    //Button BU9(45,  0, 45,  16, 0 );
    //Button BU10(43, 0, 46,  16, 0 );
    //Button BU11(41, 0, 47,  16, 0 );
    //Button BU12(39, 0, 48,  16, 0 );
    //Button BU13(37, 0, 49,  16, 0 );
    //Button BU14(35, 0, 50,  16, 0 );
    //Button BU15(33, 0, 51,  16, 0 );
    //Button BU16(31, 0, 52,  16, 0 );
    //Button BU17(29, 0, 53,  16, 0 );
    //*******************************************************************
    //Add buttons used to array below like this->  Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8, &BU9, &BU10, &BU11, &BU12, &BU13, &BU14, &BU15, &BU16, BU17};
    Button *BUTTONS[] {&BU1, &BU2, &BU3}; 
    
    //*******************************************************************
    
    
    //***DEFINE BUTTONS CONNECTED TO MULTIPLEXER*************************
    Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);
    //** Command parameter 0=NOTE  1=CC  2=Toggle CC **
    
    Button MBU1(M1, 0, 1, 64, 16, 0);   // Mute 1
    Button MBU2(M1, 1, 1, 65, 16, 0);   // Mute 2
    Button MBU3(M1, 2, 1, 66, 16, 0);   // Mute 3
    Button MBU4(M1, 3, 1, 67, 16, 0);   // Mute 4
    Button MBU5(M1, 4, 1, 68, 16, 0);   // Mute 5
    Button MBU6(M1, 5, 1, 69, 16, 0);   // Mute 6
    Button MBU7(M1, 6, 1, 70, 16, 0);   // Mute 7
    Button MBU8(M1, 7, 1, 71, 16, 0);   // Mute 8
    Button MBU9(M1, 8, 1, 72, 16, 0);   // Mute 9
    Button MBU10(M1, 9, 1, 73, 16, 0);  // Mute 10
    Button MBU11(M1, 10, 1, 74, 16, 0); // Mute 11
    Button MBU12(M1, 11, 1, 75, 16, 0); // Mute 12
    Button MBU13(M1, 12, 1, 90, 16, 0); // Clear Track
    Button MBU14(M1, 13, 1, 93, 16, 0); // Mark
    Button MBU15(M1, 14, 1, 94, 16, 0); // Copy
    Button MBU16(M1, 15, 1, 95, 16, 0); // Splat
    Button MBU17(M1, 16, 1, 76, 16, 0);   // Select 1
    Button MBU18(M1, 17, 1, 77, 16, 0);   // Select 2
    Button MBU19(M1, 18, 1, 78, 16, 0);   // Select 3
    Button MBU20(M1, 19, 1, 79, 16, 0);   // Select 4
    Button MBU21(M1, 20, 1, 80, 16, 0);   // Select 5
    Button MBU22(M1, 21, 1, 81, 16, 0);   // Select 6
    Button MBU23(M1, 22, 1, 82, 16, 0);   // Select 7
    Button MBU24(M1, 23, 1, 83, 16, 0);   // Select 8
    Button MBU25(M1, 24, 1, 84, 16, 0);   // Select 9
    Button MBU26(M1, 25, 1, 85, 16, 0);   // Select 10
    Button MBU27(M1, 26, 1, 86, 16, 0);   // Select 11
    Button MBU28(M1, 27, 1, 87, 16, 0);   // Select 12
    Button MBU29(M1, 28, 1, 88, 16, 0);   // Toggle Solo 
    Button MBU30(M1, 29, 1, 89, 16, 0);   // Toggle Transposable Track
    Button MBU31(M1, 30, 1, 91, 16, 0);   // Toggle Trig Next Seq
    Button MBU32(M1, 31, 1, 92, 16, 0);   // Toggle Click Track
    Button MBU33(M1, 32, 1, 76, 1,  0);   // Select 1
    Button MBU34(M1, 33, 1, 77, 1,  0);   // Select 2
    Button MBU35(M1, 34, 1, 78, 1,  0);   // Select 3
    Button MBU36(M1, 35, 1, 79, 1,  0);   // Select 4
    Button MBU37(M1, 36, 1, 80, 1,  0);   // Select 5
    Button MBU38(M1, 37, 1, 81, 1,  0);   // Select 6
    Button MBU39(M1, 38, 1, 82, 1,  0);   // Select 7
    Button MBU40(M1, 39, 1, 83, 1,  0);   // Select 8
    Button MBU41(M1, 40, 1, 84, 1,  0);   // Select 9
    Button MBU42(M1, 41, 1, 85, 1,  0);   // Select 10
    Button MBU43(M1, 42, 1, 86, 1,  0);   // Select 11
    Button MBU44(M1, 43, 1, 87, 1,  0);   // Select 12
    Button MBU45(M1, 44, 1, 88, 1,  0);   // Toggle Solo 
    Button MBU46(M1, 45, 1, 89, 1,  0);   // Toggle Transposable Track
    Button MBU47(M1, 46, 1, 91, 1,  0);   // Toggle Trig Next Seq
    Button MBU48(M1, 47, 1, 92, 1,  0);   // Toggle Click Track
    //*******************************************************************
    ////Add multiplexed buttons used to array below like this->  Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
    
    Button *MUXBUTTONS[] {&MBU1,&MBU2,&MBU3,&MBU4,&MBU5,&MBU6,&MBU7,&MBU8,&MBU9,&MBU10,&MBU11,&MBU12,&MBU13,&MBU14,&MBU15,&MBU16,
    &MBU17,&MBU18,&MBU19,&MBU20,&MBU21,&MBU22,&MBU23,&MBU24,&MBU25,&MBU26,&MBU27,&MBU28,&MBU29,&MBU30,&MBU31,&MBU32, 
    &MBU33,&MBU34,&MBU35,&MBU36,&MBU37,&MBU38,&MBU39,&MBU40,&MBU41,&MBU42,&MBU43,&MBU44,&MBU45,&MBU46,&MBU47,&MBU48};
    
    //*******************************************************************
    
    //***DEFINE POTENTIOMETERS CONNECTED TO MULTIPLEXER*******************
    //Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
    //**Command parameter is for future use**
    
    //Pot MPO1(M2, 0, 1, 1, 1);
    //Pot MPO2(M2, 1, 1, 7, 1);
    //Pot MPO3(M2, 2, 1, 50, 1);
    //Pot MPO4(M2, 3, 1, 55, 2);
    //Pot MPO5(M2, 4, 1, 50, 1);
    //Pot MPO6(M2, 5, 1, 55, 2);
    //Pot MPO7(M2, 6, 1, 50, 1);
    //Pot MPO8(M2, 7, 1, 55, 2);
    //Pot MPO9(M2, 8, 1, 50, 1);
    //Pot MPO10(M2, 9, 1, 55, 2);
    //Pot MPO11(M2, 10, 1, 50, 1);
    //Pot MPO12(M2, 11, 1, 55, 2);
    //Pot MPO13(M2, 12, 1, 50, 1);
    //Pot MPO14(M2, 13, 1, 55, 2);
    //Pot MPO15(M2, 14, 1, 50, 1);
    //Pot MPO16(M2, 15, 1, 55, 2);
    //*******************************************************************
    //Add multiplexed pots used to array below like this->  Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
    Pot *MUXPOTS[] {};
    //*******************************************************************
    
    
    void setup() {
    
       MIDI1.begin();
         
    }
    void loop() {
                
        if (NUMBER_BUTTONS != 0) updateButtons();
        if (NUMBER_POTS != 0) updatePots();
        if (NUMBER_MUX_BUTTONS != 0) updateMuxButtons();
    //  if (NUMBER_MUX_POTS != 0) updateMuxPots(); // we'll cross that bridge when we get to it...
    }
    
    //*****************************************************************
    void updateButtons() {
     
      // Cycle through Button array
      for (int i = 0; i < NUMBER_BUTTONS; i = i + 1) {
        byte message = BUTTONS[i]->getValue();
    
        //  Button is pressed
        if (message == 0) {
          switch (BUTTONS[i]->Bcommand) {
            case 0: //Note
              MIDI1.sendNoteOn(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
              break;
            case 1: //CC
              MIDI1.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
              break;
            case 2: //Toggle
              if (BUTTONS[i]->Btoggle == 0) {
                MIDI1.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
                BUTTONS[i]->Btoggle = 1;
              }
              else if (BUTTONS[i]->Btoggle == 1) {
                MIDI1.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
                BUTTONS[i]->Btoggle = 0;
              }
              break;
          }
        }
    
        //  Button is not pressed
        if (message == 1) {
          switch (BUTTONS[i]->Bcommand) {
            case 0:
              MIDI1.sendNoteOff(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
              break;
            case 1:
              MIDI1.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
              break;
          }
        }
      }
    }
    
    //*******************************************************************
    
    void updateMuxButtons() {
    
      // Cycle through Mux Button array
      for (int i = 0; i < NUMBER_MUX_BUTTONS; i = i + 1) {
    
        MUXBUTTONS[i]->muxUpdate();
        byte message = MUXBUTTONS[i]->getValue();
    
        //  Button is pressed
        if (message == 0) {
          switch (MUXBUTTONS[i]->Bcommand) {
            case 0: //Note
              MIDI1.sendNoteOn(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
              break;
            case 1: //CC
              MIDI1.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
              break;
            case 2: //Toggle
              if (MUXBUTTONS[i]->Btoggle == 0) {
                MIDI1.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
                MUXBUTTONS[i]->Btoggle = 1;
              }
              else if (MUXBUTTONS[i]->Btoggle == 1) {
                MIDI1.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
                MUXBUTTONS[i]->Btoggle = 0;
              }
              break;
          }
        }
        //  Button is not pressed
        if (message == 1) {
          switch (MUXBUTTONS[i]->Bcommand) {
            case 0:
              MIDI1.sendNoteOff(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
              break;
            case 1:
              MIDI1.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
              break;
          }
        }
      }
    }
    //***********************************************************************
    void updatePots() {
    
      for (int i = 0; i < NUMBER_POTS; i = i + 1) {
        
        byte potmessage = POTS[i]->getValue();
     
         if (potmessage != 255) switch (POTS[i]->PmidiPort) {
            case 0:
               MIDI1.sendControlChange(POTS[i]->Pcontrol,potmessage, POTS[i]->Pchannel);
               break;
             case 1:
               MIDI1.sendControlChange(POTS[i]->Pcontrol,potmessage, POTS[i]->Pchannel);
               break;
          }
        }
      }
    
    
    //***********************************************************************
    
    void updateMuxPots() {
      for (int i = 0; i < NUMBER_MUX_POTS; i = i + 1) {
        MUXPOTS[i]->muxUpdate();
        byte potmessage = MUXPOTS[i]->getValue();
        if (potmessage != 255) MIDI1.sendControlChange(MUXPOTS[i]->Pcontrol, potmessage, MUXPOTS[i]->Pchannel);
      }
    }
    for the sake of posting the full picture, here's Controller.cpp
    Code:
    #include "Controller.h"
    
    //****************************************************************************************
    Mux::Mux(byte outpin_, byte numPins_, bool analog_)
    {
      outpin = outpin_;
      
      numPins = numPins_;
      analog = analog_;
      if (analog == false) pinMode(outpin, INPUT_PULLUP);
      
      pinMode(22, OUTPUT);
      pinMode(23, OUTPUT);
      pinMode(24, OUTPUT);
      pinMode(25, OUTPUT);
      pinMode(26, OUTPUT);
      pinMode(27, OUTPUT);
    }
    //****************************************************************************************
    //Button (Pin Number, Command, Note Number, Channel, Debounce Time)
    Button::Button(byte pin, byte command, byte value, byte channel, byte debounce)
    {
      _pin = pin;
      pinMode(_pin, INPUT_PULLUP);
      _value = value;
      _command = command;
      _debounce = debounce;
      _time = 0;
      _busy = false;
      _status = 0b00000010;
      _last = 1;
      Bcommand = command;
      Bvalue = value;
      Bchannel = channel;
      Btoggle = 0;
    }
    //****************************************************************************************
    
    Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
    {
      _pin = mux.outpin;
      _numMuxPins = mux.numPins;
      _muxpin = muxpin;
      _value = value;
      _command = command;
      _debounce = debounce;
      _time = 0;
      _busy = false;
      _status = 0b00000010;
      _last = 1;
      Bcommand = command;
      Bvalue = value;
      Bchannel = channel;
      Btoggle = 0;
    }
    /* We've commented this out coz this was for use on a UNO
    void Button::muxUpdate()
    {
      byte temp = _muxpin;
      temp = temp << 2;
      if (_numMuxPins > 8) PORTD = PORTD & B11000011;
      else PORTD = PORTD & B11100011;
      PORTD = PORTD | temp;
    }
    */
    
    void Button::muxUpdate()
    {
    // set S pins on MUX in correct value to read value : eg read Y2: S2-S1-S0 = B010
    // pins used on MEGA: 22 (PA0), 23 (PA1), 24 (PA2), (25 (PA3), 26 (PA4), (27 (PA5))
    // set MUX S-pins LOW
    
      PORTA = PORTA & B11000000;
    
    // add value of temp to PORTA (= add value of the required channel, so set the correct pins)
      PORTA = PORTA | _muxpin;
    }
    
    byte Button::getValue()
    {
      // If BUSY bit not set - read button
        if (bitRead(_status, 0) == false) { // If busy false
        if (digitalRead(_pin) == _last) return 2; // If same as last state - exit
      }
    
      // If NEW Bit set - Key just pressed, record time
      if (bitRead(_status, 1) == true) { // If new is true
          bitSet(_status, 0); // Set busy TRUE
          bitClear(_status, 1); // Set New FALSE
          _time = millis();
        return 255;
      }
    
      // Check if debounce time has passed - If no, exit
      if (millis() - _time < _debounce) return 255;
    
      // Debounce time has passed. Read pin to see if still set the same
      // If it has changed back - assume false alarm
      if (digitalRead(_pin) == _last) {
        bitClear(_status, 0); // Set busy false
        bitSet(_status, 1); // Set new true
        return 255;
      }
    
      // If this point is reached, event is valid. return event type
      else {
        bitClear(_status, 0); // Set busy false
        bitSet(_status, 1); // Set new true
        _last = ((~_last) & 0b00000001); // invert _last
        return _last;
      }
    }
    
    void Button::newValue(byte command, byte value, byte channel)
    {
      Bvalue = value;
      Bcommand = command;
      Bchannel = channel;
    }
    //***********************************************************************************
    
    
    //********************************************************************
    Pot::Pot(byte pin, byte command, byte control, byte midiPort, byte channel, int mapInLow, int mapInHigh, byte mapOutLow, byte mapOutHigh)
    {
      _pin = pin;
      _control = control;
      _value = analogRead(_pin);
      _oldValue = _value ;
      Pcommand = command;
      Pcontrol = control;
      PmidiPort = midiPort;
      Pchannel = channel;  
      PmapInLow = mapInLow;
      PmapInHigh = mapInHigh;
      PmapOutLow = mapOutLow; 
      PmapOutHigh = mapOutHigh;
    }
    
    void Pot::muxUpdate()
    {
      byte temp = _muxpin;
      temp = temp << 2;
      if (_numMuxPins > 8) PORTD = PORTD & B11000011;
      else PORTD = PORTD & B11100011;
      //PORTD = PORTD & B11000011;
      PORTD = PORTD | temp;
    }
    
    Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte midiPort, byte channel, int mapInLow, int mapInHigh, byte mapOutLow, byte mapOutHigh)
    //Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
    {
      _pin = mux.outpin;
      _numMuxPins = mux.numPins;
      _muxpin = muxpin;
      _control = control;
      muxUpdate();
      _value = analogRead(_pin);
      _value = _value >> 3;
      _oldValue = _value << 3;
      _value = _value << 3;
      Pcommand = command;
      Pcontrol = control;
      PmidiPort = midiPort;
      Pchannel = channel;
    }
    
    int Pot::getValue(){
      _value = analogRead(_pin);
      _value = _value + analogRead(_pin);
      _value = _value + analogRead(_pin);
      _value = _value + analogRead(_pin);
      _value = _value / 4;
      
      int tmp = (_oldValue - _value);
        if (tmp >= 8 || tmp <= -8) {
        _oldValue = _value  >> 3;
        _oldValue = _oldValue <<3;
        _value = map(_value, PmapInLow, PmapInHigh, PmapOutLow, PmapOutHigh);
        _value =  constrain(_value ,PmapOutLow , PmapOutHigh);
      return _value;
      }
      return 255;
    }
    
    void Pot::newValue(byte command, byte value, byte channel, byte midiPort, int mapInLow, int mapInHigh, byte mapOutLow, byte mapOutHigh) {
    //void Pot::newValue(byte command, byte value, byte channel) {
      Pcommand = command;
      Pcontrol = value;
      Pchannel = channel;
    }
    And here's Controller.h
    Code:
    #ifndef Controller_h
    #define Controller_h
    
    #include <Arduino.h>
    
    //***********************************************************************
    class Mux
    {
      public:
        Mux(byte outpin_, byte numPins_, bool analog_);
        byte outpin;
        byte numPins;
        bool analog;
    };
    //************************************************************************
    //Button (Pin Number, Command, Note Number, Channel, Debounce Time)
    class Button
    {
      public:
        Button(byte pin, byte command, byte value, byte channel, byte debounce);
        Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);
        byte getValue();
        void muxUpdate();
        void newValue(byte command, byte value, byte channel);
        byte Bcommand;
        byte Bvalue;
        byte Bchannel;
        byte Btoggle;
    
      private:
        byte _previous;
        byte _current;
        uint16_t  _time;
        uint16_t  _debounce;
        byte _pin;
        byte _muxpin;
        byte _numMuxPins;
        uint16_t _value;
        byte _command;
        bool _busy;
        byte _status;
        byte _last;
        byte _enablepin;
    };
    
    //*************************************************************************
    class Pot
    //Pot (Pin Number, Command, CC Control, MidiPort, Channel Number, inLow, inHigh, outLow, outHigh)
    {
      public:
        Pot(byte pin, byte command, byte control, byte midiPort, byte channel, int mapInLow, int mapInHigh, byte mapOutLow, byte mapOutHigh);
        Pot(Mux mux, byte muxpin ,byte command, byte control, byte midiPort, byte channel, int mapInLow, int mapInHigh, byte mapOutLow, byte mapOutHigh);
        void muxUpdate();
        void newValue(byte command, byte value, byte midiPort,byte channel, int mapInLow, int mapInHigh, byte mapOutLow, byte mapOutHigh);
        int getValue();
        byte Pcommand;
        byte Pcontrol;
        byte PmidiPort;
        byte Pchannel;
        int PmapInLow;    
        int PmapInHigh;
        byte PmapOutLow;
        byte PmapOutHigh;
    
      private:
        byte _pin;
        byte _muxpin;
        byte _numMuxPins;
        byte _control;
        int _value;
        int _oldValue;
        bool _changed;
        byte _enablepin;
    };
    
    
    //*************************************************************************
    #endif
    The code compiles for and works on a Mega however falls over on both PC's for a Teensy ++2 with :-

    Arduino: 1.8.5 (Windows 7), TD: 1.45, Board: "Teensy++ 2.0, Serial, 16 MHz, US English"

    Build options changed, rebuilding all
    GizMegaController:108: error: declaration of 'Button::Button(Mux, byte, byte, byte, byte, byte)' outside of class is not definition [-fpermissive]
    Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);

    Mama Google led me on a wild goose chase suggesting I get rid of some semicolons.. Hmm

    So, to cut to the chase, how or what do I need to do / learn in order to make it happen?

    Thanks in advance.

  3. #3
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,068
    This line (108) should be a comment:
    Code:
    Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);
    It just documents the order of the arguments to Button().

    Pete

  4. #4
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16
    Doh! Thanks Pete. Looks like I will be able to upload and will prob work. Have a little more soldering to do before can test.

    The IDE ignores that one when compiling for Mega but not so for Teensy?

    So I'm guessing that:-

    GizMegaController:317: warning: array subscript is out of array bounds
    byte potmessage = MUXPOTS[i]->getValue();

    Is like it says, a warning - not picked up compiling for Mega, but is for Teensy?

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,914
    Quote Originally Posted by PatMaximum View Post
    Is like it says, a warning - not picked up compiling for Mega, but is for Teensy?
    In Arduino's File > Preferences you can configure whether Arduino's boards show compiler warnings. You've probably got the default to not show any warnings.

    Teensy ignore that setting. Compiler warnings are always shown.

  6. #6
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16
    Thanks Paul.

    In Arduino's File > Preferences you can configure whether Arduino's boards show compiler warnings. You've probably got the default to not show any warnings.
    Is how I had it set.

    Have more homework to do this end interrupted by travels so am relegated out of the den for some days.

    Cheers.

  7. #7
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16
    Before I start soldering I thought to ask if this makes sense?Click image for larger version. 

Name:	MegaTeensy.jpg 
Views:	5 
Size:	61.6 KB 
ID:	15937

  8. #8
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16
    Have answered my own question here and am gonna use optocouplers as this simplifies the layout given that we're using double side plate thru proto board.
    A benefit is that we're not going to encourage any ground - induced noise. In any case, have to order more parts..

    One design criteria is that we're gonna use the basis of this design in other Midi controllers where pots are needed to send Midi values larger than 0 - 127.

    After a bit of fiddling with Analog input circuitry at the test bench, I thought to share the result:-

    Click image for larger version. 

Name:	IMG_20190219_0002.jpg 
Views:	5 
Size:	33.4 KB 
ID:	15955

    It is advisable that the 10k and 100n be attached as close as possible to the Analog in Pin of the Teensy. In experimental code, using a 5- stage averaging filter followed by Map and Constrain have had useful results getting stable output of 0 - 500 although it is a good idea to use a 22mm pot with a largish knob.

  9. #9
    Banned
    Join Date
    Jan 2019
    Location
    Australia
    Posts
    16
    With respect to Pins 3 and 4 on Teensy 3.2:-
    ...
    MIDI_CREATE_DEFAULT_INSTANCE();
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI1);
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, MIDI2);
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, MIDI3);
    ...
    At this point I'm of the assumption that we can do FOUR Din Midi ports here, and likewise, Seven Din Midi ports on a Teensy 3.5 - 3.6. I've not found any specific info as to whether or not my assumption is correct, and if so are there any caveats before I warm up the soldering iron? The necessary goodies just arrived.
    Thanks in advance

Posting Permissions

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