Last active
June 13, 2020 06:06
-
-
Save ubidefeo/3e7362235cee5317cec4a36f07585e29 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Arduino analog to BLE MIDI | |
Ubi de Feo @ Bar Arduino | |
https://www.youtube.com/watch?v=0zNmt_IKwRg | |
supported boards: | |
- Arduino MKR WiFi 1010 | |
- Arduino Nano 33 IoT | |
- Arduino Nano 33 BLE | |
- Arduino Nano 33 BLE Sense | |
- Arduino UNO WiFI Rev. 2 | |
**** Sketch for USB MIDI version (Nano 33 BLE not supported) **** | |
**** can be found here https://gist.github.com/ubidefeo/6098d95332b6529f1b0599bfd443ebae **** | |
**** Thank you Larry Bank for pointing out the lack of a BLE version **** | |
BLE init code courtesy of T. Igoe | |
https://tigoe.github.io/SoundExamples/midi-ble.html | |
*/ | |
#include <ArduinoBLE.h> | |
byte midiData[] = {0x80, 0x80, 0x00, 0x00, 0x00}; | |
const byte emptyMIDIMessage[] = {0x80, 0x80, 0x00, 0x00, 0x00}; | |
// set up the MIDI service and MIDI message characteristic: | |
BLEService midiService("03B80E5A-EDE8-4B33-A751-6CE34EC4C700"); | |
BLECharacteristic midiCharacteristic("7772E5DB-3868-4112-A1A9-F2669D106BF3", | |
BLEWrite | BLEWriteWithoutResponse | | |
BLENotify | BLERead, | |
sizeof(midiData)); | |
bool isMIDIOn = false; | |
void controlChange(byte channel, byte control, byte value) { | |
midiData[2] = 0xB0 | channel; | |
midiData[3] = control; | |
midiData[4] = value; | |
midiCharacteristic.setValue(midiData, sizeof(midiData)); | |
} | |
const int SAMPLES_COUNT = 20; | |
// FIFO | |
int samplesBuffer[SAMPLES_COUNT] = {0}; | |
int sampleIndex = 0; | |
const int knobInputPin = A1; | |
const int changeThreshold = 20; | |
int lastSensorValue; | |
int lastMappedValue; | |
unsigned long samplesSum = 0; | |
void setup() { | |
Serial.begin(57600); | |
delay(5000); | |
// Initialize BLE: | |
if (!BLE.begin()) { | |
Serial.println("starting BLE failed!"); | |
while (true) | |
; | |
} | |
// set local name and advertised service for BLE: | |
BLE.setLocalName("ARDUINO_MIDI_BLE"); | |
BLE.setAdvertisedService(midiService); | |
// add the characteristic and service: | |
midiService.addCharacteristic(midiCharacteristic); | |
BLE.addService(midiService); | |
// start advertising | |
BLE.advertise(); | |
Serial.println("SETUP"); | |
} | |
void loop() { | |
int knobReadOut = filterAnalogValue(knobInputPin); | |
int mappedValue = map(knobReadOut, 0, 1023, 0, 127); | |
BLEDevice central = BLE.central(); | |
// When a central is connected to the peripheral we initially send | |
// an empty MIDI command in order to let certain platforms acknowledge the MIDI device | |
// Once that is done we set isMIDIOn to true and do not send the empty message until | |
// a reconnection happens upon disconnection (isMIDIOn needs to be false) | |
if (central && !isMIDIOn) { | |
midiCharacteristic.setValue(emptyMIDIMessage, sizeof(emptyMIDIMessage)); | |
isMIDIOn = true; | |
}else{ | |
isMIDIOn = false; | |
} | |
if(isMIDIOn){ | |
if (lastMappedValue != mappedValue) { | |
// Serial.println("************ CHANGE ***************"); | |
// Serial.print(">>> "); | |
// Serial.print(mappedValue); | |
// Serial.println(" <<<"); | |
controlChange(0, 4, mappedValue); | |
} | |
lastMappedValue = mappedValue; | |
} | |
//delay(100); | |
} | |
int filterAnalogValue(int _inputPin) { | |
samplesSum = 0; | |
int analogValue = analogRead(_inputPin); | |
// int valueDelta = abs(analogValue - lastSensorValue); | |
// Serial.print(analogValue); | |
// Serial.print(" - "); | |
// Serial.println(lastSensorValue); | |
// if(valueDelta < changeThreshold){ | |
// analogValue = lastSensorValue; | |
// } | |
if (sampleIndex < SAMPLES_COUNT) { | |
samplesBuffer[sampleIndex] = analogValue; | |
sampleIndex++; | |
} else { | |
for (int samplePosition = 0; samplePosition < sampleIndex - 1; | |
samplePosition++) { | |
0; | |
samplesBuffer[samplePosition] = samplesBuffer[samplePosition + 1]; | |
} | |
samplesBuffer[SAMPLES_COUNT - 1] = analogValue; | |
} | |
for (int samplePosition = 0; samplePosition < sampleIndex; samplePosition++) { | |
0; | |
samplesSum += samplesBuffer[samplePosition]; | |
} | |
// lastSensorValue = analogValue; | |
if (samplesSum == 0) | |
return 0; | |
unsigned int filteredValue = samplesSum / sampleIndex; | |
return filteredValue; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment