Stylo 3D

Bonjour / Bonsoir;
Si je viens ici c'est que effectivement vous vous en doutez... j'ai besoin de votre aide. Et oui effectivement Arduino et moi ça fait... ben en fait ça fait rien du tout car on ce déteste tout les deux :stuck_out_tongue:
Je bosse sur un bout d'un projet qui consiste à allumer une LED ou bout d'un certains temps d'utilisation d'un objet. (1000h)

je vais vous donner quelques explications sur mon programme :

  • J'ai tout d'abord fait mon programme pour utiliser une RTC grove( basé sur la RTC 1307)
    => Je n'ai gardé que les informations d'heures, minutes et secondes (le reste n'étant pas utile dans mon cas.)
    => Et j'ai fais en sorte que l'heure soit en secondes (c'est plus simple pour la suite)

  • Deuxième étape, j'ai fait en sorte que le programme compte combien de temps s'écoule entre deux appuie sur le bouton.
    => Et j'ai fais en sorte que ce temps soit affichée en secondes donc pour cela j'ai réaliser mon petit calcul et le résultat porte le nom de variable "resultatfinal"
    => J'ai ajouté au temps entre deux appuis 995 s (Pour pouvoir atteindre plus rapidement 1000s, OUI je sais 1000s n'est pas égale à 1000h mais pour ne pas m'embèter avec 50 variables pour le moment j'ai fait comme cela. Donc disons la dans ce cas je veux atteindre 1000s donc environ 16min36s si je me trompe pas)

  • Ensuite troisième étape j'ai "préparé" ma donné à être stocker dans l'eeprom d'arduino" comme le max peut être 1000 secondes j'ai découpé la donné en deux morceau pour la stocker : 1) millième et centième (dans le programme variable "mc") 2) dizaine et unité centième (dans le programme variable "du" )
    => J'ai par la suite affiché toutes ces données dans le port série pour tester.

VOILA ! J'ai récapituler mon programme.
Je vous le montre :

#include <TinkerKit.h>

#include <Wire.h>
#include "DS1307.h"

double SEC;
const int buttonPin = A2;
int buttonState = 0;
double result1; 
double result2;
int comptage=0;
int resultfinal;
int resultat_mc;  // nombre partie cemtaine et millieme
int resultat_du;  // nombre partie dizaine et unite

DS1307 clock;//define a object of DS1307 class
void setup()
{
	Serial.begin(9600);
	clock.begin();
	clock.fillByYMD(2014,3,27);// 06 Fevrier,2014
	clock.fillByHMS(17,50,30);//13:53 30"
	clock.fillDayOfWeek(THU);//Jeudi
  	clock.setTime();//write time to the RTC chip
}
void loop()
{
	printTime();
        calcul_SEC();
        buttonState = digitalRead(buttonPin);
         resultat_mc=round(resultfinal/100);
  
  Serial.print("nombre de depart : ");
  Serial.println(resultfinal);
  
  Serial.print("nombre partie cemtaine et millieme : ");
  Serial.println(resultat_mc);
  
  resultat_du=(resultfinal-(100*resultat_mc));
  
  Serial.print("nombre partie dizaine et unite : ");
  Serial.println(resultat_du);

     delay(1000);

}


/*--------------------------------------------------* 
 * Fonction: Affiche le temps sur le moniteur série *
 *--------------------------------------------------*/
void printTime()
{
	clock.getTime();
        
       
        Affiche_HMS();
	Serial.println(" ");
        
        delay(500);
        
}

void Affiche_HMS()
    {
     Serial.print(clock.hour, DEC);
     Serial.print(":");
     Serial.print(clock.minute, DEC);
     Serial.print(":");
     Serial.print(clock.second, DEC); 
    }


    
 void calcul_SEC()
     {
    buttonState = digitalRead ( buttonPin ) ; 
     if (buttonState == HIGH) 
     {
       SEC= ((clock.hour)*36E2)+((clock.minute)*60)+ (clock.second);
       Serial.println(SEC);
       comptage++;
       if (comptage==1)
       {
         result1= SEC;
       }
       if (comptage==2)
       {
        result2 = SEC;
        resultfinal=(result2-result1)+1000; //// le "1000" pour les tests
        comptage=0;

       }
     
     }
     }

Maintenant je vais vous exposer mon problème :
Ce que j'ai fait ça ne comptabilise qu'un seul temps d'utilisation. J'aimerais pouvoir cumuler plusieurs temps d'utilisation (pour effectivement atteindre ces fameux 1000h) et sans y perdre lorsque j'éteint mon arduino. Pour cela je veux stocker dans l'eeprom pour cumuler. J'ai essayé de faire un bout de programme mais ce n'est pas concluant du tout...
Je vous le montre tout de mème :

if ((resultat_mc)>=10) // lit si les millieme et cemtaine on atteint "10" ==> Ce qui veut dire 1000 secondes
  {
	Serial.print("nombre d'heures atteint !!!!! ");	
delay(2000);
  }
  else
  {
	if (digitalRead(buttonPin) ==HIGH) // si utilisation
	{
    	  dueeprom=EEPROM.read(resultat_du)+1;
	  mceeprom=EEPROM.read(resultat_mc);

    	  if (dueeprom==60) // + de 60s -> +1min
 	  {
		dueeprom=0;
	        mceeprom++;
	  }
    	

		// sauvegarde
	  EEPROM.write(resultat_du,dueeprom);
	  EEPROM.write(resultat_mc, mceeprom);
	  delay(1000);       //  1 sec
}
}

Je suppose que c'est du grand n'importe quoi mais bon ^^ Merci d'avance de votre aide et de votre patience j'ai essayé au mieux d'ètre clair.

La mise à jour de l'horloge

clock.fillByYMD(2014,3,27);// 06 Fevrier,2014
clock.fillByHMS(17,50,30);//13:53 30"

ne doit être effectuée qu'une seule fois, ensuite la pile bouton intégrée prend le relais hors tension.
Là, ton code Arduino repart au 27 mars 2014 à chaque redémarrage.
Il faut commenter ces lignes avec //

Tout d'abord merci de ta réponse.
Oui oui c'est vrai mais c'est juste un programme de test comme ça ! Vous pensez que c'est ça qui fait que mon programme ne marche pas ?

Il vaut mieux écrire dans la mémoire du DS1307 que dans l'EEPROM de l'Arduino (car le nombre de cycles R/W y est limité).

Sinon, le calcul du temps de fonctionnement me semble très alambiqué.

Plus simplement, on peut s'inspirer du "blink without delay"

pour compter juste les minutes, depuis l'Arduino, et écrire en RAM le nombre de minutes écoulées chaque minute.
Pas besoin de passer par la clock Ds1307 pour ça.

Le programme que j'ai mis en premier marche parfaitement ce n'est pas le problème.

Je suis obligé d'utiliser une RTC et un EEPROM c'est imposé.
Mon problème est le suivant :

Ce que j'ai fait ça ne comptabilise qu'un seul temps d'utilisation. J'aimerais pouvoir cumuler plusieurs temps d'utilisation (pour effectivement atteindre ces fameux 1000h) et sans y perdre lorsque j'éteint mon arduino. Pour cela je veux stocker dans l'eeprom pour cumuler. J'ai essayé de faire un bout de programme mais ce n'est pas concluant du tout...
Je vous le montre tout de mème :

if ((resultat_mc)>=10) // lit si les millieme et cemtaine on atteint "10" ==> Ce qui veut dire 1000 secondes

{
Serial.print("nombre d'heures atteint !!!!! ");
delay(2000);
  }
  else
  {
if (digitalRead(buttonPin) ==HIGH) // si utilisation
{
      dueeprom=EEPROM.read(resultat_du)+1;
  mceeprom=EEPROM.read(resultat_mc);

if (dueeprom==60) // + de 60s -> +1min
  {
dueeprom=0;
        mceeprom++;
  }

	// sauvegarde
  EEPROM.write(resultat_du,dueeprom);
  EEPROM.write(resultat_mc, mceeprom);
  delay(1000);       //  1 sec

}
}




Je suppose que c'est du grand n'importe quoi mais bon ^^ Merci d'avance de votre aide et de votre patience j'ai essayé au mieux d'ètre clair.

Je tiens à préciser que oui il y a une limite d'écriture pour l'eeprom qui est 100 000 mais dans mon cas ça mettrais des années à s'épuiser.

Perso j'ai rien compris à ce que tu veux en lisant ton post.

Pour ce que tu veux faire je comprends pas il suffit de comparer le temps qui passe?

Pour info ton DS1307 a une pile de sauvegarde donc s'il s'écoule 15min tu peux le détecter sans créer un compteur indépendant.

Tu regardes quelle heure il est quand ta led s'allume et quelle heure il est quand ta led s'éteint. Par différence tu auras le temps écoulé.

Pour ce que tu veux faire je comprends pas il suffit de comparer le temps qui passe?

Pour info ton DS1307 a une pile de sauvegarde donc s'il s'écoule 15min tu peux le détecter sans créer un compteur indépendant.

Tu regardes quelle heure il est quand ta led s'allume et quelle heure il est quand ta led s'éteint. Par différence tu auras le temps écoulé.

Non mais ça il n'y a pas de problème avec ça.
En fait voila le soucis : Mon programme compte le temps, il fait la comparaison etc..
Je veux maintenant stocker les valeurs dans l'EEPROM (Oui ici, ne me dites pas de le faire ailleurs je n'ai pas le choix).
J'ai découpé le nombre de seconde (j'ai tout mis en secondes pour que ce soit plus simple) en deux. Par exemple 1003, une première partie appellé milième centième (mc) ce sera : 10 ; une seconde partie appelé dizaine et unité (du) ce sera : 03.

Voila la partie de mon programme concerné :

// sauvegarde
	  EEPROM.write(adresse_epromdu, resultat_du);
          adresse_epromdu++;
   
	  EEPROM.write(adresse_eprommc, resultat_mc);
          adresse_eprommc++;
	  delay(200); //  1 sec
          adresse_eprommc=0;
          adresse_epromdu=0;
          
          
// Lecture 

   valuedu = EEPROM.read(adresse_epromdu);
  Serial.print("nombre partie dizaine et unite sauvegarde  : ");
  Serial.println(valuedu, DEC);
  Serial.println("\t");
   

     valuemc = EEPROM.read(adresse_eprommc);
  Serial.print("nombre partie centaine et millieme sauvegarde: ");
  Serial.println(valuemc, DEC);  
  Serial.println("\t");
 
    adresse_eprommc++;
      adresse_epromdu++;
          adresse_epromdu=0;  
           adresse_eprommc=0;  
      
          
}

Le problème c'est qu'il m'affiche bien le "nombre partie centaine et millieme" la pas de soucis, mais dans la zone d'affichage "nombre partie dizaine et unite" et bien il m'affiche la valeur de la partie centaine et millième. Je n'arrive pas à comprendre... je sauvegarde peut ètre sur la mème adresse donc il réecrit dessus ? Je sais pas trop..

merci d'avance de votre aide.

Salut,

Oui tu te capote avec les adresses et je sais pas pourquoi tu les incrémentent pour ensuite les remettre à zéro ^^

mets en haut de ton programme

const int adresse_epromdu = 0;
const int adresse_eprommc = 1;

et enlève tout ça :
adresse_eprommc++;
adresse_epromdu++;
adresse_epromdu=0;
adresse_eprommc=0;

Oui je m'embrouille un peu ^^"

D'accord mais j'enlève les incrémentations et les remises à zéro de partout dans mon programme ou juste à la fin ?
Parce que je ne peux pas vraiment le tester pour le moment je n'ai pas le matériel (je ne l'aurais que jeudi en cours).

Partout, tes adresses sont fixes, c'est pour ça que tu peux les déclarer en tant que constantes une seule fois au début de ton programme.

Oui c'est vrai je n'avais pas pensé à ça... merci beaucoup.

J'ai une autre question.
En fait si tu veux ce programme est fait pour compter le temps qui va s'écouler entre deux appuies sur un bouton (Un fait c'est pour caractérisé l'utilisation d'un stylo 3D) donc on stocke en mémoire ce temps. Une fois attend 1000h une led s'allumera.

J'avais des variables seulement pour diviser le temps en deux donc pour avoir 4 chiffres sois un max de 9999 secondes soit environ 2.7 heures. Je doutes qu'une utilisation dure autant de temps mais on est jamais assez prudent ^^"
Le soucis c'est que on va devoir cumuler le temps d'utilisation pour attendre 1000h sois 3600000 secondes il me faudra donc 4 variables (donc il faut que j'en crée deux autres encore + celle déja faites) mais comment faire ce cumul... ?
Faire dans ce style la ?

	  if (sec==60) // + de 60s -> +1min
 	  {
		sec=0;
		minu++;
	  }
    	  if (minu==60) // + de 60min -> +1h
	  {
		minu=0;
		heu++;
	  }
  	  if (heu==100)  // + de 100h -> +1centaine d'heure
	  {
		heu=0;
		cen++;
	  }

Il y a d'autre nom de variable parce qu'il s'agit d'un autre programme que j'ai réalisé sur le mème principe.

La bonne question à se poser : a t 'on réellement besoin d'une précision à la seconde près quand on compte 1000h d'utilisation?

Puis même si tu en a besoin, il ne te faut que 3 adresses EEPROM pour stoquer ce chiffre puis jouer avec les masques et les décalages de bits.

Il est intessant de revenir aux bases.
Un peu de curiosité est toujours une qualité.
Regardons le code la bibliothèque EEPROM Arduino (débarrassé des commentaires pour gagner de la place) :

#include <avr/eeprom.h>
#include "Arduino.h"
#include "EEPROM.h"
uint8_t EEPROMClass::read(int address)
{
	return eeprom_read_byte((unsigned char *) address);
}

void EEPROMClass::write(int address, uint8_t value)
{
	eeprom_write_byte((unsigned char *) address, value);
}

EEPROMClass EEPROM;

Première remarque : Arduino inclu <avr/eeprom.h> qui appartient à l'avr-libc.
Quand on voit ceci la première chose à faire est d'aller consulter les fonctions de l'avr-libc.
Et on constate que la bibliothèque arduino ne fait qu'encapsuler des fonctions de l'avr-libc.
Leur seul intérêt est de dispenser l'utilisateur de l'usage d'un pointeur.

Mais il y plus fort : on se rend compte que ce n'est pas 2 fonctions d'écriture/lecture qu'Atmel met à notre disposition mais 15 !

uint8_t 	eeprom_read_byte (const uint8_t *__p) __ATTR_PURE__
uint16_t 	eeprom_read_word (const uint16_t *__p) __ATTR_PURE__
uint32_t 	eeprom_read_dword (const uint32_t *__p) __ATTR_PURE__
float 	eeprom_read_float (const float *__p) __ATTR_PURE__
void 	eeprom_read_block (void *__dst, const void *__src, size_t __n)
void 	eeprom_write_byte (uint8_t *__p, uint8_t __value)
void 	eeprom_write_word (uint16_t *__p, uint16_t __value)
void 	eeprom_write_dword (uint32_t *__p, uint32_t __value)
void 	eeprom_write_float (float *__p, float __value)
void 	eeprom_write_block (const void *__src, void *__dst, size_t __n)
void 	eeprom_update_byte (uint8_t *__p, uint8_t __value)
void 	eeprom_update_word (uint16_t *__p, uint16_t __value)
void 	eeprom_update_dword (uint32_t *__p, uint32_t __value)
void 	eeprom_update_float (float *__p, float __value)
void 	eeprom_update_block (const void *__src, void *__dst, size_t __n)

Lien général vers l'avr-libc :
http://www.nongnu.org/avr-libc/
Pour le sommaire des différentes fonctions de l'avr-libc:
http://www.nongnu.org/avr-libc/user-manual/modules.html
et vers la page du manuel en ligne traitant de l'EEPROM
http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html

En espérant que tu trouvera ton bonheur dans cette avalanche de fonctions qu'Arduino nous cache.

Tout d'abord merci beaucoup de vos réponses.
Je dois avouer que vous m'avez totalement perdu sur ce coup ... j'ai un très faible niveau sur arduino alors parlez moi comme un abrutis :stuck_out_tongue:
C'est vrai que je n'aurais pas vraiment besoin des secondes quand on y réfléchi mais mon prof y tiens...

Tu peux faire des propositions à ton prof mais si au final il maintient sa demande initiale tu fais ce qu'il veut, point barre.

Le sujet est pédagogique il n'est pas "industriel".

Le prof a certainement des idées bien précises derrière la tête et veut t'ammener à découvrir ou utiliser certaines connaissances.
C'est à toi qui le côtoie d'essayer de comprendre où il veut te diriger.
Pour une fois qu'on en trouve un qui encadre son élève on ne va pas le contrarier.

Oui on va dire ça comme cela :slight_smile:

Donc bon ben voila :
Je n'aurais jamais plus de 3h d'utilisation soit : 10800 secondes, donc il me faudra droit variable (Une dizaine et unité, Une millième et centième et une dernière dizaine de millième) pour le comptage du temps d'utilisation, inutile d'en mettre une 4ième déja 3h d'utilisation c'est très très long.
Par contre au niveau du stockage si puisque qu'on veut attendre 1000h soit 3600000 secondes.
Est-ce que ça marcherais de dire que lorsque l'on atteint 99999 secondes (environ 27,7 heures) il faut incrémenté la variable suivante pour avoir 1000000 ?
Dans ce model la (ici c'est fait avec les minutes et secondes) :

  if (sec==60) // + de 60s -> +1min
 	  {
		sec=0;
		minu++;
	  }
    	  if (minu==60) // + de 60min -> +1h
	  {
		minu=0;
		heu++;
	  }
  	  if (heu==100)  // + de 100h -> +1centaine d'heure
	  {
		heu=0;
		cen++;
	  }

Merci beaucoup de votre aide, c'est pas simple ayant le matériel que lorsque je suis en cours le jeudi et le lundi... des projets de bac à rendre très bientot donc il faut que j'avance cher moi tout de mème.

Edit : Dans l'hypothèse ou c'est bien cela qu'il faut faire, ce bout de programme ce met ou ? Après le stockage ?

SGRmetrage:
Par contre au niveau du stockage si puisque qu'on veut attendre 1000h soit 3600000 secondes.
Est-ce que ça marcherais de dire que lorsque l'on atteint 99999 secondes (environ 27,7 heures) il faut incrémenté la variable suivante pour avoir 1000000 ?

Arrivée là on se demande surtout si ce ne serait pas plus simple de gérer heures, minutes et secondes normalement.