Pages: [1] 2   Go Down
Author Topic: Aide pour temporisation  (Read 660 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour a tous,

alors voila, je vous explique mon probleme : je souhaite creer une sorte d'automate pour mon aquarium recifal qui le permetterais de :

- creer un mode nourissage (qui couperait mon brassage pendant 10 minutes a l'appui sur un BP)
- creer un mode pour couper l'ecumeur pendant un temps prédéfini (pour l'ajout de produits dans le bac)

j'ai realiser plusieurs essais, mais c'est avec la temporisation que j'ai un probleme. En effet, j'utilise "delay" (ayant commencer le programmation arduino il n'y a vraiment pas tres longtemps), mais si mon ecumeur est deja coupé, je ne peut pas couper mon brassage.

Dans un premier temps, juste 2 LED RGD et 2 BP suffiront pour la partie hardware, en plus, bien sur, des relais, pour l'ecran tactile, on vera dans quelques années (pas encore les connaissance necessaire pour lol).

voila, si quelqu'un pouvait m'aider pour mon probleme de tempo.

cordialement
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 164
Alarme domestique sans fil : http://forum.arduino.cc/index.php?topic=239679.0
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

La solution : la fonction millis() !!!
Elle permet de temporise sans bloquer le programme.
C'est une horloge interne qui représente les millisecondes écoulés depuis le lancement du micro contrôleur
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

la fonction millis n'est pas limitée a 50 jours ?

je vais essayer d'ecrire un programme en remplacant delay par millis, et te tiens au courant.

Merci beaucoup (et desole si ma question est un peu "bebete", mais comme je l'ai dit, je debute lol)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

je comprend pas bien comment utilisé millis, j'ai regarder sur google, mais on trouve tout un tas de chose differente.

Aurait-tu un exemple concret pour resoudre mon probleme stp

en te remerciant d'avance
Logged

IDF/SO
Offline Offline
Edison Member
*
Karma: 41
Posts: 2306
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

la fonction millis n'est pas limitée a 50 jours ?
La fonction milli() telle que conçue par l'équipe arduino oui mais la tienne non .  smiley-mr-green

La fonction milli utilise le timer 0 qui est prépositionné avec un pré-diviseur de 64 par la fonction init() qui s'exécute en tâche de fond sans que tu t'en aperçoive au début du programme.
Mais rien n'empèche de modifier les préréglages dans la suite du programme.  Tu peux choisir un pré-scaler de 256 ou 1024, cf datasheet ATMega328p pages 109 et 110.
Il suffit de modifier la valeur des bits  CS02, CS01, CS00 dans le registre TCCR0B.
Attention cette modification aura des conséquences sur la fréquence de la PWM et la valeur de delay().
On peut aussi s'inspirer du code de la fonction millis() pour écrire sa propre fonction qui utiliserait les timer1 ou 2 et éviterait les inconvénients précédents.
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 147
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
...
  readKbd();
  timeTch4=millis(); //capture la valeur de millis

  while (tch4){  // tant qu'on appui sur la touche 4
    if (millis()<timeTch4+1000) {
      Serial.println("appui court touche 4");
    }
    if (millis()>timeTch4+1000) {
      Serial.println("appui long touche 4");  
    }
    readKbd();
  }
...
Logged

France
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3634
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

je comprend pas bien comment utilisé millis, j'ai regarder sur google, mais on trouve tout un tas de chose differente.

Aurait-tu un exemple concret pour resoudre mon probleme stp

en te remerciant d'avance
Dans les exemples chargés avec l'IDE il y a le programme BlinkWithoutDelay. C'est un bon exemple de gestion de délai utilisant millis() à la place de delay().
Logged

Ales
Online Online
Faraday Member
**
Karma: 39
Posts: 3829
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://battomicro.wordpress.com/2013/06/07/tutorial-les-interruptions-temporelles-avec-arduino/
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

mouais........ sa complique pas mal les choses se truc la, je comprend rien lol

je vais reecrire mon code en utilisant delay d'abord, et je verais pour modifier avec milliis par la suite.
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 164
Alarme domestique sans fil : http://forum.arduino.cc/index.php?topic=239679.0
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sans vouloir te paraître vexant, si tu trouves que millis est compliqué c'est que tu n'as pas du comprendre son utilité .

Millis te permet de maîtriser le temps dans une boucle d'un programme tout en continuant a exécuter d'autre tâche. Contrairement au delay qui ne permet d'exécuter aucun code.

Donc tu enregistres ton temps dans une variable en unsigned long puis dans ta boucle principale tu tests cette variable + ta tempo dans un if.
Comme ça tu déclenches ce que tu veux dans ton if sans bloque le reste des actions.
Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 167
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bon alors :

millis() est une fonction qui retourne le nombre de millisecondes écoulées depuis le démarrage de l'arduino.

La valeur retournée est de type unsigned long int : c'est un nombre entier positif codé sur 32 bits.
Sa plage de valeurs va de 0 à 2^32-1, soit de 0 à 4 294 967 295

La valeur maxi est donc atteinte au bout de 4 294 967 295 millisecondes après le démarrage de l'arduino, soit 49 jours, 17 heures, 2 minutes, 47 secondes et 295 millisecondes.

Là, il se produit un roll over, c'est-à-dire que la valeur repasse à zéro, puis continue à s'incrémenter.

Il y a un moyen très simple d'éviter tout problème lié à ce phénomène de roll over.
Il suffit de ne pas utiliser telle quelle la valeur retournée par millis(), mais de raisonner uniquement sur la différence entre deux valeurs retournées par millis(), c'est-à-dire sur le délai écoulé entre les deux appels.

par exemple :

Code:
unsigned long int delai, topchrono;
...
//debut de periode de mesure
   topchrono = millis();
...
//vérification d'expiration du délai à intervalles réguliers
  delai = millis() - topchrono;
  if (delai > mon_delai_souhaite)
  {
    youpi_je_traite();
    //puis l'une ou l'autre des réinitialisations ci-dessous
    top_chrono = millis(); //pour un redéclenchement dans mon_delai_souhaite
    top_chrono += mon_delai_souhaite; //pour un redéclenchement à intervalles plus précis
  }

L'astuce réside dans le fait que l'opération de soustraction est insensible au roll over.

Ainsi, delai = millis() - topchrono donnera toujours un résultat correct, même si un roll over intervient dans la période d'attente.
Au moment du calcul, millis() aura alors une valeur très petite, et topchrono aura une valeur très grande.
D'un point de vue mathématique, le résultat de la soustraction devrait avoir une valeur négative.
Mais nous sommes dans le monde informatique, avec des entiers ayant une plage de valeurs limitée, et des opérateurs qui tronquent les résultats, ce qui donne au final des valorisations en boucles.
Ainsi par exemples :
4 294 967 295 + 1 = 0
2 - 4 294 967 295 = 3
Et tant pis pour les maths
« Last Edit: August 19, 2014, 04:20:19 am by bricoleau » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Si sin j'ai compris l'utilité de millis, mais je ne comprend pas bien comment le codé

Tenez, je vous met le code comme je l'aurais fais avec delay

Code:
const int APPUI=LOW;
const int bp_ecumeur=2;
const int bp_nourissage=3;
const int relais_ecumeur=4;
const int relais_brassage=5;
const int relais_pompe=6;

const int Vert_ecumeur=7;
const int Rouge_ecumeur=8;

const int Vert_nourissage=9;
const int Rouge_nourissage=10;

void setup() {
 
  pinMode (bp_ecumeur, INPUT);
  pinMode (bp_nourissage, INPUT);
  pinMode (relais_ecumeur, OUTPUT);
  pinMode (relais_brassage, OUTPUT);
  pinMode (relais_pompe, OUTPUT);
 
  pinMode (Vert_ecumeur, INPUT);
  pinMode (Rouge_ecumeur, INPUT);
  pinMode (Vert_nourissage, INPUT);
  pinMode (Rouge_nourissage, INPUT);
 
  digitalWrite (bp_ecumeur, HIGH);
  digitalWrite (bp_nourissage, HIGH);
  digitalWrite (relais_ecumeur, LOW);
  digitalWrite (relais_brassage, LOW);
  digitalWrite (relais_pompe, LOW);
 
}

void loop () {
 
  if (digitalRead(bp_ecumeur)==APPUI) {
   
    digitalWrite (relais_ecumeur, HIGH);
    digitalWrite (Vert_ecumeur, LOW);
    digitalWrite (Rouge_ecumeur, HIGH);
    delay(21600000);
    digitalWrite (relais_ecumeur, LOW);
    digitalWrite (Vert_ecumeur, HIGH);
    digitalWrite (Rouge_ecumeur, LOW);
   
  }
 
  if (digitalRead(bp_nourissage)==APPUI) {
   
    digitalWrite (relais_brassage, HIGH);
    digitalWrite (relais_pompe, HIGH);
    digitalWrite (Vert_nourissage, LOW);
    digitalWrite (Rouge_nourissage, HIGH);
    delay(600000);
    digitalWrite (relais_brassage, LOW);
    digitalWrite (relais_pompe, LOW);
    digitalWrite (Vert_nourissage, HIGH);
    digitalWrite (Rouge_nourissage, LOW);
   
  }
 
}
 
 
   
 

si quelqu'un peut m'expliquer comment le modifier (en etant aider, je comprendrais peut etre mieux pour la prochaine fois

En vous remerciant d'avance
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 164
Alarme domestique sans fil : http://forum.arduino.cc/index.php?topic=239679.0
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Delay 21600000

21 600 secondes d'arrêt 0_o !!!
Logged

Offline Offline
Sr. Member
****
Karma: 7
Posts: 266
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour

J'ai fait ça sur un coin de table. À tester.

Code:
const int APPUI=LOW;
// Entrées boutons
const int bp_ecumeur=2;
const int bp_nourrissage=3;

// Sorties relais
const int relais_ecumeur=4;
const int relais_brassage=5;
const int relais_pompe=6;

// Sorties voyants écumeur
const int Vert_ecumeur=7;
const int Rouge_ecumeur=8;

// Sorties voyants nourrissage
const int Vert_nourrissage=9;
const int Rouge_nourrissage=10;

// Temporisations - maximum = 49j 17h 2mn 47s 295ms
const unsigned long tempo_ecumeur     = 21600000L; // 6h
const unsigned long tempo_nourrissage =   600000L; // 10mn

int ecumeur_en_route, brassage_en_route;
unsigned long heure, heure_arret_ecumeur, heure_arret_brassage;

void setup()
{
  pinMode(bp_ecumeur, INPUT_PULLUP);
  pinMode(bp_nourrissage, INPUT_PULLUP);

  pinMode(relais_ecumeur, OUTPUT);
  pinMode(relais_brassage, OUTPUT);
  pinMode(relais_pompe, OUTPUT);
 
  pinMode(Vert_ecumeur, OUTPUT);
  pinMode(Rouge_ecumeur, OUTPUT);
  pinMode(Vert_nourrissage, OUTPUT);
  pinMode(Rouge_nourrissage, OUTPUT);
 
  ecumeur_ON();
  brassage_ON();
}

void loop()
{
  heure = millis();

  if( ecumeur_en_route ) {
    if( digitalRead(bp_ecumeur) == APPUI ) {
      heure_arret_ecumeur = heure;
      ecumeur_OFF();
    }
  } else
  if ( (heure - heure_arret_ecumeur) >= tempo_ecumeur )
    ecumeur_ON();
 
  if( brassage_en_route ) {
    if( digitalRead(bp_nourrissage) == APPUI ) {
      heure_arret_brassage = heure;
      brassage_OFF();
    }
  } else
  if ( (heure - heure_arret_brassage) >= tempo_nourrissage )
    brassage_ON();

  delay(10);
}
 
void ecumeur_ON()
{
  ecumeur_en_route = 1;
  digitalWrite(relais_ecumeur, LOW);
  digitalWrite(Vert_ecumeur, HIGH);
  digitalWrite(Rouge_ecumeur, LOW);
}

void ecumeur_OFF()
{
  ecumeur_en_route = 0;
  digitalWrite(relais_ecumeur, HIGH);
  digitalWrite(Vert_ecumeur, LOW);
  digitalWrite(Rouge_ecumeur, HIGH);
}

void brassage_ON()
{
  brassage_en_route = 1;
  digitalWrite(relais_brassage, LOW);
  digitalWrite(relais_pompe, LOW);
  digitalWrite(Vert_nourrissage, HIGH);
  digitalWrite(Rouge_nourrissage, LOW);
}

void brassage_OFF()
{
  brassage_en_route = 0;
  digitalWrite(relais_brassage, HIGH);
  digitalWrite(relais_pompe, HIGH);
  digitalWrite(Vert_nourrissage, LOW);
  digitalWrite(Rouge_nourrissage, HIGH);
}

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

et oui, 6h d'arret de l'ecumeur apres l'ajout de suppléments (afin d'eviter que l'ecumeur n'elimine les complements avant que les coraux est pu en profiter)

ok, je comprend un peu mieux, et je n'aurais jamais penser faire sa comme sa, je vais etudier sa de pres, faire un test, et je te tiens au courant.

En tout cas, merci beaucoup pour votre aide
Logged

Pages: [1] 2   Go Up
Jump to: