Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Controlador de Respiración Arduino Asequible con Integración USB-MIDI

Componentes y Suministros

Componente Cantidad Notas
Arduino Micro 1 Solo el Micro (ATmega32U4) funciona por sus capacidades USB nativas. Se recomienda el original.
Protoboard media 1
Sensor de Presión MPS20N0040D-D 1 Muy barato y fácil de encontrar.
Amplificador Operacional LM358-N 1 Amplifica la señal del sensor.
Resistencia 1M Ω 2
Kit de cables 22 AWG 1 Solo necesita unos cm de cable rígido.
Aspirador Nasal para Bebé 1 Se usa la boquilla del lado del padre y el aspirador del lado del bebé. Hay docenas de aspiradores manuales del mismo tipo (ej. Physiomer, Chicco Physioclean). Elija la boquilla más cómoda.
Tubo para acuario 5mm 1 Opcional, si el tubo del aspirador no es lo suficientemente largo.
Conector en T para tubo de aire 1 Se encuentra fácilmente en tiendas de acuario. Encaja directamente en el sensor.

Herramientas Necesarias

Aplicaciones y Servicios Online

Descripción del Proyecto

Introducción

En este proyecto construiremos un controlador de respiración USB MIDI plug-and-play simple. Está diseñado con componentes baratos y fáciles de encontrar para que el coste total sea asequible y muy inferior a los equivalentes comerciales. Esta es la versión básica que solo usa el sensor de presión de aire, pero el plan es actualizarlo para incluir sensor de mordida y de inclinación/asentimiento en el futuro.

El proyecto asume conocimientos muy básicos de electrónica y Arduino, pero incluso un principiante puede construirlo ya que no requiere soldadura. Usuarios más avanzados pueden soldar todo en una protoboard definitiva. No cubro la instalación del IDE/librerías ni las instrucciones para subir el código, ya que hay excelentes tutoriales en internet.

Se usa sobremuestreo (oversampling) para suavizar la entrada del sensor con muy buenos resultados. También puede ajustar el rango a su gusto e incluso definir curvas personalizadas para ajustar el comportamiento del controlador.

Como el sensor puede medir presión negativa también, hay una segunda corriente de mensajes de control que se emite cuando aspira aire en lugar de soplar. Ambos tipos de mensajes pueden configurarse por el usuario. Por ejemplo, puede configurar "soplar" para pitch bend up y "aspirar" para pitch bend down. Por defecto, ambos están en controlador n.º 2.

Pasos de Construcción

  1. Inserte el Arduino en la protoboard como se muestra en la foto/esquemático.
  2. Inserte el sensor y el amplificador operacional en sus posiciones, observe la orientación según las muescas en sus lados.
  3. Inserte las resistencias tras cortar sus patas a longitudes adecuadas.
  4. Corte/pelé los cables rígidos y colóquelos en sus posiciones. He usado rojo para 5V, negro para tierra y amarillo para señal para facilitar la comprensión, pero puede usar lo que tenga.
  5. Conecte la boquilla, tubo, conector en T y aspirador como se muestra en la foto. Necesitará cortar un trozo de tubo para la "salida de escape".
  6. Presione el conector en T para que encaje en el sensor. Debe quedar fijo.
  7. Instale el Arduino IDE e instale las dos librerías necesarias (Oversampling y USB-MIDI) desde Herramientas → Gestionar librerías. Conecte el Arduino con cable USB a su computadora. Suba el código adjunto.
  8. Debería estar listo: el Arduino debería aparecer como dispositivo MIDI en su DAW/Software musical. Actívelo y enrútelo junto con su teclado a un plugin que soporte controlador de respiración.

Información Avanzada

Un inconveniente físico de este diseño es la saliva que inevitablemente fluirá por el tubo y puede causar fluctuaciones notables en el flujo de aire. El conector en T se usa para abordar este problema dirigiendo la saliva al tubo de "escape". Para minimizar la saliva atrapada en el tubo, asegúrese de que hay una pendiente continua desde la boquilla al conector en T ajustando la longitud del tubo. Si el tubo cuelga por debajo del nivel del conector en T, la saliva se atrapará en su punto más bajo causando fluctuaciones. La parte del lado del bebé del aspirador incluyendo su filtro se conecta al escape para minimizar goteos, ruido y aumentar el flujo de aire al sensor.

En el código hay valores que puede ajustar a su gusto, incluyendo curvas personalizadas. Los comentarios describen cómo hacerlo. Si le cuesta llegar al valor 127, disminuya el rango máximo; si es demasiado fácil, auméntelo. Cuando cambie valores, deberá volver a subir el código.

Las primeras lecturas tras el arranque del Arduino se promedian para calibrar el punto de reposo. No sople en el tubo mientras conecta/resetea el dispositivo.

Puede cambiar el nombre del dispositivo MIDI editando el archivo boards.txt (información sobre cómo hacerlo para cada plataforma está disponible en internet).

Código

Código del Controlador de Respiración (Arduino)

/* Controlador de Respiración */
// Librerías usadas - instálelas desde Herramientas -> Gestionar Librerías
#include <Oversampling.h>
#include <USB-MIDI.h>

// Modo debug (descomente para habilitar)
//#define DEBUG 1

// Creación de la interfaz USB MIDI
USBMIDI_CREATE_DEFAULT_INSTANCE();

// Inicialización Oversampling
Oversampling adc(10, 13, 6);

// ***************** Configuración del Usuario *****************
// Valores terminados en 1 corresponden a soplar, terminados en 2 a aspirar

// Configuración de pines
const int sensorPin1 = A0; // Pin de entrada Arduino para salida Sensor/OpAmp

// Calibración de Rango. Ajuste manualmente para alcanzar el máximo pero no demasiado fácilmente.
int sensorRange1 = 800;
int sensorRange2 = 800;

// Número de controlador de salida. Seleccione de la tabla:
// 0-127: mensajes control change regulares
// 128: aftertouch monofónico
// 129: Pitch Bend Up
// 130: Pitch Bend Down
int controllerNumber1 = 2; // Controlador al soplar
int controllerNumber2 = 2; // Controlador al aspirar

// Canales de controlador de salida
int controllerChannel1 = 1;
int controllerChannel2 = 1;

// Umbrales de seguridad para valores más bajos y altos para evitar fluctuaciones en reposo o al máximo.
// Si se envían múltiples mensajes en reposo, aumente lowThreshold.
// Si se envían múltiples mensajes al máximo, aumente highThreshold.
const int lowThreshold1 = 5;
const int lowThreshold2 = 5;
const int highThreshold1 = 0;
const int highThreshold2 = 0;

// Definición de curvas. Las tablas pueden tener cualquier longitud >= 2. Valores 0-127.
// Las tablas "in" deben estar en orden ascendente.
int in1[] = {0, 127};
int out1[] = {0, 127};
int in2[] = {0, 127};
int out2[] = {0, 127};

// Curvas de ejemplo (modifique el número de sensor accordingly)
// Suave
//int in1[] = {0, 6,24,78,127};
//int out1[] = {0,32,64,96,127};
// Rango reducido
//int in1[] = {50, 100};
//int out1[] = {50, 100};

// Ciclo de refresco (milisegundos). Valores más bajan = más mensajes enviados.
int refreshCycle = 0;

// ***************** Implementación *****************
// No modifique a partir de aquí si no pretende alterar el funcionamiento del sensor.

// Valores internos de sensores
int sensorValue1 = 0;
int sensorValue2 = 0;

// Valores mínimos de sensores
int sensorMin1;
int sensorMin2;

// Valores de controlador de salida
int controllerValue1 = 0;
int controllerValue2 = 0;

// Valores del ciclo anterior para evitar repetición de mensajes idénticos
int previousControllerValue1 = 0;
int previousControllerValue2 = 0;

// Variables de conversión de rango
int outputRange1;
int outputRange2;
int sensorLow1;
int sensorLow2;
int sensorHigh1;
int sensorHigh2;

void setup() {
  MIDI.begin(1);
  #ifdef DEBUG
  Serial.begin(115200); // Solo para modo debug
  #endif

  // Calibre el punto de reposo del sensor promediando 10 primeros valores.
  // No use el sensor mientras arranca el dispositivo.
  sensorMin1 = adc.read(sensorPin1);
  sensorMin2 = 0;

  // Determine rangos de salida para los controladores elegidos
  outputRange1 = outputRange(controllerNumber1);
  outputRange2 = outputRange(controllerNumber2);
}

void loop() {
  // Lea el valor del sensor:
  sensorValue1 = adc.read(sensorPin1);
  // Soplando aire
  sensorValue2 = sensorMin1 - sensorValue1; // Aspirando aire

  // Guarde valores anteriores
  previousControllerValue1 = controllerValue1;
  previousControllerValue2 = controllerValue2;

  // Límites de rango usable para sensor arriba/abajo
  sensorLow1 = sensorMin1 + lowThreshold1;
  sensorLow2 = sensorMin2 + lowThreshold2;
  sensorHigh1 = sensorLow1 + sensorRange1 - highThreshold1;
  sensorHigh2 = min(sensorMin1, sensorRange2) - highThreshold2;

  // Convierta valores internos a rango de salida (0..127 para controladores/aftertouch, 0..+/-8191 para Pitchbend)
  // usando las curvas definidas en tablas "in" y "out".
  controllerValue1 = map(mapToCurve(constrain(sensorValue1, sensorLow1, sensorHigh1), sensorLow1, sensorHigh1, in1, out1, sizeof(in1)/sizeof(int)), sensorLow1, sensorHigh1, 0, outputRange1);
  controllerValue2 = map(mapToCurve(constrain(sensorValue2, sensorLow2, sensorHigh2), sensorLow2, sensorHigh2, in2, out2, sizeof(in2)/sizeof(int)), sensorLow2, sensorHigh2, 0, outputRange2);

  // Envíe mensajes MIDI
  if (controllerValue1 != previousControllerValue1) sendSensorOutput(controllerNumber1, controllerValue1, controllerChannel1);
  if (controllerValue2 != previousControllerValue2) sendSensorOutput(controllerNumber2, controllerValue2, controllerChannel2);

  // Debug
  #ifdef DEBUG
  // Valores sensor (entrada) (descomente para debug)
  // Serial.print(sensorValue1); Serial.print(","); Serial.print(sensorValue2); Serial.print(",");
  // Valores controlador (salida)
  Serial.print(controllerValue1); Serial.print(","); Serial.println(controllerValue2);
  #endif

  delay(refreshCycle);
}

// Función para enviar mensajes MIDI según número de controlador
void sendSensorOutput(int number, int value, int channel) {
  if (number < 128) MIDI.sendControlChange(number, value, channel);
  else if (number == 128) MIDI.sendAfterTouch(value, channel);
  else if (number == 129) MIDI.sendPitchBend(value, channel);
  else if (number == 130) MIDI.sendPitchBend(-value, channel);
}

// Función para determinar el rango de un controlador específico
int outputRange(int number) {
  if (number > 128) return 8191;
  else return 127;
}

// Función multiMap modificada para crear curvas. Original de Rob Tillaart.
int mapToCurve(int val, int sensorLow, int sensorHigh, int* _in, int* _out, uint8_t size) {
  if (val <= map(_in[0], 0, 127, sensorLow, sensorHigh)) return map(_out[0], 0, 127, sensorLow, sensorHigh);
  if (val >= map(_in[size-1], 0, 127, sensorLow, sensorHigh)) return map(_out[size-1], 0, 127, sensorLow, sensorHigh);

  uint8_t pos = 1;
  while(val > map(_in[pos], 0, 127, sensorLow, sensorHigh)) pos++;

  int inPos = map(_in[pos], 0, 127, sensorLow, sensorHigh);
  int outPos = map(_out[pos], 0, 127, sensorLow, sensorHigh);
  int inPrv = map(_in[pos-1], 0, 127, sensorLow, sensorHigh);
  int outPrv = map(_out[pos-1], 0, 127, sensorLow, sensorHigh);

  if (val == inPos) return outPos;

  return ((long)val - (long)inPrv) * ((long)outPos - (long)outPrv) / ((long)inPos - (long)inPrv) + (long)outPrv;
}

Esquemáticos

Proceso de manufactura

  1. Panel de control para Flight Simulator 2020 con Arduino Nano: Pantallas LCD y CDI
  2. Sistema de Iluminación DMX Controlado por Web – Controlador Maestro Arduino
  3. Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
  4. Unopad: Controlador MIDI Arduino para Ableton Live sin complicaciones
  5. Teletransportador de Texto Bluetooth: Arduino + Android
  6. Kit controlador para display fluorescente al vacío (VFD) basado en Arduino
  7. Controlador doméstico Arduino con Alexa: Automatización inteligente simplificada
  8. Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
  9. Librería Eficiente de Puerto I/O de 8 Bits para Arduino – Expande el Control Digital
  10. Circuito de entrada analógica aislada para Arduino
  11. Kit de Robot de Navegación Interior Inteligente para Proyectos Arduino