Arduino Helicopter Autopilot

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(angleX57.2957795130823)); Serial.print(","); Serial.print(int(angleY57.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(angleX57.2957795130823)); Serial.print(", AngleY: "); Serial.print(int(angleY57.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.

Cheers,
Ed

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...

Thanks!

:slight_smile:

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..

Cheers

@Ed

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

"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..."

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.

Jim

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!!

:slight_smile:

Another thing I should probably add at this point is that I will be making changes to the library for reading the PPM - It seems that there are enough occurrences of noise in the right time frame to trigger false positive signal identification, this only happens occasionally, but it is enough for it to throw off the values horrendously when it does happen, and at present that causes an offset on all the channels of a random amount.

I think I'll make it wait for a considerable number of frame periods within the right time scale before it allows any data into the code, at present this is done by counting 30x consecutive ok status reports and then allowing data through. However - somehow this still occasionally causes an odd erroneous positive identification...??

Watch out for an altered version of the library soon. I'll post here when it's working.

GPS on it's way very soon - I've been thinking about that one a lot.

Anyhow - back to the code.
Enjoy!!

Hello again,

I've just fixed some daft errors in the gyro and radio control code, it should now behave more sensibly.

The Z axis gyro uses a really ugly hack to make the kalman filter work without an angular input - but it works remarkably well. I'll look into getting a compass or using the heading from GPS - this will make the rotational readings much more accurate, and a heading would make position hold even more usable. I hope to make the new kalman code soon - it's going to be one big filter rather than one per axis - this will hopefully have more resistance to noise from other axes and should run faster too.

Alpha3 has been updated with these changes - anyone experiencing difficulties with RC or gyros should grab a new copy from my site.

:smiley:

Subscripted :slight_smile:

With respect to the PPM noise, maybe you can try to add a limit for a maximum amount an axis can change between PPM frames. Since it is unlikely for any axis to change say >25% in 20ms (unless you have super fast commands).

I donno, just thinking...

Cheers,
-Z-

Hello,

Welcome aboard zitron, I have a feeling that I'll be doing just that - also making it lock on more securely to the tracking of the framing period, and checking whether the number of pulses in any frame is consistent with the rest.

I'm also going to add a 100nF cap to gnd on the output of my RC receiver to aid the noise rejection.

All the best!

Ed

Hello everyone!

I've made further progress with the helicopter code, and the processing sketch. Linear correction will be integrated into the next version release.

I now have video working under linux, the display is now a video overlay. Also the display has been re-arranged considerably to include an artificial horizon (which is very accurate) and some pretty little piecharts to illustrate the throttle and tail rotor pitch.

http://www.eclipseaudioservices.co.uk/extras/artificialhorizon.html

The Xbox 360 controller integration is going well - this will be included in the next release.

Thanks again to everyone who is testing the code for me - it's certainly speeding the process up.

Ed :smiley:

Hello Ed,

great project! PCM was mentioned a few times the thread and I'm wondering if there is code for Futaba's PCM?

Hi,

The PCM is a standard across manufacturers, as the servo pulses are derived directly from the baseband PCM. All you need to do is locate the PCM pulses in your receiver and make a connection to it > pin 8 arduino.

Mem's library (servo decode) will have you up and running in no time.

I've had some major luck with new filtering for the gyros and accels, I can sense a rotation of less than a degree accurately and use the feedback to smooth movements. Also I've achieved a filter system to detect linear, tilt compensated accelerations without the gravity component. All of this means the helicopter should be flying very steadily very soon.

All the best!
Ed

The PCM is a standard across manufacturers, as the servo pulses are derived directly from the baseband PCM. All you need to do is locate the PCM pulses in your receiver and make a connection to it > pin 8 arduino.

Ed, arnewbie is referring to PCM (Pulse Code Modulation), not PPM (Pulse Position Modulation). PCM is an encoding method where the actual digital values are sent as a serial stream. Unlike PPM it is not standardized and it needs a lot more work to decode.

Does anyone of you know at what voltage level the ppm pulses are? Is it the same for all radio manufacturers?

Hi,

My bad re: PPM vs. PCM - oops

Yeah - my receiver has the pulses at about 4 volts, plenty enough for the microcontroller to go digital high. It should be roughly the supply voltage of the receiver in most cases.

Hope that helps,
Ed

Oops, my bad. I thought you were using the PPM stream coming from the buddy port.

It's been quiet on the thread a bit. I just put in an order for a collective-pitch heli, and I expect it'll take some time for me to learn it (since I've not flown a CP before).

I was wondering if there's more room to minimize the size and weight here. Either by making a "stickduino shield" or just going straight for an Atmel on a heli-oriented board. And adding an air-pressure altimeter seems like a no-brainer, except helis are low-altitude and I'm not sure how accurate the devices are when near the ground.

It seems like the ultimate aim is to let a program dictate higher-level commands to the heli, like "lift off gently," "climb to 30 meters," "turn to heading 270," and maybe even patterns like "zoom forward and tilt up into a stall-left turn." While flying manually is a great amusement for some, I can see this as being more task-oriented for serious applications, UAV style.

Adding a couple generic "accessory activation" pins would be interesting as well. Nerf launchers, cargo winch drivers, cargo jettison, camera triggers, laser or light effects, ...

what do you use for wireless communication?

Hi everyone!

Sorry for the complete lack of news for a while. I've been working on GPS, camera and compass functions.

The 168 arduino is being pushed to the limits with the IMU and correction code alone, so some changes to the hardware have been made.

There will be a major release in the near future. There are new versions of the code for the 328p and Sanguino to allow for more than just IMU and correction functions.

I will post here when the release is made, there will also be a hardware release soon, once it's finalised.

Wireless serial is handled by a UM96 from sparkfun, although I'm tempted to move onto trying wifi using something like a fonera on the heli.

All the functionality of the system is being tailored towards minimal human input - GPS waypointing is improving etc. I will have to come up with a method of giving really simple commands 'live' but otherwise I think it's fulfilling most of the questions people have asked.

All the best!
Ed
:smiley:

hi my friends,
[ch305] need some idea about driving the dc motor with arduino board.

firstly [ch305] detect the tilt angle and I want the produce PWM signal to drive the motors with l293d, but my system likes a teeterboard for ex for negative tilt [ch305] drive the one motor and for positive tilt [ch305] drive the other one, just [ch305] want to stablize the platform thanks for your helps...