Ordering parts and planning the build (7)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

After spending a couple of weeks strategizing about the build and the tech to go into it my friends invited me and my wife to come visit them in Michigan for the 4th of July. Since we live in a big city there aren’t a lot of open spaces where you can perform a launch without having to worry about trees, power lines, and population, so I thought this would be a great chance to get in a few launches and collect some telemetry data that I can use to plan further iterations. The only problem: I had no rocket.

With only 10 days before we left on our trip I needed to order all of the parts, receive them, assemble them, and hope everything dries in time to be able to pack it all up for the road.

I had already been looking at Apogee for inspiration on body designs and what kinds of materials are commonly used. Normally I might stray from the more expensive specialized retailers and try to buy the raw materials from cheaper businesses, but with the time crunch I figured I could streamline the process by purchasing all parts that were designed to work together.

I settled on the Estes BT-60 (Body Tube #60, 41.6mm) for a few reasons. It was large enough to fit the camera payload and telemetry electronics without being so large it would be too heavy or experience too much aerodynamic drag. Apogee had a clear payload tube, fiberglass engine compartment, nose cones and other components in this size. It was also very close to the diameter that I had already used in my computer modeling, so I could easily adjust the digital models to be accurate to the real build without too much re-working.

In total, there are just over a dozen body components that I needed, and some other tools and supplies that I used to assemble it. Here’s what I went with:

I probably could have done well to order a fin jig like the one they sell on Apogee, and perhaps some vice grips as well, but I had a deadline and I was just going to go for it! Unfortunately USPS delayed my order by a couple of days, but I did receive everything just with enough time that some late nights made up the difference.

In my next post I will show you how I put it all together, as we get closer to our first launch day!

Achieving Stable Aerodynamic Flight (6)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

Since I started working on this project I’ve had a lot of fun learning about aerodynamics. It’s something that only really matters once you put the parts together, but planning for an aerodynamically rocket is critical for success. There are a TON of great resources to help you learn about the science of aerodynamics. I’m going to include the videos that I found the most informative in here to help me illustrate the concepts that we will need to understand. After we cover the basics, I will show you how we can apply the concepts to our own designs using a rocket simulator as we plan to build the exact vehicle we need.

Basics of Aerodynamic Stability

Before we get started, we should establish the axes of a rocket, so we have a common understanding. The Z axis runs from the tip of the rocket to the tail, and then the X and Y axes run from side to side, sometimes in line with the fins (on a 4-fin model).

The three most important concepts in aerodynamics are the Center of Gravity, Center of Thrust, and Center of Pressure.

Center of Gravity is the point where the weight is evenly distributed on any axis you choose. This will change slightly over time as fuel is burned, which is something to consider in larger rockets with massive fuel tanks, but in smaller model rockets losing mass in the tail will only work to your benefit. On the Y and Z axes you want the CoG to be as close to the origin as possible. Moving the CoG along the Z axis will be how we achieve stability.

Center of Thrust is where the force of the motor(s) or thruster(s) is applied. You can change this using Thrust Vectoring or RCS thrusters to change the trajectory of the rocket. Typically your center of thrust will be at the rear, and optimally the direction of thrust is perfectly aligned with the X axis.

Center of Pressure is the center of the force applied on the body by the air flowing over it. This can be very dynamic, and there are a lot of ways to determine the CoP, some of which will be covered in this video.

Essentially the goal is to align the Center of Thrust with the X axis perfectly, then arrange the rocket body and payload in such a way that the CoG and CoP are at the origin of the Y and Z axes, and the CoG is forward of the CoP. This way, as the rocket flies the pressure forces acting on it will keep it pointing straight. This is usually achieved by adding fins toward the base of the rocket, which move the CoP backwards by giving added surface area to the body.

Unlike with engines (😂), bigger fins aren’t always better. There is a phenomena called Wind Cocking, which is caused when wind blowing along the Y or Z axes exerts more force on the tail of the rocket than the nose, tipping the body, and causing the engine to push the rocket into the wind. To avoid this you want to try to keep your fin size and shape just large enough to provide stability, but not much larger. Here’s a great video about estimating CoG and CoP, and properly balancing your rocket body so it is aerodynamically stable.

Rocket Stability – LabRat Scientific

Software Modeling for Aerodynamic Stability

Now that we understand how aerodynamic flight works, let’s talk about simulating the design. As I mentioned before, I have been using OpenRocket to do all of my virtual modeling so far. OpenRocket is a Java app, so you can run it on any computer, and it has some pretty simple components you can add and customize to suit your design goals.

For the first version of my rocket I had already done some shopping for parts, and settled on a clear payload bay for the 360º camera, a fiberglass engine compartment, and a pre-fabricated ogive nose cone. The fins that I used were made of balsa as well. With most of these components pre-determined, the two biggest variables would be payload placement/weight and fin size/shape.

As we discussed earlier the payload and engine weight and placement will both dramatically change the center of gravity. For the rocket’s maiden voyage I didn’t want to send up the camera, which only left the telemetry package, a mere total of about 60-80 grams, in the front and a large heavy motor in the back. This meant that the fins would have to be somewhat larger, to pull the center of pressure further back.

In the image below you can see what the rocket’s properties would be like with the motor I anticipated using and just the telemetry in the payload bay. I trimmed the tips of the fins to reduce the stability so the rocket would fly better if we encountered wind. Realistically, though, this was still a lot of fin in the face of any wind.

Version 1.0 digital model with an empty payload bay

When I add the 360º camera then the stability goes way up. This would result in a lot of wind-cocking, since the inertia of the heavy payload bay would exaggerate the tipping. This was about as far as I could trim the fins and still have a stable empty flight, though, so it would have to work.

Version 1.0 digital model with camera onboard

One of my favorite features of RocketSim is the ability to plot the model of the flight. There are a few considerations to remember here. The rocket takes off under power, and flies under power for a total of 3.5 seconds. After the motor burns out the rocket is in ballistic flight for about 6 seconds (the current model uses a 6-second delay) after which a charge detonates separating the engine compartment from the payload bay and ejecting the parachute. From this point the vehicle should gently descend back to the earth at a steady rate of ~-10m/s.

Plot of simulation altitude, vertical velocity, and vertical acceleration vs time

You can even adjust parameters like recovery chute delay and launch rod angle to accommodate for windy conditions and predict how far the vehicle will travel from the launchpad.

Plot of simulation altitude vs position

This last plot I found really informative, which shows stability over time. Note the first second or so, where stability is most critical. You don’t want the rocket to be unstable when it leaves the launch rod, because it may tip, and without enough wind passing over the fins it won’t correct itself, and may fly off uncontrollably.

Plot of simulation stability vs time

Finally, I’ll leave you with a couple of videos that I really enjoyed. The first one is very informative about rocketry on many levels, and the other illustrates how active aerodynamic controls works in the context of the F-22 fighter jet. In my next post, I will discuss parts, and the strategy I used that allowed me to assemble the rocket in just a couple of days.

Radio Telemetry – Connecting it all together (5)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

Now that we know we will be using the Arduino Nano 33 BLE Sense and (for the sake of demonstration) the HC-12 RF module, let’s go ahead and put the software and hardware together. I’ll try to go into as much detail here as possible, and cover many of the issues I had, but there’s a lot, so bear with me. For all of the schematics I use Fritzing and I currently still write all of my code in the free Arduino IDE.

Sending sensor data over serial

First we can start with just reading as many of the sensors as we’d like to from the Arduino Nano and writing their values to the USB connection’s serial port. I load this particular sketch quite frequently when I’m checking the functionality of the board or the computer’s telemetry software (which we will cover later). This isn’t some beautiful perfectly written code, but it works just fine.

// Start with the includes
#include <Arduino_LSM9DS1.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_HTS221.h>
#include <Arduino_APDS9960.h>

// These variables will be used to store the sensor values on each cycle
float ax;
float ay;
float az;
float cx;
float cy;
float cz;
float gx;
float gy;
float gz;
float pressure;
float temperature;
float humidity;
float prox;

unsigned long timer = millis();                 // Delay Timer

const int redPin = 22;
const int greenPin = 23;
const int bluePin = 24;
boolean flash = false;
const int statusColor = redPin;
boolean err = false;


void setup() {
  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT);
  pinMode(24, OUTPUT);
  digitalWrite(redPin, LOW); // Red on while we initialize
  delay(500);
  Serial.begin(9600);

  // These conditional statements give me feedback on Serial and with the LED
  if (!IMU.begin()) {
    Serial.println("Error initializing IMU sensor!");
    err = true;
  }
  if (!BARO.begin()) {
    Serial.println("Error initializing BARO sensor!");
    err = true;
  }
  if (!HTS.begin()) {
    Serial.println("Error initializing HTS sensor!");
    err = true;
  }
  if (!APDS.begin()) {
    Serial.println("Error initializing APDS sensor!");
    err = true;
  }
  digitalWrite(greenPin, LOW);
  if (!err) {
    digitalWrite(redPin, HIGH);
  }
}

void loop() {
  flash = !flash; // Alternating the LED is useful for visually checking cycle time
  digitalWrite(greenPin, flash); // green
  if (err) {
    digitalWrite(redPin, flash);
  }

  // Now we will read all of the sensors and write their values to the variables from before
  IMU.readAcceleration(ax, ay, az);
  IMU.readMagneticField(cx, cy, cz);
  IMU.readGyroscope(gx, gy, gz);
  pressure = BARO.readPressure();
  temperature = HTS.readTemperature();
  humidity = HTS.readHumidity();

  // Now we will print out a line of text over serial with each valuee separated by spaces
  Serial.print(millis());
  Serial.print(" ");
  Serial.print(pressure);
  Serial.print(" ");
  Serial.print(temperature);
  Serial.print(" ");
  Serial.print(humidity);
  Serial.print(" ");
  Serial.print(ax);
  Serial.print(" ");
  Serial.print(ay);
  Serial.print(" ");
  Serial.print(az);
  Serial.print(" ");
  Serial.print(cx);
  Serial.print(" ");
  Serial.print(cy);
  Serial.print(" ");
  Serial.print(cz);
  Serial.print(" ");
  Serial.print(gx);
  Serial.print(" ");
  Serial.print(gy);
  Serial.print(" ");
  Serial.println(gz);
}

If you want to see the output from this, while you’re in the Arduino editor, you can select the appropriate port in Tools > Port, and then view the output with Tools > Serial Monitor or as a graph in Tools > Serial plotter. Keep in mind that serial plotter will automatically pick up on the available values, plot them, and resize the screen to fit them. Because of this, the millis() function that I am using to track the delta-time will cause the screen to resize rapidly as the value increases, relegating the other values to appearing like straight lines with minuscule deviations. If you want a better plot then just comment out the Serial.print(millis()); line.

Your output will come out looking something like this if you’re really agitating the IMU. You can do a moving average if you’d rather have smoother curves (like in this picture) and you can even apply some kind of coefficient to normalize the values (in this example the denominator used in the moving average calculation).

If you’re not able to see the output from the Serial.print() statements, make sure that the “baud” in the bottom left of Serial Monitor or Serial Plotter matches the number from the Serial.begin() line.

Serial Plotter showing IMU data from the Arduino

I was back and forth about normalizing the IMU data, but I ultimately decided against it for a couple of reasons. First, if you are trying to make decisions based on sensor data, there’s no reason to water down the readings. I will eventually need to add some logic in to make decisions based on values over time, etc., but normalization doesn’t solve this problem.

The second reason is because while normalization does smooth out the graph beautifully, it also makes the readings lag behind by a significant amount. Timeliness matters when making automated in-flight decisions, so it’s better to let the flight computer have the raw values and then figure out how to handle them on its own.

Making the Transmitter

When it comes to wiring the HC-12 to the Arduino that we will be using as the telemetry computer, it’s pretty straightforward. I know that there are some great things you can do to make the circuits safer and more reliable, but I already told you this is not the place for that. You can easily connect the two devices pin-for-pin and it will work just fine. Here’s a handy chart of the pin names for your reference moving forward:

The Arduino has two different serial channels on it, which we will take advantage of here. There is a separate Serial1 channel with its own hardware TX and RX pins. Since radios use serial communications, we can use these to connect to the HC-12, which really simplifies the configuration.

Wireless telemetry transmitter wiring diagram

First, you will want a 9v battery connector. This can be accomplished by connecting the negative terminal to the ground, and the positive terminal to the VIN pin. You can power the Arduino in various ways, but some of them will only result in the 3V3 power output working. Using a 9V battery on the VIN will power the 5V power output, which is the voltage you need for optimum performance of the HC-12.

Next, to connect the HC-12, there are five wires that connect to the Arduino:

  1. The first two are the GND (black) and VCC (red), which make a complete circuit so electricity can flow between the two devices, powering the HC-12.
  2. Then connect the SET pin (Orange) on the HC-12 to digital out #2 on the Arduino. This pin will be defined in the software, and will be used to put the HC-12 into configuration mode so we can set channel number, TX strength, etc. We won’t use this pin, but it’s good to wire it up in case we need it.
  3. The TXD pin on the HC-12 connects to the RX pin on the Arduino (green) and the RXD pin on the HC-12 connects to the TX pin on the Arduino (Yellow). The reason for the flip-flop is because the labelling refers to the function in the context of the local device. You want the data to flow from a transmitting pin to a receiving pin, otherwise it wouldn’t be read.

Finally we connect the antenna. The HC-12 comes with small coil antennas that work just fine for shorter range applications, but you can pick up a couple of high gain antennas for $12 that will greatly improve your signal strength and quality.

3dbi high-gain antennas from Amazon

Programming the Transmitter

Now that the transmitting device is connected, we need to update our Arduino sketch from before with the code needed to operate the radio. Remember when I said before that the Nano has a built-in hardware Serial1. Technically it’s as simple as changing the Serial.print() statements to Serial1.print(). I’ll show you some more features of the HC-12 in a moment, but here’s a functioning copy of the remote telemetry code:

// Start with the includes
#include <Arduino_LSM9DS1.h>
#include <Arduino_LPS22HB.h>
#include <Arduino_HTS221.h>
#include <Arduino_APDS9960.h>

// These variables will be used to store the sensor values on each cycle
float ax;
float ay;
float az;
float cx;
float cy;
float cz;
float gx;
float gy;
float gz;
float pressure;
float temperature;
float humidity;
float prox;

unsigned long timer = millis();                 // Delay Timer

const int redPin = 22;
const int greenPin = 23;
const int bluePin = 24;
boolean flash = false;
const int statusColor = redPin;
boolean err = false;


