Flight-proven Do-it-yourself Spacecraft

Similar projects worth following
The Rocketometer is a set of MEMS sensors integrated along with a microcontroller and an SD card. One could say that it is a self-contained spacecraft, after the model of such distinguished predecessors as Explorer 1. It has sensors, self-contained power, and a structure capable of withstanding the rigors of launch and spaceflight. It does not have telemetry, but it is recoverable. Therefore, I like to claim that I built my own complete spacecraft.

I proved my claim on 21 October 2013, when the Rocketometer, traveling on board NASA Sounding Rocket 36.290, traveled into space, safely returned, and functioned properly through the whole flight.

One of my long-term projects, or rather dreams, has been to record a trip on the Space Mountain roller coaster in Disneyland, California. Since it is in the dark, it is difficult to get a good idea of what the track path is. I designed a Rollercoasterometer to measure the track with inertial sensors.

The first version, made in 2009, was on a breadboard in a small plastic box. I carried this box in a backpack and successfully measured the forces, but I was not able to analyze the data to the point where I could measure the speed and position of the course. This breadboard version consisted of a Sparkfun Logomatic and several analog MEMS sensors. The Logomatic was used to digitize and record the measurements.

Science Marches On, and after a short while, the sensor manufacturers were packing more and more sensors into smaller and smaller packages. In 2012, the state of the art was to have the ADC built into the sensors, which then reported their measurements digitally over an I2C or SPI bus.

Since the Logomatic is open source hardware, I used it as a jumping-off point for a custom board with an ARM microcontroller, three MEMS sensors, and one magnetic sensor. The high-force accelerometer was analog, so I used an external I2C ADC to convert that measurement.

I designed the board to be small and light enough to fit into the payload compartment of a small model rocket. The final dimensions are 0.9 inches by about 2.4 inches, easily small enough to fit within a 1.1" diameter payload section. This is when it became a Rocketometer in addition to a Rollercoasterometer. This device is much smaller and easier to carry in a pocket, rather than a backpack.

My day job presented an opportunity. I am not a rocket scientist, but I work for some. They actually do science with rockets, both satellite and sounding rocket. I showed them my rollercoasterometer and one of them suggested that I let them fly the rocketometer version on their next flight.

I have worked in the space business since 2003, but one of the odd things about this business is that you can work on these things forever without ever actually seeing or touching them. I had never touched hardware that actually went into space. I changed that by building my own flight hardware. It's primary mission was to travel over 100km altitude, the official boundary of space, and be safely recovered. That was mostly up to the rocket itself. Once recovered, the part would be returned to me for analysis. The hardware itself would be retired and mounted on a plaque. The secondary mission was to function properly during the flight. If it didn't, the primary mission is still fulfilled, since I would have my trophy for my mantel.

As things turned out, the Rocketometer functioned perfectly, on roller coasters (including Space Mountain in Disney World, Florida), in a model rocket (twice) and in the sounding rocket. I finally got around to mounting the device this past Christmas.

  • 1 × Black Brant IX Two-stage sounding rocket capable of carrying a ton of payload to 285km altitude
  • 1 × MPU6050 MEMS 3-axis accelerometer and 3-axis gyro
  • 1 × HMC5338 3-axis magnetometer
  • 1 × ADXL375 Sensors / Acceleration - 3-axis high acceleration analog accelerometer
  • 1 × LPC2148 Microprocessors, Microcontrollers, DSPs / ARM, RISC-Based Microcontrollers

View all 8 components

  • 2015-Apr-24 - Is this a spacecraft?

    kwan321704/05/2017 at 17:13 0 comments

    This is not a pipe. (It is a picture of a pipe)
    Is this a picture of a spacecraft?

    I have discussed my rocketometer project on this blog in depth before. That's it, the purple board in the picture above. I think I can lay claim to it being a full-blown spacecraft.

    • It has structure.
    • It has command/data handling.
    • It has a science payload with multiple instruments.
    • It has independent power - it is charged from the rocket payload, but carries its own battery and is capable of operating for the whole mission from launch through recovery. In fact, it did operate on its own power during entry and descent. From the point of view of the Rocketometer, the external power system is ground support equipment.
    • It is capable of operating in the vacuum and freefall of space. If it were magically transported into orbit, it would operate for at least a little while (it lacks thermal control).
    • It lacks propulsion and recover, but so do many spacecraft.

    The biggest strike against it is that it was bolted inside another spacecraft. How many other systems in the rocket would I count as a spacecraft under this same definition?

    The other biggest strike is that it has no telecom system. I know of spacecraft which have been flown with transmitters but no receivers, but the only spacecraft I can think of that had neither were things like Echo, Lageos, and Starshine. Do those count as spacecraft?

  • 2014-Mar-10 - Rocketometer raw data published

    kwan321704/05/2017 at 17:11 0 comments

    This documents the data produced by the Rocketometer during NASA Sounding Rocket Flight 36.290, 2013 Oct 21.

    I was getting sick of looking at this data, unable to fully process it but holding it jealously. This has to change. The data wants to be free. Get it at

    Encoding format

    The data was captured and encoded in the form of CCSDS packets. The exact structure of each packet is most completely documented in the source code.

    Source code

    The Rocketometer contains an LPC2148 ARM-based MCU with 512kiB flash memory. As this was far more memory than I needed for the firmware, I worked out a way to attach the source code of the firmware as well as the hardware design to the firmware itself. The Rocketometer spits this out into the packet stream as one of the first things it does at startup. How's that for configuration control?

    The source code package is in the form of a ZPAQ TAR archive. The folder includes all the C++ source code, Makefiles, and such for rebuilding the firmware, which will be identical to the firmware carried on the flight with the exception of the date stamp on the firmware.

    The hardware design is in the form of an Eagle CAD board and schematic, editable with the Eagle freeware version (as that is what it was designed with). It also includes a bill of materials in the form of Digikey catalog numbers for all parts used on the board.

    The source code package is attached to the firmware, along with pointers to exactly where in the firmware the package begins and ends. This enables the firmware to copy a piece of itself into the packet stream as multiple CCSDS packets.

    Time Stamp

    The firmware uses one of the MCU counter/timers for timing. This counter is a 32-bit unsigned number which starts at zero during firmware bootup, and counts up to one less than 3.6 billion counts exactly, at which point it resets to zero. The counter nominally runs at 60MHz, so this counter resets once every 60 seconds. Each time-sensitive packet (almost all of them except for some startup packets) have this count in it, and the packets are generated at such a rate that it is possible to unambiguously unwind the counter and get an exact number of counts since startup. Unfortunately the time of startup was not marked in any absolute time scale such as UTC, so absolute timing has to be inferred from timestamped events in the data.

    Sensor data

    The sensor data stream consists of three separate streams of packets:

    1. The Fast packet includes the MPU6050 3-axis acceleration, 3-axis rotation, and temperature readings, along with the ADXL377 3-axis high-acceleration readings. These were read once every 3 milliseconds and timestamped as indicated above.
    2. The Compass packet includes the HMC5883 3-axis magnetic readouts. These were measured at a multiple of the Fast packet period (see the source code for details)
    3. The BMP packet includes the BMP180 pressure and temperature readouts, both raw and calibrated into physical units.
    4. The Power packet stream includes one packet each time the external power state changed (including one at startup).
    5. The Vertical packet stream includes data on the vertical sensing fast/slow packet rate (see the source code for details). I have verified that this worked as intended, and that the entire flight was recorded at the fast rate.

    Packet storage

    Packet storage was on a 16GB microSD card. Less than 1GB was used between the time I delivered the Rocketometer and the time it was returned to me.


    The board consumes something around 100mA, not counting charging. The charger can use and additional 100mA. The system has an internal battery in the form of a 100mAh LiPo cell. The Rocketometer is powered externally by a 5V line from the rocket payload. It charges the battery with its on-board LiPo charging circuit as necessary when external power is available, and runs off the battery when external power is off. The on-board...

    Read more »

  • 2013-Oct-25 - On-board video

    kwan321704/05/2017 at 17:04 0 comments

    This video shows the raw output of the two cameras on the rocket (the forward-looking camera footage is replaced by the more interesting exterior views during the launch) as well as three "instruments". The first one is a clock with a minute and second hand. The second is a velocity and acceleration gauge. The velocity is that reported by the radar data from the flight -- the rocket doesn't carry a GPS, as the range radar is more accurate. The acceleration is that reported by the Rocketometer. It shows 1G while sitting on the ground, even though the velocity is not changing at all, and it shows 0G in space, even though the velocity is changing by almost 1G as the rocket falls back towards the Earth. This is the same acceleration as would be felt by a hypothetical passenger on the rocket. The third instrument shows the flight track, and has an altitude readout. This altitude is again from the radar tracking data.

    The highest acceleration during the boost was just over 12G, while the highest acceleration during the entire flight was during reentry, where the acceleration hit 21G and briefly saturated the low-acc sensor. The high-acc sensor recorded data the whole time, and caught the part of the flight that the low-acc sensor missed.

  • 2013-Oct-23 - Rocketometer flight experience

    kwan321704/05/2017 at 16:58 0 comments

    The Rocketometer flew into space on 21 October 2013, on board NASA sounding rocket 36.290. The following are notes on its performance, including any glitches or other things to be corrected on the next flight


    The Rocketometer performed as designed during the flight. It was able to record inertial readings once every 3ms throughout the flight. I have to look pretty hard to find anything which didn't go according to plan.

    The device was installed with -Z in the direction of powered flight. This was unexpected, but caused no problems. It's a good thing I wrote the vertical test to check for both directions, no Genesis sensor problem for me.

    Card reading

    I tried reading the card in my laptop Natsumi, in Linux mode. In order to insert it there, I put it in a microSD to normal SD adapter, with the write-protect switch on the adapter set to lock. The card failed to read in this mode. I then put the switch in unlock, and initially it didn't read that way either. It seemed like it either just took a long time to mount, or that the video-copying I was doing simultaneously was interfering with it. Anyway, I eventually saw it as /dev/sdc1, started doing a dd dump, and about half way through that, the device automounted and I could copy files normally.


    The magnetometer was able to see the Earth's magnetic field through the skin of the rocket and the various cases and boxes between it and the external field.

    Axis naming

    I had assumed without looking closely that the sensor registers in the HMC5883 were in order, and wrote the code accordingly. Upon getting the data, the "x" and "z" axes were showing spin, when I expected the x and y axes to show the spin around the Z axis. Closer examination of the HMC5883 data sheet shows that the registers are in XZY order, not the expected XYZ. In order to maintain compatibility, the magnetometer packet is now documented to be in XZY order and will not be changed. Code is changed such that it catches the Y and Z axes in the Y and Z variables, in case any on-board systems wish to analyze the data. Any change in the packet to write XYZ ordered data will be done with a new APID.


    The device is capable of readout at 100Hz or more. Design performance was one compass read every 20 inertial reads. Actual performance achieved that, with a read every 60ms, except one sample in every 7 was delayed, only reading after 111ms. This has to do with the fact that the compass and pressure sensor were not in phase with each other. The code as originally designed had a phase variable incremented once every inertial read. It was checked (phase%20==0) for the appropriate phase to fire the compass reading, then checked and reset whenever the pressure sensor was read. This happened at such a rate that effectively every 7th reading was delayed, since the phase got reset at the wrong time.

    Future code will have an independent phase for the compass and pressure sensors, and will read the sensor closer to its capability.

    Hard and soft iron

    The hard iron effect was of such a magnitude that the sensor readout ellipsoid did not even contain the zero vector. The hard iron offset appeared to change in a step on at least one axis during reentry, near 575 seconds after launch. There is significant soft-iron distortion of the ellipse as well.

    Analyzing hard and soft iron is roughly equivalent to finding the center and size of an ellipsoid that fits the measured points. We use the ellipsoid_fit routine which finds the principal axis unit vectors, radii, and center of the best-fit ellipsoid. The center is directly the hard iron distortion in DN. The principal axis unit vectors and radii are used as eigenvalues and eigenvectors, and the matrix which has those eigenproperties is found as follows:




    Read more »

  • 2013-Oct-21 - IT WORKED!!!

    kwan321704/05/2017 at 16:53 0 comments

    I turned the Rocketometer over to the rocket guys back in July, and had no contact with it until after the flight today. It had been exposed to every environment it was going to see except for vacuum, but I still had no confidence that it would work.

    Well, it did.

    The first time I stuck the SD card into my computer after the flight, it said "what card?"

    That was disappointing.

    It took a few minutes for the computer to recognize the card, but when it did, I saw that it had recorded 419 MiB in 66 files. One of the last was also the longest, so I ran it through my quick extraction program, then through IDL, and saw the characteristic acceleration pulse during first and second stage.

    The first thing I did after that was press the Victory button on my phone:

    No one else in the lab either heard that or got it, so I had to shout, "It Worked!!!".Now I have to analyze the data...

  • 2013-Oct-21 - Public Relations

    kwan321704/05/2017 at 16:51 0 comments

    I had worked on sounding rocket flights before (this was the fifth or so flight of this payload) in an official capacity, but this time I was there on my own time and budget. Therefore I took my own car on the long trek to Las Cruces, New Mexico, the nearest civilization to White Sands.

    Even though it was a noon launch, you have to get to the base extra early. I was there around 7:00am, because the safety roadblocks go up about then, and because this is the last time any of us get to actually touch the rocket. A pretty common thing to do is to sign the rocket with a sharpie, and put stickers on it. Unfortunately, I didn't get a chance to sign the rocket (I was a few minutes late) but I did get to put a Rocketometer 1 sticker on the interior of the blockhouse.

    This time, our Principal Investigator (PI, the chief scientist and person most responsible for the mission) made an effort to get many people from the lab to join us at the launch. We had about 15 people that were able to attend, and I, being a veteran of past launches but having no official duties on this flight, was drafted for public relations. As I said, it was a several hour wait from the time people had to show up on site to the time of launch. So, I told stories I had directly experienced, stories I had heard about the base, stories about Range Safety, etc.

    For instance: The launch was at White Sands Missile Range, Complex 36 Athena launcher. This is a complex run by the US Navy, on a US Army base. The mission was sponsored by NASA, so there was plenty of bureaucracy to go around. The Army was in charge of Range Safety, which meant that there was an Army officer somewhere with his hand on a button ready to set off the Flight Termination System (a fancy word for "self-destruct") if needed. This position dates back all the way to 1946, when the Army started flying captured V2 rockets. The range is a long piece of ground, with the launch sites in the south and the intended impact points in the north. One day, they launched a V2 that went off course and started flying south, ultimately crashing in a cemetery in Juarez, Mexico and causing quite an international incident. On that day, the concept of Range Safety was born. Since that day, no rocket launched on any American rocket range has caused any damage or injury to anyone off the range.

    I also talked about the history of Complex 36. It was built by NASA back in the Apollo days, for testing the launch escape system. The whole complex is still like a time capsule of how rocketry was done. I say there is quite a bit of bureaucracy involved in a simple sounding rocket launch, but that is NOTHING like what has to be done to get something into orbit. There is an old saying about how you can't fly until the weight of the paperwork equals the weight of the vehicle. Well, a sounding rocket is a pretty light vehicle, so there is still plenty of opportunity to get hands dirty.

    I kept the crowd entertained with stories, with videos, with talks about sounding rockets in general and our mission in particular, until just before noon when we all went outside (about half a mile away from the launcher) and counted down to launch.

    If you have never seen a rocket launch, you have no idea what one looks like. Pictures don't do it justice. A rocket is bright. If you have seen ten launches, you still don't remember what one looks like. It is brighter than you remember.

    After the launch, we went back inside to listen to the chatter on the voice loops. The main payload worked fine, and the three scientists operating it collected the data they needed in space. After about 10 minutes, the rocket fell back into the atmosphere, slowed from about mach 7 to almost zero in about 20 seconds, then plummeted back to near the ground, when it fired its drogue and then main parachute, bringing it to a soft landing in the desert about 15 minutes after launch.

    About an hour after landing, the Army sent a pair of helicopters out to pick up the payload. Three hours...

    Read more »

  • 2013-Oct-21 - Minimum mission success achieved!

    kwan321704/05/2017 at 15:15 0 comments

    At 12:01:12MDT today, the Rocketometer achieved minimum mission success by riding above 100km and therefore reaching space.

    It will be some time yet before I can recover the device to see that it worked, which will represent full mission success.

    This was sent from my phone on the day of the flight, at 2:56pm (about 3 hours after the flight, which launched at 12:00 noon). That's why it is so short.

  • 2013-Oct-12 - The Curiously Recurring Template Pattern

    kwan321704/05/2017 at 13:21 0 comments

    Go look up on Wikipedia what it is. I am going to talk about how I am having to use it.

    I was doing fine with the Rocketometer analysis code in C++, using the NewMat library to handle matrices, with a Quaternion layer on top that I wrote myself. After five days of doing battle with various things, I finally got something that worked, but I was curious if this was the "best" way to do it. The C++ Standard Template Library didn't have anything directly related to matrices. The Boost library had a section called uBLAS, but the documentation for it kind of de-recommended itself. It suggested several alternatives, and the one that looked best is called Eigen.

    Eigen is interesting in that it is entirely header files, containing almost all of its code in C++ templates. Templates are cool, mostly because when they are instantiated, the compiler gets to see the code in the context that it is used, and gets to inline and optimize it there. Specifically, Eigen contains a dynamic-sized matrix, but also is a template for fixed-sized vectors and matrices. I want to use these as much as possible because all vector sizes used in Rocketometer data analysis are known at compile-time, so the compiler can unroll loops and so on to best optimize the code.

    However, templates do not mix with virtual methods, so I had to figure out how to make that work, since I used virtual methods to implement the physics model. I had code that looks like this with NewMat:

    class SimModel {
      /** Physics function. Calculates the derivative of the state with respect to time */
      virtual ColumnVector fd_only(double t, const ColumnVector& x)=0;
      /** Measurement function. Calculates the measurement from the given state and time */
      virtual ColumnVector g_only (double t, const ColumnVector& x, int k)=0;
      /** Physics function with process noise. Uses fd virtual function to calculate physics, then adds process noise.*/
      ColumnVector fd(double t, const ColumnVector& x, const ColumnVector* v);
      /** Measurement function with measurement noise. Uses g virtual
      function to calculate measurement, then adds measurement noise. */
      ColumnVector g (double t, const ColumnVector& x, int k, 
        const ColumnVector* w) {
        ColumnVector result=g_only(t,x,k);
        return result;

    But I wanted to adapt that to use Eigen, specifically with the fixed-length vectors, since the size of the state vector is determined by the problem and known at compile time. That means that ColumnVector has to go, to be replaced by Matrix<double,n,1> where n is a template parameter determining the size of the state vector. But what about the measurement? The purpose of the k parameter to g_only is to tell which of several kinds of measurements to use. For instance, in the Rocketometer problem, we have a measurement vector coming from the inertial and magnetic sensors, treated as a single 9-element vector. We also have measurements coming from radar or equivalent, treated as a 3-element vector. So, we need a template function g_only, which generates either a 9-element vector or a 3-element vector. You can't do that and have it be virtual, too. Basically, virtual functions are a runtime binding issue, while templates are a compile-time binding. So, I can't have a virtual g_only function, callable by the base class g function.

    Enter the Curiously Repeating Template Pattern (CRTP). As it happens, this is something that I read about just a few days ago, just reading up on the C++ language in general. For us, the pattern goes something like this:

    template<int n, class Derived> class SimModel {
      template<int m> Matrix<double,m,1> g (double t, const Matrix<double,n,1>& x, int k, const Matrix<double,m,1>* w) {
         Matrix<double,m,1> result=static_cast<Derived*>(this)->template g_only<m>(t,x,k); if(w)result+=*w;
         return result;

    Note that g_only isn't even defined in this class template, only used....

    Read more »

  • 2013-Oct-10 - Calibration

    kwan321704/05/2017 at 13:11 0 comments

    It's kinda weird, but it turns out that C++ is the best language for processing Rocketometer data. There is a cool library NewMat which creates appropriate operator overloads to do matrices in C++, and I have extended it to include quaternions. C++ was doing in minutes what it was taking IDL hours. However, it took me 5 days to translate from IDL to C++, so I had better process a lot of data to ever get that time back.

    The time that the Rocketometer spends in zero gravity may be the most valuable calibration time I ever get. Zero acceleration, zero rotation, and I expect a wide range of temperatures.

    Remember that the goal of this is to get something into space, but that goal requires no further effort on my part to achieve. The secondary goal is to be able to calibrate the data and report something useful to Tom. The long-term goal though is to measure the track of Space Mountain.

    So I am putting something in Space to get it ready for a roller coaster.

    That made me laugh.

  • 2013-Jul-31 - Rocketometer has been integrated

    kwan321704/05/2017 at 12:56 0 comments

    The rocketometer is now an integral part of the rocket payload. It is mechanically attached to the CCD heater card, a part of the payload which is the real purpose for this flight. It has power and ground connections to charge the battery, but power is only available for the first 9 minutes of the 15-minute flight, which doesn't even include reentry, the most dynamically interesting part of the flight -- so, the LiPo battery cell is there charging from the power input, but powering the board itself when the external power goes out. That is what makes the Rocketometer an independent spacecraft, even though it is physically bolted to another spacecraft.

    Attached to the CCD heater card
    In the control section card cage

    And here we have a short video demonstrating the size of the Rocketometer:

View all 26 project logs

Enjoy this project?



visualkev wrote 04/06/2017 at 14:39 point

I am looking for a sensor payload for my model rocket. Do you plan to share your project's pcb artwork, circuit design and calibration steps to the community?

  Are you sure? yes | no

kwan3217 wrote 04/06/2017 at 15:32 point

Yes on circuit design. I didn't really document my calibration steps that well.

In fact, the design is already hidden in the published source code. Look in this folder: .

Rockteometer.brd and Rocketometer.sch are the Eagle board and schematic, and is a bill of materials ready to be pasted into the Digikey BOM tool.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates