Trouble with XBees, working units stopped to!

Hello, I am doing a project based on GPS tracking that uses 4 XBee modules to wirelessly communicate the GPS data from a couple of GPS sensors to a Multiwii 328p board (works on an Atmel 328p processor so it is arduino-compatible).

I first 'solved' the problem of connecting 2 different GPS to the main board through the I2C bus, which requires a couple of extra boards converting GPS serial data to I2C protocol (I2C GPS NAV, using EosBandi firmware).

Once I had all that working, plan was to just drop the XBees between the GPS sensors and their respective I2C GPS NAV boards in order to be able to do the tracking part wirelessly.

After tweaking with XCTU and following diverse tutorials on the internet, I managed to achieve the wireless connection, and for a couple of tests, I would verify through the Arduino IDE serial monitor that the main board was receiving the GPS data.

At this point I was powering the XBees with a couple of AA batteries in series (more or less 3V).
They were running in AT mode and I only had connected VCC, GND, DIN, DOUT pins using a custom socket.

Here comes the issue. I have a sparkfun regulated explorer board and tried to migrate the XBees from being AA-powered to be fed by a 2S (7,4V) Li-Po with a voltage regulator (5,2-5,5V) through the sparkfun regulated explorer which supposedly takes care of the 5V to 3.3V conversion.

I just connetcted the GPS VCC, GND, TX, RX to the corresponding VCC, GND, DIN, DOUT of the sparkfun board, plugged in the XBee and attached the voltage regulator + and - to VCC and GND of the sparkfun also. At this point, the communication stopped for good.

When I power everything up, the main board does NOT receive GPS signals anymore.

I tested with the other XBee couple (One couple is XBee Pro S1, the other couple is XBee S2C) and wouldn't work either. Both had already been transmitting flawlessly previously. Then I tried to go back to the AA-powered configuration and ditched the sparkfun regulator BUT it wouldn't work either.

I have tried restoring factory defaults on the XBees, reflashing, updating firmware, and even tried some 'unbricking tutorials' that use the legacy X-CTU 5.8...

None of that worked. What can have happened?

At first I thought that the GPS TX and RX signals at 5V would have fried the XBees but when I use a tester to check out the voltage on all the XBee pins (while plugged to sparkfun explorer), they show a pretty harmless 3,24V.

Also when getting rid of the XBees and directly connecting the GPS sensors to the I2C GPS NAV boards, everything still works fine so it doesn't look like any other components are to blame.

Mind that I use 57600 baud rate on the GPS and I2C GPS NAV boards but I have set that baud rate also on the XBees.

Nothing makes sense. :frowning:

Maybe someone with more experience can shine light on this?

Thanks in advance,
Jandro.

Can you wire up your project again (WITH the XBees). Then, post detailed and clear pictures of all electrical connections as well as the exact code you are using. We can't be much help without that.

Sounds interesting, though. I've used the explorer dongles for XBee comms and they never gave me any problems. What sort of XBees are you using? S1, S2, S2C?

XBees are:

2x 60mW S1 PRO with small antenna.
2x 2mW S2C with small antenna.

I just received another explorer so now I have been able to plug both XBees simultaneously to the computer and test them and they appear to work fine, so they are not bricked after all it seems.

Proof that they actually are functioning:

Which in turn makes me wonder why are they NOT sending the GPS data when plugged to the GPS.

Here is a couple of snapshots of the Coordinator and End devices configuration. Maybe you can see something there that I don't.

Edit: I posted wrong pics this one is the right one:

And there goes the wiring:

(Open in new tab and zoom in to view the detail).

Currently, if I plug one XBee to the GPS receiver and the other one to the computer with explorer, XCTU actually shows it receiving data but it is and endless chain of E0 messages as shown on the image below. What does this mean? Can't find info on this issue.

1.) Why are you using serial to I2C converters?

2.) Are the serial to I2C converters 3v3 or 5v?

3.) Why are some XBees S1 and others S2Cs?

4.) Are you trying to do simplex, half duplex, or full duplex comms?

5.) Exactly which XBees communicates to which XBees? (does the GPS S1 communicate with only the receiver S1 etc?)

6.) Are the XCTU configuration and E0 error pics using the S1s or S2Cs?

6.) Can you provide a link to the GPS receiver?

7.) How are you powering the receiver Arduino?

8.) How are you powering the XBees on the Arduino side?

Sorry for so many questions, but they are necessary to know when debugging.

Also, take a look at this tutorial on using S2Cs.

Sorry for so many questions, but they are necessary to know when debugging.

No need to apologise, I understand it's necessary.

1.) Why are you using serial to I2C converters?

Because:
1 - I need to use more than one GPS.
2 - I want to free the atmel 328p chip serial bus for connection with the PC for debugging.
3 - 328p has only 1 serial bus.

2.) Are the serial to I2C converters 3v3 or 5v?

They are 5V tolerant but I am using them at the tension supplied by the main board (3.3V) and it works good (Confirmed by plugging GPS directly with no XBees, I'm able to receive the data and print coordinates on serial monitor).

3.) Why are some XBees S1 and others S2Cs?

Because I need to send wirelessly the data of a nearby GPS (<1m) and a far away GPS (up to 1km), thus need 2 XBee couples, a long range one and a short range one.
The S1 XBees are 60mW and have 1mile range and the S2C are 2mW and are cheaper. It's what was available at the store. :slight_smile:

4.) Are you trying to do simplex, half duplex, or full duplex comms?

Well, I'm not sure because I'm not so familiarized with the modules yet. I'm still a noob.
That said, I am using them in AT transparent mode. I imagine that they are working at half duplex. Ideally I would want the GPS XBee to send data continuously to the main board. I don't need data to be sent to the GPS so I imagine that Simplex would be optimal, but don't know how to set it up just yet.

5.) Exactly which XBees communicates to which XBees? (does the GPS S1 communicate with only the receiver S1 etc?)

S1 communicates with S1 and S2C with S2C. In the end they must work at the same time but for now I am doing the tests independently so either I am using the S2C ones or the S1 ones but not all simultaneously.

6.) Are the XCTU configuration and E0 error pics using the S1s or S2Cs?

The pic was captured while using S2Cs but the S1 give the same message.
FWIW, DIGI has confirmed to me that this is not an error message they have documented.

6.) Can you provide a link to the GPS receiver?

There's actually 2 of these: (UBLOX Neo M8N)

https://drotek.com/shop/en/511-ublox-neo-m8-gps-module.html

7.) How are you powering the receiver Arduino?

Connected to the PC through USB plug directly into the board.

8.) How are you powering the XBees on the Arduino side?

The XBees on the arduino side (Actually a Multiwii 328P board with custom firmware) has 4 pins dedicated to interface with external I2C devices (SDA, SCL, GND, 3.3V). The board has something to convert the voltage to 3.3V on that pin, and that's what I'm using to power the I2C GPS NAV board which in turn powers the XBee, as depicted in the picture I posted above for the wiring diagram.

RC4ever:
Because:
1 - I need to use more than one GPS.
2 - I want to free the atmel 328p chip serial bus for connection with the PC for debugging.
3 - 328p has only 1 serial bus.

