Go Down

Topic: Arduino Helicopter Autopilot (Read 27733 times) previous topic - next topic


Hi Jim,
Ed will be better placed to comment but a test I would suggest is to feed the decoded channels values directly into the servos to see if the problem is in the servo decode/encode part or the autopilot part.

Make sure that the serial print statements remain commented out, they will slow the system down if you enable them.


Sorry about the pin2 vs. pin8 issue.

It's pin 8 for the PPM - I originally had the PPM on pin 2 with all the timing done in software. The code will be updated asap.

Please come and download a new copy.

As for the jerks, please could you test the PPM results (just print the results from the RC to serial) and I will see what I can do.

I have noticed that everyone - everywhere states that servo timings are from 554 microseconds to 2500 microseconds. My rc system will only go from 1000 to 2000 microseconds. I have no idea why, but it looks to be a knock off copy of a Futaba skysport.

If you can let me know what your servo pulse range is, I can advise.
What is happening (at a guess) is the timings are not adding up correctly. Also, once you know what your rc system is outputting, change the minPulse and maxPulse values accordingly.

To be perfectly honest the majority of my development work has not involved the RC at all - I've been working over the Serial control.

Have fun!


As for the jerks, please could you test the PPM results (just print the results from the RC to serial) and I will see what I can do.

I am happy to do some tests but would prefer not to be called a jerk  ;)


Hehehe - my bad!

As I have been discussing with a couple of people who have been testing the code, if you do not have the correct accel attached, you will need to fake the outputs of the accel subroutine with x=0 y=0 and z=1024.

The code will then have the illusion that it's the right way up, and it's not falling/climbing.

I hope this should fix it - I have to confess I have tested the code without RC, and without Serial input, both work fine, but the removal of the accel causes big maths issues in the mixing of the control data.

I hope this helps, there will be some slightly tidied up code going live today. Many little changes, some useful, some just to remove things that have caused confusion.

All the best,


Hello again,

I have just made some changes to the code. A new version is available for download now. It should have some debugging help for most issues that have been raised so far.

If there is anything else I need to do (and haven't yet been made aware of) please post here or PM me - I'm having a day of fixing loose ends.



Hi Ed, had a quick look at the latest code and the servo values only seem to be set in the autopilot function. There does not seem to be a way to bypass that for testing (or reasons of safety).

Perhaps I missed it, but I suggest you have a way to drive the servos directly from the RC signal. This could be switched from a spare channel, from the failsafe, or as a compile time option or serial command. I think all the options should be available to help with testing while the code is under development.


Hi Mem,

Yes, the final values come out from the autopilot function, however the name autopilot is misleading now. It should be called stabilise or something.

I'll have a new version up on the site soon, I've just fathomed out the kalman for the Z axis gyro too, that was causing some major issues.

If you've got any changes you'd suggest I include please email me with the suggestions. The email address is on my website for anyone who wishes to contact me.

Thanks again, Mem and everyone else who has been so eager to keep this moving.



Well,joy at last :). :D

@Ed   I downloaded the latest code and ran it. Iadded the X,y, = 0 values and it ran smoothly. Now I can see the channel mixing.

Am having problems with the Processing sketch though. Not receiving any data from the Arduino. Is there a trick to getting this done? Guess I will go to the Processing Tutorials to see how Serial Communication is done.

Thank you very much for the changes. I am with MEM here on that it would be nice to be able to run the Radio Control code without the other stuff as testing. Is there a way to get the refresh rate to printout on the serial monitor? I would like to be able to see how fast it refreshes( about 450?)?



Hi all,

There should be two lines printed at regular intervals to the serial terminal (with the code as-is) one beginning $CTRL and one beginning $SENS. These give you all the info about sensors, control and refresh rate.

I'm not sure why the processing sketch is causing problems, as long as the correct port is selected in the sketch it should do something without any changes.

The changes needed for the RC testing should be quite easy to sort out, I'll have a go later at adding the needed bits.

Cheers for testing and the feedback!



Jan 26, 2009, 07:17 pm Last Edit: Jan 26, 2009, 07:19 pm by aercam Reason: 1

I have gone line by line in the V3 code to see what the serial print output is and I found a line that has refreshrate as a print statement. It is at the end of the $SENS line. There is no line with the $CTRL variable.

I have two lines that print out in the serial monitor window and are:

$SENS, 0,0,0,0,2710

These two line repeat over and over.

Is the refreshRate 2710ms? I cannot find any value that shows 470 or any other Hz. Is this ms value somehow converted to the refresh rate in Hz in the processing sketch?

I realize you are very busy and I really appreciate you taking the time to respond to this newbie's questions..



Hi Jim,

Sorry - my fault - wrong header - i should have said $OUTP,...

I'll add(put back) some human readable debugging stuff soon - the strings output are the data that the processing sketch read.

That would be the refresh rate, yes (it's in hz). There are 2 software timers which trigger the two lines individually. By the looks of it, you have no accel code running.

Find the commented out section at the bottom of the Accel() routine:
ax_m = 0;      // debug - these are the expected values from the accels.
ay_m = 0;
az_m = 1024;

remove the comments, and comment out this:

ax_m = x_val;  // assign the values to externally accessible variables
ay_m = y_val;
az_m = z_val;

This will fake the values from the accel and it should all begin to make a little more sense!

This will make the mixing work as the servo timings will start adding up to the correct values. The numbers in the $OUTP,... string should be within the range of 1000 and 2000.

Have a look for the SerialIO() routine, at the end of the routine there is something that will resemble this:

if (millis() - timer2 >= 300) {
   timer2 = millis();    
    // Serial output
   Serial.print("$SENS,"); Serial.print(int(rotationZ)); Serial.print(","); Serial.print(int(angleX*57.2957795130823)); Serial.print(","); Serial.print(int(angleY*57.2957795130823));Serial.print(",");Serial.print(az_m);Serial.print(","); Serial.print(int(refreshrate));Serial.println();
//   Serial.print("Sensor data, ZGyro: "); Serial.print(int(rotationZ)); Serial.print(",  Angle X: "); Serial.print(int(angleX*57.2957795130823)); Serial.print(",  AngleY: "); Serial.print(int(angleY*57.2957795130823));Serial.print(",  Z axis accel: ");Serial.print(az_m);Serial.print(", Refresh rate: "); Serial.print(int(refreshrate));Serial.println();
 if (millis() - timer3 >= 300) {
   timer3 = millis();
   Serial.print("$OUTP,"); Serial.print(valueX+minPulse);Serial.print(","); Serial.print(valueY+minPulse); Serial.print(",");Serial.print(pitch); Serial.print(",");Serial.print(pulseThrottle); Serial.print(","); Serial.print(pulseTailRotor); Serial.println(",");
  // Serial.print("Computed control output data, X control: "); Serial.print(valueX+minPulse);Serial.print(",  Y control: "); Serial.print(valueY+minPulse); Serial.print(", Pitch: ");Serial.print(pitch); Serial.print(", Throttle: ");Serial.print(pulseThrottle); Serial.print(", Yaw: "); Serial.print(pulseTailRotor); Serial.println();


I've added some human readable lines to it, you can copy and past this to replace what's there and then comment out whichever statements you don't want printing.

I hope this sheds some light on the situation.

I might point out here that the values for X Y and Pitch being printed out are not sent to servos directly, they are computed in this form first, then the CCPM mixing takes place, making the servo outputs pretty meaningless in display terms (again i should mention the processing sketch - these are basically all the values I'd discovered I'd like to monitor)

Once you've got all the values in the $OUTP line to be in the correct 1000-2000 (microseconds) range you should see nice smooth servo motion, and correct mapping of the controls onto your CCPM heli.

If you have a mechanical mixing system  on your heli (and your servos actually do provide pitch, X and Y as individual functions) then you could make a few changes to allow for the needed values to be sent to the right servos. You could effectively do away with the mixing altogether, and send the intermediate X Y and Pitch values to the servos. Please bear in mind that all the values from the intermediate X Y and pitch stage will need minPulse adding to them if you should want to (or need to) drive servos with those values.

I hope this hasn't added to the confusion. Please feel free to email me (using the address on my website) with code you are working on attached with your own comments/questions/suggestions and I'm happy to have a look.



I have just corrected some errors in the code for both the arduino and processing... please come and download new copies if you are having issues...




Jan 27, 2009, 03:00 pm Last Edit: Jan 27, 2009, 03:01 pm by amml2000 Reason: 1
Such a fantastic project Ed! Do you have any plans of adding a gps so you can send the helicopter on a mission? (eg fly to coordinates xy and fly back) Gona start building this thing soon, once im done with my other projects lol, cant wait..




Thank you for the heads up on the new code and corrections.

"[glow]I have just corrected some errors in the code for both the arduino and processing... please come and download new copies if you are having issues..[/glow]."

I finally got the processing sketch to run and the CP file running and printing out data to the serial Monitor and the Processing window. I did have to go into the CP file and correct the input pin from pin2 to pin8. I also did the mods you outlined above to get the Accel value.

It appears to be working fine for about 2 minutes. At that time, the processing sketch just does not receive or print any more values. It's like it just gets swamped with data and stops. If I stop the sketch and restart the sketch it will run for another couple of minutes before it stops again. The screen stays up and leaves the last received data on screen. The graph bars on the screen are a very nice touch especially the pitch one that changes color at the half stick position.

The only problem I am having at this time is that the throttle command does not work at all.  :-[I may have the pins messed up or something, but the servos do not move or the graph and serial monitor show no throttle activity.

Keep up the great work mate and thank you for your effort on this project.



Hi all,

Sorry again, I've made a few changes which should get the throttle working on the RC, I only have a four channel radio, so most of my work is done using the processing sketch.

I'll write up the controls on the processing sketch soon, I should have done that as I wrote it - but I got carried away with coding.

I hope that's the worst of the problems ironed out, now time to get the kalman filters nicely integrated - I've been hurting my head with all the E-books I can lay my hands on, now I have a plan to make the whole Kalman filter into one big subroutine rather that one per axis. I think this will solve some of the issues with the Z axis gyro and also make room for some GPS routines.

My girlfriend bought me the ladyada GPS Shield for xmas so I should be laughing with that soon. I'll try and add a 'black box' data recorder function logging data onto the SD card.

I'm looking at getting the next chip up the range from the standard arduino so I have more room for code (and the bonus of extra ram)

Thanks everyone!!


Go Up