Problème de test dans Sous programme ouvrir_porte() et fermer_porte()

Bonjour à vous, les spécialistes et les bénévoles qui passés un peu de temps à dépanner les faibles...

Je me suis lancé, non sans mal, dans mon 1er projet Arduino, aucun mérite puisque j'ai recopié un projet existant mais j'ai un petit bug. voici le lien vers la source et d'autres explications : Arduino et Porte automatique de poulailler | Oui Are Makers
Je vous ai mis le prog en PJ, le menu et le câblage...

Le système est simple et à pour but d'automatiser l'ouverture et la fermeture d'une porte (celle du poulailler) il y a un moteur, 2 capteurs fin de course, 1 cellule photo, 1 horloge et quelques options (cf prog)

Le menu fonctionne bien et il y a une gestion forcée des mouvements bien pratique pour la mise au point, donc quand j'appuis sur flèche haut, la porte s'ouvre jusqu'au moment où le capteur haut est activé et le moteur s'arrête...idem fleche bas, fermeture, capteur bas -> arrêt tout est nickel !

Tout bascule quand je souhaite programmer des heures d'ouverture et de fermeture et que le laisse le mode automatique se faire, le temps passe et à l'heure H c'est parti sauf que dans ce cas le moteur ne s'arrête pas, j'ai bien l'info du capteur mais le moteur continue sans cesse ! C'est la cata et je ne comprend pas pourquoi donc il y a une erreur dans le code mais je sèche...

Pouvez vous m'aider à trouver cette fichue erreur ?
Je me demande si ma fonction millis() est bien initialisée ? d'après ce que j'ai trouvé dans la fonction millis() tombé dans le panneau du dépassement et comme j’additionne timeout_porte qui vaut 15 je peux créer un dépassement dans timeout...

Merci d'avance

voici la partie de code qui me pose problème

void fermer_porte()
{
  unsigned long timeout = millis() + (timeout_porte * 1000);
  //long timeoutcapthaut = millis() + 2000;
  while ((millis() < timeout) && (digitalRead(capteur_bas) == false))
  {
    /*//vérifie si la porte commence bien à descendre
    if ((millis() > timeoutcapthaut) && digitalRead(capteur_haut))
    {
      timeout = 1000;
    }*/
    
    DateTime now = rtc.now();
    lcd.setCursor(7,1);
    if ((now.second() % 2) == 0){
      lcd.write(byte(1));
    }
    else{
      lcd.write(" ");
    }
    digitalWrite(enable, HIGH);
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
  }
  /*digitalWrite(in1, HIGH);  //freine et bloque l'inertie du moteur
  digitalWrite(in2, LOW);
  sleep(250);*/
  digitalWrite(in2, LOW);
  digitalWrite(in1, LOW);
  delay(250);
  digitalWrite(enable, LOW);
  
  if (digitalRead(capteur_bas) == false){
    erreur = true;
  }
}

void ouvrir_porte()
{
  unsigned long timeout = millis() + (timeout_porte * 1000);
  //long timeoutcaptbas = millis() + 2000;
  while ((millis() < timeout) && (digitalRead(capteur_haut) == false))
  {
    /*//vérifie si la porte commence bien à monter
    if ((millis() > timeoutcaptbas) && digitalRead(capteur_bas))
    {
      timeout = 1000;
    }*/
    
    DateTime now = rtc.now();
    lcd.setCursor(7,1);
    if ((now.second() % 2) == 0){
      lcd.write(byte(0));
    }
    else{
      lcd.write(" ");
    }
    digitalWrite(enable, HIGH);
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
  }
  /*digitalWrite(in2, HIGH);  //freine et bloque l'inertie du moteur
  digitalWrite(in1, LOW);
  sleep(250);*/
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  delay(250);
  digitalWrite(enable, LOW);
  
  if (digitalRead(capteur_haut) == false){
    erreur = true;
  }
}

poulailler.ino (19.5 KB)

menu.h (688 Bytes)

calculEphemeride.h (1.06 KB)

Bonjour

pour augmenter les chances de réponses :

-mettre un titre ciblant le problème, les titres banailsés 'd'appel à l'aide' ... ça lasse...
-penser que ceratins aidants, et pas des moindres... consultent souvent le forum avec leur smartphone : ils n'auront pas accès aux fichiers joints

Change ton titre et mets en un en rapport avec ta question.

Si ce n'est pas fait au prochain message >>> poubelle

Bonjour,

Les balises de code c'est [code] (sans espace) et non [ Code]

Ok.... on peut continuer :smiley:

Bonsoir, j ai parcouru ton code vite fait mais deja tes variables timeoutcapthaut et timeoutcaptbas sont en commentaires par le //

J'ai du mal à comprendre pourquoi au début de la fonction fermer_porte() on a

if ((millis() > timeoutcapthaut) && digitalRead(capteur_haut))
    {
      timeout = 1000;
    }

le timeout perd sa référence de temps.

CelticLord:
Bonsoir, j ai parcouru ton code vite fait mais deja tes variables timeoutcapthaut et timeoutcaptbas sont en commentaires par le //

c'est une option de sécurisation et dans ce cas tu lances le moteur et tu verifies que tu échappes le capteur dans les 2s. Je ne souhaite pas l'activer pour l'instant d'où les //

esp12:
J'ai du mal à comprendre pourquoi au début de la fonction fermer_porte() on a

if ((millis() > timeoutcapthaut) && digitalRead(capteur_haut))

{
     timeout = 1000;
   }





le timeout perd sa référence de temps.

c'est du commentaire de l'option de sécurisation perte de capteur après 2s de démarrage, ce n'est pas actif mais en commentaire

Bonjour,

Je parcourais ce sujet, dans le lien :

il y a le calculEphemeride.cpp :

#include "calculEphemeride.h"

void calculEphemeride::calculerCentreEtVariation(double longitude_ouest, double sinlat, double coslat, double d, double *centre, double *variation)
{
  //constantes précalculées par le compilateur
  const double M_2PI = 2.0 * M_PI;
  const double degres = 180.0 / M_PI;
  const double radians = M_PI / 180.0;
  const double radians2 = M_PI / 90.0;
  const double m0 = 357.5291;
  const double m1 = 0.98560028;
  const double l0 = 280.4665;
  const double l1 = 0.98564736;
  const double c0 = 0.01671;
  const double c1 = degres * (2.0*c0 - c0*c0*c0/4.0);
  const double c2 = degres * c0*c0 * 5.0 / 4.0;
  const double c3 = degres * c0*c0*c0 * 13.0 / 12.0;
  const double r1 = 0.207447644182976; // = tan(23.43929 / 180.0 * M_PI / 2.0)
  const double r2 = r1*r1;
  const double d0 = 0.397777138139599; // = sin(23.43929 / 180.0 * M_PI)
  const double o0 = -0.0106463073113138; // = sin(-36.6 / 60.0 * M_PI / 180.0)

  double M,C,L,R,dec,omega,x;

  //deux ou trois petites formules de calcul
  M = radians * fmod(m0 + m1 * d, 360.0);
  C = c1*sin(M) + c2*sin(2.0*M) + c3*sin(3.0*M);
  L = fmod(l0 + l1 * d + C, 360.0);
  x = radians2 * L;
  R = -degres * atan((r2*sin(x))/(1+r2*cos(x)));
  *centre = (C + R + longitude_ouest)/360.0;

  dec = asin(d0*sin(radians*L));
  omega = (o0 - sin(dec)*sinlat)/(cos(dec)*coslat);
  if ((omega > -1.0) && (omega < 1.0))
    *variation = acos(omega) / M_2PI;
  else
    *variation = 0.0;
}

void calculEphemeride::afficherDate(int jour, int mois, int annee)
{
  char texte[20];
  sprintf(texte, "%02d/%02d/%04d", jour, mois, annee);
  afficherTexte(texte);
}

void calculEphemeride::afficherCoordonnee(int degre, int minute, int seconde, char c)
{
  char texte[20];
  if (degre < 0)
  {
    degre = -degre;
    if (c == 'W') c = 'E';
    if (c == 'N') c = 'S';
  }
  sprintf(texte,"%dd%d'%d''%c", degre, minute, seconde, c);
  afficherTexte(texte);
}

void calculEphemeride::afficherHeure(double d)
{
  int h,m,s;
  char texte[20];

  d = d + 0.5;

  if (d < 0.0)
  {
    afficherTexte("(J-1)");
    d = d + 1.0;
  }
  else
  {
    if (d > 1.0)
    {
      afficherTexte("(J+1)");
      d = d - 1.0;
    }
    else
    {
      afficherTexte("     ");
    }
  }

  h = d * 24.0;
  d = d - (double) h / 24.0;
  m = d * 1440.0;
  d = d - (double) m / 1440.0;
  s = d * 86400.0 + 0.5;

  sprintf(texte,"%02d:%02d:%02d",h,m,s);
  afficherTexte(texte);
}

float calculEphemeride::convertHeure(double d)
{
  int h,m;
  
  d = d + 0.5;

  if (d < 0.0)
  {
    d = d + 1.0;
  }
  else
  {
    if (d > 1.0)
    {
      d = d - 1.0;
    }
  }

  h = d * 24.0;
  d = d - (double) h / 24.0;
  m = d * 1440.0;
  d = d - (double) m / 1440.0;
  
  float valeur = h + (m * 0.01);
  return valeur;
}

double calculEphemeride::calculerCoordonneeDecimale(int degre, int minute, int seconde)
{
  if (degre > 0)
  {
    return (double) degre + minute / 60.0 + seconde / 3600.0;
  }
  else
  {
    return (double) degre - minute / 60.0 - seconde / 3600.0;
  }
}

void calculEphemeride::avancerDate(int *jour, int *mois, int *annee)
{
  (*jour)++;
  if ((*jour>31)
  || ((*jour==31) && (*mois==2 || *mois==4 || *mois==6 || *mois==9 || *mois==11))
  || ((*jour==30) && (*mois==2))
  || ((*jour==29) && (*mois==2) && (((*annee)&3) != 0)))
  {
    *jour = 1;
    (*mois)++;
    if (*mois > 12)
    {
      *mois = 1;
      (*annee)++;
    }
  }
}

calculEphemeride::calculEphemeride(int longitude_ouest_degres, int longitude_ouest_minutes, int longitude_ouest_secondes, int latitude_nord_degres, int latitude_nord_minutes, int latitude_nord_secondes)
{
  longitude_ouest = calculerCoordonneeDecimale(longitude_ouest_degres, longitude_ouest_minutes, longitude_ouest_secondes);
  latitude_nord = calculerCoordonneeDecimale(latitude_nord_degres, latitude_nord_minutes, latitude_nord_secondes);
}

float calculEphemeride::leverSoleil(int jour, int mois, int annee, bool UTC)
{
  int nbjours;
  const double radians = M_PI / 180.0;
  double d, x, sinlat, coslat, meridien, lever;

  //calcul nb jours écoulés depuis le 01/01/2000
  if (annee > 2000) annee -= 2000;
  nbjours = (annee*365) + ((annee+3)>>2) + jour - 1;
  switch (mois)
  {
    case  2 : nbjours +=  31; break;
    case  3 : nbjours +=  59; break;
    case  4 : nbjours +=  90; break;
    case  5 : nbjours += 120; break;
    case  6 : nbjours += 151; break;
    case  7 : nbjours += 181; break;
    case  8 : nbjours += 212; break;
    case  9 : nbjours += 243; break;
    case 10 : nbjours += 273; break;
    case 11 : nbjours += 304; break;
    case 12 : nbjours += 334; break;
  }
  if ((mois > 2) && (annee&3 == 0)) nbjours++;
  d = nbjours;

  //calcul initial meridien & lever & coucher
  x = radians * latitude_nord;
  sinlat = sin(x);
  coslat = cos(x);
  calculerCentreEtVariation(longitude_ouest, sinlat, coslat, d + longitude_ouest/360.0, &meridien, &x);
  lever = meridien - x;
  
  //seconde itération pour une meilleure précision de calcul du lever
  calculerCentreEtVariation(longitude_ouest, sinlat, coslat, d + lever, &lever, &x);
  lever = lever - x;

  float val = convertHeure(lever);
  /*
  if (!UTC)
	{
		 if ((mois == 3) && (jour > 24) && (((jour - now.dayOfWeek()) > 24) || (now.dayOfWeek() == 7)))
		{
			 + 2);
		}
	}*/
	
  return val;
}


float calculEphemeride::coucherSoleil(int jour, int mois, int annee, bool UTC)
{
  int nbjours;
  const double radians = M_PI / 180.0;
  double d, x, sinlat, coslat, meridien, coucher;

  //calcul nb jours écoulés depuis le 01/01/2000
  if (annee > 2000) annee -= 2000;
  nbjours = (annee*365) + ((annee+3)>>2) + jour - 1;
  switch (mois)
  {
    case  2 : nbjours +=  31; break;
    case  3 : nbjours +=  59; break;
    case  4 : nbjours +=  90; break;
    case  5 : nbjours += 120; break;
    case  6 : nbjours += 151; break;
    case  7 : nbjours += 181; break;
    case  8 : nbjours += 212; break;
    case  9 : nbjours += 243; break;
    case 10 : nbjours += 273; break;
    case 11 : nbjours += 304; break;
    case 12 : nbjours += 334; break;
  }
  if ((mois > 2) && (annee&3 == 0)) nbjours++;
  d = nbjours;

  //calcul initial meridien & lever & coucher
  x = radians * latitude_nord;
  sinlat = sin(x);
  coslat = cos(x);
  calculerCentreEtVariation(longitude_ouest, sinlat, coslat, d + longitude_ouest/360.0, &meridien, &x);
  coucher = meridien + x;

  //seconde itération pour une meilleure précision de calcul du coucher
  calculerCentreEtVariation(longitude_ouest, sinlat, coslat, d + coucher, &coucher, &x);
  coucher = coucher + x;
  
  float val = convertHeure(coucher);
  
  return val;
}

void calculEphemeride::afficherTexte(char texte[])
{
#ifdef DEBUG_MODE
    Serial.print(texte);
#endif
}

les * en debut de ligne comme :

    *centre = (C + R + longitude_ouest)/360.0;

    *variation = acos(omega) / M_2PI;

    *variation = 0.0;

Elles font quoi ? j'ai chercher mais je trouve tjrs un rapport par rapport au */ pour commenter un paragraphe.

Du coup si qqu'un peut m'éclairé ?

Merci

Bonjour

la réponse au questionnement sur l'étoile se trouve du côté de la notion de pointeur
Chercher du côté de l'initiation au langage C
içi par exemple (mais tout moteur de recherche proposera des explications variées et multiples)

Merci al1fch.