Arduino Forum

International => Español => Hardware => Topic started by: roxo on Dec 06, 2018, 12:36 am

Title: 21 Potenciometros en proyecto midi (SOLUCIONADO)
Post by: roxo on Dec 06, 2018, 12:36 am
hola a todos, debo decir que este es mi primer proyecto arduino, por necesidad, armé un controlador midi siguiendo las instrucciones de MusicoNerd, bueno, yo de programar se casi nada, estoy recién viendo cosas muy básicas, y bueno, este codigo, a prueba y error, lo fui modificando para mis necesidades, la cosa es que necesito 19 potenciometros, pero en este código solo pude configurar un max de 16, que son los canales del multiplexor 4067, y no esta programado para usar los puertos del arduino pro-micro como potenciometros, solo como botones, entonces, por favor, yo se que que este proyecto es demasiado para mis conocimientos super limitados de arduino, pero me gustaría terminarlo con éxito, y empezar con arduino de 0 despues de esto, quisiera q me ayudaran a incluir 3 potenciometros por los puertos del arduino, (18,19,20) porfa, muchisimas gracias de antemano



Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 06, 2018, 12:57 am
Code: [Select]
#include "MIDIUSB.h"

#include <Multiplexer4067.h> // Multiplexer CD4067 library >> https://github.com/sumotoy/Multiplexer4067
#include <Thread.h> // Threads library >> https://github.com/ivanseidel/ArduinoThread
#include <ThreadController.h> // Mesma lib de cima
//#include "digitalIOPerformance.h"

/////////////////////////////////////////////
// buttons
const byte muxNButtons = 0; // *coloque aqui o numero de entradas digitais utilizadas no multiplexer
const byte NButtons = 8; // *coloque aqui o numero de entradas digitais utilizadas
const byte totalButtons = muxNButtons + NButtons;
const byte muxButtonPin[muxNButtons] = {}; // *neste array coloque na ordem desejada os pinos das portas digitais utilizadas
const byte buttonPin[NButtons] = { 10, 16, 14, 15, 6, 7, 8, 9}; // *neste array coloque na ordem desejada os pinos das portas digitais utilizadas
int buttonCState[totalButtons] = {0}; // estado atual da porta digital
int buttonPState[totalButtons] = {0}; // estado previo da porta digital

/////////////////////////////////////////////
// debounce
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 5; // the debounce time; increase if the output flickers

/////////////////////////////////////////////
// potentiometers
const byte NPots = 17; // *coloque aqui o numero de entradas analogicas utilizadas
const byte muxPotPin[NPots] = {8, 9, 10, 11, 12, 1, 0, 3, 2, 5, 4, 6, 7, 13, 14, 15}; // *neste array coloque na ordem desejada os pinos das portas analogicas, ou mux channel, utilizadas
int potCState[NPots] = {0}; // estado atual da porta analogica
int potPState[NPots] = {0}; // estado previo da porta analogica
int potVar = 0; // variacao entre o valor do estado previo e o atual da porta analogica
int lastCcValue[NPots] = {0};

/////////////////////////////////////////////
// pot reading
int TIMEOUT = 50; //quantidade de tempo em que o potenciometro sera lido apos ultrapassar o varThreshold
byte varThreshold = 4; //threshold para a variacao no sinal do potenciometro
boolean potMoving = true; // se o potenciometro esta se movendo
unsigned long pTime[NPots] = {0}; // tempo armazenado anteriormente
unsigned long timer[NPots] = {0}; // armazena o tempo que passou desde que o timer foi zerado

/////////////////////////////////////////////
// midi
byte midiCh = 0; // *Canal midi a ser utilizado
byte note = 36; // *Nota mais grave que sera utilizada
byte cc = 1; // *CC mais baixo que sera utilizado

/////////////////////////////////////////////
// Multiplexer
Multiplexer4067 mplex = Multiplexer4067(2, 3, 4, 5, A3);

/////////////////////////////////////////////
// threads - programa cada atividade do Arduino para acontecer em um determinado tempo
ThreadController cpu; //thread master, onde as outras vao ser adicionadas
Thread threadReadPots; // thread para controlar os pots

/////////////////////////////////////////////

void setup() {

mplex.begin(); // inicializa o multiplexer

for (int i = 0; i < NButtons; i++) { // inicializa os botoes como input utilizando o pull up resistor
pinMode(buttonPin[i], INPUT_PULLUP);
}

pinMode(A3, INPUT_PULLUP);

/////////////////////////////////////////////
// threads
threadReadPots.setInterval(10);
threadReadPots.onRun(readPots);
cpu.add(&threadReadPots);
/////////////////////////////////////////////

}

void loop() {

cpu.run();
readButtons();

}

/////////////////////////////////////////////
// read buttons

void readButtons() {

for (int i = 0; i < muxNButtons; i++) { //reads buttons on mux
int buttonReading = mplex.readChannel(muxButtonPin[i]);
//buttonCState[i] = map(mplex.readChannel(muxButtonPin[i]), 22, 1023, 0, 2); // stores on buttonCState
if (buttonReading > 1000) {
buttonCState[i] = HIGH;
}
else {
buttonCState[i] = LOW;
}
//Serial.print(buttonCState[i]); Serial.print(" ");
}
//Serial.println();

for (int i = 0; i < NButtons; i++) { //read buttons on Arduino
buttonCState[i + muxNButtons] = digitalRead(buttonPin[i]); // stores in the rest of buttonCState
}

for (int i = 0; i < totalButtons; i++) {

if ((millis() - lastDebounceTime) > debounceDelay) {

if (buttonCState[i] != buttonPState[i]) {
lastDebounceTime = millis();

if (buttonCState[i] == LOW) {
noteOn(potMidiCh(), note + i, 127); // Channel 0, middle C, normal velocity
MidiUSB.flush();
//MIDI.sendNoteOn(note + i, 127, potMidiCh()); // envia NoteOn(nota, velocity, canal midi)
//Serial.print("Note: "); Serial.print(note + i); Serial.println(" On");
buttonPState[i] = buttonCState[i];
}
else {
noteOn(potMidiCh(), note + i, 0); // Channel 0, middle C, normal velocity
MidiUSB.flush();
//MIDI.sendNoteOn(note + i, 0, potMidiCh());
//Serial.print("Note: "); Serial.print(note + i); Serial.println(" Off");
buttonPState[i] = buttonCState[i];
}
}
}

}

}

/////////////////////////////////////////////
//read potentiometers

void readPots() {

for (int i = 0; i < NPots - 1; i++) { // le todas entradas analogicas utilizadas, menos a dedicada a troca do canal midi
potCState[i] = mplex.readChannel(muxPotPin[i]);
}

for (int i = 0; i < NPots; i++) {

potVar = abs(potCState[i] - potPState[i]); // calcula a variacao da porta analogica

if (potVar >= varThreshold) { //sets a threshold for the variance in the pot state, if it varies more than x it sends the cc message
pTime[i] = millis(); // armazena o tempo previo
}
timer[i] = millis() - pTime[i]; // reseta o timer
if (timer[i] < TIMEOUT) { // se o timer for menor que o tempo maximo permitido significa que o potenciometro ainda esta se movendo
potMoving = true;
}
else {
potMoving = false;
}

if (potMoving == true) { // se o potenciometro ainda esta se movendo, mande o control change
int ccValue = map(potCState[i], 22, 1022, 0, 127);
if (lastCcValue[i] != ccValue) {
controlChange(11, cc + i, ccValue); // manda control change (channel, CC, value)
MidiUSB.flush();
//MIDI.sendControlChange(cc + i, map(potCState[i], 0, 1023, 0, 127), 11); // envia Control Change (numero do CC, valor do CC, canal midi)
//Serial.print("CC: "); Serial.print(cc + i); Serial.print(" value:"); Serial.println(map(potCState[i], 22, 1023, 0, 127));
potPState[i] = potCState[i]; // armazena a leitura atual do potenciometro para comparar com a proxima
lastCcValue[i] = ccValue;
}
}
}

}

/////////////////////////////////////////////
// calculates midi channel based on pot position
int potMidiCh () {
int potCh = map(mplex.readChannel(muxPotPin[9]), 22, 1023, 0, 4);

if (potCh == 4) {
potCh = 3;
}

return potCh + midiCh;
}

/////////////////////////////////////////////
// Arduino (pro)micro midi functions Arcore Library
//void noteOn(byte channel, byte pitch, byte velocity) {
// MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity};
// MIDIUSB.write(noteOn);
//}
//
//void noteOff(byte channel, byte pitch, byte velocity) {
// MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity};
// MIDIUSB.write(noteOff);
//}

/////////////////////////////////////////////
// Arduino (pro)micro midi functions MIDIUSB Library
void noteOn(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
MidiUSB.sendMIDI(event);
}
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 06, 2018, 01:00 am
Y cual es el ejemplo para poder entender la idea?
Puedes poner el link al ejemplo que has copiado y pegado?


Supongo que es este Build this MIDI controller using an Arduino: Fliper Dj (https://www.musiconerd.com/single-post/Build-this-MIDI-controller-Fliper-Dj)

Estas equivocado en tu enfoque.

Quote
y no esta programado para usar los puertos del arduino pro-micro como potenciometros
El 4067 es un multiplexor digital x ende no puedes configurarlo para usarlo con algo analógico.
No puede convertirse para leer 16 potenciometros

Tienes que usar un CD4051 y es un multiplexor de 8 canales no 16, claro que puedes poner 2 o 3 y llegar a 24 potenciometros.


EDITADO: Me he equivocado. Consultando la hoja de datos del CD4067 compruebo que no es multiplexor digital sino analógico.


Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 06, 2018, 01:11 am
este el video de MusicoNerd en youtube Fliper DJ (https://www.youtube.com/watch?v=SvmHu1tpLbw), yo tome esto como punto de partida para crear una superficie de control para DAW (REAPER), con 8 potes deslizables (para 8 canales de audio) 1 pote deslizable para control de master, 8 controles rotarorios para control de paneo de cada pista y 2 potes para zoom de pista vertical y horizontal, todo esto es asignable en el DAW, la maquina solo manda mensajes midi, y para tal caso me faltan 3 potenciometros, debo aclarar que ya estoy usando 16 potes asignados a REAPER, funcionando a la perfección.
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 06, 2018, 04:02 am
El habla de 16 botones no de 16 potenciometros. Dice que ajusta el knob (potenciometro) y cambia los botones. Para mi esta claro.
El código lo afirma, no hay un solo analogRead que es el comando que se usa para leer una entrada analógica que es precisamente lo que un potenciómetro te dará, valores entre 0 y 5V.
Min 1:49" it´s to show you the function of this knob. Actually this knob here it´s a bank selector
for the buttons so I have 16 buttons...."
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 06, 2018, 04:16 am
me enredo, si bien te entiendo, los potes están programados como botones? me es difícil de entender, pues en mi caso los 16 potes que tengo conectados a las 16 entradas del multiplexor actúan como potes en el programa y en el monitor midi, los deslizables mueven los faders del programa, los rotatorios mueven los controles de panorama, emulando perfectamente el funcionamiento de una consola análoga, como explique en el encabezado es mi primer acercamiento a arduino y no estoy familiarizado con casi nada, me falta muchísimo si no es que todo por aprender, entonces como podría modificar este código para incluir 3 potenciometros mas en los puertos del arduino para que actúen tal cual como los que están conectados al multiplexor?
Title: Re: 21 Potenciometros en proyecto midi
Post by: tauro0221 on Dec 06, 2018, 04:46 am
Hi,
Adjunto una foto del esquematico de como esta alambrado el  MIDI controller seguiendo el link dado en la pagina de U-tube. Creo que en el programa el lee los switches y lee las resistencias variables para cambiar el rimbo de la musica. El esta usando el 4067 para seleccionar las salidas del los potenciometros como senales analogas. Tambien adjunto el link donde puede bajar el  programa y el esquematico del midi.

https://musiconerd.us10.list-manage.com/subscribe?u=9942d2218aede48d044e43a2c&id=f809dcd271 (https://musiconerd.us10.list-manage.com/subscribe?u=9942d2218aede48d044e43a2c&id=f809dcd271)





(https://forum.arduino.cc/index.php?action=dlattach;topic=583532.0;attach=284804)
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 06, 2018, 12:20 pm
eso mismo, salvo que yo necesito solo potenciometros en el multiplexor (que ya los tengo, si revisan el codigo se daran cuenta), aparte necesito 3 potenciometros mas en el arduino, para hacer un total de 19 potenciometros, el resto en botones, (5 botones que tambien ya estan listos), el codigo esta programado para transformar las señales del multiplexor en mensajes midi del tipo CC (pots), y los botones del arduino como mensajes on-off midi (buttons), yo no pude cambiar el codigo para que 3 puertos del arduino, que funcionan como botones, funcionen como CC, (tal cual los del multiplexor), y para esto necesito ayuda, ojala se entienda
Title: Re: 21 Potenciometros en proyecto midi
Post by: tauro0221 on Dec 06, 2018, 05:55 pm
Hi,
Aqui la solucion es que en vez de usar un micro uses un mega. Te va a dar mas puertos y mas senales analogas. Ya el micro esta a su  max capacidad y no te vaz a  poder anadir mas componentes mas tarde.
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 06, 2018, 06:03 pm
gracias por la respuesta tauro0221, si para otros proyectos tengo pensado usar mega, por ahora no necesito mas puertos, solo configurar pero bueno, gracias de todos modos
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 06, 2018, 08:54 pm
Bueno estoy recalculando porque pense que el CD4067  (http://www.ti.com/lit/ds/symlink/cd4097b.pdf)era un multiplexor digital y es analógico asi que tengo que volver a mirar todo con otros ojos.

Reconsiderando tu petición de aumentar la cantidad de potenciometros encontré esto:

Sin embargo si miras la línea 24
Code: [Select]
// potentiometers
const byte NPots = 17; // coloque aquí el numero de entradas analógicas.

const byte muxPotPin[NPots] = {8, 9, 10, 11, 12, 1, 0, 3, 2, 5, 4, 6, 7, 13, 14, 15}; // en esta vector coloque en el orden deseado los pines de los puertos analógicos, o mux channel, utilizados
int potCState[NPots] = {0}; // estado actual del puerto analógico
int potPState[NPots] = {0}; // estado previo del puerto analógico
int potVar = 0; // variación entre el valor del estado previo y el actual del puerto analógico
int lastCcValue[NPots] = {0};


Ahi lees const byte Npots = 17 quiere decir que usa 16 potenciometros.
Si quieres mas potenciometros, bien aumenta el nro ahi y luego tendremos que asignar pines para su conexionado físico.

El problema que tengo es que mi mente se frena cuando ve esquemas hechos en Fritzing de este tipo, claro que Fritzing tmb permite visualizar las cosas como esquema electronico, pero todos gustan de ver el protoboard y eso no dice nada de hecho luce confuso para mi y no puedo interpretar el conexionado.

Tampoco comprendo como hay 10 potenciometros y se definen 16.
Lo único que veo son 16 botones (menos mal, algo veo!!).



Amplio la idea:

esta linea
Code: [Select]
Multiplexer4067 mplex = Multiplexer4067(2, 3, 4, 5, A3);
Define que pines se usan para elegir la entrada analógica y por donde se lee finalmente A3
Tendrias que usar por ejemplo otro 4067 y el pin A4, algo asi

Multiplexer4067 mplex1 = Multiplexer4067(2, 3, 4, 5, A4);

Con lo cual tendrias 16 potenciometros mas!!
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 06, 2018, 09:01 pm
gracias por la respuesta, lo que pasa es que el diseño original fliper DJ, lleva 10 potes y creo 16 botones, y en la configuracion de potes dice -1, pues uno esta destinado a un control midi, yo como dije antes, quiero modificar eso, entonces, aumente el numero de potes a 17, de primera instancia, y cambie a todos los puertos del multiplexor, asi me quedo en 16 canales de potes, y los botones q originalmente estaban asignados al multiplexor los deje en 0, asi al menos pude tener 16 potes, la cosa ahora es, q no puedo hacer q 3 pines del mismo arduino funcionen como 3 potes mas, asi pudiendo completar los 19 que necesito, me imagino q hay q programar todo para q el programa reconozca esos 3 pines como potes, luego q los cambie a mensajes midi y los mande a 3 canales mas, ahi yo me pierdo completamente
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 06, 2018, 09:03 pm
Entonces ese esquema que tauro y yo vimos no corresponde a tu circuito?

To loop debería entonces leer solo esto

Code: [Select]
void loop() {
  cpu.run();
  readPots();
}


Ahora dice

Code: [Select]
void loop() {
  cpu.run();
  readButtons();
}


Estas cosas se prestan a confunsión
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 06, 2018, 09:39 pm
Bueno habria que establecer un criterio similar a como hace con los botones.
Veo que el código usa botones multiplexados y botones del arduino. Bueno en tu caso buscas lo mismo entonces

hay que definir pot multiplexados que son los que estan conectados al 4067 y pot a los pines AD que queden del Arduino.

Esto es lo que resultó

Definí 3 potenciometros a A0 A1 y A2
A3 es la entrada del CD4067

Mira a ver porque no puedo compilarlo.

Code: [Select]
#include "MIDIUSB.h"

#include <Multiplexer4067.h> // Multiplexer CD4067 library >> https://github.com/sumotoy/Multiplexer4067
#include <Thread.h> // Threads library >> https://github.com/ivanseidel/ArduinoThread
#include <ThreadController.h> // Mesma lib de cima
//#include "digitalIOPerformance.h"

/////////////////////////////////////////////
// buttons
const byte muxNButtons  = 0; // *coloque aqui o numero de entradas digitais utilizadas no multiplexer
const byte NButtons     = 8; // *coloque aqui o numero de entradas digitais utilizadas
const byte totalButtons = muxNButtons + NButtons;
const byte muxButtonPin[muxNButtons] = {}; // *neste array coloque na ordem desejada os pinos das portas digitais utilizadas
const byte buttonPin[NButtons] = { 10, 16, 14, 15, 6, 7, 8, 9}; // *neste array coloque na ordem desejada os pinos das portas digitais utilizadas
int buttonCState[totalButtons] = {0}; // estado atual da porta digital
int buttonPState[totalButtons] = {0}; // estado previo da porta digital

/////////////////////////////////////////////
// debounce
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 5; // the debounce time; increase if the output flickers

/////////////////////////////////////////////
// potentiometers
const byte muxPots   = 17;
const byte NPots     = 3; // coloque aqui las entradas digitales no multiplexadas utilizadas
const byte totalPots = Npots + muxPots;
const byte muxPotPin[muxPots] = {8, 9, 10, 11, 12, 1, 0, 3, 2, 5, 4, 6, 7, 13, 14, 15}; // este vector coloque los canales analogicos multiplexados
const byte potsPin[NPots]     = {A0, A1, A2}; // tres potenciometros
int potCState[totalPots] = {0}; // estado atual de la puerta analogica
int potPState[totalPots] = {0}; // estado previo de la puerta analogica
int potVar = 0; // variación entre un valor del estado previo y el actual
int lastCcValue[totalPots] = {0};

/////////////////////////////////////////////
// pot reading
int TIMEOUT = 50; //quantidade de tempo em que o potenciometro sera lido apos ultrapassar o varThreshold
byte varThreshold = 4; //threshold para a variacao no sinal do potenciometro
boolean potMoving = true; // se o potenciometro esta se movendo
unsigned long pTime[totalPots] = {0}; // tempo armazenado anteriormente
unsigned long timer[totalPots] = {0}; // armazena o tempo que passou desde que o timer foi zerado

/////////////////////////////////////////////
// midi
byte midiCh   = 0; // *Canal midi a ser utilizado
byte note     = 36; // *Nota mais grave que sera utilizada
byte cc       = 1; // *CC mais baixo que sera utilizado

/////////////////////////////////////////////
// Multiplexer
Multiplexer4067 mplex = Multiplexer4067(2, 3, 4, 5, A3);

/////////////////////////////////////////////
// threads - programa cada atividade do Arduino para acontecer em um determinado tempo
ThreadController cpu; //thread master, onde as outras vao ser adicionadas
Thread threadReadPots; // thread para controlar os pots

/////////////////////////////////////////////

void setup() {

mplex.begin(); // inicializa o multiplexer

for (int i = 0; i < NButtons; i++) { // inicializa os botoes como input utilizando o pull up resistor
    pinMode(buttonPin[i], INPUT_PULLUP);
}

pinMode(A3, INPUT_PULLUP);

/////////////////////////////////////////////
// threads
threadReadPots.setInterval(10);
threadReadPots.onRun(readPots);
cpu.add(&threadReadPots);
/////////////////////////////////////////////

}

void loop() {
  cpu.run();
  readPots();
}


/////////////////////////////////////////////
// read buttons

void readButtons() {

  for (int i = 0; i < muxNButtons; i++) { //reads buttons on mux
      int buttonReading = mplex.readChannel(muxButtonPin[i]);
      //buttonCState[i] = map(mplex.readChannel(muxButtonPin[i]), 22, 1023, 0, 2); // stores on buttonCState
      if (buttonReading > 1000) {
          buttonCState[i] = HIGH;
      }
      else {
          buttonCState[i] = LOW;
      }
  //Serial.print(buttonCState[i]); Serial.print(" ");
  }
  //Serial.println();

  for (int i = 0; i < NButtons; i++) { //read buttons on Arduino
      buttonCState[i + muxNButtons] = digitalRead(buttonPin[i]); // stores in the rest of buttonCState
  }

  for (int i = 0; i < totalButtons; i++) {

      if ((millis() - lastDebounceTime) > debounceDelay) {
          if (buttonCState[i] != buttonPState[i]) {
              lastDebounceTime = millis();

              if (buttonCState[i] == LOW) {
                  noteOn(potMidiCh(), note + i, 127); // Channel 0, middle C, normal velocity
                  MidiUSB.flush();
                  //MIDI.sendNoteOn(note + i, 127, potMidiCh()); // envia NoteOn(nota, velocity, canal midi)
                  //Serial.print("Note: "); Serial.print(note + i); Serial.println(" On");
                  buttonPState[i] = buttonCState[i];
              }
              else {
                  noteOn(potMidiCh(), note + i, 0); // Channel 0, middle C, normal velocity
                  MidiUSB.flush();
                  //MIDI.sendNoteOn(note + i, 0, potMidiCh());
                  //Serial.print("Note: "); Serial.print(note + i); Serial.println(" Off");
                  buttonPState[i] = buttonCState[i];
              }
          }
      }
  }
}

/////////////////////////////////////////////
//read potentiometers

void readPots() {

for (int i = 0; i < muxPots - 1; i++) { // le todas entradas analogicas utilizadas, menos a dedicada a troca do canal midi
    potCState[i] = mplex.readChannel(muxPotPin[i]);
}

for (int i = 0; i < NPots; i++) { //read buttons on Arduino
      buttonCState[i + muxPots] = analogRead(potsPin[i]); // stores in the rest of buttonCState
}

for (int i = 0; i < NPots; i++) {

    potVar = abs(potCState[i] - potPState[i]); // calcula a variacao da porta analogica

    if (potVar >= varThreshold) { //sets a threshold for the variance in the pot state, if it varies more than x it sends the cc message
        pTime[i] = millis(); // armazena o tempo previo
    }
    timer[i] = millis() - pTime[i]; // reseta o timer
    if (timer[i] < TIMEOUT) { // se o timer for menor que o tempo maximo permitido significa que o potenciometro ainda esta se movendo
        potMoving = true;
    }
    else {
        potMoving = false;
    }

    if (potMoving == true) { // se o potenciometro ainda esta se movendo, mande o control change
        int ccValue = map(potCState[i], 22, 1022, 0, 127);
        if (lastCcValue[i] != ccValue) {
            controlChange(11, cc + i, ccValue); // manda control change (channel, CC, value)
            MidiUSB.flush();
            //MIDI.sendControlChange(cc + i, map(potCState[i], 0, 1023, 0, 127), 11); // envia Control Change (numero do CC, valor do CC, canal midi)
            //Serial.print("CC: "); Serial.print(cc + i); Serial.print(" value:"); Serial.println(map(potCState[i], 22, 1023, 0, 127));
            potPState[i] = potCState[i]; // armazena a leitura atual do potenciometro para comparar com a proxima
            lastCcValue[i] = ccValue;
        }
    }
}

}

/////////////////////////////////////////////
// calculates midi channel based on pot position
int potMidiCh () {
  int potCh = map(mplex.readChannel(muxPotPin[9]), 22, 1023, 0, 4);

  if (potCh == 4) {
      potCh = 3;
  }

  return potCh + midiCh;
}

/////////////////////////////////////////////
// Arduino (pro)micro midi functions Arcore Library
//void noteOn(byte channel, byte pitch, byte velocity) {
// MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity};
// MIDIUSB.write(noteOn);
//}
//
//void noteOff(byte channel, byte pitch, byte velocity) {
// MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity};
// MIDIUSB.write(noteOff);
//}

/////////////////////////////////////////////
// Arduino (pro)micro midi functions MIDIUSB Library
void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 07, 2018, 04:40 pm
gracias por la ayuda, a mi también me da error al compilar, sin embargo me gusta la idea de usar otro multiplexor, tengo varios


el codigo q propones me da este error
"exit status 1 'Npots' was not declared in this scope"
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 07, 2018, 05:37 pm
No hace falta con el código y las instrucciones que te pasé
Pero como gustes.
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 07, 2018, 11:07 pm
ahora estoy entrampado en como hacer funcionar los 2 multiplexores, probe varias formas y no doy con la que funcione
Title: Re: 21 Potenciometros en proyecto midi
Post by: tauro0221 on Dec 07, 2018, 11:55 pm
Hi,
Aqui puedes hacerlo con solo anadirle un transistor y puedes usar los dos multiplexer sin necesidad de anadirle mas puertos. Lo que tienes que hacer es mover una de las senales analogas al segundo cd4067 y usas ese port para seleccionar cual de los cd4067 quieres leer.  Un zero selecciona uno y uno positivo secciona el segundo por medio del transistor.

Adjunto esta el esquematico para que lo consideres. Creo que estas haciendo mas deficil la programacion por querer seguir usando el NANO. Al usar un mega se te va hacer mas facil pero es tu projecto.

(https://forum.arduino.cc/index.php?action=dlattach;topic=583532.0;attach=285057)
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 08, 2018, 12:20 am
gracias por la respuesta, pero me estas dando una solucion que esta lejisimos de mis posibilides, en este momento probe con 2 multiplexores y no me funciono, tampoco funciono el codigo que se posteo para incluir entradas analogas del arduino, en lo de poner 2 multiplexores, llego a un punto en que o funciona uno, o el otro, pero no logro que funcionen ambos a la vez
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 08, 2018, 03:21 am
Quote
tampoco funciono el codigo que se posteo para incluir entradas analogas del arduino,
Cómo que no funciona?
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 08, 2018, 03:33 am
lo he subido tal cual lo escribiste y me sale este mensaje de error
Code: [Select]
Arduino:1.8.7 (Windows 7), Tarjeta:"SparkFun Pro Micro, ATmega32U4 (5V, 16 MHz)"

12potes_14_botones:27:24: error: 'Npots' was not declared in this scope

 const byte totalPots = Npots + muxPots;

                        ^

12potes_14_botones:30:24: error: size of array 'potCState' is not an integral constant-expression

 int potCState[totalPots] = {0}; // estado atual de la puerta analogica

                        ^

12potes_14_botones:31:24: error: size of array 'potPState' is not an integral constant-expression

 int potPState[totalPots] = {0}; // estado previo de la puerta analogica

                        ^

12potes_14_botones:33:26: error: size of array 'lastCcValue' is not an integral constant-expression

 int lastCcValue[totalPots] = {0};

                          ^

12potes_14_botones:40:30: error: size of array 'pTime' is not an integral constant-expression

 unsigned long pTime[totalPots] = {0}; // tempo armazenado anteriormente

                              ^

12potes_14_botones:41:30: error: size of array 'timer' is not an integral constant-expression

 unsigned long timer[totalPots] = {0}; // armazena o tempo que passou desde que o timer foi zerado

                              ^

exit status 1
'Npots' was not declared in this scope

Este reporte podría tener más información con
"Mostrar salida detallada durante la compilación"
opción habilitada en Archivo -> Preferencias.
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 08, 2018, 03:36 am
Indicame en donde puedo descargar la librerías

Code: [Select]
#include "MIDIUSB.h"

#include <Multiplexer4067.h> // Multiplexer CD4067 library >> https://github.com/sumotoy/Multiplexer4067
#include <Thread.h> // Threads library >> https://github.com/ivanseidel/ArduinoThread
#include <ThreadController.h> // Mesma lib de cima
//#include "digitalIOPerformance.h"


Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 08, 2018, 03:48 am
El Error estaba en la linea 27 decia Npots, y debia ser NPots, corregido esto se puede compilar y subir al arduino, pero no manda MIDI, edito, si manda midi, pero solo por los botones, todos los potenciometros no funcionan


https://github.com/arduino-libraries/MIDIUSB (https://github.com/arduino-libraries/MIDIUSB)
https://github.com/sumotoy/Multiplexer4067 (https://github.com/sumotoy/Multiplexer4067)
https://github.com/ivanseidel/ArduinoThread (https://github.com/ivanseidel/ArduinoThread)
Title: Re: 21 Potenciometros en proyecto midi
Post by: tauro0221 on Dec 08, 2018, 03:57 am
Hi,
Si las salidas de los cd4067 estan conectadas juntas  no pueden trabajarlas  dos  a  la vez. Tienes que leer una y despues lee la otra. Si quires leer las dos a las vez entonces tienes que leer las salidas individuales. Pero tienes que seleccionar una a las vez y lee las salidas. Acuerdate que las salidas estan en paralelo.
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 08, 2018, 04:21 am
Te felicito por encontrar el error de Npots vs NPots, es lo menos que se puede esperar de alguien que pide ayuda pero que debe poner algo de su parte para llegar a la solución que se pretende.

Bueno el error fue que copie lo hecho con buttons y se me deslizaron algunas variables que no cambie
Mira esto a ver si estamos algo mejor.

Code: [Select]
#include "MIDIUSB.h"

#include <Multiplexer4067.h> // Multiplexer CD4067 library >> https://github.com/sumotoy/Multiplexer4067
#include <Thread.h> // Threads library >> https://github.com/ivanseidel/ArduinoThread
#include <ThreadController.h> // Mesma lib de cima
//#include "digitalIOPerformance.h"

/////////////////////////////////////////////
// buttons
const byte muxNButtons  = 0; // *coloque aqui o numero de entradas digitais utilizadas no multiplexer
const byte NButtons     = 8; // *coloque aqui o numero de entradas digitais utilizadas
const byte totalButtons = muxNButtons + NButtons;
const byte muxButtonPin[muxNButtons] = {}; // *neste array coloque na ordem desejada os pinos das portas digitais utilizadas
const byte buttonPin[NButtons] = { 10, 16, 14, 15, 6, 7, 8, 9}; // *neste array coloque na ordem desejada os pinos das portas digitais utilizadas
int buttonCState[totalButtons] = {0}; // estado atual da porta digital
int buttonPState[totalButtons] = {0}; // estado previo da porta digital

/////////////////////////////////////////////
// debounce
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 5; // the debounce time; increase if the output flickers

// potentiometers
const byte muxPots   = 17;
const byte NPots     = 3; // coloque aqui las entradas digitales no multiplexadas utilizadas
const byte totalPots = NPots + muxPots;
const byte muxPotPin[muxPots] = {8, 9, 10, 11, 12, 1, 0, 3, 2, 5, 4, 6, 7, 13, 14, 15}; // este vector coloque los canales analogicos multiplexados
const byte potsPin[NPots]     = {A0, A1, A2}; // tres potenciometros
int potCState[totalPots] = {0}; // estado atual de la puerta analogica
int potPState[totalPots] = {0}; // estado previo de la puerta analogica
int potVar = 0; // variación entre un valor del estado previo y el actual
int lastCcValue[totalPots] = {0};

/////////////////////////////////////////////
// pot reading
int TIMEOUT = 50; //quantidade de tempo em que o potenciometro sera lido apos ultrapassar o varThreshold
byte varThreshold = 4; //threshold para a variacao no sinal do potenciometro
boolean potMoving = true; // se o potenciometro esta se movendo
unsigned long pTime[totalPots] = {0}; // tempo armazenado anteriormente
unsigned long timer[totalPots] = {0}; // armazena o tempo que passou desde que o timer foi zerado

/////////////////////////////////////////////
// midi
byte midiCh   = 0; // *Canal midi a ser utilizado
byte note     = 36; // *Nota mais grave que sera utilizada
byte cc       = 1; // *CC mais baixo que sera utilizado

// Multiplexer
Multiplexer4067 mplex = Multiplexer4067(2, 3, 4, 5, A3);


// threads - programa cada atividade do Arduino para acontecer em um determinado tempo
ThreadController cpu; //thread master, onde as outras vao ser adicionadas
Thread threadReadPots; // thread para controlar os pots

void setup() {

mplex.begin(); // inicializa o multiplexer

for (int i = 0; i < NButtons; i++) { // inicializa os botoes como input utilizando o pull up resistor
    pinMode(buttonPin[i], INPUT_PULLUP);
}

pinMode(A3, INPUT_PULLUP);

/////////////////////////////////////////////
// threads
threadReadPots.setInterval(10);
threadReadPots.onRun(readPots);
cpu.add(&threadReadPots);
/////////////////////////////////////////////

}

void loop() {
  cpu.run();
  readPots();
}


/////////////////////////////////////////////
// read buttons

void readButtons() {

  for (int i = 0; i < muxNButtons; i++) { //reads buttons on mux
      int buttonReading = mplex.readChannel(muxButtonPin[i]);
      //buttonCState[i] = map(mplex.readChannel(muxButtonPin[i]), 22, 1023, 0, 2); // stores on buttonCState
      if (buttonReading > 1000) {
          buttonCState[i] = HIGH;
      }
      else {
          buttonCState[i] = LOW;
      }
  //Serial.print(buttonCState[i]); Serial.print(" ");
  }
  //Serial.println();

  for (int i = 0; i < NButtons; i++) { //read buttons on Arduino
      buttonCState[i + muxNButtons] = digitalRead(buttonPin[i]); // stores in the rest of buttonCState

  }

  for (int i = 0; i < totalButtons; i++) {

      if ((millis() - lastDebounceTime) > debounceDelay) {
          if (buttonCState[i] != buttonPState[i]) {
              lastDebounceTime = millis();

              if (buttonCState[i] == LOW) {
                  noteOn(potMidiCh(), note + i, 127); // Channel 0, middle C, normal velocity
                  MidiUSB.flush();
                  //MIDI.sendNoteOn(note + i, 127, potMidiCh()); // envia NoteOn(nota, velocity, canal midi)
                  //Serial.print("Note: "); Serial.print(note + i); Serial.println(" On");
                  buttonPState[i] = buttonCState[i];
              }
              else {
                  noteOn(potMidiCh(), note + i, 0); // Channel 0, middle C, normal velocity
                  MidiUSB.flush();
                  //MIDI.sendNoteOn(note + i, 0, potMidiCh());
                  //Serial.print("Note: "); Serial.print(note + i); Serial.println(" Off");
                  buttonPState[i] = buttonCState[i];
              }
          }
      }
  }
}

/////////////////////////////////////////////
//read potentiometers

void readPots() {

for (int i = 0; i < muxPots - 1; i++) { // le todas entradas analogicas utilizadas, menos a dedicada a troca do canal midi
    potCState[i] = mplex.readChannel(muxPotPin[i]);
    Serial.println("Canal["+String(i)+"]="+String(potCState[i]));
}

for (int i = 0; i < NPots; i++) { //read buttons on Arduino
     potCState[i + muxPots] = analogRead(potsPin[i]); // stores in the rest of buttonCState
    Serial.println("Canal["+String(i+muxPots)+"]="+String(potCState[i+muxPots]));
}

for (int i = 0; i < NPots; i++) {

    potVar = abs(potCState[i] - potPState[i]); // calcula a variacao da porta analogica

    if (potVar >= varThreshold) { //sets a threshold for the variance in the pot state, if it varies more than x it sends the cc message
        pTime[i] = millis(); // armazena o tempo previo
    }
    timer[i] = millis() - pTime[i]; // reseta o timer
    if (timer[i] < TIMEOUT) { // se o timer for menor que o tempo maximo permitido significa que o potenciometro ainda esta se movendo
        potMoving = true;
    }
    else {
        potMoving = false;
    }

    if (potMoving == true) { // se o potenciometro ainda esta se movendo, mande o control change
        int ccValue = map(potCState[i], 22, 1022, 0, 127);
        if (lastCcValue[i] != ccValue) {
            controlChange(11, cc + i, ccValue); // manda control change (channel, CC, value)
            MidiUSB.flush();
            //MIDI.sendControlChange(cc + i, map(potCState[i], 0, 1023, 0, 127), 11); // envia Control Change (numero do CC, valor do CC, canal midi)
            //Serial.print("CC: "); Serial.print(cc + i); Serial.print(" value:"); Serial.println(map(potCState[i], 22, 1023, 0, 127));
            potPState[i] = potCState[i]; // armazena a leitura atual do potenciometro para comparar com a proxima
            lastCcValue[i] = ccValue;
        }
    }
}

}

/////////////////////////////////////////////
// calculates midi channel based on pot position
int potMidiCh () {
  int potCh = map(mplex.readChannel(muxPotPin[9]), 22, 1023, 0, 4);

  if (potCh == 4) {
      potCh = 3;
  }

  return potCh + midiCh;
}

/////////////////////////////////////////////
// Arduino (pro)micro midi functions Arcore Library
//void noteOn(byte channel, byte pitch, byte velocity) {
// MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity};
// MIDIUSB.write(noteOn);
//}
//
//void noteOff(byte channel, byte pitch, byte velocity) {
// MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity};
// MIDIUSB.write(noteOff);
//}

// Arduino (pro)micro midi functions MIDIUSB Library
void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 08, 2018, 04:43 am
bueno bueno muchísimas pero muchísimas gracias por tanta ayuda, yo suelo ser muy entregado a este tipo de cosas, pero como dije es mi primer proyecto y creo que fue demasiado complejo.
Luego de revisar y comparar, creo que ya esta bien, me faltan hacer las pruebas finales con el DAW, entonces

en la fila 78 hay q ingresar esto

readButtons();

y en la fila 145 hay q poner

for (int i = 0; i < totalPots; i++) {

esto lo deduje observando el primer codigo,

Bueno repito mis mas sinceras y mas sentidas gracias y felicitaciones por el apoyo y ayuda q brindan, sin duda que no habria logrado nada sin su ayuda, por mi parte, me di cuenta de que necesito empezar desde 0 con arduino, para en un futuro poder saber exactamente donde buscar,  un abrazo enorme y estaré comentando como progresa el proyecto
Title: Re: 21 Potenciometros en proyecto midi
Post by: surbyte on Dec 08, 2018, 02:14 pm
Si claro que fue muy complejo, pero uno no se da cuenta hasta ponerse con la tarea.

Lo bueno es que te propondrás estudiar y eso te dará mas herramientas y al menos tienes el sentido común que no todos encuentran.

Recuerda que cuando algo no funcione, puedes usar Serial.print(variables) para que te diga que esta sucediendo.
Los que te brindamos ayuda no tenemos tu hardware y a veces se dificulta guiarlos. A veces no, casi siempre.
Title: Re: 21 Potenciometros en proyecto midi
Post by: roxo on Dec 11, 2018, 08:16 pm
bueno, he ido probando y funciona todo muy bien, muy estable, completamente configurable desde el DAW, ahora estaba empezando a leer mas cosas sobre arduino y pues otra cosa se me vino encima como una ola de 25 metros, quizá mas complejo q lo anterior, la cosa es esto, hay 16 pontenciometros mandando 16 mensajes midi, para 8 canales de audio (un volume y un paneo L-R) veo q a través de una matriz se puede hacer que esos 16 botones cambien a 16 mensajes midi diferentes, entonces de esta forma se podrían configurar mas canales de audio según el porte de la matriz, también decir q en reaper se pueden configurar hasta 99 canales de audio, pero bueno yo nunca trabaje en proyectos tan grandes así es que hasta 64 canales estaría de lujo, entonces tendría q hacer una matriz de 8x8 (o 16x8) y un par de botones que cambien la fila (o la columna, aun no se como se hace), peeeero se me queda muy grande también esta tarea, quiza mas adelante la lleve a cabo cuando tenga mas experiencia programando el arduino, por ahora sigo con los tutoriales básicos jejejej