Hi everyone, I am working on building a gyrologger with an nano, MPU6050. The goal was to use this with Gyroflow. I have been able to get just about everything working but running into an issue with the sampling rate being low about 31Hz.
Some things that I have tried are reading raw values and also adjusting the time between samples to as low as possible. But nothing seems to be helping. Granted my programming experience is limited but maybe I have not initialized the 6050 with the correct parameters or just writing to the SD card is the limiting factor. At one point I was trying to buffer the data and then write to the SD card but when compiled was using more memory that the nano offered.
I have read a lot of posts around the MPU 6050 and looked at many examples, but I know I am missing something. I have posted the full code here:
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include "I2Cdev.h"
#include "MPU6050.h"
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
#define LOGGER_NAME "Arduino Logger" // Change this to whatever name you want
MPU6050 mpu;
File dataFile;
// Global Variables
int count = 0; // Variable to increment when button is pressed
char filename[13]; // Filename buffer
int16_t accelerometer[3]; // Accelerometer values
int16_t gyro[3]; // Gyroscope values
const int buttonPin = 2; // Button pin *change this according to what pin you use*
const int ledPin = 7; // LED pin *change this according to what pin you use*
int buttonState = 0; // Current state of the button
int lastButtonState = 0; // Previous state of the button
int ledState = LOW; // Current state of the LED
bool toggleFlag = false; // Flag to track the toggle state
bool incrementedFile = false; //Flag to track if filename has been incremented
bool recordStart = false; //track when recording started
void setup() {
pinMode(ledPin, OUTPUT); // For the LED Output
pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// Initialize serial communication
Serial.begin(115200);
// Initialize the MPU6050 sensor
Wire.begin();
mpu.initialize();
mpu.setFullScaleAccelRange(1); //0: 250deg/s | 1: 500deg/s | 2: 1000deg/s | 3: 2000deg/s
mpu.setFullScaleGyroRange(1); //0: 2g | 1: 4g | 2: 8g | 3: 16g
mpu.setDLPFMode(0); // 0: 240Hz | 1: 184Hz | 2: 94Hz | 3: 44Hz | 4: 21Hz | 5: 10HZ | 6: 5HZ
// Configure MPU6050 to operate in raw sensor mode
mpu.setSleepEnabled(false); // Wake up the MPU6050 from sleep mode
mpu.setDMPEnabled(false); // Disable the Digital Motion Processor (DMP)
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
// Open the root directory
File root = SD.open("/");
if (!root) {
Serial.println("Failed to open root directory!");
return;
}
int highestNumber = 0; // Variable to store the highest number found
// Read filenames from the root directory
while (true) {
File entry = root.openNextFile();
if (!entry) {
// No more files
break;
}
// Get the filename
String filename = entry.name();
entry.close();
// Look for numbers in the filename
String numbers = extractNumbers(filename);
// Parse the number and check if it is higher than the current highest number
if (numbers.length() > 0) {
int currentNumber = numbers.toInt();
if (currentNumber > highestNumber) {
highestNumber = currentNumber;
}
}
}
root.close();
// // Print the highest number found
Serial.print("Highest number found: ");
Serial.println(highestNumber);
count = highestNumber;
Serial.println(count);
}
void loop() {
// Check if it's time to take a sample (1kHz)
static unsigned long prevTime = 0;
unsigned long currentTime = micros();
unsigned long timeInterval = 50; // Desired time interval between samples in microseconds
if (currentTime - prevTime >= timeInterval) {
prevTime = currentTime;
// Read sensor data from MPU6050
mpu.getMotion6(&accelerometer[0], &accelerometer[1], &accelerometer[2],
&gyro[0], &gyro[1], &gyro[2]);
}
buttonState = digitalRead(buttonPin);
// Check if the button state has changed
if (buttonState != lastButtonState) {
// If the button was pressed (change from HIGH to LOW)
if (buttonState == LOW) {
toggleFlag = !toggleFlag; // Toggle the flag
}
delay(50); // Debounce delay
}
lastButtonState = buttonState;
if (toggleFlag) {
ledState = HIGH; // Turn on the LED
// Increment count and create new filename when button is pressed
if (incrementedFile == false){
createFilename();
Serial.println(filename);
}
if (recordStart == false){
Serial.println("");
Serial.println("data logging started");
Serial.println(currentTime);
}
recordStart = true;
// Append the data to the file
appendDataToFile(currentTime, gyro, accelerometer);
}
else {
ledState = LOW; // Turn off the LED
if (incrementedFile == true){
Serial.println("");
Serial.println("data logging stopped");
Serial.println(currentTime);
}
incrementedFile = false;
recordStart = false;
}
digitalWrite(ledPin, ledState);
}
void createFilename() {
// Generate new filename
count++;
snprintf(filename, sizeof(filename), "data%d.csv", count);
incrementedFile = true;
unsigned long timeStamp = micros();
// Open a file for writing
dataFile = SD.open(filename, FILE_WRITE);
if (dataFile) {
// Write the header line
dataFile.println("GYROFLOW IMU LOG");
dataFile.println("version,1.3");
dataFile.print("id,");
dataFile.println(LOGGER_NAME);
dataFile.println("orientation,XYZ");
dataFile.print("timestamp,");
dataFile.println(timeStamp);
dataFile.println("tscale,0.000001");
dataFile.println("gscale,0.00013309054");
dataFile.println("ascale,0.00012207031");
dataFile.println("t,gx,gy,gz,ax,ay,az");
dataFile.close();
Serial.print("Header Lines Created for: ");
Serial.print(filename);
Serial.println("");
Serial.print("File created :");
Serial.println(filename);
Serial.println("");
Serial.println("data logging started");
} else {
Serial.println("Error opening file!");
}
}
String extractNumbers(String str) {
String numbers = "";
for (int i = 0; i < str.length(); i++) {
if (isDigit(str.charAt(i))) {
numbers += str.charAt(i);
}
}
return numbers;
}
void appendDataToFile(unsigned long time, int16_t* gyro, int16_t* accelerometer)
{
// Create a file on the SD card
File dataFile = SD.open(filename, FILE_WRITE);
if (dataFile) {
// Write the data to the file
dataFile.print(time);
dataFile.print(",");
dataFile.print(gyro[0]);
dataFile.print(",");
dataFile.print(gyro[1]);
dataFile.print(",");
dataFile.print(gyro[2]);
dataFile.print(",");
dataFile.print(accelerometer[0]);
dataFile.print(",");
dataFile.print(accelerometer[1]);
dataFile.print(",");
dataFile.println(accelerometer[2]);
// Close the file
dataFile.close();
}
else {
Serial.println("Error opening file!");
}
}
Any help would be greatly appreciated!