Skip to main content


The software was divided into three main sections: data collection, data processing, and motor processing. When the program starts up main first calls initialize to set up the program. Initialize first sets up the UART to output data to hyperterm. This was useful during testing and to see the data collected. All necessary pins were setup and variables initialized to starting values. If pin D5 is grounded the program goes into a data dump state. Here data is sent to hyperterm and formatted for use in MATLAB. The program then hangs here forever with a very fast blinking LED. If D5 is connected to VCC we assume the rocket is in launch mode and all previous data is erased.

As seen in the state diagram in appendix if we are not data dumping we go into a WAITING state. We use the heartbeat LED to tell us which state we are in. Slow is waiting, medium is flying, and fast is falling. Every 1ms we enter a timer interrupt and every 100ms we get new data from all three 8g accelerometers, and the gyroscope. This is done by using two 8-bit SPI ADC using code modified from Professor Land. This data is then offset via a hardcoded offset obtained from leveling the rocket. Next x and y are converted to the stationary x and y axis via translation of gyroscope angle. This is done using the following equation, where ax and ay are with respect to the stationary axis and x and y are in respect to the rotating axis of the rocket:

ax=x*cos(Θ)-y*cos(90- Θ)
ay=x*sin(Θ)+y*sin(90- Θ)

Sine and cosine are computed via a function that sets theta from 0 to 90 degrees and uses a lookup table stored in flash. This then sets a data ready flag to process the data. All data is then processed via an external function called updateData. This is done because float addition and multiplication take hundreds of cycles so we want to minimize the time in the interrupt. First the acceleration data is converted to ft/s2. Then if we are still waiting for liftoff we check to see if az>0. If so we assume that we have launched and are in the state FLYING since we overcame gravity. If we are not WAITING for liftoff we then integrate acceleration to be velocity, and double integrate to get displacement. This is computed by the verlet algorithm from here:


The data collection storage is stored in EEPROM because of failures to get SD to work correctly. Due to the limited size of EEPROM (1024 bytes), much less data can be stored here. To maximize the amount of data stored we first convert the floats into 12:4 fixed point. This makes each data point only 16 bits instead of 32, thus letting us store approximately twice as much data. Because EEPROM is limited and we cannot store all data collected we only store displacement and a timestamp. This data collection is collected at two different rates. After liftoff we store data at a high rate. Then we store data at a slower rate after a maximum number of samples have been collected. The total number of samples we can store is (1024-8 bytes)/(2bytes*4samples)=127 samples. The other 8 bytes are used to store critical times things happened, such as liftoff, falling, and parachute deployment.

The state machine changes to FALLING when we were flying at one point and the z velocity becomes negative. This is the apogee of the fight. This can only happen after 3.5 seconds since the rocket engines last 3.1 seconds. If the rocket is in the air for more than 7 seconds we then release the parachute anyway. This number is above the calculated estimate for apogee and serves are redundancy if the internal guidance system fails. After this we wait 2 second and pull the lines on the parachute taught. A third redundant system is an external timer that will fire the parachute after 9 seconds.

If we are in state falling and a motor timer expires, we attempted to navigate to where we started. We turn the rocket if the acceleration and displacement vectors are going in the same direction. To attempt to eliminate jerking motions when going in the correct direction, we widen the range of acceptable values. To turn, we pull on one side of the parachute and then release. The stepper motor is controlled via its own state machine as shown in appendix. This state machine was devised from the ECE 476 Wall of Pong project.



The trickiest part of creating the program was testing sections and making them take less clock cycles. Testing was hard because using hyperterm during lab tests adds another cycle intensive process. Many tests were done using static data so that the cycle intensive conversions would not be important. This let us verify that parts of the program worked, such as numeric integration.

There were many failures that caused us to change our design. We could not get many SPI devices to work. We had tried digital accelerometers to reduce error and give us more bits of accuracy. We also tried to use one 8-input, 12 bit ADC. For some unknown reason we were not able to interface with either of these properly. This wasted much time, and in the end we dropped them for sensors that worked. Other hardware failures include using a 3-axis analog accelerometer. This let use us select a max g level for increased senor accuracy and would give us redundant data results for the z axis. In the end we decided to simplify the design and use the same accelerometer on 3-axis.

Due to the computationally intense program, we decided to cut back form 3 gyros with one on each axis to one gyro in the XY plane. With the assumption the rocket did not tilt much we reduced the amount of computation to converted reading to the stationary XYZ axis.