Introduction: Brushless Gimbal With Arduino

Picture of Brushless Gimbal With Arduino

This is a Spring 2014 Electronics project at Pomona College created by Andreas Biekert and Jonah Grubb. Thanks to Professor Dwight Whitaker, Tony Grigsby and the Pomona Physics Department.

Our goal with this project was to create a 2 axis brushless gimbal controlled solely by an Arduino Uno with input from an accelerometer/gyro. A gimbal is a camera stabilization system that uses motors to correct unwanted camera motion. The goal is to create perfectly steady footage, although smoothing out any bumps is a reasonable first benchmark. "Brushless" refers to brushless motors which we will explain more about later. All the other gimbal projects we found are controlled using fabricated gimbal control boards so we wanted to approach the project from a more fundamental level. Our hope was to create brushless gimbal control without this kind of board, but rather using the more general purpose Arduino Uno.

We're going to have to be upfront; we never got the gimbal we were looking for. However, we did learn a lot about how the device should work, so we have written our thoughts on improvements and directions to pursue with the project. We hope this is at least a good resource for a starting point. Let us know if you have any questions or suggestions for improvement.

Between learning how to control the brushless motors and interfacing with the accelerometer we consulted quite a few sources for this project. We will be referencing material and using photos from this project, which served as our foundation for brushless motor control. Our code is heavily based on both the aforementioned motor control project and this I2C library with sample code for an MPU6050 chip. A big thanks to both of these projects for giving us direction in our efforts!

There are several ways to go about getting the parts for this kind of project. Naturally, one of the principle components is the Arduino Uno.

We bought a frame and brushless motor set on Amazon: Frame and Brushless Motors. It's probably possible to machine or print your own frame, but we were more interested in the electronics portion of this project, so we went with the quicker route of simply buying the frame ready-made.

We also bought our accelerometer off Amazon: Accelerometer/gyro. The GY-521 breakout board is significantly cheaper than any other MPU6050 models we found, but it worked just fine for our project. However, we did manage to break one and had to order another one. We still aren't sure if its failure was our fault.

We used two Mauser 511-L298 h-bridges (with heat sinks) to control the motors---more on that later. These are able to handle the higher voltages and currents needed to drive the motors so they can move the frame and camera.

Some other small components we used were two 2.2k resistors, three 0.1 microFarad capacitors, and a lot of wiring :)

Step 1: Brushless Motor Control (Part 1 - Concepts and Theory)

Picture of Brushless Motor Control (Part 1 - Concepts and Theory)

Brushless DC motors are ideal for this project because they are efficient, precise, and have plenty of torque; the trick is actually controlling them. The most common hobby route is to buy programmable electronic speed controllers which can take throttle inputs and convert that to rotational speed in the brushless motors. However, these can cost $20 for the cheapest ones, so we decided to save costs and figure out how to control the motors without them.

Unlike brushed DC motors, which work by simply reversing the current in loops of wire in a permanent magnetic field via a commutator, brushless motors have no physical connection between the wire coils on the stator and the rotor. The most common brushless motors are known as three phase brushless motors. This means that they have three distinct sets of coils, often labelled A, B, and C. Surrounding these are permanent magnets with alternating orientations.

Our motors have twelve coils or electromagnets (3 sets of 4) and fourteen permanent magnets on the rotor. The idea is that we change the polarity of our electromagnets in a cycle and the permanent magnets follow the changing magnetic field. In the simplest form, we have three electromagnets (A, B, and C) and the rotor is just a single NS permanent magnet. If we have coil A creating a north magnetic field and coil B creating a south field and coil C off, the magnet will turn to align itself as closely as it can to the generated magnetic field. We can then rotate the polarities of our electromagnets by one position (A off, B North, and C South) and the magnet will follow. In this manner, we have a set of commutation phases that when we run them in order cause the rotor to turn, and we can reverse this cycle to run it in the opposite direction.

Watch these two videos for a clean and clear explanation with diagrams.

We did some research and found that sending Sine waves that are 120 degrees out of phase through the three sets of electromagnets, we can create a dynamic magnetic field that drives motor rotation. Introducing a sinusoidal signal smooths out the motion of the motor considerably by changing the polarity of the electromagnets gradually. This site was very useful in taking that theory and turning it into Arduino software. The trick to this approach is running our PWM signal from our Arduino through an H Bridge to allow negative polarity of one of the coils since PWM signals only output High (1) and Low (0).

One of the biggest challenges of brushless motors is that to properly control them you need information of where the rotor is in reference to the stator coils. That way the controller knows exactly where in the commutation cycle to begin or to jump to. We were hoping that the accelerometer may be able to give this feedback, which seemed to work with moderate success. More sophisticated methods include attaching hall effect sensors to detect the position of the rotor or even using the "back emf" induced in the coils.

Step 2: Implementing Brushless Motor Control

Picture of Implementing Brushless Motor Control

Introducing the h-bridge to control the motors allows us the bi-directional motion that the gimbal requires, and also allows for very smooth stepping of the motor's position. The H bridge essentially flips the sign on one of the electromagnets so that we can have a high, a middle and a low voltage. As mentioned in the introduction, we used L298 h-bridges, which have 15 pins. We wired each of them as seen in the image above. Here is the data sheet.

  • Pin 1: Ground
  • Pin 2: Motor Pin 1
  • Pin 3: Motor Pin 2
  • Pin 4: External Supply Voltage (put a 0.1 microFarad capacitor to ground)
  • Pin 5: Arduino PWM Digital Output (pin 3 or 9)
  • Pin 6: +5V from Arduino (put a 0.1 microFarad capacitor to ground)

  • Pin 7: Arduino PWM Digital Output (pin 5 or 10)
  • Pin 8: GND
  • Pin 9: +5V from Arduino
  • Pin 10: Arduino PWM Digital Output (pin 6 or 11)
  • Pin 11: +5V from Arduino
  • Pin 12: Not Connected
  • Pin 13: Motor Pin 3
  • Pin 14: Not Connected
  • Pin 15: GND

Our source describes a clever scheme of approximating a sinusoidal signal to the motors. They construct an array of 48 values between 0 and 255 which represent the values of the sine function at equal increments. They begin each electromagnet state A, B, and C 16 values apart from one another, which divides the period of the function into thirds or, in other words, phase shifts the states by 120 degrees. Then, they simply increment each state's value in the array so that the states cycle through the sine wave with each loop of the program. The result is very smooth rotation in the motor, although it is somewhat speed limited by the physical ability of the motor to keep up with the Arduino signals.

We use the same PWM sine-array scheme as our source, which allows to increment though a numerical approximation of the sine function over a given number of steps in the period. In our case, we doubled the number of values in the array from 48 to 96 so that we could more precisely control the motor. This is because our gimbal application does not need the motor to make full rotations, well, ever; we only need to adjust the camera's position against the motion of the base. Quick observations suggest our scheme allows the motor to step in 0.2 degree steps at a time.

It's important to note that this is mostly a makeshift way of controlling brushless motors. At any given moment, we want one electromagnet high current, one low, and one in a high-impedence state, which approximates to neither high or low. In our case, the "high-impedence" state actually lets current run off to ground, which generates a significant amount of heat in the motor. A definite place for improvement is to keep the motors from getting hot in the case of long-term (e.g. over a minute or two) operation.

Another hazard with our implementation is in the case that the motor physically misses or overshoots one of the steps, which can happen given the significant weight of the frame and camera relative to the motor's torque. In this case, our program is unaware that the motor isn't in sync with the signals, and cycles through the sine wave once before "catching" the motor and resuming normally.

Step 3: Using the Accelerometer and Gyro

Picture of Using the Accelerometer and Gyro

The accelerometer allows the Arduino to understand the position of our camera at any given time in reference to gravity and detects axial accelerations. The gyro detects changes in angle. With this data we created a servo (a feedback loop that approaches a given set point) to keep the gimbal at a fixed position. We used the MPU 6050 6-DOF (Degree of Freedom) Accelerometer and Gyro mounted on the GY 521 breakout board.

We wired the accelerometer to the Arduino as seen in the picture above. Unfortunately there is no data sheet for this breakout board. This is what we found in the comments on Amazon:

  • VCC: +3.3V From Arduino (attach 0.1 microFarad capacitor to ground)
  • GND: GND
  • SCL: A5 on Arduino Uno (With 2.2k pull up resistor to Arduino +5V)
  • SDA: A4 on Arduino Uno (With 2.2k pull up resistor to Arduino +5V)
  • XDA: Not connected
  • XCL: Not connected
  • ADO: GND
  • INT: Digital Pin 2 on Arduino

We searched around and found some Arduino sketches that give you the raw data. However, this is pretty noisy and not particularly useful, especially in servo-ing. The MPU 6050 has a built in Digital Motion Processor (DMP); however, instructions on using it are not provided. Some brilliant person at MIT (thanks Jeff Rowberg!) reverse engineered the chip and figured out how to activate the DMP and get the clean and steady data from that. We used his code which allowed us to receive the data in several different forms including Euler Angles, Quaternions or Yaw Pitch and Roll (YPR).

We decided to use the YPR data since it directly correlated to how we are controlling our camera. We have a pitch motor (think looking up and down) and a roll motor (think a banking airplane). Once we had the data in this form the coding was relatively easy and we wrote a basic servo code to turn the motor to whichever angle we set in the code, by "incrementing" the sine wave in the appropriate direction. Conveniently, our two motors match up exactly to two of these coordinates, so we can servo the two motors separately without them interfering with each other. This was a relatively simple concept core to our project.

The YPR data is a bit tricky since it only gives angles between -90 and 90 degrees so the servo occasionally get confused if it becomes near horizontal, theoretically not a problem in a gimbal application (although still a place to improve we think).

Step 4: Putting It Together

Picture of Putting It Together

For our final product, we simply mashed the two concepts of motor control and accelerometer readings together to form a servo. You can view the resulting code here.

Of course, the solution is not so simple. We encountered a lot of problems at the combining stage, most of which went unresolved. Our setup initially consisted of just one of the two axes; we struggled a long time to get the motor to even turn on in the presence of the accelerometer, even though we had a relatively straightforward time getting the two to work separately. We found the solution to be two 2.2k pull-up resistors between the I2C ports A4/A5 on the Arduino and +5V. Strangely, all other resistor values, other than 3.3k, did not allow for power to reach the motor. Pull-up resistors tend to be inserted into analog read ports to stabilize the signal and prevent the Arduino from freezing, but they are generally a safety precaution rather than a strict necessity. As such, it shouldn't matter what the value of the pull-up resistor is (within reason), contrary to what we found. Our conclusion: clearly the pull-up resistors are compensating for something, but we still aren't sure exactly for what.

For whatever reason every time we added external power that was over about 7 or 8 volts on 1 axis (although we "resolved" 1 axis eventually) and 3 to 4 volts with both axes (0.30 amps seemed to be the limit) to the H Bridges the accelerometer data went out-of-wack and was useless. This in turned caused the motors to freeze up since the Arduino eventually crashes.

Poking around with a oscilloscope we discovered a few things. Basically when we attach the external power supply the circuit draws about 0.8 amps and there is noise introduced just about everywhere--and a lot of it. "Ground" was fluctuating between -2 and +3 volts!!!! It makes sense that the accelerometer has no idea what to do with that. This seems to be the root of all our problems and had we solved this we may have had a working product.

When using brushless motors, you are creating a changing magnetic field through coils of wire. This induces a emf in the coils according to Faraday's Law. We think this "back emf" may be the cause of the noise we're seeing.

A second guess is simply our messy setup. We used pretty long wires running too and from the H Bridges and to a and from the accelerometer. Long wires and high voltages are excellent at picking up electromagnetic signals and introducing noise into the circuit.

By the end it seemed that with the 2.2k pull up resistors, we solved the problem for one axis. We had a nice servo going with just pitch that ran indefinitely and could even handle 15V, giving it a lot of torque. Note here we were trying to servo to an off zero angle to test the servo action and make sure it wasn't just gravity doing all the work. Normal gimbal functions take advantage of gravity to aid in stabilization, so the centering of mass is crucial.

The motor control was still a bit jumpy and always ran at a constant speed. We think we could solve this by doing two things, firstly create a Sine Wave array with much greater resolution. Then by implementing a PID Library we can change how quickly the motor reacts based on how far from the set point it is. When its really far off it will move through the sine wave quickly resulting it fast motion and as it approaches the set point it will slow down and stabilize. This in theory would remove the jerking we experience when the motor reached the set point and create faster, smoother gimbal action.

Here is our final 2 axis action. It had low voltage and low current so didn't have all the torque we needed. Once again it was set to be a bit tilted.

Here is test footage from the GoPro -- not exactly that perfect steady footage we were hoping for. The horrible noise comes from the brushless motors. We are not sure if they are normally this loud, but who needs audio anyway.


chubby8 (author)2016-03-06

What is the advantage of a brushless motor over a servo or a stepper motor? Other than effiency? possibly the reaction time?

HenningP2 (author)chubby82017-11-17

Fluid motion. The servo will have some deadband and the stepper will have jumpy motion. But they would be easier to control.

instructable123456789 (author)2017-07-15

its really shaky so take that in mind

tmercados (author)2016-12-08

Is there a way to use the L293d instead of the l293n?


gimbal1123 (author)2016-09-19

Can someone help me?

When verifying the code given above, an error pop up and said the 'move' is not declared in this scope. Did I miss some libraries. I have installed the I2cdev,mpu6050 as well as the PID libraries.

RadovanL (author)2016-01-03

Hello, this might be a dull question but I'll try anyway - the ear-tearing noise is I assume, casued by the motors Can anyone tell me how loud it is? I would like to buil a DSLR Gimball with probably larger motors and I am concerned about the noise interfering with my audio. Shooting on a external mic with recorder but I still need some kind of a reference to the level of this highfrq. noise.

Thank you

KCWCK55 (author)RadovanL2016-01-13

