Magnometer calibration

All of our smartphones have an integrated compass. It can be very useful when you are looking for in which direction you should start heading while walking. However, you have probably noticed that sometimes, the direction showed by our phones can be quite...wrong! It happens when the compass has not been calibrated correctly. But if you try to turn the compass around in every direction, you'll probably notice that the direction arrow finally takes the right direction. Why? Because the smartphone is doing a "live" calibration as you move the compass.

What you should keep from this introduction is that compass calibration is fundamental ! Don't intend on using a magnetic sensor in your project unless you have it calibrated. Otherwise, the data you'll be using will probably be inaccurate, if not completely random 😀

Back to basics
What does a magnetometer do?

"Well, it obviously gives you your heading!"

"NOPE! (Chuck Testa)"

The magnetometer gives you a three dimensional vector of the magnetic field it senses. This magnetic field is a combination of both the earth's field and of the magnetic field created by all the surrounding objects. And this second magnetic field is far from being negligible,  especially in our hobbyist projects where there's electronics (and motors) all around.

Theoretically, the measured magnetic field should :

  •  be centered around 0
  • always have the same strength

If we could represent it in 3D, it should basically look like a perfect sphere centered in 0.

In reality :

  • it is not centered around 0, because of the presence of other magnetic fields around the sensors(such as other magnets, electric wires) : it is hard iron distortion.
  • it does not have a constant strength, because of the presence of other ferromagnetic materials around the sensors, which skew the magnetic field. This is soft iron distortion.

What we get is essentially a potato-shaped magnetic field (because of soft iron distortion), that is not even centered (because of hard iron distortion).

Calibration techniques
Hard Iron distortion

Hard iron errors introduce an offset in the magnetometer data

\mathbf(Field_{magnetomer} =Field_{earth} +Field_{hard iron})


To get this offset is pretty simple : we keep track of the maximum and minimum values the magnetometer outputs on each axis while moving it in space. From what we know the maximum and minimum should be centered around 0, so we get the offset by :

 x_{offset} = \frac{x_{min} + x_{max}}{2}

We can then subtract the measured offset from each raw measurement in order to get  hard iron free data.

Soft Iron distortion

Here, the work consist in transforming a potato in an orange. Or, transforming an ellipsoid into a sphere, if you prefer. It's actually easier than it sounds. There are  obviously mathematical formulas that involve matrices but let's keep it simple here.

Let's say earth magnetic field's value is F. It is the norm of the vector given by the magnetometer. While we've seen it should be the same on the three axes, experience shows it's not. So let's assume we have measured the maximum magnetic field Fx for the x axis,Fy for the y axis, Fz for the z axis.

We then calculate the average field value F by :

 F = \frac{F_x+F_y+F_z}{3}

Let's assume that F = 1. If F_x = 0.8, it means that F_x is only 80% of the average field value. Hence the potato. Now if we simply multiply all the incoming x values by F/F_x, the potato effect, will be gone, as we expand the range of the x values so that it is no longer 80% of what it should be, but 100%.

Scale_x = \frac{F}{F_x}

Final equation

If we no combine the two equations and use vectors, we get:

\mathbf(Field_{corrected} = Scale * (Field_{raw} - Offsets) )

Scale transforms the potato into an orange(soft iron distortion) and the Offsets vector brings it back in the center(hard iron).

Calibration process

The calibration consist in getting the min/max values of x/y/z fields, and then calculations the offsets and scale factors. The more you move the magnetometer in all directions, the more efficient your calibration will be.

Using calibration data

// We get the raw values here  in mx,my,mz

//(this is pseudo code)


// Now we apply the calibration data

mx = (int)((scale_x)*(mx-x_offset));
my = (int)((scale_y)*(my-y_offset));
mz = (int)((scale_y)*(mz-z_offset));


Using Processing and  a slightly modified version of this program, I was able to quickly draw the 3D representation of the magnetic field. The video shows the before/after.


As you can see, hard irons distortion was HUGE before calibration. I could never have gotten reliable readings without correcting them. Soft iron errors were also present, and completely removed by the calibration. 🙂






The drone parachute

Let's talk about parachutes.

Multicopters can become deadly weapons if the motors stop spinning as they should. There are so many reasons for a failure to happen (bad motors, bad battery, radio problems,etc...)  that it is absolutely necessary for the pilot to anticipate it, especially if you intend to flight over people's head!  We made the choice to never fly directly above people, but if you're willing take that risk,  you might be interested into getting a parachute on your drone . That's why we designed last year a DIY parachute for our quadcopter  🙂

The principle is very simple : the parachute is carefully folded  in a tube on top of which lies a lid that a servomotor keeps closed. At the bottom of the tube, a big spring pushes strongly the parachute towards its top end. So if the servo lets the lid go, the spring will push the parachute in the air.

It may be hard to believe, but the parachute will fit in the tube !
It may be hard to believe, but the parachute will fit in the tube !
The spring is separated from the parachute by a CNC milled ring.
The spring is separated from the parachute by a CNC milled ring.

I recommend you use a strong spring, so the parachute is entirely pushed out when the servo releases the lid. The spring we used is 10cm long, has 8 turns and is 3.5cm wide. It can be fully compressed under pressure, which is what we wanted here, in order to get the smaller parachute we could.

A hook holds the string to the bottom plate
A hook holds the string to the bottom plate

One of the major problems with parachutes is that the air needs to get "under" the parachute envelope in order to make it act as it should. If it doesn't , the parachute will become useless. We followed the method described in the following video :


This is how the parachute looks before we insert the actual parachute. The spring will eventually be pressured until its minimum lenth
This is how the parachute looks before we insert the actual parachute. The spring will eventually be pressured until its minimum lenth
We used a glass fiber bottom plate as it needs to resist to a lot of pressure
We used a glass fiber bottom plate as it needs to resist to a lot of pressure
Bottom plate. It can attached to your frame by screws or zip-ties (we love them :) )
Bottom plate. It can attached to your frame by screws or zip-ties (we love them 🙂 )

Parachute surface calculation


Obviously, your parachute's surface needs to match the weight of your copter, and the desired landing speed you would like to reach. I think a commonly accepted falling speeds sits around 5m/s (18km/h).

We found in the past a pretty useful formula that gives the diameter of tissue to use depending on the weight you want to slow down and its expected falling speed:

 Diameter = \frac{70*\sqrt{m}}{V}

, with m in grams and V in km/h.


For our 1kg drone, it gives us a diameter of 122cm. As you can see, the parachute can quickly become huge compared to the size of your multicopter, and you should maybe start thinking about where to place it on your drone from the very beginning of its conception.

For our quadcopter, we used a slightly smaller parachute (taken from a distress rocket) than the 120cm recommended size given by the formula, which led to higher falling speeds than the expected 5m/s, but it stayed slow enough to keep the drone intact after many, many test flights ! 🙂

Parachute ready for insertion
Parachute ready for insertion
See, it fits ! :)
See, it fits ! 🙂
Ready to go!
Ready to go!
The servo arm is under a lot of pressure here.
The servo arm is under a lot of pressure here. We used the TGY-53317M servo for this parachute.


Here's the final video 🙂

Comment if you have any question ! 🙂

New videos/ photos. When a drone goes 250m high

Hi everyone!

I created a new album on my flick'r account : Drones and stuff. I will try to update it frequently with pictures of everything we do 🙂

Our quadcopter
Our quadcopter

We also posted 3 new videos on Youtube:

A FPV flight where we reach 250m of altitude with our quadcopter


A peaceful flight near Saint-Benin, France.


A little "ad" for multicopters 🙂


More to come soon 🙂

The Ardupilot Mega 2.5 : why it's awesome.

After a good run, we decided it was time for our homemade quadcopter controller board to go. Actually, it had to. It started to wobble in the air pretty violently for no reason while flying. We made no change to the program, nor touched the hardware, and since it was working fine before, we figured that it probably came from an electronic problem somewhere in the tons of wires and soldering we made. Pretty hard to "debug"...

So here we were, on 3D Robotics website, ready to click the famous "Add to cart" button. And we finally did click, after a long time of hesitation. It was not that long, in fact. It was a no-brainer. For 180$, you get a tiny assembled PCB with an accelerometer, gyroscope, magnetic sensor, pressure sensor, GPS, current sensor, with completely open-source software that will let you do basically anything you could want to do with any kind of RC model. Not only this works with quadcopters in + or X configurations, it's also made for RC cars, planes,hexacopters, Y6 copters, octocopters, tricopters, and even helicopters! 180$ seems pretty cheap now, doesn't it? 😉

All the firmwares you can upload to the onboard Arduino mega
All the firmwares you can upload to the onboard Arduino mega
We don't regret having spent so much time on our controller board at all. It was a great experience, it worked pretty well and got us to understand pretty much everything about how these drones fly. We just couldn't make something so small and so well designed ourselves in our garage. Plus, the huge community working on the Ardupilot's software came to something close to perfection, with a dedicated windows program (APM mission planner) that can control every single parameter of the drone, communicate with it in flight via a telemetry module, prepare mission scripts with GPS waypoints and actions to take, read flights logs and export them into Google earth-friendly KML files (and more)!

What comes with the Ardupilot
What comes with the Ardupilot
We ordered the fully assembled APM 2.5 with a Mediatek GPS, and a current sensor. It also delivers with a USB to micro USB cable so you have everything you need to start playing 🙂

The Mediatek GPS,  current sensor and APM2.5
The Mediatek GPS, current sensor and APM2.5
It turned out very easy to setup on our existing quadcopter frame. We followed the instructions given on the arducopter google code project and everything went smooth and fast! The steps are the following:

  1. Download mission planner and install it (it will also install the Arduino mega drivers on your computer)
  2. Plug-in your APM
  3. Start mission planner
  4. Choose from the drop-down list the COM port you APM has (check Windows Device manager to find which one)
  5. Go on the firmware tab, select the one you want to use, upload it!
  6. Press connect and you're ready to configure everything!

The default parameters should be fine for an average quadcopter frame (50cm wide, ~1200kv motors, 1kg). At least they are okay for flying. We lowered a bit the PIDs on ours because it was a bit too nervous but the first flight was still pretty good and the stability in the air was quite amazing, even with high winds!

A log from the the Ardupilot
A log from the the Ardupilot
You can assign any action you want on your radio extra switches and knobs. The most impressive one obviously being the "Auto" mode, where the quadcopter will follow a script of actions the user can write with the mission planer software. Just flick a switch, sit down and let the drone take off, fly to the waypoints you told him at the altitude you told him, and then land where you told him.

Casual flight around the Eiffel tower...
Flying has never been so easy! 😀 Also, it is really, really nice to have the return to launch (RTL) feature, which will bring back the drone where your armed the motors. It is a life saving feature, for those of us who put expensive cameras on their drones and don't want to crash them in case they lose the orientation or the video signal when doing FPV. It actually happened to us in one of our first flights. We were about to test the RTL feature when the drone was so far that we couldn't see its orientation anymore. We were already thinking about the "walk of shame" we would have to take with the broken pieces of our beloved quadcopter. But none of that happened. We flicked the RTL switch, and the drone came back home 😀 This feature really is a must-have! It's awesome and works great. We've only played with it last weekend, and even though it was a pretty windy weekend here, we managed to fly up to 80 meters with no problem whatsoever for the drone!

OMG, we see that the earth is round! No. It's the Gopro fisheye that does that. But everything seems pretty tiny at 80 meters of altitude.
"OMG, we see that the earth is round!" No. It's the Gopro fisheye that does that. But everything seems pretty tiny at 80 meters of altitude.
If there should be a conclusion to this article, it would be : buy the Ardupilot. It's great, works with everything, has a big developer community around it, and is actually not that expensive when you think about all the electronics it contains.
We just ordered the telemetry and OSD module so we can go all FPV on it 😉 We are definitely going to play our quadcopter in the weeks to come, and will try to add a nice video to this article (or to a new one) to show you what you can do which such a powerful tool 🙂

The quadcopter goes to an abandoned factory

The Simons abandoned factory

A new video made with our quadcopter! This time we went to an abandoned factory in Le Cateau, France and shot around 30 minutes of video in and around the factory. We will go back there in a few weeks and we will hopefully try FPV flight there ! 🙂


The T-REX 450 filmed by our quadcopter

We tried for the first time to fly together and that was pretty cool, until Benoit crashed the T-REX... Never forget the idle-up when looping with a collective pitch heli 🙂

For some copyright reasons, you might have to go on youtube to see the video....


We'll surely try again really soon with our soon coming FPV kit 😉

The quadcopter : how to compute the pitch, roll and yaw

 The stick IMU from sparkfun
The stick IMU from sparkfun: ADXL345 accelerometer, ITG3200 gyroscope, HMC5883L compass.

After having introduced here the basics of an aircraft orientation and how to control it, this article is about actually computing the orientation of the quadcopter in space with sensors and with the Arduino.

 Which sensors to use?

3 axis accelerometer + compass for yaw

To get easily the orientation of a non-moving object (pitch and roll), a 3-axis accelerometer (how does it work?) can be used. For a static object, it gives the value of the gravity field on 3 axes, therefore its direction. And since it always points to the center of the earth, we can therefore know how the accelerometer is inclined with the help of man's best friend, trigonometry.

