Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Betaalbare Arduino Ademcontroller met USB-MIDI-integratie

Onderdelen en benodigdheden

Arduino Micro 1
Solderloos breadboard (half formaat) 1
MPS20N0040D-D Druksensor 1
LM358-N Op-Amp 1
Weerstand 1M ohm 2
Hook-up draad kit, 22 AWG 1
Baby neusaspirator 1
5mm aquarium luchtbuis 1
3-weg luchtbuis connector 1

Nodige gereedschappen en machines

Draadstripper & knipper, 32-20 AWG / 0.05-0.5mm²

Apps en online diensten

Arduino IDE

Over dit project

Inleiding

In dit project bouwen we een eenvoudige USB MIDI plug-and-play ademcontroller. Het is ontworpen met makkelijk te vinden, goedkope componenten zodat de totale kosten betaalbaar blijven en ver onder commerciële equivalenten. Dit is de basisonly versie die alleen de luchtdruksensor gebruikt, maar de planning is om het in de toekomst uit te breiden met een bijt- en knik/kantel-sensor.

Het project vergt enige basiskennis van electronica en Arduino, maar zelfs een beginner kan het bouwen omdat er geen solderen nodig is. Gevorderde gebruikers kunnen alles op een perma-protoboard solderen. Ik behandel niet de installatie van de IDE/bibliotheken en instructies om code te uploaden, omdat er uitstekende tutorials op internet zijn.

Oversampling wordt gebruikt om de sensorinput glad te maken met uitstekende resultaten. Je kunt het bereik naar wens aanpassen en zelfs aangepaste curves instellen om het gedrag van de controller aan te passen.

Omdat de sensor ook negatieve druk kan meten, is er een tweede stroom controllerberichten die wordt uitgevoerd wanneer je lucht intrekt in plaats van uitblaast. Beide typen berichten kunnen door de gebruiker ingesteld worden. Bijvoorbeeld: uitblazen = pitch bend omhoog, intrekken = pitch bend omlaag. Standaard zijn beide ingesteld op controllernummer 2.

Bouwstappen

  1. Plaats de Arduino op het breadboard zoals getoond in de foto/schema.
Betaalbare Arduino Ademcontroller met USB-MIDI-integratie
  1. Plaats de sensor en op-amp op hun respectieve posities, let op de oriëntatie gebaseerd op de kleine insnijdingen aan hun zijkanten.
  2. Plaats de weerstanden na het inkorten van de poten tot de juiste lengte.
  3. Kort/strip de massieve draadjes en plaats ze op hun respectieve posities. Ik heb rood gebruikt voor 5V, zwart voor ground en geel voor signaal om het duidelijker te maken, maar je kunt natuurlijk gebruiken wat je hebt.
  4. Verbind het mondstuk, de buis, de 3-weg connector en de aspirator zoals getoond in de foto. Je moet een stukje van de buis afknippen voor de „uitlaat”.
Betaalbare Arduino Ademcontroller met USB-MIDI-integratie
  1. Druk de 3-weg connector op de sensor. Hij moet vast zitten.
Betaalbare Arduino Ademcontroller met USB-MIDI-integratie
  1. Installeer de Arduino IDE en installeer de twee benodigde bibliotheken (Oversampling en USB-MIDI) via Tools → Manage Libraries. Verbind de Arduino met een USB-kabel met je computer. Upload de bijgevoegde code.
  1. Je zou nu klaar moeten zijn. De Arduino zou nu als een MIDI-apparaat moeten verschijnen in je DAW/Muzieksoftware. Schakel het in en routeer het samen met je toetsenbord naar een plug-in die ademcontroller ondersteunt.
Betaalbare Arduino Ademcontroller met USB-MIDI-integratie
Betaalbare Arduino Ademcontroller met USB-MIDI-integratie

Geavanceerde informatie

Een fysiek nadeel van dit ontwerp is de speeksel die onvermijdelijk in de buis vloeit en zichtbare luchtstroomfluctuaties kan veroorzaken. De 3-weg connector lost dit op door de speeksel naar de „uitlaat”-buis te leiden. Om vastgelopen speeksel in de buis te minimaliseren, zorg ervoor dat er een continu helling is van het mondstuk naar de 3-weg connector door de buislengte aan te passen. Als de buis onder het niveau van de 3-weg connector hangt, zal speeksel vastlopen op het laagste punt wat fluctuaties veroorzaakt. Het baby-deel van de aspirator inclusief filter is aan de uitlaat bevestigd om druppelen en geluid te minimaliseren en de luchtstroom naar de sensor te vergroten.

In de code zijn waarden die je naar wens kunt aanpassen, inclusief aangepaste curves. Commentaar beschrijft hoe dit te doen. Als je het moeilijk vindt om het 127-punt te bereiken, verlaag dan het maximale bereik, of als het te makkelijk is, verhoog het. Wanneer je waarden wijzigt, moet je de code opnieuw uploaden.

De eerste paar metingen na het opstarten van de Arduino worden gemiddeld om de rustpositie te kalibreren. Blaas niet in de buis terwijl je het apparaat aansluit/reset.

Je kunt de naam van het MIDI-apparaat wijzigen door het boards.txt-bestand te bewerken (informatie over hoe dit voor elk platform te doen is op internet beschikbaar).

Code

Ademcontroller-code (Arduino)

/* Ademcontroller */
// Bibliotheken - installeer via Tools->Manage Libraries
#include <Oversampling.h>
#include <USB-MIDI.h>

// Debug-modus (uncomment om in te schakelen)
//#define DEBUG 1

// USB MIDI-interface aanmaken
USBMIDI_CREATE_DEFAULT_INSTANCE();

// Oversampling initialiseren
Oversampling adc(10, 13, 6);

// ***************** Gebruikersinstellingen *****************
// Waarden eindigend op 1 corresponderen met uitblazen, op 2 met intrekken
const int sensorPin1 = A0; // Arduino-inputpin voor sensor/Op-Amp-uitgang

// Bereik kalibratie. Handmatig aanpassen zodat je maximum kunt bereiken maar niet te makkelijk.
int sensorRange1 = 800;
int sensorRange2 = 800;

// Uitgangscontrollernummer. Kies uit onderstaande tabel
// 0-127: gewone control change berichten
// 128: monofone aftertouch
// 129: Pitch Bend Up
// 130: Pitch Bend Down
int controllerNumber1 = 2; // Controller bij uitblazen
int controllerNumber2 = 2; // Controller bij intrekken

// Uitgangscontrollerkanalen
int controllerChannel1 = 1;
int controllerChannel2 = 1;

// Veiligheidsdrempels voor laagste en hoogste waarden om fluctuaties bij rust of max te voorkomen.
// Als er meerdere berichten bij rust worden verstuurd, verhoog lowThreshold.
// Als er meerdere berichten bij max worden verstuurd, verhoog highThreshold.
const int lowThreshold1 = 5;
const int lowThreshold2 = 5;
const int highThreshold1 = 0;
const int highThreshold2 = 0;

// Curve-definitie. Tabellen kunnen elke lengte hebben gelijk of groter dan 2. Waarden 0-127. Tabellen moeten evenveel elementen hebben en "in"-tabellen oplopend.
int in1[] = {0, 127};
int out1[] = {0, 127};
int in2[] = {0, 127};
int out2[] = {0, 127};

// Voorbeeldcurves (sensor-nummer dienovereenkomstig aanpassen)
// Zacht
//int in1[] = {0, 6,24,78,127};
//int out1[] = {0,32,64,96,127};
// Verminderd bereik
//int in1[] = {50, 100};
//int out1[] = {50, 100};

// Vernieuwingscyclus (milliseconden). Lagere waarden = meer berichten tijdens operatie.
int refreshCycle = 0;

// ***************** Implementatie *****************
// Niet wijzigen vanaf hier tenzij je de werking wilt aanpassen.

// Interne sensorwaarden
int sensorValue1 = 0;
int sensorValue2 = 0;

// Minimale sensorwaarden
int sensorMin1;
int sensorMin2;

// Uitgangscontrollerwaarden
int controllerValue1 = 0;
int controllerValue2 = 0;

// Vorige cycluswaarden om herhaling van identieke berichten te voorkomen
int previousControllerValue1 = 0;
int previousControllerValue2 = 0;

// Bereikconversie-variabelen
int outputRange1;
int outputRange2;
int sensorLow1;
int sensorLow2;
int sensorHigh1;
int sensorHigh2;

