Je travaille sur un projet dans lequel je pilote en position deux moteurs à courant continu. Je gère la position grâce à un encodeur et une programmation Arduino en PID.
Mon problème est que j'ai actuellement une position relative et non absolue.
Pour avoir une position absolue, j'ai pensé mémoriser puis dans la foulée écraser toutes mes mesures de positions réalisées par les encodeurs. Ainsi, au redémarrage de l'Arduino, j'aurai en mémoire la dernière position sauvegardé.
Si par "redémarrage" tu penses à une mise hors/sous tension de l'arduino, ou même à un reset sans coupure électrique, sache que le contenu de la ram est réinitialisé.
La solution principale pour mémoriser des informations d'état après un redémarrage, consiste à les écrire dans l'eeprom.
Mais attention l'eeprom n'est pas destinée à subir un nombre important de cycles d'écritures.
Pas question par exemple de sauvegarder l'état courant dans l'eeprom n fois par seconde.
Effectivement, on peut stocker la position dans l'eeprom à condition de respecter le nombre d'écritures limitées comme le dit bricoleau.
Mais à mon avis ça va m**der à plus ou moins long terme.
Je veux en effet mémoriser la dernière valeur d'un compteur dans l'EEPROM, pour que lorsque je démarre l'application, mon objectif position prenne en compte la position actuelle (la dernière position mémorisé).
Je pensais mémoriser les valeurs au fur et à mesure du comptage, et écraser les plus anciennes au fur et à mesure aussi, possible ?
Pour l'eeprom il existe des cartes RTC à 1€ qui contiennent une eeprom en plus du DS3231 ou du DS1307(bien moins bon que le DS3231). Cerise sur le gâteau on peut horodater les mesures.
De plus le nombre limité d'écritures est position par position, il n'y a pas de limite pour la lecture.
Donc si le nombre de valeurs à sauvegarder n'est pas grand il devrait être possible d'écrire un bout de programme pour éviter d'écrire toujours au même endroit.
Le module RTC peut se changer facilement.
Après il reste la carte SD, quasi même techno donc nombre d'écriture limité aussi mais il doit y avoir de la marge et on peut en changer préventivement très facilement.
Pour illustrer : l'arduino uno dispose d'une eeprom de 1024 octets.
Chaque cellule de l'eeprom a une "espérance de vie" de 100.000 écritures (minimum plus ou moins garanti).
En prenant l'hypothèse favorable d'une gestion intelligente de la distribution des écritures sur l'ensemble de l'eeprom, sans perte de place significative liée au besoin de gestion de cette distribution :
Je veux par exemple écrire 20 octets toutes les 100 ms, ce qui correspond à un volume d'écritures de 200 octets par seconde.
L'espérance de vie de l'eeprom sera de 1024*100.000 / 200 = 512.000 secondes, soit un peu moins de 6 jours en fonctionnement continu.
Pour les besoins d'écriture intensive d'un faible volume d'information, il existe une autre solution assez proche de celle indiquée par 68tjs :
Le RTC DS1307 dispose d'une mémoire non volatile 56 octets, sans limite de réécriture.
En fait il s'agit d'une RAM dont la sauvegarde est assurée par la pile bouton du RTC.
De toute façon ça va merder a plus ou moins long terme car on ne va pas pouvoir mémoriser la position à chaque pas et si on coupe à ce moment là on sera décalé. De plus on va perdre un pas par ci, un pas par la surtout au changement de sens et au bout d'un moment on sera décalé.
Je ne pense pas que ce soit fiable sans top 0 (ou codage absolu).
bricoleau:
Quelle est la quantité d'information à mémoriser (en octets)?
Quelle est la fréquence de mémorisation?
La réponse précise à ces questions est indispensable pour définir la solution adaptée au besoin.
Il faut mémoriser un nombre compris entre -28600 et 28600.
La fréquence d'échantillonnage de mon programme est 20 Hz, mais on peut imaginer mémoriser un point sur 4. Sois une fréquence d'écriture de 5 Hz.
68tjs:
Pour l'eeprom il existe des cartes RTC à 1€ qui contiennent une eeprom en plus du DS3231 ou du DS1307(bien moins bon que le DS3231). Cerise sur le gâteau on peut horodater les mesures.
De plus le nombre limité d'écritures est position par position, il n'y a pas de limite pour la lecture.
Donc si le nombre de valeurs à sauvegarder n'est pas grand il devrait être possible d'écrire un bout de programme pour éviter d'écrire toujours au même endroit.
Le module RTC peut se changer facilement.
Après il reste la carte SD, quasi même techno donc nombre d'écriture limité aussi mais il doit y avoir de la marge et on peut en changer préventivement très facilement.
bricoleau:
Pour les besoins d'écriture intensive d'un faible volume d'information, il existe une autre solution assez proche de celle indiquée par 68tjs :
Le RTC DS1307 dispose d'une mémoire non volatile 56 octets, sans limite de réécriture.
En fait il s'agit d'une RAM dont la sauvegarde est assurée par la pile bouton du RTC.
Je vais étudier ces solutions, merci !
kamill:
De toute façon ça va merder a plus ou moins long terme car on ne va pas pouvoir mémoriser la position à chaque pas et si on coupe à ce moment là on sera décalé. De plus on va perdre un pas par ci, un pas par la surtout au changement de sens et au bout d'un moment on sera décalé.
Je ne pense pas que ce soit fiable sans top 0 (ou codage absolu).
Je suis d'accord avec toi, mais l'application ne demande pas une précision énorme, donc même si l'on est un peu décalé par rapport à la vraie position, ça n'est pas très problématique.
Des idées de top 0 ?
infobarquee:
bonjour,
si tu expliquais vraiment ton projet.
tu entends quoi par absolue et relative?
Je pilote via Arduino un moteur CC en position. Je connais sa position relative grâce à l'encodeur. Je connais donc le nombre de tour effectué entre la position au démarrage de l'application et la fin de course. Par contre, je ne connais pas ma position de départ, je ne suis donc pas en position absolue.
Si je me souviens bien, tu as dans ton système une vis sans fin et tu cherches à positionner quelque chose en translation, c'est bien ça ?
Si oui, tu pourrais peut-être attacher ton dispositif à un potentiomètre linéaire ? Ca ne sera pas hyper-précis mais ce serait mieux que rien. En tout cas, le zéro absolu doit se faire sur la partie en translation car côté moteur, comme celui-ci tourne a priori de plus d'un tour sur la course totale de ton système, tu ne pourras jamais connaître le "vrai" zéro.
3Sigma:
Si je me souviens bien, tu as dans ton système une vis sans fin et tu cherches à positionner quelque chose en translation, c'est bien ça ?
Si oui, tu pourrais peut-être attacher ton dispositif à un potentiomètre linéaire ? Ca ne sera pas hyper-précis mais ce serait mieux que rien. En tout cas, le zéro absolu doit se faire sur la partie en translation car côté moteur, comme celui-ci tourne a priori de plus d'un tour sur la course totale de ton système, tu ne pourras jamais connaître le "vrai" zéro.
En fait, l'arbre de mon moteur entraîne un pointeau qui par sa position verticale règle un débit d'air. J’entraîne mon pointeau en rotation qui translate verticalement via son pas de vis.
En effet, le moteur tourne sur +/- 8 tours.
Pourquoi l'interrupteur de mise en marche/arrêt de ton robot ne serait t'il pas un inter qui pilote le programme de l'arduino, qui sauvegarde, et qui éteint ton robot?
Quand tu décides de mettre sur OFF ton robot, un bout de code enregistre dans l'eeprom ce qu'il faut (positions etc...), puis un autre bout de programme actionne un transistor de puissance (et un relais) qui vient ouvrir ton circuit (couper le + de la batterie). Avec un interrupteur on off on, tu peux peut être te servir d'un on pour piloter l'arduino, et de l'autre on pour le redémarrage du robot (réexciter le relais).
Perso je partirais sur la NVRAM d'un DS1307.
Une écriture à 20Hz ne poserait aucun problème.
Pour être propre et robuste, utiliser par exemple 9 octets de la NVRAM
4 octets : signature constante
1 octet : indicateur de valeur a ou b chargée
2 octets : valeur a
2 octets : valeur b
La signature constante permet, au démarrage de l'arduino, de vérifier que le contenu de la RAM est ok (détection du cas de pile bouton HS et donc de contenu de RAM perdu)
Et comme une coupure électrique peut intervenir au milieu du cycle d'écriture en NVRAM, il est nécessaire de stocker en double pour avoir la garantie d'intégrité de ta donnée.
J'écris mon entier dans la valeur a, puis j'écris 'a' dans l'indicateur.
Et sur la sauvegarde suivante, j'écris mon entier dans la valeur b puis j'écris 'b' dans l'indicateur
En lecture, je lis d'abord la valeur de l'indicateur pour savoir si je dois récupérer la donnée dans la valeur a ou b
Ainsi, quel que soit le moment de la coupure électrique de l'arduino, je dispose toujours d'une dernière valeur correctement sauvegardée.
La seule faiblesse de cette solution, c'est la durée de vie de la pile bouton du RTC.
bricoleau:
4 octets : signature constante
1 octet : indicateur de valeur a ou b chargée
2 octets : valeur a
2 octets : valeur b
J'écris mon entier dans la valeur a, puis j'écris 'a' dans l'indicateur.
Et sur la sauvegarde suivante, j'écris mon entier dans la valeur b puis j'écris 'b' dans l'indicateur
Ainsi, quel que soit le moment de la coupure électrique de l'arduino, je dispose toujours d'une dernière valeur correctement sauvegardée.
Bricoleau, je comprend bien l'idée mais en cas de coupure pendant l'écriture, disons pendant "a", on se retrouve avec comme seule donnée valide "b" mais du cycle de sauvegarde précédent donc périmée, vieille de 50ms? Non?
@Thomas : en fait c'est tout bête, un DS1307 dispose d'une RAM de 64 octets dans laquelle il n'utilise que les 8 premiers pour y incrémenter automatiquement la date et l'heure. Les 56 octets suivants sont disponibles.
@Jambe : là tu pinailles. Si la coupure intervient au milieu d'une sauvegarde, alors par définition la seule sauvegarde disponible est la précédente. Ceci dans tout système de sauvegarde. A compenser par la fréquence de sauvegarde.
Edit : et de toute manière, si tu sauvegardes à 20 Hz, au moment du redémarrage ta dernière sauvegarde sera statistiquement vieille de 0 à 49 ms par rapport à l'arrêt. Sauf bien sûr si tu mets d'autres mécanismes en place pour maîtriser l'arrêt du système et déclencher une sauvegarde avant extinction.
ReEdit : en fait l'idée de la double écriture est surtout d'éviter tout risque de redémarrer le système en se retrouvant avec des valeurs aberrantes, car selon les montages les conséquences peuvent être fâcheuses.
bricoleau: @Thomas : en fait c'est tout bête, un DS1307 dispose d'une RAM de 64 octets dans laquelle il n'utilise que les 8 premiers pour y incrémenter automatiquement la date et l'heure. Les 56 octets suivants sont disponibles.
Merci beaucoup. Quelles sont les bibliothèques disponibles pour coder sur ce composant ? Y en a-t-il des spécifique ou les bibliothèques EEPROM conviennent ?