Skip to content

Instantly share code, notes, and snippets.

@remisarrailh
Created December 28, 2018 09:56
Show Gist options
  • Save remisarrailh/a500b57b33a710cfc200331917dcd0ea to your computer and use it in GitHub Desktop.
Save remisarrailh/a500b57b33a710cfc200331917dcd0ea to your computer and use it in GitHub Desktop.
/*
BLE Midi 8 Buttons
by Rémi Sarrailh
by Olivier Sarrailh
Based on BLE_MIDI Example by neilbags
https://github.com/neilbags/arduino-esp32-BLE-MIDI
Based on BLE_notify example by Evandro Copercini.
Creates a BLE MIDI service and characteristic.
Once a client subscibes, press a button to play a midi note
//Todo get CC commands
//Essentials of the Midi Protocol https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html
//Note to hex (https://www.wavosaur.com/download/midi-note-hex.php)
//http://chephip.free.fr/mus/midi.html
*/
/* BLUETOOTH */
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#define SERVICE_UUID "03b80e5a-ede8-4b33-a751-6ce34ec4c700"
#define CHARACTERISTIC_UUID "7772e5db-3868-4112-a1a9-f2669d106bf3"
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
/* BUTTONS */
int buttons_pins[8] = {13, 15, 2, 0, 4, 16, 17, 5};
int buttons_note[8] = {50, 52, 54, 55, 57, 59, 61, 62};
bool buttons_pressed[8] = {false, false, false, false, false, false, false, false};
/* MIDI */
#define NOTE_OFF 0x80
#define NOTE_ON 0x90
#define AFTERTOUCH 0xA0
#define PITCH_BEND 0xE0
uint8_t midiPacket[] = {
0x80, // header
0x80, // timestamp, not implemented
0x00, // commands
0x3c, // 0x3c == 60 == middle c
0x00 // velocity
};
//midiPacket[0] : Header
//midiPacket[1] : TimeStamp
//midiPacket[2] : Status
//midiPacket[3] : Note
//midiPacket[4] : Velocity
// https://www.wavosaur.com/download/midi-note-hex.php
// 0x30 C3
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("Connected");
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
Serial.begin(115200);
for (int i = 0; i < 8; i++) {
if (!digitalRead(buttons_pins[i])) {
pinMode(buttons_pins[i],INPUT_PULLUP);
}
Serial.println(buttons_pins[i]);
}
/* BLUETOOTH */
BLEDevice::init("flute BLE Midi");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID));
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
BLEUUID(CHARACTERISTIC_UUID),
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_WRITE_NR
);
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
// Create a BLE Descriptor
pCharacteristic->addDescriptor(new BLE2902());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
}
void loop() {
//if (deviceConnected) {
buttons_read();
//}
}
void buttons_read() {
for (int i = 0; i < 8; i++) {
//delay(30);
if (!digitalRead(buttons_pins[i])) {
if(!buttons_pressed[i]){
buttons_pressed[i] = true;
Serial.print(i);
Serial.println(":ON");
midiPacket[2] = NOTE_ON; // note down, channel 0
midiPacket[3] = buttons_note[i];
midiPacket[4] = 127; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
pCharacteristic->notify();
}
} else {
if (buttons_pressed[i]) {
buttons_pressed[i] = false;
Serial.print(i);
Serial.println(":OFF");
midiPacket[2] = NOTE_OFF; // note down, channel 0
midiPacket[3] = buttons_note[i];
midiPacket[4] = 127; // velocity
pCharacteristic->setValue(midiPacket, 5); // packet, length in bytes
pCharacteristic->notify();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment