Advertisement
Guest User

Arduino USB MIDI Theremin

a guest
Jul 18th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.09 KB | None | 0 0
  1. /*
  2.  * MIDI_theremin.ino
  3.  * featuring a button! and a ToF sensor! and an ultrasonic sensor! and another button!
  4.  * July 2018
  5.  * ~ anonymous
  6.  */
  7.  
  8. #include "Adafruit_VL53L0X.h"
  9. #include "MIDIUSB.h"
  10. #include "NewPing.h"
  11.  
  12. #define ENABLE_PIN 10 // to enable the instrument
  13. #define SET_RANGE_PIN 11 // used to setup MIDI volume mapping in Ableton
  14. #define TRIGGER_PIN 5 // HC-SR04 trigger
  15. #define ECHO_PIN 4 // HC-SR04 echo
  16. #define MAX_DISTANCE 150 // max HC-SR04 range
  17. #define PING_SAMPLES 3 // number of samples to use with NewPing median mode
  18.  
  19. int RANGE_DIVIDER = 4; // determines pitch sensitivity
  20. int RANGE_OFFSET = 0; // offset pitch
  21.  
  22. bool keyDown = false;
  23. VL53L0X_RangingMeasurementData_t rangeMeasurement;
  24. Adafruit_VL53L0X lox = Adafruit_VL53L0X();
  25. uint8_t current_range = 0;
  26. uint8_t last_range = 0;
  27. uint8_t current_volume = 0;
  28. uint8_t last_volume = 0;
  29. NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
  30.  
  31. void noteOn(byte channel, byte pitch, byte velocity) {
  32.   midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  33.   MidiUSB.sendMIDI(noteOn);
  34. }
  35.  
  36. void noteOff(byte channel, byte pitch, byte velocity) {
  37.   midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  38.   MidiUSB.sendMIDI(noteOff);
  39. }
  40.  
  41. void setup() {
  42.   pinMode(ENABLE_PIN, INPUT);
  43.   pinMode(SET_RANGE_PIN, INPUT);
  44.   Serial.begin(115200);
  45.   while (!Serial) {
  46.     delay(1);
  47.   }
  48.   Serial.println("Starting...");
  49.   Serial.flush();
  50.   lox.begin();
  51. }
  52.  
  53. void loop() {
  54.   lox.rangingTest(&rangeMeasurement, false);
  55.   if (rangeMeasurement.RangeStatus == 4) {
  56.       current_range = 0;
  57.   } else {
  58.     current_range = (rangeMeasurement.RangeMilliMeter/RANGE_DIVIDER) + RANGE_OFFSET;
  59.   }
  60.  
  61.   current_volume = 64 - map(sonar.ping_median(PING_SAMPLES) / 58, 0, MAX_DISTANCE, 0, 64);  
  62.  
  63.   if (digitalRead(ENABLE_PIN) == LOW && keyDown) {
  64.     noteOff(0, last_range, 64);
  65.     //noteOff(15, last_volume, 64);
  66.     MidiUSB.flush();
  67.     keyDown = false;
  68.     Serial.println("Sending note off");
  69.     Serial.flush();
  70.   } else if (digitalRead(ENABLE_PIN) == HIGH && !keyDown) {
  71.     noteOn(0, current_range, 64);
  72.     noteOn(15, current_volume, 64);
  73.     MidiUSB.flush();
  74.     last_range = current_range;
  75.     last_volume = current_volume;
  76.     keyDown = true;
  77.     Serial.println("Sending note on");
  78.     Serial.flush();
  79.   } else if (current_range != last_range && keyDown) {
  80.     noteOff(0, last_range, 64);
  81.     //noteOff(15, last_volume, 64);
  82.     MidiUSB.flush();
  83.     noteOn(0, current_range, 64);
  84.     noteOn(15, current_volume, 64);
  85.     MidiUSB.flush();
  86.     last_range = current_range;
  87.     last_volume = current_volume;
  88.     keyDown = true;
  89.     Serial.println("Changing note");
  90.   }
  91.   // use this to set the MIDI mapping range for volume control in Ableton
  92.   if (digitalRead(SET_RANGE_PIN) == HIGH) {
  93.     noteOn(15, 0, 64);
  94.     noteOn(15, 64, 64);
  95.     MidiUSB.flush();
  96.     Serial.println("Setting range");
  97.     Serial.flush();
  98.     delay(500);
  99.     noteOff(15, 0, 64);
  100.     noteOff(15, 64, 64);
  101.     MidiUSB.flush();
  102.     delay(100);
  103.   }
  104.  
  105.   MidiUSB.flush();
  106.   delay(20);
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement