цифровая электроника
вычислительная техника
встраиваемые системы

 


Контроллер дыхания на основе Arduino своими руками

В этом проекте мы создадим простой USB-MIDI-контроллер дыхания. Он разработан с использованием простых и дешевых компонентов, поэтому общая стоимость остается доступной и намного ниже коммерческих эквивалентов. Это базовая версия, в которой используется только датчик давления воздуха, но ее можно модернизировать, включив в нее датчик прикуса и кивка/наклона.


Контроллер дыхания на основе Arduino своими руками

Проект предполагает наличие некоторых базовых знаний в области электроники и Arduino, но даже новичок может собрать его, так как пайка здесь не требуется. Конечно, более продвинутые пользователи могут паять все на плате. Здесь не рассказывается об установке IDE, библиотек и инструкциях по загрузке кода, так как в Интернете есть отличные руководства.


Передискретизация используется для сглаживания входного сигнала датчика с очень хорошими результатами. Вы также можете настроить диапазон по своему вкусу и даже набрать пользовательские кривые, чтобы настроить поведение контроллера. Поскольку датчик также может измерять отрицательное давление, существует второй поток сообщений контроллера, который выводится, когда вы втягиваете воздух вместо того, чтобы дуть. Оба типа сообщений могут быть установлены пользователем.


Подключите Arduino и компоненты на макетной плате, как показано на схеме/фото.


Контроллер дыхания на основе Arduino своими руками

Контроллер дыхания на основе Arduino своими руками

Контроллер дыхания на основе Arduino своими руками

Вставьте датчик и операционный усилитель в их соответствующие положения, обратите внимание на ориентацию, основанную на небольших выемках на их сторонах. Далее вставьте резисторы, отрезав их ножки до нужной длины. Обрежьте/зачистите провода и поместите их на соответствующие места. Используйте красный провод для 5 В, черный для земли и желтый для сигнала, чтобы упростить понимание, но вы, конечно, можете использовать все, что у вас есть. Подключите мундштук, трубку, трехходовой соединитель и аспиратор, как показано на фотографии. Вам нужно будет отрезать кусок трубки для «выдыха».


Контроллер дыхания на основе Arduino своими руками

Надавите на 3-выводной разъем, чтобы он вошел в датчик. Он должен оставаться на месте.


Контроллер дыхания на основе Arduino своими руками

Установите Arduino IDE (если у вас ее еще нет) и установите две необходимые библиотеки (Oversampling и USB-MIDI) из Инструменты - Управление библиотеками (Tools- Manage Libraries). Подключите Arduino к компьютеру с помощью кабеля USB. Загрузите следующий код.



#include <Oversampling.h>
#include <USB-MIDI.h>

//#define DEBUG 1

USBMIDI_CREATE_DEFAULT_INSTANCE();

Oversampling adc(10, 13, 6);

const int sensorPin1 = A0;   

int sensorRange1 = 800;
int sensorRange2 = 800;

int controllerNumber1 = 2; 
int controllerNumber2 = 2;  

int controllerChannel2 = 1;

const int lowThreshold1 = 5;
const int lowThreshold2 = 5;

const int highThreshold1 = 0;
const int highThreshold2 = 0;

int in1[]   = {0, 127};
int out1[]  = {0, 127};

int in2[]   = {0, 127};
int out2[]  = {0, 127};

//int in1[]   = {0, 6,24,78,127};
//int out1[]  = {0,32,64,96,127};

//int in1[]   = {50, 100};
//int out1[]  = {50, 100};

int refreshCycle = 0;


int sensorValue1 = 0;
int sensorValue2 = 0;

int sensorMin1;
int sensorMin2;

int controllerValue1 = 0;
int controllerValue2 = 0;

int previousControllerValue1 = 0;
int previousControllerValue2 = 0;

int outputRange1;
int outputRange2;

int sensorLow1;
int sensorLow2;

int sensorHigh1;
int sensorHigh2;

void setup() {
  MIDI.begin(1);

#ifdef DEBUG
  Serial.begin (115200); 
#endif

  sensorMin1 = adc.read(sensorPin1);
  sensorMin2 = 0;

  outputRange1 = outputRange(controllerNumber1);
  outputRange2 = outputRange(controllerNumber2);
}

void loop() {
  sensorValue1 = adc.read(sensorPin1);
  sensorValue2 = sensorMin1 - sensorValue1;

  previousControllerValue1 = controllerValue1;
  previousControllerValue2 = controllerValue2;
  
  sensorLow1 = sensorMin1 + lowThreshold1;
  sensorLow2 = sensorMin2 + lowThreshold2;

  sensorHigh1 = sensorLow1 + sensorRange1 - highThreshold1;
  sensorHigh2 = min(sensorMin1,sensorRange2) - highThreshold2;

  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);

  if (controllerValue1 != previousControllerValue1) sendSensorOutput(controllerNumber1, controllerValue1, controllerChannel1);
  if (controllerValue2 != previousControllerValue2) sendSensorOutput(controllerNumber2, controllerValue2, controllerChannel2);


#ifdef DEBUG
//  Serial.print (sensorValue1);
//  Serial.print (",");
//  Serial.print (sensorValue2);
//  Serial.print (",");
  
  Serial.print (controllerValue1);
  Serial.print (",");
  Serial.println (controllerValue2);
#endif
  
  delay(refreshCycle);
}

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);
}

int outputRange (int number) {
  if (number > 128) return 8191;
  else return 127;
}
int mapToCurve(int val, int sensorLow, int sensorHigh, int* _in, int* _out, uint8_t size)
{
  // 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);

  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;
}

Arduino теперь должен отображаться как MIDI-устройство в вашем DAW/музыкальном программном обеспечении. Включите его и направьте вместе с клавиатурой в плагин, поддерживающий контроллер дыхания.


Контроллер дыхания на основе Arduino своими руками

Контроллер дыхания на основе Arduino своими руками



© digitrode.ru




Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий