Let's see your Arduino-based flight computers!

The Rocketry Forum

Help Support The Rocketry Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
The Arduino Nano is capable of recording the 6DoF MPU-6050 at 200Hz to an SD file plus the Altitude, Pressure, and Temperature from the BMP280 at 50Hz. If you find you need more speed you can use the Arduino MKR Zero. It has an on-board SD socket and can record the MPU-6050 data at ~500Hz.
Thanks, I will try to look at the Arduino MKR Zero, it sound great that it is faster and got SD-card on it. :)
 
Hi, I know that ChatGPT is not the way to go, but I just need some code idea to get started. I think I will learn something from it and then lookup/read the rest I need to get it to "work" and then start to tweek it over time. I just need to learn my self how to code.
Have started to watch the toptechboy.com that you recommended, Thanks :)
I got an ESP-32 that is a bit faster to run the code from later, if I understand that right ;-)
I just wanted to start with the Arduino to learn.
Thanks
Nothing wrong with using ChatGPT that way, I think it’s a fantastic tool for exactly how you’re using it.

ESP32 boards are amazing, I’m yet to even come close to using the full capability yet. But you can run code on separate processing threads, control it and receive information from it via wifi, and you can pick them up for like $4 from AliExpress haha.
 
Hi, This is just what I am trying to build, I also am using an Arduino Nano, BMP280 and MPU6050.
But then I try to use an small OLED Display just to show the max altitude and speed.
I can't code, but I try to use ChatGPT to make the code
data logging on SD card sound like an good idea to add
Here is my test setup :)
View attachment 631479
Here's the code for our Pro-mini based Altimeter. It records altitude data in meters, converts it to feet and writes it to an SD card. I'll post pics later.

______________________________________

#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

#define BMP_SDA 4 // BMP280 SDA pin
#define BMP_SCL 5 // BMP280 SCL pin
#define SD_CS 3 // SD card CS pin

int Counter = 1;
int altitudeF = 1;

Adafruit_BMP280 bmp; // Create BMP280 sensor object
File dataFile; // File object to write data
float maxAltitude = -9999.0; // Initialize the maximum altitude to a very low value

void setup() {
Serial.begin(9600);
while (!Serial)
; // Wait for serial connection

if (!bmp.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}

Serial.print("Initializing SD card...");
if (!SD.begin(SD_CS)) {
Serial.println("SD card initialization failed!");
while (1);
}
Serial.println("SD card initialized successfully.");

dataFile = SD.open("data.csv", FILE_WRITE);
if (!dataFile) {
Serial.println("Error opening data.csv for writing.");
while (1);
}
Serial.println("Writing data to data.csv...");
dataFile.println("Counter, Altitude (m),Altitude (F),MaxAltitude (F),Temperature (Deg C),Pressure (hPa)");
dataFile.close(); //Save everything to SD

}

void loop() {
// Read temperature, pressure, and altitude from BMP280
float temperature = bmp.readTemperature();
float pressure = bmp.readPressure() / 100.0; // Convert Pa to hPa
float altitude = bmp.readAltitude(1018.5); // Assuming sea-level pressure of 1013.25 hPa

altitudeF = (altitude*3.25);

// Update maximum altitude if current altitude is higher
if (altitudeF > maxAltitude) {
maxAltitude = altitudeF;
}

// Print the data to serial monitor
Serial.print("Counter: " );
Serial.print(Counter);
Serial.print(" Altitude: (m)" );
Serial.print(altitude);
Serial.print(" Altitude: (Ft)" );
Serial.print(altitudeF);
Serial.print(" Max Altitude: (Ft) ");
Serial.print(maxAltitude);
Serial.print(" Temperature: Deg C ");
Serial.print(temperature);
Serial.print(" Pressure: kPa ");
Serial.println(pressure);

// Write the data to the SD card
dataFile = SD.open("data.csv", FILE_WRITE);
dataFile.print(Counter);
dataFile.print(",");
dataFile.print(altitude);
dataFile.print(",");
dataFile.print(altitudeF);
dataFile.print(",");
dataFile.print(maxAltitude);
dataFile.print(",");
dataFile.println(temperature);
// dataFile.print(",");
// dataFile.println(pressure);

dataFile.close(); //Save everything to SD

Counter = Counter + 1;


// Delay before taking the next reading
delay(100);
}
 
ESP32 boards are amazing, I’m yet to even come close to using the full capability yet. But you can run code on separate processing threads, control it and receive information from it via wifi, and you can pick them up for like $4 from AliExpress haha.

The downside to ESP32 boards is their larger size, and getting them to fit in low powered rockets.

The board I've been experimenting with, but not built anything with yet is the Seeduino Xiao. It's tiny and very powerful for it's size. It has 256Kb of flash memory vs 32kb on a pro-mini. For comparison, that's a USB-C plug.

1-102010328-seeed-studio-xiao-samd21-45font.jpg

Eventually, I'd like to scrap the SD card and go to onboard datalogging using the Seeduino, but haven't had the time to work on that project as of yet.
 
As promised, here's our pro-mini based altimeter. It's got a BMP-280 barometric pressure sensor, a GY-521 3 Axis Gyroscope and 3 Axis Accelerometer and a microSD card reader all connected to a custom printed PCB.

20240222_145044.jpg
 
Here's the code for our Pro-mini based Altimeter. It records altitude data in meters, converts it to feet and writes it to an SD card. I'll post pics later.

______________________________________

#include <Wire.h>
#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
SdFat SD;
#define BMP_SDA 4 // BMP280 SDA pin
#define BMP_SCL 5 // BMP280 SCL pin
#define SD_CS 10 // SD card CS pin for Uno
unsigned long start, Time;
int altitudeF = 1;

Adafruit_BMP280 bmp; // Create BMP280 sensor object
File dataFile; // File object to write data
float maxAltitude = -9999.0; // Initialize the maximum altitude to a very low value

void setup() {
Serial.begin(115200);
while (!Serial)
; // Wait for serial connection

if (!bmp.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X8, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X4, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_125); /* Standby time. */
Serial.print("Initializing SD card...");
if (!SD.begin(SD_CS)) {
Serial.println("SD card initialization failed!");
while (1);
}
Serial.println("SD card initialized successfully.");

dataFile = SD.open("data.csv", FILE_WRITE);
if (!dataFile) {
Serial.println("Error opening data.csv for writing.");
while (1);
}
Serial.println("Writing data to data.csv...");
dataFile.println("Counter, Altitude (m),Altitude (F),MaxAltitude (F),Temperature (Deg C),Pressure (hPa)");
dataFile.close(); //Save everything to SD
start = millis(); // Start millis() timer
Wire.setClock(400000); //Set I2C clock to 400KHz
}

void loop() {
// Read temperature, pressure, and altitude from BMP280
float temperature = bmp.readTemperature();
float pressure = bmp.readPressure() / 100.0; // Convert Pa to hPa
float altitude = bmp.readAltitude(1018.5); // Assuming sea-level pressure of 1013.25 hPa
Time = millis() ;
altitudeF = (altitude*3.25);

// Update maximum altitude if current altitude is higher
if (altitudeF > maxAltitude) {
maxAltitude = altitudeF;
}

// Write the data to the SD card
dataFile = SD.open("data.csv", FILE_WRITE);
dataFile.print(Time);
dataFile.print(",");
dataFile.print(altitude);
dataFile.print(",");
dataFile.print(altitudeF);
dataFile.print(",");
dataFile.print(maxAltitude);
dataFile.print(",");
dataFile.print(temperature);
dataFile.print(",");
dataFile.println(pressure);

dataFile.close(); //Save everything to SD

}
I breadboarded a simple altimeter to run your Pro Mini Altimeter code. Your code is very simple, easily understood to quickly start a project collecting altimeter data. I did find a few sections of code that were not critical for flight altitude data.

1. The Counter has no value for flight analysis. I replaced it with "Time = millis();".
2. The "delay(100);" statement is not necessary. Avoid using delay() function in any datalogging system.
3. All of the "Serial.print();" statements in the "void loop" are for easy ground testing and not necessary for flight. They slow the data collection speed during a flight. Elimination of the "Serial.print()" functions and delay(100) increased the data collection from ~8Hz to 72Hz. Barometric altimeter data collected at >=50Hz gives you a usable velocimeter without the need of an accelerometer.

Ran a quick vacuum test. Needs some adjustments in the oversampling. The data shows everything is working.

If it works, fly the hardware/software that you have. Collect data, the data will show you what needs to be changed for future flights.
 

Attachments

  • Altimeter Test 5.png
    Altimeter Test 5.png
    56.9 KB · Views: 1
As promised, here's our pro-mini based altimeter. It's got a BMP-280 barometric pressure sensor, a GY-521 3 Axis Gyroscope and 3 Axis Accelerometer and a microSD card reader all connected to a custom printed PCB.

View attachment 632081
That is very close to a module flight computer a friend made almost 5 years ago. My post #51 shows launch data from his flight computer taken 3 years ago. How fast does yours collect data?
 
I breadboarded a simple altimeter to run your Pro Mini Altimeter code. Your code is very simple, easily understood to quickly start a project collecting altimeter data. I did find a few sections of code that were not critical for flight altitude data.

1. The Counter has no value for flight analysis. I replaced it with "Time = millis();".
2. The "delay(100);" statement is not necessary. Avoid using delay() function in any datalogging system.
3. All of the "Serial.print();" statements in the "void loop" are for easy ground testing and not necessary for flight. They slow the data collection speed during a flight. Elimination of the "Serial.print()" functions and delay(100) increased the data collection from ~8Hz to 72Hz. Barometric altimeter data collected at >=50Hz gives you a usable velocimeter without the need of an accelerometer.

Ran a quick vacuum test. Needs some adjustments in the oversampling. The data shows everything is working.

If it works, fly the hardware/software that you have. Collect data, the data will show you what needs to be changed for future flights.

Thanks for the reply. I posted it elsewhere (but not in this thread) that my son and I originally built this to fulfil part two of Requirement 3 of the Space exploration Merit Badge. It's in bold.

3. Build, launch, and recover a model rocket.* Make a second launch to accomplish a specific objective.

We couldn't really figure out what to do part the second part, so we built this, which also fulfilled requirements for the Coding and Electronics Merit badge (he soldered it together himself). I was just trying to keep the kid occupied productively last summer! :D

Would you mind pasting in the time code mods? I learned basic in the 1980's, didn't do much with anything for 40 years, and then have been slowly learning Arduino coding. BUT, the techniques I'm using aren't always the most efficient. They're mostly the brute force method.

Good catch on the serial print functions, we had those in for our initial troubleshooting. It's residual code that we can eliminate. Thanks.

The modification to the code that I would like to add would be writing to an individual file each time the unit is reset, to better keep track of each launch.
 
Last edited:
That is very close to a module flight computer a friend made almost 5 years ago. My post #51 shows launch data from his flight computer taken 3 years ago. How fast does yours collect data?

It uses the code I posted earlier, so 100ms intervals. It was sufficient for our needs. At this point, launching on A's, B's and C's, all the kid really cares about is Max Altitude.
 
Would you mind pasting in the time code mods? I learned basic in the 1980's, didn't do much with anything for 40 years, and then have been slowly learning Arduino coding. BUT, the techniques I'm using aren't always the most efficient. They're mostly the brute force method.
#include <Wire.h>
#include <SPI.h>
#include <SdFat.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
SdFat SD;
#define BMP_SDA 4 // BMP280 SDA pin
#define BMP_SCL 5 // BMP280 SCL pin
#define SD_CS 10 // SD card CS pin for Uno
unsigned long start, Time;
int altitudeF = 1;

Adafruit_BMP280 bmp; // Create BMP280 sensor object
File dataFile; // File object to write data
float maxAltitude = -9999.0; // Initialize the maximum altitude to a very low value

void setup() {
Serial.begin(115200);
while (!Serial)
; // Wait for serial connection

if (!bmp.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X4, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X2, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_1); /* Standby time. */
Serial.print("Initializing SD card...");
if (!SD.begin(SD_CS)) {
Serial.println("SD card initialization failed!");
while (1);
}
Serial.println("SD card initialized successfully.");

dataFile = SD.open("data.csv", FILE_WRITE);
if (!dataFile) {
Serial.println("Error opening data.csv for writing.");
while (1);
}
Serial.println("Writing data to data.csv...");
dataFile.println("Counter, Altitude (m),Altitude (F),MaxAltitude (F),Temperature (Deg C),Pressure (hPa)");
dataFile.close(); //Save everything to SD
start = millis(); // Start millis() timer
Wire.setClock(400000); //Set I2C clock to 400KHz
}

void loop() {
// Read temperature, pressure, and altitude from BMP280
float temperature = bmp.readTemperature();
float pressure = bmp.readPressure() / 100.0; // Convert Pa to hPa
float altitude = bmp.readAltitude(1018.5); // Assuming sea-level pressure of 1013.25 hPa

altitudeF = (altitude*3.25);

// Update maximum altitude if current altitude is higher
if (altitudeF > maxAltitude) {
maxAltitude = altitudeF;
}

Time = millis() ; // Time in milliseconds


// Write the data to the SD card
dataFile = SD.open("data.csv", FILE_WRITE);
dataFile.print(Time);
dataFile.print(",");
dataFile.print(altitude);
dataFile.print(",");
dataFile.print(altitudeF);
dataFile.print(",");
dataFile.print(maxAltitude);
dataFile.print(",");
dataFile.print(temperature);
dataFile.print(",");
dataFile.println(pressure);

dataFile.close(); //Save everything to SD

}
 
It uses the code I posted earlier, so 100ms intervals. It was sufficient for our needs. At this point, launching on A's, B's and C's, all the kid really cares about is Max Altitude.
I work with university students and getting them motivated to go beyond what their professors teach or require has been a challenge for the past 5 years. The aerospace students want to work with the latest and fastest processors, but the code they write only records their data at 100Hz instead of the 1000Hz the processor is capable of doing. For grade school and high school students, altitude is the status for bragging rights.
 
My background is biological sciences, but when I was in middle school back in the 1980's I was one of 3-4 kids that spent their after school time in the computer lab. The school had 4-5 Apple ][e's and we'd write simple little programs in basic. When I got to High School they only had two semesters of programming (1 year). After my sophomore year, I was at the end of the road. So I followed a different path in life. Every now and again, I wonder "What if?"

I work with university students and getting them motivated to go beyond what their professors teach or require has been a challenge for the past 5 years. The aerospace students want to work with the latest and fastest processors, but the code they write only records their data at 100Hz instead of the 1000Hz the processor is capable of doing. For grade school and high school students, altitude is the status for bragging rights.

That's hysterical. I personally think of it like this. When things are nominal, in this case flight conditions, collecting data at a sub-optimal or reduced rate is fine. The gaps between data points and sensor readings are usually small enough that the conditions do not change that much between them, or the condition between point a and point b are such that you can interpolate between them. But when things start to go off kilter, THAT's when high frequency data is critical for figuring out the sequence of events that led to whatever event we're trying to troubleshoot. When writing code, one must consider the cost benefit of sampling data rates vs storage capacity. But again, I came from an era where our storage capacity was VERY limited. The micro-SD card readers we're using only work with up to 32GB cards. Given the limited amount of data we collect, that's thousands upon thousands of hours of flight time. But much like the Y2K bug debacle, good programmers (which I'm not) should not think about their code TODAY, they should think about how their code might be modified for future uses.

Thanks again for your replies, they're taking my mind to new places and this old dog is still learning new tricks!

L
 
Last edited:
My background is biological sciences, but when I was in middle school back in the 1980's I was one of 3-4 kids that spent their after school time in the computer lab. The school had 4-5 Apple ][e's and we'd write simple little programs in basic. When I got to High School they only had two semesters of programming (1 year). After my sophomore year, I was at the end of the road. So I followed a different path in life. Every now and again, I wonder "What if?"

That's hysterical. I personally think of it like this. When things are nominal, in this case flight conditions, collecting data at a sub-optimal or reduced rate is fine. The gaps between data points and sensor readings are usually small enough that the conditions do not change that much between them, or the condition between point a and point b are such that you can interpolate between them. But when things start to go off kilter, THAT's when high frequency data is critical for figuring out the sequence of events that led to whatever event we're trying to troubleshoot. When writing code, one must consider the cost benefit of sampling data rates vs storage capacity. But again, I came from an era where our storage capacity was VERY limited. The micro-SD card readers we're using only work with up to 32GB cards. Given the limited amount of data we collect, that's thousands upon thousands of hours of flight time. But much like the Y2K bug debacle, good programmers (which I'm not) should not think about their code TODAY, they should think about how their code might be modified for future uses.

Thanks again for your replies, they're taking my mind to new places and this old dog is still learning new tricks!

L
I wanted to be either an aerospace or nuclear engineer. The university shutdown the reactor my freshman year. I gravitated over to Fluid Dynamics. Not my favorite subject, but I understood it better than my professors. Thirty years of my career was in semiconductor. Developing flow controllers and new process materials to take the industry from 4 micron to 14 nanometer resolution. Twelve years was with two hardware/software developers that could write 500-1100 lines of Assembly code a day. I could write 20-50 lines of Assembly code a day at my best. I don't think Carl David Todd realized the influence he had on me with writing code. I'm still just an average code writer, but Carl showed me the correct way to write code.

When I went from 100Hz to 400Hz data rates, I knew I was opening a new door to other possibilities. What I didn't realize was that I opened a door to a gallery of open doors of possibilities to study.
 
The Arduino Nano is capable of recording the 6DoF MPU-6050 at 200Hz to an SD file plus the Altitude, Pressure, and Temperature from the BMP280 at 50Hz. If you find you need more speed you can use the Arduino MKR Zero. It has an on-board SD socket and can record the MPU-6050 data at ~500Hz.
Spacedog how do you go about saving the data in the SD card file with differing rates of recording?

Right now I just write a string of variables straight to a .csv file and then just dump it in to excel to create graphs etc - eg millis, pressure, altitude, accelerometer and gyro variables just get written with a comma between them once per loop like:

30152, 1011.58, 30.5, 0.5, 0.42, 35.48, 0.15, 1.02, 1.42

...Completely random numbers just for demonstration obviously, and it's fast enough for what I'm doing at the moment but I'm absolutely positive there is a far better way to do this, and just doing a cycle of "read BMP390, read MPU, print it to SD card" as my loop wouldn't work if I want to record barometer readings at 100hz and accelerometer + gyro at 400hz haha.
 
Spacedog how do you go about saving the data in the SD card file with differing rates of recording?

Right now I just write a string of variables straight to a .csv file and then just dump it in to excel to create graphs etc - eg millis, pressure, altitude, accelerometer and gyro variables just get written with a comma between them once per loop like:

30152, 1011.58, 30.5, 0.5, 0.42, 35.48, 0.15, 1.02, 1.42

...Completely random numbers just for demonstration obviously, and it's fast enough for what I'm doing at the moment but I'm absolutely positive there is a far better way to do this, and just doing a cycle of "read BMP390, read MPU, print it to SD card" as my loop wouldn't work if I want to record barometer readings at 100hz and accelerometer + gyro at 400hz haha.
Sorry about replying so late. I had a computer problem and lost track of this thread. Attached is one example of a loop that records IMU data at 500Hz and barometric data at 100Hz. You can adjust the "if ()" statement millisecond or microsecond time to match the limits of the processor and sensors you use.
 

Attachments

  • Loop Example.pdf
    68.7 KB · Views: 0
Sorry about replying so late. I had a computer problem and lost track of this thread. Attached is one example of a loop that records IMU data at 500Hz and barometric data at 100Hz. You can adjust the "if ()" statement millisecond or microsecond time to match the limits of the processor and sensors you use.
Awesome, thank you for this. I figured it was something like this but what you’ve written is a bit cleaner than what I had!
 
Back
Top