Another newbee

Tano

Member
Hello I'm new the arduino/teensie world but not to making some effects for music. So I'm new to coding as well.I purchased a teensie 4.1 because I wanted to try
my hand at making a midi peddle. Found some projects on line and successfully breadboarded 2 projects. I came across a project that I want to build and that one gives me errors. I've watched vids on coding and understand a little but not enough. So if there is anyone that might help that would be great.This is the error I keep getting. I also attached the file. It's actually line 59 to 61 that's highlighted

C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino: In function 'void updateMuxButtons()':
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:207:17: warning: array subscript i is outside array bounds of 'Button* [0]' [-Warray-bounds]
207 | MUXBUTTONS->muxUpdate();
| ~~~~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:104:9: note: while referencing 'MUXBUTTONS'
104 | Button *MUXBUTTONS[] {};
| ^~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:208:32: warning: array subscript i is outside array bounds of 'Button* [0]' [-Warray-bounds]
208 | byte message = MUXBUTTONS->getValue();
| ~~~~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:104:9: note: while referencing 'MUXBUTTONS'
104 | Button *MUXBUTTONS[] {};
| ^~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:212:27: warning: array subscript i is outside array bounds of 'Button* [0]' [-Warray-bounds]
212 | switch (MUXBUTTONS->Bcommand) {
| ~~~~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:104:9: note: while referencing 'MUXBUTTONS'
104 | Button *MUXBUTTONS[] {};
| ^~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:226:25: warning: array subscript i is outside array bounds of 'Button* [0]' [-Warray-bounds]
226 | MUXBUTTONS->Btoggle = 0;
| ~~~~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:104:9: note: while referencing 'MUXBUTTONS'
104 | Button *MUXBUTTONS[] {};
| ^~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:222:25: warning: array subscript i is outside array bounds of 'Button* [0]' [-Warray-bounds]
222 | MUXBUTTONS->Btoggle = 1;
| ~~~~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:104:9: note: while referencing 'MUXBUTTONS'
104 | Button *MUXBUTTONS[] {};
| ^~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:233:27: warning: array subscript i is outside array bounds of 'Button* [0]' [-Warray-bounds]
233 | switch (MUXBUTTONS->Bcommand) {
| ~~~~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:104:9: note: while referencing 'MUXBUTTONS'
104 | Button *MUXBUTTONS[] {};
| ^~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino: In function 'void updateMuxPots()':
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:254:14: warning: array subscript i is outside array bounds of 'Pot* [0]' [-Warray-bounds]
254 | MUXPOTS->muxUpdate();
| ~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:131:6: note: while referencing 'MUXPOTS'
131 | Pot *MUXPOTS[] {};
| ^~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:255:32: warning: array subscript i is outside array bounds of 'Pot* [0]' [-Warray-bounds]
255 | byte potmessage = MUXPOTS->getValue();
| ~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:131:6: note: while referencing 'MUXPOTS'
131 | Pot *MUXPOTS[] {};
| ^~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:256:60: warning: array subscript i is outside array bounds of 'Pot* [0]' [-Warray-bounds]
256 | if (potmessage != 255) MIDI.sendControlChange(MUXPOTS->Pcontrol, potmessage, MUXPOTS->Pchannel);
| ~~~~~~~~~^
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\MIDI_Crab_v2.ino:131:6: note: while referencing 'MUXPOTS'
131 | Pot *MUXPOTS[] {};
| ^~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp: In member function 'void Button::muxUpdate()':
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:59:38: error: no match for 'operator&' (operand types are 'PORTDemulation' and 'int')
59 | if (_numMuxPins > 8) PORTD = PORTD & B11000011;
| ~~~~~ ^
| |
| PORTDemulation
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:60:22: error: no match for 'operator&' (operand types are 'PORTDemulation' and 'int')
60 | else PORTD = PORTD & B11100011;
| ~~~~~ ^
| |
| PORTDemulation
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:61:17: error: no match for 'operator|' (operand types are 'PORTDemulation' and 'byte' {aka 'unsigned char'})
61 | PORTD = PORTD | temp;
| ~~~~~ ^ ~~~~
| | |
| | byte {aka unsigned char}
| PORTDemulation
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp: In member function 'byte Button::getValue()':
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:80:24: warning: comparison of integer expressions of different signedness: 'uint32_t' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
80 | if (millis() - _time < _debounce) return 255;
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp: In member function 'void Pot::muxUpdate()':
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:124:38: error: no match for 'operator&' (operand types are 'PORTDemulation' and 'int')
124 | if (_numMuxPins > 8) PORTD = PORTD & B11000011;
| ~~~~~ ^
| |
| PORTDemulation
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:125:22: error: no match for 'operator&' (operand types are 'PORTDemulation' and 'int')
125 | else PORTD = PORTD & B11100011;
| ~~~~~ ^
| |
| PORTDemulation
C:\Users\Guy\Documents\Teensy\MIDI_Crab_v2\Controller.cpp:127:17: error: no match for 'operator|' (operand types are 'PORTDemulation' and 'byte' {aka 'unsigned char'})
127 | PORTD = PORTD | temp;
| ~~~~~ ^ ~~~~
| | |
| | byte {aka unsigned char}
| PORTDemulation

exit status 1

Compilation error: no match for 'operator&' (operand types are 'PORTDemulation' and 'int')
 

Attachments

  • MIDI_Crab_v2.ino
    9.1 KB · Views: 11
This is the error I keep getting. I also attached the file. It's actually line 59 to 61 that's highlighted
Not sure what "controller.h" is, so I can't try to build the project, and maybe this is C++ syntax I'm not familiar with, but line 59 below looks wrong to me.

Code:
Pot *POTS[] {&PO1};

Pot *POTS[] defines a variable named POTS that is an array of pointers to items of type Pot. What is inside the curly brackets are the initial values, and as far as I know there should be an equal sign between them as shown below. In this case, variable POTS will be an array with one element, a pointer to PO1. There are a number of lines like this in the file, so if this one helps, you can change the others, too.

Code:
Pot *POTS[] = {&PO1};
 
Thank you Joe for trying but it didn't work. The same message comes up. I'll keep playing with it though.
 
I posted the attachment. That is the full file.



C++:
#include <MIDI.h>
#include "Controller.h"

/*************************************************************
  MIDI CONTROLLER

  by Notes and Volts
  www.notesandvolts.com
 
  Modified by Nick Leonard & Kai Dornel
  LED Array by Michael Fischer

  Version 1.2 MIDI Crab Edition v2 **Arduino UNO ONLY!**
 *************************************************************/
 
byte BU_LED[6] = { 8, 9, 10, 11, 12, 13 }; //LED Array

MIDI_CREATE_DEFAULT_INSTANCE();

//************************************************************
//***SET THE NUMBER OF CONTROLS USED**************************
//************************************************************
//---How many buttons are connected directly to pins?---------
byte NUMBER_BUTTONS = 6;
//---How many potentiometers are connected directly to pins?--
byte NUMBER_POTS = 1;
//---How many buttons are connected to a multiplexer?---------
byte NUMBER_MUX_BUTTONS = 0;
//---How many potentiometers are connected to a multiplexer?--
byte NUMBER_MUX_POTS = 0;
//************************************************************

//***ANY MULTIPLEXERS? (74HC4067)************************************
//MUX address pins must be connected to Arduino UNO pins 2,3,4,5
//A0 = PIN2, A1 = PIN3, A2 = PIN4, A3 = PIN5
//*******************************************************************
//Mux NAME (OUTPUT PIN, , How Many Mux Pins?(8 or 16) , Is It Analog?);


//Mux M1(10, 16, false); //Digital multiplexer on Arduino pin 10
//Mux M2(A5, 8, true); //Analog multiplexer on Arduino analog pin A0
//*******************************************************************


//***DEFINE DIRECTLY CONNECTED POTENTIOMETERS************************
//Pot (Pin Number, Command, CC Control, Channel Number)
//**Command parameter is for future use**

//Analog Expression Pedal Inputs

Pot PO1(A0, 0, 27, 1);
//Pot PO2(A1, 0, 28, 1);
//Pot PO3(A2, 0, 119, 1);
//Pot PO4(A3, 0, 118, 1);
//Pot PO5(A4, 0, 30, 1);
//Pot PO6(A5, 0, 31, 1);
//*******************************************************************
//Add pots used to array below like this->  Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6};
Pot *POTS[] {&PO1};
//*******************************************************************


//***DEFINE DIRECTLY CONNECTED BUTTONS*******************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
//** Command parameter 0=NOTE  1=CC  2=Toggle CC **


Button BU1(2, 2, 21, 1, 5);
Button BU2(3, 2, 22, 1, 5);
Button BU3(4, 2, 23, 1, 5 );
Button BU4(5, 2, 26, 1, 5 );
Button BU5(6, 2, 25, 1, 5 );
Button BU6(7, 2, 24, 1, 5 );
//Button BU7(8, 1, 64, 1, 5 );
//Button BU8(9, 2, 64, 1, 5 );
//*******************************************************************
//Add buttons used to array below like this->  Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8};
Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6};
//*******************************************************************


//***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, 0, 70, 1, 5);
//Button MBU2(M1, 1, 1, 71, 1, 5);
//Button MBU3(M1, 2, 2, 72, 1, 5);
//Button MBU4(M1, 3, 0, 73, 1, 5);
//Button MBU5(M1, 4, 0, 74, 1, 5);
//Button MBU6(M1, 5, 0, 75, 1, 5);
//Button MBU7(M1, 6, 0, 76, 1, 5);
//Button MBU8(M1, 7, 0, 77, 1, 5);
//Button MBU9(M1, 8, 0, 78, 1, 5);
//Button MBU10(M1, 9, 0, 79, 1, 5);
//Button MBU11(M1, 10, 0, 80, 1, 5);
//Button MBU12(M1, 11, 0, 81, 1, 5);
//Button MBU13(M1, 12, 0, 82, 1, 5);
//Button MBU14(M1, 13, 0, 83, 1, 5);
//Button MBU15(M1, 14, 0, 84, 1, 5);
//Button MBU16(M1, 15, 0, 85, 1, 5);
//*******************************************************************
////Add multiplexed buttons used to array below like this->  Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
Button *MUXBUTTONS[] {};

//*******************************************************************


//***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, 0, 1, 1);
//Pot MPO2(M2, 1, 0, 7, 1);
//Pot MPO3(M2, 2, 0, 50, 1);
//Pot MPO4(M2, 3, 0, 55, 2);
//Pot MPO5(M2, 4, 0, 50, 1);
//Pot MPO6(M2, 5, 0, 55, 2);
//Pot MPO7(M2, 6, 0, 50, 1);
//Pot MPO8(M2, 7, 0, 55, 2);
//Pot MPO9(M2, 8, 0, 50, 1);
//Pot MPO10(M2, 9, 0, 55, 2);
//Pot MPO11(M2, 10, 0, 50, 1);
//Pot MPO12(M2, 11, 0, 55, 2);
//Pot MPO13(M2, 12, 0, 50, 1);
//Pot MPO14(M2, 13, 0, 55, 2);
//Pot MPO15(M2, 14, 0, 50, 1);
//Pot MPO16(M2, 15, 0, 55, 2);
//*******************************************************************
//Add multiplexed pots used to array below like this->  Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
Pot *MUXPOTS[] {};
//*******************************************************************

//Serial specifies the baud rate, this is set up for the Hairless to MIDI converter

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

  }

