2

I am an undergraduate student at a public university in Maryland. I am currently doing a project with an arduino and I came across a problem that I could not figure out after several days of researching. Regarding my project, I am trying to collect 6 data (acceleration and gyration in x,y,z) from an accelerometer/gyroscope sensor at a desired constant rate (trying to make it 1000 Hz, so about 1000 sets of the 6 data per second) into a SD card. However, I could not make the arduino do this; I am able to collect the data, but not at a constant sampling frequency of 1000 Hz. Could someone help me set the sampling frequency at 1000 Hz please. Here are some of the information of the sensors and arduino I am using:

  1. Arduino nano
  2. MPU-6050 gy-521 accelerometer/gyroscope - http://playground.arduino.cc/Main/MPU-6050
  3. SD card reader - http://www.aliexpress.com/item/SD-Card-Reader-Module-for-Arduino-ARM-Read-and-Write-Free-shipping/526750081.html?spm=2114.12010108.1000023.4.JkncUu&spm=2114.12010108.1000023.4.JkncUu

Also, I have posted my code. Thank you in advance for the help.

My code:

#include <Wire.h>
#include <LiquidCrystal.h>
#include <SPI.h>
#include <SD.h>
unsigned long time;
#include "I2Cdev.h"
#include "MPU6050.h"
MPU6050 accelgyro;
#define OUTPUT_READABLE_ACCELGYRO

const int sdcard = 7;
int num;
int16_t ax,ay,az,gx,gy,gz;
LiquidCrystal lcd(10, 9, 5, 4, 3, 2); //12 is 10 and 11 is 9

void setup() 
{
    Serial.begin(115200);
    lcd.begin(16, 2);
    pinMode(8, INPUT_PULLUP);
    Serial.print("Initializing SD card...");
    if (!SD.begin(sdcard)) 
    {
        Serial.println("initialization failed!");
        return;
    }
    Serial.println("initialization done.");
    accelgyro.initialize();
}

void loop() 
{
    lcd.setCursor(0,0);
    lcd.print("Push button");
    lcd.setCursor(0,1);
    lcd.print("to start");
    int sensorVal = digitalRead(8);
    if (sensorVal == 0)
    {
        delay(500);
        num = 1;
        collect();
    }
}

void collect()
{             
    File myFile = SD.open("test.txt",FILE_WRITE);
    myFile.println("Begin:");
    myFile.print("x-axis  ");
    myFile.print("y-axis  ");
    myFile.print("z-axis ");
    myFile.print("\n");

    Serial.println("Begin:");
    Serial.print("x-axis: ");
    Serial.print("\t");
    Serial.print("y-axis: ");
    Serial.print("\t");
    Serial.print("z-axis: ");
    Serial.print("\n");

    if(myFile)
    {
        while (num == 1)
        {
            accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
            lcd.setCursor(0,0);
            lcd.print((double) ax/16384*9.81);
            lcd.setCursor(7,0);
            lcd.print((double) ay/16384*9.81);
            lcd.setCursor(0,1);
            lcd.print((double) az/16384*9.81);
            lcd.setCursor(7,1);
            lcd.print(time);

            time = millis();

            Serial.print("Time: ");
            Serial.println(time);
            Serial.print(ax);
            Serial.print("\t");
            Serial.print((double) ax/16384*9.81);
            Serial.print("\t"); 
            Serial.print(ay);
            Serial.print("\t"); 
            Serial.print((double) ay/16384*9.81);  
            Serial.print("\t");   
            Serial.print(az); 
            Serial.print("\t"); 
            Serial.print((double) az/16384*9.81);
            Serial.print("\n");

            myFile.print("Time: ");
            myFile.println(time);
            myFile.print(ax);
            myFile.print("\t");
            myFile.print(ay);
            myFile.print("\t");   
            myFile.println(az); 

            int sensorVal = digitalRead(8);
            if(sensorVal == 0)
            {
                delay(500);
                num = 0;
                Serial.println("STOPPED");
                myFile.println("STOPPED");
                Serial.print("\n");
                myFile.print("\n");
                myFile.close();
                lcd.clear();
                lcd.setCursor(0,0);
                lcd.print("Stopped");
                delay(2000);
            }
        }
    }
}
  • 2
    What is connected to D8? If you want to collect data at 1kHz, why are you delaying for 500ms each loop? Have you heard of interrupts? – uint128_t Apr 19 '16 at 3:48
  • If you want people to analyse your code try formatting it properly and including some comments. This is good for your own future analysis as well. – Milliways Apr 19 '16 at 11:48
  • Sounds ambitious! Have you measured how long does it take to do the measurement, update the lcd, and write out all data to an SD card? – Gee Bee Apr 19 '16 at 20:57
  • uint128_t : I am only delaying at the very beginning and at the very end when the button is clicked to stop the while loop that reads the data from the sensor. – ssiltare Apr 19 '16 at 23:52
  • milliways: sorry, I will make sure I do that next time – ssiltare Apr 19 '16 at 23:53
1

You will not remotely be able to achieve 1000 Hz operation of a loop which performs so many time consuming operations. Even leaving out the possibility of substantial delay on some attempts to write to the SD card, your serial output alone could never keep up. A 115200 baud serial implementation can only transmit on the order of 11 thousand characters per second, which means there is only time for 11 or so per your hoped interval, and you produce far more than that. (And buffering is irrelevant if you are continually producing data faster than you can transmit it)

If you want to achieve a high sampling rate, you are going to have to pare the code down to the bare minimum required functionality and analytically or experimentally determine how much time each portion takes.

If you want regular samples, you are also going to have to study the rate at which the sensor produces them - you may actually want to consider letting the sensor be the timing master, and simply record the samples as they become available.

And you will need to study the SD card writing process and determine its possible worst-case delay. To overcome that, you may find that you have to collect your samples in an interrupt and use most of your available RAM to buffer them across the worst-case card delays. If the data you need to store is only a few megabytes, you might consider an SPI flash for its more deterministic timing behavior.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.