Accéder à la carte Micro SD
Pour la gestion de la carte Micro SD, nous utilisons la bibliothèque SD déjà mise à disposition dans l’environnement de développement lors de l’installation de la carte ESP32-CAM pour l’Arduino IDE. Il reste simplement à la déclarer par l’instruction:
#include <SD.h>
Dans cette étape du tutoriel, le programme réalisé va ouvrir le système de fichier de la carte Micro SD, récupérer ses caractéristiques et les afficher puis le fermer.
Les broches SPI du lecteur de carte
La description du brochage de l’ESP32-CAM permet de déduire les 4 broches utilisées pour l’échange de données avec la carte Micro SD par protocole SPI:
- MISO (IO2): pour l’envoi des données au microcontrôleur. Ce sont des données lues sur la carte ou bien ce sont des données de protocole (réponses à des commandes).
- CS (IO13): permet au microcontrôleur de sélectionner l’esclave avec lequel il souhaite communiquer.
- SCLK (IO14): horloge série pour synchroniser les échanges avec le microcontrôleur.
- MOSI (IO15): pour l’envoi des données sur la carte Micro SD. Ces données peuvent être du contenu à écrire ou bien des données de protocole (commandes).
// Brochage lecteur de cartes: #define PORT_CARD_SCLK 14 #define PORT_CARD_MISO 2 #define PORT_CARD_MOSI 15 #define PORT_CARD_CS 13
Les broches du lecteur intégré de carte Micro SD ne correspondent pas au brochage SPI par défaut de l’ESP32. Aussi il est nécessaire de les assigner avant d’utiliser cette interface.
Assignation du brochage SPI
L’assignation du brochage SPI commence par la déclaration d’une classe SPI avec en paramètre le bus matériel associé (c’est à dire VSPI ou HSPI pour l’ESP32). Le choix du bus n’a pas d’importance pour le projet :
SPIClass hspi_G(HSPI);
Nous utilisons ensuite la méthode “begin” de cette classe pour préciser au microcontrôleur le brochage à utiliser pour le bus SPI:
hspi_G.begin(port_CLK_p, PORT_CARD_MISO, port_MOSI_p, port_CS_p);
Ouverture/fermeture du système de fichier de la carte Micro SD
L’objet « SD » de la librairie “SD“ permet l’ouverture du système de fichier par la méthode “begin“. Dans le cas de l’ESP32-CAM, nous lui passons 3 paramètres :
- la boche CS,
- la classe SPI que nous venons d’initialiser,
- la fréquence que nous forçons à 80 MHz (soit la fréquence maximale du bus SPI pour l’ESP32) plutôt que de la laisser à sa valeur par défaut 40 MHz.
if (!SD.begin(port_CS_p, hspi_G, 80000000)) { Serial.println("Carte SD absente, mal formatée ou lecteur mal câblé."); }
La méthode « end » du même objet SD ferme un système de fichier préalablement ouvert:
SD.end();
Récupérer les caractéristiques de la carte Micro SD
Une fois le système de fichier ouvert, la librairie « SD » offre plusieurs méthodes pour récupérer les caractéristiques de la carte Micro SD insérée:
- « cardType » : permet de déterminer le standard de carte : SD pour Secure Digital (ou SDSC pour SD Standard Capacity), MMC pour MultiMediaCard ou SDHC pour SD High Capacity.
- « numSectors » : nombre total de secteurs présents sur la carte.
- « sectorSize » : taille d’un secteur en octets.
- « totalBytes » : taille de la carte en octets.
- « usedBytes » : nombre d’octets utilisés sur la carte.
Pour ce tutoriel, nous choisissons d’afficher sur le port série le nombre et la taille des secteurs de la carte Micro SD ainsi que sa capacité totale obtenue en multipliant ces deux première grandeurs entre elles.
Pour être plus lisible, la taille totale n’est affichée en octets mais en Gio (gigaoctet binaire) et Go (gigaoctet décimal). La différence entre ces deux unités de mesure est expliquée ici et là.
nombre_secteurs_l = SD.numSectors(); taille_secteur_l = SD.sectorSize(); sprintf(tampon_traces_g, "Découpée en %u secteurs de %u octets, soit une capacité de %.2f Go ou de %.2f Gio", nombre_secteurs_l, taille_secteur_l, ((float)nombre_secteurs_l * (float)taille_secteur_l)/(1000.0*1000.0*1000.0), ((float)nombre_secteurs_l * (float)taille_secteur_l)/(1024.0*1024.0*1024.0)); Serial.println(tampon_traces_g);
L’espace disponible sur la carte Micro SD est calculé en effectuant la différence et la taille totale et le nombre d’octets utilisés:
sprintf(tampon_traces_g, "Il reste %.2f Gio de disponibles.", ((float)SD.totalBytes()-(float)SD.usedBytes())/(1024.0*1024.0*1024.0)); Serial.println(tampon_traces_g);
Code logiciel de l’accès à la carte Micro SD
Voici l’ensemble du code pour cette partie:
/* Déclaration des librairies utilisées */ #include <SD.h> /* Définition des constantes globaless */ // Brochage lecteur de cartes: #define PORT_CARD_SCLK 14 #define PORT_CARD_MISO 2 #define PORT_CARD_MOSI 15 #define PORT_CARD_CS 13 /* Déclaration des fonctions */ bool SD_demarre(int port_CLK_p, int port_MISO_p, int port_MOSI_p, int port_CS_p); /* Déclaration globales */ SPIClass hspi_G(HSPI); char tampon_traces_g[120]; // Fonction de démarrage, s'exécute une seule fois: void setup() { // Pour le debug Serial.begin(115200); Serial.println("-----\n"); // Initialisation de la carte SD while(!SD_demarre(PORT_CARD_SCLK, PORT_CARD_MISO, PORT_CARD_MOSI, PORT_CARD_CS)) { // On bloque la poursuite du programme tant qu'une carte SD correcte n'a pas été insérée delay(1000); } // Fermeture de la carte SD SD.end(); } // Fonction principale du programme, s'exécute en boucle: void loop() { } bool SD_demarre(int port_CLK_p, int port_MISO_p, int port_MOSI_p, int port_CS_p) { bool Retour_L; uint8_t type_carte_L; size_t nombre_secteurs_l, taille_secteur_l; // Valeur par defaut Retour_L = false; // Réassigne les ports SPI du bus HSPI hspi_G.begin(port_CLK_p, PORT_CARD_MISO, port_MOSI_p, port_CS_p); if (!SD.begin(port_CS_p, hspi_G, 80000000)) { Serial.println("Carte SD absente, mal formatée ou lecteur mal câblé."); } else { // Identification du type de carte type_carte_L = SD.cardType(); if(type_carte_L == CARD_NONE) { Serial.println("Carte SD illisible"); } else { Serial.print("Type de carte SD: "); switch(type_carte_L) { case CARD_MMC: Serial.println("MMC"); break; case CARD_SD: Serial.println("SDSC"); break; case CARD_SDHC: Serial.println("SDHC"); break; default: Serial.println("Inconnu"); break; } // Caractéristiques de la carte nombre_secteurs_l = SD.numSectors(); taille_secteur_l = SD.sectorSize(); sprintf(tampon_traces_g, "Découpée en %u secteurs de %u octets, soit une capacité de %.2f Go ou de %.2f Gio", nombre_secteurs_l, taille_secteur_l, ((float)nombre_secteurs_l * (float)taille_secteur_l)/(1000.0*1000.0*1000.0), ((float)nombre_secteurs_l * (float)taille_secteur_l)/(1024.0*1024.0*1024.0)); Serial.println(tampon_traces_g); sprintf(tampon_traces_g, "Il reste %.2f Gio de disponibles.", ((float)SD.totalBytes()-(float)SD.usedBytes())/(1024.0*1024.0*1024.0)); Serial.println(tampon_traces_g); Retour_L = true; } } return(Retour_L); }
Exécution du programme d’accès à la carte Micro SD
Une fois ce programme compilé et transféré dans l’ESP32-CAM, l’affichage obtenu sur le moniteur série permet de vérifier que la carte Micro SD est bien reconnue par l’ESP32-CAM:

Si vous obtenez le résultat ci-dessus, vous pouvez passer à la page suivante. Sinon je vous invite à revoir le formatage de votre carte Micro SD.
Super article, cela va beaucoup m’aider dans mon projet. Merci beaucoup.
Je suis content que cela vous soit utile…
De quel projet s’agit-il si ce n’est pas secret ? 😉