Repository navigation
Expand file tree
/
Copy pathfunction.cpp
More file actions
231 lines (193 loc) · 7.74 KB
/
Copy pathfunction.cpp
File metadata and controls
231 lines (193 loc) · 7.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/**
* @file function.cpp
* @brief Fonctions utilitaires, gestion de la carte SD, de l'OLED et de la configuration NVS.
* @version 1.6.2
* @author Paul Miailhe
* @date 27/06/2026
*
* Version 1.6.2 : Alignement RF et suppression du saut de ligne série pour NectarMC.
*/
#include "header.h"
#include <Preferences.h>
/**
* @brief Détecte, initialise et affiche l'état de la carte SD au démarrage.
* @param u8g2 Pointeur vers l'écran OLED.
* @param SDSPI Bus SPI dédié à la carte SD.
* @param SDCard Variable de retour indiquant si la carte est active.
*
* Configure le bus SPI et démarre le système de fichiers SD.
* - En cas d'échec : Lance un avertissement visuel clignotant sur l'écran (triangle '⚠').
* - En cas de réussite : Affiche un logo circulaire de validation '✓' et la taille de la carte.
*/
void SDCardDetection(U8G2_SSD1306_128X64_NONAME_F_HW_I2C* u8g2, SPIClass* SDSPI, bool* SDCard) {
pinMode(SDCARD_MISO, INPUT_PULLUP);
SDSPI->begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI, SDCARD_CS);
u8g2->setFont(u8g2_font_ncenB08_tr);
if (!SD.begin(SDCARD_CS, *SDSPI, 20000000)) {
*SDCard = false;
Serial.println("[SD] Initialization FAILED!");
// Alerte clignotante en cas d'erreur de carte SD (6 itérations de 300ms = 1.8s)
for (int i = 0; i < 6; i++) {
u8g2->clearBuffer();
if (i % 2 == 0) {
// Dessin du triangle d'avertissement
u8g2->drawLine(64, 10, 46, 38);
u8g2->drawLine(64, 10, 82, 38);
u8g2->drawLine(46, 38, 82, 38);
u8g2->drawLine(64, 11, 47, 37);
u8g2->drawLine(64, 11, 81, 37);
u8g2->drawLine(47, 37, 81, 37);
// Point d'exclamation au centre
u8g2->drawBox(63, 18, 2, 10);
u8g2->drawBox(63, 31, 2, 2);
// Libellé de l'erreur
int w = u8g2->getStrWidth("SD CARD: FAILED!");
u8g2->drawStr((128 - w) / 2, 56, "SD CARD: FAILED!");
}
u8g2->sendBuffer();
delay(300);
}
}
else {
*SDCard = true;
uint32_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("[SD] Initialization OK. Size: %.2f GB\n", cardSize / 1024.0);
// Écran de succès graphique
u8g2->clearBuffer();
// Cercle de validation
u8g2->drawCircle(64, 26, 14);
u8g2->drawCircle(64, 26, 13);
// Symbole '✓' (coche) tracé manuellement
u8g2->drawLine(55, 25, 61, 31);
u8g2->drawLine(55, 26, 61, 32);
u8g2->drawLine(55, 27, 61, 33);
u8g2->drawLine(61, 31, 73, 19);
u8g2->drawLine(61, 32, 73, 20);
u8g2->drawLine(61, 33, 73, 21);
// Affichage textuel de la capacité de stockage détectée
char buf[64];
snprintf(buf, sizeof(buf), "SD CARD: OK (%.1f GB)", cardSize / 1024.0);
int w = u8g2->getStrWidth(buf);
u8g2->drawStr((128 - w) / 2, 56, buf);
u8g2->sendBuffer();
delay(1500);
}
}
/**
* @brief Calcule et affiche l'espace disponible sur la carte SD via le port série.
*/
void checkSDCardSpace() {
uint64_t totalBytes = SD.totalBytes();
uint64_t usedBytes = SD.usedBytes();
uint64_t freeBytes = totalBytes - usedBytes;
double freeSpaceGB = freeBytes / (1024.0 * 1024.0 * 1024.0);
double totalSpaceGB = totalBytes / (1024.0 * 1024.0 * 1024.0);
Serial.printf("[SD] Free Space: %.2f GB / %.2f GB\n", freeSpaceGB, totalSpaceGB);
}
/**
* @brief Enregistre les métadonnées et la charge utile brute d'une trame dans le fichier log CSV.
* @param filepath Chemin absolu du fichier log (ex: "/log_0.csv").
* @param frame Pointeur vers le tableau de données reçues.
* @param length Taille en octets de la trame brute.
* @param rssi Valeur RSSI (puissance du signal radio reçu).
* @param snr Rapport signal/bruit (SNR).
* @param ssid_str Chaîne de caractères décrivant l'identifiant du tracker.
* @param apid Code de l'APID du tracker.
*
* Cette fonction est optimisée pour minimiser le temps de traitement dans la boucle
* principale. Elle écrit une ligne au format CSV :
* Index,Timestamp,Length,RSSI,SNR,SSID,APID,RawFrame
* La trame est écrite en hexadécimal continu rapide grâce à une table statique,
* ce qui évite les conversions lentes basées sur 'sprintf'.
*/
void writeFrameToFile(const char* filepath, const uint8_t* frame, size_t length, float rssi, float snr, const char* ssid_str, uint8_t apid) {
static uint32_t logPacketCount = 0;
logPacketCount++;
File log = SD.open(filepath, FILE_APPEND);
if (log) {
// 1. Index du message reçu pour cette session
log.print(logPacketCount);
log.print(",");
// 2. Horodatage (HH:MM:SS) depuis l'horloge RTC
char timeStr[16];
snprintf(timeStr, sizeof(timeStr), "%02d:%02d:%02d", rtc.getHour(true), rtc.getMinute(), rtc.getSecond());
log.print(timeStr);
log.print(",");
// 3. Nombre d'octets de la trame
log.print(length);
log.print(",");
// 4. Paramètres physiques radio
log.print(rssi);
log.print(",");
log.print(snr);
log.print(",");
// 5. SSID décodé et APID
log.print(ssid_str);
log.print(",");
log.print(apid);
log.print(",");
// 6. Charge utile brute convertie en Hexadécimal continu (sans sprintf)
static const char hexChars[] = "0123456789ABCDEF";
char hexBuffer[MAX_FRAME_SIZE * 2 + 1];
for (size_t i = 0; i < length; i++) {
hexBuffer[i * 2] = hexChars[(frame[i] >> 4) & 0x0F];
hexBuffer[i * 2 + 1] = hexChars[frame[i] & 0x0F];
}
hexBuffer[length * 2] = '\0';
log.println(hexBuffer);
log.close();
} else {
Serial.println("[SD] Error: Failed to open log file. SD card marked as OFFLINE.");
*SDCard = false;
}
}
/**
* @brief Récupère les configurations LoRa enregistrées en mémoire non-volatile (NVS).
*
* Si aucune configuration personnalisée n'est stockée, applique les valeurs
* par défaut issues de la bande native de la carte de développement.
*/
void loadLoRaConfig() {
Preferences prefs;
// Ouvre le namespace "loracfg" en mode lecture seule pour plus de sécurité
prefs.begin("loracfg", true);
// Lecture ou application des valeurs par défaut si non trouvées
activeConfig.frequency = prefs.getFloat("freq", DEFAULT_FREQUENCY);
activeConfig.spreadingFactor = prefs.getUChar("sf", DEFAULT_SF);
activeConfig.bandwidth = prefs.getFloat("bw", DEFAULT_BW);
activeConfig.crcEnable = prefs.getBool("crc", true);
activeConfig.crcMode = prefs.getBool("crcMode", false);
activeConfig.activeFrameFormat = prefs.getUChar("fmt", DEFAULT_FRAME_FORMAT);
prefs.end(); // Fermeture propre de la NVS
Serial.printf("[CONFIG] Loaded from NVS: Freq=%.3f MHz, SF=%d, BW=%.1f kHz, CRC=%s (Mode=%s), FMT=%d\n",
activeConfig.frequency, activeConfig.spreadingFactor, activeConfig.bandwidth,
activeConfig.crcEnable ? "ON" : "OFF", activeConfig.crcMode ? "IBM" : "CCITT",
activeConfig.activeFrameFormat);
}
/**
* @brief Enregistre définitivement la configuration radio actuelle dans la NVS.
*/
void saveLoRaConfig() {
Preferences prefs;
prefs.begin("loracfg", false);
prefs.putFloat("freq", activeConfig.frequency);
prefs.putUChar("sf", activeConfig.spreadingFactor);
prefs.putFloat("bw", activeConfig.bandwidth);
prefs.putBool("crc", activeConfig.crcEnable);
prefs.putBool("crcMode", activeConfig.crcMode);
prefs.putUChar("fmt", activeConfig.activeFrameFormat);
prefs.end();
Serial.println("[CONFIG] Saved current config to NVS.");
}
/**
* @brief Supprime l'intégralité des configurations stockées dans la NVS.
*
* Permet de restaurer les paramètres d'usine lors d'un appel ultérieur ou d'un reboot.
*/
void resetLoRaConfig() {
Preferences prefs;
prefs.begin("loracfg", false);
prefs.clear(); // Supprime toutes les clés du namespace
prefs.end();
Serial.println("[CONFIG] NVS configuration cleared.");
}