void setup() {
  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT);
  pinMode(24, OUTPUT);
  digitalWrite(redPin, LOW); // Red on while we initialize
  delay(500);
  Serial1.begin(9600);

  // These conditional statements give me feedback on Serial1 and with the LED
  if (!IMU.begin()) {
    Serial1.println("Error initializing IMU sensor!");
    err = true;
  }
  if (!BARO.begin()) {
    Serial1.println("Error initializing BARO sensor!");
    err = true;
  }
  if (!HTS.begin()) {
    Serial1.println("Error initializing HTS sensor!");
    err = true;
  }
  if (!APDS.begin()) {
    Serial1.println("Error initializing APDS sensor!");
    err = true;
  }
  digitalWrite(greenPin, LOW);
  if (!err) {
    digitalWrite(redPin, HIGH);
  }
}

void loop() {
  flash = !flash; // Alternating the LED is useful for visually checking cycle time
  digitalWrite(greenPin, flash); // green
  if (err) {
    digitalWrite(redPin, flash);
  }

  // Now we will read all of the sensors and write their values to the variables from before
  IMU.readAcceleration(ax, ay, az);
  IMU.readMagneticField(cx, cy, cz);
  IMU.readGyroscope(gx, gy, gz);
  pressure = BARO.readPressure();
  temperature = HTS.readTemperature();
  humidity = HTS.readHumidity();

  // Now we will print out a line of text over serial with each value separated by spaces
  Serial1.print(millis());
  Serial1.print(" ");
  Serial1.print(pressure);
  Serial1.print(" ");
  Serial1.print(temperature);
  Serial1.print(" ");
  Serial1.print(humidity);
  Serial1.print(" ");
  Serial1.print(ax);
  Serial1.print(" ");
  Serial1.print(ay);
  Serial1.print(" ");
  Serial1.print(az);
  Serial1.print(" ");
  Serial1.print(cx);
  Serial1.print(" ");
  Serial1.print(cy);
  Serial1.print(" ");
  Serial1.print(cz);
  Serial1.print(" ");
  Serial1.print(gx);
  Serial1.print(" ");
  Serial1.print(gy);
  Serial1.print(" ");
  Serial1.println(gz);
}

When I was experimenting I noticed that the status light was flashing slower and slower with each new feature I was adding. This was of course to be expected because each line of code causes the loop to take longer to process, but I was not anticipating it to be so noticeable. After some experimentation I found that the biggest culprit was reading the humidity sensor. Since this was not essential for telemetry, and was more for curiosity, I eventually removed the humidity sensor from the equation.

One huge realization I had during this process was that since the Arduino could not handle parallel tasks, if I want to use the Arduino as the flight controller I’m going to have to really strip the components down to the essentials. If I still want to monitor

Making the Receiver

Now it’s time to wire up the second Arduino (the Uno) so it can act as the data receiver, and relay the data to the computer over the USB connection. There are some pre-built 433MHz serial data receivers, but where’s the fun in that??

Wiring diagram for the Arduino Uno and HC-12 telemetry receiver

Since we will be using the USB connection from the computer, this one is much simpler, but we will also be limited in the amount of voltage we can supply. Using the 3.3V output that we are limited to from the computer won’t be as much of a problem since we won’t be transmitting from this device, just receiving. To connect the HC-12 is just like before with one minor variation for the serial ports.

  1. The first two are the GND (black) and VCC (red), which make a complete circuit so electricity can flow between the two devices, powering the HC-12.
  2. Then connect the SET pin (Orange) on the HC-12 to pin #4 on the Arduino. This pin will be defined in the software, and will be used to put the HC-12 into configuration mode so we can set channel number, TX strength, etc. Since this device will be connected to the computer, we will probably use the SET pin at some point.
  3. This time we will do something completely different with the TX and RX pins. The Arduino Uno has a library called Software Serial that will allow us to define a serial channel without having to use the onboard pins. Because of this, the TXD pin on the HC-12 connects to pin 5 on the Arduino (green) and the RXD pin on the HC-12 connects to pin 6 on the Arduino (Yellow).

Once again we connect the antenna the same way as before. I picked up a plastic Arduino Uno project box that just snaps around it, but I had to drill a hole in the plastic to be able to mount the antenna. All in all I was pretty satisfied with the outcome:

The receiver inside its project box

Programming the Receiver

The Arduino sketch for the receiver is pretty simple. The basic goal is to take the output from the HC-12 radio and reprint it to the USB Serial output so the computer can process it. The HC-12 is connected to ports 5 and 6 which will be assigned to SoftwareSerial with the statement SoftwareSerial HC12().

Since the receiver is connected to the computer, we are going to add some functionality that will allow us to configure it if we need to. There’s an amazing post by Mark Hughes that covers the HC-12 system in detail, including how to use the set pin. Practically all of the sketch for the receiver came from this post (I even left in the comments for you since he did such a great job), and I spent hours just messing around with the radios to understand them well enough to feel comfortable trusting them in my rocket.

#include <SoftwareSerial.h>

const byte HC12RxdPin = 6;                      // "RXD" Pin on HC12
const byte HC12TxdPin = 5;                      // "TXD" Pin on HC12
const byte HC12SetPin = 4;                      // "SET" Pin on HC12

unsigned long timer = millis();                 // Delay Timer

char SerialByteIn;                              // Temporary variable
char HC12ByteIn;                                // Temporary variable
String HC12ReadBuffer = "";                     // Read/Write Buffer 1 for HC12
String SerialReadBuffer = "";                   // Read/Write Buffer 2 for Serial
boolean SerialEnd = false;                      // Flag to indicate End of Serial String
boolean HC12End = false;                        // Flag to indiacte End of HC12 String
boolean commandMode = false;                    // Send AT commands

// Software Serial ports Rx and Tx are opposite the HC12 Rx and Tx
// Create Software Serial Port for HC12
SoftwareSerial HC12(HC12TxdPin, HC12RxdPin);

void setup() {

  HC12ReadBuffer.reserve(64);                   // Reserve 64 bytes for Serial message input
  SerialReadBuffer.reserve(64);                 // Reserve 64 bytes for HC12 message input

  pinMode(HC12SetPin, OUTPUT);                  // Output High for Transparent / Low for Command
  digitalWrite(HC12SetPin, HIGH);               // Enter Transparent mode
  delay(80);                                    // 80 ms delay before operation per datasheet
  Serial.begin(9600);                           // Open serial port to computer
  HC12.begin(9600);                             // Open software serial port to HC12
}

void loop() {

  while (HC12.available()) {                    // While Arduino's HC12 soft serial rx buffer has data
    HC12ByteIn = HC12.read();                   // Store each character from rx buffer in byteIn
    HC12ReadBuffer += char(HC12ByteIn);         // Write each character of byteIn to HC12ReadBuffer
    if (HC12ByteIn == '\n') {                   // At the end of the line
      HC12End = true;                           // Set HC12End flag to true
    }
  }

  while (Serial.available()) {                  // If Arduino's computer rx buffer has data
    SerialByteIn = Serial.read();               // Store each character in byteIn
    SerialReadBuffer += char(SerialByteIn);     // Write each character of byteIn to SerialReadBuffer
    if (SerialByteIn == '\n') {                 // Check to see if at the end of the line
      SerialEnd = true;                         // Set SerialEnd flag to indicate end of line
    }
  }

  if (SerialEnd) {                              // Check to see if SerialEnd flag is true

    if (SerialReadBuffer.startsWith("AT")) {    // Has a command been sent from local computer
      HC12.print(SerialReadBuffer);             // Send local command to remote HC12 before changing settings
      delay(100);                               //
      digitalWrite(HC12SetPin, LOW);            // Enter command mode
      delay(100);                               // Allow chip time to enter command mode
      Serial.print(SerialReadBuffer);           // Echo command to serial
      HC12.print(SerialReadBuffer);             // Send command to local HC12
      delay(500);                               // Wait 0.5s for a response
      digitalWrite(HC12SetPin, HIGH);           // Exit command / enter transparent mode
      delay(100);                               // Delay before proceeding
    } else {
      HC12.print(SerialReadBuffer);             // Transmit non-command message
    }
    SerialReadBuffer = "";                      // Clear SerialReadBuffer
    SerialEnd = false;                          // Reset serial end of line flag
  }

  if (HC12End) {                                // If HC12End flag is true
    if (HC12ReadBuffer.startsWith("AT")) {      // Check to see if a command is received from remote
      digitalWrite(HC12SetPin, LOW);            // Enter command mode
      delay(100);                               // Delay before sending command
      Serial.print(SerialReadBuffer);           // Echo command to serial.
      HC12.print(HC12ReadBuffer);               // Write command to local HC12
      delay(500);                               // Wait 0.5 s for reply
      digitalWrite(HC12SetPin, HIGH);           // Exit command / enter transparent mode
      delay(100);                               // Delay before proceeding
      HC12.println("Remote Command Executed");  // Acknowledge execution
    } else {
      Serial.print(HC12ReadBuffer);             // Send message to screen
    }
    HC12ReadBuffer = "";                        // Empty buffer
    HC12End = false;                            // Reset flag
  }
}

Note how the HC12SetPin is brought low in order to execute AT commands. This comes in really handy when troubleshooting, because you can then just send “AT” across the Serial Monitor, and it will tell you the status of the system. I’m not sure if all of the delays are really necessary, but I feel like he knows a lot more about this than I do, so I’ll just leave it as-is.

If you need to configure the radio on the onboard telemetry transmitter you can always repurposes the above sketch to work with the Nano. Just remember the pins are different, and there will be no SoftwareSerial.

