Arduinoon perustuva ohjelmoitava kantoraketti

Ajattelin tuossa rakentaa kantoraketin, joka toimii kiinteÀllÀ polttoaineella (alumiini jauheen, ammonium perkloraatin ja polyesterihartsin seos), ja jota voisi ohjata servoilla.

Olen opetellut arduinon ohjelmointia noin puoli vuotta ja laitoin itselleni vÀhÀn isomman haasteen, joten kirjoitin tuossa ohjelman joka lukee serial portista tietoja, ja laittaa ne muuttujina EEPROM:iin, josta ne haetaan taas servojen ohjausta varten.
Muuttujilla ohjataan kantoraketin neljÀÀ servoa, jotka ovat kiinni kantoraketin neljÀssÀ ohjaussiivekkeessÀ.
Raketissa olisi elektroniikkana arduino duemilanove, yhdensuuntainen kiihtyvyysanturi, kolmiakselinen gyroskooppi, korkeusmittari ja mahdollisesti SD kortti, johon nÀmÀ tiedot voi halutessaan tallentaa.

En ole vielĂ€ tehnyt tĂ€lle muuta kuin arduino koodin, mutta varmasti on lisÀÀ tulossa


Sanokaa sitten pliis, jos huomaatte koodissa virheitÀ, kun oon vaan 14 vuotias


TÀssÀ koodia:

#include <SD.h>
#include <EEPROM.h>
#include <Servo.h>

Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

//SPI SD Kortin PinnejÀ
//MOSI = Pin 11
//MISO = Pin 12
//SCLK = PIN 13
int CS_pin = 10;
int pow_pin = 8;
// Kiihtyvyys pinni
int acceleration_pin = 4;
int recovery_pin = 13;
//Korkeus pinni
int altitude_pin = 3;
//Gyro pinnit
int gyro1_pin = 0;
int gyro2_pin = 1;
int gyro3_pin = 2;

//Servo pinnit
int servo1_pin = 11;
int servo2_pin = 10;
int servo3_pin = 9;
int servo4_pin = 6;

//EEPROM osoitteet
int servo_address1 = 3;
int servo_address2 = 4;
int servo_address3 = 5;
int servo_address4 = 6;
int gyro_address1 = 7;
int gyro_address2 = 8;
int gyro_address3 = 9;
//Sytytys pinni
int ignition_pin = 2;

//Servojen kulmat EEPROM:ista
float servo1_position = EEPROM.read(servo_address1);
float servo2_position = EEPROM.read(servo_address2);
float servo3_position = EEPROM.read(servo_address3);
float servo4_position = EEPROM.read(servo_address4);
//Gyroskooppien odotetut kulmat EEPROM:ista
float gyro_angle1 = EEPROM.read(gyro_address1);
float gyro_angle2 = EEPROM.read(gyro_address2);
float gyro_angle3 = EEPROM.read(gyro_address3);

