Advertisement
bipping

FreehareV2.cpp

Mar 18th, 2025
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.19 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <SD.h>
  3. #include <avr/wdt.h>
  4.  
  5. // Constantes système
  6. #define PIN_CAPTEUR A2
  7. #define PIN_CS_SD 4
  8. #define DUREE_ACQUISITION_S 7
  9. #define BAUD_RATE 115200
  10.  
  11. // Constantes de conversion pour l'accéléromètre ADXL335
  12. #define ZERO_G_VALUE 261
  13. #define SCALE_FACTOR 205
  14.  
  15. // Constantes de buffer
  16. #define TAILLE_BUFFER 1024
  17. #define TAILLE_MAX_ENTREE 20
  18. #define ESPACE_SECURITE (TAILLE_BUFFER - TAILLE_MAX_ENTREE)
  19.  
  20. // Variables globales
  21. File myFile;
  22. volatile bool acquisitionTerminee = false;
  23. volatile uint8_t compteurSecondes = 0;
  24.  
  25. // Buffer d'acquisition pour mémoriser tous les échantillons
  26. char bufferDonnees[TAILLE_BUFFER];
  27. uint16_t indexBuffer = 0;
  28. uint32_t nbEchantillons = 0;
  29. unsigned long tempsDebutAcquisition;
  30.  
  31. // Routine d'interruption du Watchdog
  32. ISR(WDT_vect) {
  33.     if (++compteurSecondes >= DUREE_ACQUISITION_S) {
  34.         acquisitionTerminee = true;
  35.         wdt_disable();  // Désactivation du Watchdog
  36.     }
  37. }
  38.  
  39. // Lecture ADC optimisée avec accès direct aux registres
  40. inline uint16_t lectureADC(uint8_t pin) {
  41.     // Sélection du canal ADC (A0-A5 correspond aux canaux 0-5)
  42.     ADMUX = (ADMUX & 0xF0) | (pin & 0x07);
  43.    
  44.     // Démarrer la conversion
  45.     ADCSRA |= (1 << ADSC);
  46.    
  47.     // Attendre la fin de la conversion
  48.     while (ADCSRA & (1 << ADSC));
  49.    
  50.     // Lire le résultat (ADCL doit être lu en premier)
  51.     uint8_t low = ADCL;
  52.     uint8_t high = ADCH;
  53.    
  54.     return (high << 8) | low;
  55. }
  56.  
  57. void setup() {
  58.     // Initialisation de la communication série
  59.     Serial.begin(BAUD_RATE);
  60.     Serial.println(F("Initialisation..."));
  61.    
  62.     // Configuration de l'ADC pour une conversion plus rapide
  63.     // Diviseur d'horloge = 64 au lieu de 128 (par défaut)
  64.     ADCSRA = (ADCSRA & 0xF8) | 0x06;
  65.  
  66.     // Configuration de la carte SD
  67.     if (!SD.begin(PIN_CS_SD)) {
  68.         Serial.println(F("Echec carte SD"));
  69.         return;
  70.     }
  71.    
  72.     // Préparation du fichier
  73.     if (SD.exists("MESURE.txt")) {
  74.         if (!SD.remove("MESURE.txt")) {
  75.             Serial.println(F("Erreur suppression fichier"));
  76.             // Continuer malgré l'erreur
  77.         }
  78.     }
  79.    
  80.     // Configuration du Watchdog pour timing approximatif
  81.     configurerWatchdog();
  82.    
  83.     // Marquage du temps initial
  84.     tempsDebutAcquisition = millis();
  85.    
  86.     // Écriture de l'en-tête dans le buffer
  87.     const char *entete = "Accel Z (g), Temps (ms)\n";
  88.     strcpy(bufferDonnees, entete);
  89.     indexBuffer = strlen(entete);
  90.  
  91.     Serial.println(F("Début acquisition"));
  92. }
  93.  
  94. // Configuration du Watchdog comme timer approximatif
  95. void configurerWatchdog() {
  96.     cli();  // Désactiver les interruptions
  97.    
  98.     // Effacer le flag de reset
  99.     MCUSR &= ~(1 << WDRF);
  100.    
  101.     // Permettre la modification des registres du Watchdog
  102.     WDTCSR |= (1 << WDCE) | (1 << WDE);
  103.    
  104.     // Mode interruption uniquement (pas de reset) avec intervalle ~1s
  105.     WDTCSR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1);
  106.    
  107.     sei();  // Réactiver les interruptions
  108. }
  109.  
  110. // Fonction utilitaire pour compter le nombre de chiffres
  111. inline uint8_t numDigits(uint16_t valeur) {
  112.     if (valeur < 10) return 1;
  113.     if (valeur < 100) return 2;
  114.     if (valeur < 1000) return 3;
  115.     return 4;
  116. }
  117.  
  118. // Fonction optimisée pour l'écriture d'une entrée accélération/temps
  119. void ecrireEntree(int16_t valeur, unsigned long timestamp) {
  120.     // Partie entière de l'accélération (peut être négative)
  121.     int16_t partieEntiere = valeur / 10000;
  122.     itoa(partieEntiere, &bufferDonnees[indexBuffer], 10);
  123.     indexBuffer += strlen(&bufferDonnees[indexBuffer]);
  124.    
  125.     // Séparateur décimal
  126.     bufferDonnees[indexBuffer++] = '.';
  127.    
  128.     // Partie décimale (4 chiffres significatifs) - toujours positive
  129.     int16_t partieDecimale = abs(valeur % 10000);
  130.  
  131.     // Gestion optimisée des zéros en tête (moins d'instructions)
  132.     char* ptrDecimale = &bufferDonnees[indexBuffer];
  133.    
  134.     // Allocation d'espace pour 4 chiffres + null terminator
  135.     memset(ptrDecimale, '0', 4);
  136.    
  137.     // Conversion de la partie décimale en chaîne
  138.     itoa(partieDecimale, ptrDecimale + (4 - numDigits(partieDecimale)), 10);
  139.     indexBuffer += 4;
  140.    
  141.     // Séparateur entre colonnes
  142.     bufferDonnees[indexBuffer++] = ',';
  143.     bufferDonnees[indexBuffer++] = ' ';
  144.    
  145.     // Conversion du timestamp
  146.     itoa(timestamp, &bufferDonnees[indexBuffer], 10);
  147.     indexBuffer += strlen(&bufferDonnees[indexBuffer]);
  148.    
  149.     // Retour à la ligne
  150.     bufferDonnees[indexBuffer++] = '\n';
  151. }
  152.  
  153. // Écriture du buffer complet sur la carte SD
  154. void sauvegarderDonnees() {
  155.     myFile = SD.open("MESURE.txt", FILE_WRITE);
  156.    
  157.     if (myFile) {
  158.         myFile.write(bufferDonnees, indexBuffer);
  159.         myFile.close();
  160.         Serial.println(F("Données sauvegardées"));
  161.     } else {
  162.         Serial.println(F("Erreur ouverture fichier"));
  163.     }
  164. }
  165.  
  166. void loop() {
  167.     // Phase d'acquisition
  168.     if (!acquisitionTerminee) {
  169.         // Acquisition uniquement si le buffer n'est pas plein
  170.         if (indexBuffer < ESPACE_SECURITE) {
  171.             // Lecture et conversion optimisée
  172.             uint16_t valeurADC = lectureADC(PIN_CAPTEUR - A0);
  173.             int32_t acceleration = ((int32_t)ZERO_G_VALUE - (int32_t)valeurADC) * SCALE_FACTOR;
  174.            
  175.             // Capture du temps relatif
  176.             unsigned long tempsRelatif = millis() - tempsDebutAcquisition;
  177.            
  178.             // Écriture formatée dans le buffer
  179.             ecrireEntree(acceleration, tempsRelatif);
  180.            
  181.             // Comptage
  182.             nbEchantillons++;
  183.         }
  184.     }
  185.     // Phase de sauvegarde
  186.     else {
  187.         static bool sauvegardeFaite = false;
  188.        
  189.         if (!sauvegardeFaite) {
  190.             sauvegarderDonnees();
  191.            
  192.             Serial.print(F("Échantillons acquis: "));
  193.             Serial.println(nbEchantillons);
  194.             Serial.print(F("Taille buffer (octets): "));
  195.             Serial.println(indexBuffer);
  196.             Serial.print(F("Fréquence moyenne (Hz): "));
  197.             Serial.println((float)nbEchantillons / DUREE_ACQUISITION_S);
  198.            
  199.         } // sauvegardeFaite non réinitialisé car fin du programme
  200.     }  // Boucle infinie
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement