Entwicklungsproject (EUM126)
AirDrum
Wintersemester 2017/18
locr1011@hs-karlsruhe.de
roda1019@hs-karlsruhe.de
Startseite
Team
Definitionsphase
Vorwort
Problemstellung
Stand der Technik
Aufgabenstellung
Mindmap
ProjektplanIST
Anforderungsliste
Konzeptphase
Black-Box
Funktionsstruktur
Morphologie
Konzeptentwicklung
Bestellliste
Ausarbeitung
Blockschaltbild
Portbelegungsplan
Schaltplan
Quellcode
3-D-Druck
Weiterentwicklungen
Linkliste
Fazit
Quellcode
ESP32
#include <Wire.h>
#include "SSD1306.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.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);
/**************************************************************************/
/*
*/
/**************************************************************************/
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 = 50;
int y_tresh_r = 60;
int gyro_tresh = 400;
int ideal = 0;
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 1!");
while(1);
}
if(!bno2.begin())
{
/* There was a problem detecting the BNO055 */
Serial.print("Ooops, no BNO055 detected 2!");
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");
}
/**************************************************************************/
/*
*/
/**************************************************************************/
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);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Floor tom");
ideal = 60;
}
if((angle_x >= 330 && angle_x < 360 || angle_x >= 0 && angle_x < 30) && angle_y < y_tresh_c) {
Serial.write(1);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Snare Drum");
ideal = 0;
}
if((angle_x >= 0 && angle_x < 30 || angle_x >= 330 && angle_x <= 360) && angle_y >= y_tresh_c) {
Serial.write(3);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "High toms");
ideal = 0;
}
if(angle_x >= 270 && angle_x < 330 && angle_y < y_tresh_l) {
Serial.write(2);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "High hat");
ideal = 300;
}
if((angle_x >= 30 && angle_x <= 90) && angle_y >= y_tresh_r) {
Serial.write(4);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Crash cymbal");
ideal = 60;
}
if((angle_x >= 270 && angle_x < 330) && angle_y >= y_tresh_l) {
Serial.write(4);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Crash cymbal");
ideal = 300;
}
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;
angle_x_cal = (int(angle_x_cal) - (ideal - int(angle_x))) % 360;
if(angle_x_cal < 0){
angle_x_cal = angle_x_cal + 360;
}
}
}
display.display();
}
if(!flag_strike){
counter_strike++;
if(counter_strike == 3){
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);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Floor tom 2");
ideal = 60;
}
if((angle2_x >= 330 && angle2_x < 360 || angle2_x >= 0 && angle2_x < 30) && angle2_y < y_tresh_c) {
Serial.write(1);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Snare Drum 2");
ideal = 0;
}
if((angle2_x >= 0 && angle2_x < 30 || angle2_x >= 330 && angle2_x <= 360) && angle2_y >= y_tresh_c) {
Serial.write(3);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "High toms 2");
ideal = 0;
}
if(angle2_x >= 270 && angle2_x < 330 && angle2_y < y_tresh_l) {
Serial.write(2);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "High hat 2");
ideal = 300;
}
if((angle2_x >= 30 && angle2_x <= 90) && angle2_y >= y_tresh_l) {
Serial.write(4);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Crash cymbal 2");
ideal = 60;
}
if((angle2_x >= 270 && angle2_x < 330) && angle2_y >= y_tresh_l) {
Serial.write(4);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 0, "Crash cymbal 2");
ideal = 300;
}
// 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));
angle_x_cal = (int(angle_x_cal) - (ideal - int(angle_x))) % 360;
if(angle_x_cal < 0){
angle_x_cal = angle_x_cal + 360;
}
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);
}
Processing
import processing.serial.*;
import processing.sound.*;
import processing.serial.*;
Serial myPort;
int val;
SoundFile snare_file;
SoundFile hightoms_file;
SoundFile floortom_file;
SoundFile highhat_file;
SoundFile crashcymbal_file;
void setup()
{
size(200, 200);
myPort = new Serial(this, Serial.list()[0], 115200);
snare_file = new SoundFile(this, "drum_snare.mp3");
hightoms_file = new SoundFile(this, "top_toms.wav");
floortom_file = new SoundFile(this, "floor_tom.wav");
highhat_file = new SoundFile(this, "high_hat.mp3");
crashcymbal_file = new SoundFile(this, "crash_cymbal.mp3");
}
void draw()
{
if ( myPort.available() > 0) { // If data is available,
val = myPort.read(); // read it and store it in val
}
background(255); // Set background to white
if (val == 1) { // If the serial value is 0,
fill(51, 102, 255); // set fill to blue
snare_file.play();
val = 0;
myPort.clear();
}
else if (val == 2){
fill(102,41,255); // set fill to purple
highhat_file.play();
val = 0;
myPort.clear();
}
else if (val == 3){
fill(204,51,255); // set fill to magenta
hightoms_file.play();
val = 0;
myPort.clear();
}
else if (val == 4){
fill(51,204,255); // set fill to light blue
crashcymbal_file.play();
val = 0;
myPort.clear();
} else if (val == 5){
fill(255,51,203); // set fill to pink
floortom_file.play();
val = 0;
myPort.clear();
}
else{
// If the serial value is not 0
fill(0); // set fill to black
}
rect(50, 50, 100, 100);
}
Mit Unterstützung von Prof. J. Walter
Wintersemester 2017/18