Show Posts
Pages: [1] 2
1  Using Arduino / Programming Questions / Re: Reading Pitch Roll from CHR6DM on: March 26, 2011, 01:45:46 pm
Hehe, that thing with goto's was pretty much a joke, for fun. smiley I just though some day I'm gonna use it.

No, don't look at that. That old code was actually working but was missing a lot of packets and didn't let you talk to the CHR6DM, only read it if it was set in broadcast mode. I and a guy called Lokling has written a complete protocol .h file to interface with the CHR6DM using a Arduino Mega Serial1 which works just like the PC interface program, so you can do everything with settings and read everything and such.

This is the code I'm talking about which works really really great. It is implemented as a C++ class:
https://github.com/AeroQuad/AeroQuad/blob/master/CHR6DM.h

You might wanna make it a library instead. For use, read the .h file and the relevant parts of the other code on how to use it (making the object and calling the accessors/mutators).

Here's how it flies:
2  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: July 29, 2010, 04:37:06 pm
Hello!

This is just what I need for a quadcopter project measuring air pressure and IR distance sensors for height holding/regulating. I was gonna write it myself this evening, but this seems very much better than I suspect I could write now.

I wonder how to add/use it to/from a library? I don't see an #include in what I believe you made the "exapmple file"?

Thanks,
Henrik
3  Forum 2005-2010 (read only) / Syntax & Programs / Re: Copter with Gyro stabilization. on: April 25, 2010, 07:33:05 pm
Sorry for necroposting, but this is something that has been on my mind for years. 2 years ago I actually took a broken Silverlit X-ufo and put a Attiny2313 in it and read my usual radio transmitter from it and converting it to the quadcopter matrix of control of the 4 crappy DC-motors on it. It flew... but straight to the ground because it had no sensors at all  smiley-grin The control matrix was good though.

However, I've been checking in to the Mikrokopter project (https://www.mikrocontroller.com/index.php?main_page=index&cPath=69&language=en and http://www.mikrokopter.de/ucwiki/en/MikroKopter/ ) for a long time. It uses 3x ADXRS610 (rate gyros) in X, Y and Z and also 1x 3 axis accelerometer in conjunction with those.

What I want to know is if anyone else has some experience with these sensors (gyros/accelerometers) and the quad-copter/rotor as a base, and the Arduino platform? I'm probably gonna try the first movement sensor I get my hands on on my Silverlit base, then go over to brushless, and maybe add Sharps' IR distance sensors to make it uncrashable (or as good as) for indoor flying.
4  Forum 2005-2010 (read only) / Scandinavia / Re: Starte med Arduino on: October 24, 2010, 04:51:16 pm
Fixat så jag kan läsa min PMB-648 jag med med Arduino... med ett bibliotek som man hittar här, NMEA-biblioteket: http://code.google.com/p/arducopter/source/browse/#svn/trunk/libraries/GPS_NMEA

Men grejen är att jag ska använda den på mitt quadcopter-projekt, och jag var nyss ute å gick med mottagarn. Uppdaterade inte förrän jag gått c:a 50m, men då vart det en rätt noggrann position. Sen fortsatte den att printa samma koordinat tills jag rört mig 50m till. Så kan vi inte ha det.

Läste sen att det finns nåt "walk mode" här: http://forums.parallax.com/showthread.php?p=933456

Men lyckas inte alls ställa in det med Sirf-programmet även om jag får kontakt med Sirf-programmet med hjälp av ett FTDI-breakout-kort (Comportssimulerande chip som kopplas till USB-porten).

Så jag är rätt besviken att jag inte kan ändra läge den printar i. Nån annan som lyckats?
5  Forum 2005-2010 (read only) / Scandinavia / Re: Vettiga applicationer för Arduino on: April 25, 2010, 07:40:22 pm
Tjatja!

Har man lite tid över eller bara vill fly från något annat (matte... smiley-razz) kan man bygga roliga saker med servon. Jag gjorde en printer av glasspinnar: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1272220992




6  Forum 2005-2010 (read only) / Interfacing / Re: CHR-6dm AHRS IMU to Mega on: October 17, 2010, 05:24:19 pm
I set the unit to below 100Hz in broadcast mode to stream YAW PITCH ROLL and ACCEL_Z, and made this code for an arduino Mega. It sometimes in a specific interval skip over things and get really bad results... But most of the time I get good ones. I have not yet managed to check the checksum...


/*
Honk Super Test of CHR-6DM

It is set to stream YAW, PITCH, ROLL and ACCEL_Z in 100Hz (Broadcast setting 73)
*/

float CHR_yawClean;
float CHR_pitchClean;
float CHR_rollClean;
float CHR_accel_zClean;

#define CHR_MESSAGE_LENGTH 16 //in bytes

//byte 1 contains 's'
//byte 2 contains 'n'
//byte 3 contains 'p'
//byte 4 contains PT, packet type
//byte 5 contains N (the number of data bytes to expect)
//FIRST DATA BYTE IS BYTE NUMBER 6
//byte 6 and 7 contains info about active channels
//byte 8 and 9 contains YAW
//byte 10 and 11 contains PITCH
//byte 12 and 13 contains ROLL
//byte 14 and 15 contains ACCEL_Z
//byte 16 and 17 contains CHK_SUM (N+6/N+7)

#define BYTE1 0
#define BYTE2 1
#define BYTE3 2
#define PT_BYTE 3
#define N_BYTE 4
#define DATA_BYTE1 5
#define DATA_BYTE2 6
#define YAW_BYTE1 7
#define YAW_BYTE2 8
#define PITCH_BYTE1 9
#define PITCH_BYTE2 10
#define ROLL_BYTE1 11
#define ROLL_BYTE2 12
#define ACCEL_Z_BYTE1 13
#define ACCEL_Z_BYTE2 14
#define CHK_BYTE1 15
#define CHK_BYTE2 16


#define CHR_YAW_FACTOR 0.0109863F //from datasheet
#define CHR_PITCH_FACTOR 0.0109863F
#define CHR_ROLL_FACTOR 0.0109863F
#define CHR_ACCEL_Z_FACTOR 0.106812F

//transmission freq. from CHR6DM: 100Hz (73 in the Broadcast setting)

void setup() {
  Serial.begin(57600);
  Serial1.begin(115200);
}

void loop() {

  readCHR6DM();
  Serial.print("Yaw: ");
  Serial.print(CHR_yawClean);
  Serial.print("  Pitch: ");
  Serial.print(CHR_pitchClean);
  Serial.print("  Roll: ");
  Serial.print(CHR_rollClean);
  Serial.print("  Acc_Z: ");
  Serial.println(CHR_accel_zClean);
  
delay(350); //unit set to 100Hz continous sending
}

void readCHR6DM() {
  int CHR_yawWord, CHR_pitchWord, CHR_rollWord, CHR_accel_zWord;
  unsigned int CHR_checksumWord, calculated_checksumWord;
  int i, j;
  unsigned char buffer[CHR_MESSAGE_LENGTH+2]; //17 bytes
  unsigned long sumOfBytes;  
  
//byte 1 contains 's'
//byte 2 contains 'n'
//byte 3 contains 'p'
//byte 4 contains PT, packet type
//byte 5 contains N (the number of data bytes to expect)
//FIRST DATA BYTE IS BYTE NUMBER 6
//byte 6 and 7 contains info about active channels
//byte 8 and 9 contains YAW
//byte 10 and 11 contains PITCH
//byte 12 and 13 contains ROLL
//byte 14 and 15 contains ACCEL_Z
//byte 16 and 17 contains CHK_SUM (N+6/N+7) //N is expected to be 10
 
    if (Serial1.available() > 0) {
   startOfRead:
     i = 0;
      buffer = Serial1.read();
      if(buffer == 's') { //byte 1 element 0
        i++;
        buffer = Serial1.read();
        //Serial.println(buffer[BYTE1]); //debug
      }
      else { goto startOfRead; }
        if(buffer == 'n') { //byte 2 element 1
          i++;
          buffer = Serial1.read(); //byte 3 element 2
          //Serial.println(buffer[BYTE2]); //debug
        }
        else { goto startOfRead; }
          if(buffer == 'p') { //byte 3 element 2, begin getting the whole thing because 3 start bytes checked to be valid
             i++;
            buffer = Serial1.read(); // byte 4 element 3 (PT_BYTE)
             //Serial.println(buffer[BYTE3]); //debug        
          }
          else { goto startOfRead; }
            if(buffer == 0xB7) { // byte 4 element 3 (PT_BYTE)
              i++;
                buffer =  Serial1.read(); // byte 5 element 4 (N_BYTE)
                //Serial.println(buffer[PT_BYTE], HEX); //debug
                //Serial.println(buffer[N_BYTE], DEC); //debug this is 10 dec!
            }
           else { goto startOfRead; }
             if(buffer == 0x0A) { // byte 5 element 4 (N_BYTE) expect 10 dec checks out!
              i++;
                buffer =  Serial1.read(); // byte 6 element 5 (DATA_BYTE1)
                //Serial.println(buffer[DATA_BYTE1], BIN); //debug this prints 1110000 checks out
            }
               else { goto startOfRead; }
               if(buffer == 0xE0) { // byte 6 element 5 (DATA_BYTE1) expect 70 hex this should check out
              i++;
                buffer =  Serial1.read(); // byte 7 element 6 (DATA_BYTE2)
                //Serial.println(buffer[DATA_BYTE2], BIN); //debug
            }
               else { goto startOfRead; }
                 if(buffer == 0x02) { // byte 7 element 6 (DATA_BYTE2) expect 2 hex
                  i++;
                  buffer = Serial1.read(); //byte 8 element 7 (YAW_BYTE1)
                  i++;
                  buffer = Serial1.read(); //byte 9 element 8 (YAW_BYTE2)
                  i++;
                  buffer = Serial1.read(); //byte 10 element 9 (PITCH_BYTE1)
                  i++;
                  buffer = Serial1.read(); //byte 11 element 10 (PITCH_BYTE2)
                  i++;
                  buffer = Serial1.read(); //byte 12 element 11 (ROLL_BYTE1)
                  i++;
                  buffer = Serial1.read(); //byte 13 element 12 (ROLL_BYTE2)
                  i++;
                  buffer = Serial1.read(); //byte 14 element 13 (ACCEL_Z_BYTE1)
                  i++;
                  buffer = Serial1.read(); //byte 15 element 14 (ACCEL_Z_BYTE2)
                  i++;
                  buffer = Serial1.read(); //byte 16 element 15 (CHK_BYTE1)
                  //Serial.println(buffer, DEC);
                  i++;
                  buffer = Serial1.read(); //byte 17 element 16 (CHK_BYTE2)
                  //Serial.println(buffer, DEC);
           }
         //else { goto startOfRead; }
            //for(i = 0; i < CHR_MESSAGE_LENGTH; i++){ //we're still at byte 3 element 2, execution gets us to byte 4 element 3
            //buffer = Serial1.read();              //first time here i=3 (byte 4), i=4 (byte 5), i=5 (byte 6), i=6, i=7, i=8, i=9, i=10, i=11, i=12, i=13, i=14, i=15, i=16(byte 17), i=17(byte18 nonexistent)
            //}
    }
    else{ Serial.println("Sensor not connected"); }
  
//   sumOfBytes = 0;
//    for(i=-1;i<13;i++) { //ska gå element 0 till 14
//    sumOfBytes += buffer;
//  }
//    
//    Serial.print("sumOfBytes: ");
//    Serial.print(sumOfBytes, DEC);
//    
//   CHR_checksumWord = (unsigned)buffer[CHK_BYTE1]<<8;
//   CHR_checksumWord |= buffer[CHK_BYTE2];  
//    //CHR_checksumWord = (unsigned long)(buffer[CHK_BYTE1] + buffer[CHK_BYTE2]);
//   Serial.print(" CHR_checksumWord: ");
//   Serial.println(CHR_checksumWord, DEC);
//  

          //if( ) {
  
  //plMSB = Serial1.read();
  //plLSB = Serial1.read();

  //myInt = (int)plMSB<<8;  YÄÄÄÄH!
  //myInt |= plLSB;
  
  CHR_yawWord = (int)buffer[YAW_BYTE1]<<8;
  CHR_yawWord |= buffer[YAW_BYTE2];
 
  CHR_pitchWord = (int)buffer[PITCH_BYTE1]<<8;
  CHR_pitchWord |= buffer[PITCH_BYTE2];
  
  CHR_rollWord = (int)buffer[ROLL_BYTE1]<<8;
  CHR_rollWord |= buffer[ROLL_BYTE2];
  
  CHR_accel_zWord = (int)buffer[ACCEL_Z_BYTE1]<<8;
  CHR_accel_zWord |= buffer[ACCEL_Z_BYTE2];
  
  CHR_yawClean = (CHR_yawWord * CHR_YAW_FACTOR);
  CHR_pitchClean = (CHR_pitchWord * CHR_PITCH_FACTOR);
  CHR_rollClean = (CHR_rollWord * CHR_ROLL_FACTOR);
  CHR_accel_zClean = (CHR_accel_zWord * CHR_ACCEL_Z_FACTOR);
  //}
}
7  Forum 2005-2010 (read only) / Interfacing / Re: CHR-6dm AHRS IMU to Mega on: October 08, 2010, 01:26:06 pm
No one interested? I don't get why, this is the next generation of IMU/AHRS! Got it all!

Only trouble is interfacing, and imagine accessing so great angle and heading estimates so fast yet so easy as with the Arduino's!
8  Forum 2005-2010 (read only) / Interfacing / CHR-6dm AHRS IMU to Mega on: October 08, 2010, 07:44:28 am
Hi, I am working much on quadcopters, and need a new IMU unit. I found an amazing one which is not horribly cheap implemented on a Propeller processor:
http://vrhome.net/vassilis/category/quadcopter/

Which got me fired up since I didn't get near those results with Nintendo Wii game controller IMU's.
Here's the link to the particular sensor I've got now (impulse bought it!):

http://www.chrobotics.com/index.php?main_page=product_info&cPath=1&products_id=2

Now my question is, what would be the best way to stream the data out to my Arduino Mega. As known, the Mega's got 4 hardware UART's and 1 I2C bus and 1 SPI bus.

I've read that the 200-500Hz update rates is not working good transferring the original data over UART (3V3 to arduino 5V) because it's too slow, and the code for the CHR device is open source which is really awesome.

Would it be best to also make code that streamed out I2C to the Mega or SPI? Or enhancing the UART communication somehow? I think it should work straight off since it's hardware UART's but apparently not.

Here's a thread about it but seems not so active:
http://www.chrobotics.com/forum/viewtopic.php?f=8&t=8&start=10

Please help. I think this is a LARGE improvement to the community if we could get this good IMU data straight into a REALLY easy interface as Arduino. Imagine flying copters, self balancing wheel bots such as segways and everything else you can imagine. And it does handle real Kalman or DCM really well it seems!!
9  Forum 2005-2010 (read only) / Interfacing / Re: Quadcopter real time environment mapping on: December 27, 2010, 10:10:15 pm
"...only where the obstacles are to build up a 3d map of a room."

I did such a project last year in my university. With Mindstorms NXT and their built in bluetooth device. And of course on a wheeled platform.

I'd suggest doing that project with wheels first, then move on to a flying platform. The advantage is that you can know where the vehicle is much easier since you can measure steps the wheels have turned for example, and then use for example a SHARP IR distance sensor to tell how far away nearby obstacles are and then sending that data to the PC. In fact the NXT is far more powerful than the AVR chips in the Arduino's since it contains the power of both an AVR and an ARM processor.

However, much of this quadcopter work is already done or in progress of developing.

Check out these really great open source projects which are Arduino based:
*AeroQuad
*ArduCopter

Also there's some other projects of course, but these two are in my world the two most useful for developing. You get a fully modifyable and flyable concept which allows a really steady ground for further developing which is currently done quite collectively in the communities.
10  Forum 2005-2010 (read only) / Interfacing / Re: Reading/updating I2C BMP085 without delay() on: July 26, 2010, 08:34:29 am
Thanks for the answer!

Well, the strange thing is, that is basically what's done, I just didn't show it proper I think if I get you totally. Yes, the 26ms is the conversion time internally in the sensor.

The thing I didn't tell was this (sorry for mixing with pseudo):
Code:
if (currentTime > (barSensTime + BARSENSLOOPTIME)) { //checks if 26ms passed (the define is 26, currentTime a counter of millis())

if updateflag == 1 {//prevents first reading to be 0
read finished result;
}

updateCommand; //start measuring with sensor
updateflag =1;

barSensTime = currentTime; //update time last in loop
    }

Now I think this is the missing part I didn't tell, but this didn't work as expected and that's what was puzzling me to pieces! This should first time command sensor to start read - wait 26ms with millis() - second cycle read out the result
 But off-value is read.

However, I found a nice shortcut. Some guys working on a bigger quadcopter project made a nice library for the BMP085 with classes that is much easier to call from the same type of time statement loop and it works flawlessly.

Can be found here:
https://code.google.com/p/arducopter/source/browse/trunk/libraries/#libraries/APM_BMP085

And the calls are just like mine, but what happens when the calls are made is different, I read a little in the actual .cpp in the library and fits this time loop code better:

example of usage:
Code:
/*
  Example of APM_BMP085 (absolute pressure sensor) library.
  Code by Jordi Muñoz and Jose Julio. DIYDrones.com
*/

#include <Wire.h>
#include <APM_BMP085.h> // ArduPilot Mega BMP085 Library

unsigned long timer;

void setup()
{  
  APM_BMP085.Init();   // APM ADC initialization
  Serial.begin(57600);
  Serial.println("ArduPilot Mega BMP085 library test");
  delay(1000);
  timer = millis();
}

void loop()
{
  int ch;
  float tmp_float;
  float Altitude;
  
  if((millis()- timer) > 50)
    {
    timer=millis();
    APM_BMP085.Read();
    Serial.print("Pressure:");
    Serial.print(APM_BMP085.Press);
    Serial.print(" Temperature:");
    Serial.print(APM_BMP085.Temp/10.0);
    Serial.print(" Altitude:");
    tmp_float = (APM_BMP085.Press/101325.0);
    tmp_float = pow(tmp_float,0.190295);
    Altitude = 44330*(1.0-tmp_float);
    Serial.print(Altitude);
    Serial.println();
    }
}

This is why I love arduino and whatnot. A library was made and I was happy it worked flawlessly. Will look much nicer in my user code.

Hope this will help others too.
11  Forum 2005-2010 (read only) / Interfacing / Reading/updating I2C BMP085 without delay() on: July 25, 2010, 11:12:33 am
Hi,

I am working on a quadcopter originally from http://aeroquad.com/ which is using a Arduino Mega board.

It is a great platform for quads, but now I've run into a frustrating problem. I wanna add a BMP085 which is a I2C barometer for altitude hold control/height sensoring. I have managed to get this: http://interactive-matter.org/2009/12/arduino-barometric-pressure-sensor-bmp085/ and this: http://mitat.tuu.fi/?p=78 to work great as stand alone read code. I have already managed to get an analog sensor to regulate height fine but only to a maximum distance above ground of 1.5m due to use of SHARP IR sensor. Now I need to evolve.

The values I get are expected in the range around 1004.00-1006.00hPa, and expected temperature too.

The problem is that I cannot use the delay() function which delays and stops the whole flight program for 26ms (read time from sensor) because then it gets out of control and really wild.

Therefore I have made a change so that the code that writes to the "start measure sensor" registers are called at the end of a time interval state code and in the beginning of that code when it comes the second time to the loop it is ready to be read.

The problem is that the way the code works the values read in are in the range of 600.00hPa the way I implemented this and does not correspond as good to the real pressure as the original code. As soon as I comment in the delay in the read function again the sensor gives out relevant and correct data again.

The question is why?

I'll try to put in relevant bits of code:
Code:
//in 26ms loop for the highest resolution of BMP085
byte updateFlag = 0;

if (updateFlag == 1) { //prevent measurement before conversion started
bmp085_read_temperature_and_pressure(&temperature,&pressure);

actualPressure = pressure;
//do something useful with the read in value
}

updateCommandBMP085(); //this function I added to make "write_register" to start reading the values and then wait 26ms
updateFlag = 1;

this is the original code for starting measurement:
Code:
long bmp085_read_up() {
write_register(0xf4,0x34+(oversampling_setting<<6)); //this needs to be done in state loop
delay(pressure_waittime[oversampling_setting]); //this needs to be replaced by the loop time

unsigned char msb, lsb, xlsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(0xf6); // register to read
Wire.endTransmission();

Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.receive();
while(!Wire.available()) {
// waiting
}
lsb |= Wire.receive();
while(!Wire.available()) {
// waiting
}
xlsb |= Wire.receive();
return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}

and what I did to get rid of the delay() was:
Code:
void updateCommandBMP085 () {
   write_register(0xf4,0x2e);   //start temperature reading                  
   write_register(0xf4,0x34+(oversampling_setting<<6)); //start pressure reading
   };

And all this should work exactly as the original test code for BMP085 and Arduino, but just by commenting in/out the "delay(pressure_waittime[oversampling_setting]);" line, I get two totally different readings, when using delay() the reading is correct and the quad goes wild, when commented out and the "write_register" is called from the state loop, the values read in from the sensor is off.

My question is: what am I missing? What is the difference here between using the delay() and calling the write register from a loop instead?


Thanks for any answer!
12  Forum 2005-2010 (read only) / Interfacing / Re: Interrupt Driven Serial on: October 17, 2010, 09:21:31 pm
I have the same problem! Having an CHR-6DM AHRS/IMU and streaming 17 bytes of data in 20Hz only!

Using the Arduino Mega UART1 and a bad protocol I made I get these readings:

Yaw: 3.98  Pitch: 3.25  Roll: -2.79  Acc_Z: -568.35
Yaw: 3.97  Pitch: 324.65  Roll: 317.01  Acc_Z: 297.36
Yaw: 3.98  Pitch: 3.25  Roll: -2.82  Acc_Z: -570.06
Yaw: 3.92  Pitch: 3.27  Roll: -2.81  Acc_Z: -569.20
Yaw: 3.97  Pitch: 3.27  Roll: -2.80  Acc_Z: -569.31
Yaw: 3.97  Pitch: 3.28  Roll: -2.79  Acc_Z: -569.09
Yaw: 3.98  Pitch: 3.28  Roll: -2.80  Acc_Z: -571.23
Yaw: 4.03  Pitch: 3.27  Roll: -2.79  Acc_Z: -570.70
Yaw: 3.96  Pitch: 3.27  Roll: -2.78  Acc_Z: -569.95
Yaw: 3.98  Pitch: 324.65  Roll: 317.01  Acc_Z: 297.36
Yaw: 3.91  Pitch: 3.28  Roll: -2.81  Acc_Z: -569.09
Yaw: 3.90  Pitch: 3.30  Roll: -2.81  Acc_Z: -571.02
Yaw: 324.65  Pitch: 317.01  Roll: 30.59  Acc_Z: 54.79
Yaw: 3.98  Pitch: 3.27  Roll: -2.80  Acc_Z: -568.13


It is unacceptable! Is there anything I can do about it?
13  Forum 2005-2010 (read only) / Interfacing / Re: Wire connectors for i/o pins on: October 08, 2010, 08:24:53 am
http://wingshieldindustries.com/products/screwshield/

There are several "shields" like that.

Otherwise those regular square pins used on like every electronic device fits. I've slaughtered lots of computer board for those pins.
14  Forum 2005-2010 (read only) / Exhibition / Re: Orientation without kalman filter. on: April 27, 2010, 09:02:42 am
Well, for the moment I am just screwing around collecting info to make it reality. Played with an old X-Ufo before and made a static control board for it (RC - to - Xufo), but nothing more atm.

I am thinking of having Sharp distance sensors as collision detectors for indoor flying for example on the real thing.

May I ask why the extreme torque/lifting power is needed (I read your blog, seems to be a stable platform btw)? How heavy camera are you planning to fly around with?

Hmm... Your project is really interesting! You need to post more about it and maybe some video?
15  Forum 2005-2010 (read only) / Exhibition / Re: Orientation without kalman filter. on: April 26, 2010, 11:29:43 am
I really like your idea of handling drift and noise, it is quite easy to understand.

Have you got an actual quad platform to test it on?

And are your intentions to make it be able to log its coordinates and maybe even receive coordinates and go there?


I'm into making a serious quad (been for years actually), then checked out for gyros/accelerometers and got hit in the face by the price. Then I read about interfacing Wii-sensors on the AeroQuad forum (arduino based quad) and it seems to work really well: http://aeroquad.com/showthread.php?12-Low-cost-6DOF-for-this-project/page4 (the thread where it is discussed)
Pages: [1] 2