If using an actual gimbal control board (like alexmoss, I reccomend this board for large dslr's because it is pretty professional and easy to use), you can actually set how loud the high pitch whine is. At the lowest volume level, it is completely unnoticeable, regular volume is pretty annoying but if using an external mic that is like 4 feet away from it, it'll be ok .

ArduinoDeXXX (author)2015-05-20

I published a new instructable of a DIY 3axis brushless gimbal with Arduino. There the sketch for single axis brushless gimbal is attached. I could get a good starting point for your article. Thank you.

Yummychop (author)ArduinoDeXXX2015-05-23

I met some problems when I tried to drive a 3 phase BLDC motor with a DRV8313, I followed the scheme,but the motor didn't rotate

ArduinoDeXXX (author)Yummychop2015-05-23

I would like to know the detail. Could you possibly post the comment again with more detail to my instructables?

ArduinoDeXXX (author)2015-01-05

Hi, thank you for your article and telling referred site. I have a similar project to yours. You gave me just "a good resource for a starting point".

I tried the two sketches in the referred site, discrete and sinusoidal, and got a conclusion that they are not good for our projects. These sketch would be applied to projects that need rather high speed (RPM) and "the load is so light".

Therefore I prepared a new sketch originally. It works well at least for the next point to yours.

Video(1) A BLDC works as Servo.

Video(2) A test bench as a single axis BL gimbal

I improved my original sketch to remove small shake at stop. Video(3) below shows the points of it. And Video(4) contains two shots on more improved gimbal. I would like to tell detail in a new Instructable in near future.

Video(3) Improving my original sketch to control single axis BL gimbal

Video(4) Comparing between two films taken on more improved gimbal

Awesome work!!!! i'm looking for some information to do my own 2 axis gimbal, can you post the code of the 4th video??

Thank you so much! :D

Hi, I published a new instructable. There the Arduino sketch for 1axis brushless gimbal is attached. Thank you for waiting.

Hi, I will show detail in a new Instractables once with a prospect. Please wait. I am assembling a DIY frame of 2 axis gimbal now. Though I like simple project it is not so, much less with electrical components.

My first trial DIY 2-axis camera gimbal was assembled and moved.

Here SPI interface between sensors and Arduino is disturbed. Using multi-core cable such as servo cable makes it worse. So un-bundled wires are used.Though they reduce the problem some defect remains. I cannot find related article in web sites. I am glad to know the reason or good solution.

Intentional tilting is arrowed anew. Though the disturbance of SPI interface has remained, the first shooting test was done. It seems working well as a trial piece with no fine adjustment. Two subjects are left before such adjustment. Electrical elements on breadboard should be transplanted to a special Shield for Arduino. And the 3rd axis would be added.

Thank you so so much, i'm waiting for your code and do something profitable with the 3d printer!!

d.martinfree (author)2015-01-30

Hi I would like to remake this but I am very un-experienced with arduino code. Can you lead me to the code used on this project?

Build_it_Bob (author)2014-12-06

Very nice work. Code is over my skill level , but very well written and documented.

I hope to play around more with this ; thank you for more insight into how to use the neat device!


chrwei (author)2014-05-13

the notes for the GY-521 on recomend to use 5V to VCC, not 3.3V. I suspect what was happening is that adding the motor controller made just enough of a drop so that 3.3V would no longer work, and adding additional resistors stabilised it. you may not need the extra resistors if you power the breakout on 5V

AndreasBiek (author)chrwei2014-05-13

Good catch! Would love to try this out, but currently we are moving out for the semester so the setup is packed up. We are still looking to work on this in the future, so thanks a lot for your input!

Iceberg86300 (author)2014-05-13

Hopefully I can help out a bit. Think you got ripped on those motors. They seem pretty small, but I'd need to know the Kv and torque constant. I can tell you that a motor used on a 700 size heli is usually around 450-500 Kv, runs on 12 cell Lipo battery, very high torque, and costs about 4 times what you paid for the entire gimbal assembly. The motors you have are high mag pole count, so better for positioning purposes, but they generally require high timing values during accell and deccell. Some want 15-20 degrees.

I don't know what your PWM frequency is, most RC speed controls run from 8-16kHz. This can and does wreck havoc on electronics. When run off a battery it creates a nasty ripple where the power hits your electronics, and the longer the wires from the power source to the electronics shots up the inductance and makes the ripple worse. This can and does kill electronics. Fairly large caps are usually placed at the electronics to help smooth this out.

Don't know if this would make a difference or not because I haven't looked at the h bridge data, but the phases are usually switched with 6 power FETS with built in diodes acting as a flyback circuit when the FET is switched off.

Now, because you have no position feedback from the motors, ideally you should run them through a reduction drive. Some hall sensors could then give a lot of resolution with a real reduction in the chance of losing the motor position.

There it's also an awesome chip out that is a magnetic encoder. It has a few hall sensors in the package, and uses a circular magnet on our in a shaft over the chip.

Something like this is really required, you have the motor position servo loop inside your camera position to vehicle servo loop. Just like what you were proposing.

Now we aren't talking motors that have an encoder with a Z pulse, so upon startup you have no way of knowing where the motor is electrically. When working at Haas I was adapting a third party motion controller to our servo amps. Our amps used sinusoidal commutation, with 2 inputs for 2 phases from our in house controllers, the third phase was then calculated inside the amp.

Now, the in-house scheme was to drive the motor very slowly and when the Z pulse hit the electronics would sync up with the motor position then continue driving to limit switches to pick up machine zero. These were fairly large servo motors comparatively, and were being reduced through a ballscrew or rack and pinion.

I got a cheap third party 4 axis controller. However, because the amps needed 2 analogue ±5 volt signals to command the sinusoidal I had to combine 2 axis into one. Upon startup a zero command had to be given, driving the phases hard so the controller could sync. Not exactly the greatest method because driving the phases so hard to ensure a sync the machinery would jump quite significantly.

Personally, for this purpose I wouldn't worry about true sinusoidal commutation. You're wasting quite a bit of processing power that would be served better grabbing quad encoder signals and using 9 or 18 voltage steps per 180° of commutation, and using something to reduce the motors.

These little guys aren't really made for holding a specific position, so they will get hot if you're feeding too much current. A reduction drive will give you more torque at lower currents and better position resolution.

I know this was kinda a lot of info and ask over the place, but hopefully it will help you out. Any questions let me know.

Also, goto freescale website and search app notes for DC motor control. There are a few good apps that use cheap hcs12 16 bit MCU. I'm sure the methods can transfer over to the arduino.

However, if you are going to go for true sinusoidal commutation (really is the smoothest and most efficient method, but I was a Mechatronics Engineer at SLO, so the servo amps were like black boxes to me, Haas supports engineering pretty well, so you may be able to get some theory out of them, our possibly even a servo amp or 2, but they will be 45 amp units at least, a little big for RC gimbals lol. Can give you a name or 2 of people that could make that decision, but because of the units you'd probably have to come up with a lab exercise for servo motor control, wouldn't surprise me if you got amps and motors out of them if your proposal is good enough. Like I said, the smallest amps and motors dwarf what you're working with and would be mainly for learning about and developing a servo control, not actually developing signals sent to the motor a as the amp does this. But you would need to read the encoder and come up with something to feed the amps.)

Back to your project, Haas uses or used several coldfire processors for motion control, HMI, etc. So you may end up using several arduino MCU to get the job done. 1 to close and control each motor position servo loop (in commercial motion control this seems popular, you have an amp/servo that is fed by a master controller, much like stepper amps/motors fed by a parallel ports pulses.) Then another for the sensors and motor position commands to close the camera orientation servo loop.

Again, let me know if you have questions, delt with CNC in industry, and quite a bit of experience in the RC world.

sorry for typos / grammar, tablet doesn't like me.

AndreasBiek (author)Iceberg863002014-05-13

Hey, thanks for your detailed reply! First, a confession; a lot of your details went a little over my head (I'm a physicist, not an electrical engineer ;) ), but I can definitely get a sense of what you are talking about. Part of the goal of this project was to work as cheaply as possible and to get things working one step at a time; no doubt we would love to add things like hall-effect sensors and multiple Arduinos down the line, but we simple avoided solving problems that required spending more money for economical reasons.

Having said that, we definitely got a sense that our motor control was a little off, so that's one of the areas I'm most interested in developing. I was quite interested in your comments the HiZ commutation mechanism and how exactly that works. The motors we used were only 90kV... not too powerful. However we definitely felt we could get enough torque out of them, except for the freezing of the Arduino. Another user mentioned we were using the wrong VCC for our accelerometer breakout, which is definitely another simply fix we could test.

Unfortunately we disassembled the setup since we are in the process of packing up and moving out for the semester. However, we are definitely interested in continuing with project in some vein, so we'll get back to you if we have any more questions!

monobits (author)2014-05-10

The resulting video is awful... :( Any chance to see a working prototype that's better than that?

Jonah Grubb (author)monobits2014-05-12

If you read through the whole thing, you'll see thats the best we got it to work so far. We had lots of problems with electrical noise making it impossible to get a perfect servo. Something we are looking to improve in the future. But thats what it is so far.

AndreasBiek (author)Jonah Grubb2014-05-13

As an add-on to that, perhaps a little careless of us but the sample video is set to servo to a specific angle (like 5/20 pitch/roll or something) as a way of making sure that the motors weren't just going limp. For a better video we probably should have gone 0/0, but unfortunately the setup is currently disassembled, although we may return to it down the line.

家廖 (author)2014-05-13

I am dizzy, Gimbal compensation effect does not seem to.

marhar (author)2014-05-13

This is a great instructable. The things I really appreciate are:

- there's some good material on the theory, etc.

- you document the process you're going through -- also very educational!

It's great that you put this out as a Work in Progress, rather than waiting until it was tidy and wrapped up. I hope more Uni projects get documented like this!

bygreencn (author)2014-05-13

doing one.

bob3030 (author)2014-05-11

Cool. Thanks for sharing.

gravityisweak (author)2014-05-09

Excellent. Most of the theory behind this is beyond me, but I like the ible nonetheless, hopefully someone will run with your idea and we will have cheap, open source gimbals out there!

Jan_Henrik (author)2014-05-08

very cool!"

AwesomeAwesomeness (author)2014-05-08


About This Instructable




More by Jonah Grubb:Brushless Gimbal with Arduino
Add instructable to: