tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.23k stars 137 forks source link

Expander MCP23017 #155

Open forsakenrecordingstudios opened 4 years ago

forsakenrecordingstudios commented 4 years ago

Hello,

I am trying to add 3 of these Mux to my sketch, how do i get this Mux added to your library? Also im told i can run all 3 on 1 interrupt, do you have any insight on this?


#include <Encoder.h> // Include the Encoder library.

// Include the library
#include <Control_Surface.h>

// Instantiate a MIDI Interface to use
USBMIDI_Interface midi;

// Buttons
const int LF = A0;
const int MF = A1;
const int HF = A2;
const int LC = A3;
const int LMF = A4;
const int HMF = A5;
const int HC = A6;
const int ShowCurve = A7;
const int HighQuality = A8;
const int GainAuto = A9;

// LEDS
//const int LFLED = 44;
//const int MFLED = 45;
//const int HFLED = 46;
//const int LCLED = 47;
//const int LMFLED = 48;
//const int HMFLED = 49;
//const int HCLED = 50;
//const int ShowCurveLED = 51;
//const int HighQualityLED = 52;
//const int GainAutoLED = 53;

const pin_t ledPins[] =  {44, 45, 46, 47, 48, 49, 50, 51, 52, 53};

//Encoders
int LFQa = 2;
int LFQb = 3;

// Instantiate an analog multiplexer
MCP23017 mux1 = {
  2,       // Digital input pin
  {A10, A11} // Address pins 
};

CCRotaryEncoder knob1 [] = {
  {mux.pin(6), {MIDI_CC::Channel_Volume, CHANNEL_7}},
  {mux.pin(7), {MIDI_CC::Channel_Volume, CHANNEL_8}},

};

 //Freq Activation
CCButtonLatched buttons[] =  {
  {LF, MCU::SOLO_1},
  {MF, MCU::SOLO_2},
  {HF, MCU::SOLO_3},
  {LC, MCU::SOLO_4},
  {LMF, MCU::SOLO_5},
  {HMF, MCU::SOLO_6},
  {HC, MCU::SOLO_7},
  {ShowCurve, MCU::SOLO_8},
  {HighQuality, MCU::MUTE_1},
  {GainAuto, MCU::MUTE_2},

};

//CCRotaryEncoder enc1 = {
  //{LFQa, LFQb}, 
  //MIDI_CC::Pan,
  //1,

//};

//CCPotentiometer potentiometer = {
 // A10, {MIDI_CC::Channel_Volume, CHANNEL_1}

};

// Initialize the Control Surface
void setup() {

   // Add the mapping function to the potentiometer
    //potentiometer.map(mappingFunction);

 //LED Controll
 for (pin_t ledPin : ledPins)
    pinMode(ledPin, OUTPUT);

 //Encoders
    pinMode(LFQa, INPUT_PULLUP);
    pinMode(LFQb, INPUT_PULLUP);

  // Use the Mackie Control protocol for sending relative MIDI CC messages.
  RelativeCCSender::setMode (TWOS_COMPLEMENT);
  Serial.begin(115200);
  Control_Surface.begin(); // Initialize Control Surface
  //Control_Surface.setMIDIInputCallbacks(channelMsgCallback, nullptr, nullptr); //MIDI Read
}

//Led Controll
template <class T, size_t N> 
constexpr size_t len(const T (&)[N]) { return N; }

// Update the Control Surface
void loop() {

// Update the control surface
  Control_Surface.loop();

 //LED Controll
 static_assert(len(ledPins) == len(buttons), "Use the same number of LEDs as the number of buttons!");
  for (size_t i = 0; i < len(buttons); ++i)
    digitalWrite(ledPins[i], buttons[i].getState());
}
tttapa commented 4 years ago

As mentioned in your previous thread, you cannot use CCRotaryEncoder on a mux. The encoders are handled by the PJRC encoder library, which is incompatible with the ExtIO modules that add multiplexer support.

The MCP23017 is not a multiplexer (mux), it's an I²C IO expander, and the Control Surface library doesn't have a MCP23017 class. Even if it did, you still wouldn't be able to use it with the PJRC encoder library.

If you want to use encoders with an MCP23017, you'll have to handle the encoder and the MCP23017 yourself, and use the RelativeCCSender::send or Control_Surface.sendCC functions to translate encoder movement into MIDI messages.

Most Arduinos don't have I²C libraries that are usable inside of ISRs, so the "interrupt" pin cannot be used as a true interrupt that reads and updates the encoder state immediately, you can only use it to detect changes, and handle them later.

Joshbas1 commented 4 years ago

Para encoder con mux debes usar 2 mux, luego, un pin del encoder a un pin del pirmer mux, centro a gnd y el otro pin al 2 mux. Los pines de los muxes que no uses conectalos a gnd para que no metan ruido.

Busca una libreria para tu ic expansor y pruebas haber que tal va

forsakenrecordingstudios commented 4 years ago

Okay,

So if was to also include the correct library inside yours for this expander. Would i be setting up the expanders. Then type the expanders pins into your code? Would that work still?
tttapa commented 4 years ago

Okay,

So if was to also include the correct library inside yours for this expander. Would i be setting up the expanders. Then type the expanders pins into your code? Would that work still?

No. That's impossible because encoders are handled using the PJRC Encoder library. The Encoder library has no idea what a MCP23017 is. I just uses digitalRead and attachInterrupt etc. which is only valid for Arduino pins.

forsakenrecordingstudios commented 4 years ago

Hello,

So if i was to purchase 3 CD74HC4067 multiplexers, i will be able to use 23 encoders on my Arduino Mega R3 with your library using your Mux setup? I have 6 interrupt pins on my board.

forsakenrecordingstudios commented 4 years ago

https://www.amazon.com/HiLetgo-CD74HC4067-Channel-Multiplexer-Breakout/dp/B01DLHKLNE

tttapa commented 4 years ago

No, you can only use encoders with pins of the Arduino itself, preferably interrupt pins.

Polling 23 encoders might be too slow, especially when adding other functions to your code as well, like analog inputs.

See this issue, for example: https://github.com/tttapa/Control-Surface/issues/83#issuecomment-589825663
He got 16 encoders to work on a Teensy 3.5 eventually, because it has interrupt capabilities on all pins, but the Arduino Mega was too slow and didn't have enough interrupt pins to handle that.

When using multiplexers, the number of interrupt pins is irrelevant, because multiplexers don't have a way to detect if a pin has changed state. You would need a lot of logic chips to detect that. At that point, you might as well upgrade to a suitable microcontroller.

forsakenrecordingstudios commented 4 years ago

Okay,

So definitely stick with the Expander MCP23017 and figure it out so i can utilize this board and all those encoders.
forsakenrecordingstudios commented 4 years ago

So what is the largest board with the most amount of interrupt pins and is also usb native?

tttapa commented 4 years ago

The Arduino Due has 54 interrupt-capable input pins, and native USB support, but it's not very well supported, it's clearly not Arduino's main focus.
Teensy has better software support in my experience. Teensy 3.5 and 3.6 both have 58 digital pins with interrupt capabilities, but only 40 of them are breadboard-accessible.

The advantage of using ARM-based Arduinos is that they tend to have much more advanced I2C hardware peripherals, which can relatively easily be used from within an ISR. This is not possible on an Arduino UNO, for example (definitely not with the default Wire driver, maybe not at all).
Being able to use I2C in an ISR means that you could use a MCP23017 to read an encoder with interrupts.

I've never tried this, and even though it seems possible when reading the documentation from the i2c_t3 library, there might be some details I'm missing.

I'm experimenting with rotary encoders on a MCP23017 with an Arduino UNO, and using a single MCP23017 with 8 encoders seems to work fine, as long as you don't have any code in your loop that blocks for more than a couple of hundreds of microseconds.
23 encoders without anything else might just work, but adding 8 potentiometers is probably not going to work.
I'll try to post the code later today.

forsakenrecordingstudios commented 4 years ago

Thank you so much for everything

Yes i saw a guy running 60 encoders using these daisy chained together on a mega. But he did not explain or show how he did it. Yes if you could please send some examples that woukd be amazing. I am so lost with even getting 1 encoder to operate through the MCP23017 in the library

tttapa commented 4 years ago

I added some examples:

The code is here if you're interested: https://github.com/tttapa/Arduino-Helpers/blob/c502f63c73a3f1a76355db1b832ffb9bd95c16cf/src/AH/Hardware/MCP23017Encoders.hpp