Now, unless you're not willing to change the firmware (Ardupilot?) and/or can't use specific pins (I think it's D8 and D10, but not sure), you can use altsoftserial.h to fake out an additional serial port.

RC4ever:
Because I need to send wirelessly the data of a nearby GPS (<1m) and a far away GPS (up to 1km), thus need 2 XBee couples, a long range one and a short range one.
The S1 XBees are 60mW and have 1mile range and the S2C are 2mW and are cheaper. It's what was available at the store. :slight_smile:

This is bad juju if you don't configure the S1s and S2Cs correctly. Both modules operate on the 2.4GHz band and can cause interference with each other (AND your hand controller) if on channels that are close together. Seems like the S2Cs are on channel E. What about the channels for you S1s and hand controller? (NOTE: Check out the table below)

RC4ever:
Well, I'm not sure because I'm not so familiarized with the modules yet. I'm still a noob.
That said, I am using them in AT transparent mode. I imagine that they are working at half duplex. Ideally I would want the GPS XBee to send data continuously to the main board. I don't need data to be sent to the GPS so I imagine that Simplex would be optimal, but don't know how to set it up just yet.

Good, simplex via AT/Transparent mode is what you want (based on your project description).

RC4ever:
The pic was captured while using S2Cs but the S1 give the same message.
FWIW, DIGI has confirmed to me that this is not an error message they have documented.

Yeah, that aint no error code from the XBees. That's either a nack signal from the I2C module or it's a GPS error code.

RC4ever:
The board has something to convert the voltage to 3.3V on that pin, and that's what I'm using to power the I2C GPS NAV board which in turn powers the XBee

That's some bad juju. You need to power the XBees off a separate power supply. Each S1 alone draws about 0.215 amps. You can probably use a good buck converter to step down the batt voltage to what the XBees need and then connect all the grounds together (including the MultiWii ground).

I've had XBee S1s that didn't work until on their own power supplies.

What baud is your GPS AND i2c converter set to? Baud rates not matching between the GPSs , XBees, and serial converter can give a 0xE0 code.

Power_Broker:
Now, unless you're not willing to change the firmware (Ardupilot?) and/or can't use specific pins (I think it's D8 and D10, but not sure), you can use altsoftserial.h to fake out an additional serial port.

Ain't that very processor consuming? I don't want to slow much the main loop cycle time.
Anyways, not sure I'm winning much with this other than eliminating the I2C board from the equation (which actually works well when connected directly to the GPS without XBees in between.

In the long term could be interesting but right now I'm time-constrained so I don't plan on re-doing my main board and I2C-nav sketches.

I'm not using Ardupilot, I've pretty much created my own code from scratch looking at examples out there. Copied some lines from Multiwii FC firmware but it really works differently. I have barely 700 lines of code (libraries appart) whereas MWI has in the order of tens of thousands...

Power_Broker:
This is bad juju if you don't configure the S1s and S2Cs correctly. Both modules operate on the 2.4GHz band and can cause interference with each other (AND your hand controller) if on channels that are close together. Seems like the S2Cs are on channel E. What about the channels for you S1s and hand controller? (NOTE: Check out the table below)

I don't think they will collide with the 'hand controller' as that uses a totally different protocol based on frequency hopping. It will definitely add noise though. As for crashes between the XBees, I'll have to look into that. Thanks for posting the chart. I thought that if I'd be okay just by setting different channels and PAN IDs. :o

Power_Broker:
Good, simplex via AT/Transparent mode is what you want (based on your project description).

Is that what I will get in AT mode 'out of the box' or do I need to configure some extra parameter with XCTU?

From what I have read from DIGI's info on the XBees, these act as pure receivers if no data is getting in the DIN pin, so if I am not sending data there, the default configuration should act unidirectionally, am I correct, or am I drifting? :smiley:

Power_Broker:
Yeah, that aint no error code from the XBees. That's either a nack signal from the I2C module or it's a GPS error code.

When I get that message, I don't have the I2C part connected, just the GPS with Xbee on one end and XBee with computer on the other, so I'd assume it has something to do with the XBee as I have already checked that the GPS works correctly when connected directly to the I2C GPS NAV board... Or could the connection with XBee alter the Tx signal from the GPS in any manner? I don't think so but again, I am no expert... :roll_eyes:

Power_Broker:
That's some bad juju. You need to power the XBees off a separate power supply. Each S1 alone draws about 0.215 amps. You can probably use a good buck converter to step down the batt voltage to what the XBees need and then connect all the grounds together (including the MultiWii ground).

Hmmm... if that's right it might be a problem as I plan to mount all this onto a camera gimbal, so weight is critical for correct operation of the device. If I start adding extra batteries and regulators it adds too much volume and weight. :fearful:

Power_Broker:
I've had XBee S1s that didn't work until on their own power supplies.

Ouch. :fearful: :fearful: :fearful:

Power_Broker:
What baud is your GPS AND i2c converter set to? Baud rates not matching between the GPSs , XBees, and serial converter can give a 0xE0 code.

I have everything setup to 57600 baud rate. But maybe it's crashing in spite of that. Timing issues maybe?

RC4ever:
Ain't that very processor consuming?

No, but based on your constraints, it's probably not a good time to fool with it. Just thought I'd let you know that you have options.

RC4ever:
I'm not using Ardupilot, I've pretty much created my own code from scratch looking at examples out there. Copied some lines from Multiwii FC firmware but it really works differently. I have barely 700 lines of code (libraries appart) whereas MWI has in the order of tens of thousands...

Interesting; could you post your code?

RC4ever:
I don't think they will collide with the 'hand controller' as that uses a totally different protocol based on frequency hopping. It will definitely add noise though. As for crashes between the XBees, I'll have to look into that. Thanks for posting the chart. I thought that if I'd be okay just by setting different channels and PAN IDs.

No problem. What is the channel for the S1s?

RC4ever:
Is that what I will get in AT mode 'out of the box' or do I need to configure some extra parameter with XCTU?

Yes. XBees are by default set to transparent mode. This is half duplex, but not a problem for you at all. The problem is that your S2Cs are configured in API mode instead of transparent mode. In transparent mode, there are no coordinators nor end devices, only standalone radios that talk p2p. Change your S2Cs to transparent mode (reset both to factory default configuration) and see if that fixes your 0xE0 problem.

RC4ever:
From what I have read from DIGI's info on the XBees, these act as pure receivers if no data is getting in the DIN pin, so if I am not sending data there, the default configuration should act unidirectionally...

Yep, that's how they work.

RC4ever:
When I get that message, I don't have the I2C part connected, just the GPS with Xbee on one end and XBee with computer on the other, so I'd assume it has something to do with the XBee as I have already checked that the GPS works correctly when connected directly to the I2C GPS NAV board... Or could the connection with XBee alter the Tx signal from the GPS in any manner? I don't think so but again, I am no expert...

Assuming the wiring is correct, this message should be either an API mode issue (again, you should switch to transparent mode) or incorrect baud issue. Note that your GPS works at 9600 baud by default. Can you ensure that you changed the baud to 57600 on the GPS module? Also, note that you will get a higher bit error rate at higher bauds. This may also play into the 0xE0 error.

RC4ever:
Hmmm... if that's right it might be a problem as I plan to mount all this onto a camera gimbal, so weight is critical for correct operation of the device. If I start adding extra batteries and regulators it adds too much volume and weight. :fearful:

Not really a problem; just get a small buck converter (or two) and parallel the buck inputs with the preexisting battery supply pins and wire the buck outputs to the XBees. No extra batteries, just a really light chip.

Also, why the heck are you putting all of this in a camera gimbal? Odd place to put a GPS receiver, lol. No more room in the fuselage?

Power_Broker:
Interesting; could you post your code?

There ya go!
I've attached the code for the main board and also what finally made it into the I2C GPS NAV boards.

Power_Broker:
No problem. What is the channel for the S1s?

I tested with several different... mainly C and D.

Power_Broker:
Yes. XBees are by default set to transparent mode. This is half duplex, but not a problem for you at all. The problem is that your S2Cs are configured in API mode instead of transparent mode. In transparent mode, there are no coordinators nor end devices, only standalone radios that talk p2p. Change your S2Cs to transparent mode (reset both to factory default configuration) and see if that fixes your 0xE0 problem.

Don't think so, as my S1s are showing the exact same problem.

Power_Broker:
Assuming the wiring is correct, this message should be either an API mode issue (again, you should switch to transparent mode) or incorrect baud issue. Note that your GPS works at 9600 baud by default. Can you ensure that you changed the baud to 57600 on the GPS module? Also, note that you will get a higher bit error rate at higher bauds. This may also play into the 0xE0 error.

For that reason I stood with 57600 instead of 115200, but you need at least 57600 for 5Hz update rates if I am not mistaken. I can assure that I did change the baud rate of GPS, I2C board and XBees all to 57600...

Actually the I2C board code was designed to reprogram the GPS to a particular baud rate but I think I disabled that by commenting or deleting the appropiate lines of code.
Original code was made by EosBandi.

I don't think I am using API mode either in the S2Cs though... :confused:

Power_Broker:
Also, why the heck are you putting all of this in a camera gimbal? Odd place to put a GPS receiver, lol. No more room in the fuselage?

Actually the idea is to take the GPS AWAY from the gimbal, lol.

It's the main board and the XBees the ones that would go there.

The original idea for the project is to make a GPS-based tracker for drones (or for stand-alone gimbals) so that they automatically orientate the camera in the direction of the tracked object. The main board has gyros, accelerometers, barometer and magnetometer, that can be used to calculate the cam orientation. Since drones are mostly carbon-fiber made, GPS receiver should go on top of airframe to get a clear view of the sky. Even if you just want a stand alone gimbal you still want GPS on top BUT you don't want to run wires through to the gimbal, to allow it to be able to rotate 360º continuously. Thus the need for the close-distance wireless connection in addition to the long-distance GPS telemetry thing.

I have most of the basics of the project covered but can't test it if I don't manage to get over the XBees problem detailed in this thread. I'm quite desperate frankly, at this point. Hahaha :grin:

HMC5883L.cpp (14.4 KB)

HMC5883L.h (4.83 KB)

I2Cdev.cpp (55.1 KB)

I2Cdev.h (11.9 KB)

TFGunified.ino (25.7 KB)

I2C_GPS_NAV_v2_2.zip (31.6 KB)

RC4ever:
There ya go!
I've attached the code for the main board and also what finally made it into the I2C GPS NAV boards.

Cool code! I've never seen anybody do a PLL with a gyroscope. How did you find out about that? Also, why are you doing a LPF on gyroscope data? Isn't it more useful to do a HPF on gyroscope data due to it's inherent drift?

RC4ever:
Don't think so, as my S1s are showing the exact same problem.

Hmmm, in that case, I'd try setting everything back to 9600 baud and try that (again, after resetting to factory default configuration).

RC4ever:
For that reason I stood with 57600 instead of 115200, but you need at least 57600 for 5Hz update rates if I am not mistaken. I can assure that I did change the baud rate of GPS, I2C board and XBees all to 57600...

57600 bits per second is 7200 bytes a second. Assuming you are sending a single NMEA string of about 82 characters, you can manage an update frequency of about 50Hz - 10 times your requirement. With 9600, you can get a max of about 7.3Hz update frequency. Again, I'd try everything at 9600 and see if that doesn't fix your 0xE0 error.

RC4ever:
I don't think I am using API mode either in the S2Cs though... :confused:

I'm pretty sure you are. As I said before, there's no coordinator or end device in transparent, only API.

RC4ever:
Thus the need for the close-distance wireless connection in addition to the long-distance GPS telemetry thing.

Well, instead of using S2Cs for such small distances, why not use bluetooth transceivers? They're much easier to use and have a 30ft range. NOTE: I hope you've accounted for EMI and phantom signals when doing wireless comms in a metal enclosure like a plane.

One last thing: Can you post a pic of your actual setup (including wiring and PC connections - everything)?

Well, I just resolved the issue.

After investigating a bit I found out that even though 'forcing' the I2C GPS NAV board to work at 57600 baud, the firmware used for that board initialised by doing a 'scan' through several different baud rates. After changing the code accordingly to disable this and make ALL communications at 57600 baud right from the start and reflashing, everything went well.

Power_Broker:
Cool code! I've never seen anybody do a PLL with a gyroscope. How did you find out about that? Also, why are you doing a LPF on gyroscope data? Isn't it more useful to do a HPF on gyroscope data due to it's inherent drift?

Well, I just followed the datasheet of the component manufacturer. They suggested to configure / set up the gyro in that way (PLL) for stability reasons. I don't even completely understand it, I just implemented what was suggested.

As for gyro filtering, I have been having issues. The filtering doesn't bother me so much (The angle calculated through numerical integration is quite accurate) but I have been trying to implement the so-called the complementary filter precisely to get rid of the gyro drift over time but it just DOES NOT WORK as portrayed in the tutorials. I have to investigate more on that, for the time being I'm mostly relying on the accelerometers and mag for the angle calculation which means that I can't use this on an airborne platform just yet (adding in the gyro's angle calculations help to get rid of accelerometer errors when working in a non inertial platform, such as a flying drone).

Power_Broker:
57600 bits per second is 7200 bytes a second. Assuming you are sending a single NMEA string of about 82 characters, you can manage an update frequency of about 50Hz - 10 times your requirement. With 9600, you can get a max of about 7.3Hz update frequency. Again, I'd try everything at 9600 and see if that doesn't fix your 0xE0 error.

Well, there's more to it as the GPS sends both NMEA and UBX sentences but I am no expert on that either. For the time being it works just fine. When I have more time I want to try 10Hz update rates :slight_smile:

Power_Broker:
Well, instead of using S2Cs for such small distances, why not use bluetooth transceivers? They're much easier to use and have a 30ft range. NOTE: I hope you've accounted for EMI and phantom signals when doing wireless comms in a metal enclosure like a plane.

That's an interesting alternative but I thought it would be faster to do everything with XBees... because I just need to learn how to use XBees. Otherwise I need to learn how to use both XBees and Bluetooth modules and as I said, I'm quite in a hurry now (Need to present the project).

Power_Broker:
One last thing: Can you post a pic of your actual setup (including wiring and PC connections - everything)?

I can but it's a bit chaotic... don't think it will be of much use unless I go in detail pics of EACH connection made. I will do it eventually but right now I gotta move on. Anyway, it's exactly set up as portrayed in the 'wiring diagram' pic that I posted earlier in the thread :slight_smile:

Thanks again for your help!

BTW, if you know how to properly get rid of the gyro drift, I'm all ears!

RC4ever:
Well, I just resolved the issue.

After investigating a bit I found out that even though 'forcing' the I2C GPS NAV board to work at 57600 baud, the firmware used for that board initialised by doing a 'scan' through several different baud rates. After changing the code accordingly to disable this and make ALL communications at 57600 baud right from the start and reflashing, everything went well.

Nice!! I'm glad it's working now.

RC4ever:
As gyro filtering, I have been having issues. The filtering doesn't bother me so much (The angle calculated though numerical integration is quite accurate) but I have been trying to implement the so-called the complementary filter precisely to get rid of the gyro drift over time but it just DOES NOT WORK as portrayed in the tutorials.

Drift is very common in MEMS gyroscopes. The drift itself is a low frequency component of the output that can be filtered out using a high pass filter (HPF) instead of a low pass filter (LPF). Most people use what is called a complementary filter, which is comprised of two filters; a LPF for the accelerometer and a HPF for the gyro.

Here is a link that describes how to do a discrete time HPF.

Procedure:
1.) Pick a cutoff frequency, fc (all frequency components below this cutoff will be rejected and all frequency components above will be passed)
2.) Pick a constant sampling period, deltaT (one sample per time period - for instance, it could be 1 sample per 5ms)
3.) Find alpha. [alpha = 1 / (1 + 2pifc*deltaT)]
4.) Plug it into the following code as a reference:

//cutoff frequency in Hz
int fc = 20;

//timer stuff
double currentTime = millis();
double previousTime = currentTime;
double samplePeriod = 5; //in ms

//current gyro data (current sample)
float gx = 0;
float gy = 0;
float gz = 0;

//previous gyro data (previous sample)
float PREVgx = 0;
float PREVgy = 0;
float PREVgz = 0;

//filtered gyro data
float outputgx = 0;
float outputgy = 0;
float outputgz = 0;

//previous value of filtered gyro data
float PREVoutputgx = 0;
float PREVoutputgy = 0;
float PREVoutputgz = 0;

//alpha constant
float alpha = 1/(1 + (2*pi*fc*(samplePeriod/1000))); //converting samplePeriod from ms to s



void loop()
{
  //prime the timer
  currentTime = millis();

  //execute once a time period
  if ((currentTime - previousTime) >= samplePeriod)
  {
    //reset timer
    previousTime = currentTime;


    //GET GYRO DATA HERE  <----
    

    //High Pass Filter:
    outputgx = alpha*(PREVoutputgx + gx - PREVgx);
    outputgy = alpha*(PREVoutputgy + gy - PREVgy);
    outputgz = alpha*(PREVoutputgz + gz - PREVgz);

    //reset the values of previous samples:
    PREVgx = gx;
    PREVgy = gy;
    PREVgz = gz;
    PREVoutputgx = outputgx;
    PREVoutputgy = outputgy;
    PREVoutputgz = outputgz;
  }
}

NOTE: Discrete filters only work when you take measurements at constant intervals. You must sample at a constant rate!

Also, is this for a school project?

Pics of the setup, with and without XBees:

Power_Broker:
Drift is very common in MEMS gyroscopes. The drift itself is a low frequency component of the output that can be filtered out using a high pass filter (HPF) instead of a low pass filter (LPF). Most people use what is called a complementary filter, which is comprised of two filters; a LPF for the accelerometer and a HPF for the gyro.

Well, the gyro isn't itself the source of the drift but rather the fact that we have to integrate to obtain angle orientation, and this isn't 100% precise.

Power_Broker:
Here is a link that describes how to do a discrete time HPF.

Procedure:
1.) Pick a cutoff frequency, fc (all frequency components below this cutoff will be rejected and all frequency components above will be passed)
2.) Pick a constant sampling period, deltaT (one sample per time period - for instance, it could be 1 sample per 5ms)
3.) Find alpha. [alpha = 1 / (1 + 2pifc*deltaT)]
4.) Plug it into the following code as a reference:

    //GET GYRO DATA HERE  <----

//High Pass Filter:
    outputgx = alpha*(PREVoutputgx + gx - PREVgx);

//reset the values of previous samples:
    PREVgx = gx;
    PREVoutputgx = outputgx;

}
}

What I find really interesting from your example is the way you are implementing it in the code... I will play with that. Not sure if it's just the same I was doing written in a different fashion but I think not...

The issue with my implementation is that the angle is calculated as previous angle + (gyro meassurement*cycle time). In this way, over a certain time, when the meassure has accumulated say for example 20º of error drift, the complementary filter (in the way I understood it had to be used) just decreased the 'weight' of the gyro meassurement in the calculation, but since the error does not reset, it just scales the drift down but does not get rid of it.

Will test a bit with your code and come back with the result, thank you :slight_smile:

Power_Broker:
NOTE: Discrete filters only work when you take measurements at constant intervals. You must sample at a constant rate!

Why?
I was using variable-cycle algorithm to optimize resources. cycle time is around 40-50ms

Power_Broker:
Also, is this for a school project?

It's the final project for my Bachelor's Degree in 'Engineering in Aerospace Vehicles Design'.

RC4ever:
Well, the gyro isn't itself the source of the drift but rather the fact that we have to integrate to obtain angle orientation, and this isn't 100% precise.

Oh I see now. I was confused with your last post. Either way, gyro drift is probably part of the problem. Might not need a HPF for the gyro, but would be cool to test if you get the chance. Not sure what cutoff frequency you want for the HPF, maybe 1Hz?

As for the time integration drift, I think it has to do with too large of a sampling time period. 40-50ms is quite a long time IMHO. If you could somehow manage a sample period of no more than 10ms, I think you'd get less drift. The smaller the period the better.

Also, you should try different values of "a" in your complimentary filter to see what gives the best results. Try decreasing the gyro authority from 98% and increase the accelerometer authority above 2%. That'd be my guess.

Another point; this piece of code looks rather odd. Can you explain why you are zeroing out your gyro data here:

  if (abs(gX)<2)
  {
    gX=0;
  }
  if (abs(gY)<2)
  {
    gY=0;
  }
  if (abs(gZ)<2)
  {
    gZ=0;
  }

RC4ever:
What I find really interesting from your example is the way you are implementing it in the code... I will play with that. Not sure if it's just the same I was doing written in a different fashion but I think not...

It's quite different than what you have.

RC4ever:
The issue with my implementation is that the angle is calculated as previous angle + (gyro meassurement*cycle time). In this way, over a certain time, when the meassure has accumulated say for example 20º of error drift, the complementary filter (in the way I understood it had to be used) just decreased the 'weight' of the gyro meassurement in the calculation, but since the error does not reset, it just scales the drift down but does not get rid of it.