long id = 1; //TÀmÀ antaa SD kortille tallennettaville tiedoille numeron
//*********************************************************************************************
void setup()
{

Serial.begin(9600);
Serial.println(“Valmistellaan korttia
”);
//CS Pin on output
pinMode(CS_pin, OUTPUT);
pinMode(altitude_pin, INPUT);
pinMode(gyro1_pin, INPUT);
pinMode(gyro2_pin, INPUT);
pinMode(gyro3_pin, INPUT);
pinMode(ignition_pin, OUTPUT);
pinMode(recovery_pin, OUTPUT);

//SD kortti ottaa virtaa pinnistÀ 8, joten kirjoita se 1:si
pinMode(pow_pin, OUTPUT);
digitalWrite(pow_pin, HIGH);

//Valmistellaan korttia
if (!SD.begin(CS_pin))
{
Serial.println(“Kortti ei toimi!”);//Korttia ei vĂ€lttĂ€mĂ€ttĂ€ tarvitse olla, joten jatketaan //ohjelmassa.
}
Serial.println(“Card Ready”);

//Kirjoitetaan tiedostoon otsikko:
File logFile = SD.open(“LOG.csv”, FILE_WRITE);
if (logFile)
{
logFile.println(", , , ,"); //VedetÀÀn tÀllainen viiva, jotta erotetaan edellinen data uudesta, jos kortilla oli jotain.
String header = “ID, Kiihtyvyys, Korkeus, Gyro1, Gyro2, Gyro3”;
logFile.println(header);
logFile.close();
}
//MÀÀritetÀÀn servot joko vaaka tai pystysuora ohjaaviksi antamalla serialin kautta 1, 2, 3 tai4.
Serial.println(“Anna 1, 2, 3 tai 4 mÀÀrĂ€tĂ€ksesi lĂ€htösuunnan”);
while (Serial.available() == 0);
int val = Serial.read() - ‘0’;

if (val == 1)
{//servot 1 ja 2 ohjaavat aina pystysuunnassa:
servo1.attach(servo1_pin);
servo2.attach(servo3_pin);
servo3.attach(servo2_pin);
servo4.attach(servo4_pin);
Serial.flush();
delay(5);}

if (val == 2)
{//servot 3 ja 4 ohjaavat aina vaakasuunnassa
servo1.attach(servo2_pin);
servo2.attach(servo4_pin);
servo3.attach(servo3_pin);
servo4.attach(servo1_pin);
Serial.flush();
delay(5);
}
if (val == 3)
{
servo1.attach(servo3_pin);
servo2.attach(servo1_pin);
servo3.attach(servo4_pin);
servo4.attach(servo2_pin);
}
if (val == 4)
{
servo1.attach(servo4_pin);
servo2.attach(servo2_pin);
servo3.attach(servo1_pin);
servo4.attach(servo3_pin);
}
else
{Serial.println(“Ei tunnisteta!”);
return;
}

Serial.println(“Anna haluttu 1:gyroskoopin asento”);
while (Serial.available() == 0);//Odottaa dataa serialilta.
int gyro_angle1 = Serial.read() - ‘0’;//Asetta saadun arvon muuttujaan gyro_angle1.
EEPROM.write(gyro_address1, gyro_angle1);//Kirjoittaa muuttujan gyro_angle1 osoitteeseen gyro_address1 EEPROM:illa
Serial.flush();//TyhjentÀÀ sarjaportin puskurin
delay(5);//Odottaa 5 ms

{
//Tekee saman kahdelle muulle gyroskoopin akselille
Serial.println(“Anna haluttu 2:gyroskoopin asento”);
while (Serial.available() == 0);
int gyro_angle2 = Serial.read() - ‘0’;
EEPROM.write(gyro_address2, gyro_angle2);
Serial.flush();
delay(5);
}
{
Serial.println(“Anna haluttu 3:gyroskoopin asento”);
while (Serial.available() == 0);
int gyro_angle3 = Serial.read() - ‘0’;
EEPROM.write(gyro_address3, gyro_angle3);
Serial.flush();
delay(5);
}
{//Laitetaan servojen halutut asennot muistiin samalla tavalla, kuin gyroskooppejenkin

Serial.println(“Anna pystysuunnan ohjaavien siivekkeiden asento (2 kpl) sitten paina enter, ja muista ettĂ€ 90 astetta on 0
”);
while (Serial.available() == 0);//Odottaa dataa serialilta.
int servo1_position = Serial.read() - ‘0’;//Asettaa saadun arvon muuttujaan servo1ja2_position.
EEPROM.write(servo_address1, servo1_position);//Kirjoittaa EEPROM:ille
Serial.flush();//TyhjentÀÀ puskurin
//TehdÀÀn sama kaikille servoille.
delay(5);
while (Serial.available() == 0);
int servo2_position = Serial.read() - ‘0’;
EEPROM.write(servo_address2, servo2_position);
Serial.flush();
delay(5);

Serial.println(“Anna vaakasuunnan ohjaavien siivekkeiden asento”);
while (Serial.available() == 0);
int servo3_position = Serial.read() - ‘0’;
EEPROM.write(servo_address3, servo3_position);
Serial.flush();
delay(5);

while (Serial.available() == 0);
int servo4_position = Serial.read() - ‘0’;
EEPROM.write(servo_address4, servo4_position);
Serial.flush();
delay(5);

}
servo1.write(90);
servo3.write(90);
servo2.write(90);
servo4.write(90);
delay(2000);

digitalWrite(ignition_pin, HIGH); //Odota pari sekuntia, ettÀ raketti on kerennyt nousta vÀhÀnmatkaa:
delay(2000);
servo1.write(92);
servo2.write(88);
delay(500);
servo3.write(servo3_position);
servo4.write(servo4_position);
delay(500);
servo1.write(servo1_position);
servo2.write(servo2_position);

}
//***********************************************************************************************
void loop()
{
//Tarkistaa asentoaan lennon aikana
int angle1 = analogRead(gyro1_pin);
int angle2 = analogRead(gyro2_pin);
int angle3 = analogRead(gyro3_pin);

// Haluttu arvo - oikea arvo
if (gyro_angle1 > angle1)
{
servo1.write(89);
servo2.write(91);
delay(7);

}

else if (gyro_angle1 < angle1)
{servo1.write(91);
servo2.write(89);
delay(7);}

//Ei tee mitÀÀn, kuin asettaa siivekkeet nolla asentoon
if (gyro_angle1 == angle1)
{
servo1.write(90);
servo2.write(90);
delay(3);}
//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
{
int altitude = analogRead(altitude_pin);
}
if (gyro_angle2 > angle2)
{
servo3.write(89);
servo4.write(91);
delay(7);

}

else if (gyro_angle2 < angle2)
{servo3.write(91);
servo4.write(89);
delay(7);}
//Ei tee mitÀÀn, kuin asettaa siivekkeet nolla asentoon
if (gyro_angle2 == angle2)
{
servo3.write(90);
servo4.write(90);
delay(3);
//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
}
if (gyro_angle3 > angle3)
{
servo1.write(89);
servo2.write(89);
servo3.write(89);
servo4.write(89);
delay(2);

}

else if (gyro_angle3 < angle3)
{servo1.write(91);
servo2.write(91);
delay(2);}
//Ei tee mitÀÀn, kuin asettaa siivekkeet nolla asentoon
if (gyro_angle3 == angle3)
{
servo1.write(90);
servo2.write(90);
delay(3);}
//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
int acceleration_level = analogRead(acceleration_pin);
int G_force = (acceleration_level * 1000 / 512);

if (G_force == 0)
{
delay(3000);
digitalWrite(recovery_pin, HIGH);//Avaa laskuvarjon.
while (Serial.available() == 0);}//JÀÀ tÀhÀn jumiin eikÀ tee enÀÀ muuta.
//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
//KÀytÀn CSV Formaattia
int altitude = analogRead(altitude_pin);
String dataString = String(id) + ", " + String(G_force) + ", " + String(altitude) + ", " + String(angle1) + ", " + String(angle2) + “,” + String(angle3);

//Avaa sd kortin kirjoittamista varten
File logFile = SD.open(“LOG.csv”, FILE_WRITE);
if (logFile)
{
logFile.println(dataString);
logFile.close();
//Nosta ID numeroa
id++;
}
delay(5);// Odotetaan 5ms ja ajetaan uudestaan
}