If you want a reference guide for the HC-12 component you can check out the datasheet, which clearly describes all of the AT codes, functions and limitations of the system. As a general rule, you will be able to find datasheets for almost every component you will use in projects like this, including the individual components on the Arduino, such as the IMU. I’ll show you how to edit the drivers using information in the datasheet to get more functionality from your onboard SoC’s in a later post.

Radio Telemetry – Choosing the right wireless transceiver (4)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

Enough about imaginary fuselages and prototyping boards with everything built in, LET’S BUILD SOMETHING!

In my last post we proved that the Arduino Nano 33 BLE Sense had all of the skills necessary to track attitude and some movement, but how do we get this information to the computer for analysis?

There’s a great video from BPS.space that includes a segment about all kinds of ways to transmit and save telemetry data, and I definitely should have watched this before my first flight. It boils down to two different options – onboard storage and wireless transmission.

With onboard storage you can use an SD card writer such as the ADA254 or a flash module such as this one from Amazon. The basic idea is that the builtin memory on the Arduino Nano erases itself every time the system is rebooted to make room for the new data the program will have to process. If we want to store the data more permanently then we would have to add that capability ourselves.

Both of these add-ons use the I2C communication built into the Arduino platform, so we can add as many as we would like, but there are benefits and drawbacks to each. An SD card writer would allow us to write the data to a removable card that we can plug into just about any smartphone or read with an SD card reader on almost any computer. The downside is this storage can sometimes be a little slower to write or read, and because the card is mechanically connected to the pins on the writer with pressure from the bracket, it might not withstand the stresses of rocket flight well, potentially resulting in data loss or a lost SD card.

The flash memory add-on is a great option because it can be faster to write to, and doesn’t have the mechanical weaknesses of the SD card, but the major drawback is that you can only retrieve the data by plugging the flight computer into the USB port on your main computer to download the data.

Both of these are inconvenient as primary data transmission methods because neither provide realtime data monitoring. Also, if the rocket flight ends in rapid unscheduled disassembly or a vertically premature arboreal landing, the data is gone for good. More on what I’ll call RUD and VPAL later.

All of these systems are small and lightweight, so we don’t have to worry about payload limits, but I’d really only be interested in onboard storage as a backup, in case wireless telemetry cut out mid-flight. My primary telemetry option needs to be wireless.

In order to achieve wireless communications you typically want to use Radio Frequency communications, which simply means that it’s sending the signal using Electromagnetic waves. One alternative would be light, like the infrared diode and sensor used for television remotes. This isn’t very effective on bright sunny days, though, and can be interrupted by visually opaque interference, such as rocket exhaust.

Another RF alternative would be sound, but the frequency is too low to be able to fit a reasonable amount of data in the signal, and it travels through the air too slowly (our rocket could reach 0.8x the speed of sound). Also rocket launches are audibly noisy, which makes for an all around poor environment for audio communications.

Luckily there are quite a few available RF options for the Arduino. The Arduino Nano 33 BLE Sense even has a built in Bluetooth LE SoC (System on a Chip). Bluetooth LE is a great technology for close-range wireless communications, and it would offer some cool smartphone integrations, but at 100m max range it’s just not strong enough for a rocket that’s built for 1km flight. This limitation also rules out any WiFi options.

The main reason why WiFi and BLE are poor options is because they use higher frequencies to transmit more data at a time. The tradeoff with higher frequencies is that it requires more input power to generate the same amplitude of electromagnetic wave. Since our telemetry system will just be powered by a typical 9v battery, we need a lower frequency radio to be able to transmit further without requiring more power than the battery can supply.

Another design consideration in the US is which frequencies we are legally able to transmit on. Luckily most of the devices that we can purchase online are pre-approved by the FCC and don’t require licenses to operate, but you always want to be careful and make sure you choose a frequency that won’t interfere with important uses such as emergency services, aircraft operation, or life-sustaining medical devices.

US Radio Spectrum Frequency Allocation Chart

The massive chart above shows all of the frequency allocations in the US. Needless to say it’s probably just easier to google search the frequencies you would like to use and read what people are posting about them than to try to figure out licensing from a chart like this.

Installing the HC-12 RF Transciever on the Arduino Nano

I started out building with the HC-12 RF chip, which uses the 433MHz band. These chips are great because they’re tiny, cheap, low power and the low frequency gives them a longer range for less power input. The (massive) downside is that transmitting legally on the 433MHz band requires a HAM (amateur radio operator) license. I don’t have one of these, I don’t want fines, and it will take me a few weeks at least to study and take the test.

I was able to find an alternative 2.4Ghz chip that is somewhat larger with a more limited range, but since my first flights will not be very high power, I probably don’t need the full 1Km range yet anyway.

When you’re prototyping electronics you’re going to need to plug and unplug wires quite frequently, so you don’t really want to be soldering every connection every time (although even when I solder I quite frequently have to undo and redo my wiring). There are a few things that you will need, like resistors, a solderless breadboard, and some connectors. To make this easier I just picked up an electronics project kit that included every component I could possibly ever need. I also have a separate connector kit that I can either use on solderless breadboards, or to make more precise runs on a soldered circuit board.

Prototyping the HC-12 using a solderless breadboard

Another great thing about the kit is that it comes with a knockoff Arduino Uno. I wired this up to another RF module with the same configuration as the onboard system, and it’s ready to rock!

In my next post I’ll discuss exactly how you wire the transceivers to the Arduinos, and the code that is required to run them.

Basic Telemetry – What is the rocket doing? (3)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

One important goal for this project is to be able to make automated in-flight decisions and monitor flight progress. To accomplish this we need some kind of flight computer.

Something you may not know about me – I love Arduinos. With just a tiny amount of programming and wiring knowledge you can build almost anything. The Italian rapid prototyping board has dramatically changed the world of inventing and product design. The Arduino system has been used not only by hobbyists, but educators, NASA and even the Department of Defense have been known to employ the tiny prototyping boards in research and development projects.

If we’re planning to keep the body as small as possible, an obvious choice would be the Arduino Nano because of its size. You can even try the Seeeduino, an offbrand controller that claims to be the smallest arduino-based controller on the market.

I wanted more than just to launch a controller board into the air, though. I wanted to know what it was doing. Where is it going? How fast? How high?

To be able to answer these questions you need a few components. The first is called an IMU or Inertial Measurement Unit. IMU capabilities are measured in axes, and axes are grouped into 3’s based on what they measure. The three axes of any 3-dimensional system are X, Y and Z. Think of a 3-dimensional graph:

The three axes, wikipedia.com

In order to understand how something moves in space you need to understand translation and rotation, which make up the first two types of sensor in an IMU. Translation is measured by an accelerometer, linear acceleration and deceleration (which is just negative acceleration) is quantified in g’s of force, which can be best explained as how strong the acceleration force is in comparison to gravity. One g is the same amount of force as you feel pulling you down at sea level, and 5g is five times that amount of force.

Rotation is measured by a gyrometer, which uses degrees per second (dps). 360dps on the z axis means you turn a full circle around that axis in one second. We sometimes refer to these motions by the Euler Angles – “pitch”, “roll” and “yaw” – when talking about flight. This is more difficult with rockets, since rocket bodies are typically symmetrical in two axes, so in rocketry we may describe the rocket as “rolling” if it is turning around the fuselage, but I am less likely to discuss “pitch” and will probably not use the term “yaw”.

Either way, here is a diagram from Wikipedia that more clearly explains how those terms are used in aircraft:

The Euler Angles as they apply to an aircraft

I mentioned that an IMU generally has three types of sensors, but so far I have only described two of them. The third one is called a magnetometer, and it is essentially a three dimensional compass. Magnetometers are essential because they can help tell us the absolute orientation, or attitude, of the rocket.

Now that we know how the IMU works, we need to figure out how to add one to the telemetry system. We could pick up one of the Arduino Nanos I mentioned earlier and connect it with an external IMU board, and there’s nothing wrong with this EXCEPT I want something smaller, and I love integrated components!

After some digging I found that I had started this project right on time, since Arduino had recently released the Arduino Nano 33 BLE Sense with integrated 9-axis IMU (and a lot of other goodies). This meant a simple plug-and-play solution that I could use to measure attitude and motion in flight, and it also meant access to an onboard thermometer, hygrometer and even a barometer, which I could use for measuring altitude.

I won’t go into the details of how to calculate altitude by using barometric pressure, but it is based on the principle that air pressure is generally higher the lower you are in altitude. As the rocket climbs, then, the air pressure should decrease, and some mathematical formulas allow us to use the change in pressure over time to estimate how what altitude we have reached, and we can use the rate of change to determine what stage of flight we are currently in.

Arduino Nano 33 Ble Sense – Amazon.com

Once the telemetry board (new designation) arrived I hooked it up to my computer and wrote a quick program that fed the signals back through the built in serial communications. I noticed that the data was a little noisy (the image below is of me shaking it around – not what I’m talking about) so I added some moving average logic to smooth out the values. Ultimately I took this logic out because I determined logging the raw values would result in the best data, and I could always do smoothing with the raw data at a later time.

In my next post I will discuss wireless telemetry, and the wonderful world of RF comms (Radio Frequency communications).

Arduino IMU data plotted in “Data Monitor”, sketch showing data smoothing

Imaginary Rockets – Modeling, Mocking and Planning (2)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

Most people who know me probably wouldn’t be surprised if I skipped the planning phase and just started building a rocket, blindly trusting it would work. Kerbal inspired me, though, and modeling and testing virtual prototypes had its own appeal. I downloaded OpenRocket, and found that on this modeling software, much like in KSP, I could build outrageous designs and test them for feasibility without ever having to worry about the dangers of live testing.

Before I even got started building I figured it would be important to set a few goals of what I would like to accomplish through iterative testing and development:

  • Stable Aerodynamic Flight
  • 1km Apogee
  • 360º Video
  • Aerodynamic control (articulated control surfaces? thrust vectoring?)
  • Remote Telemetry
  • Powered Descent/Landing
  • Maintain Medium Powered Rocket Classification

I’ll go into more detail about each of these objectives in their own posts, but to summarize, I wanted to build a rocket under 1kg that could take a 360º camera up to 1km altitude. Meanwhile, I thought it would be fun if that rocket constantly sent telemetry data back to a computer, and was able to perform some tricks.

At first I thought it might be necessary to build a massive body rocket that can carry larger camera systems, since most 360º cameras are fairly wide, but with some searching I was able to find the Kandao Qoocam 4K – a 360º camera in a stick configuration, which will help greatly reduce the diameter of the rocket, and therefore improve A LOT of the aerodynamics, but I’ll discuss this more in my “Optics” post.

Kandao Qoocam 4K 360º Camera on Amazon.com

A 1km rocket isn’t easy, especially when one key limitation is that I’m not certified to fly anything over a G class motor. We can get further into motor classes and model rocketry certification levels, but suffice to say I was not going to just be able to strap more motors on it like you would in KSP. This time I needed to be a lot more strategic about my design choices.

I spent some time looking around for a suitable rocket modeling program, and settled on OpenRocket because it was straightforward, free, and cross-platform (which meant it would work on my Mac). There are a lot of great modeling programs out there. They range from simplistic, like OpenRocket, to complex all-purpose 3d modeling suites. Choose one based on your level of comfort or ambition, and employ google search liberally.

In OpenRocket you can change each of the design parameters of your craft, including weight, roughness, shape, placement, motors and timing. One major setback is there seems to be a bug when running on OSX that causes it to crash when switching back to “Side View” from other view modes.

Another big setback of OpenRocket, but also almost all model rocketry software I encountered, was that it isn’t built for modeling electronically influenced flight plans, such as off-engine recovery methods, chute delays, dynamic flight control or electronically timed staging. It’s not the end of the world, and I’m probably one of very few people who have this complaint.

The first versions of the MarkDart were very bulky. Before I found the Qoocam, large cameras led to large bodies, lots of engines, and ultimately nowhere near Medium Power classification.

OpenRocket rendering of an early, unfeasible version of the MarkDart

As you can see from the image above, it would have been a BEAST of a rocket, both in size and trajectory. While I would have loved to violate FAA airspace regulations, I’m not entirely confident I’m ready to be able to light 3 motors simultaneously, and the risk of rapid unscheduled disassembly would have been altogether way too high.

Another early/scrapped MarkDart design

Moving to the Qoocam allowed me to be a lot more realistic about the design, ultimately settling for a one-engine vehicle with a 41.6mm diameter body. The rocket would have a clear payload tube for the optics payload (that’s aeronautical engineering lingo for the camera), and a fiberglass engine/parachute compartment.

The final MarkDart1 design before ordering parts

In my next post, I will discuss building a system to understand what the rocket is doing at any given point in time, also known as telemetry.

Introduction – Space Frogs (1)

(I try to link to the products I used so you can find them more easily. If you purchase them from these links I may receive compensation from affiliate programs. I am not employed or influenced by the manufacturers or distributors.)

I think just about everyone has taken up a new hobby during the COVID pandemic. It just so happens that I spent a fair portion of our time in “quarantine” playing Kerbal Space Program, which inspired me to rediscover my love of rocketry. It wouldn’t be nearly as interesting, though, without a pile of convoluted tech. As it stands, I’ve only built one such rocket, and it only carried a small, somewhat dysfunctional remote telemetry package. Now I will start with the second generation of what I’ll nickname the markdart, and I’m going to try my best to blog about it.

I’m not making any commitments about the quality or accuracy of this blog. I’m not an engineer, this is not an “instructable”, and you should assume nothing I write about is safe, well planned, accurate, or best-practice.

What I do hope you take away from this blog is an inspiration to explore science and engineering without fear.

Kerbal Space Program

What do frogs have to do with rocketry? It’s not about the ballistic flight of amphibians post-leap, or the aerodynamic drag of pear-shaped amphibian bodies. It’s about simulation, exploration and inspiration.

Kerbal Space Program (KSP) is a game that lets players build and fly rockets and space planes, while employing realistic-enough physics modeling that teaches physics and engineering concepts like aerodynamics and orbital mechanics. It’s a beast of a game, with infinite possibilities, and some really fun missions that push players to build toward planetary exploration and scientific discovery.

The best part about KSP is that while fun and engaging, it’s a powerful learning tool for all ages, since it lets you experiment without fear of the consequences of real-world failures. Rockets are expensive and fail hard, so it’s way easier to experiment on a computer than on a real launchpad.

https://www.reddit.com/user/Space_Scumbag/

After countless days spent on KSP imaginary rockets weren’t enough, though. It was time to build something real.