This method has been used in a lot of smartphones and gives pretty accurate results, if you are not moving. Indeed, if you start translating the phone in space, you are creating a force on it, therefore you are changing its acceleration. The assumption we made previously to compute the  orientation is not valid anymore, so the calculated orientation won't be accurate.

Another problem of accelerometers is their sensitivity to vibrations.(it is actually not a "problem"  per say, it is just a consequence of the forces created by vibrations, which are essentially shocks). If you want a stable quadcopter, you absolutely need a smooth angle! I think it is by far the most important thing about a quadcopter. If you're stuck with your PID tuning and that all the settings you try are not efficient, it probably means that your angles are not smooth/ accurate enough.

As you can see, using only an accelerometer is not a valid option. You can of course try to filter the signal and reduce the amount of vibrations received by the sensor( using some foam or anything to free the accelerometer from the motors vibrations can really change a lot the output of the sensor) but it will never be precise/ fast enough to satisfy the needs of this application.


The most common used sensor in quadcopter control boards is the gyroscope sensor. It  gives the angular rate around the 3 axes of space in deg/s, so, as for the accelerometer, some simple maths are needed to compute the actual angle by integration. But using only a gyroscope raises problems:

  • The first problem raised is caused by the nature of the sensor. It just gives an angular rate, not an absolute measure. So if you start up the quadcopter on a crooked floor, the initials pitch/ roll angles shouldn't be 0, but they will be in your program since the gyroscope will just output null angular rates!
  • All the common MEMS gyroscopes used with Arduinos have a drift. It means that even if you stay steady and don't move, the sensor will output values different than zero. The drift can be pretty big for some sensors (it can go up 2 deg/s on the z axis of our L3G4200d !), therefore ruining the accuracy of the measurement when you integrate the values ! But it's not as bad as it could sound, most of the gyro drift can be subtracted from the measurement since it's a constant value (given a certain temperature).

So, both accelerometers and gyros are bad? The answer is no!

There is actually many different ways of getting the most accurate orientation from a combination of sensors and they all have their good and bad sides. The simplest  approach we've taken so far for our quadcopter, and which turns out doing pretty good, is a complementary filter.

The idea of the complementary filter is the following : the filtered accelerometer value of the angle  is not subject to drift, so we use it to "correct" the value given by the gyroscope(more precise and less subject to vibrations noises). How do we do that? We combine the two values like so:

 Angle_{accurate} = (GyroPercentage) * Angle_{Gyro} +(1-GyroPercentage)* Angle_{Accel}

GyroPercentage is just a floating value between 0 and 1. It is typically ranged from 0.9 to almost 1, depending on how much you can trust your gyroscope and accelerometer.

The angle given by this very simple method is actually pretty accurate and isn't too much time consuming for the Arduino. So if you don't want to go too deep into  the maths, I would suggest you to use this method, it is very satisfactory and easy to understand 😉

On the yaw axis, the same complementary filter is used  with a compass (which gives the direction of the earth's magnetic field), giving us the 3D orientation of the quadcopter like so:

 Yaw_{accurate} = (GyroPercentage) * Yaw_{Gyro} +(1-GyroPercentage)* Yaw_{Compass}

Last, but not least, filter your signals!!  It is fundamental to reduce the impact of the frame vibrations on the angle computation, if your computed angles are not accurate, your quadcopter will never fly. It is really the most important thing to do. And filtering the signals means both in software and in the conception of the frame. Use strong materials (such as carbon fiber), try to protect your IMU( Inertial Measurement Unit = Accelerometer + gyroscope + compass) from the vibrations. On the software side, if your sensors have a built in low pass filter (like on the ITG3200 and the L3G4200D ), activate them by writing in the good registers.  If you want to program  your own software low pass filter for you sensors, a simple method is to smooth the values given by the sensor like it is done in this pseudo  C code:

/* This code shows an easy way to smooth readings from a sensor subject to
 high frequency noise.
It uses a low pass filter on a circular buffer.
This circular buffer always contains the last BUFFER_SIZE-1 readings from
the sensor.
The new reading is then added to this buffer, from which wecompute the
mean value by simply dividing the sum of the readings in the buffer by the
number of readings in the buffer.

int indexBuffer;
float circularBuffer[BUFFER_SIZE];
float sensorDataCircularSum;
int BUFFER_SIZE; // Number of samples you want to filter on.
float filteredOutput;
float sensorRawData; // typically the value you read from your sensor
 //in your loop() function

void smoothSensorReadings(){
 // We remove the oldest value from the buffer
 sensorDataCircularSum= sensorDataCircularSum - circularBuffer[indexBuffer];
  // The new input from the sensor is placed in the buffer
// It is also added to the total sum of the last  BUFFER_SIZE readings
// This method avoids to sum all the elements every time this function is called.
// We increment the cursor

 if (indexBuffer>=BUFFER_SIZE) indexBuffer=0;// We test if we arrived to the end
//of the buffer, in which case we start again from index 0
 filteredOutput =(SensorDataCircularSum/BUFFER_SIZE); // The output is the the mean
//value of the circular buffer.

What is basically done here is just an average value of the BUFFER_SIZE last inputs from the sensor. This is a simple way to get rid of high frequency noise and can also be used to smooth PWM inputs from a RC control, for example 🙂

If you made it until here, I hope you are now able to implement by yourself your own implementation of orientation computing. It's actually a big area of research and much more complex solutions are still developed ( I invite you to look at Sebastian Madgwick  fusion filter algorithm 🙂 ).

The quadcopter : first video !

Our quadcopter

After having been through many, many hardware problems, the quadcopter is finally flying! We still have troubles with the ITG3200 on the stick IMU from Sparkfun which is causing some stability problems, but it's pretty cool to fly, and to watch ! 🙂

The hardware features :

  • A 50 centimeters wide full carbon frame that we built using Benoits CNC mill
  • 4 Turnigy Aerodrive SK3 2826 1130 kv motors
  • 4 Turnigy Plush ESCs 30 A
  • 4 9x4.7 or 8x4.5 propellers
  • A homemade flight controller shield mounted on an Arduino Uno
  • A 2200 mAh battery for regular flights, and a 5000 mAH battery when the GoPro is mounted
  • Possibility to fly in X or + configuration (we only use X now )

Here is the first video we release on Youtube, we will try to add more, especially from the GoPro 🙂


Pretty cool, isn't it? 🙂 We will post soon more articles about the details of the quadcopter, with more pictures and even more videos. Stay tuned 😉

The quadcopter : the flight controller shield

For our new quadcopter frame(article coming soon 😉 ), we decided to create a completely new Arduino shield, using new sensors and trying to avoid having lots of wires floating around.

We bought the 9 DOF stick sensor from sparkfun and the BMP085 barometer (used for altitude hold). When on the  old shield we had the 3 sensors (ADXL345, L3G4200D, HMC588L) on different boards and linked to the shield by  wires, we now have a single breakout board, directly soldered on the shield, which is a much better looking solution. It also avoids long steps of soldering, plugging mistakes etc... The EM406 breakout board is also directly soldered on the shield. We added two 7x2 connectors, in order to plug the RC receiver, SRF02 sonar sensor and possibly 2 servos in order to control a 2 axis gimball 🙂 The schematic looks like this:

The shield schematic

Another novelty of this shield is the connections with LEDs flexible strip. In addition to the aesthetic side, it will also be useful to distinguish the front from the back of the quadcopter, signal the end of calibration, blink during altitude hold mode etc.. These LEDs strip are not directly plugged to the Arduino, since they require 12V input and could be a bit too much power consuming to be fed from the Arduino. So they are controlled by a NPN BC517 transistor of which the base is connected to a digital output  like so:

How to control the LED strip with the Arduino

The last difference with our previous quadcopter is the change from a L3G4200D gyro in SPI mode to a ITG3200 in I²C mode. We did this partly to free all the SPI connections of the Arduino (10-13) because we needed available ports for the LEDs and for the future gimball, and because our L3G4200D was  pretty often giving completely false readings without any reason. We couldn't find the cause of this problem but we found a few people having the same problem  when we googled it... That pushed us to buy this stick sensor.

The final PCB looks like this:

The shield PCB

The holes and the contour were drilled with Benoit's CNC router and after soldering all the parts, the final results looks like this:

The Arduino shield with theEM406 breakout board, the 9 DOF stick IMU, and the BMP085 barometer

We have tried this shield with our old prototype frame and everything works fine, the flight is really stable.We use the LEDs to show the end of calibration and of course to show the front of the aircraft which is a big help when flying.

So as I said in the beginning of this article we are currently building a brand new frame entirely made of carbon fiber, with new motors, new ESCs and new propellers. We hope that we can finish the construction within the month to come (if we receive our order made at Hobbyking 2 weeks ago 🙂 ) and we will of course post pictures on the website! Stay tuned 😉

The quadcopter : control the orientation

We will use use these axes as reference

Quadcopter principle

The quadcopter orientation can be defined by three angles : Pitch, Roll, and Yaw. These angles determine orientation and therefore the direction the quadcopter will take. Basically, changing the pitch will make the quadcopter go forward/backward, the roll  bend to the left/right, and finally the yaw will make it rotate around its vertical axis.

So, to fully control a quadcopter- i.e make it go where you want over your neighbors' garden to spy on them- you just need to control these 3 angles. Do you? Almost ;). You need a 4th parameter, the throttle of the rotors. Obviously, if the propellers are not spinning, it would be hard to take off, wouldn't it? 😉 But let's forget about that and assume that the throttle is sufficient enough so the drone takes off.

Control individually pitch, roll and yaw angles

In order to change the pitch and roll angles , the main idea is to change each motors speed so the quadcopter starts bending in the desired direction. Let's formalize things a bit and define the motors "power"  in  C++ language style :

int motor1Power, motor3Power; // Motors on the X axis

//=>; changing their speeds will affect the pitch

int motor2Power, motor4Power; // Motors on the Y axis

//=>; changing their speeds will affect the roll

As I said in the previous paragraph, the motors power depends on the throttle you can give them with a remote control for example. A simple implementation of this in an Arduino-like sketch would look like this

void loop(){

motor1Power = throttle;

motor2Power = throttle;

motor3Power = throttle;

motor4Power = throttle;


What is done here is just simply redirecting the throttle input (coming from a remote control for example) to the motors, which will just concretely change the altitude/ vertical speed of the drone.

Now, let's think a bit about how to make the quadcopter move forward/ backward . This motion corresponds to the pitch angle. In order to change the pitch, we only need to change the speed of the two motors on the X axis. Indeed, affecting the speed of the motors 2 and 4 (on the Y axis) would just start a rotation around the X axis (therefore changing the roll angle).

But how to change the first and third motors speeds?

If you try adding the same value offset to the motors speed, it won't change anything because what you need in order to incline the aircraft is a difference in the motors speed. Imagine you attach two weights of one kg to the two opposite motors, what happens to the pitch? Nothing, you would need to attach different weights to incline the quadcopter. It's very intuitive and works exactly the same with the motors speed!

The best way to get different motors speed is to add the offset value one one motor output, and to subtract it on the other, so the "overall throttle " of the axis remains constant and therefore changing the pitch won't affect the quadcopter's "vertical speed"

 Throttle_{13} = \frac {(throttle + offset)+(throttle-offset)} 2 =throttle

By the same method, you can change the roll angle by changing motors speeds on the Y axis (in our example motors 2 and 4) and therefore control separately pitch and roll! Let's look at the updated pseudo-code introducing two new inputs pitchOffset and rollOffset

void loop(){

motor1Power = throttle + pitchOffset;

motor2Power = throttle + rollOffset;

motor3Power = throttle - pitchOffset;

motor4Power = throttle - rollOffset;


And that's it! This is how the pitch and roll are controlled.

 The yaw..

Why is the yaw different? Because it's not a matter of inclination here, so changing two motors speed won't make it. But i forgot  to tell you a little detail about quadcopters 😉 Two propellers turn clockwise, the two others turn counterclockwise. And how does it help you? The answer is the torque . When an object rotates around an axis, it creates a torque, creating a rotation movement of the body holding the propeller, and that's why traditional helicopters have an anti torque rotor on their tail, keeping the rotorcraft from spinning until the pilot pukes (it is more likely he dies in an awful crash). With opposite rotations, the quadcopter doesn't need and anti-torque tail, one axis compensating the torque of the other.

Changing the torque and therefore the yaw seems now really simple,doesn't it? Just add a yawOffset to the speed of two motors on the same axis, while you subtract it from the speeds on the other axis (so the overall throttle doesn't change). The final code looks like this:

void loop(){

motor1Power = throttle + pitchOffset + yawOffset;

motor2Power = throttle + rollOffset  - yawOffsett;

motor3Power = throttle - pitchOffset + yawOffsett;

motor4Power = throttle - rollOffset  - yawOffsett;



And that's it for the basics of how to control a quadcopter, hope it was clear and detailed enough. If you want to take it to the next level and auto stabilize your quadcopter, it's right here 😉