Truco Arduino: Usar cualquier opto-cupla de baja ganancia para MIDI

midi_in arduino uno - low gain opto_schem2

Cuando hablamos de MIDI y Arduino, todos usan la opto-cupla 6N138, y por un buen motivo. ¡Tiene una ganancia relativamente alta!

Imaginate que te ataca la inspiración y no podés encontrar un 6N138 en tu stock. ¡Oh no! pero encontrás otra opto-culpa y un transistor NPN. ¡Todavía podés safar!

Una ganancia alta es necesaria porque:

  1. Usualmente una resistencia de 470Ω conectada a +5V  se usa para superar la resistencia de 1kΩ que el Arduino conecta al chip USB-a-Serial (que está a 5V o 0V), para que el pin 0 (RX) lea un valor digital ALTO.
  2. La interfaz MIDI tiene que poder absorber al rededor de 20mA de esa resistencia para conseguir un voltaje suficientemente bajo para que el Arduino lo tome como un digital BAJO.

El problema con las opto-cuplas “normales” es que su ganancia, o más técnicamente de hoja de datos, “Proporción de transferencia de corriente” (CTR por sus siglas en inglés: Current Transfer Ratio”), es usualmente menor al 100%. Ej. si una opto tiene un CTR del 20% significa que si le metés 15mA este dejará pasar solo 3mA en su salida (el caso del 6N136 o 4N25). El 6N138, por otro lado, tiene un CTR de ~2000%, y 15mA dejaría pasar ¡hasta 300mA! ¿Se vé la diferencia?

La opto-cupla

Una opto-cupla por dentro es en efecto un LED que emite luz infra-roja a un foto-sensor que convierte esa luz en una corriente ínfima, que luego es amplificada por un transistor. Es un dispositivo estrictamente dominado por la corriente, como los transistores BJT. Vos controlas la corriente de entrada y obtenes una corriente de salida que es un porcentaje de la de entrada (para cierto rango). Luego podés convertir esa corriente a voltaje con una resistencia por ley de Ohm.

Uno podría pensar “bueno, simplemente le subimos la corriente de entrada” pero existe el límite físico de lo que soporta el LED antes de quemarse (o reducir su vida útil). Usualmente el máximo son 20mA. 20mA con un CTR del 20% nos deja igualmente una salida de unos pobres 4mA, no más.
Además, puede que haya una resistencia limitando desde el otro lado del cable MIDI (o el cable mismo), y no podés contar con eso. Necesitás otro transistor más para amplificar esa corriente débil entregada por la opto-cupla.

El truco está en copiar la manera en la que está internamente conectado el 6N138, agregando el transistor apropiadamente.

6n136-6n138

Y acá hay un diagrama de como lo estoy haciendo yo. El circuito integrado es un 6N136 y el transitor NPN un BC547, pero casi cualquier otro NPN que soporte 20mA o más y tenga una ganancia de 20 o más funcionaría, como el 2N2222, 2N3904, etc.

Yo usé un 6N136 (probado) pero vos podés probar con otras opto-cuplas. El 4N25 puede funcionar tambien (no probado), pero tené en cuenta que tienen diferente orden de pines. Ambos trabajan en el rango de 250kHz asi que están bien para la frecuencia relativamente lenta de ~32kHz del protocolo MIDI.

midi_in arduino uno - low gain opto_bb

midi_in arduino uno - low gain opto_schem2

Bajar archivo Fritzing midi_in arduino uno – low gain opt.fzz

Un poco de matemática para la explicación técnica.

La hoja de datos del ATmega328P (En el que se basa el Arduino UNO) especifica que para 5V de Vcc, un valor digital BAJO es un voltaje debajo de 1.5V y un digital ALTO es un valor sobre 3V. Para estar seguros vamos a apuntar a valores menores de 1.5V y mayores a 3V.

El Pin 0 (RX) del Arduino está conectado por una resistencia de 1kΩ al chip conversor USB-a-Serial (ATMega8U2 en mi caso). No sabemos cuando va a estar alto o bajo, asi que tenemos que “sobreescribir” este valor con el nuestro. La resistencia típica de 470Ω forma un divisor de voltaje:

Teniendo en cuenta que Vo = Vi * R2 / (R1+R2)
‘Vo = 5V * 1000Ω / (470Ω+1000Ω) = 3.4V

Así que en cualquier momento, el pin 0 va a estar entre 3.4V and 5V. Eso es un valor ALTO.

Ahora necesitamos tirar esos 3.4-a-5V por debajo de 1.5V cuando nos llegue un pulso MIDI.

Si el chip USB esta bajo, solo necesitamos absorber 11mA (Ley de Ohm, 5V/470Ω ≈ 0.011mA), pero si está alto, ambas resistencias de 1kΩ and 470Ω estan en paralelo, formando una resistencia menor de ~320Ω (R1*R2/(R1+R2)). En este caso necesitamos absorber al menos 17mA para cubrir ambos casos.

Con la corriente de entrada de la opto-cupla en 15mA y un CTR de 20% podriamos absorber 3mA, pero multiplicandolo por la ganancia (hFE) del nuestro transistor NPN (en el caso del BC547 es al rededor de 200), tendriamos un CTR de %4000 y podríamos absorber hasta 600mA de corriente. 600mA quemarian este pequeño transistor pero la resistencia mínima de 320Ω limita el máximo de corriente al rededor de ~17mA.

Datasheets para referencia (en inglés): 4N25 6N136 6N138 ATmega328P

¡Buena suerte!

6 comments

  1. Daz dice:

    Great hack and great explanation, thanks and well done!

  2. Luciano dice:

    Dude, thanks a lot! It helped me to solve a problem with optos(6n135, the best I found in local store) and Arduino. I’ve worked 5 days on it. Very well explained.

  3. Tarci dice:

    Gracias por el articulo!
    Quiero aportar que probe con la optocupla 4N25 y anduvo!
    Al principio no me anduvo pero porque conecte el pin 6 del 4N25 a VCC, el pin correspondiente del 4N136 seria el pin 7, que queda desconectado.

  4. Sebas Carra dice:

    Básicamente, lo que estamos haciendo acá es completar un par Darlington, donde usamos el optoacoplador para controlar otro transistor que (a su vez) controla la salida del sistema (alta o baja).

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *