Aller au contenu


Photo
- - - - -

course du soleil


  • Veuillez vous connecter pour répondre
224 réponses à ce sujet

#181 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 04 mars 2020 - 02:15

bonjour Sandro ,

voila j'ai compléter ton code .

Bonne journée.

[attachment=11293:sketch_mar04a.ino]



#182 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 04 mars 2020 - 03:11

Bonjour,

du coup, tu as testé? Tout marche bien?

 

Une autre petite chose : est-ce que tu pourrais essayer de faire une indentation propre, c'est à dire mettre exactement une tabulation de décalage à l'intérieur de chaque fonction (une seconde si tu entre dans un if ou une boucle, une troisième si tu entres encore dans un if ou une boucle à l'intérieur d'un premier, ...). Bref, à chaque fois que tu passe une accolade ouvrante, tu augmente le nombre de tabulations du début de chaque ligne d'une tabulation, et à chaque fois que tu ferme une accolade, tu réduit de 1 le nombre de tabulations.

Nb : désolé, sur le canevas que je t'avais donné, je ne l'avais fait que très approximativement avec des espaces, car j'avais écrit le code directement dans le forum (qui ne permet pas les tabulations) au lieu de l'écrire dans l'IDE arduino).

 

Pour le bouton rotatoire, tu ne l'utilise que pour régler l'heure, c'est bien ça?

Si ce n'est pas le cas, alors tu pourrais me dire pour quoi d'autre? (dans ce cas, pas la peine de faire la suite pour l'instant, il se peut que ce ne soit pas addapté

Si c'est le cas, alors je te propose d'écrire les 2 fonctions suivantes, dans l'ordre :

 

1) Une fonction getPushLength qui renverra 0 si le bouton n'est pas appuyé au moment où elle est appelée, et la durée entre l'appel de la fonction et la fin de l'appui si le bouton est pressé au moment de l'appel.

// La ligne qui suit doit être placée au début du code, juste après les "#include"
#define PIN_BOUTON_KNOB A0  //remplace A0 par la pin que tu utilise pour le bouton. Tu pourra utiliser digitalRead(PIN_BOUTON_KNOB) pour lire le bouton


int getPushLenght()
{
    //à compléter
    return ...//renvoyer la durée en millisecondes, ou 0 si le bouton n'était pas pressé
}

NB : aucune variable globale n'est nécessaire (le pin du bouton est passé en argument)

NB : la fonction sera bloquante (ie si initialement le bouton est pressé, elle ne terminera pas avant que le bouton soit relaché
 

Teste la fonction avant de passer à la suite (je te laisse écrire un petit code pour la tester : tu peux par exemple afficher la durée d'un appui avec Serial.print depuis loop, et vérifier si un appui de 10 secondes renvoi bien environ 10000.

 

2) Une fois la première fonction en place, tu peux ajouter une fonction qui permet de sélectionner (et renvoyer) une valeur comprise entre valeur_min et valeur_max à l'aide du bouton tournant (knob). Je suggère de mettre un troisième argument à la fonction (valeur_initiale) : de cette manière, quand on utilisera cette fonction pour régler l'heure ou le jour, on pourra commencer immédiatement à la dernière valeur enregistrée.

 

Le squelette de la fonction est :

int chooseValue(int min, int max, int initialValue)
{
  ...
  return ... //renvoi la valeur choisie
}

Tu pourra t'inspirer d'une des fonctions qui servaient à modifier la date ou l'heure.

Nb : pour l'instant, on vas n'utiliser que Serial.print, pas l'écran

Nb : la seule variable globale dont tu as besoin est le bouton (knob)

 

Bonne journée

Sandro


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#183 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 964 messages
  • Gender:Male
  • Location:Anglet

Posté 04 mars 2020 - 04:34

Petite précision pour t'aider avec l'indentation : 

Press " Ctrl + t " quand  tu es dans l'ide arduino ça indentera tout ton code automatiquement =)


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#184 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 04 mars 2020 - 05:12

rebonjour Sandro,

le bp rotary a deux fonctions :

le premier appui long = réglages( jour,mois,année,jour de la semaine,heure,minute,timezone,longitude,latitude,volume d'eau pour l'arrosage,humidité du soil moisture )

seul bémol c'est qu'il faut passer dans tout le programme successivement jusqu’à atteindre ceux que l'on veux modifier.

appui court = passe de  l'écran principal au écran secondaire (Sun,Moon,turntable,arrosage)

Bonne soirée .



#185 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 964 messages
  • Gender:Male
  • Location:Anglet

Posté 05 mars 2020 - 04:43

Michel, afin de te montrer pourquoi on te demande de faire des fonctions, voici un exemple de code qui permet de calculer le PWM de ta led en fonction des heures courantes de levé et de coucher. Il est facile de tester cette fonction pour vérifier qu'elle marche correctement en essayant différents paramètres. D'ailleurs je te laisse le soin de la tester.
Telle que rédigée cette fonction marche aussi bien pour le soleil que pour la lune .
Cette fonction sera appelé par des fonction de type setPwmLune et setPwmSoleil ... 
J'ai fais un exemple de setPwmLune mais elle comme tu pourra le constater elle est à modifier : pour la fonction plus propre il faudra faire une fonction " getRiseTimeLune() et getSetTimeLune() " sur le même modèle que getCurrentTime() ... 
 

// Fonction qui calcule le PWM à mettre en fonction du temps courant, de l'heure de levé et de l'heure de couché
// Les heures doivent être fournies en minutes sur 24h => comprises entre 0 et 24 * 60 

#define PINPWMLUNE 8

// fonction de calcul de PWM pour la lune et pour le soleil 

int calculPwm( int currentTime, int riseTime, int setTime ) {  
  
  int pwm = 0;

  // gestion du cas où le levé est plus tard que le couché comme pour la lune on décale de 24h pour faciliter les calculs
  if( riseTime > setTime) 
    setTime += 24 * 60; // ajout de 24h...
  if( currentTime < riseTime )
    currentTime += 24 * 60; // ajout de 24h ... 
  // fin de la gestion

  int midi = (riseTime + setTime) / 2;
  
  // phase montante
  if(currentTime > riseTime && currentTime < midi) {
    pwm = map( currentTime, riseTime, midi, 0, 255); 
  }

  // phase décendante 
  if(currentTime > midi && currentTime < setTime) {
    pwm = map( currentTime, midi, setTime, 255, 0); 
  }

  return pwm;

}

int getCurrentTime() {
  return getHeureCourante() * 60 + getMinuteCourante();
}

void setPwmLune() {

  int currentTime = getCurrentTime();  
  int riseTime = Rise_time[0] * 60 + Rise_time[1]; // Attention variables globales à modifier avec des fonctions...
  int setTime = Set_time[0]*60 + Set_time[1]; // Attention variables globales ...
  int pwmLune = calculPwm( currentTime, riseTime, setTime ); 
  analogWrite(PINPWMLUNE, pwmLune);

}

Est ce qu'avec cet exemple c'est plus clair pour toi ? Et est ce que tu es complètement d'accord avec le fait que faire des fonctions comme cela va te faciliter la vie pour coder ton projet ? 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#186 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 05 mars 2020 - 02:45

Bonjour,

@ Michel (#184): du coup, vu les utilisations que tu comptes en faire, c'est bon, tu peux implémenter les deux fonctions dont je te parlais dans le #182

 

@Mike (#185) : je crois que tu as fait une petite erreure : il faut remplacer tous les "minuitLunaire" par "midi" (qui désigne soit le midi solaire, soit le "midi lunaire" (ie le moment où la lune est au plus haut). J'ai aussi un doute de ce qui se passe à 2h du matin pour la lune avec ton ajout des 24h au setTime (car currentTime ne dépasse pas 24*60)


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#187 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 05 mars 2020 - 03:09

bonjour Sandro et Mike 118 ;

j'ai une erreur de compilation avec arduino

# 185

int pwmLune = calculPwm( currentTime, riseTime, setTime );// void value not ignored as it ought to be

d'avance merci .



#188 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 05 mars 2020 - 04:28

sandro ,

je ne sais pas si cela peu marcher

int setFuseau() {
int Min = 0;
int Max = 100;
int initialValue = 0;

  pushlength = pushlengthset;
  pushlength = getpushlength ();
  if (pushlength != pushlengthset) {
    return setFuseautemp;
  }
  knob.write(0);
  delay (50);
  knobval = knob.read();
  if (knobval < Min) { //bit of software de-bounce
    knobval = Min;
    delay (50);
  }
  if (knobval > Max) {
    knobval = Max;
    delay (50);
  }
  if (knobval=initialValue){
    knobval = initialValue;
    delay (50);
  }
  setFuseautemp = setFuseautemp+ knobval;
  if (setFuseautemp < 1) {/*0*/
    setFuseautemp = 0;
  }
  if (setFuseautemp > 2) {/*3*/
    setFuseautemp = 3;
  }
  itoa(setFuseautemp, tmp_string, 10);
  EEPROM.update(4,setFuseautemp);//SystemLimens.setFuseau_Limen
  u8g.firstPage();
  do {
    u8g.setFont(u8g_font_6x10);
    u8g.drawStr( 0, 20, "Set Timezone");
    u8g.drawStr(35, 40, tmp_string);
  } while ( u8g.nextPage() );
  setFuseau();
}
 
 


#189 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 05 mars 2020 - 04:30

Bonjour,

remplace

void calculPwm( int currentTime, int riseTime, int setTime ) {  

par

int calculPwm( int currentTime, int riseTime, int setTime ) {  

 


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#190 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 05 mars 2020 - 04:34

Pour le #188, je ne sais pas si ça marche ou pas, mais ce n'est clairement pas bon dans le cadre de re-écrire un code propre sans variables globales qui ne sont pas strictement superflues et sans répéter de bouts de code.

Avant de pouvoir écrire setFuseau, il faut que tu écrives les fonctions getPushLenght et chooseValue du post #182 : elles permettront ensuite d'écrire une fonction setFuseau beaucoup plus propre.


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#191 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 05 mars 2020 - 05:18

Sandro il n'y a plus d'erreur mais cela ne fonctionne pas .



#192 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 05 mars 2020 - 06:22

:diablo: Combien de fois je dois encore te dire :

1) "ça ne marche pas" ou "ça ne fonctionne pas" ne m'apporte aucune information : tu as testé quel code, qu'est-ce qui précisément ne marche pas (qu'est-ce qui se passe? qu'est-ce que tu t'attends qu'il se passe mais qui ne se passe pas? Qu'est-ce qui se passe différemment de ce à quoi tu t'attendais?)

2) tu ne donne pas le code que tu teste

 

 

Du coup, en l'absence de ces infos, je ne peux que jouer aux devinettes, ce qui est une grosse perte de temps.


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#193 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 05 mars 2020 - 06:28

#185 ne fonctionne pas rien en sortie sur analogWrite(PINPWMLUNE, pwmLune);

par contre ton code pour le bouton je sèche désolé .

bonne soirée .



#194 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 05 mars 2020 - 06:38

Tu le fais exprès ou quoi?

Je te demande de me donner le code que tu teste. Tu ne teste certainement pas le code du #185 tel quel, car tu y a (normalement) remplacé un "void" par "int". Mais même une fois cette modif faite, je ne pense pas que tu le teste tel quel, car il n'y a ni setup, ni loop, et que de toute façon, Rise_time et SetTime n'étant pas définis, tel quel tu ne peux qu'obtenir une erreur de compilation (que tu ne semble pas avoir).

 

Pour le code du bouton (getPushLenth), voici un pseudo code, je te laisse le transformer en vrai code

Si bouton pas appuyé : renvoyer 0
Si bouton appuyé :
  prendre temps initial
  tant que le bouton est appuyé : faire rien
  prendre temps final
  renvoyer temps final - temps initial

 


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#195 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 964 messages
  • Gender:Male
  • Location:Anglet

Posté 05 mars 2020 - 07:00

 

 

@Mike (#185) : je crois que tu as fait une petite erreure : il faut remplacer tous les "minuitLunaire" par "midi" (qui désigne soit le midi solaire, soit le "midi lunaire" (ie le moment où la lune est au plus haut). J'ai aussi un doute de ce qui se passe à 2h du matin pour la lune avec ton ajout des 24h au setTime (car currentTime ne dépasse pas 24*60)

 

En effet j'avais laissé 3 fautes de frappe dans le code fournit ...  minuitLunaire au lieu de midi,  int au lieu de void + oubli de la l'ajout des 24h quant current est inférieur à riseTime ... 

J'ai corrigé dans #185 ... 

 

 

@Michel pour tester le code fournit tu peux faire dans ton loop un truc du genre 

for(int i = 0; i < 24 * 60; i ++ ) {
  int pwm = calculPwm( i, 360, 1200);  // riseTime à 6h du matin setTime à 20h et le temps file en accéléré ...
  analogWrite(PINPWMLUNE, pwm);
  delay(100);                           // 100 ms => 1min  
}

en ayant ajouté les fonctions que j'ai fournie en #185 ( qui maintenant sont corrigées ) aux code que tu as fais en #181. 

Après j'avais pas testé le but était de montrer un exemple avec l'usage des fonctions ...


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#196 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 06 mars 2020 - 02:34

bonjour Mike 118

voila j'ai tester ton programme sans currentime .

je l'ai mis dans mon code existant je te met le code pour que tu vois ce qui cloche et si je n'ai rien oublier d'avance merci .

#define PINPWMLUNE 8
int moonriseHour, moonriseMin, moonsetHour, moonsetMin;
int valeur_Moon = 0;
String nfm = ""; // days to next full moon
float F_TIMEZONE = 0 ; /* UTC france = +1 Hiver + 2 ete */
int TIMEZONE ;
int TimeMins; // number of seconds since midnight
int LATITUDE ,LATITUDE_1, LONGITUDE,LONGITUDE_1, Long,Lat ;
#include "RTClib.h"
RTC_DS1307 RTC;

/* Moon Calcul */

static float Dec[3] = { 0.0, 0.0, 0.0 };
static float RAn[3] = { 0.0, 0.0, 0.0 };
static float VHz[3] = { 0.0, 0.0, 0.0 };
static float Sky[3] = { 0.0, 0.0, 0.0 };
const static float DR = M_PI / 180;

static int Rise_time[2] = {0.0, 0.0};
static int Set_time[2] = {0.0, 0.0};

static bool Moonrise, Moonset;

/* returns value for sign of argument*/
float sgn(float x)
{
    float rv;
    if (x > 0.0)
  rv = 1;
    else if (x < 0.0)
  rv = -1;
    else
  rv = 0;
    return rv;
}

/* determine Julian day from calendar date (Jean Meeus, "Astronomical Algorithms", Willmann-Bell, 1991)*/

float julian_day(const int day_const, const int month_const,
      const int year_const)
{
    float a, b, jd;
    bool gregorian;

    int month = month_const;
    int day = day_const;
    float year = (float) year_const;

    gregorian = (year < 1583) ? 0 : 1;

    if ((month == 1) || (month == 2)) {
  year = year - 1;
  month = month + 12;
    }

    a = floor(year / 100);
    if (gregorian)
  b = 2.0 - a + floor(a / 4.0);
    else
  b = 0.0;

    jd = floor(365.25 * (float)(year + 4716.0))
  + floor(30.6001 * (float)(month + 1))
  + day + b - 1524.5;

    return jd;
}
/* moon's position using fundamental arguments  (Van Flandern & Pulkkinen, 1979)*/

void moon(float jd)
{


  float d, f, g, h, m, n, s, u, v, w;

    h = 0.606434 + 0.03660110129 * jd;
    m = 0.374897 + 0.03629164709 * jd;
    f = 0.259091 + 0.0367481952 * jd;
    d = 0.827362 + 0.03386319198 * jd;
    n = 0.347343 - 0.00014709391 * jd;
    g = 0.993126 + 0.0027377785 * jd;

    h = h - floor(h);
    m = m - floor(m);
    f = f - floor(f);
    d = d - floor(d);
    n = n - floor(n);
    g = g - floor(g);

    h = h * 2 * M_PI;
    m = m * 2 * M_PI;
    f = f * 2 * M_PI;
    d = d * 2 * M_PI;
    n = n * 2 * M_PI;
    g = g * 2 * M_PI;

    v = 0.39558 * sin(f + n);
    v = v + 0.082 * sin(f);
    v = v + 0.03257 * sin(m - f - n);
    v = v + 0.01092 * sin(m + f + n);
    v = v + 0.00666 * sin(m - f);
    v = v - 0.00644 * sin(m + f - 2 * d + n);
    v = v - 0.00331 * sin(f - 2 * d + n);
    v = v - 0.00304 * sin(f - 2 * d);
    v = v - 0.0024 * sin(m - f - 2 * d - n);
    v = v + 0.00226 * sin(m + f);
    v = v - 0.00108 * sin(m + f - 2 * d);
    v = v - 0.00079 * sin(f - n);
    v = v + 0.00078 * sin(f + 2 * d + n);

    u = 1 - 0.10828 * cos(m);
    u = u - 0.0188 * cos(m - 2 * d);
    u = u - 0.01479 * cos(2 * d);
    u = u + 0.00181 * cos(2 * m - 2 * d);
    u = u - 0.00147 * cos(2 * m);
    u = u - 0.00105 * cos(2 * d - g);
    u = u - 0.00075 * cos(m - 2 * d + g);

    w = 0.10478 * sin(m);
    w = w - 0.04105 * sin(2 * f + 2 * n);
    w = w - 0.0213 * sin(m - 2 * d);
    w = w - 0.01779 * sin(2 * f + n);
    w = w + 0.01774 * sin(n);
    w = w + 0.00987 * sin(2 * d);
    w = w - 0.00338 * sin(m - 2 * f - 2 * n);
    w = w - 0.00309 * sin(g);
    w = w - 0.0019 * sin(2 * f);
    w = w - 0.00144 * sin(m + n);
    w = w - 0.00144 * sin(m - 2 * f - n);
    w = w - 0.00113 * sin(m + 2 * f + 2 * n);
    w = w - 0.00094 * sin(m - 2 * d + g);
    w = w - 0.00092 * sin(2 * m - 2 * d);

    s = w / sqrt(u - v * v);  // compute moon's right ascension ...  
    Sky[0] = h + atan(s / sqrt(1 - s * s));

    s = v / sqrt(u);    // declination ...
    Sky[1] = atan(s / sqrt(1 - s * s));

    Sky[2] = 60.40974 * sqrt(u);  // and parallax
}

/* test an hour for an event*/
float test_moon(int k, float t0, float lat, float plx)
{

const static float K1 = 15 * M_PI * 1.0027379 / 180;
static float Rise_az = 0.0, Set_az = 0.0;

    float ha[3] = { 0.0, 0.0, 0.0 };
    float a, b, c, d, e, s, z;
    float hr, min, time;
    float az, hz, nz, dz;

    if (RAn[2] < RAn[0])
  RAn[2] = RAn[2] + 2 * M_PI;

    ha[0] = t0 - RAn[0] + (k * K1);
    ha[2] = t0 - RAn[2] + (k * K1) + K1;

    ha[1] = (ha[2] + ha[0]) / 2;  // hour angle at half hour
    Dec[1] = (Dec[2] + Dec[0]) / 2; // declination at half hour

    s = sin(DR * lat);
    c = cos(DR * lat);

    /* refraction + sun semidiameter at horizon + parallax correction*/
    z = cos(DR * (90.567 - 41.685 / plx));

    if (k <= 0)     // first call of function
  VHz[0] = s * sin(Dec[0]) + c * cos(Dec[0]) * cos(ha[0]) - z;

    VHz[2] = s * sin(Dec[2]) + c * cos(Dec[2]) * cos(ha[2]) - z;

    if (sgn(VHz[0]) == sgn(VHz[2]))
  return VHz[2];    // no event this hour

    VHz[1] = s * sin(Dec[1]) + c * cos(Dec[1]) * cos(ha[1]) - z;

    a = 2 * VHz[2] - 4 * VHz[1] + 2 * VHz[0];
    b = 4 * VHz[1] - 3 * VHz[0] - VHz[2];
    d = b * b - 4 * a * VHz[0];

    if (d < 0)
  return VHz[2];    /* no event this hour*/

    d = sqrt(d);
    e = (-b + d) / (2 * a);

    if ((e > 1) || (e < 0))
  e = (-b - d) / (2 * a);

    time = ((float) k) + e + 1 / 120; /* time of an event + round up*/
    hr = floor(time);
    min = floor((time - hr) * 60);

    hz = ha[0] + e * (ha[2] - ha[0]); /* azimuth of the moon at the event*/
    nz = -cos(Dec[1]) * sin(hz);
    dz = c * sin(Dec[1]) - s * cos(Dec[1]) * cos(hz);
    az = atan2(nz, dz) / DR;
    if (az < 0)
  az = az + 360;

    if ((VHz[0] < 0) && (VHz[2] > 0)) {
  Rise_time[0] = (int) hr;
  Rise_time[1] = (int) min;
  Rise_az = az;
  Moonrise = 1;
    }

    if ((VHz[0] > 0) && (VHz[2] < 0)) {
  Set_time[0] = (int) hr;
  Set_time[1] = (int) min;
  Set_az = az;
  Moonset = 1;
    }

    return VHz[2];
}

/* Local Sidereal Time for zone*/
float lst(const float lon, const float jd, const float z)
{
    float s =
  24110.5 + 8640184.812999999 * jd / 36525 + 86636.6 * z +
  86400 * lon;
    s = s / 86400;
    s = s - floor(s);
    return s * 360 * DR;
}

/* 3-point interpolation*/
float interpolate(const float f0, const float f1, const float f2,
       const float p)
{
    float a = f1 - f0;
    float b = f2 - f1 - a;
    float f = f0 + p * (2 * a + b * (2 * p - 1));

    return f;
}


/* calculate moonrise and moonset times*/
void riseset(const float lat, const float lon, const int day,
       const int month, const int year, const int TIMEZONE )//
{
    int i, j, k;
    float ph;
    // guido: julian day has been converted to int from float
//    float jd = (julian_day(day, month, year)) - 2451545;  // Julian day relative to Jan 1.5, 2000
    float jd = (julian_day(day, month, year)) - 2451545;  // Julian day relative to Jan 1.5, 2000
    float mp[3][3];
    float lon_local = lon;

    if ((sgn(-TIMEZONE) == sgn(lon)) && (TIMEZONE != 0))//
  Serial.println("WARNING: time zone and longitude are incompatible!");

    for (i = 0; i < 3; i++) {
  for (j = 0; j < 3; j++)
      mp[i][j] = 0.0;
    }

    lon_local = lon / 360;
    float tz = -((float)TIMEZONE) / 24;
    float t0 = lst(lon_local, jd, tz);  /* local sidereal time*/

    jd = jd + tz;   /* get moon position at start of day*/

    for (k = 0; k < 3; k++) {
  moon(jd);
  mp[k][0] = Sky[0];
  mp[k][1] = Sky[1];
  mp[k][2] = Sky[2];
  jd = jd + 0.5;
    }

    if (mp[1][0] <= mp[0][0])
  mp[1][0] = mp[1][0] + 2 * M_PI;

    if (mp[2][0] <= mp[1][0])
  mp[2][0] = mp[2][0] + 2 * M_PI;

    RAn[0] = mp[0][0];
    Dec[0] = mp[0][1];

    Moonrise = 0;   /* initialize*/
    Moonset = 0;

    for (k = 0; k < 24; k++)  /* check each hour of this day*/
    {
  ph = ((float) (k + 1)) / 24;

  RAn[2] = interpolate(mp[0][0], mp[1][0], mp[2][0], ph);
  Dec[2] = interpolate(mp[0][1], mp[1][1], mp[2][1], ph);

  VHz[2] = test_moon(k, t0, lat, mp[1][2]);

  RAn[0] = RAn[2];  // advance to next hour
  Dec[0] = Dec[2];
  VHz[0] = VHz[2];
    }

}

float get_phase(const DateTime now, const int TIMEZONE) {/*TZOffset*/
  //float phase = (julian_day(now.day(),now.month(), now.year()) - 2451550.1);
  //float phase = (julian_day(now.day(),now.month(), now.year()) - 2440594.359028);  //CE 1970 January 07 20:37:00.2 UT  Wednesday - new moon
  float phase;
 
  phase = julian_day(now.day(),now.month(), now.year());
//  phase -= 2455211.8; //CE  2010 January 15 07:12:00.0 UT - new moon
  phase -= 2440594.359028;
  phase += ((now.hour() * 60) + now.minute()) / (float)1440; // Adjust for current time JD returns Midnight. 1140 = minutes in day.
  phase += -((float)TIMEZONE) / 24.0; // Now adjust local to UTC.
  phase = fmod(phase,29.530588853);
  return (phase);
}


/* check for no moonrise and/or no moonset*/
int moon_up(const DateTime now) {
 
  int riseMin=(Rise_time[0]*60)+Rise_time[1];
  int setMin=(Set_time[0]*60)+Set_time[1];
  int nowMin=(now.hour()*60)+now.minute();

  if ((!Moonrise) && (!Moonset)) { // neither moonrise nor moonset
    if (VHz[2] < 0)
      return(0); // down all day
    else
      return(1); // up all day
    }
 
  if (Moonrise && Moonset) {
    if ((setMin > riseMin) && (riseMin < nowMin) && (nowMin < setMin)) {
      return(1); // up
    }

    if ((setMin < riseMin) && ((nowMin < setMin) || (nowMin > riseMin))) {
      return(1); // up
    }
  }
 
  if (Moonrise && (!Moonset)) { // Moonrise only
    if (nowMin > riseMin) {
      return(1);
    }
  }
 
  if (Moonset && (!Moonrise)) { // Moonset only
    if (nowMin < setMin) {
      return(1);
    }
  }

  return(0); // if in doubt turn blow it out

}
int moon_phase(){
  /* calculates the age of the moon phase(0 to 7)*/
  /* there are eight stages, 0 is full moon and 4 is a new moon*/
  DateTime now = RTC.now();  
  double jd = 0; // Julian Date
  double ed = 0; //days elapsed since start of full moon
  int b= 0;
  jd = julianDate(now.year(), now.month(), now.day());
  //jd = julianDate(1972,1,1); // used to debug this is a new moon
  jd = int(jd - 2244116.75); // start at Jan 1 1972
  jd /= 29.53; // divide by the moon cycle    
  b = jd;
  jd -= b; // leaves the fractional part of jd
  ed = jd * 29.53; // days elapsed this month
  nfm = String((int(29.53 - ed))); // days to next full moon
  b = jd*8 +0.5;
  b = b & 7;
  return b;
   
}
double julianDate(int y, int m, int d){
/* convert a date to a Julian Date}*/
  int mm,yy;
  double k1, k2, k3;
  double j;
 
  yy = y- int((12-m)/10);
  mm = m+9;
  if(mm >= 12) {
    mm = mm-12;
  }
  k1 = 365.25 *(yy +4172);
  k2 = int((30.6001 * mm) + 0.5);
  k3 = int((((yy/100) + 4) * 0.75) -38);
  j = k1 +k2 + d + 59;
  j = j-k3; // j is the Julian date at 12h UT (Universal Time)

  return j;
}
void print_moonrise (void) {
    if (Moonrise) {
    if (Rise_time[0] < 10) {
      Serial.print("0");
    }
    Serial.print(Rise_time[0]);
    Serial.print(":");
    if (Rise_time[1] < 10) {
      Serial.print("0");
    }
    Serial.print(Rise_time[1]);
    } else {
    Serial.print("  none");
  }
}

void print_moonset (void) {
    if (Moonset) {
    if (Set_time[0] < 10) {
      Serial.print("0");
    }
    Serial.print(Set_time[0]);
    Serial.print(":");
    if (Set_time[1] < 10) {
      Serial.print("0");
    }
    Serial.print(Set_time[1]);
    } else {
    Serial.print("  none");
  }
}

void print_phase(const DateTime now) {
    Serial.print(get_phase(now, TIMEZONE),4);
}

 
void draw(void) {
DateTime now = RTC.now();
setPwm_Lune();
}
 
int calculPwm( int TimeMins, int riseMin, int setMin ) {
  DateTime now = RTC.now();
   TimeMins =  (now.hour() * 60) + now.minute();
   riseMin = Rise_time[0] * 60 + Rise_time[1];
   setMin  = Set_time[0]*60 + Set_time[1];
  int pwm = 0;

  // gestion du cas où le levé est plus tard que le couché comme pour la lune
  if( riseMin > setMin)
    setMin += 24 * 60; // ajout de 24h...
  if( TimeMins < riseMin )
    TimeMins += 24 * 60; // ajout de 24h ...
  // fin de la gestion
 

  int minuitLunaire = (riseMin + setMin) / 2;
 
  // phase montante
  if(TimeMins > riseMin && TimeMins < minuitLunaire) {
    pwm = map( TimeMins, riseMin, minuitLunaire, 0, valeur_Moon);
  }

  // phase descendante
  if(TimeMins > minuitLunaire && TimeMins < setMin) {
    pwm = map( TimeMins, minuitLunaire, setMin, valeur_Moon, 0);
  }
    
  return pwm;

}
void setPwm_Lune() {
  DateTime now = RTC.now();
  TimeMins = (now.hour() * 60) + now.minute();
  //int currentTime = getCurrentTime();  
  int riseMin = Rise_time[0] * 60 + Rise_time[1]; // Attention variables globales à modifier avec des fonctions...
  int setMin = Set_time[0]*60 + Set_time[1]; // Attention variables globales ...
  int pwm_Lune = calculPwm ( TimeMins, riseMin, setMin );
  analogWrite(PINPWMLUNE, pwm_Lune);

}
void setup(void) {
if (! RTC.begin()) {
      Serial.println("Couldn't find RTC");
      while (1);
  }
      if (! RTC.isrunning()) {
      Serial.println("RTC is NOT running!");
      RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
 /* pin PWM bleu lune*/
      pinMode (8,OUTPUT);
      analogWrite(PINPWMLUNE,LOW);// commande pwm bleu lune
}
void loop(void) {
 
      DateTime now = RTC.now();
      int riseMin=(Rise_time[0]*60)+Rise_time[1];
      int setMin=(Set_time[0]*60)+Set_time[1];
      TimeMins = (now.hour() * 60) + now.minute();
      /*  Moon Rise initialisation */
      riseset(LATITUDE, LONGITUDE, now.day(), now.month(), now.year(), TIMEZONE);
      Moonset = Set_time[0]*60 + Set_time[1];
      moonsetHour = Set_time[0];
      moonsetMin = Set_time[1];
      Moonrise = Rise_time[0]*60 + Rise_time[1];
      moonriseHour = Rise_time[0];
      moonriseMin = Rise_time[1];
}
 
 
 
 
 


#197 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 06 mars 2020 - 03:41

Bonjour,

ce n'est pas comme ça qu'il faut s'y prendre :

- ce n'est pas en lisant un code qu'on peut dire qu'il est correct. Sauf si le code ne fait que quelques lignes, personne ne le peut. Il n'y a qu'une manière de voir si un code est correct : le tester (enfin, il y a une autre solution, la preuve formelle, mais c'est abominable à mettre en place, du coup on ne le fait que sur des systèmes critiques tels que les commandes d'un avion).

- ce n'est ni mon boulot, ni celui de Mike de lire ton code pour voir si on y trouve des erreurs si tu ne te donne même pas la peine de tester

- si tu ne cherches pas à programmer et à déboguer par toi même, tu ne progressera jamais. Personne n'écrit un grand programme sans faire la moindre erreur : tout l'art consiste à écrire le code de telle manière qu'on puisse facilement le tester pour s'assurer de trouver et corriger toutes les erreurs. C'est ce qu'on essaye de te faire faire, mais tu as l'air de vouloir n'en faire qu'à ta tête, et ensuite compter sur nous pour trouver tes erreurs.

 

Dans le message #195, Mike te donne une bonne façon de tester simplement la fonction calculPWM (même s'il aurait peut-être mieux valu utiliser la pin du PWM du soleil vu les horaires). Du coup, commence par tester calculPWM comme le suggère Mike, donne le code correspondant, et dis nous si le test est passé avec succès ou pas (et dans ce cas, quel est le problème).

 

 

De manière générale, il faut tester CHAQUE fonction/bout de code séparément (éventuellement en se servant d'autres fonctions à conditions quelles aient été testées au préalable).

Un autre conseil général : tester un code qui dépend de la date et de l'heure est compliqué, car on n'a pas envie d'attendre que le temps s'écoule. Du coup, le mieux est de passer le temps en paramètres à toutes les fonctions, comme ça tu peux tester instantanément avec l'heure/la date que tu veux (par exemple faire une journée en accéléré comme le suggère Mike).

 

 

Donc pour ton projet :

- aucune fonction n'as le droit d'utiliser RTC ou now sauf celles qui servent uniquement à renvoyer l'heure/la date

- toutes les autres fonctions qui utilisent le temps doivent avoir le temps en argument, comme ça elles sont plus faciles à tester

- aucune fonction n'a le droit d'être utilisée ailleurs si elle n'a pas été testée auparavant (ce qui implique d'écrire un petit code de test dans loop ou dans setup pour la tester)

- aucune variable globale n'est autorisée, à moins que soit on t'ai dit de la mettre, soit que tu ais argumenté pourquoi tu ne peux pas t'en passer

- quand on te dis de tester le code de telle manière, ou d'implémenter telle fonction, fait le (sauf si tu as une bonne raison de ne pas le faire, dans ce cas argumente), et n'essaye pas d'avancer plus vite, au final on y perd plus de temps qu'autre chose. Après, si tu ne veux pas écouter nos conseils, pas de problème, mais dans ce cas, ça ne sert à rien qu'on passe des heures à te les donner

- ne nous mets JAMAIS de code sans l'avoir testé : ça nous fait perdre notre temps : teste le, et dis nous le résultat, ensuite on peut en discuter (par exemple le code ci-dessus ne compilera même pas, car il manque l'accolade de fermeture du loop


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#198 michel

michel

    Habitué

  • Membres
  • PipPip
  • 179 messages
  • Gender:Male
  • Location:nice

Posté 06 mars 2020 - 04:36

bonjour sandro,

à juste titre j'ai rectifier le code # 196

je t'ai mis tout ce que je penser pour que tu puisse avoir tout pour voir si je n'avais pas oublier quelque chose .

mais apparemment c’était trop , je suis désolé je pense que je vais laisser tomber .

je suis entrain de le tester et je dirais à Mike118 le résultat .

je fais ce que je peux pour vous fournir ce que je pense pouvoir vous aider .

je ne pense pas que tu sache conduire un tgv alors sois indulgent avec moi je suis novice et ne sais pas très bien coder .

voila je vous souhaite à tout les deux (toi et Mike118 )une bonne soirée et vous remerci pour votre patience .



#199 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 06 mars 2020 - 06:37

Bonsoir,

Non, je ne sais pas conduire un TGV. Et je n'attends pas non plus de toi que tu sois un programmeur chevronné. En revanche, j'apprécierais si tu pouvais suivre la méthode et la progression qu'on te propose avec Mike (et là, pas besoin de savoir programmer, il suffit de relire 2-3 fois nos messages, et de bien vérifier que tu as suivit toutes les consigne, quitte à nous demander si l'une d'elles n'est pas claire ou que tu n'arrives pas à l'appliquer).

 

En l’occurrence, pour l'instant, on essaye de te faire avancer par petites étapes, de manière à garder un code propre sur lequel on peut construire un gros projet sans que ce ne soit trop le bordel et sans que ce ne soit trop dur de le déboguer.

Pour l'instant, je n'ai pas l'impression que tu ai vraiment assimilé la méthode, qui consiste à faire de petites fonctions et de les tester indépendamment (ie ce qu'on essaye de te faire faire). Ça ne me surprends pas, vu qu'on est encore en train de mettre ces tests en place. Mais tant que ce ne sera pas assimilé, je pense qu'on avancera plus vite si tu ne fais pas d'excès de zèle. Une fois que tu aura bien compris la méthode, tu devrais pouvoir t'occuper du reste du programme quasi sans aide.

 

Un petit rappel sur la technique pour écrire un code propre :

1) écrire une petite fonction (souvent entre 1 et 20 lignes, au delà de 100 lignes c'est rarement une bonne idée), qui effectue une tâche "simple". Cette fonction ne doit pas utiliser de variables globales.

2) écrire un petit code pour tester cette fonction sur tous les cas possibles, ou au moins un nombre représentatif de cas.

3) essayer de compiler le code : si ça ne compile pas, corriger les erreurs (souvent le compilateur donne des indications assez précises sur la nature de l'erreur et sur sa localisation)

4) une fois que le code compile : regarder les résultats du test. Si les résultats ne sont pas ceux attendus, chercher l'erreur, et la corriger (-> ensuite, retour à l'étape 3).

5) Si les résultats du test sont bon, recommencer au 1) avec une seule nouvelle fonction

 

Quelques pistes sur comment trouver les erreurs (étape 4) :

1) identifier la fonction qui pose problème. Si tu as bien suivit la méthode sur la technique pour écrire un code propre, alors c'est trivial : il s'agit forcément de la fonction que tu viens de créer, vu que tu as testé les autres avant. En pratique, il arrive quand même que tu ais oublié de tester un cas particulier dans une des fonctions précédentes : dans ce cas, il est souvent utile d'afficher les arguments donnés en entrée des fonctions et la valeur de retour, et de vérifier que c'est cohérent

2) une fois la fonction coupable identifiée, tu as plusieurs méthodes possibles :

2.1) essayer de deviner d'où vient l'erreur à partir du résultat du test : par exemple, si la led de la lune est allumée en plein jour, il est possible que l'erreur vienne des conditions des if qui disent s'il fait jour ou nuit

2.2) relire le code pour voir si tu trouve l'erreur : ça peut marcher ou pas, c'est une question de chance. Pour avoir de bonnes chances que ça marche, il faut avoir réussi à déterminer que l'erreur est dans un bout de code aussi petit que possible (si tu as plus que 20-30 lignes de code, oublie à ton niveau, et même pour moi, je n'utilise pas cette méthode pour plus qu'une 50ène de lignes)

2.3) Utilise un affichage (sur arduino, en général Serial.print) pour afficher :

2.3.1) -le déroulement du programme : il faut mettre un Serial.print au début de chaque bloc (ie juste après chaque accolade ouvrante) : de cette manière, tu sais dans quel "if" tu rentre, combien de tours tu fais dans les boucles, ...

2.3.2) -la valeur des variables : tu affiche les variables qui te semblent pertinentes (voir toutes), et tu vérifie à la main que tout au long de l'exécution les valeurs restent cohérentes : quand tu as trouvé quelle est la première variable à devenir fausse et où, tu as en général (quasi) trouvé l'erreur

3) Si après une heure tu n'as pas trouvé l'erreur, alors vient demander de l'aide. Il est complètement normal de passer beaucoup de temps à chercher les erreurs (pour ma part, je dirais que je passe les 3/4 de mon temps à chercher mes erreurs quand je programme). Si beaucoup d'erreurs se trouvent en quelques minutes, passer une heure sur une erreur un peu moins évidente n'a rien d’anormal, même pour un programmateur expérimenté. J'ai même déjà eut, sur un gros projet, un bug qui m'a pris 2 ou 3 jours à identifier

 

 

 

Du coup, tiens nous au courant du résultat des tests!

Bonne soirée

Sandro


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#200 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 964 messages
  • Gender:Male
  • Location:Anglet

Posté 07 mars 2020 - 01:42

Du coup afin de te donner un coup de pouce, je te propose de reprendre avec ce code de départ à tester : 


 

#define PINPWMLUNE 8

void setup() {
  Serial.begin(9600);
  Serial.println( "Initialisation");
  pinMode(PINPWMLUNE, OUTPUT);
  digitalWrite(PINPWMLUNE, LOW);
}

void loop() {
  Serial.println( "Un nouveau jour commence!");
  for (int i = 0; i < 24 * 60; i ++ ) {
    int pwm = calculPwm( i, 360, 1200);  // riseTime à 360 = 6h du matin setTime à 1200 = 20h et le temps file en accéléré ...
    analogWrite(PINPWMLUNE, pwm);
    delay(100);                           // 100 ms => 1min
  }
}


// Fonction qui calcule le PWM à mettre en fonction du temps courant, de l'heure de levé et de l'heure de couché
// Les heures doivent être fournies en minutes sur 24h => comprises entre 0 et 24 * 60
// fonction pouvant fonctionner pour la lune et pour le soleil

int calculPwm( int currentTime, int riseTime, int setTime ) {

  int pwm = 0;

  // gestion du cas où le levé est plus tard que le couché comme pour la lune on décale de 24h pour faciliter les calculs
  if ( riseTime > setTime)
    setTime += 24 * 60; // ajout de 24h...
  if ( currentTime < riseTime )
    currentTime += 24 * 60; // ajout de 24h ...
  // fin de la gestion

  int midi = (riseTime + setTime) / 2;

  // phase montante
  if (currentTime > riseTime && currentTime =< midi) {
    pwm = map( currentTime, riseTime, midi, 0, 255);
  }

  // phase décendante
  if (currentTime > midi && currentTime < setTime) {
    pwm = map( currentTime, midi, setTime, 255, 0);
  }

  return pwm;

}

Normalement tu dois pouvoir le mettre sur ta carte et le tester. 

Quand tu le testes, ouvre le moniteur série ( règle le sur 9600 baud ) et confirme moi que tu vois bien le texte 
" Initialisation " une fois, suivi de " Un nouveau jour commence! "

De plus si ta led est branchée elle devrait s'allumer et s'éteindre progressivement. Peux tu confirmer tout ça ? 

 

Si oui, essaye de juste changer cette ligne du loop

int pwm = calculPwm( i, 360, 1200);  // riseTime à 360 = 6h du matin setTime à 1200 = 20h 

change les valeurs 360 et 1200 afin de vérifier que ça marche bien dans des cas différents. 
Quand tu seras sûr que tout marche après on verra ensemble pour ajouter une autre fonction =)

 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 





0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users