I'm working on a MIDI controller project, and a part of it involves some motion sensing, but i'm a noob to gyros and maybe someone can help me out with some advice.
So the function i'd like to implement is the following: While (playing a trumpet and) a button is pressed, i would like to inc/dec 2 values according to vertical/horizontal movement of the tip ot the instrument.
The attached picture maybe explains better. The gyro is mounted to the bottom of the instrument.
Basically, i would like to map these values to an X-Y control, so if the button is pressed, the X-Y value changes like the movement of the instruments tip.
But i'm very new to gyros, and stuff like motion sensing. I've successfully connected the MPU-6050 to my Nano board, and it is working well, and i've figured out that the accelerometer y axis data is something that maybe i want to use, because as i change the vertical angle of the horn, it changes correspondingly.
But maybe thats not the best idea, and i got no clue how should i track the horizontal movement. Also, i dont know nothing about how should i filter filter or averaging the raw data of anything that should make it more usable, and what resolution, or sensitivity should be the best .
At any position of the instruments tip, i would like to increment or decrement the value maximum by 127., with about max. 40 degree movement.
Sorry for my bad english, and thanks in advance for the help
As an amateur musician, I appreciate what you're trying to do. However, as a professional mathematician, I would urge you to give up the accelerometer and look for a simple tilt sensor.
An accelerometer measures acceleration, and the tilt you really want to measure must be derived from that output by some fairly complex math. Even if you master the math, accelerometers have a "creep" error which requires a calibration/reset at intervals.
A tilt sensor will just directly use the gravitational field to give you a tilt angle, directly, and without lots of complex math. I haven't researched any of them, but that's where I would look.
I would agree since the accelerometer will only give you momentary changes and cause a constant seasaw effect on the out put, where as a tilt sensor will hold the variable as to the attitude more like a Theremin.
A good simple tilt sensor is a mems type accelerometer such as the MMA7660. This acts more like a tilt sensor with about 30 steps per 90 degree tilt rotation among 3 axises.
Delirious:
I would agree since the accelerometer will only give you momentary changes and cause a constant seasaw effect on the out put, where as a tilt sensor will hold the variable as to the attitude more like a Theremin.
A good simple tilt sensor is a mems type accelerometer such as the MMA7660. This acts more like a tilt sensor with about 30 steps per 90 degree tilt rotation among 3 axises.
jrdoner:
As an amateur musician, I appreciate what you're trying to do. However, as a professional mathematician, I would urge you to give up the accelerometer and look for a simple tilt sensor.
An accelerometer measures acceleration, and the tilt you really want to measure must be derived from that output by some fairly complex math. Even if you master the math, accelerometers have a "creep" error which requires a calibration/reset at intervals.
A tilt sensor will just directly use the gravitational field to give you a tilt angle, directly, and without lots of complex math. I haven't researched any of them, but that's where I would look.
Good Luck, sounds like a neat project.
John Doner
Thank both of You for the answers, I've checked after these tilt sensor things but according to the interwebs, these are somekind of accelerometers, so i think that anything they can do, the MPU could do.
The MPU 6050 looks like a very smart device, since it has 3 axis accelero, and gyroscope, and also an integrated DMP whick should be fairly enough i think to do the complex math involved, and act like a tilt sensor.
I would like to stick to this unit, because I already have it, and i would like to do some more motion sensing stuff, like shake detection, and some control command sending when i rotate the horn back and forth like a steering wheel.
I think somebody who has some experience with the MPU6050 could help me, but i will consider buying a tilt sensor.
So i got something running, i can set a value regarding the vertical angle.
#include <Wire.h>
const uint8_t IMUAddress = 0x68;
const uint8_t Button=2;
/* IMU Data */
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
byte counter=0;
byte counter1=0;
int avg=0;
int sum=0;
int accYY;
int tresh=0;
int val=0;
int prevval=0;
void setup() {
pinMode(Button,INPUT);
digitalWrite(Button,HIGH);
Serial.begin(115200);
Wire.begin();
i2cWrite(0x6B,0x00); // Disable sleep mode
if(i2cRead(0x75,1)[0] != 0x68) { // Read "WHO_AM_I" register
Serial.print(F("MPU-6050 with address 0x"));
Serial.print(IMUAddress,HEX);
Serial.println(F(" is not connected"));
while(1);
}
}
void loop() {
uint8_t ButtonState=digitalRead(Button);
/* uint8_t* data = i2cRead(0x3B,14);
accX = ((data[0] << 8) | data[1]);
accY = ((data[2] << 8) | data[3]);
accZ = ((data[4] << 8) | data[5]);
gyroX = ((data[8] << 8) | data[9]);
gyroY = ((data[10] << 8) | data[11]);
gyroZ = ((data[12] << 8) | data[13]);
accYY=map(accY,-20000,20000,-127,127);
*/
uint8_t* data = i2cRead(0x3B,14);
accY = ((data[2] << 8) | data[3]);
// sum=(sum+ 0.5*(accY-sum));
accYY=map(accY,-20000,20000,-127,127);
if (ButtonState == LOW){
if (counter1 == 0){
tresh=accYY;
counter1++;
}
if (counter1 == 1){
val=64+accYY-tresh;
}
}
else{
counter1=0;
}
if (val > 127){
val=127;
}
if (val < 0){
val=0;
}
Serial.print(accYY);
Serial.print("\t");
Serial.print(tresh);
Serial.print("\t");
Serial.print(counter1);
Serial.print("\t");
Serial.print(val);
// Serial.print("\t");
// Serial.print(gyroY);
// Serial.print("\t");
// Serial.print(gyroZ);
// Serial.print("\t");
Serial.print("\n");
delay(100); // The accelerometer's maximum samples rate is 1kHz
}
void i2cWrite(uint8_t registerAddress, uint8_t data){
Wire.beginTransmission(IMUAddress);
Wire.write(registerAddress);
Wire.write(data);
Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
uint8_t data[nbytes];
Wire.beginTransmission(IMUAddress);
Wire.write(registerAddress);
Wire.endTransmission(false); // Don't release the bus
Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
for(uint8_t i = 0; i < nbytes; i++)
data[i] = Wire.read();
return data;
}
I would like to smoothen the data from the accelero with exponential smoothing and im stuck. I cant figure it out how should i do it correctly, is there anybody who could help?