Prof. J. Walter - Informationstechnik, Mikrocomputertechnik, Digitale Medien Quellcode
Hochschule Karlsruhe Logo Mikrocontroller
AirDrum v2
Sommersemester 2018
roda1019@hs-karlsruhe.de
locr1011@hs-karlsruhe.de

Quellcode


Verwendet IDE für die Microkontroller entwicklung: Visual Studio


Aktuelle Zustand der Quellcode:







/**************************************************************************/
/*
* Project : AirDrum_v3_1
*
* Program name : airdrum_v3-1.ino
*
* Author : Cristian Lopez & Dante Ros
*
* Date created : 20180529
*
* Purpose : This program integrates one BNO055 sensor to measure the angular velocity and linear acceleration.
These measurements are then processed to determine the position of the sensor and use them as transducer
for the drumstick action. Furthermore, this program implements BLE to connect to an Android app that can handle
multiple devices and translate the drumstick action to sound.
*
* Revision History :
*
* Date Author Ref Revision
* 20180529 eu4m_cd 1 Included BLE code. Pending to implement two sensor measurement and reinialization of sensor calibration
per hit of drumstick.
*
*/
/**************************************************************************/

#include <Wire.h>
#include "SSD1306.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

#define BNO055_SAMPLERATE_DELAY_MS (20)

Adafruit_BNO055 bno1 = Adafruit_BNO055(55, BNO055_ADDRESS_A);
Adafruit_BNO055 bno2 = Adafruit_BNO055(56, BNO055_ADDRESS_B);

//Adafruit_BNO055 bno2 = Adafruit_BNO055(55, BNO055_ADDRESS_A);
//Adafruit_BNO055 bno3 = Adafruit_BNO055(56, BNO055_ADDRESS_B);

//SSD1306 display(0x3c, 21, 22);

BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
String txValue = "";

#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9F" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9F"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9F"


/**************************************************************************/
/*

*/
/**************************************************************************/

float angle_x;
float angle_y;
float last_gyro_y = 0;
float last_gyro2_y = 0;
float angle_x_temp = 0;
float angle_t2 = 0;
int counter_cal = 0;

float angle2_x;
float angle2_y;

float gyro_y = 0;
float gyro2_y = 0;

bool flag = true;
bool flag_strike = true;
bool flag_strike2 = true;
bool flag_first_display = true;
bool flag_calibration = true;

int counter_strike = 0;
int counter2_strike = 0;
unsigned long now;
unsigned long initial_time = 0;
long remaining_time = 0;
unsigned long last_time_sampled=0;
unsigned long last_time_printed=0;

float angle_x_cal = 0;
float angle2_cal = 0;
float sum = 0;

int y_tresh_l = 60;
int y_tresh_c = 40;
int y_tresh_r = 60;
int gyro_tresh = 400;

class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};

void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};

class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();

if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");

for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
}

Serial.println();

if (rxValue.find("A") != -1) {
/*Serial.print("Turning ON!");
digitalWrite(LED, HIGH);*/
}
else if (rxValue.find("B") != -1) {
//Serial.print("Turning OFF!");
//digitalWrite(LED, LOW);
}

Serial.println();
Serial.println("*********");
}
}
};

void setup(void)
{
Serial.begin(115200);

/* Initialise the OLED */
//display.init();
//display.flipScreenVertically();

/* Calibration of the position */
//display.setTextAlignment(TEXT_ALIGN_LEFT);
//display.setFont(ArialMT_Plain_24);
//display.drawString(20, 0, "AirDrum");

//display.setFont(ArialMT_Plain_10);
//display.drawString(0, 40, "Hochschule Karlsruhe");

//display.setFont(ArialMT_Plain_10);
//display.drawString(0, 50, "EU4M");
//
//display.display();

if (!bno1.begin())

{
/* There was a problem detecting the BNO055 */
Serial.print("Ooops, no BNO055 detected 2!");
while (1);
}

if(!bno2.begin())

{
/* There was a problem detecting the BNO055 */
Serial.print("Ooops, no BNO055 detected 1!");
while(1);
}

// Serial.print("OK");

delay(2000);

bno1.setExtCrystalUse(true);
bno2.setExtCrystalUse(true);

initial_time = micros();
Serial.println("Calibration status values: 0 = uncalibrated, 3 = fully calibrated");

// Create the BLE Device
BLEDevice::init("ESP32 UART Test"); // Give it a name

// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());

// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);

// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);

pCharacteristic->addDescriptor(new BLE2902());

BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);

pCharacteristic->setCallbacks(new MyCallbacks());

// Start the service
pService->start();

// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");

}

/**************************************************************************/
/*

*/
/**************************************************************************/

void loop(void)
{

// Possible vector values can be:
// - VECTOR_ACCELEROMETER - m/s^2
// - VECTOR_MAGNETOMETER - uT
// - VECTOR_GYROSCOPE - rad/s
// - VECTOR_EULER - degrees
// - VECTOR_LINEARACCEL - m/s^2
// - VECTOR_GRAVITY - m/s^2

imu::Vector<3> euler1 = bno1.getVector(Adafruit_BNO055::VECTOR_EULER);
imu::Vector<3> linearaccel1 = bno1.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
imu::Vector<3> gyroscope1 = bno1.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);

//imu::Vector<3> euler2 = bno2.getVector(Adafruit_BNO055::VECTOR_EULER);
//imu::Vector<3> linearaccel2 = bno2.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
//imu::Vector<3> gyroscope2 = bno2.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);

// Serial.println("angle1: " + String(euler1.x()));

// imu::Vector<3> euler2 = bno2.getVector(Adafruit_BNO055::VECTOR_EULER);
// imu::Vector<3> linearaccel2 = bno2.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
// imu::Vector<3> gyroscope2 = bno2.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
//
// imu::Vector<3> euler3 = bno3.getVector(Adafruit_BNO055::VECTOR_EULER);
// imu::Vector<3> linearaccel3 = bno3.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
// imu::Vector<3> gyroscope3 = bno3.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);

now = micros();

if(flag_calibration){

//display.clear();
//display.setFont(ArialMT_Plain_24);
//display.drawString(0, 0, "Calibration");
//display.setFont(ArialMT_Plain_10);
//display.drawString(0, 24, "Please put the sticks in front of you");
//display.drawString(0, 34, "(transversal) In this way ||");
//display.drawString(0, 54, "Remaining time: " +
//String((20000000-(now-initial_time))/1000000)+ " sec");
//display.display();

if (now - initial_time >= 10000000){

//angle_t2 = angle_t2 + euler2.x();
angle_x_temp = angle_x_temp + euler1.x();
counter_cal = counter_cal + 1;

}

if (now - initial_time >= 20000000){

angle_x_cal = angle_x_temp/counter_cal;
// angle2_cal = angle_t2/counter_cal;
//angle_x_cal = (angle_x_temp + angle_t2)/(2 * counter_cal);
// angle_x_cal = angle_x_temp/counter_cal;
flag_calibration = false;

}

}

else{

if(flag_first_display){

//display.clear();
//display.setFont(ArialMT_Plain_24);
//display.drawString(20, 0, "Play!");
//display.display();
flag_first_display = false;

}

last_time_sampled = now;

// First sensor (stick 1)

gyro_y = gyroscope1.y();

if(flag_strike){

if(gyro_y > gyro_tresh){

if(gyro_y > last_gyro_y){

last_gyro_y = gyro_y;

} else{

angle_x = euler1.x() - angle_x_cal;

if(angle_x < 0){

angle_x = 360 + angle_x;

}

angle_y = euler1.y();

// Serial.print(angle_x);
// Serial.print("\t\t");
// Serial.println(angle_y);

//display.clear();

//Second configuration

if(angle_x >= 30 && angle_x < 90 && angle_y < y_tresh_r) {

//Serial.write(5);

if (deviceConnected) {

txValue = "Floor tom";
char *cstr = new char[txValue.length() + 1];
strcpy(cstr, txValue.c_str());
pCharacteristic->setValue(cstr);

pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txValue);
Serial.println(" ***");

}

//display.setFont(ArialMT_Plain_24);
//display.drawString(0, 0, "Floor tom");

}

if((angle_x >= 330 && angle_x < 360 || angle_x >= 0 && angle_x < 30) && angle_y < y_tresh_c) {

//Serial.write(1);

if (deviceConnected) {

txValue = "Snare drum";
char *cstr = new char[txValue.length() + 1];
strcpy(cstr, txValue.c_str());
pCharacteristic->setValue(cstr);

pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txValue);
Serial.println(" ***");

}

/* display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Snare drum"); */

}

if((angle_x >= 0 && angle_x < 30 || angle_x >= 330 && angle_x <= 360) && angle_y >= y_tresh_c) {

//Serial.write(3);

if (deviceConnected) {

txValue = "High toms";
char *cstr = new char[txValue.length() + 1];
strcpy(cstr, txValue.c_str());
pCharacteristic->setValue(cstr);

pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txValue);
Serial.println(" ***");

}

//display.setFont(ArialMT_Plain_24);
//display.drawString(0, 0, "High toms");

}

if(angle_x >= 270 && angle_x < 330 && angle_y < y_tresh_l) {

//Serial.write(2);

if (deviceConnected) {

txValue = "High hat";
char *cstr = new char[txValue.length() + 1];
strcpy(cstr, txValue.c_str());
pCharacteristic->setValue(cstr);

pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txValue);
Serial.println(" ***");

}

/* display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "High hat"); */

}

if((angle_x >= 30 && angle_x <= 90 || angle_x >= 270 && angle_x < 330) && angle_y >= y_tresh_l) {

//Serial.write(4);

if (deviceConnected) {

txValue = "Crash cymbal";
char *cstr = new char[txValue.length() + 1];
strcpy(cstr, txValue.c_str());
pCharacteristic->setValue(cstr);

pCharacteristic->notify(); // Send the value to the app!
Serial.print("*** Sent Value: ");
Serial.print(txValue);
Serial.println(" ***");

}

//display.setFont(ArialMT_Plain_24);
//display.drawString(0, 0, "Crash cymbal");

}

// display.setFont(ArialMT_Plain_10);
// display.drawString(0, 24, "Angle x: " + String(angle_x));
//// sum = angle2_x + angle_x_cal;
//// display.drawString(0, 24, "Angle x: " + String(sum));
// display.drawString(0, 34, "Angle y: " + String(angle_y));
// display.drawString(0, 44, "V: " + String(gyro_y));
// display.drawString(0, 54, "Cal: " + String(angle_x_cal) + " " + String(angle2_cal));

flag_strike = false;

}

}

//display.display();

}

if(!flag_strike){

counter_strike++;

if(counter_strike == 7){

flag_strike = true;
counter_strike = 0;

}

}


// Second sensor (stick 2)

