Flight Computer/Datalogger for Air/Water Rocket

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Flight Computer/Datalogger for Air/Water Rocket

Postby scubaben » Sat Mar 09, 2013 11:54 pm

My friend started getting interested in building an air/water rocket from two liter bottles. These rockets can reach a few hundred feet and need a parachute system to soften the descent so they can be reused. Here's a neat example of a two stage version:
https://www.youtube.com/watch?v=0qzOzjRJpaU

Anyways, I thought it would be neat to build a flight computer around an Arduino. For this project I used a Duemilanove, an Adafruit BMP085 pressure sensor, and an SD card breakout board.

The system has a few basic functions:
1) press a button to close a servo (which would be used to secure a parachute)
2) press a button to arm the system, and wait to detect a launch
3) use the pressure sensor and SD card breakout board to log the altitude
4) detect a descent and deploy the parachute

This was a fun little project and I learned a lot along the way, the breakout boards for the pressure sensor and the SD card were super easy to use. Hope you like it, and I hope someone else might be able to use it, or learn from it too!

Code: Select all
/*
Air/Water Rocket Flight Computer
Written by Ben Shiner 3/9/2013
Uses a BMP085 pressure sensor to detect altitude
Detects descent and activates a servo to deploy a parachute
Logs altitude throughout the flight to an SD card

SD Card Breakout Board
CLK - PIN 13
DO - PIN 12
DI - PIN 11
CS - PIN 10

BMP085
SCL - PIN 5 (ANALOG)
SDA - PIN 4 (ANALOG)
*/

//include the library for servos, wire, the Adafruit BMP085 pressure sensor, and SD cards
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SD.h>

//create objects for the pressure sensor, the servo, and the data file
Adafruit_BMP085 bmp;
Servo deployservo;
File dataFile;

//create constants used for the pins
const int armpin = 2;  //Pushbutton connected to +5v
const int servopin = 9;  //Servo signal
const int readyled = 5;  //Ready LED
const int initled = 4;  //Initialized LED
const int armled = 3;  //Arm LED
const int chipSelect = 10;  //CS pin for SD card Breakout Board

//create constant for logging interval
const int loginterval = 300;

//create constants for the launch and descent thresholds and touchdown altitude (in meters)
const float launchthreshold = 2;
const float descentthreshold = 2;
const float touchdownalt = .5;

//create variables for armed states, button states, altitude and time
int armed = 0;
int buttonstate;
int lastbuttonstate;
float currentalt = 0;
float groundalt = 0;
float peakalt = 0;
float adjustedalt = 0;
long launchmillis = 0;
long armmillis = 0;

void setup(){
Serial.begin(9600);
bmp.begin();

//set pinmodes
pinMode(armpin, INPUT);
pinMode(readyled, OUTPUT);
pinMode(servopin, OUTPUT);
pinMode(armled, OUTPUT);
pinMode(initled, OUTPUT);
pinMode(chipSelect, OUTPUT);

Serial.println("Initializing SD card..."); //check if the sd card can be initialized
if(!SD.begin(chipSelect)){
  Serial.println("SD card failed to initialize");
}

deployservo.attach(servopin);
Serial.println("Zeroing servo position...");
deployservo.write(0); //intitalize the servo position

buttonstate = digitalRead(armpin); //initialize the button states
lastbuttonstate = buttonstate;

//open the datafile
dataFile = SD.open("log.txt", FILE_WRITE);
if (dataFile) {
    dataFile.println("System Powered ON");
}
}

void loop(){
initialize(); //this function waits for a button press to initialize the system
arm(); //this function waits for a button press to arm the system
launch(); //this function detects a launch, when a change in altitude exceeds the launch threshold
inflight(); //this function logs the alittude during the flight and detects a decent when a decrease in altitude exceeds the descent threshold
descent(); //this function logs altitude during descent detects when the altitude falls below the touchdown threshold
}

void initialize(){
//if the data file isn't already open, then open the file
  if(!dataFile){
  dataFile = SD.open("log.txt", FILE_WRITE);
}

  while(armed == 0){
  digitalWrite(readyled, HIGH);  //turn on the readyled
  buttonstate = digitalRead(armpin);
  //check for a button press to initialize the system
  if(buttonstate != lastbuttonstate){
  if(digitalRead(armpin) == HIGH){
      armed = 1;
      Serial.println("Initializing...");
      digitalWrite(initled, HIGH);
      if(deployservo.read() == 0){
          deployservo.write(180);
          Serial.println("Initialized");
           if (dataFile) {
            dataFile.println("System Initialized");
       }
       
  }
  lastbuttonstate = buttonstate;
// wait .5 seconds to protect against accidental double clicking and arming
delay(500); 
}
}
lastbuttonstate = buttonstate;
}
}

void arm(){
while(armed == 1){
  //check for a button press to arm the system
  buttonstate = digitalRead(armpin);
  if(buttonstate != lastbuttonstate){
    if(digitalRead(armpin) == HIGH){
        armed = 2;
        //get the current altitude, set it as the peak and as the ground altitude.
        currentalt = bmp.readAltitude();
        groundalt = currentalt;
        peakalt = currentalt;
        Serial.println("ARMED");
        if (dataFile) {
          dataFile.println("System ARMED");
       }
        digitalWrite(armled, HIGH);
        armmillis = millis();
  lastbuttonstate = buttonstate; 
}
}
lastbuttonstate = buttonstate;
}
}

void launch(){
while(armed == 2){
  currentalt = bmp.readAltitude();
  adjustedalt = currentalt - groundalt;
  recordAltitude((millis() - armmillis), adjustedalt);
  //if the current alt is greater than the ground alt + launch threshold and the rocket has not been launched yet then update arm status
  if(currentalt > (groundalt + launchthreshold) && armed == 2){
    Serial.println("Launch Detected"); 
      if (dataFile) {
        dataFile.println("Launch Detected");
       }
      launchmillis = millis();
      armed = 3;
      digitalWrite(armled, LOW);
      digitalWrite(initled, LOW);
  }
}
}

void inflight(){ 
  while(armed == 3){
    currentalt = bmp.readAltitude();
    adjustedalt = currentalt - groundalt;
    if(currentalt > peakalt){
      peakalt = currentalt;
    }
    recordAltitude((millis() - armmillis), adjustedalt);

//if the current alt plus the descentthreshold is less than the peak alt, then detect a descent and deploy the chute
  if(peakalt > (currentalt + descentthreshold) && armed == 3){
    deployservo.write(0);
      Serial.println("Chute Deployed");
      if (dataFile) {
        dataFile.println("Chute Deployed");
       }
armed = 4;
}
}
}

void descent(){ 
while(armed == 4){
    currentalt = bmp.readAltitude();
    adjustedalt = currentalt - groundalt;
    recordAltitude((millis() - armmillis), adjustedalt);
    //write touchdown and calculate peak altitude and flight duration when the altitude drops below the touchdown altitude.
  if(adjustedalt < touchdownalt){
      Serial.println("Touchdown!");
      Serial.print("Flight Duration: ");
      Serial.print(millis() - launchmillis);
      Serial.println("ms");
      Serial.print("Peak Altitude: ");
      Serial.print((peakalt - groundalt) * 3.28);
      Serial.println("ft");
            if (dataFile) {
                dataFile.println("Touchdown!");
                dataFile.print("Flight Duration: ");
                dataFile.print(millis() - launchmillis);
                dataFile.println("ms");
                dataFile.print("Peak Altitude: ");
                dataFile.print((peakalt - groundalt) * 3.28);
                dataFile.println("ft");
       }
       //clean up the variables before closing out the descent function
      peakalt = 0;
      currentalt = 0;
      groundalt = 0;
      buttonstate = digitalRead(armpin);
      lastbuttonstate = buttonstate;
      dataFile.close();
      armed = 0;
  }
}
}

void recordAltitude(long flighttime, float altitude){
    Serial.print(flighttime);
    Serial.print(",");
    Serial.println(altitude * 3.28);
    if (dataFile) {
        dataFile.print(flighttime);
        dataFile.print(",");
        dataFile.println(altitude * 3.28);
       }
       delay(loginterval);
}

scubaben
 
Posts: 2
Joined: Sat Mar 09, 2013 11:43 pm


Re: Flight Computer/Datalogger for Air/Water Rocket

Postby scubaben » Sun Mar 10, 2013 6:06 pm

adafruit_support wrote:Very cool. Do you have any photos if it for the blog?

Sure! Here's a picture of it prototyped on a breadboard, for now. We'll be working on integrating it with the rocket over the next week or so, and I'll try to post more pictures as we make progress.

Image
scubaben
 
Posts: 2
Joined: Sat Mar 09, 2013 11:43 pm


Return to Arduino

Who is online

Users browsing this forum: No registered users and 12 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [108]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[31]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[34]
LCDs & Displays[48]
Components & Parts[70]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[111]
 
Wireless[14]
Cables[62]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]