Ignorer et passer au contenu

Livraison offerte à partir de 50€ d'achats, livrée sous 48h !

Livraison à partir de seulement 2.50€ !

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Vos premiers pas avec votre lecteur de carte microSD uPesy

(Mis à jour le 04/07/2023)

Cette page va vous guider dans la prise en main du lecteur de carte micro SD d’uPesy. Il est compatible avec toutes les cartes : Arduino Uno, Arduino Nano, ESP8266, ESP32 et la Raspberry Pi Pico. Ce lecteur peut complètement être éteint depuis le code, pour consommer très peu d’énergie (1µA). Il est parfaitement adapté pour des projets sous batteries.

lecteur micro SD pour Arduino, ESP32 et Raspberry Pi Pico

Lecteur micro SD uPesy pour Arduino, ESP32, Raspberry Pi Pico

Branchement du module microSD

Le lecteur de carte microSD d’uPesy est un module polyvalent qui peut être utilisé avec différentes cartes électroniques, telles que les Arduino, ESP8266, ESP32 ou Pi Pico. Il possède un convertisseur de niveau logique intégré pour s’adapter le fonctionnement de la carte à la tension des niveaux logiques de la carte (5V ou 3.3V). Il est recommandé d’alimenter ce module avec une tension comprise entre 3.5 et 5V. Il peut être alimenté par exemple depuis l’USB ou depuis une batterie Lipo 4.2V.

Ce module utilise le bus SPI pour interfacer la carte microSD à votre microcontrôleur via les broches CS , MISOMOSI et SCLK .

Lecteur SD

Arduino Uno | Nano

ESP32

Pi Pico

CS | SS

D10

GPIO 5

GPIO 17

SCK | SCLK

D13

GPIO 18

GPIO 18

MOSI

D11

GPIO 23

GPIO 19

MISO

D12

GPIO 19

GPIO 16

5V

+5V

+5V ou VBAT

+5V

GND

GND

GND

GND

La broche optionnelle OFF est utile pour désactiver le lecteur depuis votre programme. Pour tester et valider votre montage, je vous conseille de ne pas l’utiliser tout de suite.

Note

La vitesse de communication SPI avec la carte SD est assez élevée par rapport à la plupart des autres capteurs/modules. Il est fréquent d’avoir des bugs de transmissions avec les lecteurs SD dus aux parasitages. En cas de soucis, éviter de relier le module sur une breadboard et utiliser des fils les plus courts possibles .

Communiquer avec la carte micro SD

Une fois les connexions réalisées, nous allons vérifier que le lecteur de carte micro SD fonctionne correctement en utilisant un petit programme de test. Dans le logiciel Arduino IDE, vous trouverez plusieurs exemples de codes pour tester le lecteur. Cependant, selon l’exemple choisi, la broche CS peut varier. C’est pourquoi je vous recommande de commencer par les codes ci-dessous pour vous assurer que la carte µSD est bien détectée.

Test du lecteur microSD pour les Arduino Uno & Nano

/*
uPesy SD card test

    (Micro) SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno
** MISO - pin 12 on Arduino Uno
** CLK - pin 13 on Arduino Uno
** CS - pin 10 (can be changed)
** 5V - +5V of Arduino
*/

#include <SPI.h>
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;

const int CS = 10;

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

Serial.print("\nInitializing SD card...");

// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, CS)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the CS pin to match your shield or module?");
    while (1);
} else {
    Serial.println("Wiring is correct and a card is present.");
}

// print the type of card
Serial.println();
Serial.print("Card type:         ");
switch (card.type()) {
    case SD_CARD_TYPE_SD1:
    Serial.println("SD1");
    break;
    case SD_CARD_TYPE_SD2:
    Serial.println("SD2");
    break;
    case SD_CARD_TYPE_SDHC:
    Serial.println("SDHC");
    break;
    default:
    Serial.println("Unknown");
}

// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
}

Serial.print("Clusters:          ");
Serial.println(volume.clusterCount());
Serial.print("Blocks x Cluster:  ");
Serial.println(volume.blocksPerCluster());

Serial.print("Total Blocks:      ");
Serial.println(volume.blocksPerCluster() * volume.clusterCount());
Serial.println();

// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("Volume type is:    FAT");
Serial.println(volume.fatType(), DEC);

volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
volumesize *= volume.clusterCount();       // we'll have a lot of clusters
volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
Serial.print("Volume size (Kb):  ");
Serial.println(volumesize);
Serial.print("Volume size (Mb):  ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Gb):  ");
Serial.println((float)volumesize / 1024.0);

Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);

// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}

void loop(void) {
}

Test du lecteur microSD pour les cartes ESP32

/*
uPesy SD card test

(Micro) SD card attached to SPI bus as follows:
** MOSI - pin 23 on ESP32
** MISO - pin 19 on ESP32
** CLK - pin 18 on ESP32
** CS - pin 5
** 5V - +5V of ESP32
*/

#include "FS.h"
#include "SD.h"
#include "SPI.h"

void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.name(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void createDir(fs::FS &fs, const char * path){
    Serial.printf("Creating Dir: %s\n", path);
    if(fs.mkdir(path)){
        Serial.println("Dir created");
    } else {
        Serial.println("mkdir failed");
    }
}

void removeDir(fs::FS &fs, const char * path){
    Serial.printf("Removing Dir: %s\n", path);
    if(fs.rmdir(path)){
        Serial.println("Dir removed");
    } else {
        Serial.println("rmdir failed");
    }
}

void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
        Serial.write(file.read());
    }
    file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
    file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("Message appended");
    } else {
        Serial.println("Append failed");
    }
    file.close();
}

void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}

void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}

void testFileIO(fs::FS &fs, const char * path){
    File file = fs.open(path);
    static uint8_t buf[512];
    size_t len = 0;
    uint32_t start = millis();
    uint32_t end = start;
    if(file){
        len = file.size();
        size_t flen = len;
        start = millis();
        while(len){
            size_t toRead = len;
            if(toRead > 512){
                toRead = 512;
            }
            file.read(buf, toRead);
            len -= toRead;
        }
        end = millis() - start;
        Serial.printf("%u bytes read for %u ms\n", flen, end);
        file.close();
    } else {
        Serial.println("Failed to open file for reading");
    }


    file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }

    size_t i;
    start = millis();
    for(i=0; i<2048; i++){
        file.write(buf, 512);
    }
    end = millis() - start;
    Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
    file.close();
}

void setup(){
    Serial.begin(115200);
    if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    uint64_t cardSize = SD.cardSize() / (1024 * 1024);
    Serial.printf("SD Card Size: %lluMB\n", cardSize);

    listDir(SD, "/", 0);
    createDir(SD, "/mydir");
    listDir(SD, "/", 0);
    removeDir(SD, "/mydir");
    listDir(SD, "/", 2);
    writeFile(SD, "/hello.txt", "Hello ");
    appendFile(SD, "/hello.txt", "World!\n");
    readFile(SD, "/hello.txt");
    deleteFile(SD, "/foo.txt");
    renameFile(SD, "/hello.txt", "/foo.txt");
    readFile(SD, "/foo.txt");
    testFileIO(SD, "/test.txt");
    Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
    Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

void loop(){

}

Test du lecteur microSD pour la carte Raspberry Pi Pico

/*
    uPesy SD card test

    (Micro) SD card attached to SPI bus as follows:
    ** MOSI - pin 19 on Pi Pico
    ** MISO - pin 16 on Pi Pico
    ** CLK - pin 18 on Pi Pico
    ** CS - pin 17 on Pi Pico
    ** 5V - +5V of Pi Pico
*/

#include <SPI.h>
#include <SD.h>

File root;

void setup() {
    delay(5000);
    // Open serial communications and wait for port to open:
    Serial.begin(115200);

    Serial.print("Initializing SD card...");

    if (!SD.begin(SS)) {
        Serial.println("initialization failed!");
        return;
    }
    Serial.println("initialization done.");

    root = SD.open("/");

    printDirectory(root, 0);

    Serial.println("done!");
}

void loop() {
// nothing happens after setup finishes.
}

void printDirectory(File dir, int numTabs) {
while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
    // no more files
    break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
    Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
    Serial.println("/");
    printDirectory(entry, numTabs + 1);
    } else {
    // files have sizes, directories do not
    Serial.print("\t\t");
    Serial.print(entry.size(), DEC);
    time_t cr = entry.getCreationTime();
    time_t lw = entry.getLastWrite();
    struct tm * tmstruct = localtime(&cr);
    Serial.printf("\tCREATION: %d-%02d-%02d %02d:%02d:%02d", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec);
    tmstruct = localtime(&lw);
    Serial.printf("\tLAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec);
    }
    entry.close();
}
}

Utilisation du mode économie d’énergie

Ce module dispose d’une broche supplémentaire OFF qui permet d’allumer/éteindre le module selon la valeur du niveau logique :

  • 3.3V ou 5V : Le module est allumé.

  • 0V : Le module est éteint et donc la carte µSD aussi

Si la broche OFF n’est pas utilisée, le lecteur est par défaut allumé. Cette fonctionnalité est complètement optionnelle.

Elle est très utile dans les projets alimentés sur batterie, qui utilisent ponctuellement une carte SD pour enregistrer des données. Au lieu que le module soit alimenté en permanence, il sera activé uniquement au moment d’enregistrer des données. Cela permet d’augmenter considérablement l’autonomie d’un data-loggeur qui par exemple enregistre sur carte SD la température ambiante toute les 30mins.

Lorsque le lecteur est désactivé, la consommation n’est que de 1µA.

Caractéristiques techniques

  • La communication avec votre carte µSD se fait via SPI

  • Tension d’alimentation comprise entre 3.5V et 6.5V.

  • Le lecteur contient un convertisseur de niveaux logiques (5V → 3.3V) pour être utilisé par des cartes Arduino sans risquer d’endommager la carte microSD fonctionnant en 3.3V.

  • Protection contre les inversions de polarité (si vous inversez l’alimentation et la masse), pour ne pas endommager la carte µSD.

  • Le lecteur contient 2 trous de fixations pour des vis M2 (Ø2,2 mm)

  • Consommation en courant :

    • Lecteur désactivé via la broche OFF : environ 1µA

      lecteur micro sd upesy consomme en mode économie d'énergie seulement 1µA

      Le module consomme en moyenne 1µA en mode économie d’énergie

    • Lecteur activé avec une carte µSD de branché. (Mode IDLE : la communication SPI n’est pas utilisée) : Autour de 150µA

      150uA idle current
    • Lecture/écriture sur la carte µSD : < 30 mA en général, dépend de la carte µSD