Johan olet koodin kirjoittanut, muuta ite en sano koodiin mitÀÀn. Mutta kai olet tutustunut pienoismallirakettien rakenteluun ja niiden kÀyttöön. Kato vaikka tÀÀltÀ: http://pollux.ayy.fi/rakettiforum/index.php?sid=981b2f3d7f3d41769548ccf4967eb790

Onnea hienosta projektista.

Koodia en uskalla katsoa, mutta toivottavasti toimii. Sellainen softa kuin VMLab. SillÀ voi simuloida Atmelia ja ehkÀ Arduinojakin.

Raketeista


Raketin polttoaine on rÀjÀhdysainetta (siinÀ on hapetin) ja sen hankkimiseen ja hallussapitoon tarvitaan lupia. Luvat vaativa tÀysi-ikÀisyyttÀ. Laukaisu on myös luvanvaraista ja lennonjohdot yms. pahastuvat jne. Laukaisuun tarvitset kÀytÀnnössÀ vakuutuksen. Maksat itsesi kipeÀksi jos tiputat vÀrkin jonkun sata amppeerisen Datsunin pÀÀlle. Kalliimpi auto niin lapsenlapsesikin maksavat sitÀ velkaa.

MikÀli rikokseen yllyttÀminen ei olisi rangaistavaa niin neuvoisin seuraavasti:

Nyt kun tiedÀt reaaliteetit niin tee tÀmÀ sitten oikein. Ole neuvokas, kehitÀ tekniikkaa, testaa, dokumentoi, laukaise korvessa, dokumentoi laukaisu, tule vasta sitten julkisuuteen ja huuda suureen ÀÀneen, ettÀ yhteiskunta olet paha, kun estÀt nuoria ihmisiÀ toteuttamasta itseÀÀn ja haistakaa pitkÀt. Alan sosiaalipummiksi moisten kieltojen takia, Mutta silti tein sen BUAHAHAHA.

Tee itse mahdollisimman paljon ja kysy fiksummilta neuvoa vain turvallisuuden suhteen. PÀÀasia, ettÀ voit sanoa itse tehneesi.

Mutta noin en voi neuvoa, koska se on vÀÀrin. Tutustu rakettiharrastukseen. Jos olet TRE:n lÀhellÀ niin kysele TTY:ltÀ Castorin ihmisiÀ. YhdessÀ se on kivempaa ja porukalla tehtÀessÀ vastuujutut on yleensÀ kunnossa.

Ai niin. Hapettimet ovat vaarallisia. Omakin elÀmÀ muuttui ehkÀ paremmaksi, kun pÀÀsin yhdyttÀmÀÀn sitÀ mÀÀrissÀ kuusi vuotta sitten.

Juu
 Ajattelin ettÀ tohon tulee laskuvarjo, jonka se avaa kun kiihtyvyys tippuu alle yhteen G:hen


Muista kuitenki varjon aukeminen ei ole 100% tai sitten vaikka aukeekin niin saattaa sorkeutuu narut. Kannattaa lisÀksi olla ehkÀ vara-varjo joka aukeaa jonku ajan kuluttuu kun pÀÀ varjon pitÀs olla auveta.

Mutta suosittelisin enemmÀ jotain valmista isohkoa ruutimoottoria mikÀ on tarkotettu pienoismalliraketteihin ja itse rakentaisi kaiken muun mootorin ympÀrille. NiitÀ saa ostettuu kun on hommannut rakettikortin ja tÀllÀin ampumiseen ei tarvita erillisiÀ lupia, tÀÀlÀ enemmÀ raketti kortista http://pollux.ayy.fi/raketit.html

Hei!

Koodista pieni kysymys. MinkÀtakia ohjaat muuttujat EEPROMiin? Eikös se ole aika hidasta?