BTS Mesure BTS Mesure
DébutTP 1UARTLED RGBBilanCapteursDataloggingStationUltrasonCAN seriePontRégulationCO2

Comment fonctionne une liaison SPI

Comme nous sommes curieux nous avons voulu visualiser comment communique l'Arduino (Master) avec une carte SD (Slave).

  • L'Arduino (Master) envoie des signaux à la carte SD (Slave) : Master Out Slave In (MOSI)
  • l'Arduino (Master) reçoit des signaux de la carte SD (Slave) : Master In Slave Out (MISO)

Pour cela nous avons réalisé un programme qui écrit sur la carte SD toutes les 2 secondes : xx;A;B;C/r/n  (xx étant le numéro de la mesure)

/*
  SD écrire A;B;C sur une carte SD

 * La carte SD est cablée ainsi au bus SPI :
 ** MOSI - pin 11     précablé sur les cartes d'extension
 ** MISO - pin 12    Les noms MOSI MISO et CLK sont déjà préprogrammé par Arduino
 ** CLK - pin 13
 ** CS - pin 10      ou pin 10 seule patte à déclarer dans le programme
 	 
 */
#include <SD.h>

int chipSelect=10;  // Peut-être 4 selon le shield utilisé
int i;             // Le numéro de mesure

void setup()
{
  Serial.begin(9600);
  pinMode(chipSelect, OUTPUT);
  IniSD();    // Appel Sous Programme pour initialiser le Saleae
}

// Boucle Principale :
void loop()
{
  i++;
  Serial.print("Mesure Numero ");Serial.println(i);
  File Saleae = SD.open("Saleae.csv", FILE_WRITE);
    if (Saleae) {
        Saleae.print(i); 
        Saleae.println(";A;B;C");       
        Saleae.close();
        Serial.print(i);
        Serial.println(";A;B;C");  
        }
      else Serial.println("Erreur Saleae.csv");
  delay(2000);
  
}

// Sous Programmes :

void IniSD()
{
    if (!SD.begin(chipSelect)){
       Serial.println("Erreur carte SD");
       return;}
    Serial.println("Carte presente");
}

SPI Arduino SD

Nous constatons que la SPI-CLOCK est à 4 MHz. Ce qui est la fréquence par défaut pour la liaison SPI d'un Arduino.

Il faut se méfier : le logiciel SALEAE échantillonne à 4 MHz ce qui est insuffisant et donne un résultat faux. Il faut AUGMENTER  la fréquence d'échantillonnage à 24 MHz.

Analyse du dialogue carte SD - Arduino

Nous avons été surpris de constater qu'écrire "137;A;B;C/r/n" demandait plus de 10 ms et un échange intense.

Voici une analyse succincte des échanges :

Vue d'ensemble SPI Arduino SD

Définitions Wikipédia :

Le secteur est la plus petite unité physique de stockage sur un support de donnée. Sa capacité est au minimum de 512 octets.

Un cluster est un groupe de secteurs. Il sert d'unité d'allocation aux fichiers. Un cluster comporte au minimum 8 secteurs en FAT32.

FAT, acronyme anglais de file allocation table (table d'allocation de fichiers), est un système de fichiers devenu un standard de l'industrie.

Un fichier comporte un nombre entier de cluster.

Analyse :

Au bilan pour écrire 10 octets, la bibliothèque SD réalise des manipulations assez complexes. Voici notre tentative d'analyse à partir de notre analyseur logique:

  • l'Arduino (MOSI) appelle le dernier cluster écrit.
  • La carte SD (MISO) répond en envoyant les 512 octets du cluster.
  • l'Arduino (MOSI) réécrit les 512 octets du cluster en écrasant les anciennes données par les nouvelles en fonction de la position du pointeur.
  • lorsque le pointeur arrive à la fin des 512 octets, on ajoute un nouveau cluster au fichier.
  • puis gestion des noms de fichiers, pointeurs et paramètres système pour le Root Directory et la table d'allocation.
  • cet échange demande environ 11 ms.

Arduino SD FAT 32Une carte SD utilise une table d'allocation de fichiers (FAT). L'unité de base pour écrire sur une carte SD en FAT32 est un cluster d'un minimum de 4 ko (soit 8 secteurs de 512 octets) .

Mais visiblement l'Arduino traite des clusters de 512 Octets (1cluster = 1 secteur). Comme le montre les propriétés du fichier (image ci-contre)

Pour stocker 3082 Octets il lui faut  7 clusters de données de 512 Octets + 1 cluster contenant la pile  en cours d'écriture ? (à vérifier)

Mais la taille réelle d'un cluster est de 4096 Octets. (en FAT 32 1 cluster = 8 secteurs minimum)

 Au bilan la place occupée par le fichier de 3082 octets est de 8*4096 = 32768 octets.