Temps maximal de fonctionnement Arduino Uno

Bonjour,

J’ai un Arduino Uno avec un shield ethernet et un écran LCD, tous ça est branché avec des capteurs, tout fonctionne super super j’ai des mesures tout ça tout ça.

MAIS après un fonctionnement continu (24h/24) depuis Lundi 18/05/2015 (on est le 21/05/2015), le programme ne va plus dans la boucle loop (enfin je pense)

Le boitier d’acquisition (avec les cartes arduino) est installé à deux heures de cher moi, et j’ai une personne qui vérifie de temps en temps, ce matin il m’appelle et me dit il n’y a pas les valeurs que tu m’avais dit sur l’écran LCD, il y a seulement marqué “INIt réussi” puis “Fichier ouvert”.

J’en déduit que le programme redémarre mais je ne sais pas pourquoi.

Pour les amateurs de code :

// /////////////////////////////// 1. Entête déclarative ///////////////////////////////
// Bien penser à installer les bibliothèques sur l'ordinateur
// Cherche sur google par exemple : library SPI.h et télécharger un fichier Zip
// Croquis => Include library => add zip library 
#include <SPI.h> // Serial Peripheral Interface
#include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD
#include <LiquidCrystal.h> // Inclusion de la librairie pour afficheur LCD
  
const int brocheSDCardSelect=4; // broche utilisée pour sélectionner la carte SD

float  vitesse_nke=0; //vitesse de l'eau
float  vitesse_rotation=0; //vitesse de rotation 
float freq_nke=0; //frequence du NKE
float calcul_freq=0; 
float freq_rotation=0; //frequence du codeur
int count=0; //compteur NKE
int count_rotation=0; //compteur rotation
float vitesse_ms=0; //vitesse de l'eau en m/s
int y=0;      

LiquidCrystal lcd(9, 6, 5, 4, 7, 8); // broche afficheur alphanumérique 

int test; // Variable utilisée pour tester la valeur renvoyée par fonctions SD Card

File file; // objet file
File root; // objet root pour le répertoire racine

// /////////////////////////////// 2. FONCTION SETUP = Code d'initialisation ///////////////////////////////
void setup(void) {
 
  // --- Liaison série ---
  Serial.begin(115200);
  Serial.flush(); // vide le buffer
  
  pinMode(0, INPUT); 
  pinMode(1, INPUT);
  attachInterrupt (0,vitesse_int, RISING); //Quand il y a une interruption (front montant) sur la broche 2, on appelle la fonction vitesse_int
  attachInterrupt (1,compteur, RISING);  //Quand il y a une interruption (front montant) sur la broche 3, on appelle la fonction compteur  
  
  //--- Initialisation du LCD ---
  lcd.begin(16,2); // Initialise le LCD avec 16 colonnes x 2 lignes
  delay(10); // pause rapide pour l'initialisation
 
  //--- Initialise l'utilisation de la carte mémoire SD en mode SPI ---
  pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (nécessaire avec module ethernet)
  digitalWrite(10, HIGH); // mais désactive le  circuit intégré W5100 du module ethernet (on ne peut donc pas utiliser la connexion RJ45 et la carte SD en même temps)

  //--- Si la carte SD n'est pas inséré il y a une erreur ---
  if (!SD.begin(4)) {
   lcd.setCursor(0,0);
   lcd.println("Erreur SD");
   lcd.setCursor(0,1);
   lcd.print("RESET");
   delay(1000000);
  }
  else { // si initialisation réussie
   lcd.print("Init reussie");
   delay(1000);
   lcd.clear();
  
    //--- Affiche le contenu du répertoire ---
   root = SD.open("/"); // ouvre la carte SD à la racine
   lcd.print("Fichier ouvert");
   delay(1000);
   lcd.clear();
    
   file.seek(file.size()); //écrit à la fin du fichier
  } // fin si, initialisation réussie

  file = SD.open("data.txt", FILE_WRITE); // ouverture du fichier data.txt en écriture
  file.println("NumeroMesure;VitesseNKE;Vitessederotation;Temps"); // écriture sur la premier ligne du fichier data.txt
  file.close(); //fermeture fichier data.txt
}
 
// /////////////////////////////// 3. FONCTION LOOP = Boucle principale ///////////////////////////////
void loop() { 
 freq_nke=count;
 count=0;
 vitesse_nke=freq_nke/4.5; //le constructeur dit 4.5 Hz => 1 Noeud
 vitesse_ms=vitesse_nke*0.514444; // 1 Noeud = 0.5144444 m/s

 freq_rotation=count_rotation;
 count_rotation=0;
 vitesse_rotation=freq_rotation/1.66; 
   
  ecritureSD();  // Fonction ecritureSd(), permet d'écrire sur la carte SD
  ecritureLCD();  // Fonction ecritureLCD(), permet d'écrire sur l'afficheur LCD
  y++;
  delay(1000);
} 
  
void ecritureSD() { // Boucle écriture sur la carte SD et dans le fichier data.txt
    file = SD.open("data.txt", FILE_WRITE); 
    file.print(y), file.print(';'); // Numéro de la mesure
    file.print(vitesse_ms), file.print(';'); // Vitesse de l'eau en m/s
    file.print(vitesse_rotation), file.print(';'); // Vitesse de rotation en tr/min
    file.print(millis()); // Temps écoulé depuis le début du programme
    file.println(); 
    file.close(); 
}
   
void ecritureLCD(){ // Boucle affichage LCD
  // --- Affiche la vitesse de rotation ---                
  lcd.setCursor(0,0);
  lcd.print("N=");
  lcd.setCursor(3, 0); // colonne 4, ligne 1
  lcd.print(vitesse_rotation,2);
  lcd.setCursor(11, 0);
  lcd.print("tr/mn");
  // --- Affiche la vitesse de l'eau ---     
  lcd.setCursor(0,1);
  lcd.print("V=");
  lcd.setCursor(3, 1); // colonne 4, ligne 2
  lcd.print(vitesse_ms,3);
  lcd.setCursor(11, 1);
  lcd.print("m/s");     
}

void vitesse_int() { //Fonction appellé par attachInterrupt
  count++;
}

void compteur() { //Fonction appellé par attachInterrupt
  count_rotation++;
}

count++; finit par provoquer un dépassement de capacité, comme millis() et les autres variables toujours croissantes.

Count est remis à 0 mais millis non.

Donc en gros si je redémarre le programme ça va fonctionner

Déjà une remarque : les interruption normalement toujours en fin de setup(), ça évite les mauvaises surprises ...

Ensuite root n'est jamais fermé. Enfin aucune erreur n'est gérée : si tu veux un programme fiable il faut partir du principe que ça peut ne pas fonctionner. Sur les file.open() il faut toujours les inclure dans une condition if pour être sûr que ça marche, sinon ça peut partir en cacahuète

Bonjour,

tout d'abord un grand merci pour vos réponses, j'ai une meilleur compréhension du problème.

je viens de supprimer les valeurs qui s'incrémente (y et millis), normalement je dois gagner de la place mémoire. Logiquement sans "y" et sans "millis" il ne devrait plus y avoir de dépassement de capacité.

Pouvez-vous me le confirmer ?

@ B@tto je m'attaque maintenant à la gestion des erreurs, vu que lors de mes essais cher moi il n'y a jamais eu de problèmes (gestion de la mémoire interne, erreur), je n'ai pas sécurisé le programme.

Je vais faire comme tu me l'as dit mettre les file.open() dans des conditions.

Cordialement.

Christian s'est trompé, le dépassement n'est pas grave en soi, la variable revient à zéro (ou à la valeur négative inférieure du type de la variable) et c'est tout. Donc ce n'est pas ça qui a pu faire planté ton programme. Ca serait un problème si le dépassement de la variable est un problème dans son emploi. Exemple : emploi de la variable pour pointer dans un tableau. Index négatif = problème

count et count_rotation doivent être déclarée volatile car elle sont manipulées sous interruption.
Les vitesse, frequence de rotation et numéros de mesure étant, je suppose, toujours positifs ces variables devraient être des unsigned int.

Au passage, le calcul est entâché d’erreur. Tu calcules des tr/sec et des m/s mais tu places un delay d’une seconde à la fin de loop. Il faudrait soustraire le temps passé dans les diverses fonctions.
Le mieux serait d’utiliser millis() pour gérer le temps dans la boucle. Charger une variable temps avec millis() après une mesure, lancer les fonctions de stockage/affichage et entrer dans une boucle d’attente jusqu’à ce que millis() soit supérieur ou égal à temps+1000.

Petite explication :

Les capteurs que j’utilise délivrent un signal dont la fréquence nous donne la valeur :

Une fréquence est en Hz :
1 Hz correspond à une impulsion par seconde
Donc si on sait le nombre d’impulsion en 1 seconde, on sait le nombre de Hz.
Voila pourquoi le delay(1000).

Pourquoi j’utilise des int/float/char car je connais seulement ça :smiley:
je vais faire les modifications (je vais quand même vérifier ce que tu me dis :D)

Merci pour la réponse.
Et le gros problème c’est que je suis électrotechnicien, donc un moteur synchrone à fabriquer aucun soucis, mais pour la programmation, ça devient plus complexe donc je fais avec les connaissances que j’ai et puis le forum m’a beaucoup aidé.

Cordialement

elhemia: Petite explication : Une fréquence est en Hz : 1 Hz correspond à une impulsion par seconde Donc si on sait le nombre d'impulsion en 1 seconde, on sait le nombre de Hz. Voila pourquoi le delay(1000).

Ce que je te dis c'est que ta boucle ne s'exécute pas en 1 seconde mais en 1s + le temps d'exécution de toutes les fonctions appellées dans la boucle. Admettons que la routine d'affichage + l'écriture sur la carte mémoire prenne 100ms alors ta boucle dure 1,1s au lieu d'une seconde comme tu le crois (ce qui ferait 10% d'erreur). D'ailleurs tu peux le vérifier facilement en dépouillant les valeurs sur ta carte mémoire. Puisque tu écris le temps écoulé par cette ligne: file.print(millis()); // Temps écoulé depuis le début du programme Tu devrais voir qu'entre 2 lignes consécutives de mesure il ne s'écoule pas 1000 ms.

Bonjour,

Comment faire la simulation sur proteus 8 avec ce programme.