View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

Tracé de la courbe de l'Equation du Temps (Equation of Time ou EOT) calculée par une carte Arduino

ARDUINO - EXPERT - SERIE
Par X. HINAULT - Créé le 24/08/2010

1.  Présentation

Ce programme permet d'explorer les fonctions de calcul de la carte Arduino : on fait calculer à la carte Arduino la valeur de l'équation du temps pour chaque jour de l'année (365 valeurs calculés). L'Equation du Temps correspond au décalage en minutes de la position du soleil par rapport à l'heure locale. Il existe une légère variation par rapport à l'heure locale due à l'excentricité de l'orbite terrestre et autres paramètres. Plus de détails ici (en anglais) : http://en.wikipedia.org/wiki/Equation_of_time

La courbe des valeurs reçues est tracée dans une interface graphique Processing côté PC. On utilise également le logiciel de calcul numérique Scilab pour vérifier la validité du calcul par Arduino.

Sur cette page, à la fois le programme SCITE, le programme Arduino et le programme Processing.

Ce programme utilise les fonctionnalités suivantes :

  • la connexion série vers le PC

Voir également :

2.  Formule utilisée

Plusieurs possibilités existent. La formule de calcul de l'équation du temps (EOT) que nous utiliserons est :

où :

où Jour est le jour courant de l'année (1er janvier = 1).

Voir également :

3.  Calcul préalable dans le logiciel Scilab

3.1  Courbe obtenue avec Scilab

3.2  Le script Scilab

A copier coller dans l'éditeur Scilab (depuis la console : Applications > Editeur ) puis lancer exécution (dans l'éditeur : Executer > charger dans Scilab ou raccourci CTRL + L )


// Script Scilab
// courbe annuelle de l'Equation du temps
// par X. HINAULT - Aout 2010

ma_figure=scf(1); // crée une figure id=1 et la nomme ma_figure et la fait devenir la figure courante

// paramétrage de la figure 
ma_figure.figure_name="Ma figure"; // nom de la figure
ma_figure.figure_size=[600,600]; // fixe la taille de la figure en pixel
ma_figure.figure_position=[10,10]; // fixe la position de la fenétre par rapport au coin supérieur gauche

// initialisation 
clf(ma_figure); // efface la figure courante

axes=ma_figure.children; // nomme les axes de la figures
axes.grid=[0,0]; // grid = [colorX, color Y, color Z] - 0 pour noir -1 pas de grille
axes.x_location="middle"; // positionnement de l'axe x - "middle" "top" "bottom"
axes.y_location="left"; // positionnement de l'axe y - left, right, middle, origin

//xgrid(); // ajoute la grille

Day=1:1:365; // crée une série de valeur régulièrement espacée

// calcul de la fonction 
BN=2*%pi/365; // calcul de y
BN=BN*(Day-81);


//--- calcul de EOT ----
EOT=(9.87*sin(2*BN))-(7.53*cos(BN))-(1.5*sin(BN));


// tracés
//plot(Day,BN,'r-'); // trace une courbe ligne rouge
plot(Day,EOT,'r-');


4.  Matériel Nécessaire

4.1  L'espace de développement Arduino

  • ... pour éditer, compiler le programme et programmer la carte Arduino.

5.  Instructions de montage

  • Connexion série entre la carte Arduino et le PC (utilise les broches 0 et 1)

6.  Le schéma théorique du montage


Le schéma théorique du montage

7.  Le circuit du montage


Le schéma du montage à réaliser

8.  Explication du programme Arduino

8.1  Structure globale du programme

Ce programme simple comprend :

  • une entête déclarative
  • une partie « configuration » qui ne sera exécutée qu'une fois (fonction setup( ) )
  • une partie constituée d'une boucle sans fin que le programme répètera à l'infini ( fonction loop( ) ) : c'est le coeur du programme.

8.2  Déroulement du programme

Le programme se déroule de la façon suivante :

  • Après avoir pris en compte les instructions de la partie déclarative,
  • puis après avoir exécuté la partie configuration ( fonction setup( ) ),
  • le programme bouclera sans fin ( fonction loop ( ) ), exécutant de façon répétée le code compris dans la boucle sans fin.

