samedi 15 février 2014

Carte SD, MSP430 Launchpad et Energia

Comme le titre l'indique, nous allons nous amuser à lire et écrire sur une carte SD en utilisant le MSP430 Launchpad de Texas Instruments.  Pour ce faire, je vais encore une fois utiliser les petits lecteurs de carte commercialisés par LC Studio, puisqu'ils sont facile à trouver et ne coûtent presque rien...  Et pas question de se compliquer la vie avec Code Composer Studio:  nous utiliserons Energia afin de programmer le Launchpad à la manière Arduino.

Le Launchpad comporte un avantage sur l'Arduino: puisqu'il fonctionne à 3,3 V, aucune conversion de niveau logique ne sera requise:  votre lecteur de carte SD sera donc branché directement au Launchpad, de la façon suivante:

Carte SD  ------ Launchpad
GND         ------    GND
+3.3          ------    Vcc
+5             ------    Pas branché
CS            ------     P2.0
MOSI       ------     P1.7
SCK         ------    P1.5
MISO       ------    P1.6


Attention:  ces branchements sont valables pour un Launchpad muni du MSP430G2553; d'autres microcontrôleurs supportés par le Launchpad ont leurs pins MOSI et MISO inversées (consultez cette référence pour connaître avec certitude la position des pins de votre configuration).

Côté logiciel, toutefois, le Launchpad est nettement désavantagé par rapport à l'Arduino.  Le problème, c'est qu'il comporte beaucoup moins de mémoire RAM.  Par conséquent, la seule bibliothèque qu'on peut raisonnablement utiliser pour gérer une carte SD est la "Petit FatFS" (oui, je sais, ce nom est épouvantable). Spécialement conçue pour les microcontrôleurs à mémoire restreinte, cette bibliothèque n'offre pas toutes les fonctions auxquelles ont pourrait généralement s'attendre.  Ainsi, elle est incapable de créer un fichier sur la carte SD:  on peut uniquement lire un fichier, ou écrire à l'intérieur d'un fichier déjà existant.  Et ce fichier doit avoir été créé à une taille qui convient à nos besoins, car la bibliothèque "Petit FatFS" n'est pas en mesure de le redimensionner!

Si ces contraintes ne vous rebutent pas, vous pouvez donc télécharger et installer la bibliothèque "Petit FatFS" (vous la placez dans Energia/hardware/msp430/libraries).

Le sketch ci-dessous est évidemment très inspiré des exemples qui accompagnent la bibliothèque.   Si vous désirez l'essayer, vous devez d'abord télécharger ce fichier texte et le copier sur votre carte SD.  Ce fichier contient le texte "Nombre de visites du Launchpad dans ce fichier: 1 ".

Le sketch est prévu pour fonctionner pendant que le serial monitor d'Energia est actif.  Puisque tout est dans la partie "Setup", le code ne s'exécute qu'une seule fois et vous devrez appuyer sur le bouton "reset" si vous désirez qu'il s'exécute à nouveau.

1)  Le sketch fait d'abord la liste des fichiers et répertoires qui se trouvent sur la carte SD, et affiche cette liste dans le moniteur série.
2) Si le fichier "test.txt" existe, on l'ouvre, on lit son contenu afin de l'afficher dans le moniteur série, puis on le referme.
3)  On ouvre à nouveau le fichier afin d'incrémenter le nombre qui s'y trouve:  le texte va donc devenir "Nombre de visites du Launchpad dans ce fichier: 2 ".  On referme le fichier.
4)  On ouvre une nouvelle fois le fichier pour lire son contenu et l'afficher dans le moniteur série, pour vérifier que les modifications ont été enregistrées avec succès.