You have to use the share-encoder branch of the library.

forsakenrecordingstudios commented 4 years ago

thank you trying this out now. says im missing this though?

include <AH/Hardware/MCP23017Encoders.hpp>

forsakenrecordingstudios commented 4 years ago

`Arduino: 1.8.12 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\forsa\OneDrive\Documents\Arduino\libraries -fqbn=arduino:avr:mega:cpu=atmega2560 -vid-pid=0X2341_0X0001 -ide-version=10812 -build-path C:\Users\forsa\AppData\Local\Temp\arduino_build_898589 -warnings=none -build-cache C:\Users\forsa\AppData\Local\Temp\arduino_cache_930879 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\forsa\OneDrive\Documents\Arduino\MCP23017_Test\MCP23017_Test.ino C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\forsa\OneDrive\Documents\Arduino\libraries -fqbn=arduino:avr:mega:cpu=atmega2560 -vid-pid=0X2341_0X0001 -ide-version=10812 -build-path C:\Users\forsa\AppData\Local\Temp\arduino_build_898589 -warnings=none -build-cache C:\Users\forsa\AppData\Local\Temp\arduino_cache_930879 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\forsa\OneDrive\Documents\Arduino\MCP23017_Test\MCP23017_Test.ino Using board 'mega' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr Detecting libraries used... "C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\mega" "C:\Users\forsa\AppData\Local\Temp\arduino_build_898589\sketch\MCP23017_Test.ino.cpp" -o nul Alternatives for Control_Surface.h: [Control-Surface-1.1.1@1.1.1 Control-Surface-share-encoder@1.1.1] ResolveLibrary(Control_Surface.h) -> candidates: [Control-Surface-1.1.1@1.1.1 Control-Surface-share-encoder@1.1.1] "C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\mega" "-IC:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1\src" "C:\Users\forsa\AppData\Local\Temp\arduino_build_898589\sketch\MCP23017_Test.ino.cpp" -o nul Alternatives for SPI.h: [SPI@1.0] ResolveLibrary(SPI.h) -> candidates: [SPI@1.0] "C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\mega" "-IC:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "C:\Users\forsa\AppData\Local\Temp\arduino_build_898589\sketch\MCP23017_Test.ino.cpp" -o nul Alternatives for SoftwareSerial.h: [SoftwareSerial@1.0] ResolveLibrary(SoftwareSerial.h) -> candidates: [SoftwareSerial@1.0] "C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega2560 -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_MEGA2560 -DARDUINO_ARCH_AVR "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\mega" "-IC:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src" "-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\src" "C:\Users\forsa\AppData\Local\Temp\arduino_build_898589\sketch\MCP23017_Test.ino.cpp" -o nul Alternatives for AH/Hardware/MCP23017Encoders.hpp: []MCP23017_Test:3:10: fatal error: AH/Hardware/MCP23017Encoders.hpp: No such file or directory

ResolveLibrary(AH/Hardware/MCP23017Encoders.hpp) #include <AH/Hardware/MCP23017Encoders.hpp>

-> candidates: [] ^~~~~~~~~~

compilation terminated.

Multiple libraries were found for "Control_Surface.h" Used: C:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1 Not used: C:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-share-encoder Using library Control-Surface-1.1.1 at version 1.1.1 in folder: C:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1 Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI Using library SoftwareSerial at version 1.0 in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial exit status 1 AH/Hardware/MCP23017Encoders.hpp: No such file or directory`

tttapa commented 4 years ago

Multiple libraries were found for "Control_Surface.h" Used: C:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1 Not used: C:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-share-encoder Using library Control-Surface-1.1.1 at version 1.1.1 in folder:

It's using the wrong version of Control Surface. You have to delete the folder C:\Users\forsa\OneDrive\Documents\Arduino\libraries\Control-Surface-1.1.1.

forsakenrecordingstudios commented 4 years ago

sorry deleted the original library and it compiled.

forsakenrecordingstudios commented 4 years ago

I copied and pasted the example and changed the interrupt pin to the correct one but no action is happening. Im sorry for being a pest. Im guessing it is the communication pins (SDA/SCL).

tttapa commented 4 years ago

It's probably best to try some examples (a single button, a single LED) with the Adafruit_MCP23017 library first, to make sure your wiring is correct.

tttapa commented 4 years ago

Also note that the examples use the USBDebugMIDI_Interface. It won't send actual MIDI, it'll print the MIDI messages to the serial monitor.

forsakenrecordingstudios commented 4 years ago

okay ill try that. and i was using the serial monitor.

forsakenrecordingstudios commented 4 years ago

2020-04-09

forsakenrecordingstudios commented 4 years ago

strange the button shows no communication also.

tttapa commented 4 years ago

The ground and power connections for the MCP23017 are missing, and you seem to have swapped SDA and SCL the wrong way around.

forsakenrecordingstudios commented 4 years ago

Forsaken Pro EQ

forsakenrecordingstudios commented 4 years ago

opps. i did have the SDA and SCL swapped. I had a bad PDF of the layout. I do have it grounded and powered though. I just didnt finish the sketch. But this would be the complete sketch correctly though?

tttapa commented 4 years ago

That looks alright, apart from the lack of current limiting resistors on the LEDs. You need those or they'll burn out.

forsakenrecordingstudios commented 4 years ago

so strange, copy and pasted code and changed interrupt pin, wired up exactly as sketch. still zero communication.

`#include

include <AH/Hardware/MCP23017Encoders.hpp>

include <MIDI_Outputs/Abstract/MIDIRotaryEncoder.hpp>

include

// Type for the MCP23017 encoders (translates encoder pulses to position) using WireType = decltype(Wire); // The type of I²C driver to use using EncoderPositionType = int32_t; // The type for saving encoder positions constexpr bool IntSafe = true; // Make it safe to call update in an ISR using MCPEncoderType = MCP23017Encoders<WireType, EncoderPositionType, IntSafe>;

// Type for the MIDI encoders (translates position to MIDI messages) struct CCMCPEncoder : GenericMIDIRotaryEncoder<MCPEncoderType::MCP23017Encoder, RelativeCCSender> { CCMCPEncoder(MCPEncoderType::MCP23017Encoder enc, MIDIAddress address, int16_t multiplier = 1, uint8_t pulsesPerStep = 4) : GenericMIDIRotaryEncoder(std::move(enc), address, multiplier, pulsesPerStep, {}) {} };

USBDebugMIDI_Interface midi;

const uint8_t interrupt_pin = 2;

// Create an object that manages the 8 encoders connected to the MCP23017. MCPEncoderType enc = {Wire, 0x0, interrupt_pin}; // │ │ └─ Interrupt pin // │ └────── Address offset // └──────────── I²C interface

// Instantiate 8 MIDI rotary encoders. CCMCPEncoder ccencoders[] = { { enc[0], // The encoder to use MCU::V_POT_1, // The MIDI address 1, // Encoder speed multiplier 4, // Number of pulses per physical "click" of the encoder }, {enc[1], MCU::V_POT_2}, {enc[2], MCU::V_POT_3}, {enc[3], MCU::V_POT_4}, {enc[4], MCU::V_POT_5}, {enc[5], MCU::V_POT_6}, {enc[6], MCU::V_POT_7}, {enc[7], MCU::V_POT_8}, };

void isr() { enc.update(); // Read the state of the encoders and update the positions }

void setup() { Control_Surface.begin(); Wire.begin(); // Must be called before enc.begin() Wire.setClock(800000); enc.begin(); // Initialize the MCP23017 attachInterrupt(digitalPinToInterrupt(interrupt_pin), isr, LOW); }

void loop() { // No enc.update() here, updating the encoders happens inside of the ISR Control_Surface.loop(); }`

forsakenrecordingstudios commented 4 years ago

would i possibly need to do something special for the mega so the code knows what SDA and SCL pins to use?

tttapa commented 4 years ago

Did you try the Adafruit examples?

forsakenrecordingstudios commented 4 years ago

yes and still zero communication. and every example for these are with the uno and i have a mega that has dedicated SDA and SCL pins.

tttapa commented 4 years ago

That might be because you don't have any pull-up resistors on the I²C bus. I don't know if the AVR Wire library enables them automatically. Try adding pull-up resistors of 4k7Ω or so to the SDA and SCL lines.

ciapamusche commented 4 years ago

Im tryng to use the expander for have 8 buttons with 8 led (not yet implemented in the code)

for now i have only 3 button attached on expander and 1 on the board with different midi channels.

my code compile and load but when i press mcp button no message is sent if i press the 0 button al 4l midi CC are sent togheter. Where im wrong?

#include <Wire.h>
#include <Adafruit_MCP23008.h>
#include <Control_Surface.h> // Include the Control Surface library
Adafruit_MCP23008 mcp;
// Instantiate a MIDI over USB interface.
USBSerialMIDI_Interface midi = 115200;

//MCP23017 buttons
CCButtonLatched MCPbuttons[] = {
 {mcp.digitalRead(8),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_16}},
 {mcp.digitalRead(9),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_15}},
 {mcp.digitalRead(10),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_14}},
 //{mcp.digitalRead(11),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_13}},
 //{mcp.digitalRead(12),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_12}},
 //{mcp.digitalRead(13),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_11}},
 //{mcp.digitalRead(14),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_10}},
 //{mcp.digitalRead(15),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_9}},
};

// Instantiate a CCButton object
CCButtonLatched play = {
  // Push button on pin 0:
  0,
  // General Purpose Controller #1 on MIDI channel 1:
  {MIDI_CC::General_Purpose_Controller_8, CHANNEL_16},
};

void setup() {
  pinMode (0,INPUT);
  mcp.begin();      // use default address 0
  mcp.pinMode(8, INPUT);
  mcp.pullUp(8, HIGH);  // turn on a 100K pullup internall
  mcp.pinMode(9, INPUT);
  mcp.pullUp(9, HIGH);  // turn on a 100K pullup internal
  mcp.pinMode(10, INPUT);
  mcp.pullUp(10, HIGH);  // turn on a 100K pullup internall
  pinMode(LED_BUILTIN,OUTPUT);
Control_Surface.begin();
}

void loop() {
  Control_Surface.loop(); // Update the Control Surface
    digitalWrite(LED_BUILTIN, !play.getState());

}

i executed the i2c scanner succesfully

tttapa commented 4 years ago
 {mcp.digitalRead(8),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_16}},

This line is meaningless. If you look in the documentation, the first constructor argument is the pin number to read from. mcp.digitalRead doesn't return a pin number.

You're not allowed to call mcp.digitalRead before calling mcp.begin, so it'll probably return 0, hence the CCButtonLatched objects you create will be configured to read from pin 0.

There is no out-of-the-box MCP23017 ExtIO support (only for encoders), if you want to use it with the library, you'll have to write an adapter of the ExtendedIOElement that calls the appropriate MCP23017 functions.
You'll have to create a class that inherits from ExtendedIOElement and implements all pure virtual methods.

ciapamusche commented 4 years ago

Thank you…. There is a document where i can see an example to modify?

a good point can be MCP23017Encoders.hpp?

for now seems to be faster use a multiplexer to do it… i have one and i tried this

//#include <Wire.h>
//#include <Adafruit_MCP23008.h>
#include <Control_Surface.h> // Include the Control Surface library
//Adafruit_MCP23008 mcp;
// Instantiate a MIDI over USB interface.
HairlessMIDI_Interface midi;

//const pin_t ledPins[] =  {0, 1, 2, 3, 4, 5, 6, 7};

CD74HC4067 mux = { 
  A0,               
  {14, 12, 13, 15},   
};

CCButtonLatched buttons[] = {
 {mux.pin(0),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_16}},
 {mux.pin(1),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_15}},
 {mux.pin(2),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_14}},
 {mux.pin(3),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_13}},
 {mux.pin(4),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_12}},
 {mux.pin(5),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_11}},
 {mux.pin(6),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_10}},
 {mux.pin(7),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_9}},
 {mux.pin(8),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_8}},
 {mux.pin(9),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_7}},
 {mux.pin(10),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_6}},
 {mux.pin(11),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_5}},
 {mux.pin(12),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_4}},
 {mux.pin(13),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_3}},
 {mux.pin(14),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_2}},
 {mux.pin(15),{MIDI_CC::General_Purpose_Controller_7, CHANNEL_1}},
};

// Instantiate a CCButton object
CCButtonLatched play = {
  // Push button on pin 0:
  0,
  // General Purpose Controller #1 on MIDI channel 1:
  {MIDI_CC::General_Purpose_Controller_8, CHANNEL_16},
};

void setup() {
  pinMode (0,INPUT);
  pinMode(LED_BUILTIN,OUTPUT);
  Control_Surface.begin(); // Initialize Control Surface

Control_Surface.begin();
}

//template <class T, size_t N> 
//constexpr size_t len(const T (&)[N]) { return N; }

void loop() {
  Control_Surface.loop(); // Update the Control Surface
    digitalWrite(LED_BUILTIN, !play.getState());

}

`

It compile but the latching buttons didnt works No midi output. If i use the example of potentiometer everything seems works except a very amount of the noise and my trimmer (10K) which dont regulate. I try to pull the input to 3.3 and GND with a pullup resistor and seems to change from 0 to 127

why cannot work with latched?

tttapa commented 4 years ago

An example of an ExtendedIOElement implementation is the AnalogMultiplex class: https://github.com/tttapa/Control-Surface/blob/master/src/AH/Hardware/ExtendedInputOutput/AnalogMultiplex.hpp
MCP23017Encoders does not implement ExtendedIOElement.

Does the play button work? Does the LED toggle when you press it?
There are two calls to Control_Surface.begin() in your setup, that could be a problem.

What board are you using?

Having a lot of noise on the analog inputs is not normal. The potentiometer should be pretty much noise free. Check your connections and power supply. What do you mean by "my trimmer (10K) which dont regulate"?

If you are positive that your multiplexer and switches are connected correctly, verify this using the DigitalReadSerial example.

If your MIDI sketch still doesn't work, use the USBDebugMIDI_Interface instead of the HairlessMIDI_Interface, and check the output in the serial monitor.

ciapamusche commented 4 years ago

Hi. I did a little step. I had a problem with trimmers . When regulate the Potentiometer to have 3.3v on Analog pin (turning at the potentiometer at very fullscale) the Value became noisy sending continuous message between 120 and 127 . Added a resistor in series to the trimmer in order to not go under a certain value . It seems to work. Tested also with midi hairless now i can trim from 0 to 127 (tried only 2 channels but i hope it works with the other) very stable.

I cannot get work instead the sketch with CClatched OR CCbuttons. No response.

The Blue led and Play button works in every situation.

The Example Not work. ive got 0 in all channels. Tied to ground nothing happens. Tied To 3,3 Nothing Happens.

Tried to:

Change Sig GPIO of ESP from A0 to 10 (digital input like the example) (i've Got 1 in All channel) Set Pinmode input on 10 (1 in All channel) Set Pinmode input pullup on 10 (1 in all channel)

My board is ESP8266 NodeMCU and i use the 3.3 from nodeMCU regulator for the MUX.

tttapa commented 4 years ago

The Example Not work. ive got 0 in all channels. Tied to ground nothing happens. Tied To 3,3 Nothing Happens.

That's because you used the analog input of the ESP. It's not a GPIO pin, you cannot use it for digital signals, and it doesn't have a pull-up resistor.

Change Sig GPIO of ESP from A0 to 10 (digital input like the example) (i've Got 1 in All channel)

Yes, that should work. If your wiring is correct, one of the channels should drop to zero when pressing a button.
Don't set the pinmode yourself, Control Surface will take care of it.

ciapamusche commented 4 years ago

So... maybe i found the problem. I have a Lolin NodeMCU V3 with CH340 chip

I loaded the same identical sketch on NodeMCU with CP2120 chip and everything works correctly. Latching button works as expected.

I tried to load in another 2 Lolin Node MCU V3 with CH340 and doesn’t work. Same situation.

After some tries it reset

ets Jan 8 2013,rst cause:4, boot mode:(3,7)

wdt reset load 0x4010f000, len 3456, room 16 tail 0 chksum 0x84 csum 0x84 va5432625 ~ld

Any ideas ?

tttapa commented 4 years ago

I don't know, I don't see how the USB-TTL converter could cause watchdog timeouts. I don't have the right hardware with me to test it myself right now.

ciapamusche commented 4 years ago

the problem is not relevant. ch340 NodeMCU are very old.

Now i will come back to the original theme of this thread.. tryng to create a class for gettin work MCP23017 as Extender (input and output). I think is a good improvement for the project. one of thise allow you to have 16 extra Gpios

I will stress you again. Thank you very much for your work