Le déroulement du programme

9.  Détails du programme

  • Le programme calcule 365 valeurs à l'aide selon la formule utilisée. Les valeurs de sortie sont adaptées par un coefficient multiplicateur à l'interface de sortie Processing.
  • Pour plus de précisions, se reporter aux commentaires présents dans le programme

10.  Mise en oeuvre du programme

10.1  Fonctionnement

  • Lancer l'exécution du programme processing
  • Faire un reset sur la carte Arduino : le graphique apparaît.

La comparaison avec le graphique obtenu avec Scilab montre que la carte Arduino calcule très bien cette courbe.

11.  Le programme complet en langage Arduino :

A copier/coller directement dans l'éditeur Arduino


// --- Programme Arduino ---
// Copyright X. HINAULT - Créé le 21/08/2010
// www.mon-club-elec.fr 

//  Code sous licence GNU GPL : 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//  

// --- Que fait ce programme ? ---
/* Envoie vers le PC des valeurs numériques issues du calcul
de l'Equation du Temps (EOT) tout au lond de l'année - 365 valeurs (1/jour)*/

// --- Fonctionnalités utilisées ---
// Utilise la connexion série vers le PC 

// --- Circuit à réaliser ---
// Connexion série entre la carte Arduino et le PC (utilise les broches 0 et 1)  

//**************** Entête déclarative *******
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables...

// --- Inclusion des librairies utilisées ---

// --- Déclaration des constantes ---
const float pi=3.14159; // constante pi
const int nbre_jour_annee=365; 

// --- constantes des broches ---

// --- Déclaration des variables globales ---
float valeurf; // variable pour calcul 
int valeur; // variable pour envoi vers le PC

float yf_min, yf_max, yf_base, yf; // variables pour les ordonnées
float xf_min, xf_max, xf; // variables pour les abscisses

int y_min, y_max, y_base, y; // variables pour les ordonnées
int x_min, x_max, x; // variable pour les abcisses

//--------- Déclaration utiles pour les calculs solaires -----------------
float BN; 
float Jour; 
float DECL; 
float EOT, EOT1,EOT2,EOT3; 

// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---

//**************** FONCTION SETUP = Code d'initialisation *****
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()

// --- ici instructions à exécuter au démarrage --- 

Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission 


// ------- Broches en sortie -------  


// ------- Broches en entrée -------  


// ------- Activation du rappel au + interne des broches en entrée si nécessaire -------  

//------ initialisation des variables utilisées 

valeurf=0.0; 
valeur=0; 

xf_min=0.0, xf_max=600.0, xf=0.0; // pour 600 valeurs
x_min=0, x_max=600, x=0;

yf_min=0.0, yf_max=100.0, yf_base=yf_max/2.0, yf=0.0; // échelle des y
y_min=0, y_max=100, y_base=y_max/2, y=0;



} // fin de la fonction setup()
// ********************************************************************************

//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

// --- ici instructions à exécuter par le programme principal --- 

for (x=1; x<nbre_jour_annee; x++) { // incrémente les abcisses de x_min à x_max

  Jour=x;

  //---- calcul de BN ----

  BN=2.0*pi/365.0;
  BN=BN*(Jour-81.0); 

  //---- calcul de la déclinaison 
  // DECL=23.75*2*%pi/360*sin(BN); // calcul Scilab
  DECL=sin(BN);
  DECL=DECL*23.75*2.0;
  DECL=DECL*pi/360.0;


  //--- calcul de EOT ----
  //EOT=(9.87*sin(2*BN))-(7.53*cos(BN))-(1.5*sin(BN)); // calcul Scilab
  EOT1=2*BN;
  EOT1=sin(EOT1);
  EOT1=9.87*EOT1;

  EOT2=-7.53*cos(BN); 

  EOT3=-1.5*sin(BN); 

  EOT=EOT1+EOT2+EOT3; 

  //----- pour affichage sur PC --------

  //yf=BN*40.0; // adaptation au tracé Processing Y=400
  //yf=DECL*200.0; // adaptation au tracé Processing Y=400
  yf=EOT*12.0; // adaptation au tracé Processing Y=400

  //yf=map(yf,yf_min,yf_max,0,1023); // renvoie valeur 0 - 1023

  y=yf; // conversion au format int

  Serial.println(y); // envoi ordonnée vers Processing

  delay(10); // pause entre chaque valeur



} // fin boucle for

while(1); // stoppe loop

} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

//*************** Autres Fonctions du programme *************

// --- Fin programme ---


12.  Le programme complet en langage Processing :

A copier/coller directement dans l'éditeur Processing


/* Processing code for this example

 // Graphing sketch


 // Ce programme reçoit des chaine de caractère ASCII
 // depuis le port Série à 115200 bauds et les affiche sous forme de courbe
 // lorsque les données sont suivies d'un retour de ligne

 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe 
 //
 // modifié par X. HINAULT - January 2010 - Aout 2010
 // www.mon-club-elec.fr
 */

 import processing.serial.*;

 Serial myPort;        // Variable Port Série
 int xPos = 1;         // variable abscisse  - x
 int xPos0=1;       // variable mémorisation xPos n-1

float yPos=1;  // variable yPos - ordonnée
float yPos0=1; // variable yPos n-1

 void setup () {

 // initialise la fenêtre 
// size(int(screen.width*0.9), int(screen.height*0.9));        
// 90% de l'écran par défaut - régler au besoin - 
// viser taille maxi en hauteur - taille fenêtre (x,y)

size(365,400); // initialise la fenetre à la taille L x h 

 // Liste tous les ports disponible et affiche le résultat 
 println(Serial.list());

 // Le port utilisé est listé avec l'indice 0
 // donc j'ouvre le port Serial.list()[0].

 // A adapter si votre port est différent - cf liste qui s'affiche à l'exécution
 myPort = new Serial(this, Serial.list()[0], 115200);
 // ne génère aucun évènement Série tant qu'aucun caractère saut de ligne n'est reçu
 myPort.bufferUntil('\n');
 // initialise le fond de la fenêtre
 background(255);// 0 = noir - 255 = blanc

 quadrillage(); // trace quadrillage - cf fonction ci-dessous

 }
 void draw () {
 // tout se passe dans la fonction SerialEvent car le programme reçoit des données
 }

 void serialEvent (Serial myPort) {
 // mémorise la chaîne de caractères reçue
 String inString = myPort.readStringUntil('\n');

 if (inString != null) {
 // enlève les espaces
 inString = trim(inString);
 // convertit la chaîne en valeur numérique 
 float inByte = float(inString); 

 yPos=inByte; // l'ordonnée est la valeur reçue par le port série // +5 pour affichage du zero

 // trace la ligne
 stroke(0,0,255); // fixe la couleur utilisée pour le tracé en RVB 

 line (xPos0,height/2-yPos0,xPos,height/2-yPos); // trace une ligne en tenant compte valeur reçue

 xPos0=xPos; // mémorisation xPos n-1
 yPos0=yPos; // mémorisation xPos n-1

 // à la fin de l'écran revient au début
 if (xPos >= width) {
 xPos = 0;
 xPos0=0; // pour retour de la trace sans ligne

 background(255); // 0 pour noir - 255 pour blanc... réinitialise l'écran au début  
 } 
 else {
 // incrémente la position horizontale (abscisse)
 xPos++;
 }

 }  // fin while inString

 } // fin serial Event


void quadrillage () {

 stroke(0,255,0); // fixe la couleur utilisée pour le tracé en RVB 

 // lignes verticales

 for (int i=1; i<=36; i++) {

   line (i*10,height-0,i*10,height-399); // trace une ligne verticale

 }

 // lignes horizontales 
 for (int i=1; i<40; i++) {

   if (i==20) stroke(255,0,0);else stroke(0,255,0); // fixe la couleur de la ligne médiane

   line (0,height-(i*10),364,height-(i*10)); // trace ligne horizontale

 }

}