Monday, September 17, 2012

Charts

 
 Figure 1
 

 
Figure 2
 



Figure 3

 
 
 Figure 4
 




 


[Testing] Flight test 9-15-12

Purpose:
    1. Collect data for pressure readings from the senor as a function of altitude of the plane and make a graph of this function.
    2. Test the product code during flight to see if the servo rotate at given different levels.

Procedure:

Our plane climbed from ground to 9000 feet. During the flight, we collected pressure and altitude from the program, and altitude from the altimeter of the plane for every 500 feet. When the plane went down, we used our product code to control the servo to rotate at certain altitude and checked if it functions.


Data section:

Table of data from ReadAltitude function (from 1500ft to 9000ft)

Pressure(pa)
altitude(ft)
96025
1478.98636
94700
1859.03592
93375
2243.41572
92050
2632.23762
90725
3025.61801
89400
3423.6781
88075
3826.54418
86750
4234.34789
85425
4647.22657
84100
5065.32359
82775
5488.7887
81450
5917.77842
80125
6352.4565
78800
6792.99431
77475
7239.57142
76150
7692.37605
74825
8151.6057
73500
8617.46778
72175
9090.18027
            (see figure 1 in post "chart")


Table of data collected from plane

Pressure(pa)
altitude(ft)
95953
1500
94130
2000
92351
2500
90756
3000
89033
3500
87523
4000
85849
4500
84280
5000
82702
5500
81230
6000
78645
6500
78129
7000
76700
7500
75145
8000
73792
8500
72404
9000
              (see figure 2 in post "chart")


Analysis:

When we combine the data collected from the function and plane, the data collect from function is overlap with the data from plane. This char indicates that the function from the library matches the real data very well. Thus, the ReadAltitude function from library is dependable.

(see figure 3 in post "chart")

Also, we noticed that the data in this chart look like a linear function, but the theoretical function from library is an exponential function:

Altituded(ft) = 145402*(1-( Pressure(pa) / 101325)^0.1903)

The reason we get a linear function is that the range of altitude in the chart is too small. When we changed the range to from 0 to 100000ft, we get a exponential function finally. As we can see, the collected data is a part of this function, and it looks like a linear function in this part:

(see figure 4 in post "chart")

We tested the product code to control the rotation of servo for serval times, but it did not rotate until the product code was corrected. Finally, the servo rotated as predicted at the last time when the plane went down through the altitude of 2000ft.

Before the product code was corrected, the servo did not work because the program calibrated the initail pressure every time the board is restarted or the code is uploaded. The variable, gaugePressure, which is the difference between initail and current pressure, was used to control the servo. However, if the initial pressure is calibrated during the flight, the wrong gaugePressure would be used to control the servo and lead to failure. At the last time, the code was changed to control the servo by using directly the reading from pressure sensor, and the servo worked as predicted.

This problem implied that initial pressure is not a necessary variable for servo control, and calibration of initial pressure might be get rid of.

Conclusion:

In this test, we achieved our goals successfully. We found out that the reading from the plane matches the theorical function very well and controlled the servo working as predicted by solving a little bug. Also, we noticed that the calibration might not be necessary in servo control. At last, thank Jason for his adept flying skills to make this test possible.

Saturday, September 15, 2012

[Programming] Servo control code


Stage 1: Basic function

Goal: Create a code that allows servo to rotate certain angel for certain pressure

Idea: Use “Level model” to rotate the servo
         Assume that we allow servo to rotate each 30 degree for each 1000 Pa change of pressure
         We have:
 
 
 

 
 
Level = (current pressure – initial pressure) / pressurePerLevel
                               and then we can let servo rotate: Level * AngelPerLevel degree
Solution:

int floors=(bmp.readPressure() - initialPressure)/PPerFloor;
if(floors<lastFloor)
{
myservo.write(AngelPerFloor*lastFloor);
}
else
{
myservo.write(AngelPerFloor*floors);
lastFloor=floors;
}
(codes from “main_code 5.1_debug swtich”)

P.S.
          In the code: “floors” refers to levels
          To avoid the servo rotating back to previous level, I used variabe “Lastfloors” to record the last level. Only when the current level is greater than last floor, we change the degree that servo should rotate.


Stage 2: Non- uniform function

Goal: Becasue the change of pressuren and the change angel of the servo are not linear functions,      each point in the function of “pressure vs servo” should be executed separately

Idea: To avoid the servo rotating back to previous level, we used variabe “levelflag” here to record the last level.

