Pages: [1] 2 3 ... 20   Go Down
Author Topic: BlueCopter - Arduino Quadcopter  (Read 91990 times)
0 Members and 4 Guests are viewing this topic.
Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey,

I spent the summer working with a new hobby of mine, Quadcopters =D! The quadcopter board is homemade (atmega32u4). Because my board has the same pinout as a leonardo, I decided to go with the multiwii firmware. So I etched a shield for my board containing headers for the receiver, motors and the IMU (cheap chinese found on ebay, ADXL345, L3G4200D, HMC5883 and BMP085).

I was happy with the quadcopter, it flew very nicely (after some PID changes of course).. But in the end I'm the type that likes to write my own code.. Trying to look at multiwii's code to see how they made it work (just to get a hunch), I directly noticed that the code isn't very, hmm how do I put it, reader friendly... So I trashed Multiwii, and there my summer began learning the dynamics and physics of quadcopters.

Three days later, I got a working code.. Three weeks after that I finally managed to find the optimal PID values for my quadcopter =P (yes it took three weeks of tweaking)..

Anyhow I'm not going to bore you out with my story. Instead I'm going to share my code with the arduino community and a video of the quadcopters first flight with my code..

If there is a big demand for a code explanation/theory about quadcopters and how everything works, shout out here, and I'll come up with something for you...

Here is the code: https://github.com/baselsw/BlueCopter

See attachment for pinout..

And here is the video:


Edit: I've updated the code.. Made the sketch run more efficiently and reduced code size.. With this change I managed to find better PID values and thus get better/faster stabilization.. For those interested I've added pictures of the main board and hardware setup..

//Basel


* Connecting_ProMicro.jpg (168.53 KB, 900x1217 - viewed 8392 times.)

* IMAG0529.jpg (431.42 KB, 1632x920 - viewed 5289 times.)

* IMAG0485.jpg (200.63 KB, 1143x644 - viewed 4327 times.)

* IMAG0527.jpg (691.2 KB, 1632x920 - viewed 5711 times.)
« Last Edit: September 15, 2013, 05:33:40 am by baselsw » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18811
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Very nice, but I think I'll move it to Exhibition / Gallery.

Thanks for sharing the video and the code.
Logged


Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very nice, but I think I'll move it to Exhibition / Gallery.

Thanks for sharing the video and the code.
Hey, thanks Nick =)..  Couldn't figure out where to start the topic..  Good thing you moved it..

//Basel
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1920
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Tweeking takes time. Very good job I would say. Though the drawings are not clear to me at all.
Thats probably cause by my lack of knowledge
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tweeking takes time. Very good job I would say. Though the drawings are not clear to me at all.
Thats probably cause by my lack of knowledge
Jantje

Thx =).. By drawing I assume you mean the pinout? Well, it's simple.. I used the X-configuration (meaning the quad is flying in a X shape).. If you look at the pinout the motor pins should be,

Left upper motor: Pin 6
Left bottom motor: Pin 5
Right upper motor: Pin 10
Right bottom motor: Pin 9

For RX (receiver), PPM signal (Pulse-position modulation), The pins are as follows:
Roll: Pin 16
Pitch: Pin 14
Yaw: Pin 15
Throttle: Pin 7
AUX1: Pin 8
AUX2: Pin 0

I've also got a LED on pin 13, that indicates if the quad is in rate or level/angle mode..

And of course SDA/SCL for the sensors...

Currently the code only uses the accelerometer and gyrometer to make the quad stable during rate- and angle mode..

In the future I may implement heading hold (magnetometer) and altitude hold (barometer).. Not sure yet, cause I didn't have any need for them...
Logged

Offline Offline
Newbie
*
Karma: 2
Posts: 39
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome project! How much did it cost to build it?
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome project! How much did it cost to build it?

Thanks bro =)..! Well, for the quadcopter parts without the main board (home made btw), around 150 USD. I bought all the parts (frame, ESC, motors, propellers...etc) from hobbyking.

//Basel
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 217
Posts: 13742
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well done,

many questions pop up
- how high can it fly?
- how long can it stay in the air?
- what does it do when it looses contact with remote?
- ...
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well done,

many questions pop up
- how high can it fly?
- how long can it stay in the air?
- what does it do when it looses contact with remote?
- ...

-- Pretty high.. I didn't measure the distance yet.. But it's so high that it starts to look like a small fly in the sky (cant see the orientation of the quad, nothing)..
-- I'm using a double 2200mAh (3 cells, LiPo, coupled in parallell).. It gave me approx. 15min of flight..
-- Well I lost contact with it when I pushed the throttle to the max! (meaning it flew very high).. Nothing special happens.. It will stay leveled in the air until battery begins to run out, and it will descend (depending on the ESC ur using, it can descend slowly(ESC cutting power slowly) or it will suddenly stop (ESC cuts the power alltogether)).

And here's my parts list (all from hobbyking.com):

Item/PartPcs
20CM Male to Male Servo Lead (JR) 26AWG (10pcs/set)
1
Hobby King 2.4Ghz 6Ch Tx & Rx V2 (Mode 2)
1
Turnigy 2200mAh 3S 25C Lipo Pack
2
NTM Prop Drive 28 Series Accessory Pack
4
Hobby King Quadcopter Power Distribution Board
1
NTM Prop Drive 28-26 1350KV / 310W
4
HobbyKing 30A BlueSeries Brushless Speed Controller
4
Hobbyking X666 Glass Fiber Quadcopter Frame 666mm
1
8045 SF Props 2pc Standard Rotation/2 pc RH Rotation (Blue)
1

And consider buying spares of ex. propellers and such (if you're a beginner you'll need it)..

//Basel
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18811
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you need an additional device to "bind" or "register" the receiver to the transmitter, or does the one you listed do that?
Logged


Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you need an additional device to "bind" or "register" the receiver to the transmitter, or does the one you listed do that?

The packages comes with a transmitter and receiver..

No, you get a 'special' wire that shorts the signal line on the PWR-input to ground (on the receiver).. This will put it in binding mode (Led will start to blink once per second)... In the transmitter all you have to do is hold the bind button and turn it on.. One second later the connection is accomplished, and the led on the receiver will stop blinking =D!

//Basel
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i have made quadcopter with arduino uno and gy_80 sensor i have ppm 4channel radio controller and it is not sum every single channel is ppm . i tried to use your program for this but receiver dont work when i want it to fly .....
" when i connect my ppm receiver to single motor with esc radio control work perfectly but when i use it as quadcopter with code does not work
.........
help me plz . help smiley-sad
faramarz.zareian@gmail.com
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i have made quadcopter with arduino uno and gy_80 sensor i have ppm 4channel radio controller and it is not sum every single channel is ppm . i tried to use your program for this but receiver dont work when i want it to fly .....
" when i connect my ppm receiver to single motor with esc radio control work perfectly but when i use it as quadcopter with code does not work
.........
help me plz . help smiley-sad
faramarz.zareian@gmail.com

Well, it won't work, I'd be surprised if it did.. This sketch is written for the arduino leonardo (atmega32u4), meaning it won't work on the UNO directly, specially the receiver part. The receiver is using the PCINT (pin change interrupts), and because there is no built-in library for arduino I had to address the registers directly, the atmega32u4 registers (which is not the same for the UNO atmega328p)..

For a beginner I recommend the use of MultiWii's code (http://www.multiwii.com/software), my code is "kind of" for people that wants to write their own code and needs some starting ground..

Edit: Another thing I would like to add.. If you decide to modify my code to work with your quadcopter, you'd have to make sure that your ESC supports PWM at a frequency of ~480-500Hz... Most ESC are made to only support PPM.. PPM isn't the same as PWM, the signal looks different and in most ESC is made to run on a frequency of 50Hz...

Here is a whole discussion about the difference: http://forum.arduino.cc/index.php/topic,14146.0.html

And if you decide to replace the 480Hz PWM with 50Hz PPM, you'll have a lot of trouble getting the quadcopter to be stable... With a little luck, you'll maybe be able to fly it in rate mode.. Angle/Level mode needs a faster update rate...
« Last Edit: September 05, 2013, 02:37:13 pm by baselsw » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 23
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Tweeking takes time. Very good job I would say. Though the drawings are not clear to me at all.
Thats probably cause by my lack of knowledge
Jantje

Thx =).. By drawing I assume you mean the pinout? Well, it's simple.. I used the X-configuration (meaning the quad is flying in a X shape).. If you look at the pinout the motor pins should be,

Left upper motor: Pin 6
Left bottom motor: Pin 5
Right upper motor: Pin 10
Right bottom motor: Pin 9

For RX (receiver), PPM signal (Pulse-position modulation), The pins are as follows:
Roll: Pin 16
Pitch: Pin 14
Yaw: Pin 15
Throttle: Pin 7
AUX1: Pin 8
AUX2: Pin 0

I've also got a LED on pin 13, that indicates if the quad is in rate or level/angle mode..

And of course SDA/SCL for the sensors...

Currently the code only uses the accelerometer and gyrometer to make the quad stable during rate- and angle mode..

In the future I may implement heading hold (magnetometer) and altitude hold (barometer).. Not sure yet, cause I didn't have any need for them...

For RX (receiver), PPM signal (Pulse-position modulation), The pins are as follows:
you mean ppm receiver work with your code ?
Logged

Sweden
Offline Offline
Sr. Member
****
Karma: 13
Posts: 257
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For RX (receiver), PPM signal (Pulse-position modulation), The pins are as follows:
you mean ppm receiver work with your code ?

Yes, the receiver sends ordinary servo pulses/PPM to the arduino (one signal per axis/control-rod, a total of 6 pins/signals). And because the signals are ordinary servo signals (50Hz update rate), I used interrupts in order to read these when they change and thus avoid getting my loop rate (~800Hz) draged down by these signals..

Here is a example of how these signals looks like:



Edit: I just read your other post about needing a code that reads PPM. I'll try to explain how I did it code-wise:

Let me begin by stating the problem ahead.. If we take the throttle-rod as an example, when the throttle-rod is in the (0% position) the receiver will send a signal that's ~21ms long (a high pulse for 1ms and a low pulse for 20ms).. And when its in the (100% position) the receiver will send a signal that's ~22ms long (a high pulse for 2ms and a low pulse for 20ms).. As you noticed the 20ms part is just a "synchronization part" and doesn't provide anything useful in our case..

What we need is to measure how long the "high pulses" are. And to do that we need to know when a pulse starts and when it ends. The simplest way of doing this is using External interrupts (very few pins on arduino!!)..

Here is a example code:

Code:
#define RX_INT_PIN_THROTTLE 0
volatile int rxPrev = 0; //variable that will contain the previous time
volatile int rxVal = 0; //variable that will contain the current throttle pulse length

void rxGoesHigh(){
/* As soon as we get into this function we measure the current time (with micros)
and put that value in our variable rxPrev. After that we re-attach the same interrupt
but this time we want it to fire when the pin goes low "FALLING". When that happens it
will call the function rxGoesLow */
  rxPrev=micros();
  attachInterrupt(RX_INT_PIN_THROTTLE,rxGoesLow,FALLING);
}
void rxGoesLow(){
/* As soon as we get into this function we measure the current time (with micros) and
subtract the previous time (rxPrev). By doing that we will get the length of the pulse,
from start to the end. We end this process by re-attaching the throttle pin to a RISING
interrupt, which will repeat the process again... */
  rxVal=micros()-rxPrev; 
  attachInterrupt(RX_INT_PIN_THROTTLE,rxGoesHigh,RISING);
}

void setup(){
attachInterrupt(RX_INT_PIN_THROTTLE,rxGoesHigh,RISING); /*We begin by attaching a interrupt
to the throttle pin. the interrupt will fire when the pin goes high "RISING" (meaning the
start of the pulse). When that happens it will call the function rxGoesHigh.*/
}
void loop(){
//Nothing to do here!
}

Begin by reading the comments in setup, then go to the function rxGoesHigh and continue to the function rxGoesLow. Because interrupts are handling your pulse-length changes, all you have to do to get the latest pulse-length is read the variable rxVal.

If you need to read a lot of pins I can write something similar to explain how you can use PIN-CHANGE-INTERRUPTS instead..
« Last Edit: September 07, 2013, 05:54:48 pm by baselsw » Logged

Pages: [1] 2 3 ... 20   Go Up
Jump to:  

Powered by SMF 1.1.19 | SMF © 2013, Simple Machines