Can't compile SD card functionality (Teensy 3.1 / TeensyLoader 1.18 / Arduino 1.0.5 )

Status
Not open for further replies.

tarnerich

Member
I'm porting some code which includes SD card datalogging over to a Teensy 3.1, which has successfully run with Arduino versions Uno R3 and Pro Mini. I've hit some sort of barrier, possibly centered on the versions of the SD library I have available, even though all that I've read so far makes it seem like it should have been relatively easy.

The error messages are:

C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.cpp:418:9: error: prototype for 'uint8_t Sd2Card::init(uint8_t, uint8_t)' does not match any in class 'Sd2Card'
In file included from C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.cpp:21:0:
C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.h:187:11: error: candidates are: uint8_t Sd2Card::init(uint8_t, uint8_t, int8_t, int8_t, int8_t)
C:\..\arduino-1.0.5\libraries\SD\utility\Sd2Card.h:184:11: error: uint8_t Sd2Card::init(uint8_t)
C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.h:176:11: error: uint8_t Sd2Card::init()

The errors above are what I get when I use an SD library with files that have date stamps of 12/15/2013.

I have other SD libraries available (only one is present at a time in the libraries folder and I always exit then re-enter Arduino when I switch libraries). Each of them results in wildly different collections of errors, and in much greater quantity; the date stamps of them are 11/5/2013 (SDadafruit), another at 5/17/2013, and I also have SdFat which has a huge number of files with a wide range of dates (12/15/2013 for SdFat.h). Most of the files contain references to SparkFun authorship in the comments.

I have 2 questions so far:

a. Which SD library should I be using? A link to an download source would be great.

b. Can anyone spot a problem with these lines of code (which work beautifully with Arduinos):


What I have in the global code space:

#include <SPI.h>
#include <SD.h>
File logfile;
char filename[13];
const int slaveSelectPin = 10;


What I have in setup():

pinMode (slaveSelectPin, OUTPUT);

// see if the card is present and can be initialized:
if (!SD.begin(slaveSelectPin)) {
Serial.println("Is an SD card in place?");
}
// Construct a unique file name
strcpy(filename, "TGPS__00.CSV");
for (uint8_t i = 0; i < 100; i++) {
filename[6] = '0' + i/10;
filename[7] = '0' + i%10;
if (! SD.exists(filename)) { // create if does not exist, do not open existing, write, sync after write
break;
}
}
// Get ready to log
logfile = SD.open(filename, FILE_WRITE);
if( ! logfile ) {
Serial.println("No Go "); //Serial.println(filename);
while(1); // might as well stop if we can't open the file for logging
}


Supporting hardware information:
Teensy 3.1 (powered from 5V)
AdaFruit SD card breakout board (5V power, includes 5V, 3.3V level shifters for the data lines)
CS connected to Teensy pin 10
DO connected to Teensy pin 11
DI connected to Teensy pin 12
CLK connected to Teensy pin 13
 
I'm wondering if I have a library conflict from another source. I'm also using the version of TinyGPS that I copied from the Teensy web page. Here are the lines of code associated with that:

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object. */
TinyGPS gps;
HardwareSerial Uart = HardwareSerial();
void gpsdump(TinyGPS &gps);
void printFloat(double f, int digits = 2);

Probable simple mistake: I just realized that I have two versions of the TinyGPS library in my Arduino libraries folder. Each contains files with identical names. I'll have to investigate further by eliminating one or the oter: TinyGPS and TinyGPS_13.
 
I don't know if I understood your post correctly but I'll give it a try.

C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.cpp:418:9: error: prototype for 'uint8_t Sd2Card::init(uint8_t, uint8_t)' does not match any in class 'Sd2Card'
In file included from C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.cpp:21:0:
C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.h:187:11: error: candidates are: uint8_t Sd2Card::init(uint8_t, uint8_t, int8_t, int8_t, int8_t)
C:\..\arduino-1.0.5\libraries\SD\utility\Sd2Card.h:184:11: error: uint8_t Sd2Card::init(uint8_t)
C:\...\arduino-1.0.5\libraries\SD\utility\Sd2Card.h:176:11: error: uint8_t Sd2Card::init()

The errors above are what I get when I use an SD library with files that have date stamps of 12/15/2013.
The date fits SDfatlib, but the paths in the error messages don't. Is there a mistake in your description?

#include <SD.h>
This include won't work with SDfatlib. It includes the standard SD lib from arduino.

Additionally I wonder where SD is declared. This code doesn't seem to be compatible with arduinos SD lib or SDfatlib.
 
You did not post a complete program that demonstrates/reproduces the problem. Please read these guidelines.

http://forum.pjrc.com/threads/15136-Please-Post-Code-amp-Details-In-Your-Question!

What you did post was only a partial program. I put your code into a setup() function and added an empty loop() function. Your code compiles without any error. Here's a screenshot.

screen.png

Here is the *exact* code I tested, based on what you posted, with only minimal additions to form it into a complete program.

Code:
#include <SPI.h>
#include <SD.h>
File logfile;
char filename[13];
const int slaveSelectPin = 10;

void setup() {

  pinMode (slaveSelectPin, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(slaveSelectPin)) {
    Serial.println("Is an SD card in place?");
  }
  // Construct a unique file name
  strcpy(filename, "TGPS__00.CSV");
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    if (! SD.exists(filename)) { // create if does not exist, do not open existing, write, sync after write
      break;
    }
  }
  // Get ready to log
  logfile = SD.open(filename, FILE_WRITE);
  if( ! logfile ) {
    Serial.println("No Go "); //Serial.println(filename);
    while(1); // might as well stop if we can't open the file for logging
  }
}

void loop() {
}

Perhaps something else you didn't include in your post is causing the problem? If you had posted a complete program that reproduces the problem, I would have written a helpful answer, instead of this message...
 
I don't know if I understood your post correctly but I'll give it a try.


The date fits SDfatlib, but the paths in the error messages don't. Is there a mistake in your description?

The SD library that was in place at the time of my compile was most probably the one that is distributed with Arduino 1.0.5. I have also tried the Sdfat library but it gave me a much larger list of errors, different ones, when I tried to use it. Based on your next comment below I'm suspecting that I was naïve in thinking that one could be a drop-in replacement for the other. I've done C programming some time ago but much of the C++ syntax is opaque to me, which limits what I can learn by reading the .cpp files.

This include won't work with SDfatlib. It includes the standard SD lib from arduino.

Additionally I wonder where SD is declared. This code doesn't seem to be compatible with arduinos SD lib or SDfatlib.

It was cloned from the Arduino SD datalogging example which compiles and runs well with my Arduinos.

Code:
/*
  SD card datalogger
 
 This example shows how to log data from three analog sensors 
 to an SD card using the SD library.
 	
 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4
 
 created  24 Nov 2010
 modified 9 Apr 2012
 by Tom Igoe
 
 This example code is in the public domain.
 	 
 */

[B]#include <SD.h>[/B]

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
const int chipSelect = 4;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  [B]if (!SD.begin(chipSelect))[/B] {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
}

New information I can add from a clean development environment: just now on my work PC (not the same system I was using last night at home which led to my initial post), that example above compiles with no errors when the target is the Teensy 3.1. That did not happen when I tried it on my home PC last night. So this supports the idea that the development environment on my home PC is corrupted somehow.
 
Last edited:
I think you managed to place a second SD.h somewhere in you include paths. I don't know what you did, but don't place files in your arduino installation directory and remove all SD libraries from your sketchbook. This way it should work as far as I can imagine what you could have done wrong.
You don't need to remove SDfatlib because it's files have different names, but you can remove it because you don't use it.
 
Fixed!

I think you managed to place a second SD.h somewhere in you include paths. I don't know what you did, but don't place files in your arduino installation directory and remove all SD libraries from your sketchbook. This way it should work as far as I can imagine what you could have done wrong.
You don't need to remove SDfatlib because it's files have different names, but you can remove it because you don't use it.

Things are back on track now. Simply moving the extraneous SD library copies out of the Arduino directory structure didn't turn out to be enough. I still don't know what the minimal fix would have been; I nuked the whole Arduino directory and reinstalled it and Teensyduino.

Thanks you, potz! and Paul, for your help.

For the record, the standard Arduino distribution of the SD library is what I'm using.
 
Trying to get SD capability going as well. I have Arduino 1.6.7 installed and teensyduino 1.27. When I try to compile any of the examples, I get compile errors. To duplicate, grab the example 'cardinfo.ino' file from the example directory and try to compile it. I get these errors and it does not compile or run. I get the same behavior from all the examples in the sd example folder that I have tried:

Code:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:25:57: error: 'void (* SdFile::dateTime_)(uint16_t*, uint16_t*)' is not a static member of 'class SdFile'
void (*SdFile::dateTime_)(uint16_t* date, uint16_t* time) = NULL;
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:33:28: error: no 'uint8_t SdFile::addCluster()' member function declared in class 'SdFile'
uint8_t SdFile::addCluster() {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:46:35: error: no 'uint8_t SdFile::addDirCluster()' member function declared in class 'SdFile'
uint8_t SdFile::addDirCluster(void) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:61:44: error: no 'dir_t* SdFile::cacheDirEntry(uint8_t)' member function declared in class 'SdFile'
dir_t* SdFile::cacheDirEntry(uint8_t action) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:74:27: error: no 'uint8_t SdFile::close()' member function declared in class 'SdFile'
uint8_t SdFile::close(void) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:91:71: error: no 'uint8_t SdFile::contiguousRange(uint32_t*, uint32_t*)' member function declared in class 'SdFile'
uint8_t SdFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:130:44: error: no 'uint8_t SdFile::createContiguous(SdFile*, const char*, uint32_t)' member function declared in class 'SdFile'
const char* fileName, uint32_t size) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:158:36: error: no 'uint8_t SdFile::dirEntry(dir_t*)' member function declared in class 'SdFile'
uint8_t SdFile::dirEntry(dir_t* dir) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:178:50: error: no 'void SdFile::dirName(const dir_t&, char*)' member function declared in class 'SdFile'
void SdFile::dirName(const dir_t& dir, char* name) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:201:46: error: no 'void SdFile::ls(uint8_t, uint8_t)' member function declared in class 'SdFile'
void SdFile::ls(uint8_t flags, uint8_t indent) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:245:58: error: no 'uint8_t SdFile::make83Name(const char*, uint8_t*)' member function declared in class 'SdFile'
uint8_t SdFile::make83Name(const char* str, uint8_t* name) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:284:57: error: no 'uint8_t SdFile::makeDir(SdFile*, const char*)' member function declared in class 'SdFile'
uint8_t SdFile::makeDir(SdFile* dir, const char* dirName) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:384:74: error: no 'uint8_t SdFile::open(SdFile*, const char*, uint8_t)' member function declared in class 'SdFile'
uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:476:68: error: no 'uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)' member function declared in class 'SdFile'
uint8_t SdFile::open(SdFile* dirFile, uint16_t index, uint8_t oflag) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:502:64: error: no 'uint8_t SdFile::openCachedEntry(uint8_t, uint8_t)' member function declared in class 'SdFile'
uint8_t SdFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:550:26: error: 'uint8_t SdFile::openRoot' is not a static member of 'class SdFile'
uint8_t SdFile::openRoot(SdVolume* vol) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:550:26: error: 'SdVolume' was not declared in this scope
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:550:36: error: 'vol' was not declared in this scope
uint8_t SdFile::openRoot(SdVolume* vol) {
^
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD\utility\SdFile.cpp:550:41: error: expected ',' or ';' before '{' token
uint8_t SdFile::openRoot(SdVolume* vol) {
^
exit status 1
Error compiling.
 
Turn on verbose info in File > Preferences. Then compile again, and much more info will appear. Use the Copy Error Messages button, and paste it all here in code tags. The extra info is really useful for figuring out what's wrong.

But usually the problem ends up being a conflicting library in Documents/Arduino/libraries. The SD library example do all compile without any error when no other conflicting libs are present.
 
Paul,

Thanks! That was it. I removed all the libraries I am not currently using from the libraries directory and now they compile. We will now see if I can write a file to the SD card!

Keith
 
Status
Not open for further replies.
Back
Top