Forums LR PRESSE

Où il est question de trains, petits et grands

  • Advertisement

Arduino - Bloc automatique

Toutes les discussions sur l'Arduino !

Modérateur: MOD

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 17:41 
Article 4

Le programme est repris ci dessous :

// Déclaration des variables internes
Boolean Z_1, Z_2, Z_3, Z_4, Z_5, Z_6, Z_7, Z_8;
boolean ZA_1, ZA_2, ZA_3, ZA_4, ZA_5, ZA_6, ZA_7, ZA_8;
boolean S_1, S_2, S_3, S_4, S_5, S_6, S_7, S_8;
boolean A_1, A_2, A_3, A_4, A_5, A_6, A_7, A_8;
boolean VL_1, VL_2, VL_3, VL_4, VL_5, VL_6, VL_7, VL_8;

void setup() {

}

void loop() {

// on attend 100ms entre deux boucles

delay(100);

// faire l'acquisition des entrées Z_1 ... Z_8, ZA_1 ... ZA_8
// et les stocker dans les variables internes de même nom
//
// Non décrit ici

// Signal S1

if (!Z_1 || !ZA_2) {S_1 = true ;} else {S_1 =false ;}
if (S_2 && Z_1 && ZA_2 ) {A_1 = true ;} else {A_1 = false ;}
if (!S_2 && Z_1 && ZA_2 ) {VL_1 = true ;} else {VL_1 = false ;}

// Signal S2

if (!Z_2 || !ZA_3) {S_2 = true ;} else {S_2 =false ;}
if (S_3 && Z_2 && ZA_3 ) {A_2 = true ;} else {A_2 = false ;}
if (!S_3 && Z_2 && ZA_3 ) {VL_2 = true ;} else {VL_2 = false ;}

// Signal S3

if (!Z_3 || !ZA_4) {S_3 = true ;} else {S_3 =false ;}
if (S_4 && Z_3 && ZA_4 ) {A_3 = true ;} else {A_3 = false ;}
if (!S_4 && Z_3 && ZA_4 ) {VL_3 = true ;} else {VL_3 = false ;}

// Signal S4

if (!Z_4 || !ZA_5) {S_4 = true ;} else {S_4 =false ;}
if (S_5 && Z_4 && ZA_5 ) {A_4 = true ;} else {A_4 = false ;}
if (!S_5 && Z_4 && ZA_5 ) {VL_4 = true ;} else {VL_4 = false ;}

// Signal S5

if (!Z_5 || !ZA_6) {S_5 = true ;} else {S_5 =false ;}
if (S_6 && Z_5 && ZA_6 ) {A_5 = true ;} else {A_5 = false ;}
if (!S_6 && Z_5 && ZA_6 ) {VL_5 = true ;} else {VL_5 = false ;}

// Signal S6

if (!Z_6 || !ZA_7) {S_6 = true ;} else {S_6 =false ;}
if (S_7 && Z_6 && ZA_7 ) {A_6 = true ;} else {A_6 = false ;}
if (!S_7 && Z_6 && ZA_7 ) {VL_6 = true ;} else {VL_6 = false ;}

// Signal S7

if (!Z_7 || !ZA_8) {S_7 = true ;} else {S_7 =false ;}
if (S_8 && Z_7 && ZA_8 ) {A_7 = true ;} else {A_7 = false ;}
if (!S_8 && Z_7 && ZA_8 ) {VL_7 = true ;} else {VL_7 = false ;}

// Signal S8

if (!Z_8 || !ZA_1) {S_8 = true ;} else {S_8 =false ;}
if (S_1 && Z_8 && ZA_1 ) {A_8 = true ;} else {A_8 = false ;}
if (!S_1 && Z_8 && ZA_1 ) {VL_8 = true ;} else {VL_8 = false ;}

// envoyer vers les sorties les valeurs de feux S_1, A_1, VL_1, ... S_8, A_8, VL_8
//
// Non décrit ici

}

Avec l’emploi de l’algèbre de Boole, on obtient le code suivant

// Déclaration des variables internes

boolean Z_1, Z_2, Z_3, Z_4, Z_5, Z_6, Z_7, Z_8;
boolean ZA_1, ZA_2, ZA_3, ZA_4, ZA_5, ZA_6, ZA_7, ZA_8;
boolean S_1, S_2, S_3, S_4, S_5, S_6, S_7, S_8;
boolean A_1, A_2, A_3, A_4, A_5, A_6, A_7, A_8;
boolean VL_1, VL_2, VL_3, VL_4, VL_5, VL_6, VL_7, VL_8;

void setup() {

}

void loop() {

// on attend 100ms entre deux boucles

delay(100);

// faire l'acquisition des entrées Z_1 ... Z_8, ZA_1 ... ZA_8
// et les stocker dans les variables internes de meme nom
//
// Non décrit ici

// Signal S1

S_1 = !Z_1 | !ZA_2 ;
A_1 = S_2 & Z_1 & ZA_2 ;
VL_1 = !S_2 & Z_1 & ZA_2 ;

// Signal S2

S_2 = !Z_2 | !ZA_3 ;
A_2 = S_3 & Z_2 & ZA_3 ;
VL_2 = !S_3 & Z_2 & ZA_3 ;

// Signal S3

S_3 = !Z_3 | !ZA_4 ;
A_3 = S_4 & Z_3 & ZA_4 ;
VL_3 = !S_4 & Z_3 & ZA_4 ;

// Signal S4

S_4 = !Z_4 | !ZA_5 ;
A_4 = S_5 & Z_4 & ZA_5 ;
VL_4 = !S_5 & Z_4 & ZA_5 ;

// Signal S5

S_5 = !Z_5 | !ZA_6 ;
A_5 = S_6 & Z_5 & ZA_6 ;
VL_5 = !S_6 & Z_5 & ZA_6 ;

// Signal S6

S_6 = !Z_6 | !ZA_7 ;
A_6 = S_7 & Z_6 & ZA_7 ;
VL_6 = !S_7 & Z_6 & ZA_7 ;

// Signal S7

S_7 = !Z_7 | !ZA_8 ;
A_7 = S_8 & Z_7 & ZA_8 ;
VL_7 = !S_8 & Z_7 & ZA_8 ;
// Signal S8

S_8 = !Z_8 | !ZA_1 ;
A_8 = S_1 & Z_8 & ZA_1 ;
VL_8 = !S_1 & Z_8 & ZA_1 ;

// envoyer vers les sorties les valeurs de feux S_1, A_1, VL_1, ... S_8, A_8, VL_8
//
// Non décrit ici

}

Pour Information :

- la version If Else occupe 1360 octets
- la version Booléenne occupe 1136

Soit une différence de 17%

Dans le prochain article nous proposerons la réduction de la taille du programme
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 17:43 
L'article 5 sera publié dans la soirée :ange3:
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 18:23 
ramboman a écrit:
C'est devenu mon livre de chevet... mais c'est un des derniers chapitres que je ne maîtrise pas encore. Promis, je m'y mets ce soir :ange3:


Les derniers chapitres de ce livre sont les plus intéressants car le reste, on retrouve beaucoup ce qui existe sur le site Arduino, ou dans d'autres tutoriels ; mais il y a aussi quelques petits détails intéressants à noter.

Bonne lecture.

Christian
Avatar de l’utilisateur
Arduino
Prolixe
 
Messages: 1698
Inscrit le: Mer 25 Sep 2013, 16:14

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 18:35 
Article 5

Plutôt que de d’écrire pour chaque signal son code, nous allons écrire les équations une seule fois et les utiliser pour chaque signal.

Pour cela, nous allons stocker les variables internes dans un tableau.
Par exemple, pour les variables S, nous utilisons un tableau nommé S et comportant 8 cases.
S_1 va être stocké dans la première case, … , S_8 va être stocké dans la huitième case
Attention, l’indice de la première case est 0 et celle de la 8ème est 7.

Le programme figure ci-dessous.
Chaque signal est fonction du suivant (I+1) sauf pour le dernier qui dépend du premier, d’ou le test sur I dans la boucle.

// Déclaration des variables internes

boolean Z[8]; // Zones Z_1 à Z_8
boolean ZA[8]; // Zones ZA_1 à ZA_8
boolean S[8]; // Feux S_1 à S_8
boolean A[8]; // Feux A_1 à A_8
boolean VL[8]; // Feux VL_1 à VL_8

byte I; //compteur de la boucle

void setup() {

}

void loop() {

// on attend 100ms entre deux boucles

delay(100);

// faire l'acquisition des entrées Z_1 ... Z_8, ZA_1 ... ZA_8
// et les stocker dans les tableaux internes de meme nom
//
// Non décrit ici


for (I=0 ; I<=7 ; I++)
{
if (I<7)
{
if (!Z[I] || !ZA[I+1]) {S[I] = true ;} else {S[I] =false ;}
if (S[I+1] && Z[I] && ZA[I+1] ) {A[I] = true ;} else {A[I] = false ;}
if (!S[I+1] && Z[I] && ZA[I+1] ) {VL[I] = true ;} else {VL[I] = false ;}
}
else
{
if (!Z[I] || !ZA[0]) {S[I] = true ;} else {S[I] =false ;}
if (S[0] && Z[I] && ZA[0] ) {A[I] = true ;} else {A[I] = false ;}
if (!S[0] && Z[I] && ZA[0] ) {VL[I] = true ;} else {VL[I] = false ;}
}
}

// envoyer vers les sorties les valeurs de feux S_1, A_1, VL_1, ... S_8, A_8, VL_8
//
// Non décrit ici

}


En algèbre de Boole

// Déclaration des variables internes

boolean Z[8]; // Zones Z_1 à Z_8
boolean ZA[8]; // Zones ZA_1 à ZA_8
boolean S[8]; // Feux S_1 à S_8
boolean A[8]; // Feux A_1 à A_8
boolean VL[8]; // Feux VL_1 à VL_8

byte I; //compteur de la boucle

void setup() {

}

void loop() {

// on attend 100ms entre deux boucles

delay(100);

// faire l'acquisition des entrées Z_1 ... Z_8, ZA_1 ... ZA_8
// et les stocker dans les variables internes de meme nom
//
// Non décrit ici


for (I=0 ; I<=7 ; I++)
{
if (I<7)
{
S[I] = !Z[I] | !ZA[I+1] ;
A[I] = S[I+1] & Z[I] & ZA[I+1] ;
VL[I] = !S[I+1] & Z[I] & ZA[I+1] ;
}
else
{
S[I] = !Z[I] | !ZA[0] ;
A[I] = S[0] & Z[I] & ZA[0] ;
VL[I] = !S[0] & Z[I] & ZA[0] ;
}
}

// envoyer vers les sorties les valeurs de feux S_1, A_1, VL_1, ... S_8, A_8, VL_8
//
// Non décrit ici

}

Chacun peut modifier le nombre de signaux, il suffit de modifier la taille des tableaux, la limite de la boucle for et le test if. Cette modification est beaucoup plus simple que dans le cas du code de l’article 4.

Pour Information :

- la version If Else occupe 892 octets
- la version Booléenne occupe 838 octets

Soit une différence de 35% par rapport au code présenté dans l’article 4
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 18:37 
lgperrin a écrit:Article 4


Pour Information :

- la version If Else occupe 1360 octets
- la version Booléenne occupe 1136

Soit une différence de 17%

Dans le prochain article nous proposerons la réduction de la taille du programme


Voilà qui donne un élément de réponse à la question de ramboman. Et 17%, c'est énorme pour un microcontrôleur qui n'a pas la même puissance qu'un PC auquel nous sommes tous habitués. D'où l'intérêt de prendre les bonnes habitudes pour programmer (mais là, on aborde déjà un côté expert, ce vers quoi chaque Arduineur doit tendre). :wink:

Christian
Avatar de l’utilisateur
Arduino
Prolixe
 
Messages: 1698
Inscrit le: Mer 25 Sep 2013, 16:14

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 18:44 
Entre temps, le 5ème article vient de sortir :coeur1:

Bon, je ne parle pas ici du gain de 35%, il a été facilement obtenu ! :wink:

Mais tout de même ... :ange:

