Module carte SD sur bus SPI

Ce tutoriel explique comment mettre en oeuvre un module carte SD sur bus SPI avec MicroPython.

Une grande partie des projets que vous aurez envie de développer nécessiteront un accès en lecture et écriture à une carte SD, pour :

  • Enregistrer / relire des mots de passe ou des paramètres utilisateurs
  • Enregistrer / relire des séries de mesures en provenance de capteurs
  • Enregistrer / relire des messages d’erreur
  • Etc.

Ce tutoriel partage un code exemple des différentes fonctions indispensables à la mise en oeuvre d’un module de lecture / écriture sur une carte SD. Ce code et la bibliothèque sdcard.py sont directement copiés depuis ce site.

Matériel requis

  1. La carte NUCLEO-WB55
  2. Un module carte SD SPI Module SD utilisé : MH-SD Card Module alimentable en 3.3V & 5V Attention : les modules microSD (ou µSD) Catalex ne semblent pas fonctionner avec sdcard.py !
  3. Des câbles dupont
  4. Un module Grove BME280 pour la deuxième partie du tutoriel

Le module carte SD SPI qui fonctionne correctement avec sdcard.py :

Module carte SD SPI


Crédit image : Aranacorp

Première partie : le code MicroPython pour tester la bibliothèque sdcard.py

Les scripts présentés ci-après sont disponibles dans la zone de téléchargement..

Branchez le module carte SD sur sur le bus SPI1 de la carte NUCLEO-WB55. Les broches utilisées sont les suivantes, sur les connecteurs Arduino :

  • MOSI : D11
  • MISO : D12
  • SCK : D13
  • CS : D9
  • GND : Celle que vous voulez
  • Alimentation : 5V

Et voici le code :

#Source : https://github.com/micropython/micropython/tree/master/drivers
# Objet du script : Présenter les fonctions de lecture et écriture offertes par sdcard.py.

import pyb, sdcard, os
from pyb import SPI

spi = SPI(1, SPI.MASTER, baudrate=100000, polarity=1, phase=0) # Instance du bus SPI
sd = sdcard.SDCard(spi, machine.Pin('D9')) # Broche de sélection du module carte SD

vfs = os.VfsFat(sd) # Déclaration d'un système de fichier FAT
os.mount(vfs, "/fc") # Montage du volume logique associé au module carte SD

print("Test du système de fichiers")
print(os.listdir("/fc"))

ligne_alphabet = "abcdefghijklmnopqrstuvwxyz\n"
deux_cent_ligne_alphabet = ligne_alphabet * 200 # 5400 caractères
ligne_nombres = "1234567890\n"

fn = "/fc/fichier1.txt"
print()

print("Lecture / écriture de plusieurs blocs")
with open(fn, "w") as f:
	n = f.write(deux_cent_ligne_alphabet)
	print(n, "octets écrits")
	n = f.write(ligne_nombres)
	print(n, "octets écrits")
	n = f.write(deux_cent_ligne_alphabet)
	print(n, "octets écrits")

with open(fn, "r") as f:
	result1 = f.read()
	print(len(result1), "octets lus")

fn = "/fc/fichier2.txt"
print()
print("Lecture/écriture d'un seul block")
with open(fn, "w") as f:
	n = f.write(ligne_nombres)  # un seul block
	print(n, "octets écrits")

with open(fn, "r") as f:
	result2 = f.read()
	print(len(result2), "octets lus")

os.umount("/fc")

print()
print("Contrôle des données écrites")
success = True

if result1 == "".join((deux_cent_ligne_alphabet, ligne_nombres, deux_cent_ligne_alphabet)):
	print("Grand fichier : OK")
else:
	print("Grand fichier : Echec")
	success = False
	
if result2 == ligne_nombres:
	print("Petit fichier : OK")
else:
	print("Petit fichier : Echec")
	success = False
print()
print("Tests", "réussis" if success else "échoués")

Si vous avez correctement câblé le module et que celui-ci est compatible avec la bibliothèque sdcard.py, vous devriez obtenir ce retour sur le terminal série du l’USB user :


Module carte SD SPI, retour du test fonctionnel


Vous devriez trouver sur la carte SD les fichiers “fichier1.txt” et “fichier2.txt” avec les contenus écrits par le code ci-avant.

Deuxième partie : le code MicroPython pour enregistrer les mesures d’un module Grove BME280

Les scripts présentés ci-après sont disponibles dans la zone de téléchargement.

Nous allons à présent donner un exemple de script pour enregistrer sur la carte SD les mesures effectuées par un module I2C Grove BME280. Nous sommes repartis du script donné pour cet exemple.

Laissez le module carte SD connecté là où il est, et branchez le module BME280 sur sur le bus I2C de la carte NUCLEO-WB55. Les broches utilisées sont les suivantes, sur les connecteurs Arduino :

  • SCL : D15
  • SDA : D14
  • GND : Celle que vous voulez
  • Alimentation : 3V3

Et voici le code :

# Objet du script : Mise en oeuvre du module grove I2C capteur de pression,
# température et humidité basé sur le capteur BME280
# Enregistre les mesures dans un fichier sur une carte SD.

import os,pyb,time,sdcard,bme280	# Pilotes pour lire-écrire des fichiers, pour temporiser, 
									# du module carte SD et du capteur bme280.
from machine import I2C, Pin # Pilotes du contrôleur de bus I2C et des entrées-sorties
from pyb import SPI # Pilote du contrôleur de bus SPI

# On utilise l'I2C n°1 de la carte NUCLEO-W55 pour communiquer avec le capteur
i2c = I2C(1)

# Pause d'une seconde pour laisser à l'I2C le temps de s'initialiser
time.sleep_ms(1000)

# Liste des adresses I2C des périphériques présents
print("Adresses I2C utilisées : " + str(i2c.scan()))

# Instanciation du capteur
bme = bme280.BME280(i2c=i2c)

spi = SPI(1, SPI.MASTER, baudrate=100000, polarity=1, phase=0) # Instance du bus SPI
sd = sdcard.SDCard(spi, machine.Pin('D9')) # Broche de sélection du module carte SD

vfs = os.VfsFat(sd) # Déclaration d'un système de fichier FAT
os.mount(vfs, "/fc") # Montage du volume logique associé au module carte SD

fname = "/fc/log.csv"

with open(fname, "w") as log: # Ouverture du fichier "log.csv" en écriture
	
	n = log.write("Temps,Temp,Pres,Humi" + '\n')
	
	while True:

		# Temporisation d'une seconde
		time.sleep_ms(1000)
	
		# Lecture des valeurs mesurées
		bme280data = bme.values
	
		# Séparation et formattage (arrondis) des mesures
		temp = round(bme280data[0],1)
		press = int(bme280data[1])
		humi = int(bme280data[2])

		# Affichage des mesures
		print('=' * 40)  # Imprime une ligne de séparation
		print("Température : " + str(temp) + " °C")
		print("Pression : " + str(press) + " hPa")
		print("Humidité relative : " + str(humi) + " %")
	
		# Ecriture dans un fichier "log.csv" de la carte SD
		t = time.ticks_ms() # Etiquette de temps
		# écriture dans le fichier
		#n = log.write(str(t) + "," + str(temp) + "," + str(press) + "," + str(humi) + '\n')
		n = log.write("{},{},{},{}\n".format(t, temp, press, humi))
		print(n, "octets écrits")

Vous devriez obtenir ce retour sur le terminal série du l’USB user :


Module carte SD SPI, retour du test fonctionnel


Et, si vous accédez au contenu de la carte SD, vous devriez y trouver un fichier “log.csv” avec un contenu de cette forme :


Module carte SD SPI, retour du test fonctionnel