Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: Teensy 4.0: SD card problems/errors

  1. #1
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9

    Teensy 4.0: SD card problems/errors

    I want to hook up my Micro-SD Card with my Teensy 4.0. I want to use the SPI-Pins of my Teensy rather than the pads on the back (I connected it correct but for CS i used Pin 10 instead of 4 and changed chipSelect to 10). Is this possible? And how do I get the SD library to work with my board? I'm only getting errors :(

    I already talked with someone on Reddit (maybe the chat will help): https://www.reddit.com/r/arduino/com...osd_card_with/

    I hope nothing is mission or it is too messy. It's my first post on aa forum like this...

    Error message: no matching function for call to 'SDClass::open(String&, int)'

    Code:
    #include <SPI.h>
    #include <SD.h>
    #include <math.h>
    
    #define LED_PIN 2
    
    const int chipSelect = 10;
    
    long randNumber;
    String filename = "";
    String dataString = "";
    
    unsigned long i = 3;
    unsigned long nr = 2;
    unsigned long old_t = 0;
    unsigned long delta_t = 0;
    
    /*
    unsigned long long i = 3;
    unsigned long long nr = 2;
    unsigned long long old_t = 0;
    unsigned long long delta_t = 0;
    */
    
    void setup() {
      pinMode(LED_PIN, OUTPUT);
      digitalWrite(LED_PIN, LOW);
      
      Serial.begin(115200);
      
      Serial.print("Initializing SD card... ");
      if (!SD.begin(chipSelect)) {
        Serial.println("Card failed, or not present!");
        digitalWrite(LED_PIN, HIGH);
        while (1);
      }
      
      Serial.println("Card initialized.");
    
      randomSeed(analogRead(0));
      randNumber = random(10000000, 100000000);
      filename += String(randNumber);
      filename += String(".txt");
    
      File dataFile = SD.open(filename, FILE_WRITE);     // Line of Error
    
      if (dataFile) {
        dataFile.println("Nr;Prime;Calc_Time(us);Runtime(us)");
        
        dataString = "";
      
        dataString += String("1;2;0;");
        dataString += String(micros());
    
        dataFile.println(dataString);
    
        dataFile.close();
      }
    
      else {
        Serial.print("Error opening ");
        Serial.print(filename);
        Serial.println(".");
        digitalWrite(LED_PIN, HIGH);
        while (1);
      }
    
      Serial.println();
    
    }
    
    void loop() {
      old_t = 0;
     
      old_t = micros();
      long prime = is_prime(i);
      delta_t = micros() - old_t;
     
      if (prime == 1) {
        Serial.println(nr);
    
        dataString = "";
      
        dataString += String(nr);
        dataString += String(";");
        dataString += String(i);
        dataString += String(";");
        dataString += String(delta_t);
        dataString += String(";");
        dataString += String(micros());
    
        File dataFile = SD.open(filename, FILE_WRITE);
    
        if (dataFile) {
          dataFile.println(dataString);
          dataFile.close();
        }
    
        else {
          Serial.print("Error opening ");
          Serial.print(filename);
          Serial.println(".");
          digitalWrite(LED_PIN, HIGH);
          while (1);
        }
           
        nr++;
      }
    
      i = i + 2;
    }
    
    
    bool is_prime(uint32_t n){
      if(n<=1) return false;
      else if (n<=3) return true;
      else if(n%2==0 or n%3==0) return false;
      uint32_t i= 5;
        while (i * i <=n)
        {
          if(n%i== 0 or n%(i + 2) == 0) return false;
           i+=6;
        }
      return true;
      nr++;
    }

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,538
    Your issue is the SD library does not accept the String library. Generally, due to the limited memory on microprocessors, it isn't a good idea to use the String class (granted the 4.0 has more memory, but still it can be a problem).

    Instead you should use the C string functions (strcpy, strcat, memcpy) and/or sprintf to build up the filename.

    Code:
    #define MAX_NAME_LEN 32
    #define MAX_DATA_LEN 32
    char filename[MAX_NAME_LEN];
    char dataString[MAX_DATA_LEN];
    
    // ...
    
      randomSeed(analogRead(0));
      randNumber = random(10000000, 100000000);
      sprintf (filename, "%ld.txt", randNumber);

  3. #3
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    Thx. That worked. But now I got a new problem...

    It says: incompatible types in assignment of 'const char [1]' to 'char [32]'

    Could it be that I have to change all my dataString += ... commands and my write command? If so, how do I do that? I'm a C++ beginner, only used to easy "Arduino-C"

    And does #define MAX_DATA_LEN 32 mean I have to split my write command if I want to write more than 32 characters? Because my output lenght rises very fast thanks to the 600MHz chip


    Code:
      if (dataFile) {
        dataFile.println("Nr;Prime;Calc_Time(us);Runtime(us)");
        
        dataString = "";       //Line of Error
      
        dataString += String("1;2;0;");
        dataString += String(micros());
    
        dataFile.println(dataString);
    
        dataFile.close();
      }

  4. #4
    Senior Member
    Join Date
    Nov 2017
    Location
    Belgium
    Posts
    215
    You could also use the c_str() StringObject Function.
    Code:
    File dataFile = SD.open(filename.c_str(), FILE_WRITE);

  5. #5
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,538
    Quote Originally Posted by 3Domse3 View Post
    Thx. That worked. But now I got a new problem...

    It says: incompatible types in assignment of 'const char [1]' to 'char [32]'

    Could it be that I have to change all my dataString += ... commands and my write command? If so, how do I do that? I'm a C++ beginner, only used to easy "Arduino-C"

    And does #define MAX_DATA_LEN 32 mean I have to split my write command if I want to write more than 32 characters? Because my output lenght rises very fast thanks to the 600MHz chip
    No, just bump up MAX_DATA_LEN to whatever size that is the maximum for your output + 1 for the trailing null byte.

  6. #6
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    But what is this error: incompatible types in assignment of 'const char [1]' to 'char [32]'

    Can't figure it out

  7. #7
    Quote Originally Posted by 3Domse3 View Post
    But what is this error: incompatible types in assignment of 'const char [1]' to 'char [32]'

    Can't figure it out
    you cant treat a c character array like a c++ String object.

    Code:
    #define MAX_NAME_LEN 32
    #define MAX_DATA_LEN 32
    char filename[MAX_NAME_LEN];
    char dataString[MAX_DATA_LEN];

    Code:
        dataString = "";       //Line of Error
      
        dataString += String("1;2;0;");
        dataString += String(micros());

    its probably best if you go back to using the String object like you did before and then calling dataString.c_str() when you want to convert it into a c character array for the library.

    this is a bit ugly but otherwise you will have to learn how to use all the c character array functions like sprintf and so forth.

  8. #8
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    What do you mean with
    its probably best if you go back to using the String object like you did before and then calling dataString.c_str() when you want to convert it into a c character array for the library.

  9. #9
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,538

    Cool

    Quote Originally Posted by 3Domse3 View Post
    What do you mean with
    Use your original code, and use the c_str() method where it complains to change String into normal C-style char arrays.

    Code:
    #include <SPI.h>
    #include <SD.h>
    #include <math.h>
    
    #define LED_PIN 2
    
    const int chipSelect = 10;
    
    long randNumber;
    String filename = "";
    String dataString = "";
    
    unsigned long i = 3;
    unsigned long nr = 2;
    unsigned long old_t = 0;
    unsigned long delta_t = 0;
    
    /*
    unsigned long long i = 3;
    unsigned long long nr = 2;
    unsigned long long old_t = 0;
    unsigned long long delta_t = 0;
    */
    
    void setup() {
      pinMode(LED_PIN, OUTPUT);
      digitalWrite(LED_PIN, LOW);
      
      Serial.begin(115200);
      
      Serial.print("Initializing SD card... ");
      if (!SD.begin(chipSelect)) {
        Serial.println("Card failed, or not present!");
        digitalWrite(LED_PIN, HIGH);
        while (1);
      }
      
      Serial.println("Card initialized.");
    
      randomSeed(analogRead(0));
      randNumber = random(10000000, 100000000);
      filename += String(randNumber);
      filename += String(".txt");
    
      File dataFile = SD.open(filename.c_str(), FILE_WRITE);     // Line of Error
    
      if (dataFile) {
        dataFile.println("Nr;Prime;Calc_Time(us);Runtime(us)");
        
        dataString = "";
      
        dataString += String("1;2;0;");
        dataString += String(micros());
    
        dataFile.println(dataString);
    
        dataFile.close();
      }
    
      else {
        Serial.print("Error opening ");
        Serial.print(filename);
        Serial.println(".");
        digitalWrite(LED_PIN, HIGH);
        while (1);
      }
    
      Serial.println();
    
    }
    
    void loop() {
      old_t = 0;
     
      old_t = micros();
      long prime = is_prime(i);
      delta_t = micros() - old_t;
     
      if (prime == 1) {
        Serial.println(nr);
    
        dataString = "";
      
        dataString += String(nr);
        dataString += String(";");
        dataString += String(i);
        dataString += String(";");
        dataString += String(delta_t);
        dataString += String(";");
        dataString += String(micros());
    
        File dataFile = SD.open(filename.c_str(), FILE_WRITE);
    
        if (dataFile) {
          dataFile.println(dataString);
          dataFile.close();
        }
    
        else {
          Serial.print("Error opening ");
          Serial.print(filename);
          Serial.println(".");
          digitalWrite(LED_PIN, HIGH);
          while (1);
        }
           
        nr++;
      }
    
      i = i + 2;
    }
    
    
    bool is_prime(uint32_t n){
      if(n<=1) return false;
      else if (n<=3) return true;
      else if(n%2==0 or n%3==0) return false;
      uint32_t i= 5;
        while (i * i <=n)
        {
          if(n%i== 0 or n%(i + 2) == 0) return false;
           i+=6;
        }
      return true;
      nr++;
    }
    Note, I do not use the String library, but others have said that is the syntax to convert between String and char[].

  10. #10
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    Thank you very much. It compiles now without any Errors. As soon as I'm at home I'll try uploading it and will post an update.

    Already a big thanks to everyone who answered and tried to help me

    You are awesome

  11. #11
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    New problem...

    I'm using the code from MichaelMeissner and it compiles and uploads without any errors. But my SD card isn't getting recognised.

    My connections:
    Code:
    Module:  T4:
    GND   - GND
    VCC   - 3V
    MISO  - 12
    MOSI  - 11
    SCK   - 13
    CS    - 10
    My module: https://www.ebay.de/itm/2Stks-Micro-...72.m2749.l2649

    SD-Card: 4GB Micro SD, FAT32-System

    Does someone have an idea what's wrong? (Module works with Arduino Nano)

  12. #12
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,538

    Cool

    Quote Originally Posted by 3Domse3 View Post
    New problem...

    Does someone have an idea what's wrong? (Module works with Arduino Nano)
    Looking at the ebay page, the documentation says you need to feed it 4.5v or higher for VCC. So, you need to use VIN and not 3.3v to power the SD card reader. VIN is 5v if you use USB to power your Teensy. Presumably you would not be able to use a lithium-ion battery to power it, since they only produce 3.7-4.2v.

    Note, many of the Nanos run at 5v, while the Teensy LC/3.x/4.0 all run at 3.3v, which is presumably why it runs for the Nano. You can damage some Teensys (LC, 3.6, 4.0) if they get 5v on a data input line. So you need to be careful about mixing voltage. But the google translated document claimed that it was safe to use (whether it actually is, I don't know).

  13. #13
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    I tested it with the VCC pin connected to VIN after measuring all voltages and making (as good as possible) sure nothing will explode
    Everything works fine and the SD card gets written.

    Only promblem I have now is the slow write-speed. Without an SD I'm getting about 75,000 primes/s, now only 50 primes/s: /
    I don't think I can do much about it because my SD card or maybe the SPI communication is limiting me. If someone has an idea for improvements I'd appreciate it if you posted your ideas.

    My fixed and working code:

    Code:
    #include <SPI.h>
    #include <SD.h>
    #include <math.h>
    
    #define CONTR_LED 2
    
    const int chipSelect = 10;
    
    long randNumber;
    String filename = "";
    String dataString = "";
    
    unsigned long i = 3;
    unsigned long nr = 2;
    
    unsigned long old_t = 0;
    unsigned long delta_t = 0;
    unsigned int oflw1 = 0;
    unsigned int oflw2 = 0;
    
    
    void setup() {
      pinMode(CONTR_LED, OUTPUT);
      digitalWrite(CONTR_LED, LOW);
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, LOW);
      
      Serial.begin(115200);
      
      Serial.print("Initializing SD card... ");
      if (!SD.begin(chipSelect)) {
        Serial.println("Card failed, or not present!");
        digitalWrite(CONTR_LED, HIGH);
        while(1);
      }
      
      Serial.println("Card initialized.");
    
      randomSeed(analogRead(0));
      randNumber = random(10000000, 100000000);
      filename += String(randNumber);
      filename += String(".txt");
    
      File dataFile = SD.open(filename.c_str(), FILE_WRITE);
    
      if (dataFile) {
        dataFile.println("Nr;Prime;Overflows;Calc_Time(us);Runtime(us);Overflows");
        
        dataString = "";
      
        dataString += String("1;2;0;0;");
        dataString += String(micros());
        dataString += String(";0");
    
        dataFile.println(dataString);
    
        dataFile.close();
      }
    
      else {
        Serial.print("Error opening ");
        Serial.print(filename);
        Serial.println(".");
        digitalWrite(CONTR_LED, HIGH);
        while(1);
      }
    
      Serial.println();
    }
    
    
    void loop() {
      digitalWrite(LED_BUILTIN, LOW);
      
      old_t = micros();
      long prime = is_prime(i);
      delta_t = micros() - old_t;
     
      if (prime == 1) {
        digitalWrite(LED_BUILTIN, HIGH);
        
        Serial.println(nr);
    
        if(i > 4200000000){
        oflw1++;
        }
      
      if(micros() > 4200000000){
        oflw2++;
        }
    
        dataString = "";
      
        dataString += String(nr);
        dataString += String(";");
        dataString += String(i);
        dataString += String(";");
        dataString += String(oflw1);
        dataString += String(";");
        dataString += String(delta_t);
        dataString += String(";");
        dataString += String(micros());
        dataString += String(";");
        dataString += String(oflw2);
    
        File dataFile = SD.open(filename.c_str(), FILE_WRITE);
    
        if (dataFile) {
          dataFile.println(dataString);
          dataFile.close();
        }
    
        else {
          Serial.print("Error opening ");
          Serial.print(filename);
          Serial.println(".");
          digitalWrite(CONTR_LED, HIGH);
          while(1);
        }
           
        nr++;
      }
    
      i = i + 2;
    }
    
    
    bool is_prime(uint32_t n){
      if(n<=1){
        return false;
      }
      
      else if(n<=3){
        return true;
      }
      
      else if(n%2==0 or n%3==0){
        return false;
      }
      
      uint32_t i= 5;
        while (i * i <=n){
          if(n%i== 0 or n%(i + 2) == 0) return false;
          i+=6;
        }
        
      return true;
      nr++;
    }
    Again, thanks to everyone who helped me fixing my problems and explained my mistakes

  14. #14
    Junior Member 3Domse3's Avatar
    Join Date
    Jan 2020
    Location
    BW, Germany
    Posts
    9
    Attachment:

    I know that stuff like turning LEDs on and off and serial output will slow it down but I suspect the main bottleneck at transferring data to the SD card.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •