Created
June 12, 2020 21:06
-
-
Save bitbank2/6f8a58d1f4990d4b555e2a3d115f9720 to your computer and use it in GitHub Desktop.
Arduino MIDI controller Demo
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}; | |
// 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)); | |
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 = 16; // must be a power of 2 | |
const int SAMPLES_SHIFT = 4; // log2 of SAMPLES_COUNT | |
// Circular buffer | |
int samplesBuffer[SAMPLES_COUNT] = {0}; | |
int sampleIndex = 0; | |
unsigned int sampleCount = 0; | |
int samplesSum = 0; | |
const int knobInputPin = A1; | |
const int changeThreshold = 20; | |
int lastSensorValue; | |
int lastMappedValue; | |
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(); | |
// if a central is connected to the peripheral: | |
if (central) { | |
//midiCommand(0x90, 64, 127); | |
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) { | |
int filteredValue; | |
int analogValue = analogRead(_inputPin); | |
//int valueDelta = abs(analogValue - lastSensorValue); | |
// Serial.print(analogValue); | |
// Serial.print(" - "); | |
// Serial.println(lastSensorValue); | |
// if(valueDelta < changeThreshold){ | |
// analogValue = lastSensorValue; | |
// } | |
samplesSum -= samplesBuffer[sampleIndex]; // subtract the oldest value (the index wrapped around) | |
samplesBuffer[sampleIndex++] = analogValue; // overwrite the oldest value with the newest | |
sampleIndex &= (SAMPLES_COUNT-1); // ** MUST BE A POWER OF 2! ** | |
sampleCount++; // keep track of total samples collected | |
samplesSum += analogValue; // add the newest value | |
// At startup, return the raw value; once we have enough samples, return the average | |
if (sampleCount < SAMPLES_COUNT) { | |
filteredValue = analogValue; | |
} else { | |
filteredValue = (samplesSum >> SAMPLES_SHIFT); | |
} | |
return filteredValue; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment