Features in this library are now in the SdFat-beta library.
https://github.com/greiman/SdFat-beta
SdFat-beta will soon be released as SdFat V.2
Arduino FAT16/FAT32/exFAT Library
License: MIT License
Features in this library are now in the SdFat-beta library.
https://github.com/greiman/SdFat-beta
SdFat-beta will soon be released as SdFat V.2
I have been observing a seemingly random bias in the ADC readings on a Teensy 3.6 when using the SDIO interface. Switching to the SPI interface solves the issue.
Setup:
Code:
Attached, but the overview is that ADC readings are taken on an InterruptTimer and the raw value is printed out over Serial (for validation purposes). Depending on the configuration, a write to the SD card takes place once before the IntervalTimer is started and appears to instigate the issue. Pressing "s" starts logging with SD writing enabled, while pressing "n" starts logging with SD writing not enabled. Pressing any button while logging will stop logging.
Issue:
When logging is configured to write to the SD card with SDIO, the ADC results may consistently be biased by ~110 or ~230 ADC counts. The expected value is 0 since the pin is connected to AGND. Different logging sessions (stop/start logging) result in different bias values (including 0 bias), and the bias remains until logging is stopped. The code is set up to work with any pin connected to ADC1, but I have seen the same issue with ADC0.
Environment:
PlatformIO, version 3.5.3b2
teensy platform, version 3.1.0
framework-arduinoteensy, version 1.141.0
Workaround:
Use SPI interface instead of SDIO, although SPI is less than half the speed of SDIO.
Sample output with SD card enabled:
Press "s" to log with the SD card enabled or "n" to log with the SD card disabled
Starting Logging
Timers started
108
113
115
108
111
105
108
106
112
111
102
data logging stopped
Press "s" to log with the SD card enabled or "n" to log with the SD card disabled
Starting Logging
Timers started
113
105
105
106
109
110
110
109
108
107
110
105
data logging stopped
Press "s" to log with the SD card enabled or "n" to log with the SD card disabled
Starting Logging
Timers started
0
0
0
0
0
0
0
0
0
0
0
0
0
data logging stopped
I have also noticed the issue on the FRDM-K66F board from NXP, which uses (almost) the same chip as the Teensy. This leads me to believe that the issue either stems from the chip (I have reached out to NXP to see if this is the case) or has something to do with the SdFs library (though I have scoured the code and haven't seen any indications that this is the case, but I could easily have missed something). I have modified both boards (FRDM-K66F and Teensy 3.6) with a precision reference voltage, and scope readings look clean.
Hi, i have been writing to the SD card using a SdFatEX instance and SdBaseFile.
It was working fine however i'm now being returned false from the SdBaseFile.createContiguous() function.
The SD card has a 2MB file on it containing binary information, i can read the SD card using my computers SD card reader, but the Arduino cannot write to it?
I have debugged the error and the trace is:
FatFile.cpp:
line 149: (count = 59, m_firstcluster= 0, startcluster = 0)FatFileLFN.cpp:
line 584: (m_vol->cache_sync() returns false.)
Here is my sample code:
inFileName = "test.bin"
inFileLength = 480000
if (m_SD.exists(inFileName))
{
m_SD.remove(inFileName);
}
m_fileForStream.close();
// setup continguous file
bool contigFileOK = m_fileForStream.createContiguous(inFileName, inFileLength);
if (!contigFileOK)
{
// Error here <---------
}
// get the block range
bool rangeOK = m_fileForStream.contiguousRange(&m_blockBegin, &m_blockEnd); // 16000bytes file
if (!rangeOK)
{
}
// Flash erase all data in the file.
Serial3.println(F("Erasing all data"));
Serial3.flush();
uint32_t bgnErase = m_blockBegin;
uint32_t endErase;
while (bgnErase < m_blockEnd)
{
endErase = bgnErase + ERASE_SIZE;
if (endErase > m_blockEnd)
{
endErase = m_blockEnd;
}
if (!m_SD.card()->erase(bgnErase, endErase))
{
Serial3.println("erase failed");
Serial3.flush();
}
bgnErase = endErase + 1;
}
Serial3.println("Erase complete");
Serial3.flush();
// start the multiple block writing routine.
bool writeStartOk = m_SD.card()->writeStart(m_blockBegin, inFileLength / 512U);
if (!writeStartOk)
{
// print error
}
Write function called multiple times:
m_SD.card()->writeData(buffer of 512 bytes);
Stop function
bool stopWriting = m_SD.card()->writeStop();
if (!stopWriting)
{
// print error
}
m_fileForStream.close();
Maybe it has something to do with the sd format but i'm not sure, any help?
Thanks!
Hi,
I am working on a data logger project on teensy. I am trying to use your library but I am not getting success. Can anyone guide me how to set MISO, MISO, and SCK as per the board.Thanks in advance
I tired to do a directory listing on exfat and it seems to fail. I can open the SD card, but the root "/" getName() returns '\0', then openNext() returns false.
bool ret=SD.begin( PIN_SD_CS);
if (ret == false)
{
ERROR("SD error %d",ret);//,TO_MHZ(48)));//,,&SPI2));
}
FsFile dir,f;
char str[50];
dir=SD.open("/");
dir.getName(str,50);
LOG("%s",str);
uint32_t i=0;
while (dir.openNext(&f) && i<170)
{
f.getName(str,50);
LOG("%s",str);
i++;
}
dir.close();
f.close();
Hi-Rali 8 GB microSDHC class 10
formatted with SD card formatter 5 to fat32 or Windows to exFat
testing CardInfo.ino or other examples
SD_SCK_MHZ(4) also 16, 8 , 2 , no luck
===== got random of this 2 errors:
SD errorCode: SD_CARD_ERROR_CMD58 = 0x12
SD errorCode: SD_CARD_ERROR_ACMD41 = 0x17
with
SD errorData = 0xf
SD errorData = 0x1
itc
=====
arduino's SD.h working with SPI_FULL_SPEED, SPI_HALF_SPEED, maybe other
the following example (on teensy3.2) does not work with exFAT formatted disks (PC formatted)
but it works with FAT32
observation:
directories created seems to be corrupt and do not allow file to be created inside or to be opened in PC
best,
Walter
#include "SdFs.h"
#include <time.h>
#define EPOCH_YEAR 1970 //T3 RTC
#define LEAP_YEAR(Y) (((EPOCH_YEAR+Y)>0) && !((EPOCH_YEAR+Y)%4) && ( ((EPOCH_YEAR+Y)%100) || !((EPOCH_YEAR+Y)%400) ) )
static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};
/* int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
*/
struct tm seconds2tm(uint32_t tt)
{ struct tm tx;
tx.tm_sec = tt % 60; tt /= 60; // now it is minutes
tx.tm_min = tt % 60; tt /= 60; // now it is hours
tx.tm_hour = tt % 24; tt /= 24; // now it is days
tx.tm_wday = ((tt + 4) % 7) + 1; // Sunday is day 1 (tbv)
// tt is now days since EPOCH_Year (1970)
uint32_t year = 0;
uint32_t days = 0;
while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= tt) year++;
tx.tm_year = 1970+year; // year is offset from 1970
// correct for last (actual) year
days -= (LEAP_YEAR(year) ? 366 : 365);
tt -= days; // now tt is days in this year, starting at 0
uint32_t month=0;
uint32_t monthLength=0;
for (month=0; month<12; month++)
{ monthLength = monthDays[month];
if ((month==1) & LEAP_YEAR(year)) monthLength++;
if (tt<monthLength) break;
tt -= monthLength;
}
tx.tm_mon = month + 1; // jan is month 1
tx.tm_mday = tt + 1; // day of month
return tx;
}
void dateTime(uint16_t* date, uint16_t* time) {
struct tm tx=seconds2tm(RTC_TSR);
// Return date using FS_DATE macro to format fields.
*date = FS_DATE(tx.tm_year, tx.tm_mon, tx.tm_mday);
// Return time using FS_TIME macro to format fields.
*time = FS_TIME(tx.tm_hour, tx.tm_min, tx.tm_sec);
}
/*********************************************************************/
SdFs sd;
FsFile root;
FsFile file;
#define SD_CS 10
#define SD_CONFIG SdSpiConfig(SD_CS, DEDICATED_SPI, SPI_FULL_SPEED)
void setup() {
// put your setup code here, to run once:
while(!Serial);
Serial.println("start");
SPI.setMOSI(7);
SPI.setSCK(14);
if (!sd.begin(SD_CONFIG)) sd.errorHalt("sd.begin failed");
// Set Time callback
FsDateTime::callback = dateTime;
sd.ls("/", LS_R);
char dirname[80]="folder1";
if(sd.exists(dirname))
if(!sd.rmdir(dirname))sd.errorHalt("sd.rmdir failed");
if(!sd.mkdir(dirname))sd.errorHalt("sd.mkdir failed");
if(!sd.chdir(dirname))sd.errorHalt("sd.chdir failed");
sd.ls("/", LS_R);
char filename[80]="file.dat";
if (!file.open(filename, O_CREAT | O_TRUNC |O_RDWR))
sd.errorHalt("file.open failed");
int nbuf=512;
static uint8_t buffer[512];
if (nbuf != file.write(buffer, nbuf)) sd.errorHalt("write failed");
file.truncate();
file.close();
Serial.println("end");
}
void loop() {
// put your main code here, to run repeatedly:
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.