Je suis en train de développer un programme qui me permettra de piloter un système et pour cela je dois utiliser normalement un DS1307 pour me faciliter la tâche. Mais il m'est venu à l'idée de chercher plutôt à voir si l'on pouvait écrire un programme qui simulerait une horloge (c'est-à-dire à peu près comme le RTC). Je pourrai ainsi récupérer l'heure et la date afin de pouvoir faire mes calculs.
Merci.
PS : Si vous avez d'autres propositions, je suis preneur.
C'est tout à fait possible, mais il y a des restrictions. Le core arduino utilise le timer0 pour compter le nombre de millisecondes ou microsecondes qui s'écoulent depuis la mise en route.
Actuellement, le timer 0 est configuré pour déclencher une interruption toutes les 1,024ms. l'interruption est celle-ci :
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)
ISR(TIMER0_OVF_vect)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}
il est possible de réarranger un peu le basard pour alléger le traitement, rajouter un comptage de secondes, minutes, heures... Par contre, tout est remis à 0 à chaque reset. à moins d'avoir un système de sleep qui va bien (et donc une batterie de sauvegarde si c'est ammené à être débranché). si ça t'ouvre des pistes, ce code est dans le fichier wiring.c du core arduino. tu peux aussi réorganiser le timer fonction init() du même fichier) pour qu'il déclenche l'interruption toutes les ms, ce qui évite tout le traitement pour compenser les 24µs de décallage.
EDIT : il me semble que le timer2 est plus adapté à ce genre de fonction (sur le 2560, on peut même lui rajouter un quartz spécifique pour avoir un RTC)
Je suis en train de développer un programme qui me permettra de piloter un système et pour cela je dois utiliser normalement un DS1307 pour me faciliter la tâche. Mais il m'est venu à l'idée de chercher plutôt à voir si l'on pouvait écrire un programme qui simulerait une horloge (c'est-à-dire à peu près comme le RTC). Je pourrai ainsi récupérer l'heure et la date afin de pouvoir faire mes calculs.
Merci.
PS : Si vous avez d'autres propositions, je suis preneur.
bonjour
memes remarques que fdufnews
ceci etant, l'obtention d'un datage par DS1307 est ce qu'il y a de plus repandu "en amateur arduino" = ça ne coute pas cher
mais il existe d'autres alternantives offrant d'ailleurs une precision bien meilleure que le ds1307
les 2 principales :
utiliser un module GPS et recuperer les infos de datation
C'est tout à fait possible, mais il y a des restrictions. Le core arduino utilise le timer0 pour compter le nombre de millisecondes ou microsecondes qui s'écoulent depuis la mise en route.
Actuellement, le timer 0 est configuré pour déclencher une interruption toutes les 1,024ms. l'interruption est celle-ci :
bonjour S5
je n'avais jamais fait attention à ça
donc les millis ou microsecondes renvoyées de base sont donc
pour 1 = 1.024 +/- tolerance horloge (quartz) ?
ça fait quand meme une importante derive sur des temps long
+1
Pour des motifs de réduction de coût les cartes Arduino ne sont plus équipées avec des quartz mais avec des résonnateurs, excepté pour l'interface USB: l'atmega8 ou 16 à encore un quartz sinon l'USB ne fonctionnerait pas.
Et si un résonnateur est moins cher c'est qu'il est beaucoup moins précis.
D'autre part je ne vois pas l'intérêt de surcharger le micro-controleur en lui faisant faire ce qui peut être aventageusement déporté sur une électronique indépendante qui remplira bien mieux la fonction comme cela à déjà été répondu.
Effectivement, c'est dommage de ne pas utiliser une électronique externe, mais c'est toujours intéressant de programmer ce genre de fonction, c'est comme ça qu'on apprend...
Artouste:
donc les millis ou microsecondes renvoyées de base sont donc
pour 1 = 1.024 +/- tolerance horloge (quartz) ?
ça fait quand meme une importante derive sur des temps long
Oui, mais non. en fait, l'interruption utilise le principe des années bisextiles (1 an != 365 jours), et on y retrouve aussi bresenham : en gros, on compte trop lentement, puisqu'il traine des 24µS. dont tous les certains temps (le if de l'interruption), on compte un de plus pour rattraper le retard. mais on peut configurer le timer pour qu'il pète toutes le ms précisément, et ça raccourcis grandement le traitement de l'int, donc avec un comptage de secondes minutes heures jours etc etc, on s'y retrouve. sauf pour compter les mois et années, car on sort de l'incémentation standard.
En activant l'horloge interne de l'atmega, on peut mettre un quartz 32768 Hz à la place du quartz 8MHz. Ensuite, on configure le timer 2 en le mettant en mode asynchrone avec le prédiviseur réglé à 64. Ensuite il faut activer l'interruption de débordements du timer 2. Ce qui donne un programme dans ce genre :
#include <avr/io.h>
#include <avr/interrupt.h>
ISR (TIMER2_OVF_vect){ //interruption par débordement
seconde ++;
}
void setup(){
TIMSK2 = 0X00;
ASSR |=(1 << AS2);
TCCR2B =0x04;
while (ASSR != 0x20);
TIMSK2 |= (1 << TOIE2);
TCCR2B |= ((1 << CS22));
sei();
}
void loop(){
horloge();
//le reste du programme
}
void horloge(){
//On peut compter autrement les minutes et les heures.
if (seconde == 60){
minute ++;
seconde =0;
}
if (minute ==60){
heure ++;
minute = 0;
}
if (heure ==24){
jour++;
heure = 0;
if (jour > dmois[mois-1]){
jour = 1;
mois ++;
if(mois ==13){
mois = 1;
annee ++;
}
}
Tout d'abord merci pour vos réponses !
Je tiens à dire que je suis conscient que le fait d'utiliser le DS 13027 me faciliterait beaucoup la tâche. Il est tout à fait évident que le programme que je pense écrire ne remplirait pas les fonctions du RTC et qu'il y aurait même quelques imprécisions. Mais l'idée d'écrire ce programme, c'est juste au cas où. C'est un peu fou fou mais pas irréalisable. Je sais quand y réfléchissant très bien on peut trouver une alternative tout à fait commode.
Je sais que le DS1307 n'a pas été conçu pour rien mais néanmoins je voudrais trouver une alternative à cela même si c'est un peu exagéré.
Je suis moyen dans la programmation avec Arduino mais je suis près à apprendre d'avantage !