Kilomux Shield

De Wiki
Saltar a: navegación, buscar

Introducción

KilomuxGeneral.png

El Kilomux es un shield pensado para usar con una Arduino UNO (probada y funcionando con Arduino Mega y Arduino Due) que expande la cantidad de entradas y salidas usando multiplexores CD4067 y registros de desplazamiento 74HC595 y permite la comunicación via MIDI, ya sea por USB o por hardware.

Cuenta con 16 salidas digitales y 32 entradas, con la posibilidad de combinar señales digitales y analógicas a gusto. El shield tiene también 4 pines digitales libres (2, 3, 12 y 13 en la v1 y 10, 11, 12 y 13 en la v2), pensados para conectar un sensor de ultrasonido a través de J1 y un botón y un LED para su activación, y 4 pines analógicos sin usar (A2, A3, A4 y A5)

En el repositorio de GitHub se encuentra el código de Arduino que realiza la lectura de las entradas, con funciones para enviar los datos usando la librería MIDI de Arduino, o por serial y que recibe datos por MIDI o serial y enciende las salidas correspondientes.

Se pueden encontrar también en la sección de Arduino Library, la librería de código Kilomux Shield para el manejo de las entradas y salidas del shield, con ejemplos de uso.

También hay un sketch de ejemplo que implementa un controlador MIDI utilizando el shield y usando las librerías MuxShield (modificada de la de MayhewLabs), MIDI (Arduino) y NewPing (para el sensor ultrasónico).

Incorporamos al repositorio la ultima versión del proyecto HIDUINO, el firmware necesario para enviar MIDI por USB y que la PC reconozca a la Arduino como un dispositivo MIDI Plug&Play, es decir que no requiere instalar drivers específicos para funcionar. En las referencias hay un instructivo para recompilar HIDUINO, para cambiar el nombre del dispositivo y programar HIDUINO en el microcontrolador que maneja la comunicación de la Arduino.

Si tenes dudas, sugerencias o comentarios acerca del shield, podés escribir a franco (arroba) yaeltex.com.ar o postear en el foro de Yaeltex.

Agradecimientos:
- Jorge Crowe del laboratorio del juguete por la ayuda con el puntapie inicial en el shield.
- Lucas Leal por sus observaciones de diseño y programación.

Librería Kilomux Shield

La librería del Kilomux Shield está disponible para su descarga en el github de Yaeltex.

La misma contiene las funciones que leen entradas y manejan las salidas del shield, de forma que su uso sea similar a la forma normal en la que se leen las entradas y se manejan las salidas de una Arduino por sí sola.

Para usar los ejemplos de esta página, debes instalar la librería del Kilomux y la librería MIDI de Arduino.

Para instalar ambas librerías, recomendamos seguir este tutorial.

Una vez instaladas, ya puedes ver los ejemplos de uso, haciendo clic sobre Archivo -> Ejemplos -> KilomuxShield.

Conexiones y lectura de entradas

Entradas

El Kilomux Shield está preparado para recibir hasta 32 señales analógicas (potenciómetros, sensores) o digitales (botones). Para lograr esto, el shield hace uso de dos multiplexores analógicos CD4067 de 16 canales.

Se dispone de 4 puertos de conexión idénticos, con 8 entradas cada uno: MUX A-1, MUX A-2, MUX B-1 y MUX B-2.

Cada puerto se ve de la siguiente manera:

default default

Cada puerto de entrada, tiene un pin de GND y uno de 5V (para alimentar sensores, potenciómetros, etc). El pin de 5V está conectado al pin de 5V de la Arduino.

Los puertos MUX A-1 y MUX B-1 tienen los pines restantes numerados del 0 al 7.

Los puertos MUX A-2 y MUX B-2 tienen los pines restantes numerados del 8 al 15.

Analógicas

Pueden conectarse al Kilomux distintos tipos de resistencias variables como potenciómetros, faders (potenciómetros deslizables), LDRs, FSRs y más. El valor recomendado para este tipo de componentes es de 5k a 10k. Para leer un potenciómetro o un fader, conectarlo de esta manera:

Un ejemplo de cableado o conexión de 8 potenciómetros a una entrada analógica sería el siguiente:

default

La conexión de un solo potenciómetro o fader sería de la siguiente manera:

default

Luego, abrir el ejemplo OneAnalogInput de la librería Kilomux, en el Arduino IDE.

/*
 * Author: Franco Grassano - YAELTEX
 * Date: 18/02/2016
 * ---
 * LICENSE INFO
 * Kilomux Shield by Yaeltex is released by
 * * Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) - http://creativecommons.org/licenses/by-sa/4.0/
 * ----
 * Description: Reads one analog input and sends value over serial or MIDI.
 *              This example is for use with the Kilomux Shield.
 * 
 * Kilomux Library is available at https://github.com/Yaeltex/Kilomux-Shield/blob/master/Arduino%20Code/KilomuxShield%20Library/KilomuxShield.zip
 */
 
#include <Kilomux.h>              // Import class declaration
#include <KilomuxDefs.h>          // Import Kilomux defines
#include <MIDI.h>                 // Import Arduino MIDI Library headers
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE() // Create a hardware instance of the library

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define SERIAL_COMMS          // Leave uncommented (and comment the line below) to send over serial
//#define MIDI_COMMS          // Leave uncommented (and comment the line above) to send midi messages
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define MIDI_CHANNEL  1        // Pot value will be sent with CC#74 over channel 1 over MIDI port or USB
#define POT_CC        74       // CC#74 -> VCF's cutoff freq

Kilomux KmShield;              // Kilomux Shield    

unsigned int potInput = 0;     // Shield input where we connected a potentiometer or a sensor (0-15)

void setup() { 
  KmShield.init();                                    // Initialize Kilomux shield hardware

  #if defined(SERIAL_COMMS)
  Serial.begin(115200);                               // Initialize serial
  #elif defined(MIDI_COMMS)
  MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.turnThruOff();  // Initialize MIDI port. Turn MIDI-thru off, which is on by default
  #endif
}

void loop() {
  int analogData = 0;                                           // Variable to store analog values
  analogData = KmShield.analogReadKm(MUX_A, potInput);          // Read analog value from MUX_A and channel 'potInput' (0-15) 
  
  #if defined(SERIAL_COMMS)
  Serial.print("Pot reading: "); Serial.println(analogData);    // Print value at the serial monitor                        
  #elif defined(MIDI_COMMS)                                                                                                 
  MIDI.sendControlChange(POT_CC, analogData>>3, MIDI_CHANNEL);  // Or send midi message.                                 
                                                                // analogData >> 3, divides by 2^3 = 8, the value, to adjust to midi resolution (1024/8 = 128)
  #endif                                                                 
}

El ejemplo puede enviar mensajes para ver en el monitor serial del IDE de Arduino, o enviar mensajes MIDI por USB o por el puerto MIDI del Kilomux.

Para cambiar entre Serial o MIDI, se debe comentar una de las dos líneas 26 o 27.

#define SERIAL_COMMS          // Leave uncommented (and comment the line below) to send over serial
//#define MIDI_COMMS          // Leave uncommented (and comment the line above) to send midi messages

La línea

Kilomux KmShield;             // Kilomux Shield    

es la forma de indicarle a la Arduino que tiene un Kilomux Shield adherido, donde KmShield es un nombre a elección.

Donde dice

unsigned int potInput = 1;    // Identificador de la entrada donde se conectó el pin de señal de un sensor o potenciómetro (0-15)

reemplazar el número 1 con la entrada del puerto donde se colocó el potenciómetro.

Lo primero que hay que hacer, es inicializar el hardware del Kilomux, y esto se logra mediante la función init(), en el setup:

KmShield.init();                                    // Initialize Kilomux shield hardware

La función que lee el valor de la entrada se llama analogReadKM. Se le debe indicar cuál de los multiplexores se quiere leer (MUX_A o MUX_B), y qué canal del multiplexor (0-15):

analogData = KmShield.analogReadKm(MUX_A, potInput);          // Leer entrada analógica del canal 'potInput' (0-15) del MUX_A
  • Si la función tuvo éxito, devuelve un valor de 0 a 1023, correspondiente a la entrada leída.
  • Si alguno de los parámetros (multiplexor y canal) no son correctos, se devuelve -1.


Si se carga el código, al abrir el monitor serial, deberíamos ver la lectura en la pantalla. Una vez que el código funciona correctamente con el serial, podemos comentar la línea 26 y descomentar la 27, y cargar el código para que envíe mensajes MIDI.

J3

Los pines de entradas analógicas A2, A3, A4 y A5 no son utilizados por el shield y están disponibles para utilizarlos.

La lectura de los mismos es con la función analogRead() de las librerías estándar de Arduino.

Digitales

Los mismos puertos sirven para conectar sensores que tengan sólo dos valores, como por ejemplo botones.

La conexión se realiza de la misma forma en que se conecta un botón a la Arduino:

Para utilizar una entrada entera del Kilomux conectando botones, los mismos pueden cablearse o conectarse de la siguiente manera:

default

Aquí el ejemplo con un sólo botón y su explicación en cuanto al código:

default

Se puede elegir si colocar o no un resistor de PullUp o PullDown para cada botón, ya que se puede setear el PullUp interno para realizar la lectura.

Para leer el estado de un solo botón sin resistor de PullUp externo, abrir el ejemplo OneDigitalInputPullup:

/*
 * Author: Franco Grassano - YAELTEX
 * Date: 18/02/2016
 * ---
 * LICENSE INFO
 * Kilomux Shield by Yaeltex is released by
 * * Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) - http://creativecommons.org/licenses/by-sa/4.0/
 * ----
 * Description: Reads button setting internal PullUp resistor, and sends its state over serial or MIDI.
 *              Choose which, by commenting one of the lines, where it is indicated.
 *              This example is for use with the Kilomux Shield.
 * 
 * Kilomux Library is available at https://github.com/Yaeltex/Kilomux-Shield/blob/master/Arduino%20Code/KilomuxShield%20Library/KilomuxShield.zip
 */
 
#include <Kilomux.h>              // Import class declaration
#include <KilomuxDefs.h>          // Import Kilomux defines
#include <MIDI.h>                 // Import Arduino MIDI Library headers
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE() // Create a hardware instance of the library

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define SERIAL_COMMS          // Leave uncommented (and comment the line below) to send over serial
//#define MIDI_COMMS          // Leave uncommented (and comment the line above) to send midi messages
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define MIDI_CHANNEL  1        // Button will send NOTE_ON when pressed (0V/logical 0), and NOTE_OFF when released (5V/logical 1), over channel 1 over MIDI port or USB
#define BUTTON_NOTE   24       // Note 12 -> Pitch C-1

Kilomux KmShield;                 // Kilomux Shield  

unsigned int buttonInput = 0;     // Shield input where we connected a button or a sensor (0-15)
                                  // No need for 10K pull-up resistor in this example

bool buttonState = 1, lastState = 1;  // Variables to store digital values. Initialize off.

void setup() {
  KmShield.init();                                    // Initialize Kilomux shield hardware

  #if defined(SERIAL_COMMS)
  Serial.begin(115200);                               // Initialize serial
  #elif defined(MIDI_COMMS)
  MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.turnThruOff();  // Initialize MIDI port. Turn MIDI-thru off, which is on by default
  #endif
}

void loop() {
  buttonState = KmShield.digitalReadKm(MUX_B, buttonInput, PULLUP);     // Read digital value from MUX_A and channel 'buttonInput' (1-16), and set internal pullup    
  
  if(!buttonState && lastState){                                // If we read 0, and the last time we read 1, means button was just pressed
    #if defined(SERIAL_COMMS)
    Serial.println("Button state: ON");                             // Print value at the serial monitor        
    #elif defined(MIDI_COMMS)                                                                                   
    MIDI.sendNoteOn(BUTTON_NOTE, 127, MIDI_CHANNEL);                // Send midi message "note on"              
    #endif
  }
  else if(buttonState && !lastState){                           // If we read 1, and the last time we read 0, means button was just released
    #if defined(SERIAL_COMMS)
    Serial.println("Button state: OFF");                             // Print value at the serial monitor       
    #elif defined(MIDI_COMMS)                                                                                                                                                                                                   
    MIDI.sendNoteOff(BUTTON_NOTE, 0, MIDI_CHANNEL);                  // Send midi message "note off"            
    #endif
  }
  lastState = buttonState;                                        // Update last button state.
}

Para cambiar entre Serial o MIDI, se debe comentar una de las dos líneas 27 o 28.

#define SERIAL_COMMS          // Leave uncommented (and comment the line below) to send over serial
//#define MIDI_COMMS          // Leave uncommented (and comment the line above) to send midi messages

En este caso la función que realiza la lectura de una entrada digital es digitalReadKm, a la cual hay que indicarle a qué multiplexor (MUX_A o MUX_B) y en qué canal del mismo (1..16) está conectada la entrada a leer.

buttonState = KmShield.digitalReadKm(MUX_B, buttonInput, PULLUP);     // Leer el canal especificado por 'buttonInput', del MUX_A, y setear el resistor de PullUp interno

Si se coloca un resistor de PullUp físico, omitir el parámetro PULLUP y usar la función de la línea 14 de la siguiente manera:

buttonState = KmShield.digitalReadKm(MUX_B, buttonInput);     // Leer el canal especificado por 'buttonInput', del MUX_A. el cual tiene un resistor de PullUp externo.
  • Si la función tuvo éxito, devuelve el valor digital leído, es decir 0 o 1.
  • Si alguno de los parámetros (multiplexor y canal) no son correctos, se devuelve -1.

Cargando el código en la Arduino, al abrir el monitor serial, deberíamos ver la lectura en la pantalla.

Sensor de Ultrasonido (J1)

El puerto J1 (ver imágen en la introducción) del Kilomux shield está pensado para conectar un sensor de distancia ultrasónico HC-SR04, junto con un botón para activarlo y desactivarlo, y un LED indicador del estado de activación.

El puerto cuenta con cuatro pines digitales de la Arduino, y una conexión a 5V y a GND. En la siguiente imágen se ve la disposición de los mismos:

default

Y a continuación, mostramos el diagrama de conexión:

default

La librería que utilizamos para el manejo de éste sensor es la NewPing.

En el repositorio de GitHub del Kilomux shield se encuentra éste ejemplo de uso del sensor.

El código realiza la lectura del sensor, lo filtra para suavizar la señal leída (con filtro de media móvil) y los envía por Serial o por MIDI a través del USB.

El código se encuentra bien comentado, pero si surgieran dudas, se puede iniciar un tópico de discusión en el foro de Yaeltex.


Salidas

El Kilomux shield expande a 16 la cantidad de salidas digitales que tiene una Arduino UNO. Esto se logra usando dos registros de desplazamiento 74HC595 en cadena. Las salidas de estos integrados no pueden proporcionar mucha corriente, pero alcanza para encender algunos LEDs.

A ellos se pueden conectar en forma directa 16 LEDs monocromáticos a través de un resistor (220 ohms o similar) o 16 transistores para switchear relés, manejar motores o cargas que necesiten de una corriente mayor.

También se puede usar un arreglo matricial para manejar hasta 64 LEDs multiplexados.

Los puertos de salida del shield siguen la siguiente numeración:

default default

Conexión directa de LEDs y transistores

El esquema de conexión para un led o un transistor es el siguiente:

default

La resistencia de 100 ohms en serie regula la corriente que se le entrega al motor. Variando su valor, podemos variar la velocidad del eje del motor. Menor resistencia, mayor velocidad, y viceversa. Lo mismo sucede con la resistencia en serie con el LED, si se aumenta el valor, el LED brilla menos, ya que la corriente que lo atraviesa es menor.

El ejemplo "Blink" de la librería, muestra como cambiar el estado de una salida digital del shield:

/*
 * Author: Franco Grassano - YAELTEX
 * Date: 18/02/2016
 * ---
 * LICENSE INFO
 * Kilomux Shield by Yaeltex is released by
 * Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) - http://creativecommons.org/licenses/by-sa/4.0/
 * ----
 * Description: Blink an LED.
 *              This example is for use with the Kilomux Shield.
 * 
 * Kilomux Library is available at https://github.com/Yaeltex/Kilomux-Shield/blob/master/Arduino%20Code/KilomuxShield%20Library/KilomuxShield.zip
 */
 
#include <Kilomux.h>          // Import class declaration
#include <KilomuxDefs.h>      // Import Kilomux defines

Kilomux KmShield;             // KiloMux Shield   

#define MS_ON  1000             // Number of milliseconds the LED will be on 
#define MS_OFF 1000             // Number of milliseconds the LED will be off

unsigned int ledOutput = 1;   // KiloMux output where we already connected an LED (0-15)

void setup() {
  KmShield.init();                                    // Initialize Kilomux shield hardware
}

void loop() {
  KmShield.digitalWriteKm(ledOutput, HIGH);     // Turn led on
  delay(MS_ON);                                 // Wait. LED is on.
  KmShield.digitalWriteKm(ledOutput, LOW);      // Now turn it off. 
  delay(MS_OFF);                                // Wait. It's off.
}

Como antes, se instancia un objeto de la clase Kilomux llamado "KmShield", en la línea 18, y se lo inicializa con la función init() en el setup.

Luego, para cambiar el estado de una salida digital, se utiliza la función digitalWriteKm:

KmShield.digitalWriteKm(ledOutput, HIGH);     // Turn led on

donde ledOutput es el número de salida (de 1 a 16) que se quiere modificar. Luego se indica con HIGH o LOW, o 1 o 0, el nuevo estado de la salida.

Conexión matricial de LEDs

Utilizando la totalidad de las salidas podríamos conectar en forma matricial hasta 64 LEDs monocromáticos, dispuestos en 8 filas y 8 columnas.

A continuación mostramos un ejemplo simplificado de conexión de una matriz de LEDs de 4 filas y 4 columnas:

default

En este ejemplo, las filas son controladas por las salidas 1 a 4, y las columnas por las salidas 9 a 12.

La Arduino tiene un límite de corriente de 40 mA por pin, lo que alcanza para un LED, pero no es mucho si empezamos a poner muchos LEDs en paralelo (cuando se tienen LEDs en paralelo, las corrientes se suman). Por esto es que en cada fila se coloca un transistor BC337 para manejar la corriente de toda la fila, y la Arduino sólo tiene que encender y apagar el transistor. Para esto, los 40 mA que entrega cada pin de la Arduino son más que suficientes.

En las columnas esto no es necesario, ya que gracias al multiplexado, soló va a haber un LED prendido en cada columna a la vez.

El USB de una computadora entrega hasta 500 mA, por lo que dependiendo de la corriente que necesita cada LED para funcionar, la cantidad de filas y de los valores de los resistores usados en las columnas, posiblemente se deba alimentar la matriz con un transformador que tenga la corriente suficiente para ello.

Cuando una fila tiene 5V y la columna correspondiente tiene 0V, el LED en esa posición se enciende. Con cualquier otra combinación, el LED se apaga.

En el github del proyecto Kilomux, se encuentra un código de ejemplo, comentado en español, para encender uno a uno, en forma secuencial, todos los LEDs de esta matriz.

Se usa un multiplexado de filas, eso significa que en realidad sólo una fila está encendida a la vez, sólo que se recorren todas a una velocidad tal que aparentan estar todas encendidas todas en simultáneo. Si se aumenta el número de filas, se debería disminuir el tiempo que cada una está encendida, y viceversa, para mantener el efecto.

default

(gif tomado de este instructable)

En éste código de ejemplo, es importante que las filas y las columnas sean controladas por dos puertos disitintos, es decir, si las filas están en OUT-1, las columnas en OUT-2, o viceversa.


Conexiones MIDI

El Kilomux Shield cuenta con una conexión MIDI física a través dos conectores mini-plug de 3.5 mm. Uno es una conexión MIDI OUT y el otro MIDI IN.

¡CUIDADOǃ
No conectar al revés estos cables, ya que de esta forma puede quedar inutilizable tu Arduino.

default

Es importante recordar que la conexión MIDI con otros instrumentos, no permite la comunicación USB simultánea, es decir que se debe alimentar la Arduino con una fuente de alimentación DC.

Para poder utilizar esta conexión debemos contar con dos cables MIDI que en alguno de sus extremos tengan un conector mini-plug macho de 3.5mm, que respete la siguiente convención:

default

J2

Si se utiliza la conexión MIDI IN, se debe además unir ambos pines del jack J2. Este jumper conecta la línea RX (pin 0 de la Arduino) al jack MIDI IN.

default

Para utilizar la comunicación USB (programar la Arduino, usar el monitor Serial, etc) se debe quitar el jumper que conecta ambos pines.

default

La razón por la que esto sucede es porque la conexión serial que utiliza el procesador de la Arduino para comunicarse (tanto por USB, cómo con otros dispositivos) es punto a punto, es decir sólo puede haber un transmisor y un receptor en simultáneo.

Puerto de programación ISP (Atmega 8u2/16u2)

Usando el firmware HIDUINO, muchas veces era necesario re-programar la Arduino para corregir errores en el código. Para ello es necesario volver a programar el Atmega 8u2/16u2 con el firmware original USB<->Serial, de forma que el IDE reconozca nuestra Arduino.

Cuando además usábamos el Kilomux Shield, se nos hacía un poco tedioso tener que separar el shield de la Arduino, reprogramarla y volver a colocar el shield. Además, corríamos el riesgo de que se aflojen las soldaduras de los pines.

Con ésto en mente, colocamos una extensión al puerto de programación ISP del chip Atmega 8u2/16u2, de forma de poder programarlo sin tener que remover el shield de la Arduino.

default


Archivos de Eagle

El Kilomux Shield para Arduino, por Yaeltex, está bajo Licencia Creative Commons Atribución-CompartirIgual 4.0 Internacional

Esquemático -> default

Circuito -> default

Referencias

· Arduino UNO

· Código para controlador MIDI con Kilomux Shield + Arduino

. Tutorial de soldadura para el Kit de Kilomux Shield

· Librería Kilomux Shield

· Librería Arduino MIDI 4.2

· Proyecto HIDUINO

· Instructivo para recompilar y programar HIDUINO mediante ISP

· Tutorial para programar HIDUINO mediante DFU (Sólo Windows)

Hojas de datos y uso de componentes del Kilomux

· CD4067

· Librería MuxShield de Mayhew Labs - Uso de 4067

· 74HC595

· Código para el uso de 74HC595

· Hoja de datos del sensor HC-SR04

· Librería New Ping (uso del sensor ultrasónico HC-SR04)