Solution:
long gaugepressure= bmp.readPressure()- initialPressure;
if(gaugepressure>level1 && gaugepressure<level2 && levelflag < 2)
{
myservo.write(angle1);
if(levelflag<1)
levelflag=1;
}
if(gaugepressure>level2 && gaugepressure<level3 && levelflag < 3)
{
myservo.write(angle2);
if(levelflag<2)
levelflag=2;
}
if(gaugepressure>level3 && gaugepressure<level4 && levelflag < 4)
{
myservo.write(angle3);
If(levelflag<3)
levelflag=3;
}
if(gaugepressure>level4 && gaugepressure<level5 && levelflag < 5)
{
myservo.write(angle4);
if(levelflag<4)
levelflag=4;
}
if(gaugepressure>level5)
{
myservo.write(angle5);
if(levelflag<5)
levelflag=5;
}
(codes from “main_code_5.3_servo control updated”)

Stage 3: Mason's version

Goal:

First rotate: when the rocket is launched
Second rotate: reach 3 miles or 90 seconds
Third rotate: reach 5 miles or 3 mins
Fourth rotate: when it's back to 5 miles or 6 mins
Fifth rotate: 15 mins

Trival goal:

First rotate: reach Lv1 or 30 seconds
Second rotate: reach Lv2 or 90 seconds
Third rotate: reach Lv3 or 180 seconds
Fourth rotate: reach Lv4 or 360seconds
Fifth rotate: reach Lv5 or 900 seconds

Solution:

if((gaugepressure>level1 && gaugepressure<level2 && levelflag < 2) || (millis() > 30000 && millis() < 90000))
{
myservo.write(angle1);
if(levelflag<1)
levelflag=1;
}
if((gaugepressure>level2 && gaugepressure<level3 && levelflag < 3) || (millis() > 90000 && millis() < 180000))
{
myservo.write(angle2);
if(levelflag<2)
levelflag=2;
}
if((gaugepressure>level3 && gaugepressure<level4 && levelflag < 4)|| (millis() > 180000 && millis() < 360000))
{
myservo.write(angle3);
if(levelflag<3)
levelflag=3;
}
if((gaugepressure>level4 && gaugepressure<level5 && levelflag < 5) || (millis() > 360000 && millis() < 900000))
{
myservo.write(angle4);
if(levelflag<4)
levelflag=4;
}
if((gaugepressure>level5)|| (millis() > 900000 ))
{
myservo.write(angle5);
if(levelflag<5)
levelflag=5;
}
(codes from “main_code_5.5”)

Limitation: However, there's a serious bug in this code!
When it reaches Lv1 and the time goes into the interval between 90 sec and 180 sec, the program will go into both the first and the second “if”. In other world, the servo will rotate angel1 and angel2 almost at the same time. Thus, the servo will not work!

 
Stage 4: Modified version

Goal: Solve the bug in stage 3.

Idea: check the level every time before allowing the servo rotate

Solution:

if((gaugepressure<level1 && gaugepressure>level2 && levelflag < 2) || (millis() > 30000 && millis() < 90000)) //if the new floor is lower than the last floor, keep angel the servo has moved
{
if(levelflag==1)
myservo.write(angle1);
if(levelflag<1)
levelflag=1;
}
if((gaugepressure<level2 && gaugepressure>level3 && levelflag < 3) || (millis() > 90000 && millis() < 180000)) //if the new floor is lower than the last floor, keep angel the servo has moved
{
if(levelflag==2)
myservo.write(angle2);
if(levelflag<2)
levelflag=2;
}
if((gaugepressure<level3 && gaugepressure>level4 && levelflag < 4)|| (millis() > 180000 && millis() < 360000)) //if the new floor is lower than the last floor, keep angel the servo has moved
{
if(levelflag==3)
myservo.write(angle3);
if(levelflag<3)
levelflag=3;
}
if((gaugepressure<level4 && gaugepressure>level5 && levelflag < 5) || (millis() > 360000 && millis() < 900000)) //if the new floor is lower than the last floor, keep angel the servo has moved
{
if(levelflag==4)
myservo.write(angle4);
if(levelflag<4)
levelflag=4;
}
if((gaugepressure<level5)|| (millis() > 900000 )) //if the new floor is lower than the last floor, keep angel the servo has moved
{
if(levelflag==5)
myservo.write(angle5);
if(levelflag<5)
levelflag=5;
}
(codes from “main_code_5.6_modified servo control with pressure”)

Conclusion: Hopefully, it will work well in the next test that getting a function of pressure and the real altitude.

Friday, September 14, 2012

T-Minus One Week

We are one week out and have been in the lab all day.  We are here now as James and Professor Mason are debugging the program.  It appears as one of the accelerometers has died. 



Last week, the gear that attaches to the servo was machined to allow a recess for the servo arm to seat into. There was also a copper shaft made with a groove cut into it for the snap rings. Both gears also had grooves cut into them to allow an o-ring to be run around them in order to keep them positively seated.

The final design was printed and is installed on the board today.  We decided to bolt the sample container to the board in order to make sure that it does not move during flight.  The o-rings had to be lubed in order for the servo to turn the top.  All of the gears were attached to their components.  The o-ring grooves ended up not being used due to binding of the gears. 

The electrical team got all of the wiring done on the board.  All of the components were then installed on the board.  Additionally, a camera was added to watch to make sure that the servo turns during flight. 

Working on the drill press
 
 
Getting there...
 
 


The final board layout


Today, we were also able to test the whole assembly and everything held.  We put the board on the vibration simulator as the servo test program ran and everything went well.

Vertical testing
 
Horizontal testing
 
As the day/night wore on, we all got tired and so we had Professor Mason on the testing of the on-board camera.  As you can see, or rather hear, it was comical...
 
Testing on-board camera

 

Thursday, September 6, 2012

Wiring Schematics

I've spent a few hours haphazardly using/learning to use by trial and error/watching a couple tutorial videos on Eagle, an electronics CAD program, to make a schematic and PCB diagram for the project.

[Testing] 9-6-12

Today I started to put together the horizontal vibration testing chamber. I used three cans to make this apparatus. I traced and cut an outline out of the first can so that the two can apparatus could fit nicely inside. Then I hot glued the two cans onto the cutout can. Testing will be done tomorrow.

Monday, September 3, 2012

[Mechanical] Revised Design

We learned some things from the initial design and printing.  As mentioned before, we knew we had to reduce the overall size from 1.75" x 1.75" down to 1.25" x 1.25" which has been done.  In addition we added a dual gusset support underneath the sample container to support the weight and any flex in the unit as well as add additional gluing surface area. 

One challenge that we have is that we have been unable to source a 360 degree servo and the current one that we have is only operable to 180 degrees.  One solution for this was to redesign the setup and move away from a direct drive system and toward a geared one.  The new design has the servo attaching to the servo arm as normal but then the arm is inserted and glued to a gear.  The gear will contact a smaller gear (at least 2:1 ratio) that will be connected to the top disk allowing for a full 360 degree turn. 

The black part is the servo with the white servo arm attached.  It is inserted into the semi-transparent gear (shown without teeth).  The yellow part is the top disk and smaller gear (again shown without teeth).  Finally, the red part is the modified base (sample container). 

 
After meeting with the group and discussing the design we realized that we need a way to keep the gear positively connected during the vibrations associated with launch/flight.  We decided that there will need to be a groove cut into the two gears and an o-ring strung around them to keep them from vibrating apart.  This will be reflected in future designs. 
 
Another issue that we are contemplating is whether the rapid prototype printer that we have will be able to handle the printing of the gears.  If not, we will have to source pre-made gears and attach them to the parts that we print.  

Sunday, September 2, 2012

[Mechanical] Initial Structural Testing

This week we were able to use the testing apparatus that Nick E. put together to test whether using hot glue to attach the sample container to the backing plate would hold up during the stresses of the rocket launch. Some of these stresses include up to 50 g during launch and the vibrations from flight. We attached the base, top disk, servo assembly via hot glue to the backing plate and tested it against vibration at 20 Hz, 30 Hz, 40 Hz, 50 Hz, 60 Hz, 70 Hz, 80 Hz, 90 Hz and 100 Hz.

This is the high speed video (210 FPS) of the testing at 50 Hz.

This is the high speed video (210 FPS) of the testing at 100 Hz.



The vibration test was a success. Even with the initial design, which does not include the gussets to support the assembly, the hot glue held the assembly without fail.

The second test that we conducted was to drop-test the unit. We put the entire assembly inside of a container and dropped it from 11 meters. It was able to withstand three drops from 11 meters before failing. Once we have the new design eith gusset printed, we will retest. 

Saturday, September 1, 2012

[Programming] main_code 5.0 Beta SP: Pin-match table

Digital pins:
9: Servo: signal wire
10:SD CARD: CS
11:SD CARD: MOST
12:SD CARD: MISO 
13:SD CARD: CLK

Analog pins:
A0:Accelerometer: L
A1:Accelerometer: H
A2
A3
A4:Pressure Sensor: SDA
A5:Pressure Sensor: SCL

Wednesday, August 29, 2012

[Mechanical] Initial Design Printed

The initial design was printed on the rapid prototype printer. Already, we know that we have some changes to make such as with the dimesions. The 1.75" x 1.75" outside dimensions have to be modified to fit within the 1.25" constraints. The base contains a square outside to allow maximum area for securing to the backing plate. There is a 1/16" o-ring race around the outside and another around the axle shaft. This will allow the compartments to be sealed off. The five compartments allow for four altitude-based samples to be collected and one baseline sample.





The top has a cutout to allow for one open compartment at a time. The servo will rotate the top disk at the desired altitude allowing the aerogel to collect samples. 




This is how the assembly will look put together.


Tuesday, August 28, 2012

[Programming] main_code 5.0 Beta

/* Requires the SD library from the Adafruit website * SD card attached MOSI - pin 11, MISO - pin 12, CLK - pin 13, CS - pin 10*/
#include <SD.h>
#include <Servo.h>
#include "Wire.h"
#include "Adafruit_BMP085.h"
Adafruit_BMP085 bmp;
Servo myservo;  // create servo object to control a servo
const int chipSelect = 10; //??
File dataFile;
//global varibles
long initialPressure=0;
int counter = 0; //counter for flush
int flushRate = 100; //the rate of flush
//long topP;
//int floors;
//long PPerFloor= (topP-initialPressure)/floors;
//------------------------------------------------------------------------------------------- <setup>
void setup(){ 
 
  //>>>>>>>>>>>>>>>> servo setup
  myservo.attach(9); // servo-pin: pin9
 
  //>>>>>>>>>>>>>>>> pressure sensor setup
   bmp.begin();
  
  //>>>>>>>>>>>>>>>> SD card setup
 
  //----------------------------------  [initialize SD card]
  Serial.begin(57600);  // initialize serial communications: 57600
  while (!Serial) { // wait for serial port to connect. (Needed for Leonardo only) 
    ;
  }
  Serial.println("Initializing SD card..."); // (make sure that the default chip select pin is set to output, even if you don't use it)
  pinMode(SS, OUTPUT);   
  if (!SD.begin(chipSelect)) {  // see if the card is present and can be initialized:
    Serial.println("Card failed, or not present");      
    while (1) ; // if card failed, don't do anything more:
  } 
  Serial.println("card initialized sucessfully!");
 
  //-----------------------------------  [search for the last file and create a new file]
  char filename[] = "LOGGER00.TXT";
  for (uint8_t i = 0; i < 100; i++) {  
    filename[6] = i/10 + '0';  
    filename[7] = i%10 + '0';   
    if (! SD.exists(filename)) { // open a new file if it doesn't exist        
      dataFile = SD.open(filename, FILE_WRITE);    
      break;    
    } 
  }  
  if (! dataFile) {  // check if a new file is found
    Serial.println("couldnt create file"); 
  }
 
  //------------------------------------------------------ [the new file is found]
  delay(500);
  Serial.print("Logging to: "); 
  Serial.println(filename);
 
  //>>>>>>>>>>>>>>>>>> pressure sensor setup
  //------------------------------------------------------- [Calibrate pressure]
  Serial.print("Calibrate Pressure: ");
  for (int j = 0 ; j < 10; j++)
  {
    initialPressure += long(bmp.readPressure());
    delay(50);
  }
  initialPressure = initialPressure / 10;  //Average the initial pressure
  Serial.println(initialPressure);
  Serial.println();
  delay(5000);
}


//--------------------------------------------------------------------------------------------  <loop>
String accelRead()//read data from accelerometer
{
  String data = "";
  int a0 = analogRead(0);
  int a1 = analogRead(1);
 
  Serial.print(a0);
  Serial.print(",");
  Serial.print(a1);
 
  data += String(a0);
  data += ",";
  data += String(a1);
 
  return data;
}
String pressureRead()//read data from pressure
{
  String data = "";
  int t=bmp.readTemperature();
  long p=bmp.readPressure();
 
  Serial.println();
  Serial.print("T = ");
  Serial.print(t);
  Serial.println(" *C");
  Serial.print("P = ");
  Serial.print(p);
  Serial.println(" Pa");
  Serial.println();
 
  data += String(t);
  data += ",";
  data += String(p);
 
  return data;
}
int SDwrite(File inputFile, String data, int i) //write data into SD card and flush in certain rate
{
  inputFile.print(data);
  if (i>flushRate)//flush data into SD card. flush rate: 100
  {     
    dataFile.flush(); 
    i = -1; 
  }
  return i+1;
}
int SDwriteNL(File inputFile, int i)
{
  inputFile.println();
  if (i>flushRate)
  {     
    dataFile.flush(); 
    i = -1; 
  }
  return i+1;
}
long moveServoUp(const long bottomP, const long pressurePerFloor, const int movePerFloor, long lastP) // servo move according to altitude
{
  long p=bmp.readPressure();
  int i;
  if(lastP==0)
  {
    lastP=p;
  }
  if(p<lastP)
  {
    i= (bottomP-p)/ pressurePerFloor;
    lastP=p;
  }
  else
  {
    i= (bottomP-lastP)/ pressurePerFloor; 
  }
  if(i<0)
    i=0;
  myservo.write(movePerFloor*i);
 
  Serial.print("Floor: ");
  Serial.println(i);
  //Serial.println(p);
  //Serial.println(lastP);
 
  return lastP;
}
long LP=0; //LP= lastPressure has recorded
void loop()
{
  //----------------------------------- [read and write data]
  SDwrite(dataFile, accelRead(), 0); //less than flushRate forever: save time on calculation
  SDwrite(dataFile, ",", 0);
  SDwrite(dataFile, pressureRead(), 0);
  counter= SDwriteNL(dataFile,counter);
 
  
  //------------------------------------ [servo control]
   LP = moveServoUp(initialPressure, 10, 45, LP);
 
 
  //-------------------------------------- [loop frequence 20Hz]
  delay(50);
}

Friday, August 24, 2012

Rocket Project Update:

Current Progress:

Mechanical Team:  (Jason and Brandon)
  • A design has been completed and an initial prototype has been printed by the Engineering Design Technology department.  An updated design has already been made, but further updates will be made pending assembly of the initial assembly. 
  • Tasks:  Assemble prototype with Servo and Test with electrical team.
Electrical: (Stephen and Ray)
  • BMP085 altimeter is wired.  Dual Accelerometer board is completed. SD card IO is working with prototype board. Servo is wired to prototype board.   Gswitch is tested using a latching relay.
  • Tasks:  Assemble Battery Pack, Wire all parts to soldered protoboard.  Move from arduino protoboard to soldered connections on Arduino Mini.   Integrate Gswitch with package.  Determine overall power budget.
Programming: (James)
  • Code is written to read altimeter and temperature sensor, accelerometers and write data to SD card.  Servo is controlled from code based on altitude. 
  • Tasks:  Write moving average filter for pressure data, do additional calibration for sensors. General code clean up.  Present code to rest of team.
Science: (Michele)
  • Aerogels obtained.  Contacts with Material Science lab made.
  • Tasks:  Deliver aerogels for use in sample container.  Better define science mission.
Testing:  (Nick) 
  • Rotation test apparatus developed.  Status of vibration test apparatus is unknown.  
  • Tasks:  Update status of test equipment.  Test uninstrumented prototype for mechanical failure. 
Funding: (Des)
  • Proposal developed. Paperwork completed and signed.
Tasks:  Present to Student senate.

Oversight:  (Mason)
  • Provide Battery Packs.  
  • Need to decide if current servo is sufficient for needs and obtain other servos
All teams need to contribute status documentation for their area to this blog. (Pictures and text)


Saturday, July 14, 2012

It begins...

This blog will keep a record of the Mt SAC team's rocket launch project. The goal is to send a rocket into low-earth orbit and collect some data as an exercise in combining engineering and scientific research.

  - We will need data storage on the same magnitude of 35kb. An SD card was suggested.

  - We will attempt the use of three button-cell batteries to run our experiment.
  - Brandon and Nick Weiner are using the program solidworks to draw up a digital representation of the containers and structures we will need to build so that we can possibly use 3D printing to create them.
  - Nick E. is assembling a rocket launch simulator for testing the durability of our payload including a mock shell for us to use as the rocket's body (payload holder) in the simulator.
  - Michelle is going to find out the extraction techniques available to us post-mission for extracting the space junk (particles, gas molecules, microorganisms, organic material) we collect.
   - Stephen(team leader) and Kyle are going to research the current draw of the sensors and servo we are using and will be learning to program the arduino.
  - Dr. Mason is going to bring the researched parts to Kyle and Stephen tomorrow so they can start programming right away.