// gyro2_y = gyroscope2.y();
//
// if(flag_strike2){
//
// if(gyro2_y > gyro_tresh){
//
// if(gyro2_y > last_gyro2_y){
//
// last_gyro2_y = gyro2_y;
//
// } else{
//
// angle2_x = euler2.x() - angle_x_cal;
//
// if(angle2_x < 0){
//
// angle2_x = 360 + angle2_x;
//
// }
//
// angle2_y = euler2.y();
//
// // Serial.print(angle_x);
// // Serial.print("\t\t");
// // Serial.println(angle_y);
//
// display.clear();
//
////Second configuration
//
// if(angle2_x >= 30 && angle2_x < 90 && angle2_y < y_tresh_r) {
//
// //Serial.write(5);
//
// if (deviceConnected) {
//
// txValue = "Floor tom 2";
// char *cstr = new char[txValue.length() + 1];
// strcpy(cstr, txValue.c_str());
// pCharacteristic->setValue(cstr);
//
// pCharacteristic->notify(); // Send the value to the app!
// Serial.print("*** Sent Value: ");
// Serial.print(txValue);
// Serial.println(" ***");
//
// }
//
// display.setFont(ArialMT_Plain_24);
// display.drawString(0, 0, "Floor tom 2");
//
// }
//
// if((angle2_x >= 330 && angle2_x < 360 || angle2_x >= 0 && angle2_x < 30) && angle2_y < y_tresh_c) {
//
// //Serial.write(1);
//
// if (deviceConnected) {
//
// txValue = "Snare drum 2";
// char *cstr = new char[txValue.length() + 1];
// strcpy(cstr, txValue.c_str());
// pCharacteristic->setValue(cstr);
//
// pCharacteristic->notify(); // Send the value to the app!
// Serial.print("*** Sent Value: ");
// Serial.print(txValue);
// Serial.println(" ***");
//
// }
//
// display.setFont(ArialMT_Plain_24);
// display.drawString(0, 0, "Snare drum 2");
//
// }
//
// if((angle2_x >= 0 && angle2_x < 30 || angle2_x >= 330 && angle2_x <= 360) && angle2_y >= y_tresh_c) {
//
// //Serial.write(3);
//
// if (deviceConnected) {
//
// txValue = "High toms 2";
// char *cstr = new char[txValue.length() + 1];
// strcpy(cstr, txValue.c_str());
// pCharacteristic->setValue(cstr);
//
// pCharacteristic->notify(); // Send the value to the app!
// Serial.print("*** Sent Value: ");
// Serial.print(txValue);
// Serial.println(" ***");
//
// }
//
// display.setFont(ArialMT_Plain_24);
// display.drawString(0, 0, "High toms 2");
//
//
// }
//
// if(angle2_x >= 270 && angle2_x < 330 && angle2_y < y_tresh_l) {
//
// //Serial.write(2);
//
// if (deviceConnected) {
//
// txValue = "High hat 2";
// char *cstr = new char[txValue.length() + 1];
// strcpy(cstr, txValue.c_str());
// pCharacteristic->setValue(cstr);
//
// pCharacteristic->notify(); // Send the value to the app!
// Serial.print("*** Sent Value: ");
// Serial.print(txValue);
// Serial.println(" ***");
//
// }
//
// display.setFont(ArialMT_Plain_24);
// display.drawString(0, 0, "High hat 2");
//
// }
//
// if((angle2_x >= 30 && angle2_x <= 90 || angle2_x >= 270 && angle2_x < 330) && angle2_y >= y_tresh_l) {
//
// //Serial.write(4);
//
// if (deviceConnected) {
//
// txValue = "Crash cymbal 2";
// char *cstr = new char[txValue.length() + 1];
// strcpy(cstr, txValue.c_str());
// pCharacteristic->setValue(cstr);
//
// pCharacteristic->notify(); // Send the value to the app!
// Serial.print("*** Sent Value: ");
// Serial.print(txValue);
// Serial.println(" ***");
//
// }
//
// display.setFont(ArialMT_Plain_24);
// display.drawString(0, 0, "Crash cymbal 2");
//
// }
//
//// display.setFont(ArialMT_Plain_10);
//// display.drawString(0, 48, "Sec" + String(angle2_x) + " " + String(angle2_y));
//
// display.setFont(ArialMT_Plain_10);
// display.drawString(0, 24, "Angle x: " + String(angle2_x));
//// sum = angle2_x + angle2_cal;
//// display.drawString(0, 24, "Angle x: " + String(sum));
// display.drawString(0, 34, "Angle y: " + String(angle2_y));
// display.drawString(0, 44, "V: " + String(gyro2_y));
// display.drawString(0, 54, "Cal: " + String(angle_x_cal) + " " + String(angle2_cal));
//
// flag_strike2 = false;
//
// }
//
// }
//
// display.display();
//
// }
//
// if(!flag_strike2){
//
// counter2_strike++;
//
// if(counter2_strike == 3){
//
// flag_strike2 = true;
// counter2_strike = 0;
//
// }
//
// }
//
}

delay(BNO055_SAMPLERATE_DELAY_MS);

}



  Mit Unterstützung von Prof. J. Walter Sommersemester 2018