J'espère que tout le mal que tu te donnes donnera envie aux débutants de réaliser cet ovale de cantons, même s'ils se limitent à 4 ou 5 et que je verrai des vidéos de trains qui se suivent. Faut pas que cela reste de la théorie ! :roll:
Avatar de l’utilisateur
Arduino
Prolixe
 
Messages: 1698
Inscrit le: Mer 25 Sep 2013, 16:14

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 18:48 
et le 6ème arrive ... :mdr2:

Ce qui veux dire que j'ai 4 articles d'avance sur mon planning

4 *3 = 12 jours

je vais pouvoir me consacrer à Madame ensuite :lol:
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 19:07 
Dis donc Gérard, t'as mangé quoi à midi ? :lol:

En tout cas, si Madame est mécontente, montre lui ce que j'ai écrit sur le forum Arduino - Traitement de l'information ; j'apprends aux Arduineurs à passer l'aspirateur ...

Tu pourras dire que tu révises ! :lol:
Avatar de l’utilisateur
Arduino
Prolixe
 
Messages: 1698
Inscrit le: Mer 25 Sep 2013, 16:14

Re: Arduino - Bloc automatique

Publié: Sam 09 Nov 2013, 19:08 
Article 6

Si nous examinons attentivement le programme présenté dans les articles 4 ou 5, on constate que le signal 1 est traité avant le signal 2, etc. Ce qui veut dire que si les indications du signal 2 varient lors d’une itération, elles ne seront prises en compte par le signal 1 que lors de l’itération suivante.

On pourrait inverser l’ordre de traitement : signal 7 en premier. Effectivement, on élimine le décalage d’une itération sauf pour le signal 7.

Pour éliminer tout décalage, il suffit d’exécuter deux fois la boucle I.

Il existe une autre méthode plus sioux qui consiste à exécuter la boucle jusqu’à ce qu’il n’y ait plus de variations. Je n’en parlerai pas pour l’instant car la méthode proposée ci-dessous est largement suffisante pour notre exemple.

Le programme devient :

Code: Tout sélectionner
// Déclaration des variables internes

boolean Z[8];     // Zones Z_1 à Z_8
boolean ZA[8];    // Zones ZA_1 à ZA_8
boolean S[8];     // Feux S_1 à S_8
boolean A[8];     // Feux A_1 à A_8
boolean VL[8];    // Feux VL_1 à VL_8

byte I;           //compteur de la boucle

void setup() {               
   
}

void loop() {
 
// on attend 100ms entre deux boucles
 
delay(100);
 
// faire l'acquisition des entrées Z_1 ... Z_8, ZA_1 ... ZA_8
// et les stocker dans les variables internes de même nom
//
// Non décrit ici
 
for (I=0 ; I<16 ; I++)
{
      int signal = I % 8;
      int prochain_signal = (I + 1) % 8;

      S[signal] = !Z[signal] | !ZA[prochain_signal] ;
      A[signal] = S[prochain_signal] & Z[signal] & ZA[prochain_signal] ;
      VL[signal] = !S[prochain_signal] & Z[signal] & ZA[prochain_signal] ;
}

// envoyer vers les sorties les valeurs de feux S_1, A_1, VL_1, ... S_8, A_8, VL_8
//
// Non décrit ici

}


Nous avons terminé la partie commande des feux.

Les articles suivants aborderont la gestion de la vitesse des trains.
Dernière édition par lgperrin le Dim 10 Nov 2013, 16:50, édité 5 fois au total.
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Dim 10 Nov 2013, 06:18 
Arduino a écrit:
lgperrin a écrit:Article 4


Pour Information :

- la version If Else occupe 1360 octets
- la version Booléenne occupe 1136

Soit une différence de 17%

Dans le prochain article nous proposerons la réduction de la taille du programme


Voilà qui donne un élément de réponse à la question de ramboman. Et 17%, c'est énorme pour un microcontrôleur qui n'a pas la même puissance qu'un PC auquel nous sommes tous habitués. D'où l'intérêt de prendre les bonnes habitudes pour programmer (mais là, on aborde déjà un côté expert, ce vers quoi chaque Arduineur doit tendre). :wink:

Christian


J'adore :coeur1:
Mais quel gaspillage :mdr2:
Commences ton tableau à '0'... tu gagnes une case : de 0 à 7... :ange:
Et le boolean :?:
Il prend un octet tout entier alors qu'un simple bit suffit :ange3:
Je te laisses le soin de calculer le nombre d'octets que tu gaspilles de façon éhontée :clown:
:mdr: :coeur2:
Avatar de l’utilisateur
Ramboman
Disert
 
Messages: 423
Inscrit le: Lun 23 Oct 2006, 17:13
Localisation: Waterloo, Belgique
Âge: 74
Echelle pratiquée: LGB

Re: Arduino - Bloc automatique

Publié: Dim 10 Nov 2013, 09:38 
ramboman a écrit:Commences ton tableau à '0'... tu gagnes une case : de 0 à 7... :ange:
Et le boolean :?:
Il prend un octet tout entier alors qu'un simple bit suffit :ange3:
Je te laisses le soin de calculer le nombre d'octets que tu gaspilles de façon éhontée :clown:
:mdr: :coeur2:


for (I=0 ; I<=7 ; I++) : je commence bien à zéro !!!!! :colere:

Oui on peut prendre un simple bit, mais il s'agit d'un fil pour ceux qui démarrent.

Je te laisse nous proposer un article qui explique simplement comment faire.

Je dit bien simplement, c'est à dire qui m'embrouille pas un débutant.

Allez au travail Ramboman ... je continuerai lorsque tu auras fourni ta contribution et uniquement pour une contribution simple à comprendre pour un débutant. :siffle: :siffle: :siffle:
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Dim 10 Nov 2013, 09:50 
Allons... je plaisantais... ne le prends pas mal...
Avatar de l’utilisateur
Ramboman
Disert
 
Messages: 423
Inscrit le: Lun 23 Oct 2006, 17:13
Localisation: Waterloo, Belgique
Âge: 74
Echelle pratiquée: LGB

Re: Arduino - Bloc automatique

Publié: Dim 10 Nov 2013, 09:55 
oui ma ça peux induire en erreur les débutants
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

Re: Arduino - Bloc automatique

Publié: Dim 10 Nov 2013, 10:01 
Pour ma part, je privilégie la lisibilité du code. Utiliser des octets pour stocker un bit ne me choque pas. L'optimisation commence quand ça ne passe plus :

- Ça ne passe plus au niveau temps
- Ça ne passe plus au niveau mémoire

Bon, sans vouloir critiquer Gérard, je suis attaché à l'emploi de noms de variables plus explicites. On peut aussi réduire la boucle en faisant un adressage de canton modulo pour éviter le test. Ce qui rend aussi le code plus clair.

J'écrirais la boucle de calcul comme ceci :

Code: Tout sélectionner
for (canton = 0 ; canton < 8 ; canton++)
{
    int prochain_canton = (canton + 1) & 0x07;
    S[canton] = !Z[canton] | !ZA[prochain_canton] ;
    A[canton] = S[prochain_canton] & Z[canton] & ZA[prochain_canton] ;
    VL[canton] = !S[prochain_canton] & Z[canton] & ZA[prochain_canton] ;
}


PS: Avez-vous remarqué la balise code pour formater les programmes ?
Avatar de l’utilisateur
jlb
Fécond
 
Messages: 679
Inscrit le: Jeu 04 Oct 2012, 15:38
Echelle pratiquée: N
Prénom: Jean-Luc

Re: Arduino - Bloc automatique

Publié: Dim 10 Nov 2013, 10:14 
Bien vu le coup du modulo.

Effectivement, je pestais contre le code qui est déformé. Merci pour la balise.
Avatar de l’utilisateur
lgperrin
Papotier
 
Messages: 174
Inscrit le: Dim 04 Mars 2012, 13:36
Localisation: Pontoise
Âge: 57
Echelle pratiquée: N-HO

PrécédentSuivant

Retour vers Arduino

Qui est en ligne ?

Utilisateur(s) parcourant actuellement ce forum : Aucun utilisateur inscrit et 3 invité(s)