Le forum pour tous les bidouilleurs electroniciens, du novice à l'expert ! |
Bienvenue ! Des questions sur l'électronique? Ou passionnés par ce domaine? Partageons nos savoirs et compétences en vous inscrivant. |
|
| Détection coupure d'alimentation ? | |
| | Auteur | Message |
---|
Savignyexpress Membre actif
Messages : 110 Date d'inscription : 16/05/2012 Age : 61 Localisation : Suisse Emploi/loisirs : Ingénieur informaticien, modélisme ferroviaire, électronique
| Sujet: Détection coupure d'alimentation ? Ven 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. | |
| | | Quentin Admin
Messages : 419 Date d'inscription : 21/04/2012 Age : 30 Localisation : Haute-Vienne (87) Emploi/loisirs : Collecto-bédétiste !
| Sujet: Re: Détection coupure d'alimentation ? Sam 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 ? ) Ce système serait nécessaire pour quel montage ? | |
| | | Savignyexpress Membre actif
Messages : 110 Date d'inscription : 16/05/2012 Age : 61 Localisation : Suisse Emploi/loisirs : Ingénieur informaticien, modélisme ferroviaire, électronique
| Sujet: Re: Détection coupure d'alimentation ? Mar 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)) | |
| | | Savignyexpress Membre actif
Messages : 110 Date d'inscription : 16/05/2012 Age : 61 Localisation : Suisse Emploi/loisirs : Ingénieur informaticien, modélisme ferroviaire, électronique
| Sujet: Re: Détection coupure d'alimentation ? Mar 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. | |
| | | Contenu sponsorisé
| Sujet: Re: Détection coupure d'alimentation ? | |
| |
| | | | Détection coupure d'alimentation ? | |
|
| Permission de ce forum: | Vous ne pouvez pas répondre aux sujets dans ce forum
| |
| |
| |
|