Thermostat : RTC et gestions de plages ?

Bonjour,
Dans le cadre de mon projet de domotique, je prévois un thermostat par pièce. Un Arduino esclave + DS1820 + pilotage chauffage via tête de robinet de ce type :
http://www.technoprocess.lu/danfoss_chauffage/05-danfoss_chauffage_electro.html

Je souhaite avoir un programme pour chaque jour de la semaine avec une précision d'1/4 d'heure ou d'1/2 heure. Il faut donc une consigne basse, une consigne haute, et une horloge temps réel pour que le système sache à quelle heure il doit s'activer, ou pas. Pour l'horloge, je prévois un DS1307 sur 1 Arduino maitre qui enverra l'heure régulièrement vers tous les esclaves (en mode broadcast).

Je coince sur ces parties de l'algorithme :

Plages horaires
Si je réserve des plages de mémoire pour chaque jour de la semaine, comment faire pour les exploiter en pratique ?

Horloge
Une fois l'heure reçue (par exemple une fois par jour) par la carte esclave, comment cette dernière gère-t-elle le temps ? Dois-je utiliser une interruption intenre pour incrémenter un compteur interne ? Car je ne me vois pas installer 1 x DS1307 par carte !

Pourriez-vous me dire ce que vous utilisez, ou me renvoyer vers des algogithmes existants ?
Merci.

Une fois l'heure reçue (par exemple une fois par jour) par la carte esclave, comment cette dernière gère-t-elle le temps ?

En principe c'est tout simple. La carte esclave retient maintient l'heure elle même le mieux qu'elle peut avec millis() convertit en date, heure, minute et peut-être même second. A chaque fois que le temps est utilisé, ta fonction qui retourne le temps ajuste le temps d'abord avec millis(). Pour que ça marche, il faut aussi retenir la valeur de millis() de la dérniere fois que le temps a été actualisé. C'est assez bon si le temps est actualisé au moins une fois tout les 49 jours. Il y a même une librairie qui le fait pour toi ici: Arduino Time Library
Si maintenant le maître envoi le temps exacte, la valeur interne est ajustée et toute erreur se corrige automatiquement. La librairie fournie la fonction setTime pour ceci.

Pour les plages horaires, probablement il serait plus simple d'avoir une liste d'états avec les données: jour, temps démarrage, consigne haute et basse. L'entrée qui a commencé le plus récemment est la bonne.

Ton programme de réglage ensuite retient la valeur actuelle et cherche dans la liste les consignes actuelles, ensuite elle vérifie si la valeur est encore dans le bon intervalle et règle si non. Le programme va avoir une structure du genre:

loop (){

// Récupérer le temps actuel
...

// boucle sur toutes les chambres
for (int chambre = 0; chambre < chambreMax; chambre++) {
    // Trouver les consignes désirée dans la liste à base du temps et la chambre
    ...
    // Comparer consignes avec la valeur actuelle et réglage de la chambre
    ...
}
}

Il n'y a pas besoin de fonctions d'interruption. Le tout va devenir un peu plus compliqué parce qu'il faut aussi traiter des informations reçu des esclaves et leur envoyer de temps en temps l'heure exacte.

Korman

...Si maintenant le maître envoi le temps exacte, la valeur interne est ajustée et toute erreur se corrige automatiquement. La librairie fournie la fonction setTime pour ceci....

Je vais partir sur une actualisation de l'heure (maitre => esclaves) une ou n fois par jour (plus simple et efficace). J'ai regardé, millis() stocke en unsigned long.Dans ce cas, il me faut récupérer la valeur du DS1307 et l'écrire directement dans millis(). Donc ce registre représentera une sorte de clone du DS1307, autonome pendant 49 jours entre 2 refresh. Est-ce bien cela ?

Pour les plages horaires, probablement il serait plus simple d'avoir une liste d'états avec les données: jour, temps démarrage, consigne haute et basse. L'entrée qui a commencé le plus récemment est la bonne.

Finalement, plutôt que des consignes haute/basse, je pars sur des valeurs (plus souple). Ex. : chambre 19°C, salon 22°C et salle de bain le matin 24°C. La liste d'état dont tu parles serait une table en mémoire qui contiendrait :
lundi 25/10 - 06h00 - 24°C
lundi 25/10 - 08h00 - 19°C
lundi 25/10 - 17h00 - 21°C
A chaque changement d'état, on envoie la température de consigne à une adresse mémoire "consigne". Charge ensuite au sous programme "heating" lancé régulièrement de comparer "température du DS1820" à "consigne" et d'activer le chauffage selon l'écart. Est-ce OK ?

L'entrée qui a commencé le plus récemment est la bonne.

Cette façon de faire me parait plus optimale que ma proposition de x cases mémoires par 1/2 heure. En revanche, cela me parait compliqué à programmer (paramétrage et déclenchement). Je sais créer un menu balayant et renseignant les plages de 30', mais là je ne vois pas bien l'algorithme...

PS :
La fonction thermostat ne devrait pas être compliquée car gérée localement par chaque carte.
L'idée étant d'ajouter localement un clavier et un afficheur de ce type
http://cgi.ebay.fr/128X64-12864-Dot-Graphic-LCD-LCM-White-on-Blue-KS0107-/350403434348?pt=LH_DefaultDomain_0&hash=item5195ac176c
pour permettre aux utilisateurs d'ajuster le chauffage de chaque pièce.

Le pilotage de l'ensemble des esclaves par le maître sera nécessaire pour :

  • rafraichir l'heure 1 ou n fois par jour (en broadcast)
  • récupérer les courbes de température (pour afficher sur le PC)
  • récupérer les temps d'activité du chauffage (pour afficher sur le PC)
  • récupérer les courbes de températures de consignes (pour afficher sur le PC)
  • reprogrammer les consignes de chaque esclave à partir du PC.
    etc...

Je vais partir sur une actualisation de l'heure (maitre => esclaves) une ou n fois par jour (plus simple et efficace). J'ai regardé, millis() stocke en unsigned long.Dans ce cas, il me faut récupérer la valeur du DS1307 et l'écrire directement dans millis(). Donc ce registre représentera une sorte de clone du DS1307, autonome pendant 49 jours entre 2 refresh. Est-ce bien cela ?

Non, pas du tout. Tu ne peux pas changer la valeur retournée par millis(), c'est géré par l'environnement. Avant de te lancer dans une solution douteuse, va voir la librairie Time (liens dans mon message précédant). Elle fait exactement ce dont tu as besoin. Sur le maître tu fais:EnvoisDate (esclave, now());

Sur l'esclave le code correspondant est:

time_t bonnedate = RecoisDate ();
setTime (bonnedate);

J'assume ici que tu as deux fonctions magiques EnvoisDate et RecoisDate qui s'occupent du transfert des données entre maître et esclave. Plus besoin de millis() etc.

Pour trouver la bonne température, c'est en principe bien simple. Si je trouve le temps plus tard, je vais créer un petit exemple.

Korman

D'accord, je pensais que l'on pouvait forcer une valeur dans le compteur millis(), et le laisser ensuite continuer à s'incrémenter tout seul. Je vais regarder Time de plus près.

Effectivement, je pars bien sur fonctions EnvoiDate et RecoisDate mais sans milli() je ne vois pas ou récupérer l'heure et surtout comment la faire "vivre" sur l'esclave jusqu'à la prochaine synchro. Pas encore assez clair...

Pas de soucis pour ton exemple de température lorsque tu trouveras un moment.

Merci Korman.

@+

Va voir la librairie Time et la fonction setTime. Elle résolve exactement ce problème.

Korman