| Détection coupure d'alimentation par un micro-contrôleur | |
|
|
Auteur | Message |
---|
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 9:35 | |
| 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 ? |
|
| |
jlb Membre
Age : 60 Localisation : Ici Nombre de messages : 1544 Date d'inscription : 31/12/2011
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 10:14 | |
| Tu veux palier à des pannes du secteur ou au fait que l'utilisateur coupe l'alimentation ? |
|
| |
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 10:41 | |
| - jlb a écrit:
- Tu veux palier à des pannes du secteur ou au fait que l'utilisateur coupe l'alimentation ?
Hello Jlb, Le besoin initial est de redémarrer dans l'état précédant le dernier arrêt. La baisse de la tension d'alimentation est un bon indice que le système est en cours d'arrêt et cela s'applique tout aussi bien à un arrêt normal, arrêt d'urgence ou panne d'alimentation. |
|
| |
jlb Membre
Age : 60 Localisation : Ici Nombre de messages : 1544 Date d'inscription : 31/12/2011
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 11:14 | |
| Effectivement. Qui peut le plus peut le moins mais ça restreint le nombre de solutions et ça oblige à avoir une réserve d'énergie qui peut être importante si tu as beaucoup de matériel alimenté. En ne considérant que le cas d'arrêt volontaire (urgence ou normal), une solution sans réserve d'énergie est possible.
J'ai le même problème sur mon système mais vu le nombre de micro-contrôleur, ça n'est pas possible d'avoir une réserve d'énergie.
J'ai donc prévu un calculateur de gestion de l'alimentation de l'électronique (le 9V) branché sur le bus CAN des accessoires. Un poussoir sur le 220 permet d'allumer ce calculateur et la première chose qu'il fait est de fermer un relai sur le 220V en parallèle de l'alimentation via le poussoir. Ensuite, il allume les autres systèmes (contrôleur central, cartes de pilotage des accessoires) via des relais.
Une seconde pression sur le poussoir déclenche l'arrêt du système : - envoie d'un message d'arrêt au controleur. - le contrôleur arrête les trains en envoyant des consignes aux cartes d'alimentation par le CAN. - attend que les servos soient dans une position extrême puis les arrête - sauvegarde l'état en EEPROM - indique au calculateur de gestion de l'alimentation que tout est ok par le CAN - le calculateur de gestion de l'alimentation coupe les alims des autres systèmes puis se coupe lui-même.
Quelques remarques sur l'emploi d'une goldcap.
- Il me semble que la tension max est de 5V. Donc tu dois la mettre en aval du régulateur. C'est faisable de bricoler ça sur un arduino ? - Comment charger un engin pareil sans régulation de courant ? Je soupçonne que si tu la branches directement sur un régulateur de tension 7805, l'appel de courant va effondrer le régulateur. Je verrai bien un montage avec un LM317 monté en régulateur de courant avec une diode anti-retour pour charger la goldcap. La détection de défaillance de l'alim se faisant en amont de la diode. |
|
| |
jlb Membre
Age : 60 Localisation : Ici Nombre de messages : 1544 Date d'inscription : 31/12/2011
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 11:21 | |
| Quoiqu'en fait un régulateur de tension, une diode anti-retour et une réistance de charge devrait faire l'affaire |
|
| |
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 12:03 | |
| Merci Jlb pour la description de ton système. Les besoins du système pour la gare du réseau de Jappy sont plus modestes. Il n'y a qu'un micro-contrôleur et seul quelques bytes de RAM contenant l'état courant du programme doivent être sauvegardés en EEPROM. L'état des relais alimentation et aiguilles peut être reconstitué à partir de l'état du programme. Je n'utilise pas d'Arduino, mais une carte à pastille maison, j'ai donc toute latitude pour l'alimentation en amont de l'Atmega. J'explore aussi la voie 100% logicielle. Je joins une note d'application d'Atmel qui propose d'implanter un buffer circulaire en EEPROM pour multiplier le nombre de cycles d'écriture en EEPROM. Ainsi, il suffirait ensuite de procéder à des écritures périodiques si un changement d'état a eu lieu. Compte tenu de mes besoins, je pourrais facilement multiplier par 20-30 le nombre max. de cycles d'une cellule d'EEPROM (100'000 garanti selon la doc. Atmel). 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 !!!
Bonne fin de semaine. |
|
| |
jlb Membre
Age : 60 Localisation : Ici Nombre de messages : 1544 Date d'inscription : 31/12/2011
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 12:15 | |
| - SavignyExpress a écrit:
- Nb. d'années d'exploitation = 2'000'000 / 12'480 = 160 années !!!
Ça me semble suffisant |
|
| |
Invité Invité
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 16:49 | |
| c'est un peu court 160 ans. et je ne vois pas comment tu gères le nombre d'entrées dans le buffer, a part en grillant une des entrées...donc pour moi, tu restes bloqué à 8ans. Pour moi la Gold Cap qui ne sert qu'à sauvegarder dans un eeprom reste la meilleure solution. (reste à voir comment elle est applicable sur ton micro-controleur (detection integrée de base, ajouter un minimum de hardware : diode ou autre?) |
|
| |
CleoN Membre
Age : 69 Localisation : 33 Bouliac Nombre de messages : 1624 Date d'inscription : 26/11/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 19:22 | |
| Regardes la fonction "brown out" sur le datasheet des atmel, ca peut te rendre service. |
|
| |
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 20:50 | |
| - dania a écrit:
- et je ne vois pas comment tu gères le nombre d'entrées dans le buffer, a part en grillant une des entrées...donc pour moi, tu restes bloqué à 8ans.
Hello Dania, Je n'ai pas compris tout de suite la description du document d'Atmel joint à mon précédent message. Après réflexion, voici ce que j'ai compris:
- 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 modulo le nb d'éléments des buffers.
- 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.
On a donc bien le même nombre d'écritures possibles pour les indices que pour les données. Bonne soirée.
Dernière édition par SavignyExpress le Ven 13 Sep 2013 - 20:56, édité 2 fois |
|
| |
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Ven 13 Sep 2013 - 20:54 | |
| - CleoN a écrit:
- Regardes la fonction "brown out" sur le datasheet des atmel, ca peut te rendre service.
Hello CleoN, Merci pour cette suggestion. Je viens de relire les datasheets, mais il ne me semble pas que la fonction "brown out detection" réponde au besoin de sauvegarde sur l'EEPROM avant une baisse de courant. Le "brown out detection" a pour but d'éviter que le micro ne tourne avec une tension insuffisante car cela pourrait causer des erreurs. À cet effet, le micro est maintenu à l'état reset tant que la tension d'alimentation est inférieure à un certain seuil. À la sortie du reset, on peut vérifier que le brown out était la cause du reset, mais je pense que c'est trop tard pour sauvegarder une partie de la RAM en EEPROM, car la RAM pourrait être corrompue suite à la baisse de tension. Ou alors j'ai tout compris de travers... Bonne soirée. |
|
| |
Invité Invité
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Sam 14 Sep 2013 - 7:58 | |
| - SavignyExpress a écrit:
Hello Dania,
Je n'ai pas compris tout de suite la description du document d'Atmel joint à mon précédent message. Après réflexion, voici ce que j'ai compris: ...
On a donc bien le même nombre d'écritures possibles pour les indices que pour les données.
Bonne soirée. Hello SavignyExpress, j'avais pas vu le fichier joint à ton message précédent (peut être devrais-je aller dire bonjour à mon ophtalmo?). En effet, en lisant ce document j'arrive à mieux comprendre ton "truc". Plutôt malin de la part d'atmel ce système. Ton système sort donc vainqueur du grand débat |
|
| |
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Sam 14 Sep 2013 - 13:33 | |
| Hello Dania, J'ai affiné ma compréhension du principe proposé par Atmel ! En particulier:
- Atmel propose d'incrémenter les valeurs du buffer d'indices sans prendre le modulo. Cela impose que les éléments de ce buffer fassent au moins 24 bits pour contenir le nombre maximum d'écritures totales de plusieurs millions.
- Dans ce cas, la règle est simple, il suffit que la différence entre 2 cases consécutives ne soit pas 1.
- Une évolution du mécanisme Atmel si on veut que les éléments du buffer d'indices soient plus petits, pour garder de la place en EEPROM pour le bufffer de données, on peut faire de l'arithmétique modulo 2 fois la taille du buffer. On peut alors se contenter d'un tableau de bytes pour le buffer d'indices.
- Dans ce cas, la règle est un peu plus complexe car elle doit tenir compte du modulo.
Je prévois quelques tests ces prochaines semaines pour valider tout cela et je communiquerai les résultats et fonctions. Il faudrait aussi que je change le titre de mon post car il ne s'agit plus de détecter les coupures d'alimentation, mais de retrouver l'état du système après un redémarrage. Bon dimanche. |
|
| |
SavignyExpress Membre
Age : 61 Localisation : yyy Nombre de messages : 2042 Date d'inscription : 10/10/2010
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur Mar 17 Sep 2013 - 19:43 | |
| 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. |
|
| |
Contenu sponsorisé
| Sujet: Re: Détection coupure d'alimentation par un micro-contrôleur | |
| |
|
| |
| Détection coupure d'alimentation par un micro-contrôleur | |
|