Yeah, the complimentary filter is cool, but I don't have a lot of experience with it. Based on descriptions I've seen, its supposed to combine both a LPF on the accelerometer and HPF on the gyro along with some gains relating to "a" or whatever. I can't find very vigorous or in-depth explanations on the nuts and bolts of it, so not sure what to tell you here. I would venture to guess that you are correct in assuming the error doesn't reset and only scales down.

What I would do if all else fails is to get rid of the complimentary filter, keep the LPF for the accelerometer, implement a HPF for the gyro, calculate the angle from both accelerometer and gyroscope and then take a weighted average of the two. Does that make sense?

The HPF most certainly gets rid of the drift and you are still taking into account the accelerometer readings.

RC4ever:
Why?
I was using variable-cycle algorithm to optimize resources.

I doubt it this will save you much processing, but I could be wrong. The reason discrete time filters require a fixed sample period is based on the how you convert a transfer function in the Laplace domain to the discrete time "Z" domain. If you work it out correctly, you will find you will have a constant, delta t, that will be a fixed sampling period. Change the sampling period and it will change the filter's frequency response.

Now, since the complimentary filter, I would dare to say, isn't a discrete time filter and more of a weighted average, I don't think you do not need to sample at a fixed rate (wouldn't hurt, though). If you implement a discrete time filter, like the one I posted earlier, you most definitely would need a fixed sample rate or you will get erroneous outputs most of the time.

Disclaimer: I'm only an undergrad in college myself and am no expert by any stretch. There are others in the forum that might be able to help you out better than I.

Also, if you use any of my techniques (if they work lol), I'd ask that you credit it. Thanks!

Power_Broker:
Oh I see now. I was confused with your last post. Either way, gyro drift is probably part of the problem. Might not need a HPF for the gyro, but would be cool to test if you get the chance. Not sure what cutoff frequency you want for the HPF, maybe 1Hz?

The sensors actually do implement filters on their own so you can just change the filtering by changing a registry value through I2C and therefore, saving that 'processing time' for the processor to work on other things. So the actual value that you are reading from the gyros is actually pre-processed but if filtering too much, you will lose the 'instantaneous better accuracy' that the gyro offers over the accelerometer, so I'd be careful with that. Now I'm speaking from memory so don't take me too seriously but I think the default value for the LPF is 10Hz.

Power_Broker:
As for the time integration drift, I think it has to do with too large of a sampling time period. 40-50ms is quite a long time IMHO. If you could somehow manage a sample period of no more than 10ms, I think you'd get less drift. The smaller the period the better.

You are likely right there with some limits... if you sample too fast you may start getting bigger noise errors but other than that yeah, the shorter the period, the more accurate the integration. To do that, one should make a software interrupt service routine that periodically sampled the gyro at a constant rate. It can be done but it is more work... Probably worth it and maybe I will implement it later on but right now I just don't have time to spare hahaha!

Power_Broker:
Also, you should try different values of "a" in your complimentary filter to see what gives the best results. Try decreasing the gyro authority from 98% and increase the accelerometer authority above 2%. That'd be my guess.

I already did. There's where I find out that the filter just scaled the drift error but didn't eliminate it. Actually, if you set 'a' to 0.5 (50% weight to each sensor) you are just calculating the arithmetic average of both. A not really elegant to solve the drift issue would be to set some 'if' condition that reset the 'accumulated angle' to 0 when the accelerometer is reading only 1G and the x and y components of acceleration are approximately zero. That should work but I'd prefer to find a more elegant and robust solution. Yeah, I've also heard about the Kalman filter but I don't like implementing 'magic' procedures into my project... like to understand exactly what I'm doing and Kalman filters would take many hours to learn properly. :slight_smile:

Power_Broker:
Another point; this piece of code looks rather odd. Can you explain why you are zeroing out your gyro data here:

  if (abs(gX)<2)

{
    gX=0;
  }
  if (abs(gY)<2)
  {
    gY=0;
  }
  if (abs(gZ)<2)
  {
    gZ=0;
  }

Yup, sure.
This is a deadband. I was just playing with possibilities. This limits the drift greatly.
When the board is almost still, the drift still accumulates because of gyro noise. With these lines I'm forcing readings to be zero if not greater than 2 bits, so the error accumulates when moving but not when still. It's not the best way to deal with it but for the time being, makes the problem smaller.

Power_Broker:
Yeah, the complimentary filter is cool, but I don't have a lot of experience with it. Based on descriptions I've seen, its supposed to combine both a LPF on the accelerometer and HPF on the gyro along with some gains relating to "a" or whatever. I can't find very vigorous or in-depth explanations on the nuts and bolts of it, so not sure what to tell you here. I would venture to guess that you are correct in assuming the error doesn't reset and only scales down.

Well, that's what it does on my implementation but it isn't what it is meant to be. I saw some experimental data from people supposedly implementing complementary filters and they were getting rid of the drift but the offered equations and code just did not translate into the same results, which leads me to think that I'm either missing something or they didn't post the final version of the code.

Power_Broker:
What I would do if all else fails is to get rid of the complimentary filter, keep the LPF for the accelerometer, implement a HPF for the gyro, calculate the angle from both accelerometer and gyroscope and then take a weighted average of the two. Does that make sense?

It makes... but it doesn't... I mean (no offense) that's exactly what the complementary filter is doing now. :slight_smile:

Power_Broker:
I doubt it this will save you much processing, but I could be wrong. The reason discrete time filters require a fixed sample period is based on the how you convert a transfer function in the Laplace domain to the discrete time "Z" domain. If you work it out correctly, you will find you will have a constant, delta t, that will be a fixed sampling period. Change the sampling period and it will change the filter's frequency response.

Now that you mention it, it makes sense to me. Since 'a' and time constant are directly related, modifying the time constant (variable cycle time) would require to modify 'a' (which I don't). Still, I assume that the error from doing this is several orders of magnitude smaller than that of the drift so for now I'd just ignore it. But yes, I think you are right on your assertions.

Power_Broker:
Now, since the complimentary filter, I would dare to say, isn't a discrete time filter and more of a weighted average, I don't think you do not need to sample at a fixed rate (wouldn't hurt, though). If you implement a discrete time filter, like the one I posted earlier, you most definitely would need a fixed sample rate or you will get erroneous outputs most of the time.

Can try to test and see :slight_smile:

Power_Broker:
Disclaimer: I'm only an undergrad in college myself and am no expert by any stretch. There are others in the forum that might be able to help you out better than I.

Also, if you use any of my techniques (if they work lol), I'd ask that you credit it. Thanks!

Well, you are actually helping which is a lot to me, thank you.
If the filter thing ends up on my code I'll definitely mention it on the report. I will have to do an exhaustive list of all my sources... it's going to be a long one, lol. :smiley:

RC4ever:
The sensors actually do implement filters on their own so you can just change the filtering by changing a registry value through I2C and therefore, saving that 'processing time' for the processor to work on other things. So the actual value that you are reading from the gyros is actually pre-processed but if filtering too much, you will lose the 'instantaneous better accuracy' that the gyro offers over the accelerometer, so I'd be careful with that. Now I'm speaking from memory so don't take me too seriously but I think the default value for the LPF is 10Hz.

No, no, no. I think you misunderstood me. I get that the IMU already does filtering, BUT only Low Pass Filtering (LPF). I'm saying that you should keep the IMU filtering, but add a High Pass Filter (HPF) for the gyro data. HPF is very different than a LPF. They are literally opposites. Are you sure you know the difference between the two?

RC4ever:
if you sample too fast you may start getting bigger noise errors

Ridiculous. Noise will be relatively constant no matter what sample rate you use. The noise from the sensor can be safely approximated as Additive White Gaussian Noise (AWGN). In this case, you will have a Signal to Noise Ratio (SNR) that has no bearing on sample rate.

RC4ever:
To do that, one should make a software interrupt service routine that periodically sampled the gyro at a constant rate.

Eh, not really. That is, unless your code is really that slow (in that case, you might want to use a more powerful microcontroller in future project revisions). For instance, the discrete time HPF I posted has a fixed sample rate without touching interrupts.

RC4ever:
It makes... but it doesn't... I mean (no offense) that's exactly what the complementary filter is doing now. :slight_smile:

I've done some thinking on the so called complimentary "filter", and I've reached the conclusion that is really just a weighted average between two signals. This is not what I would consider a true digital "filter". What people have done is created an algorithm with no feedback that uses averages to "fake" the filtering of the gyro and accel data. What I proposed was VERY different and, in my opinion, much better.

My technique (albeit untested) uses true digital filtering with feedback in addition to a weighted average that will virtually eliminate gyro drift as long as the alpha constant is correctly chosen.

Let me say it again: there is no digital filtering in a complimentary filter - just a weighted average between two angles.

This is different than what I proposed.

RC4ever:
Now that you mention it, it makes sense to me. Since 'a' and time constant are directly related, modifying the time constant (variable cycle time) would require to modify 'a' (which I don't).

Ok, now we have to be careful to differentiate between the "janky" complimentary filter and real digital filters. The 'a' constant in your complimentary filter is drastically different than the alpha constant in the discrete filter.

The 'a' constant is absolutely nothing more than a constant that controls how much weight, or credibility, is given to the gyro vs the accel. It has absolutely zero to do with anything else; no time constant, nothing.

On the other hand, the alpha constant used in discrete filters is almost entirely based on the desired time constant and sampling period.

RC4ever:
Well, you are actually helping which is a lot to me, thank you.

No problem, I'm glad it's helping. By the way, your youtube vids and planes are awesome!