Les dessoudeurs de l'extrême
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.


Le forum pour tous les bidouilleurs electroniciens, du novice à l'expert !
 
AccueilAccueil  Dernières imagesDernières images  RechercherRechercher  S'enregistrerS'enregistrer  Connexion  
Bienvenue ! Des questions sur l'électronique? Ou passionnés par ce domaine? Partageons nos savoirs et compétences en vous inscrivant.
Le Deal du moment : -23%
EVGA SuperNOVA 650 G6 – Alimentation PC 100% ...
Voir le deal
77.91 €

 

 Détection coupure d'alimentation ?

Aller en bas 
2 participants
AuteurMessage
Savignyexpress
Membre actif
Membre actif
Savignyexpress


Messages : 110
Date d'inscription : 16/05/2012
Age : 61
Localisation : Suisse
Emploi/loisirs : Ingénieur informaticien, modélisme ferroviaire, électronique

Détection coupure d'alimentation ? Empty
MessageSujet: Détection coupure d'alimentation ?   Détection coupure d'alimentation ? EmptyVen 13 Sep - 9:33

Bonjour à tous,

J'aimerais réaliser un montage à micro-contrôleur tel que le programme soit capable de sauvegarder son état courant dans l'EEPROM lorsqu'une coupure d'alimentation survient, pour pouvoir ensuite le reprendre au prochain redémarrage. J'ai plusieurs idées à ce sujet, mais votre avis m'intéresse.

Sauvegarde à chaque changement d'état
Cette solution est purement logicielle, elle consiste à sauvegarder l'état en EEPROM chaque fois qu'il change !

Avantage: pas de matériel supplémentaire.

Inconvénients: applicable que si les changements d'états sont peu fréquents car le nombre max garanti de cycles d'écritures de l'EEPROM est de 100'000.

Gold cap et mesure / comparaison de tension en amont
Il s'agit de placer une gold cap comme réservoir de courant entre le régulateur de tension et le micro-contrôleur. La tension à l'entrée est mesurée et comparée. Lorsqu'elle descend au-dessous d'un certain seuil, on en déduit qu'elle va être coupée. Il est possible d'utiliser le comparateur analogique présent sur les micros de la famille AVR (conversion AD par indispensable) avec peut-être un diviseur de tension pour s'adapter à la référence interne du micro. On sauvegarde alors l'état courant en EEPROM après avoir mis le micro-contrôleur en mode basse consommation.

Avantage: écritures en EEPROM qu'à la coupure de courant.

Inconvénient: besoin de composants supplémentaires.


Avez-vous d'autres suggestions ?

Meilleures salutations.
Revenir en haut Aller en bas
Quentin
Admin
Admin
Quentin


Messages : 419
Date d'inscription : 21/04/2012
Age : 29
Localisation : Haute-Vienne (87)
Emploi/loisirs : Collecto-bédétiste !

Détection coupure d'alimentation ? Empty
MessageSujet: Re: Détection coupure d'alimentation ?   Détection coupure d'alimentation ? EmptySam 14 Sep - 23:02

La deuxième solution me semble vraiment simple et fiable !  
(Est-ce que l'ajout de 2-3 composants est vraiment un problème ? hun
Ce système serait nécessaire pour quel montage ? Smile
Revenir en haut Aller en bas
https://dessoudeurs-ex.lebonforum.com
Savignyexpress
Membre actif
Membre actif
Savignyexpress


Messages : 110
Date d'inscription : 16/05/2012
Age : 61
Localisation : Suisse
Emploi/loisirs : Ingénieur informaticien, modélisme ferroviaire, électronique

Détection coupure d'alimentation ? Empty
MessageSujet: Re: Détection coupure d'alimentation ?   Détection coupure d'alimentation ? EmptyMar 17 Sep - 9:51

Hello Quentin,

Le montage doit gérer la gare d'un réseau ferroviaire à l'échelle N. Il est souhaité que l'état de la gare soit conservé après l'arrêt du système pour le reprendre au démarrage suivant du système.

Un arrêt peut soit être normal, soit d'urgence par coupure quasi instantanée de courant pour éviter une collision entre trains.

Depuis que j'ai posté ce message, j'ai approfondi la solution logicielle et j'ai trouvé une note d'application d'Atmel (cf. pièce jointe) très intéressante. Comme le nombre d'écritures max d'un byte de l'EEPROM est de 100'000, l'idée est d'utiliser plusieurs bytes pour sauvegarder l'état à chaque changement. À l'aide de 2 buffers circulaires, on sauvegarde l'état ainsi qu'une info permettant de déterminer quel élément du buffer doit être utilisé.

Au détriment d'une plus grande place en EEPROM, cette solution permet de multiplier le nombre d'écritures max en EEPROM par 10-20 selon la taille des données à sauvegarder. On évite ainsi le besoin de détecter la coupure de courant pour sauvegarder et économiser le nombre de cycles d'écritures.

En imaginant 2 changements d'état par minute d'exploitation du réseau, 2 heures d'exploitation par semaine, cela donne de la marge.


  • Nb. changements d'états par heure: 120.
  • 2 heures par semaine -> 240 changements d'états par semaine -> 240 * 52 = 12'480 changements d'états par année.
  • Nb. cycles max = nb. d'entrées dans le buffer * nb. cycles max EEPROM = 20 * 100'000 = 2'000'000.
  • Nb. d'années d'exploitation = 2'000'000 / 12'480 = 160 années !!!


Le principe est le suivant:


  • Il y a aussi un buffer circulaire contenant les indices utilisés et libres. Il a le même nombre d'éléments, mais ils peuvent être de plus petite taille que le buffer de données.

  • Les 2 buffers sont parcourus en même temps.

  • Le buffer des indices est initialement rempli avec des zéros. Cela se fait à l'aide d'un fichier .eep.

  • Après écriture dans l'élément courant dans le buffer de données, l'indice est écrit à la même position dans le second buffer. Les indices sont incrémentés.

  • Pour déterminer quel élément est libre, on parcourt le buffer d'indices. Si l'élément courant contient un zéro, il est libre. Si la différence entre l'indice de l'élément courant et l'indice du précédent élément est plus grande que 1, utiliser cet élément.

  • Pour déterminer quel élément contient la dernière sauvegarde, on parcourt aussi le buffer d'indices. Si la différence entre l'indice de l'élément courant et l'indice du suivant est plus grande que 1, l'indice courant pointe vers la dernière sauvegarde.


Même si la solution matérielle ne comporte que peu de composants, je suis toujours intéressé par les solutions logicielles qui offrent plus de souplesse !


Dernière édition par Savignyexpress le Mar 17 Sep - 9:55, édité 2 fois (Raison : Ajout pièce jointe (copyright Atmel))
Revenir en haut Aller en bas
Savignyexpress
Membre actif
Membre actif
Savignyexpress


Messages : 110
Date d'inscription : 16/05/2012
Age : 61
Localisation : Suisse
Emploi/loisirs : Ingénieur informaticien, modélisme ferroviaire, électronique

Détection coupure d'alimentation ? Empty
MessageSujet: Re: Détection coupure d'alimentation ?   Détection coupure d'alimentation ? EmptyMar 17 Sep - 19:45

Bonsoir à tous,

Voici le programme de test de gestion d'un buffer circulaire. Pour l'instant, c'est simulé sur PC, la prochaine étape est de compléter les accès aux 2 tableaux à l'aide des instructions d'accès à l'EEPROM.

Dans la simulation, les tableaux ont 4 éléments. Celui de données aData contient des entiers sur 16 bits, celui des indices aIndices contient des bytes.

Code:

//
//   TestBufferEeprom.c
//
//   Programme de test d'un buffer en EEPROM pour augmenter
//   le nombre de cycles d'écritures.
//
//   2013.09.17   MHP   Création.
//
//   Directives de compilation: PC ou AVR.
//

#ifdef PC
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#endif


#define   LONG_BUFFER   4
#define   INDICE_MAX   (2*LONG_BUFFER)
#define   VIDE   0xFF

uint16_t   aEtats[LONG_BUFFER];
uint8_t   aIndices[LONG_BUFFER];

static void Init(void)
{
uint8_t   i;

   for(i = 0; i < LONG_BUFFER; i++)
      aIndices[i] = VIDE;
} // Init


static void AfficherBuffer(void)
{
#ifdef PC
uint8_t i;

   printf("Après écriture\n");
   for(i = 0; i < LONG_BUFFER; i++)
      printf("aIndices[%d] = %d\t\taEtats[%d] = %d\n", i, aIndices[i], i, aEtats[i]);

   printf("\n");
#endif
} // AfficherBuffer


static uint8_t bVide(void)
{
uint8_t i;

   for(i = 0; i < LONG_BUFFER; i++)
   {
      if(aIndices[i] != VIDE)
         return(0);
   } // for

   return(1);
} // bVide


static uint8_t nTrouverPositionLecture(void)
{
uint8_t   i;

   #ifdef PC
   if(bVide())
   {
      printf("Vide, lecture impossible\n");
      exit(-1);
   } // if
   #endif

   i = 0;
   while(((aIndices[i] + 1) % INDICE_MAX) == aIndices[i+1])
      i++;

   return(i);
} // nTrouverPositionLecture


static uint8_t nTrouverPositionEcriture(void)
{
uint8_t i;

   if(!bVide())
   {
      i = nTrouverPositionLecture();
      return((i + 1) % LONG_BUFFER);
   }
   else
      return(0);
} // nTrouverPositionEcriture


static void EcrireEEPROM(uint16_t nVal)
{
uint8_t   i, j;

   i = nTrouverPositionEcriture();
   #ifdef PC
   printf("Ecriture de: %d en position: %d\n", nVal, i);
   #endif
   aEtats[i] = nVal;

   if(!bVide())
   {
      j = nTrouverPositionLecture();
      aIndices[i] = (aIndices[j] + 1) % INDICE_MAX;
   }
   else
      aIndices[i] = 0;

   AfficherBuffer();
} // EcrireEEPROM


static uint16_t nLireEEPROM(void)
{
uint8_t i;

   i = nTrouverPositionLecture();
   #ifdef PC
   printf("Position: %d, lecture: %d\n\n", i, aEtats[i]);
   #endif
   return(aEtats[i]);
} // nLireEEPROM


void main(void)
{
#ifdef PC
uint16_t nVal;

   Init();

   EcrireEEPROM(10);
   EcrireEEPROM(23);
   EcrireEEPROM(34);
   nVal = nLireEEPROM();
   EcrireEEPROM(5);
   EcrireEEPROM(30);
   nVal = nLireEEPROM();
   EcrireEEPROM(1013);
   nVal = nLireEEPROM();
   EcrireEEPROM(1012);
   EcrireEEPROM(255);
   nVal = nLireEEPROM();
   EcrireEEPROM(51);
   EcrireEEPROM(53);
   EcrireEEPROM(55);
   nVal = nLireEEPROM();
   EcrireEEPROM(125);
   nVal = nLireEEPROM();
   EcrireEEPROM(355);
   nVal = nLireEEPROM();
#endif
} // main
Après compilation avec gcc, le résultat de l'exécution donne:
Code:

Ecriture de: 10 en position: 0
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 255      aEtats[1] = 0
aIndices[2] = 255      aEtats[2] = 0
aIndices[3] = 255      aEtats[3] = 0

Ecriture de: 23 en position: 1
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 255      aEtats[2] = 0
aIndices[3] = 255      aEtats[3] = 0

Ecriture de: 34 en position: 2
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 255      aEtats[3] = 0

Position: 2, lecture: 34

Ecriture de: 5 en position: 3
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 3      aEtats[3] = 5

Ecriture de: 30 en position: 0
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 3      aEtats[3] = 5

Position: 0, lecture: 30

Ecriture de: 1013 en position: 1
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 3      aEtats[3] = 5

Position: 1, lecture: 1013

Ecriture de: 1012 en position: 2
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 3      aEtats[3] = 5

Ecriture de: 255 en position: 3
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 7      aEtats[3] = 255

Position: 3, lecture: 255

Ecriture de: 51 en position: 0
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 7      aEtats[3] = 255

Ecriture de: 53 en position: 1
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 7      aEtats[3] = 255

Ecriture de: 55 en position: 2
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 2      aEtats[2] = 55
aIndices[3] = 7      aEtats[3] = 255

Position: 2, lecture: 55

Ecriture de: 125 en position: 3
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 2      aEtats[2] = 55
aIndices[3] = 3      aEtats[3] = 125

Position: 3, lecture: 125

Ecriture de: 355 en position: 0
Après écriture
aIndices[0] = 4      aEtats[0] = 355
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 2      aEtats[2] = 55
aIndices[3] = 3      aEtats[3] = 125

Position: 0, lecture: 355
Prochaine étape, test avec l'EEPROM d'un AVR.

Meilleures salutations.
Revenir en haut Aller en bas
Contenu sponsorisé





Détection coupure d'alimentation ? Empty
MessageSujet: Re: Détection coupure d'alimentation ?   Détection coupure d'alimentation ? Empty

Revenir en haut Aller en bas
 
Détection coupure d'alimentation ?
Revenir en haut 
Page 1 sur 1

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Les dessoudeurs de l'extrême :: AIDES & ASTUCES :: LA SECTION PROGRAMMATION :: GÉNÉRALITÉ SUR LES MICRO-CONTRÔLEURS-
Sauter vers: