BlueCopter - Arduino Quadcopter

GoussLegend:
About your old method of rate-PID tuning:
What is your speed setpoint/reference ? I guess 0 deg/s and before your have manually put your quad at 0 deg for roll and pitch angle?

I have trouble understanding what you mean.. But I'll give it a shot.. When the quadcopter is in rate-mode, the set-point is determined by the RC-reciever.. Meaning you change the setpoint directly with the transmitter/Remote control.. For example, if you roll left then the setpoint will be something <0deg/s (negative angular rate), and the opposite if you roll right, >0deg/s (positive angular rate)..

If you're in angle mode, the reciever controls the setpoint of the angle-PID, and the angle-PID will in turn decide the setpoint for the rate-PID...

GoussLegend:
I know well Matlab and I have got it on my laptop. (My dream would have been to use Simulink :)). Anyway what do you do with your Matlab script? Transfer function?

Simulink is slow and not optimal for something you run and optimize in real time.. Sure, you got the Real-Time toolbox, but if you ask me it sucks!

No it's not transfer functions, that would be optimal in-case i modeled the system.. But instead I did the following:

Arduino side: Wrote a whole new sketch that only handles inputs, outputs and gyro, acc calculations.. Meaning all the PID calculations are done in matlab..

Matlab side: I implemented some known PID tuning methods, like Ziegler-Nichols, SIMC, IMC etc.. They are easy to calculate.. It was just a matter of iterating and testing the results I got from the different methods.. The method that gave the best result for my quad. was the SIMC.. Still the results were not perfect, but it got me pretty close to something acceptable.. I know your going to ask why it didn't give me the optimal magical numbers =P! The reason is lag/delay in the system.. Matlab runs fast, a little too fast for the Serial-communication on the arduino.. So by the time arduino sends the data, the quadcopter would have changed its state drastically (not for the human eye maybe, but you can see it if you look at the data).. This kind of lag/delay can lead to early oscillations in the PID-tuning..

The optimal way to run this type of tuning is on the arduino itself.. So maybe write a PID optimizer for the arduino??

//Basel

hi again.
i have some question i fixed my receiver and now i have some question .
how we can change pid values? is it compatible with multiwii gui ?

sk8amazing:
hi again.
i have some question i fixed my receiver and now i have some question .
how we can change pid values? is it compatible with multiwii gui ?

Hmm, if you're talking about my code then no.. To change the PID values you'll have to go to the Config.h file and change them there... You'll find these lines inside the file:

#define ROLL_PID_KP  0.250
#define ROLL_PID_KI  0.950
#define ROLL_PID_KD  0.011
#define ROLL_PID_MIN  -50.0
#define ROLL_PID_MAX  50.0

#define PITCH_PID_KP  0.250
#define PITCH_PID_KI  0.950
#define PITCH_PID_KD  0.011
#define PITCH_PID_MIN  -50.0
#define PITCH_PID_MAX  50.0

#define YAW_PID_KP  0.680
#define YAW_PID_KI  0.500
#define YAW_PID_KD  0.0001
#define YAW_PID_MIN  -50.0
#define YAW_PID_MAX  50.0

#define ANGLEX_KP 5.0
#define ANGLEX_KI 0.02
#define ANGLEX_KD -0.015
#define ANGLEX_MIN -100.0
#define ANGLEX_MAX 100.0

#define ANGLEY_KP 5.0
#define ANGLEY_KI 0.02
#define ANGLEY_KD -0.015
#define ANGLEY_MIN -100.0
#define ANGLEY_MAX 100.0

The first three sections is for the rate mode PID.. And the last two are for the angle mode PID..

:smiley: sorry bro how arm the quad ? i tried all the ways but quadcopter didnot armed and motors didint start anyway

sk8amazing:
:smiley: sorry bro how arm the quad ? i tried all the ways but quadcopter didnot armed and motors didint start anyway

The copter will arm when the throttle is higher than 1100ms.. Just increase the throttle slowly until it arms..

1 Like

i changed pins because i use arduino uno and i think problem caused bcuz of that .....

sk8amazing:
i changed pins because i use arduino uno and i think problem caused bcuz of that .....

Hmm, then what pins did you change to?? You can find the pins definition in the Config.h file.. The throttle is on pin 7.. And it's a interrupt pin on the leonardo.. Did you come around the receiver code, and in that case did you implement it in the firmware???

If you need further help then please provide me with everything you have, so I know how to formulate my answers..

//Basel

i changed the motors to 3 9 10 11 pins
and throttle to pin 2 and other 3channel to 4 5 6
i think the interupt of arduino is pins 3 isnt it ?

sk8amazing:
i changed the motors to 3 9 10 11 pins
and throttle to pin 2 and other 3channel to 4 5 6
i think the interupt of arduino is pins 3 isnt it ?

I'm currently at work.. But i'll look at it as soon as I get home.. Will you be so kind and post all your code changes so I can take a look at them??? Just zip the whole project and post it here...

Edit: Just got back from work.. i looked over your pin choices.. Well yes the interrupts are on pin 2 and 3.. So that also means that you can't use pin 3 for one of the motors.. Why not leave the motor pins as is??? Did you write a new interrupt routine for the receiver? Because the current one won't work on the UNO..

//Basel

i can unchange the pins but the uno dont have more than 13 pins ...

sk8amazing:
i can unchange the pins but the uno dont have more than 13 pins ...

4 pins for the motors, 4 for the receiver, and 2 for the I2C.. that's 10 pins.. how many do you need??

//Basel

that looks enough but i told that bcuz you said leave the pins as their default .. ]:smiley:

hello,
I am sankha. i made qudocopter using Arduino mega bord. i am trying to make that using this code. but this code has compiling errors and i cant to find circuit diagram..... please help me to bild ub this qudo copter..... thank you.

hello,
I am sankha. i made qudocopter using Arduino mega board. i am trying to make that using this code. but this code has compiling errors and i cant to find circuit diagram..... please help me to bild ub this qudo copter..... thank you.

Huh? Why did you report yourself to the moderator?

shsankha:
hello,
I am sankha. i made qudocopter using Arduino mega board. i am trying to make that using this code. but this code has compiling errors and i cant to find circuit diagram..... please help me to bild ub this qudo copter..... thank you.

Hey,

I've provided the circuit for the different connections in the attachment of my first post.. So go back and look at it.. The code is written for the arduino leonardo/micro.. And won't work out of the box with the mega..

I've got a lot of private messages like this, where people have tried getting this code running on boards other than leonardo/micro..
I'll rewrite/add the missing pieces, to the code in-order for it to work with the UNO and MEGA if I can get any volunteers that can test the code for me on their quadcopters..

//Basel

Hi Basel,

I come back again (I have asked you a few questions some weeks ago). So I have made some progress :). And now my quadcopter is stable on a testbed. Like you, I use an inner rate loop, and outer position loop.

So my problem is that, for now, both loops run at the same frequency (around 200Hz). The inner loop could run alone at (I guess) around 300Hz. And I would like the outer loop to run at around 50Hz. But I don't know how to structure my code to obtain this. I looked at your code, but it's not very clear to me how you do it.

Thanks for your help!
Romain

GoussLegend:
So my problem is that, for now, both loops run at the same frequency (around 200Hz). The inner loop could run alone at (I guess) around 300Hz. And I would like the outer loop to run at around 50Hz. But I don't know how to structure my code to obtain this. I looked at your code, but it's not very clear to me how you do it.

Hey,

Well I do it by reading millis() and comparing that to the value 1000/FREQ (which equals to the duration of each loop in milliseconds).. For example:

#define RATE_FREQ  300 //Hz
#define ANGLE_FREQ  50 //Hz

long prevRate=millis();
long prevAngle=millis();

void updateValues(){

  if((millis()-prevRate)>(1000/RATE_FREQ)){
    //Run rate specific function
    prevRate = millis(); 
  }

  if((millis()-prevAngle)>(1000/ANGLE_FREQ)){
    //Run Angle specific function
    prevAngle = millis(); 
  }

}


void setup() {                

  
}

void loop() {
updateValues();  
}

if you want to see it in my code, then look in the Sensor.ino (BlueCopter/Sensor.ino at master · baselsw/BlueCopter · GitHub)

On lines 15 (rate) and 19(angle)...

If you have further questions feel free to ask =)!

Edit: Just a small tip.. Use Micros for things with high frequency, like the rate loop.. Just to get better accuracy when it comes to timing =)!

//Basel

Thanks for the quick answer again!

So ok you update your rate values at 300Hz and your angle values at 50Hz. When I looked at the main arduino loop:

void loop() {
  updateSensorVal();
  FlightControl();
}

It appears to me that you run FlightControl() even if the values (rates or angles) haven't change. I find this kinda strange.

Another thing, so let's say you rate update frequency is 300Hz and angle frequency is 50Hz. So you will update like this:

update rate 1
update rate 2
update rate 3
update rate 4
update rate 5
update rate 6
update angle 1
update rate 7
update rate 8
...

In my case the update angle takes some times (reading the accelero values) and I am not too sure if between update rate 6 and update rate 7 there will be really 1/300Hz = 3 mili sec. Did you have the same problem? Like when you update your angle, your rate update frequency will be a bit slower.

I hope this makes sense for you!

GoussLegend:
Thanks for the quick answer again!

So ok you update your rate values at 300Hz and your angle values at 50Hz. When I looked at the main arduino loop:

Yes, the angle update freq. is 50Hz.. The rate update rate is 800Hz, reread the code :wink:

GoussLegend:
It appears to me that you run FlightControl() even if the values (rates or angles) haven't change. I find this kinda strange.

Strong point there! If you think of it, it's both dumb and smart at the same time :).. The reason it is dumb is that you, as you said, run it even when the values haven't changed yet.. The reason it's smart: You save code space! Because it takes a few extra lines of code, to make the same "time check" procedure for the flightcontrol.. And I chose to optimize my code based on size, both to make it simple for the reader to follow along and to kind of compete with the exiciting open source solutions ;)...What if I put a "time check" there, what will I gain? Maybe better accuracy in the scale of microseconds.. But believe me, you don't need that kind of accuracy for perfectly stable flight!

GoussLegend:
Another thing, so let's say you rate update frequency is 300Hz and angle frequency is 50Hz. So you will update like this:

update rate 1
........................................

In my case the update angle takes some times (reading the accelero values) and I am not too sure if between update rate 6 and update rate 7 there will be really 1/300Hz = 3 mili sec. Did you have the same problem? Like when you update your angle, your rate update frequency will be a bit slower.

I hope this makes sense for you!

You shouldn't have that kind of delay.. Did you initialize your accelerometer right? Because, the accelerometer will update its values once each 1/50 seconds.. But the communication between the accelerometer and Arduino has a speed of atleast 100kHz (I2C)... So you should not get that kind of delay.. I don't know if you read my last post, but I gave you a tip to use micros() instead of millis() for the rate loop, when it comes to the "time-check".. So instead of 1000/FREQ, you'll have 1000000/FREQ..

If you don't figure out the reason for the problem, please post your code, so I can take a look at it.. Also, what kind of IMU are you using?

//Basel