SdFs - a New SD Library for FAT16/FAT32/exFAT

Status
Not open for further replies.
Hi,i want to record the values that the gyroscope gives me in all three axes i use spi protocol,in my project the loop "void loop()" runs at 400Hz(every 2.5ms).
Because time is limited(2.5ms) i would like to know how much time he wants to write these three values(3 axis) on the sd card,from what i understood the variable maxWriteMicros this it shows us.Correctly?

You said

The 160 µs is the maximum time to write a 512 byte sector to the SD.

Can we reduce the 512 byte sector to 256 byte to reduced the time??
 
Last edited:
Hi,i want to record the values that the gyroscope gives me in all three axes i use spi protocol,in my project the loop "void loop()" runs at 400Hz(every 2.5ms).
Because time is limited(2.5ms) i would like to know how much time he wants to write these three values(3 axis) on the sd card,from what i understood the variable maxWriteMicros this it shows us.Correctly?

You said



Can we reduce the 512 byte sector to 256 byte to reduced the time??

No, the 512 bytes is the minimum of all known SD cards.
If you do it correctly, you get the gyro values with 400 Hz and pass the values to SD library. AFAIK, Bill's library will buffer the data and write to disk if 512 bytes are filled.
How to do it?
you acquire the data using a ISR (triggered by a 2.5 ms timer) and flag the data to be available.
in the loop() you send the data to file system. The loop() will runs some sort of in parallel to the ISR driven acquisition.
Important is NOtT to write from ISR to file system, but from loop().
 
Hi,i want to record the values that the gyroscope gives me in all three axes i use spi protocol,in my project the loop "void loop()" runs at 400Hz(every 2.5ms).
Because time is limited(2.5ms) i would like to know how much time he wants to write these three values(3 axis) on the sd card,from what i understood the variable maxWriteMicros this it shows us.Correctly?

You said

Can we reduce the 512 byte sector to 256 byte to reduced the time??

At 400 Hz, the time to write the SD should not be a problem if you are using a Teensy 3.6.

Which gyroscope are you using? How long does it take to read the three values?

The ExFatLogger example can log data from four ADC channels at 4,000 Hz and doesn't use an interrupt routine.

ExFatLogger just uses a loop like this to set the interval between samples.

Code:
  while ((delta = micros() - logTime) < 0) {}
Teensy 3.6 is so fast that the max delta is zero for most runs. It takes 31 microseconds to read the four ADC channels so time jitter from not using a timer is OK.
 
In principle thank you for your answers,bill i use the l3gd20h with spi speed in 10MHz,i read all three axis in 19us.
 
Last edited:
In principle thank you for your answers,bill i use the l3gd20h with spi speed in 10MHz,i read all three axis in 19us.

I think I have a L3GD20H breakout board. Do you just want to log values each time a new set of data is ready?

Could give more details how you are using the L3GD20H?

Did you write the L3GD20H driver?

Are you setting the Output Data Rate to 380 Hz?

Are you using the DRDY signal?
 
Last edited:
I have defined the output data rate(ODR) 400Hz therefore since the loop "void loop()" runs at 400Hz after each execution the loop i read the new values.
I will reasonably have to read new values in this way.

Are you using the DRDY signal?
I do not use it.Υou think i should use it?
 
I have defined the output data rate(ODR) 400Hz therefore since the loop "void loop()" runs at 400Hz after each execution the loop i read the new values.
I will reasonably have to read new values in this way.


I do not use it.Υou think i should use it?

Have you read the Datasheet for the L3GD20H? Seems like the actual ODRs are not neat values like 400 Hz. In Table 3 in Section 2.1, the rates are.

11.9/23.7/
47.3/94.7/
189.4/
378.8/
757.6

There is a footnote that is very disturbing.
3. The period (1/ODR), length of time between two consecutive sampling, must be derived by the reciprocal of the maximum.
and minimum ODR limits: for example for ODR = 189.4 Hz, sampling period range will be within [4591 μs, 6211 μs] (where
ODR minimum and maximum have been approximated at 162 Hz, 219 Hz respectively).

With this kind of variation you may miss values or read values twice if you read at 400 Hz.

I wonder about the accuracy of the data. I haven't found a clear spec for accuracy of the dps values.

I may look for my Adafruit breakout board and play with the device.
 
Bill i read the datasheet,in the CTRL1 register should be defined the odr for this i put 400 but as if you are not like that.

I may look for my Adafruit breakout board and play with the device.
I would appreciate it.:)
 
Bill i read the datasheet,in the CTRL1 register should be defined the odr for this i put 400 but as if you are not like that.


I would appreciate it.:)

The data sheet indicates that setting CTRL1 to 400 MHZ is really approximately 378.8 Hz. The footnote suggests that the range can vary from about 314 Hz to 438 Hz.

I am assuming the "400 Hz" setting can vary by about the same percentage as the "200 Hz" setting.

This means reading the gyro at 400 Hz may not be appropriate. It depends on your application. I would read the device on the data ready signal and record the time also.

What is your application?
 
I am assuming the "400 Hz" setting can vary by about the same percentage as the "200 Hz" setting.

using orientation sensors without, say Kalman filtering, is asking for problems. So measurement errors can and should be handled.
 
using orientation sensors without, say Kalman filtering, is asking for problems. So measurement errors can and should be handled.

I found my L3GD20H Adafruit gyro break-out board and did some tests. Kalman filtering looks like a good idea.

I mounted the L3GD20H on big block of wood and ran it at several data rates to see what the noise level is when it is not moving. At very low rates it's not bad.

At 400 Hz the noise level is much higher. Also the rate is not 400 Hz. I measured 377.4 Hz for my chip. The datasheet says 378.8 Hz is typical.

You need to synchronize reading data with the DRDY signal. Here is a statement from a L3GD20H Application note.

If the reading of the angular rate data is particularly slow and cannot be synchronized (or it is
not required) with either the XYZDA bit in the STATUS register or with the DRDY signal, it is
strongly recommended to set the BDU (block data update) bit to 1 in the CTRL4 register.

This feature avoids reading values (most significant and least significant parts of the angular
rate data) related to different samples. In particular, when the BDU is activated, the data
registers related to each channel always contain the most recent angular rate data produced
by the device, but, if the reading of a given pair (i.e. OUT_X_H and OUT_X_L, OUT_Y_H
and OUT_Y_L, OUT_Z_H and OUT_Z_L) is initiated, the refresh for that pair is blocked until
both MSB and LSB parts of the data are read.

Note: BDU only guarantees that OUT_X(Y, Z)_L and OUT_X(Y,Z)_H have been sampled at the
same moment. For example, if the reading speed is too slow, it may read X and Y sampled
at T1 and Z sampled at T2.
Data must be read starting from the lower address.

Still, MEMS Coriolis Vibratory Gyroscopes are amazing devices. Makes me think of the problem of analyzing a Foucault pendulum that you get as a young Physics Major, it's tricky. Designing a MEMS Gyro must be a real challenge.

Edit: Looks like there is lots of open source software so you don't need to understand the details of quaternions or Kalman filters. Many sites have Arduino libraries for popular IMU sensor fusion algorithms.

I did an SdFat example for the MPU-6050 which has a built-in motion fusion processor. The MPU-6050 uses a propriety algorithm and is a bit slow.
 
Last edited:
Thanks for the time you dedicated and for the useful information.:)
It is therefore necessary use the drdy signal,so i can always get new data so?

At 400 Hz the noise level is much higher. Also the rate is not 400 Hz. I measured 377.4 Hz for my chip. The datasheet says 378.8 Hz is typical.

You need to synchronize reading data with the DRDY signal. Here is a statement from a L3GD20H Application note.

You could post the code you wrote to get an idea,you used the signal drdy in your test??

If i use the gyroscope FXOS8700 and the accelerometer-magnetometer FXAS21002 they will be all better as regards the frequency of renewal at 400hz that i want?

I did an SdFat example for the MPU-6050 which has a built-in motion fusion processor. The MPU-6050 uses a propriety algorithm and is a bit slow.

How much time it took to record the values on the sd card?

Sorry for the many questions i do,i am confused.
 
Last edited:
If i use the gyroscope FXOS8700 and the accelerometer-magnetometer FXAS21002 they will be all better as regards the frequency of renewal at 400hz that i want?
The FXOS8700 and FXAS21002 get good reviews but you will still need to use DRDY with the Gyro. Gyros are have a vibrating element and I believe the readout sensors are synchronized with the frequency of vibration. The datasheet for the FXAS21002 claims the ODR is good to 2.5%.

You might want to use this library from NXP.

I have attached a rough program that shows how to enable and use DRDY with the L3GD20H. I just use a loop waiting for DRDY. You could use an interrupt connected to DRDY to read the Gyro.

Here is typical output from the program.

Code:
WHO_AM_I: 0x7F
CTRL_REG1: 0b111
CTRL_REG2: 0b0
CTRL_REG3: 0b0
2653,0b1111,102,285,-65
2654,0b1111,94,261,-101
2654,0b1111,85,266,-62
2653,0b1111,69,248,-45
2654,0b1111,88,278,-78
2654,0b1111,75,262,-40
2654,0b1111,94,247,-50

The first three lines show register content.

The remaining lines have five fields, ODR period in usec, status register, xdata, ydata, and zdata. The period is about 2654 usec or 376.8 Hz.

Edit: The NXP devices are often used with I2C. SPI is limited to 1 MHz for the FXOS8700CQ and 2 MHz for the FXAS21002C.
 

Attachments

  • L3GD20Hteensy.ino
    6 KB · Views: 95
Last edited:
Just a question about the code you wrote,you have written

Code:
// [B]Try Mode 3 - looks like data sheet timing. [/B]
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, [COLOR="#FF0000"][B]SPI_MODE3[/B][/COLOR]));

I looked at the datasheet(chapter 2.4.1 and 5.2)but i did not understand how that choice was made.
What should I look for to choose the right choice

Also

You could use an interrupt connected to DRDY to read the Gyro.

we should create a simple interrupt or we should use it fifo mode from register 3?

Bill thank you very much for all your help.
 
I looked at the datasheet(chapter 2.4.1 and 5.2)but i did not understand how that choice was made.
What should I look for to choose the right choice
Section 5.2.1 Figure 18 shows clock high when idle and clocking data on rising clock. That suggests mode 3. Many sensor chips will work in mode 0 or 3 (corrected from mode 1 or 3).
we should create a simple interrupt or we should use it fifo mode from register 3?
It depends on your application. The FIFO buffering is nice but you can't get the time of the sample. You must decide based on your needs.
 
Last edited:
It depends on your application.The FIFO buffering is nice but you can't get the time of the sample.You must decide based on your needs.

For my own application (quadcopter) the fifo buffering it is not recommended because does not to continuously poll data from the sensor but only when it is necessary.Correctly?


He says to the datasheet

The device is provided with two pins which can be activated to generate either the data-ready or the interrupt signals.
The functionality of the pins is selected through CTRL3(22h).Refer to Table 16, Table 17 and to the block diagram in Figure 11 for more details.

In my application, the signal DRDY/INT2 needs to be used,the signal INT1 it is not necessary to use however, what its use could benefit from,what we could do with this signal?
 
I just unpacked a new SD card and plugged it into a Teensy 3.6.

SdInfo:
Code:
Assuming an SDIO interface.

type any character to start
init time: 126 ms

Card type: SDHC

Manufacturer ID: 0X3
OEM ID: SD
Product: SC16G
Version: 8.0
Serial number: 0XA4010BE8
Manufacturing date: 6/2011

cardSize: 15931.54 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true

OCR: 0XC0FF8000

SD Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
1,0X0,0X82,0X3,0X0,0XC,0XFE,0XFF,0XFF,8192,31108096
2,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
3,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
4,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0

Scanning FAT, please wait.

Volume is FAT32
sectorsPerCluster: 64
clusterCount:      485936
freeClusterCount:  485679
fatStartSector:    8790
dataStartSector:   16384

type any character to start
init time: 18 ms

Card type: SDHC

Manufacturer ID: 0X3
OEM ID: SD
Product: SC16G
Version: 8.0
Serial number: 0XA4010BE8
Manufacturing date: 6/2011

cardSize: 15931.54 MB (MB = 1,000,000 bytes)
flashEraseSize: 128 blocks
eraseSingleBlock: true

OCR: 0XC0FF8000

SD Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
1,0X0,0X82,0X3,0X0,0XC,0XFE,0XFF,0XFF,8192,31108096
2,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
3,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0
4,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0X0,0,0

Scanning FAT, please wait.

Volume is FAT32
sectorsPerCluster: 64
clusterCount:      485936
freeClusterCount:  485679
fatStartSector:    8790
dataStartSector:   16384

TeensySdioDemo:
Code:
SD cards must be power cycled to leave
SPI mode so do SDIO tests first.

Cycle power on the card if an error occurs.

Type '1' for FIFO SDIO
     '2' for DMA SDIO
     '3' for Dedicated SPI
     '4' for Shared SPI

FIFO SDIO mode.

size,write,read
bytes,KB/sec,KB/sec
512,18081.86,18995.38
1024,18354.41,19135.21
2048,18450.86,19319.15
4096,18616.07,19429.18
8192,18628.72,19476.91
16384,18641.10,19502.09
32768,17764.23,19497.60

totalMicros  6235782
yieldMicros  119780
yieldCalls   176
yieldMaxUsec 884
Done

Type '1' for FIFO SDIO
     '2' for DMA SDIO
     '3' for Dedicated SPI
     '4' for Shared SPI

DMA SDIO mode - slow for small transfers.

size,write,read
bytes,KB/sec,KB/sec
512,641.44,2040.90
1024,933.04,2797.25
2048,2055.78,4920.86
4096,5424.41,8521.87
8192,8517.28,12431.29
16384,12456.85,15988.96
32768,15568.80,18451.42

totalMicros  41344734
yieldMicros  40797235
yieldCalls   81341
yieldMaxUsec 114907
Done

Type '1' for FIFO SDIO
     '2' for DMA SDIO
     '3' for Dedicated SPI
     '4' for Shared SPI

Dedicated SPI mode.

size,write,read
bytes,KB/sec,KB/sec
512,3191.32,3274.82
1024,3206.42,3286.56
2048,3190.06,3291.98
4096,3213.62,3295.25
8192,3213.42,3294.78
16384,3216.56,3297.60
32768,3216.21,3297.97

totalMicros  36152599
yieldMicros  0
yieldCalls   0
yieldMaxUsec 0
Done

Type '1' for FIFO SDIO
     '2' for DMA SDIO
     '3' for Dedicated SPI
     '4' for Shared SPI

Shared SPI mode - slow for small transfers.

size,write,read
bytes,KB/sec,KB/sec
512,425.02,1077.16
1024,786.21,1660.10
2048,1390.03,2182.60
4096,2247.87,2635.44
8192,2594.29,2940.88
16384,2842.86,3103.53
32768,2870.93,3198.52

totalMicros  77324800
yieldMicros  0
yieldCalls   0
yieldMaxUsec 0
Done

I'm not sure if this info dump is useful, but I thought I'd share it because it can't hurt. I guess I'm good to go with this one since I didn't get any errors.

The next thing I need to do is read and write some kind of small configuration file - any favorite file formats and libraries for this?
 
Hey, it's an awesome library.

On Teensy 3.6 "Fastest with LTO" it's nearly 3 times as fast as the SD.h library. The way faster datarates and response times are crucial for time intense tasks, that can't be realised with SD.h.

Are you still working on it?
 
For all concerned,
Bill just corrected an "copy error" in the exFat library that was introduced last year (or so) and that affected the mkdir functionality.
The lastest version of SdFs is now working for my applications.
 
Status
Not open for further replies.
Back
Top