I2c/SPI flash/uSD/interrupt sampling design question

Status
Not open for further replies.

linuxgeek

Well-known member
What's the currently preferred method for implementing all these.

Interrupt sampling of i2c sensors written to SPI flash, that periodically copies data to uSD.
And then write to uSD card from SPI flash by transferring to RAM first so as to not interfere with samples getting written to SPI flash.

Essentially, how do you avoid long waits on uSD card to not interfere with interrupt sampling?
 
I looked through the Audio Library and I see Recorder.ino. Relevant snippets below

I'm not sure why SerialFlash.h is included. Is that needed?

Will the sdcard latency stay below that 5.8msec? If so, that will work fine for me. Any problem with including the SD writes within an interrupt sampling that's being called every 10 to 40msec?

Code:
// Record sound as raw data to a SD card, and play it back.

#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioRecordQueue         queue1;         //xy=281,63

void continueRecording() {
  if (queue1.available() >= 2) {
    byte buffer[512];
    // Fetch 2 blocks from the audio library and copy
    // into a 512 byte buffer.  The Arduino SD library
    // is most efficient when full 512 byte sector size
    // writes are used.
    memcpy(buffer, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    memcpy(buffer+256, queue1.readBuffer(), 256);
    queue1.freeBuffer();
    // write all 512 bytes to the SD card
    elapsedMicros usec = 0;
    frec.write(buffer, 512);
    // Uncomment these lines to see how long SD writes
    // are taking.  A pair of audio blocks arrives every
    // 5802 microseconds, so hopefully most of the writes
    // take well under 5802 us.  Some will take more, as
    // the SD library also must write to the FAT tables
    // and the SD card controller manages media erase and
    // wear leveling.  The queue1 object can buffer
    // approximately 301700 us of audio, to allow time
    // for occasional high SD card latency, as long as
    // the average write time is under 5802 us.
    //Serial.print("SD write, us=");
    //Serial.println(usec);
  }
}
 
Doing it in the loop, doesn't that still pose a problem with interrupt sampling where you don't want the sampling intervals to get shifted?
 
Doing it in the loop, doesn't that still pose a problem with interrupt sampling where you don't want the sampling intervals to get shifted?

I may misunderstand the problem, but ANY ISR is interrupting loop() as long the base priority is not raised explicitly.
So loop() is only processing if no other ISR based processing is running.
 
Will the sdcard latency stay below that 5.8msec?
You are WAY off base. All my MicroSD cards have worst-case latencies >800ms with standard file writes. That decreases to 30-45ms worst case latency with pre-allocated, pre-erased files.

Doing it in the loop, doesn't that still pose a problem with interrupt sampling where you don't want the sampling intervals to get shifted?
Writing inside 'loop()' is the way to go and doesn't interfere with interrupts. SdFat has no problem with getting interrupted and does a minimal amount of disabling interrupts (only for a handful of instructions).

Using pre-allocated files:
https://forum.pjrc.com/threads/43834-Real-low-latency-logging-for-Teensy-3-5-3-6-SDIO-SD
 
I sorta had this working before with sdfat, preallocation and multiple 512 byte buffers but I suspect it never worked quite right. That very well was just my coding.

Maybe I'll try a simple example and post it. My other question is what current is expected to run the sdcard continuously like that? And is there any problem with peak currents not being able to be handled by the teensy?
 
My other question is what current is expected to run the sdcard continuously like that?
A typical datasheet value is 200mA max averaged over 1s for high speed operation (50MHz), peak current is rarely specified.

While the card is not actively writing, but has open commands (e.g. open-ended SdFat writes), power consumption for my cards is 15mA - 35mA (depending on the card).

If there are no open commands and the card can go to sleep, power consumption is usually 100uA - 200uA for decent cards.
 
200mA is more than the teensy LC/3.0/3.1 (100mA) can provide, and it's fairly close to the 250mA the teensy 3.2 can provide.
Are there any special power considerations that have to be done? I know the current draw causes problems with the ADC, but will it effect the digital signals like i2c or SPI?
 
What's the currently preferred method for implementing all these.

Interrupt sampling of i2c sensors written to SPI flash, that periodically copies data to uSD.
And then write to uSD card from SPI flash by transferring to RAM first so as to not interfere with samples getting written to SPI flash.

Essentially, how do you avoid long waits on uSD card to not interfere with interrupt sampling?

I just tried out my Teensy 3.6 based rocket data logger of MPU9250 data yesterday. It captures data from the MPU9250 over SPI in an interrupt routine and records at ~256KB/sec.

The program structure is fairly simple with data capture in the interrupt service routine and the foreground task writing data to the uSD card. The ISR stores data into one of many 16KB SRAM data buffers. It only runs into trouble if the foreground task fails to write full buffers fast enough.
 
I'm not sure why SerialFlash.h is included. Is that needed?

Old versions of Arduino require you to include all the libraries used by any of the libs you're using. Since parts of the audio lib (which you're not using) make use SerialFlash.h, it needs to be included in your program even though no part of your program actually uses SerialFlash.

Yes, that's a silly requirement. It has been fixed in newer Arduino versions. But Teensyduino supports many versions of Arduino, all the way back to 1.0.6.

If you're using a modern version of Arduino, you can delete all the includes except the ones you're actually using in your program (Audio, SD from the code shown).
 
Status
Not open for further replies.
Back
Top