void loop() {
  if (NUMBER_BUTTONS != 0) updateButtons();
  if (NUMBER_POTS != 0) updatePots();
  if (NUMBER_MUX_BUTTONS != 0) updateMuxButtons();
  if (NUMBER_MUX_POTS != 0) updateMuxPots();
  delay(5);
  for (byte n = 0; n <= NUMBER_BUTTONS; n++) {
    pinMode(BU_LED[n], OUTPUT);
  }
}

//delay added to reduce extraneous data - could be reduced to 1, or raised, to increase or decrease precision. I would leave it at 20 to start

//*****************************************************************
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
          MIDI.sendNoteOn(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
          break;
        case 1: //CC
          MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
          break;
        case 2: //Toggle
          if (BUTTONS[i]->Btoggle == 0) {
            MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
            BUTTONS[i]->Btoggle = 1;           
          }
            else if (BUTTONS[i]->Btoggle == 1) {
            MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
            BUTTONS[i]->Btoggle = 0;
          }
         for (byte n = 0; n <= NUMBER_BUTTONS; n++) {
         digitalWrite(BU_LED[n],LOW);
            }
         digitalWrite(BU_LED[i],HIGH);
          break;
      }
    }

    //  Button is not pressed
    if (message == 1) {
      switch (BUTTONS[i]->Bcommand) {
        case 0:
          MIDI.sendNoteOff(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
          break;
        case 1:
          MIDI.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
          MIDI.sendNoteOn(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
          break;
        case 1: //CC
          MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
          break;
        case 2: //Toggle
          if (MUXBUTTONS[i]->Btoggle == 0) {
            MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
            MUXBUTTONS[i]->Btoggle = 1;
          }
          else if (MUXBUTTONS[i]->Btoggle == 1) {
            MIDI.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:
          MIDI.sendNoteOff(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
          break;
        case 1:
          MIDI.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) MIDI.sendControlChange(POTS[i]->Pcontrol, potmessage, POTS[i]->Pchannel);
      }
}
//***********************************************************************
void updateMuxPots() {
  for (int i = 0; i < NUMBER_MUX_POTS; i = i + 1) {
    MUXPOTS[i]->muxUpdate();
    byte potmessage = MUXPOTS[i]->getValue();
    if (potmessage != 255) MIDI.sendControlChange(MUXPOTS[i]->Pcontrol, potmessage, MUXPOTS[i]->Pchannel);
  }
}

#include "Controller.h"

//****************************************************************************************
Mux::Mux(byte outpin_, byte numPins_, bool analog_)
{
  outpin = outpin_;
  //enablepin = enablepin_;
  numPins = numPins_;
  analog = analog_;
  if (analog == false) pinMode(outpin, INPUT_PULLUP);
  //pinMode(enablepin, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  if (numPins > 8) pinMode(5, 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 = 5;
  _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;
}

void Button::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  PORTD = PORTD | temp;
}

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 channel)
{
  _pin = pin;
  _control = control;
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

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 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;
  Pchannel = channel;
}

byte Pot::getValue()
{
  _value = analogRead(_pin);
  int tmp = (_oldValue - _value);
  if (tmp >= 8 || tmp <= -8) {
    _oldValue = _value >> 3;
    _oldValue = _oldValue << 3;
    return _value >> 3;
  }
  return 255;
}

void Pot::newValue(byte command, byte value, byte channel) {
  Pcommand = command;
  Pcontrol = value;
  Pchannel = channel;
}

#include "Controller.h"

//****************************************************************************************
Mux::Mux(byte outpin_, byte numPins_, bool analog_)
{
  outpin = outpin_;
  //enablepin = enablepin_;
  numPins = numPins_;
  analog = analog_;
  if (analog == false) pinMode(outpin, INPUT_PULLUP);
  //pinMode(enablepin, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  if (numPins > 8) pinMode(5, 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 = 5;
  _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;
}

void Button::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  PORTD = PORTD | temp;
}

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 channel)
{
  _pin = pin;
  _control = control;
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

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 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;
  Pchannel = channel;
}

byte Pot::getValue()
{
  _value = analogRead(_pin);
  int tmp = (_oldValue - _value);
  if (tmp >= 8 || tmp <= -8) {
    _oldValue = _value >> 3;
    _oldValue = _oldValue << 3;
    return _value >> 3;
  }
  return 255;
}

void Pot::newValue(byte command, byte value, byte channel) {
  Pcommand = command;
  Pcontrol = value;
  Pchannel = channel;
}
 
59 if (_numMuxPins > 8) PORTD = PORTD & B11000011;
60 else PORTD = PORTD & B11100011;
61 PORTD = PORTD | temp;

These are the lines that are highlighted. Theres always a curser blinking after if (
 
This is correct C++: Pot *POTS[]{&PO1};

It’s the direct list initializer form and is my personal preference.
 
MIDI_Crab_v2.ino in attachment above is incomplete in that two Tabs are missing. These would be named Controller.cpp and Controller.h. Most compile errors in the OP are a consequence of those missing tabs.

The sketch looks like (part) of a modified version of Notes and Volts MIDI_Controller_v1-2 attached here as a Zip for reference.

Errors relating to PORTD:- PORTD is used to generate Select signals for 4067 Multiplexer(s). Teensy4.1 does not have any PORTD so code modifications are necessary to get this to work assuming that you actually need to use multiplexers.

If you manage to get it working you will most likely run into trouble with noisy Pot readings.
Hardware and layout come into play here but more significantly, the code does not have any Oversampling so my suggestion would be to look in the IDE>Examples>Teensy>USB_MIDI>ManyButtonKnobs and tweak the code to send via SerialMIDI.

You might give us an idea of what you are trying to achieve like how many Pots and Buttons you want to use.
 

Attachments

  • MIDI_Controller_v1-2.zip
    3.7 KB · Views: 6
Thanks for the info Matrix. There are 6 buttons with led indicators and 2 ports for expression peddles. That would be the pots. Sorry about the missing files I thought I included them.

Code:
#include "Controller.h"

//****************************************************************************************
Mux::Mux(byte outpin_, byte numPins_, bool analog_)
{
  outpin = outpin_;
  //enablepin = enablepin_;
  numPins = numPins_;
  analog = analog_;
  if (analog == false) pinMode(outpin, INPUT_PULLUP);
  //pinMode(enablepin, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  if (numPins > 8) pinMode(5, 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 = 5;
  _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;
}

void Button::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTD = PORTD & B11000011;
  else PORTD = PORTD & B11100011;
  PORTD = PORTD | temp;
}

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 channel)
{
  _pin = pin;
  _control = control;
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

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 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;
  Pchannel = channel;
}

byte Pot::getValue()
{
  _value = analogRead(_pin);
  int tmp = (_oldValue - _value);
  if (tmp >= 8 || tmp <= -8) {
    _oldValue = _value >> 3;
    _oldValue = _oldValue << 3;
    return _value >> 3;
  }
  return 255;
}

void Pot::newValue(byte command, byte value, byte channel) {
  Pcommand = command;
  Pcontrol = value;
  Pchannel = channel;
}


#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;
    unsigned long _time;
    int _debounce;
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _value;
    byte _command;
    bool _busy;
    byte _status;
    byte _last;
    byte _enablepin;
};
//*************************************************************************
class Pot
{
  public:
    Pot(byte pin, byte command, byte control, byte channel);
    Pot(Mux mux, byte muxpin ,byte command, byte control, byte channel);
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte getValue();
    byte Pcommand;
    byte Pcontrol;
    byte Pchannel;

  private:
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _control;
    int _value;
    int _oldValue;
    bool _changed;
    byte _enablepin;
};
//*************************************************************************
#endif
 
I do have another program that works. It just has the buttons, so I've been watching vids on coding and slowly understanding how to program the led's to turn off when anther button is pressed. I'm using momentary switches so I can't bypass coding to run them.

Thanks for all your help. I thought I might be able to make that midi crab code work. Time to move on.
 
Thanks again Matrix for pointing out the example files.Although I briefly looked at it before I really didn't pay attention to it. I took the example you mentioned and reworked it for what I wanted. Now I just need to configure the leds .Still working on that.
 
Back
Top