[url]
http://www.flickr.com/photos/18257187@N08/1895501655/[/url]
1: English is not my firts language, sorry if i made mistakes trying to describe this project.
I made an autopilot for my RC helicopter (Sabre, i bought it in Hobbie People USA) with acelerometers extracted from the NunChuck of nintendo Wii. Now i just a beta, i will change the Arduino Decimila for the mini version, you know, for weight reasons.
Arduino just control the Axis X and Y of the helicopter, but i able to read signals coming from my RC, an order to arduino to move my helicopter, easy and smoothly in that axis (X & Y), i only have to control the rotation and altitude, the rotation is not a big deal because the heli is stabilized by build-in "Gyros". I recycled the joystick axis of NunChuck, to adjust the servos with out touching the code. To se more pictures enter here
http://www.flickr.com/photos/18257187@N08/ The code:
Code:#include <Wire.h>
#include <string.h>
#include <stdio.h>
uint8_t outbuf[6]; // array to store arduino output
int cnt = 0;
int ledPin = 13;
int voltPin = 2;
int apX = 0;
int apY = 0;
int minWii = 330;
int maxWii = 694;
/////////////////
int axisX = 0; //Acelerometer axis X
int axisY = 0; //Acelerometer axis Y
int axisZ = 0; //Acelerometer axis Z
int adjustX = 127; // adjust axis X
int adjustY = 127; // adjust axis X
int contador = 0; //Contador del ciclo FOR
////////////////////Read RC
int xPin = 7; //Pin IN of servo Axis X
int yPin = 8; //Pin IN of servo Axis Y
int timeX = 0; //Show the readed control position
int timeY = 0;
long lastPulseX = 0; // the time in milliseconds of the last pulse
long lastPulseY = 0;
long mstime = 0; // reads the time in miliseconds
long hptime = 0; // Reads the time in Microseconds
///////////////////Write Servos
int minPulse = 800; // Minimum servo position
int maxPulse = 2200; // Maximum servo position
int refreshTime = 20; // the time needed in between pulses
int servoXPin = 2;
int servoYPin = 4;
long lastPulseWriteX = 0; // the time in milliseconds of the last pulse
long lastPulseWriteY = 0; // the time in milliseconds of the last pulse
int pulseX = 0; // Amount to pulse the servo X
int pulseY = 0;
////////////////////////////////////
extern volatile unsigned long timer0_overflow_count; // Sistema de conteo en microsegundos
unsigned long hpticks (void)
{
return (timer0_overflow_count << 8) + TCNT0;
}
///////////////////////////////////
void setup ()
{
pinMode(servoXPin, OUTPUT); // Set servo pin as an output pin
pinMode(servoYPin, OUTPUT); // Set servo pin as an output pin
pinMode(xPin, INPUT); //The R/C signal pin as an input pin
pinMode(yPin, INPUT);
pulseX = minPulse; // Set the motor position value to the minimum
pulseY = minPulse; // Set the motor position value to the minimum
beginSerial (38400);
Serial.print ("Finished setup\n");
Wire.begin (); // join i2c bus with address 0x52
nunchuck_init (); // send the initilization handshake
}
void loop ()
{
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ())
{
outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
digitalWrite (ledPin, HIGH); // sets the LED on
cnt++;
}
// If we recieved the 6 bytes, then go print them
if (cnt >= 5)
{
print ();
AutoPilot();
updateServo();
Serial.print ("\r\n");
}
cnt = 0;
send_zero (); // send the request for next bytes
delay(5);
}
void AutoPilot()
{
pulseX =((((axisX - minWii) * ((maxPulse-minPulse)/(maxWii-minWii))))+minPulse)-127;
pulseY =((((axisY - minWii) * ((maxPulse-minPulse)/(maxWii-minWii))))+minPulse)-127;
pulseX = pulseX + adjustX;
pulseY = pulseY + adjustY;
pulseY = maxPulse - (pulseY - minPulse);
if(axisZ <= 754)//just a test
{
if(axisX <= 500)
{
pulseX = pulseX - 300;
}
if(axisX >= 560)
{
pulseX = pulseX + 300;
}
}
Serial.print ("SrvX");
Serial.print (pulseX);
Serial.print ("\t");
Serial.print ("SrvY");
Serial.print (pulseY);
Serial.print ("\t");
}
void RadioControl()
{
/////////////////////////
if(millis() - lastPulseX >= 200) //Read Axis X every 5 milis
{
while(!digitalRead(xPin) == HIGH) //Waits for signal coming from axis X
{
continue;
}
mstime = millis();
hptime = hpticks()*4; //When the signal arrives, here we going to record the start time of reciving
while(!digitalRead(xPin) == LOW){
continue;
}
mstime = millis();
timeX = (hpticks()*4) - hptime; //Here takes the diferences of the Start and finish times, the result is the signal from RC.
hptime = 0;
Serial.print ("CtrX");
Serial.print (timeX);
Serial.print ("\t");
lastPulseX = millis();
}
///////////////////////////The same, but now for axis Y
if(millis() - lastPulseY >= 200)
{
while(!digitalRead(yPin) == HIGH){
continue;
}
mstime = millis();
hptime = hpticks()*4;
while(!digitalRead(yPin) == LOW){
continue;
}
mstime = millis();
timeY = (hpticks()*4) - hptime;
Serial.print ("CtrY");
Serial.print (timeY);
Serial.print ("\t");
hptime = 0;
lastPulseY = millis();
}
}
//Continue