void setup() {
  MIDI.begin(1);
  #ifdef DEBUG
  Serial.begin(115200); // Alleen voor debug-modus
  #endif

  // Kalibreer sensor-rustpunt door eerste 10 waarden te middelen. Gebruik sensor niet tijdens opstarten.
  sensorMin1 = adc.read(sensorPin1);
  sensorMin2 = 0;

  // Bepaal uitgangsbereiken voor gekozen controllers
  outputRange1 = outputRange(controllerNumber1);
  outputRange2 = outputRange(controllerNumber2);
}

void loop() {
  // Waarde van sensor lezen
  sensorValue1 = adc.read(sensorPin1); // Uitblazen
  sensorValue2 = sensorMin1 - sensorValue1; // Intrekken

  // Vorige waarden opslaan
  previousControllerValue1 = controllerValue1;
  previousControllerValue2 = controllerValue2;

  // Bruikbare bereikgrenzen voor sensor omhoog/omlaag
  sensorLow1 = sensorMin1 + lowThreshold1;
  sensorLow2 = sensorMin2 + lowThreshold2;
  sensorHigh1 = sensorLow1 + sensorRange1 - highThreshold1;
  sensorHigh2 = min(sensorMin1, sensorRange2) - highThreshold2;

  // Interne waarden omzetten naar uitgangsbereik (0..127 voor controllers/aftertouch, 0..+/-8191 voor Pitchbend) met curves uit "in" en "out" tabellen.
  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);

  // MIDI-berichten sturen
  if (controllerValue1 != previousControllerValue1) sendSensorOutput(controllerNumber1, controllerValue1, controllerChannel1);
  if (controllerValue2 != previousControllerValue2) sendSensorOutput(controllerNumber2, controllerValue2, controllerChannel2);

  // Debug
  #ifdef DEBUG
  // Sensor (input) waarden (uncomment voor debug)
  // Serial.print(sensorValue1);
  // Serial.print(",");
  // Serial.print(sensorValue2);
  // Serial.print(",");
  // Controller (output) waarden
  Serial.print(controllerValue1);
  Serial.print(",");
  Serial.println(controllerValue2);
  #endif

  // Programma stoppen voor  milliseconden
  delay(refreshCycle);
}

// Functie om MIDI-berichten te sturen volgens controllernummer
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);
}

// Functie om bereik van specifieke controller te bepalen. Pitch bend heeft groter bereik dan gewone controllers.
int outputRange(int number) {
  if (number > 128) return 8191;
  else return 127;
}

// Gewijzigde multiMap-functie voor curves. Origineel door Rob Tillaart.
int mapToCurve(int val, int sensorLow, int sensorHigh, int* _in, int* _out, uint8_t size) {
  // Zorg dat waarde binnen bereik is
  // val = constrain(val, _in[0], _in[size-1]);
  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);

  // Juist interval zoeken
  uint8_t pos = 1; // _in[0] al getest
  while(val > map(_in[pos], 0, 127, sensorLow, sensorHigh)) pos++;

  // Bereik aanpassen van ..127 naar sensorbereik
  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);

  // Exacte "punten" in _in-array afhandelen
  if (val == inPos) return outPos;

  // Interpoleren in juist segment voor de rest
  return ((long)val - (long)inPrv) * ((long)outPos - (long)outPrv) / ((long)inPos - (long)inPrv) + (long)outPrv;
}

Schema's

Fritzing-schema

Betaalbare Arduino Ademcontroller met USB-MIDI-integratie

CircuitLab-schema

Betaalbare Arduino Ademcontroller met USB-MIDI-integratie

Productieproces

  1. Arduino Nano Flight Simulator 2020 Bedieningspaneel – LCD & CDI Display
  2. Web-gestuurd DMX-verlichtingssysteem – Arduino Master Controller
  3. DIY Arduino USB Gaming Controller – Bouw Je Eigen High-Performance Gamepad
  4. Unopad: Naadloze Arduino MIDI-controller voor Ableton Live
  5. Bluetooth Tekst Teleporter: Arduino + Android Project
  6. Arduino-gebaseerde Vacuum Fluorescent Display (VFD) Controller Kit
  7. Alexa-ingeschakelde Arduino Thuiscontroller: Slimme Automatisering Made Simple
  8. Slim Temperatuurmonitoring Systeem voor Scholen: Nauwkeurig, Real-time en Beveiligd
  9. Efficiënte 8-bit IO-poort bibliotheek voor Arduino – Uitbreiding digitale controle
  10. Geïsoleerde analoge ingangsschakeling voor Arduino bouwen
  11. Slim Indoor Navigatie Robot Kit voor Arduino Projecten