micropython-sistema-archivos-littlefs-fat-os

Sistema de archivos en MicroPython: LittleFS y FAT

  • 5 min

El sistema de archivos en MicroPython es una capa para guardar y leer ficheros en la memoria del microcontrolador.

Una de las grandes potencias de MicroPython es que no trata la memoria flash como un bloque de bytes crudos, sino que implementa un sistema de archivos completo.

Esto significa que podemos crear archivos datos.txt, config.json o carpetas /logs exactamente igual que lo haríamos en nuestro ordenador. Estos datos son persistentes: si desconectas la alimentación, seguirán ahí cuando vuelvas a encender la placa.

Pero no todos los sistemas de archivos son iguales. En el mundo de los microcontroladores, existen dos grandes contendientes: FAT y LittleFS.

FAT y LittleFS

Dependiendo del firmware que hayas instalado y de tu placa (ESP32 o Raspberry Pi Pico), te encontrarás con uno u otro.

FAT (File Allocation Table)

Es el clásico. El mismo que usan los pendrives antiguos.

  • Ventaja: Es compatible con Windows/Mac/Linux. Por eso, cuando conectas una Raspberry Pi Pico por USB, aparece como una unidad de disco y puedes arrastrar archivos dentro.
  • Desventaja: Es frágil. Si se va la luz justo mientras estás escribiendo un archivo, es muy probable que el sistema de archivos se corrompa y pierdas datos.
  • Desventaja: No gestiona bien el desgaste de la memoria Flash.

LittleFS (Little Fail-Safe)

Es un sistema moderno diseñado específicamente para microcontroladores y memorias Flash.

  • Ventaja: Es a prueba de fallos de energía. Si se corta la luz mientras escribes, puedes perder ese último dato, pero el sistema de archivos no se romperá.
  • Ventaja: Tiene Wear Leveling (Nivelación de desgaste). Reparte las escrituras por toda la memoria para que no se quemen siempre los mismos sectores, alargando la vida de tu placa.
  • Desventaja: No es visible directamente como unidad USB en tu PC. Necesitas herramientas como Thonny, mpremote o rshell para subir y bajar archivos.

Nuestra recomendación Para desarrollo rápido y prototipos, FAT es muy cómodo. Para productos finales o dispositivos que van a estar registrando datos continuamente (dataloggers), LittleFS es obligatorio por seguridad. El ESP32 usa LittleFS por defecto en las versiones modernas de MicroPython.

El módulo os: un explorador de archivos

Para gestionar archivos y carpetas desde el código, usamos el módulo estándar os.

Listar y navegar

import os

# Listar archivos en el directorio actual
print(os.listdir())
# Salida: ['boot.py', 'main.py', 'lib']

# Obtener información de un archivo (stat)
# Devuelve una tupla: (modo, ino, dev, nlink, uid, gid, tamaño, tiempo...)
info = os.stat('boot.py')
print(f"Tamaño de boot.py: {info[6]} bytes")
Copied!

Crear carpetas y borrar

# Crear un directorio
try:
    os.mkdir('/data')
except OSError:
    print("La carpeta ya existía")

# Borrar un archivo
# os.remove('archivo_viejo.txt')

# Borrar una carpeta (debe estar vacía)
# os.rmdir('/data')
Copied!

Lectura y escritura de archivos

La sintaxis es idéntica a la de Python estándar en PC. Usamos la función open() junto con el bloque with (recomendado para asegurar que el archivo se cierra correctamente).

Modos de apertura

  • 'w' (Write): Crea el archivo. Si ya existía, borra su contenido y empieza de cero.
  • 'a' (Append): Añade contenido al final del archivo sin borrar lo anterior.
  • 'r' (Read): Solo lectura.

Escritura de un registro de datos

Vamos a simular un sistema que guarda la temperatura cada vez que se ejecuta.

import time
import random

def guardar_log(dato):
    # Usamos modo 'a' para añadir una línea nueva
    with open('registro.txt', 'a') as f:
        timestamp = time.time()
        linea = f"{timestamp},{dato}\n"
        f.write(linea)
    print("Dato guardado.")

# Simulamos guardar 5 datos
for _ in range(5):
    temp = random.randint(20, 30)
    guardar_log(temp)
    time.sleep(1)
Copied!

Si ejecutas esto varias veces, verás que el archivo registro.txt va creciendo.

Lectura de una configuración

Es muy común tener un archivo para guardar configuraciones (SSID del WiFi, tokens, tiempos de espera) para no tenerlos “hardcodeados” en el código.

def leer_config():
    try:
        with open('registro.txt', 'r') as f:
            contenido = f.read()
            print("--- Contenido del archivo ---")
            print(contenido)
            print("---------------------------")
    except OSError:
        print("El archivo no existe.")

leer_config()
Copied!

Lectura línea a línea

Si el archivo es muy grande (ej. un log de varios megas), **no debes usar f.read()** porque intentará cargar todo el archivo en la memoria RAM y te dará un MemoryError.

Lo correcto es leer línea a línea:

with open('registro.txt', 'r') as f:
    for linea in f:
        print("Procesando línea:", linea.strip())
Copied!

JSON para guardar datos estructurados

Guardar texto plano con comas (CSV) está bien, pero para configuraciones complejas es mejor usar JSON. MicroPython tiene el módulo ujson (o json) para esto.

import json

configuracion = {
    "wifi_ssid": "MiCasa",
    "wifi_pass": "123456",
    "intervalo_lectura": 60,
    "calibracion": [1.0, 0.5, 0.1]
}

# 1. Guardar diccionario a archivo JSON
with open('config.json', 'w') as f:
    json.dump(configuracion, f)

# 2. Recuperar diccionario desde archivo JSON
with open('config.json', 'r') as f:
    config_leida = json.load(f)

print(config_leida['wifi_ssid']) # Imprime "MiCasa"
Copied!

Errores comunes

  1. OSError: 28 (ENOSPC): “No space left on device”. Has llenado la memoria Flash. Te toca borrar archivos antiguos.
  2. Corrupción en FAT: En Raspberry Pi Pico, si desconectas el USB mientras el código está escribiendo un archivo, puede aparecerte como corrupto en Windows.
  3. Flash desgastada: Aunque es difícil llegar al límite, las memorias flash tienen un número limitado de escrituras (aprox 100.000 ciclos). No escribas en archivos dentro de un bucle rápido (ej. cada 10ms). Si necesitas velocidad, guarda en RAM y vuelca a disco cada hora.

Con esto, ya tenemos la capacidad de crear dispositivos que “recuerdan” cosas. Ya sea la contraseña del WiFi o el historial de temperaturas de la última semana.