#11236 Re: Der WII-Copter ( Selbstbau-Projekt )
Verfasst: 27.05.2012 19:49:24
Ja klar habe ich.
Ich hoffe es geht alles.
Ich hoffe es geht alles.
oh ja mein fehlerGoldfussel hat geschrieben:Ich bin Doof da hätte ich auch selbst drauf kommen können.
Also ich habe das gemacht und hatte bei Pitch und Yaw keine Gyro Ausschläge.
Nun war ich neugierig was passiert wenn ich die Sternchen weg mache und siehe da die alle Achsen gehen, leider aber wieder Falschrum.
/////////////////
gyroADC[ROLL] = WMP_tmpData[ROLL];
gyroADC[PITCH] = WMP_tmpData[PITCH]-1;
gyroADC[YAW] = WMP_tmpData[YAW]-1;
/////////////////
Code: Alles auswählen
void computeIMU () {
uint8_t axis;
static int16_t gyroADCprevious[3] = {0,0,0};
int16_t gyroADCp[3];
int16_t gyroADCinter[3];
static uint32_t timeInterleave = 0;
//we separate the 2 situations because reading gyro values with a gyro only setup can be acchieved at a higher rate
//gyro+nunchuk: we must wait for a quite high delay betwwen 2 reads to get both WM+ and Nunchuk data. It works with 3ms
//gyro only: the delay to read 2 consecutive values can be reduced to only 0.65ms
if (!ACC && nunchuk) {
annexCode();
while((micros()-timeInterleave)<INTERLEAVING_DELAY) ; //interleaving delay between 2 consecutive reads
timeInterleave=micros();
WMP_getRawADC();
getEstimatedAttitude(); // computation time must last less than one interleaving delay
while((micros()-timeInterleave)<INTERLEAVING_DELAY) ; //interleaving delay between 2 consecutive reads
timeInterleave=micros();
while(WMP_getRawADC() != 1) ; // For this interleaving reading, we must have a gyro update at this point (less delay)
for (axis = 0; axis < 3; axis++) {
// empirical, we take a weighted value of the current and the previous values
// /4 is to average 4 values, note: overflow is not possible for WMP gyro here
gyroData[axis] = (gyroADC[axis]*3+gyroADCprevious[axis]+2)/4;
gyroADCprevious[axis] = gyroADC[axis];
}
} else {
#if ACC
ACC_getADC();
getEstimatedAttitude();
#endif
#if GYRO
Gyro_getADC();
#else
WMP_getRawADC();
#endif
for (axis = 0; axis < 3; axis++)
gyroADCp[axis] = gyroADC[axis];
timeInterleave=micros();
annexCode();
if ((micros()-timeInterleave)>650) {
annex650_overrun_count++;
} else {
while((micros()-timeInterleave)<650) ; //empirical, interleaving delay between 2 consecutive reads
}
#if GYRO
Gyro_getADC();
#else
WMP_getRawADC();
#endif
for (axis = 0; axis < 3; axis++) {
gyroADCinter[axis] = gyroADC[axis]+gyroADCp[axis];
// empirical, we take a weighted value of the current and the previous values
gyroData[axis] = (gyroADCinter[axis]+gyroADCprevious[axis]+1)/3;
gyroADCprevious[axis] = gyroADCinter[axis]/2;
if (!ACC) accADC[axis]=0;
}
}
#if defined(GYRO_SMOOTHING)
static uint8_t Smoothing[3] = GYRO_SMOOTHING; // How much to smoothen with per axis
static int16_t gyroSmooth[3] = {0,0,0};
for (axis = 0; axis < 3; axis++) {
gyroData[axis] = (gyroSmooth[axis]*(Smoothing[axis]-1)+gyroData[axis]+1)/Smoothing[axis];
gyroSmooth[axis] = gyroData[axis];
}
#elif defined(TRI)
static int16_t gyroYawSmooth = 0;
gyroData[YAW] = (gyroYawSmooth*2+gyroData[YAW]+1)/3;
gyroYawSmooth = gyroData[YAW];
#endif
}
Code: Alles auswählen
uint8_t WMP_getRawADC() {
uint8_t axis;
TWBR = ((16000000L / I2C_SPEED) - 16) / 2; // change the I2C clock rate
i2c_getSixRawADC(0xA4,0x00);
if (micros() < (neutralizeTime + NEUTRALIZE_DELAY)) {//we neutralize data in case of blocking+hard reset state
for (axis = 0; axis < 3; axis++) {gyroADC[axis]=0;accADC[axis]=0;}
accADC[YAW] = acc_1G;
return 1;
}
// Wii Motion Plus Data
if ( (rawADC[5]&0x03) == 0x02 ) {
// Assemble 14bit data
gyroADC[ROLL] = - ( ((rawADC[5]>>2)<<8) | rawADC[2] ); //range: +/- 8192
gyroADC[PITCH] = - ( ((rawADC[4]>>2)<<8) | rawADC[1] );
gyroADC[YAW] = - ( ((rawADC[3]>>2)<<8) | rawADC[0] );
GYRO_Common();
// Check if slow bit is set and normalize to fast mode range
gyroADC[ROLL] = (rawADC[3]&0x01) ? gyroADC[ROLL]/5 : gyroADC[ROLL]; //the ratio 1/5 is not exactly the IDG600 or ISZ650 specification
gyroADC[PITCH] = (rawADC[4]&0x02)>>1 ? gyroADC[PITCH]/5 : gyroADC[PITCH]; //we detect here the slow of fast mode WMP gyros values (see wiibrew for more details)
gyroADC[YAW] = (rawADC[3]&0x02)>>1 ? gyroADC[YAW]/5 : gyroADC[YAW]; // this step must be done after zero compensation
static uint16_t WMP_tmpData[3];
for (axis = 0; axis < 3; axis++)
WMP_tmpData[axis] = gyroADC[axis];
/////////////////
gyroADC[ROLL] = WMP_tmpData[ROLL];
gyroADC[PITCH] = WMP_tmpData[PITCH]*-1;
gyroADC[YAW] = WMP_tmpData[YAW]*-1;
/////////////////
return 1;
} else if ( (rawADC[5]&0x03) == 0x00 ) { // Nunchuk Data
ACC_ORIENTATION( ( (rawADC[3]<<2) | ((rawADC[5]>>4)&0x02) ) ,
- ( (rawADC[2]<<2) | ((rawADC[5]>>3)&0x02) ) ,
( ((rawADC[4]>>1)<<3) | ((rawADC[5]>>5)&0x06) ) );
ACC_Common();
return 0;
} else
return 2;
}
#endif
hi,Goldfussel hat geschrieben:Mit 2 lagen Spiegeltap und halt das ganze über Kopf.