Una implementazione ottimizzata di SQLite per microcontrollori ESP32 e RP2040 con supporto per diversi tipi di memoria.
- ✅ Piattaforme Supportate: ESP32, RP2040 (Raspberry Pi Pico)
- ✅ Storage Multiplo:
- SPIFFS (ESP32)
- LittleFS (ESP32 e RP2040)
- SD Card (ESP32 e RP2040)
- ✅ Ottimizzato per Embedded: Configurazione ottimizzata per memoria limitata
- ✅ VFS Personalizzato: Virtual File System per ogni tipo di storage
- ✅ Facile da Usare: API semplice e intuitiva
- ✅ Esempi Completi: Esempi per ogni piattaforma e tipo di storage
- ESP32 con almeno 4MB di Flash
- (Opzionale) Modulo SD Card per storage esterno
- Raspberry Pi Pico o compatibile
- Almeno 2MB di Flash
- (Opzionale) Modulo SD Card per storage esterno
- Clona il repository:
git clone https://github.com/yayoboy/sqmini.git
cd sqmini-
Apri il progetto in PlatformIO VSCode
-
Seleziona l'environment appropriato:
esp32-spiffs- ESP32 con SPIFFSesp32-littlefs- ESP32 con LittleFSesp32-sdcard- ESP32 con SD Cardpico-littlefs- RP2040 con LittleFSpico-sdcard- RP2040 con SD Card
- Scarica il repository come ZIP
- In Arduino IDE: Sketch → Include Library → Add .ZIP Library
- Includi nel tuo sketch:
#include "sqlite_micro/sqlite_micro.h"#include <Arduino.h>
#include "sqlite_micro/sqlite_micro.h"
sqlite3 *db;
void setup() {
Serial.begin(115200);
// 1. Inizializza SQLite
sqlite_micro_init();
// 2. Inizializza SPIFFS
sqlite_micro_init_spiffs("/spiffs", 5);
// 3. Registra VFS
sqlite_micro_register_vfs(SQLITE_STORAGE_SPIFFS, "spiffs");
// 4. Apri database
sqlite_vfs_config_t config = {
.mount_point = "/spiffs",
.db_path = "/spiffs/test.db",
.storage_type = SQLITE_STORAGE_SPIFFS,
.cache_size = 64 // 64KB cache
};
sqlite_micro_open("/spiffs/test.db", &db, &config);
// 5. Crea tabella
sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS sensors ("
"id INTEGER PRIMARY KEY,"
"name TEXT,"
"value REAL);",
NULL, NULL, NULL);
// 6. Inserisci dati
sqlite3_exec(db,
"INSERT INTO sensors (name, value) VALUES ('Temp', 23.5);",
NULL, NULL, NULL);
// 7. Query
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, "SELECT * FROM sensors", -1, &stmt, NULL);
while (sqlite3_step(stmt) == SQLITE_ROW) {
Serial.printf("ID: %d, Name: %s, Value: %.2f\n",
sqlite3_column_int(stmt, 0),
sqlite3_column_text(stmt, 1),
sqlite3_column_double(stmt, 2));
}
sqlite3_finalize(stmt);
}
void loop() {
delay(1000);
}// Inizializza LittleFS invece di SPIFFS
sqlite_micro_init_littlefs_esp32("/littlefs", 5);
sqlite_micro_register_vfs(SQLITE_STORAGE_LITTLEFS, "littlefs");
sqlite_vfs_config_t config = {
.mount_point = "/littlefs",
.db_path = "/littlefs/data.db",
.storage_type = SQLITE_STORAGE_LITTLEFS,
.cache_size = 64
};
sqlite_micro_open("/littlefs/data.db", &db, &config);// Definisci i pin SPI per SD Card
#define PIN_SD_CS 5
#define PIN_SD_MOSI 23
#define PIN_SD_MISO 19
#define PIN_SD_SCK 18
// Inizializza SD Card
sqlite_micro_init_sdcard(PIN_SD_CS, PIN_SD_MOSI, PIN_SD_MISO, PIN_SD_SCK);
sqlite_micro_register_vfs(SQLITE_STORAGE_SDCARD, "sdcard");
sqlite_vfs_config_t config = {
.mount_point = "/sdcard",
.db_path = "/sdcard/datalog.db",
.storage_type = SQLITE_STORAGE_SDCARD,
.cache_size = 128 // SD Card può gestire cache più grandi
};
sqlite_micro_open("/sdcard/datalog.db", &db, &config);#include <Arduino.h>
#include "sqlite_micro/sqlite_micro.h"
sqlite3 *db;
void setup() {
Serial.begin(115200);
// Inizializza per RP2040
sqlite_micro_init();
sqlite_micro_init_littlefs_rp2040();
sqlite_micro_register_vfs(SQLITE_STORAGE_LITTLEFS, "littlefs");
sqlite_vfs_config_t config = {
.mount_point = "/lfs",
.db_path = "/lfs/sensor.db",
.storage_type = SQLITE_STORAGE_LITTLEFS,
.cache_size = 32 // RP2040 ha meno RAM
};
sqlite_micro_open("/lfs/sensor.db", &db, &config);
// Usa il database...
}SQLite Micro è configurato per minimizzare l'uso di memoria su microcontrollori:
- Page size: 512 bytes
- Cache: 64KB (configurabile)
- Max memory: 64KB
- Page size: 512 bytes
- Cache: 32KB (configurabile)
- Max memory: 32KB
Il file sqlite_config.h disabilita automaticamente features non necessarie:
- ❌ Load extension
- ❌ Virtual tables
- ❌ Views
- ❌ Triggers
- ❌ Subqueries complesse
- ❌ Window functions
- ✅ Operazioni base (SELECT, INSERT, UPDATE, DELETE)
- ✅ JOIN semplici
- ✅ Aggregazioni (SUM, AVG, COUNT, etc.)
- ✅ Indici
sqmini/
├── src/
│ ├── sqlite3.c # SQLite amalgamation
│ ├── sqlite3.h
│ ├── sqlite_micro.c # Implementazione principale
│ ├── vfs/
│ │ ├── vfs_spiffs.c # VFS per SPIFFS (ESP32)
│ │ ├── vfs_littlefs.c # VFS per LittleFS
│ │ └── vfs_sdcard.c # VFS per SD Card
│ └── platform/
│ ├── pico_hal_littlefs.c
│ └── pico_hal_littlefs.h
├── include/
│ └── sqlite_micro/
│ ├── sqlite_micro.h # Header principale
│ └── sqlite_config.h # Configurazione
├── examples/
│ ├── esp32/
│ │ ├── spiffs/
│ │ ├── littlefs/
│ │ └── sdcard/
│ └── rp2040/
│ ├── littlefs/
│ └── sdcard/
├── platformio/
│ ├── esp32/platformio.ini
│ └── rp2040/platformio.ini
└── README.md
Inizializza SQLite per microcontrollori.
int rc = sqlite_micro_init();Registra un Virtual File System per un tipo di storage specifico.
sqlite_micro_register_vfs(SQLITE_STORAGE_LITTLEFS, "littlefs");Apre un database con configurazione specifica.
sqlite_vfs_config_t config = {
.mount_point = "/littlefs",
.db_path = path,
.storage_type = SQLITE_STORAGE_LITTLEFS,
.cache_size = 64
};
sqlite_micro_open(path, &db, &config);typedef enum {
SQLITE_STORAGE_SPIFFS, // ESP32 SPIFFS
SQLITE_STORAGE_LITTLEFS, // LittleFS (ESP32/RP2040)
SQLITE_STORAGE_SDCARD, // SD Card
SQLITE_STORAGE_FLASH // Flash grezza (futuro)
} sqlite_storage_type_t;sqlite_micro_stats_t stats;
sqlite_micro_get_stats(&stats);
printf("Memoria corrente: %d bytes\n", stats.current_memory);
printf("Picco memoria: %d bytes\n", stats.peak_memory);- SPIFFS Example - Database su filesystem SPIFFS
- LittleFS Example - Database su LittleFS con transazioni
- SD Card Example - Data logging su SD Card
- LittleFS Example - Database su flash interna
- SD Card Example - Monitoraggio ambientale con SD Card
Tutti gli esempi si trovano nella cartella examples/.
| Piattaforma | Storage | Tempo |
|---|---|---|
| ESP32 | SPIFFS | ~150ms |
| ESP32 | LittleFS | ~120ms |
| ESP32 | SD Card | ~200ms |
| RP2040 | LittleFS | ~180ms |
| RP2040 | SD Card | ~250ms |
Note: i tempi sono approssimativi e dipendono dalla qualità della SD Card
- Usa Transazioni: Per inserimenti multipli, usa sempre
BEGIN/COMMIT
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
// ... inserimenti ...
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);-
Configura Cache Appropriata:
- ESP32: 64-128KB
- RP2040: 32-64KB
-
Usa Prepared Statements: Per query ripetute
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, "SELECT * FROM sensors WHERE id=?", -1, &stmt, NULL);
sqlite3_bind_int(stmt, 1, sensor_id);
sqlite3_step(stmt);
sqlite3_finalize(stmt);-
Monitora Memoria: Usa
sqlite_micro_get_stats()per tenere traccia dell'uso della memoria -
SD Card: Preferisci SD Card per grandi quantità di dati (>1MB)
- Verifica che la partizione sia configurata correttamente
- Prova a formattare il filesystem
- Riduci la cache size
- Verifica di non avere memory leak
- Usa transazioni per batch insert
- Verifica il wiring
- Controlla che la SD Card sia formattata FAT32
- Prova a ridurre la velocità SPI
- SQLite Micro usa
SQLITE_THREADSAFE=1(serialized) - Evita accessi concorrenti da task diversi
- No supporto per estensioni loadabili
- No virtual tables
- Subquery limitate
- No window functions
- Single-threaded access (serialized mode)
Contributi sono benvenuti! Per favore:
- Fai fork del repository
- Crea un branch per la tua feature
- Commit le modifiche
- Push al branch
- Apri una Pull Request
Questo progetto usa SQLite (Public Domain) e codice custom sotto licenza MIT.
- SQLite: https://www.sqlite.org/
- ESP32 Arduino Core: https://github.com/espressif/arduino-esp32
- RP2040 Arduino Core: https://github.com/earlephilhower/arduino-pico
Per problemi o domande:
- Apri una Issue su GitHub
- Consulta gli esempi nella cartella
examples/ - Leggi la documentazione ufficiale di SQLite: https://www.sqlite.org/docs.html
Autore: SQLite Micro Contributors Versione: 1.0.0 Ultimo aggiornamento: 2024