/************** Carte SD et Launchpad ***************************
*
* Exemple de lecture et écriture de carte SD avec un MSP430 Launchpad,
* Energia et la bibliotheque "Petit FatFs"
* Connexions (avec un MSP430G2553: MISO et MOSI sont inversés sur
* d'autres modèles).
* Carte SD ----- Launchpad
* GND ----------- GND
* +3.3 ---------- Vcc
* CS ------------ P2.2
* MOSI ---------- P1.7
* SCK ----------- P1.5
* MISO ---------- P1.6
*
* http://electroniqueamateur.blogspot.com/2014/02/carte-sd-msp430-launchpad-et-energia.html
*
****************************************************************/
#include "SPI.h"
#include "pfatfs.h" // bibliotheque pour les cartes SD
#define cs_pin 10 // chip select pin (P2.2)
unsigned short int bw, br;
char buffer[128]; // où 128 est la taille du buffer (en bytes).
int erreur;
DIR dir; // objet répertoire
FILINFO fno; // objet information sur le fichier
int compteur = 0;
void setup() {
Serial.begin(9600); // initialisation du moniteur série
FatFs.begin(cs_pin); // initialisation de la bibliothèque PFatFs
Serial.println();
Serial.println("Bienvenue a ce programme de demonstration de carte SD");
Serial.println("");
// ***************** Exploration du contenu de la carte *************************************
erreur = FatFs.opendir(&dir, "");
if (erreur) { // ça commence mal
Serial.println("Je ne trouve pas la carte SD. Veuillez verifier les connexions.");
return; // pas la peine d'aller plus loin!
}
Serial.println("Voici le contenu de la carte SD: ");
compteur = 0;
for (;;) {
erreur = FatFs.readdir(&dir, &fno); // Lecture d'un item du répertoire
if (erreur || !fno.fname[0]) break; // Erreur ou fin du répertoire
if (fno.fattrib & AM_DIR) { // c'est un répertoire
Serial.print("<dir>\t");
Serial.println(fno.fname); // nom du répertoire
}
else { // c'est un fichier
Serial.print(fno.fsize); // taille du fichier
Serial.print("\t"); //tabulation
Serial.println(fno.fname); // nom du fichier
if (!strcmp (fno.fname, "TEST.TXT")){
compteur = 1;
}
}
}
if (erreur) {
Serial.println("Erreur lors de l'inventaire du contenu de la carte.");
return;
}
Serial.println("");
if (compteur){
Serial.println("Le fichier test.txt est present sur la carte");
}
else{
Serial.println("Le fichier test.txt n'est pas sur la carte, cette demonstration ne peut donc pas continuer.");
return;
}
// ***************** Première Lecture du fichier *************************************
//delay(100);
erreur = FatFs.open("test.txt"); // ouverture du fichier
if (erreur) {
Serial.println("Impossible d'ouvrir le fichier.");
return;
}
Serial.println();
Serial.println("Voici le contenu du fichier, avant modification:");
//delay(100);
for (;;) {
erreur = FatFs.read(buffer, sizeof(buffer), &br); // lecture d'un bout du fichier
if (erreur || !br) break; // erreur ou fin du fichier
for (uint16_t i = 0; i < br; i++) { // affichage de ce qu'on a lu
if (buffer[i] != '\0'){
Serial.print(buffer[i]);
}
}
//delay(100);
}
if (erreur) {
Serial.println("Erreur pendant la lecture du fichier.");
return ;
}
// Récupération du nombre qui sera incrémenté
erreur = FatFs.lseek( 49 ); // on commence à lire au 49e byte du fichier, c'est là que débute le nombre à incrémenter
if (erreur) {
Serial.println("Erreur pendant le positionnement dans le fichier.");
return;
}
erreur = FatFs.read(buffer, sizeof(buffer), &br); // le nombre à incrémenter, sous la forme d'une chaîne de caractères
if (buffer[0] == '\0'){ // si ce nombre est absent, on le fixe à zéro
compteur =0;
}
else{
compteur = atoi(buffer); // conversion de la chaîne de caractères en nombre
}
compteur++; // incrémentation
erreur = FatFs.close(); // fermeture du fichier
if (erreur) { // oups, il y a une erreur
Serial.println("Erreur lors de la fermeture du fichier.");
return; // on ne va pas plus loin...
}
//******************************** écriture dans le fichier ********************************
Serial.println();
//delay(100);
erreur = FatFs.open("test.txt");
if (erreur) {
Serial.println("Impossible d'ouvrir le fichier.");
return;
}
Serial.println();
Serial.println("La modification du fichier est en cours.");
//delay(100);
bw=0;
erreur = FatFs.write("Nombre de visites du Launchpad dans ce fichier: ", 49, &bw); // utile seulement si le fichier est vide
itoa(compteur, buffer,10); // conversion du nombre en chaîne de caractères
erreur = FatFs.write(buffer, strlen(buffer), &bw);
if (erreur) {
Serial.println("Erreur pendant l'ecriture du fichier.");
return;
}
erreur = FatFs.write(0, 0, &bw); //Finalisation de l'écriture (?)
if (erreur) {
Serial.println("Erreur pendant la finalisation de l'ecriture du fichier.");
return;
}
erreur = FatFs.close(); // fermeture du fichier
if (erreur) { // oups, il y a une erreur
Serial.println("Erreur lors de la fermeture du fichier.");
return; // on ne va pas plus loin...
}
//******************************** lecture du fichier, une fois modifié ********************************
//delay(100);
erreur = FatFs.open("test.txt");
if (erreur) {
Serial.println("Impossible d'ouvrir le fichier");
return;
}
Serial.println();
Serial.println("Voici maintenant le contenu du fichier, apres modification:");
//delay(100);
for (;;) {
erreur = FatFs.read(buffer, sizeof(buffer), &br); // lecture d'un bout du fichier
if (erreur || !br) break; // erreur ou fin du fichier
for (uint16_t i = 0; i < br; i++) { // affichage de ce qu'on a lu
if (buffer[i] != '\0'){
Serial.print(buffer[i]);
}
}
//delay(100);
}
if (erreur) {
Serial.println("Erreur pendant la lecture du fichier t_write.txt.");
return ;
}
erreur = FatFs.close(); // fermeture du fichier
if (erreur) { // oups, il y a une erreur
Serial.println("Erreur lors de la fermeture du fichier.");
return; // on ne va pas plus loin...
}
Serial.println("");
Serial.println("");
Serial.println("Fin de la demonstration.");
Serial.println();
Serial.println("-----------------------------------------------------------------");
}
void loop()
{
// rien de spécial à faire dans le loop...
}
view raw carte_SD.ino hosted with ❤ by GitHub

Mes principales sources de documentation ont été ce tutoriel: Interfacing An SD-Card To The Launchpad – A Walkthrough Tutorial (qui vous intéressera particulièrement si vous désirez faire du data logging avec votre Launchpad) ainsi que cette discussion dans le forum de 430h consacré à Energia.

Yves Pelletier (Twitter:  @ElectroAmateur)

Aucun commentaire:

Enregistrer un commentaire