You are currently viewing Photos sur Carte SD par SPI avec l’ESP32-CAM
Enregistrer des photos sur SD Card par SPI avec l'ESP32-CAM

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 .

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:

Caractéristiques de la carte Micro SD affichées sur le moniteur série
Caractéristiques de la carte Micro SD affichées sur le moniteur série

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.

S’abonner
Notification pour
guest
0 Commentaires
Commentaires en ligne
Afficher tous les commentaires