Chrono Agility : nouveau

ddaweb

New Member
Bien résumé, mais j'ai arrêté les tests car à chaque téléchargement et resynchronisation il y avait un moment d'instabilité (entre 4 et 6 cycles).
Après une pause de plusieurs minutes également ... idem si je coupe l'alimentation.

Donc je tente le quartz et les capa ... je les aurais la semaine prochaine seulement.
Petite question, c'est 22pF, 27 pF ou 30 pF ? C'est trop loin pour moi.

Côté de mon code, les écarts avec la durée du temps ne sont plus trop présents, grâce à vous j'ai pu nettement améliorer ses performances et sa stabilité.
Cerise sur le gâteau, les affichages sont nettement plus rapides.
Je continue d'y travailler, tout en gardant le chrono-horloge sous le pouce.

Je ne sais pas si je me trompe, mais l'ajout d'une diode en série sur l'impulsion provoque un retard sur le start :oops:
 

ddaweb

New Member
J'ai une petite question : je ne trouve pas comment surveiller une entrée spécifique afin de pouvoir l'utiliser dans un if ensuite ... la fonction pinsB ?
J'avoue ne pas trop comprendre cette fonction.

Le but final est :
- dans le case de l'interruption déterminer quelle sera la barrière de Stop
- quand le chrono est démarré, j'active l'interruption que sur le BP après 2 sec. et regarde ensuite si cette entrée est active ou non
- dès qu'elle est au repos : BP et barrières arrêtent le chrono via un changement d'interruption

Voici le code de la boucle STOP :
Code:
        ;================ Boucle du STOP
        timer=0

        high A.0 : high A.1                    'led_status et led_defaut allumees
        high B.7                                     'buzzer ON
        val_temps=0 : val_temps_mem=0 : timer=0        'raz variables

            do {                                '---------- blocage barriere STOP
            if val_temps_mem=0 then
                hserout LCD,(254,128,"Bloc. : ")                    'affichage LCD 1ere ligne
            else if val_temps_mem=100 then
                low B.7                    'buzzer OFF
            endif
            val_temps_mem=timer
            bintoascii val_temps_mem, b1,b2,b3,b4,b5    'decomposition ascii
            if b3<>aff_sec then                                         'affichage temps en secondes
                gosub affichage_temps_chrono
                aff_sec=b3
            endif

            if val_temps_mem=200 then                          'ATTENTION : si ce temps est modifie, le faire egalement dans l'horloge si utilisee
                setint or %00000000,%00000100,B            'BP uniquement arrete le chrono
            else if val_temps_mem>200 and barriere_stop=1 then    'STOP au repos
                low A.2                                                        'led_defaut eteinte
            else if val_temps_mem>200 and barriere_stop=0 then    'STOP en alarme
                ;-> mode manuel : uniquement BP pour le Stop
            endif
        }
        loop until led_defaut=0

        val_temps_mem=0
      
        setint or %00000000,i_stop,B                'barriere STOP peut également arreter le chrono-horloge

        do {                                        '---------- attente du STOP
            if val_temps_mem=0 then
                hserout LCD,(254,128,"START.. ")        'affichage LCD 1ere ligne
            endif
            val_temps_mem=timer
            bintoascii val_temps_mem, b1,b2,b3,b4,b5        'decomposition ascii
            if b3<>aff_sec then
                gosub affichage_temps_chrono
                aff_sec=b3
            endif
        }
        loop until val_temps>0

        val_temps_mem=timer
        SETINTFLAGS OFF
        gosub chrono_arrete
J’analyserai l'impact sur sur la précision du chrono.
Je dois encore implémenter le repos de 5 sec. du Stop avant de repasser en mode automatique... analyse d'impact alors
Les améliorations sont les bienvenues ;)
 

BESQUEUT

Senior Member
Voici le code de la boucle STOP :
;================ Boucle du STOP
timer=0

val_temps=0 : val_temps_mem=0 : timer=0 'raz variables
Déjà dit : Timer=0 est une très mauvaise idée : on perd le délai depuis l'interruption jusqu'à cette réinitialisation inopportune.
Toute la précision du code donné en #118 est liée au fait que T1 et T2 sont pris en une seule instruction dans l'interruption :
interrupt:
Temps=Timer
return
Le chronométrage est la différence de ces deux temps et rien d'autre.
Si plus de chronométrages sont nécessaires, on peut utiliser des variables T3, T4,etc...
mais il faut rester sur ce principe...
do { '---------- blocage barriere STOP
if val_temps_mem=0 then
hserout LCD,(254,128,"Bloc. : ") 'affichage LCD 1ere ligne
else if val_temps_mem=100 then
low B.7 'buzzer OFF
endif
Lors de la première boucle val_temps_mem=0
donc le if est systématiquement vrai la première fois
donc on peut le mettre avant la boucle.
hserout LCD,(254,128,"Bloc. : ") 'affichage LCD 1ere ligne
do { '---------- blocage barriere STOP
if val_temps_mem=100 then
low B.7 'buzzer OFF
endif
 
Last edited:

PieM

Senior Member
Tout ça rien que pour une boucle stop !
je ne trouve pas comment surveiller une entrée spécifique afin de pouvoir l'utiliser dans un if ensuite ... la fonction pinsB
if pinB.x = 1 ....
- dans le case de l'interruption déterminer quelle sera la barrière de Stop
- quand le chrono est démarré, j'active l'interruption que sur le BP après 2 sec. et regarde ensuite si cette entrée est active ou non
- dès qu'elle est au repos : BP et barrières arrêtent le chrono via un changement d'interruption
Mais le choix de l'interruption se fait avant par un setint qui valide la bonne entrée start puis stop, ça a changé ?
Faut être clair:
on definit une config initiale : quelle est l'entrée départ, quelle est l'entree arrivée
sont alors définis les setint correspondants qui sont mis en oeuvre successivement lors des 2 interruptions.

Vous ne faites jamais d'organigramme de programmation ?
Quant à la répartition des tâches horloge - chrono, je ne comprends toujours pas qui fait quoi au bout de 160 posts!
Pour moi le chrono gère le start et le stop sur interruption en fonction de la configuration, mesure le temps entre les deux, puis le met à disposition pour l'affichage final. Une simple sortie active ou non le comptage lié à l'affichage
tout le reste est accessoire.
 
Last edited:

ddaweb

New Member
@BESQUEUT
Ne vous inquiétez pas, je n'ai absolument pas oublié le calcul du temps ;)
J'ai peut-être naïvement considéré que le fait de mettre le timer à 0 prenait un temps fixe, comme je devrai à 99% appliquer un coefficient de rectification, il était inclus. Alors c'est plus facile pour le code.
Dans le cas contraire, je vais faire en sorte d'applique ce calcul.

Bien vu pour la l'affichage unique.

@PieM
Non les interruptions n'ont pas changée de principe et toujours d'application.

Pour nous mettre sur la même longueur d'onde :
- Horloge ou chrono-horloge : c'est le picaxe qui fait le temps réel suivant le code que vous avez établi et qui fonctionne très bien
- Chrono ou chrono-complet : je vais dire que c'est l'interface de l'utilisateur, ou le chrono de départ ou ce que vous venez de nommer l'affichage final.
Dire qu'un simple start/stop est suffisant est illusoire vu qu'il y a différents modes et cas (déjà cf ci-dessous) ... mais j'ai simplifié le tout : si la led défaut s'allume, le stop ne se fait uniquement sur le BP, autrement barrière stop ou BP.
Pour le start c'est le même principe, si défaut allumé, il n'y a pas de start possible.

Concernant ma demande, elle ne concerne absolument pas l'horloge, mais c'est pour mettre le chrono en mode manuel (sans pouvoir arrêter le chrono avec la barrière stop : uniquement le BP) et si elle est de nouveau au repos durant 5 sec., repasse en mode automatique ... le cas d'une seule barrière qui tombe au start, le temps de la remettre en place sans arrêter le chrono.
Mais c'est bien durant la configuration de l'interruption que je déterminerai la barrière de stop pour l'utiliser dans la condition.

Non je n'ai pas fait d'organigramme (ce n'est pas ma tasse de thé), mais un schéma de base pour fonctionnement. Ce soir je fais un screen du programme en refermant les bouts de code des différentes boucle, vous aurez ainsi le schéma de base du fonctionnement.
 

BESQUEUT

Senior Member
J'ai une petite question : je ne trouve pas comment surveiller une entrée spécifique afin de pouvoir l'utiliser dans un if ensuite ... la fonction pinsB ?
J'avoue ne pas trop comprendre cette fonction.

Le but final est :
- dans le case de l'interruption déterminer quelle sera la barrière de Stop
- quand le chrono est démarré, j'active l'interruption que sur le BP après 2 sec. et regarde ensuite si cette entrée est active ou non
- dès qu'elle est au repos : BP et barrières arrêtent le chrono via un changement d'interruption

Je dois encore implémenter le repos de 5 sec. du Stop avant de repasser en mode automatique... analyse d'impact alors
Les améliorations sont les bienvenues ;)
On est sur ce que vous appelez le chrono et que j'appelle le Communiquant...
Comme dit par Piem, on ne fait rien lors du chronométrage, surtout pas dans l'interruption : tout doit être défini avant.

En raison des différentes sécurités, il est indispensable de clarifier les différentes phases du chronométrage :
- Mise en ordre de marche :
==> on attends que la ou les deux barrières soient en ordre de marche.
==> tant que ce n'est pas le cas, un témoin d'erreur est allumé

- Attente du start :
==> on boucle jusqu'au premier front de la première barrière, moment T1

- Chronométrage neutralisée :
==> pendant 2s, on ne prends en compte que le bouton start/stop. Les barrières sont neutralisées.
(Je ne comprends pas à quoi ça sert puisqu'on attends un front montant sur la deuxième barrière, même si la première est tombée, il ne se passera rien. S'il n'y a qu'une seule barrière et qu'elle est tombée, il faudrait la relever en moins de 2s, ce qui semble impossible...)

- attente du stop :
==> on boucle jusqu'au premier front de la deuxième barrière, moment T2

- fin de parcours et passage dit en "mode automatique"
==> tout est neutralisé pendant 5s
A priori utile. Par exemple si la deuxième barrière est tombée, il peut y avoir des start/stop intempestifs lorsqu'on la remet en ordre.

- Retour à la mise en ordre de marche.

Si j'ai raté quelque chose, merci d'expliquer...
 
Last edited:

BESQUEUT

Senior Member
J'ai peut-être naïvement considéré que le fait de mettre le timer à 0 prenait un temps fixe, comme je devrai à 99% appliquer un coefficient de rectification, il était inclus. Alors c'est plus facile pour le code.
Dans le cas contraire, je vais faire en sorte d'applique ce calcul.
Lorsque vous faites timer=0, vous "effacez" tout le temps écoulé entre T1 et la prise en compte de cet effacement.
Suivant les instructions concernées, et même la valeur des variables concernées la durée correspondante est éminemment variable.
Piem a donné la formule magique pour calculer Chrono=T2-T1+65535+1
Je ne vois pas comment faire plus "facile" ???
En tout cas, le fait de remettre Timer à zéro ne simplifie rien du tout...
 

ddaweb

New Member
Ou l'art de rendre les choses simples particulièrement obscures!
Bah ... c'est un peu subjectif, à chacun sa perception des choses ...
Vous êtes programmeur ?
Si oui, c'est de notoriété publique que les programmeurs et monsieur et madame tout le monde ne parlent pas souvent le même langage :LOL:
Ce n'est pas tant le terme qui compte, mais de se comprendre 😚
 

ddaweb

New Member
Déjà dit : Timer=0 est une très mauvaise idée : on perd le délai depuis l'interruption jusqu'à cette réinitialisation inopportune.
Un petit retour en arrière ... je parlais du communiquant ...
Il n'affiche que le temps en seconde, la précision, comme cela a été dit, n'est que facultatif, seul le temps final compte.
J'utilise à plusieurs endroits le timer avant le start, le remettre à 0 est plus facile.

Maintenant s'il est tout seul, c'est une autre histoire.

Pour votre description du fonctionnement, vous avez très bien compris, mit à part 2 détails :

- Attente du start : on regarde si le mode de fonctionnement ne change pas ou si appel mémoires -> suppression des interruptions et retour départ pour le changement de mode ou sous-programme pour appel mémoires

- mode_manuel_verification : il est vrai que 2 secondes ne sont pas nécessaire, une 1/2 sec. voir moins est suffisant ... mais là je regarde le stop et si en alarme, le mode manuel est activé (seul BP peut arrêter le communiquant), si le stop au repos durant 5 sec. consécutibe, le mode automatique (BP et Stop arrêtent le communiquant).

- fin de parcours et passage dit en "mode automatique" : juste une attente de +/- 5 sec avant le reset automatique -> permet de faire différente opérations comme : resynchroniser le système envoyer les temps au PC et afficheurs ...

Je vais regarder plus en profondeur ce WE ... doit retourner au déménagement 🥵
 

ddaweb

New Member
Je viens d'avoir une idée et qui simplifierais la partie chrono !

Si le communiquant active une sortie au start et l'arrête au stop :
- le chrono démarre par interruption sur le flanc montant de cette sortie
- le chrono arrête par interruption sur le flanc descendant de la même sortie

Toute la gestion se ferait via le communiquant qui réagit en fin de compte comme le chrono (même interruptions) ... quelques lignes de codes suffisent alors pour le chrono.

Vous en pensez quoi ?
 

PieM

Senior Member
Bah ... c'est un peu subjectif, à chacun sa perception des choses ...
Vous êtes programmeur ?
Non pas du tout, mais il est bon de définir des termes uniques et non ambigus pour décrire un système !
Ce n'est pas tant le terme qui compte, mais de se comprendre
Ben oui !!
Quant à votre dernière idée (où le chrono est ce que vous appeliez Horloge en #165 ?) d'utiliser un µC intermédiaire pour générer des interruptions sur le chrono, je pense que c'est un gag ?

- Attente du start : on regarde si le mode de fonctionnement ne change pas ou si appel mémoires -> suppression des interruptions et retour départ pour le changement de mode ou sous-programme pour appel mémoires
On attend l'interruption du start, en regardant ailleurs si rien ne se passe !?
Ce fil tourne un peu en rond maintenant... c'est lassant. Et je comprends pourquoi un organigramme n'est pas votre "tasse de thé", car votre logique ne semble pas compatible.
 
Last edited:

ddaweb

New Member
On attend l'interruption du start, en regardant ailleurs si rien ne se passe !?
Ce fil tourne un peu en rond maintenant... c'est lassant. Et je comprends pourquoi un organigramme n'est pas votre "tasse de thé", car votre logique ne semble pas compatible.
Tout a bien été dit plusieurs fois, mais voici mon schéma bloc de l'interface chrono refait au propre après tous les changements, j'espère ainsi que vous comprendrez l'ensemble et que cela fera avancer le schmilblick.
 

Attachments

ddaweb

New Member
Pour en revenir à la question de connaître l'état du STOP (dépendant du mode), c'est ici que cela se passe :

Etat_STOP.PNG
 

ddaweb

New Member
Je ne vous suit pas à 100% dans votre raisonnement, mais globalement c'est bien proche de mon idée.

Je vais vous mettre ma dernière programmation : cela vous permettra de voir le fonctionnement en détail et voir si j'ai commis des erreurs ... il y a +/- 130 lignes de moins grâce à vous ... je n'ai pas encore eu le temps de faire des tests approfondis afin de vérifier si une faille ou une incohérence serait encore présente, mais les tests préliminaires sont prometteurs. Ce WE j'ai eu un déménagement et aujourd'hui et toute la semaine travaux dans la maison ... durant ma réponse, je viens tout de même d'en trouvé une mineure : la led status ne s'éteint pas directement lors d'un défaut (après une pause)
Il y a beaucoup de commentaires pour celui qui devrait reprendre le projet après moi ... pour éviter le soucis avec le 1er chrono.
Il y a eu un tout petit changement dans le schéma bloc car j'avais oublié de remettre la vérification des barrières avec tous les changements depuis l'initialisation du projet ... encore à vérifier en proffondeur.
Je n'ai pas encore la lecture du i2c pour le temps définitif, ce n'est pas grand chose à implémenter, je l'initialise déjà !

J'ai fait en sorte que la led défaut s'allume à tout problème (barrière en alarme, changement de programmation des barrières, appel mémoires, barrière stop en alarme après le start).
La led status clignote si le chrono est 100% prêt (le juge peut donner le départ), s'allume quand le chrono est démarré et s'éteint au stop ou si un défaut.

Il faudra que le chronomètre suivent les mêmes phases du communiquant ... la led défaut peut être un repère.

Je vais encore devoir intégrer l'afficheur extérieur, mais je pense utiliser le même système que le communiquant (picaxe avec sont temps approximatif et affichage des sec. uniquement, au stop, temps via i2c et affichage jusqu'au start suivant).
Pour le PC, envoyer les 2 lignes après le stop, durant les 5 sec. pour la RAZ.

Voici mes remarques et questions :

Au NB1 - NB2 : tant que le chrono n'est pas démarré on peut le configurer à souhait, la led défaut est alors allumée pour signaler au juge que le chrono n'est pas prêt. J'annule alors l'interruption initialisée pour l'initialiser à la nouvelle valeur (idem pour l'appel mémoires).

1 Paramétrage :
- que voulez-vous dire par le délai ?
- témoin : oui c'est la led défaut, dans ma programmation, elle s'allume +/- 1/2 sec. si tout est OK
- action interrupteur : oui on peut modifier tant que le chrono n'est pas démarré, une fois démarré cela reste figé comme au moment du start ... mais il me semble que vous voulez mettre un délai pour le paramétrage ?

2 Mise en ordre de marche :
- il n'y a pas de délai, dès que c'est OK, le start peut être donné ...
Mais c'est vrai qu'après initialisation des interruptions, dans ma version, je surveille encore les bouton, si action sur un, interruption désactivée pour revenir au début.

3. Attente start :
- je vérifie le stop

4. Chronométrage neutralisé :
- interruption sur BP uniquement
- Buzzer +/- 1 sec.
- A la fin du délai, :
- si OK, la le défaut s'éteint et interruption sur BP et barrière stop
- si NOK, un bip buzzer après 1 sec durant 1/2 sec. + led défaut allumée et affichage "MANUEL" -> si 5 sec. au repos, retour en automatique avec interruption sur BP et barrière stop

5. Attente du stop :
- le témoin staus reste allumé jusqu'à l'arrêt du chrono : signale que le chrono est en fonction

6. Fin de parcours :
- buzzer +/- 1 sec suffit (1 sec c'est à peut près pause 2500)
- dès que le temps est disponible : faire les fifo des mémoires

Conclusion : si une modification est nécessaire ... pourquoi pas !!! Je ne suis pas arrêté à ma programmation actuelle
 

Attachments

Last edited:

PieM

Senior Member
;================ Boucle du START
setint or %00000000,i_start,B 'BP Start/Stop et barriere Start demarrent le chrono
timer=0 (tout a été dit sur l'inutilité de la mise à 0 du timer!)

do { '---------- attente du START
;---------- changement mode de fonctionnement ou appel memoires
if led_nbr<>choix_nbr or choix_sens<>led_sens or memoires_temps=0 then
SETINTFLAGS OFF 'suppresion de l'interruption
Vous activez une interruption, et allez voir s'il ne faut pas l'arrêter !?
ensuite vous remettez timer à 0 dans la boucle du stop ?!
Je me suis arrêté là ! Votre "logique" est déconcertante !
 

ddaweb

New Member
Ce n'est pas une logique, mais du pratique car la modification du mode fonctionnement doit se faire également ... je ne vais pas relancer à chaque fois le chrono pour le faire ... le point d'arrêt du programme sera toujours l'attente du start.
Si vous avez une bonne méthode pour faire cela, je l'ai déjà répété plusieurs fois : je suis ouvert à toute les améliorations, avec mes connaissances, je n'ai trouvé que cela !
J'ai comme l'impression que quoi que je face, c'est mauvais (ce l'est probablement partiellement), mais je ne vous voit pas proposer d'autres solutions plus logique ou plus pertinente ... c'est bien dommage car serait éducatif pour moi.

Comme vous l'avez certainement vu, @BESQUEUT semble plancher sur le cahier des charges.

NB : oui le timer=0 n'est pas ce que vous avec écris pour l'horloge, ici on parle du communiquant et comme vous l'avez dit plusieurs fois, le temps intermédiaire à l'affichage LCD n'est pas primordial, seul le temps final est important ... je n'affiche que le temps / seconde, ce timer=0 n'aura aucune incidence.
 

BESQUEUT

Senior Member
le point d'arrêt du programme sera toujours l'attente du start.
J'ai beaucoup de commentaires à faire sur vos remarques, mais ce point est effectivement important et voici rpidement mon avis :
Pou moi, il y a trois phases bien distinctes :
1) Le paramétrage et la lecture des temps précédents,
2) La mise en ordre de marche (qui peut être instantanée si les deux barrières sont libres)
3) Attente du start

Pour moi, seule la première permet de modifier les réglages. Après, c'est trop tard. C'est pour ça que ce serait bien d'avoir une LED pour signaler que les modifications sont encore possibles.
La fin de la phase 1 peut être soit due à une temporisation, après quoi on passe automatiquement en Phase 2,
soit liée à un interrupteur (on est en modification tant que l'on ne décide pas de passer à la suite,
soit un bouton poussoir qui permet de faire les deux (passer immédiatement à la suite, ou attendre la fin de la temporisation).

Chaque phase a ses propres conditions pour passer à la phase suivante. je ne comprends pas ce que vous appelez un "point d'arrêt".
 

PieM

Senior Member
Je ne pense pas que vous ayez bien compris le principe des interruptions! elles n'attendent pas; elles sont actives dès le setint.
Et je ne vois toujours pas l'intérêt d'utiliser une interruption avec le µC communiquant.

concernant cette partie:
;================ verification barriere en alarme
if mode_chrono=11 and barriere1=0 then
pause 500
hserout LCD,(254,128,"Verif barriere 1") 'affichage LCD 1ere ligne
pause 3000
goto chrono
else if mode_chrono=22 and barriere2=0 then
pause 500
hserout LCD,(254,128,"Verif barriere 2") 'affichage LCD 1ere ligne
pause 3000
goto chrono
else if mode_chrono=12 or mode_chrono=21 then
if barriere1=0 or barriere2=0 then
pause 500
if barriere1=0 and barriere2=0 then
hserout LCD,(254,128,"Verif barrieres ") 'affichage LCD 1ere ligne
else if barriere1=0 then
hserout LCD,(254,128,"Verif barriere 1") 'affichage LCD 1ere ligne
else if barriere2=0 then
hserout LCD,(254,128,"Verif barriere 2") 'affichage LCD 1ere ligne
endif
pause 3000
goto chrono
endif
endif
ça peut s'ecrire plus simplement avec:
Rich (BB code):
if mode_chrono<>22 and barriere1=0 then
                  pause 500
                  hserout LCD,(254,128,"Verif barriere 1")        'affichage LCD 1ere ligne
endif
if mode_chrono<>11 and barriere2=0 then
                  pause 500
                  hserout LCD,(254,128,"Verif barriere 2")        'affichage LCD 1ere ligne
endif
 

ddaweb

New Member
@BESQUEUT

Sur le fond, je comprends très bien cette méthodologie, mais dans la pratique, dès que vous serez dans l'attente du start (et donc du flanc descendant de l'interruption) on ne sait plus rien faire mis à part démarrer le chrono ... c'est ce que j'appelle le point d'arrêt.

On sera alors obligé de faire le cycle start et ensuite stop pour apporter une modification du mode de fonctionnement (ou facultativement un appel mémoires) ... un peu fastidieux, surtout dans la phase de montage, après, il sera assez rare de changer de mode jusqu'à la prochaine classe ... là aussi on y arrivera avant de faire les tests de la bonne configuration.
Je n'ai jamais un seul appareils qui travaille de la sorte : soit c'est configurable directement, soit via un menus spécifique ... mais pas devoir absolument passer par le cycle complet de fonctionnement ... c'est également mon idée !
Maintenant pour un appareil non configurable, je suis 100% d'accord avec vous
 

BESQUEUT

Senior Member
dès que vous serez dans l'attente du start (et donc du flanc descendant de l'interruption) on ne sait plus rien faire mis à part démarrer le chrono ... c'est ce que j'appelle le point d'arrêt.
Euh ??? Si on est bien dans un système où les barrières libres sont au niveau bas, l'interruption concerne exclusivement le front montant.
Comme la durée de l'impulsion n'est pas connue, voire infinie si la barrière est tombée, un chronométrage sur un front descendant serait totalement aléatoire...
On sera alors obligé de faire le cycle start et ensuite stop pour apporter une modification du mode de fonctionnement (ou facultativement un appel mémoires) ... un peu fastidieux, surtout dans la phase de montage, après, il sera assez rare de changer de mode jusqu'à la prochaine classe ... là aussi on y arrivera avant de faire les tests de la bonne configuration.
Je n'ai jamais un seul appareils qui travaille de la sorte : soit c'est configurable directement, soit via un menus spécifique ... mais pas devoir absolument passer par le cycle complet de fonctionnement ... c'est également mon idée !
Maintenant pour un appareil non configurable, je suis 100% d'accord avec vous
Dans ce cas, autant considérer qu'on peut revenir au mode paramétrage à tous moments. Un bouton dédié serait le bienvenu.
Dans ce cas, les boucles seraient du type :
DO
LOOP UNTIL Temps>0 or PARAM=Vrai

Nouvelle version du CCTP en annexe.
On constate que le cœur du problème n'est pas seulement le chronométrage mais la prise en compte du paramétrage et des incidents pouvant survenir à tout moment.
 

Attachments

Last edited:

ddaweb

New Member
Euh ??? Si on est bien dans un système où les barrières libres sont au niveau bas, l'interruption concerne exclusivement le front montant.
Comme la durée de l'impulsion n'est pas connue, voire infinie si la barrière est tombée, un chronométrage sur un front descendant serait totalement aléatoire...
Non toutes les entrée sont à l'état haut au repos et descendent en alarme ;) ... donc flanc descendant pour les interruptions !

Je vais regarder le CCTP attentivement ... quelques indications :
- Led défaut et non led alarme (vous parlez des 2 ?)
- Je suis un peu short en pins sur le picaxe pour en ajouter 2 pour le mode programmation (BP + led).
- L'afficheur extérieur sera autonome, avec son picaxe ... mais pas en projet de développement pour l'instant, je vais juste prévoir que le communiquant puisse le piloter sur 3 fils max (dont le 0v et le TX). Du style un top start et l'afficheur affiche son temps toutes les secondes, l'envoi du temps final et affiche alors le temps réel complet.

Par contre, pouvez-vous me donner une explication de ne pas surveiller la programmation et appel mémoire durant la boucle d'attente du start.
Je peux facilement concevoir ceci :
- ce n'est peut-être pas 100% logique : mais si facile pour l'utilisateur (et la programmation)
- il y a des pertes de temps à la lecture de cette ligne : comme je n'affiche que les secondes et que le temps max ne dépassera jamais les 3 min., ce sera imperceptible -> le temps final vient de toute façon du chronomètre
- il pourrait avoir une zone d'ombre si un chien passe au moment de la modification ? ou alors l'interruption est prioritaire et c'est dommmage : pas de modification et le chrono démarre !
Il y a-t-il quelque chose que je ne perçois pas ?

Je penses réellement que parfois il faut pouvoir faire un compromis entre la logique et le pratique ... des problèmes structurels, c'est évidemment prioritaire sur le pratique !
 

BESQUEUT

Senior Member
Non toutes les entrée sont à l'état haut au repos et descendent en alarme ;) ... donc flanc descendant pour les interruptions !
OK pour ça : à corriger dans le CCTP...
Je vais regarder le CCTP attentivement ... quelques indications :
- Led défaut et non led alarme (vous parlez des 2 ?)
- Je suis un peu short en pins sur le picaxe pour en ajouter 2 pour le mode programmation (BP + led).
Oui : 2 corrections à faire au §4.2.
Pour l'utilisation des pins, vous avez un plan ou il faut chercher dans les définitions ?
Pour le bouton, on peut se contenter du bouton MEMOIRES a condition de se mettre d'accord sur le façon de sortir du mode PARAMETRAGE.

Si vraiment impossible de brancher une LED dédiée au PARAMETRAGE, on pourrait utiliser la LED DEFAUT comme vous le suggérez. Dans ce cas, il faudrait un clignottement spécial pour distinguer cette phase des autres problèmes : par exemple 2 flashs espacés d'une seconde...
On alors, on allume alternativement les LEDs STATUS et DEFAUT...
- L'afficheur extérieur sera autonome, avec son picaxe ... mais pas en projet de développement pour l'instant, je vais juste prévoir que le communiquant puisse le piloter sur 3 fils max (dont le 0v et le TX). Du style un top start et l'afficheur affiche son temps toutes les secondes, l'envoi du temps final et affiche alors le temps réel complet.
0V et TXD, ça fait deux. C'est quoi le N°3 ?
Par contre, pouvez-vous me donner une explication de ne pas surveiller la programmation et appel mémoire durant la boucle d'attente du start.
Je peux facilement concevoir ceci :
- ce n'est peut-être pas 100% logique : mais si facile pour l'utilisateur (et la programmation)
Rien compris ... C'est quoi pour vous la programmation ?
L'appel mémoire, c'est le bouton "PARAMETRAGE" ? Si oui, c'est bien écrit dans le CCTP V2.
- il y a des pertes de temps à la lecture de cette ligne : comme je n'affiche que les secondes et que le temps max ne dépassera jamais les 3 min., ce sera imperceptible -> le temps final vient de toute façon du chronomètre
- il pourrait avoir une zone d'ombre si un chien passe au moment de la modification ? ou alors l'interruption est prioritaire et c'est dommmage : pas de modification et le chrono démarre !
Il y a-t-il quelque chose que je ne perçois pas ?
idem pour moi...De quelle phase parlez vous ? De quelle ligne parlez vous ?
"Au moment de la modification" de quoi parlez vous ?
Je penses réellement que parfois il faut pouvoir faire un compromis entre la logique et le pratique ... des problèmes structurels, c'est évidemment prioritaire sur le pratique !
Malheureusement les microcontrôleurs (dont les Picaxes) ne fonctionnent pas en logique floue.
S'il y a un IF THEN alors il faut se préoccuper du ELSE...
Et si vous imbriquez 3 tests, il y a 8 cas à traiter...
D'où la nécessité absolue de lister tous les cas de figure avant d'écrire la première ligne de code (hors POC évidement...)
 
Last edited:

ddaweb

New Member
0V et TXD, ça fait deux. C'est quoi le N°3 ?
Je dispose de 3 pins sur le boitier, 2 sont attribuée, la 3me est utilisable pour un autre signal ... au départ je pensais une sortie sur le communiquant qui s'active pendant le chronométrage ... mais le TX peut le faire également.
Pour l'utilisation des pins, vous avez un plan ou il faut chercher dans les définitions ?
La définition possède les séries pour l'afficheur extérieur et le PC si c'est bien le communiquant qui s'en occupe.
J'ai un plan également avec Qelectro, mais il date un peu sans avoir vraiment bougé (je l'ai fait lors du début de mon projet).
J'ai prévu un adressage au cas où il y aurait plusieurs communiquant sur une même plaine avec des barrières sans fils ... dans mon cas, je ne l'utilise pas (pour l'instant).
Si vraiment impossible de brancher une LED dédiée au PARAMETRAGE, on pourrait utiliser la LED DEFAUT comme vous le suggérez. Dans ce cas, il faudrait un clignottement spécial pour distinguer cette phase des autres problèmes : par exemple 2 flashs espacés d'une seconde...
On alors, on allume alternativement les LEDs STATUS et DEFAUT...
J'avais pris par habitude d'allumer systématiquement la led défaut quant le communiquant n'était pas prêt pour le chronométrage ou dans une phase de contrôle : c'est de cela que je parlais comme référence pour l'horloge -> allumée, rien doit se passer côté interruption de l'horloge.
La led status pour signaler l'état du communiquant aux juges : le départ que si elle clignote, allumée le chrono a bien démarré (bien décrit dans le CCTP).
Par contre, pouvez-vous me donner une explication de ne pas surveiller la programmation et appel mémoire durant la boucle d'attente du start.
Je peux facilement concevoir ceci :
- ce n'est peut-être pas 100% logique : mais si facile pour l'utilisateur (et la programmation)
- il y a des pertes de temps à la lecture de cette ligne : comme je n'affiche que les secondes et que le temps max ne dépassera jamais les 3 min., ce sera imperceptible -> le temps final vient de toute façon du chronomètre
- il pourrait avoir une zone d'ombre si un chien passe au moment de la modification ? ou alors l'interruption est prioritaire et c'est dommmage : pas de modification et le chrono démarre !
Il y a-t-il quelque chose que je ne perçois pas ?
Je parle de ce bout de code :
Code:
        ;================ Boucle du START
        setint or %00000000,i_start,B                'BP Start/Stop et barriere Start demarrent le chrono
        timer=0

        do {                                    '---------- attente du START
            ;---------- changement mode de fonctionnement ou appel memoires
            if led_nbr<>choix_nbr or choix_sens<>led_sens or memoires_temps=0 then
                SETINTFLAGS OFF                'suppresion de l'interruption
                low A.0                    'led_status eteinte
                goto chrono                 'reinitialisation du chrono
            endif
            ;---------- verification barriere STOP en alarme
            if mode_chrono=12 and barriere2=0 then
                SETINTFLAGS OFF                    'suppresion de l'interruption
                high A.1                        'led_defaut allumee
                low A.0                        'led_status eteinte
                pause 500
                hserout LCD,(254,128,"Verif barriere 2")    'affichage LCD 1ere ligne
                pause 3000
                goto chrono
            else if mode_chrono=21 and barriere1=0 then
                SETINTFLAGS OFF                    'suppresion de l'interruption
                high A.1                        'led_defaut allumee
                low A.0                        'led_status eteinte
                pause 500
                hserout LCD,(254,128,"Verif barriere 1")    'affichage LCD 1ere ligne
                pause 3000
                goto chrono
            else
                low A.1                            'led_defaut eteinte
            endif
            ;---------- clignotement led_status
            val_temps_mem=timer
            if val_temps_mem<=100 then
                high A.0
            else if val_temps_mem>100 and val_temps_mem<=200 then
                low A.0
            else
                timer=0
            endif
        }
        loop until val_temps>0
J'ai mit toute la programmation du communiquant, si vous faites une petite analyse de celui-ci, la compréhension serait plus aisée.
Je dois certainement avoir fait quelques erreurs ou compliqué certaines choses (quid la remarque de PieM sur la vérification des barrières).
Ma programmation est vraiment ce que j'espère arriver à faire ... mais j'ai des difficultés à le coucher en texte ... + les problèmes des noms donnés à chaque composantes (communiquant et chrono) qui a un peu foutu le bord..

J'avoue que pour l'instant j'ai l'impression de tourner en round avec les question - réponses- requestion - etc ... parfois quelques postes après, on revient à ce que j'ai déjà répondu ... j'en arrive à un début de découragement.

Ce qui manque encore :
- c'est aller chercher le temps dans le chrono via i2c, mais comme je n'ai pas encore cette partie, j'affiche provisoirement le temps du communiquant
- l'afficheur extérieur
- le PC

Je suis persuadé qu'il y a une incompréhension entre ce que vous et PieM dites et ce que je comprend ... souvent je ne saisi pas où vous voulez aller : les choses que j'ai su décrypter ont été très pertinentes et efficaces.
La grande différence entre vous 2 et moi est que je suis un junior et vous des seniors ... pas vraiment facile pour moi de comprendre tout de suite ce que vous dites ou voulez me faire comprendre ...
 
Last edited:

ddaweb

New Member
Je ne pense pas que vous ayez bien compris le principe des interruptions! elles n'attendent pas; elles sont actives dès le setint.
Et je ne vois toujours pas l'intérêt d'utiliser une interruption avec le µC communiquant.
Je ne sais pas si j'ai bien compris le principe des interruptions, mais ce que j'ai compris :
On configure le système pour réagir un évènements spécifique, quel que soit l'endroit où on se trouve dans la lecture du code : dans notre cas, sur un flanc descendant de soit le BP, ou soit le BP ou une barrière dans le do - loop until val_temps>0.
Il va alors se rendre dans la partie interupt: pour lire le code s'y trouvant et l'appliquer : donc mettre val_temps à la valeur timer et alors sortir de la boucle vu que val_temps est >0.
Dans le cas du communiquant, vous la remplaceriez par quoi ? Un if ?
 

ddaweb

New Member
Malheureusement les microcontrôleurs (dont les Picaxes) ne fonctionnent pas en logique floue.
S'il y a un IF THEN alors il faut se préoccuper du ELSE...
Et si vous imbriquez 3 tests, il y a 8 cas à traiter...
D'où la nécessité absolue de lister tous les cas de figure avant d'écrire la première ligne de code (hors POC évidement...)
Heuuuuu, un if doit être suivit d'un else, il ne peut pas être seul ?
J'avoue ne pas comprendre votre remarque.

Dans le cas d'un if - else ou if - else if - else, j'essaie que le if soit la condition la plus utilisée ... les suivants dans l'ordre de fréquence d'utilisation si cela est d'application ou possible. En PHP c'est vivement conseillé pour la rapidité d'exécution.
Dans la mesure du possible, j'essaie d'éviter les conditions imbriquée, pour la même raison que ci-dessus.
Pour le µc, cela ne doit pas être différent qu'en PHP.
 

BESQUEUT

Senior Member
ça peut s'ecrire plus simplement avec:
Il me semble qu'il manque le cas :
hserout LCD,(254,128,"Verif barrieres ")
Mais peu importe, le principe reste le même.

On peut aussi définir dès la configuration les variables qui vont bien et écrire :
Code:
if Barr2=0 then
                  pause 500
                  hserout LCD,(254,128,"Verif barriere ",BarNo)        'affichage LCD 1ere ligne
endif
Par contre, pas compris l'intérêt de la pause ?
 

ddaweb

New Member
Code:
if Barr2=0 then
                  pause 500
                  hserout LCD,(254,128,"Verif barriere ",BarNo)        'affichage LCD 1ere ligne
endif
Par contre, pas compris l'intérêt de la pause ?
Avec le goto chrono, il affiche le mode durant la durée de la pause et ensuite la vérification durant la 2me pause ... en boucle tant que le problème est persistant.
Aucune autre raison, juste du cosmétique d'affichage

Au fait, pourquoi ne pas faire un if - else if pour le code de PieM ?
Pour simplifier jusqu'au bout : Verif barriere(s) ... moins parlant peut-être
 
Last edited:

BESQUEUT

Senior Member
Heuuuuu, un if doit être suivit d'un else, il ne peut pas être seul ?
J'avoue ne pas comprendre votre remarque.

Dans le cas d'un if - else ou if - else if - else, j'essaie que le if soit la condition la plus utilisée ... les suivants dans l'ordre de fréquence d'utilisation si cela est d'application ou possible. En PHP c'est vivement conseillé pour la rapidité d'exécution.
Dans la mesure du possible, j'essaie d'éviter les conditions imbriquée, pour la même raison que ci-dessus.
Pour le µc, cela ne doit pas être différent qu'en PHP.
La remarque vaut au niveau conceptuel, pas au niveau du code.
Si vous envisagez une possibilité (un test) vous devez envisager aussi ce qui se passe dans l'autre cas. Peut -être qu'il n'y a rien à faire, et donc pas de code, mais peut être aussi que ça correspond à un cas inhabituel voire à un défaut, auquel cas il y a sans doute des actions...

Si vous imbriquez trois tests, vous avez 8 possibilités. Si seules 2 donnent des actions, alors on doit pouvoir écrire le test sous la forme
IF (test...) THEN ... ELSE ... ENDIF
 

BESQUEUT

Senior Member
Dans le cas du communiquant, vous la remplaceriez par quoi ? Un if ?
PieM ne dit pas qu'il ne faut pas le faire... mais n'en voit pas l'intérêt....
Pour moi l'intérêt est d'avoir deux Picaxes quasiment identiques et qui donc réagissent de la même façon puisqu'ils ont les mêmes entrées.
La maintenance en sera d'autant plus facile.
Accessoirement, vu vos tests, je ne serais pas surpris que le Communiquant programmé de cette façon, donne des résultats finalement pas si mauvais que ça. (Impossible à prouver pour le moment, ce sera la surprise)
Certes les interruptions ne sont prises en compte qu'entre deux instructions. Il faut donc éviter les instructions les plus longues.
Un sertxd est long si le texte envoyé est lui même long. Mais on peut faire la même chose en deux fois, ce qui prends plus de code et plus de temps, mais permet de prendre en compte plus vite l'interruption.
Il faudrait aussi tester (et au besoin remplacer) certains GOSUB, réputés longs sur un Picaxe...

J'avais pris par habitude d'allumer systématiquement la led défaut quant le communiquant n'était pas prêt pour le chronométrage ou dans une phase de contrôle : c'est de cela que je parlais comme référence pour l'horloge -> allumée, rien doit se passer côté interruption de l'horloge.
Comme déjà dit, l'interruption ne fait que mettre à jour la variable Temps.
Ainsi il y a très peu de décalage entre le front descendant et sa prise en compte :
- fin de l'instruction en cours dans le programme principal (donc éviter les instructions trop longues),
- temps de copie de la variable Timer vers la variable Temps

Toutes les instructions qui suivent pour copier vers T1 ou T2, puis pour test et affichage n'ont aucune influence sur la qualité du chronométrage.
Si on n'est pas dans une boucle qui prends en charge la variable Temps, alors elle n'est pas prise en compte et pis c'est tout...
Autrement dit, Chaque Picaxe peut continuer tranquillement à mettre à jour la variable Temps à chaque front descendant, peu importe que ça serve à quelque chose ou pas.
Autrement dit, il n'y a aucun intérêt à désactiver les interruptions.

Je comprends votre frustration parce que je sais que les débutants veulent avant tout écrire du code.
C'est pourtant une perte de temps considérable.
Une fois le POC réalisé, la prise en compte des différents cas de figure est une formalité, à conditions que ces cas soient exhaustivement listés.
Par exemple, au final, y a-t-il une LED et/ou un bouton dédiés au PARAMETRAGE ? J'ai cru comprendre qu'il reste quelques pins libres.
Sinon, comment signaler que l'on est en mode paramétrage ? Comment met-on fin au paramétrage ?
A ma connaissance ça n'a pas été précisé.

Durant la phase de "Mise en ordre de marche" on attends que la ou les barrières concernées soient libres.
Donc quand on commence à attendre le START, on n'a aucune raison de tester à nouveau si tout va bien :
- soit la barrière de départ est occultée et justement c'est un START valable,
- soit il y a une seule barrière et elle est occultée, et donc on a aussi un START valable,
- soit la seconde barrière est occultée et il me semble qu'on se laisse la possibilité de relever la barrière (test toutes les 5 secondes) ou de passer en mode manuel.

Donc, il n'y a aucune raison d'abandonner cette phase. On attends tranquillement le START (ou le retour en mode PARAMETRAGE) et on passe à la phase suivante qui va gérer les éventuels problèmes.
 
Last edited:

ddaweb

New Member
La remarque vaut au niveau conceptuel, pas au niveau du code.
Si vous envisagez une possibilité (un test) vous devez envisager aussi ce qui se passe dans l'autre cas. Peut -être qu'il n'y a rien à faire, et donc pas de code, mais peut être aussi que ça correspond à un cas inhabituel voire à un défaut, auquel cas il y a sans doute des actions...
Hummmmm oui, c'est très pertinent.
Surtout qu'à l'endroit du code, les 2 barrières seront majoritairement au repos , les seuls moments où ce n'est pas le cas :
- une barrières est tombée ou a été heurtée
- lors des mises en place du chrono et tout n'est pas encore OK

Ceci serait peut-être mieux ?
Code:
do
    ;test de quelle barrière (s) pour affichage
loop until barriere1=1 and barriere2=1
 

BESQUEUT

Senior Member
Nouvelle version du CCTP :

et en prime un bout de code pour remplacer les A.x par des variables plus explicites :
Rich (BB code):
#picaxe 28X2
#no_data
symbol led_status=A.0
symbol led_sens=A.2
symbol led_nbr=A.3

symbol PIN_status=pinA.0
symbol PIN_sens=pinA.2
symbol PIN_nbr=pinA.3

symbol OUT_sens=outpinA.2

Symbol Allumee=1 ' on peut aussi définir Vert, Jaune, Rouge...
symbol Eteinte=0

high led_sens     ' ne pas supprimer : sert à initialiser la pin...
do
      low led_status
      pause 200

      high led_status
      pause 1000
     
      toggle led_nbr
      if PIN_nbr=Allumee then
            OUT_sens=Eteinte
      else
            OUT_sens=Allumee
      endif
loop
 

Attachments

BESQUEUT

Senior Member
Code:
do
loop until barriere1=1 and barriere2=1
Oui ça semble bien pour la phase de Mise en ordre de marche.
Suivant le CDC, il faudrait aussi tester le bouton PARAMETRAGE
Mais attention aux expressions du genre :
barriere1=1 AND barriere2=1 OR PARAMETRAGE=1
A priori le AND est effectué avant le OR mais il faut être sur...
Le code
Code:
for b1=0 to 1
for b2=0 to 1
for b3=0 to 1
b4=b1 AND B2 OR b3
sertxd (#B1," AND ",#b2, " OR " ,#b3,"=", #b4,13,10)
next b3
next b2
next b1
donne :
Code:
0 AND 0 OR 0=0
0 AND 0 OR 1=1
0 AND 1 OR 0=0
0 AND 1 OR 1=1
1 AND 0 OR 0=0
1 AND 0 OR 1=1
1 AND 1 OR 0=1
1 AND 1 OR 1=1
Ça semble bon...

Toujours pour respecter le CDC, il serait bon de définir :
Symbol Libre=1
Symbol Occultee=0

de façon à pouvoir écrire :
IF Barriere1=Occultee THEN
ou bien :
DO
LOOP UNTIL Barriere1=Libre AND Barriere2=Libre

ce qui évite toute confusion, et permet de prendre en compte des barrières de polarité inversée le moment venu...

Et pour faire bonne mesure :
Symbol Demande=1
ce qui permet d'écrire :

DO
LOOP UNTIL Barriere1=Libre AND Barriere2=Libre OR Parametrage=Demande

Notez également que ce genre de symbol ne prends rien en code et évite des commentaires fastidieux.
 
Last edited:

BESQUEUT

Senior Member
Proposition pour une autre ergonomie (avec les mêmes éléments matériels) :
- une prise jaune pour une barrière
- une prise rouge pour l'autre barrière
- une LED jaune ou rouge : Barrière de départ
- une LED jaune ou rouge : Barrière d'arrivée
- un inter pour le choix de la barrière de départ,
- un inter pour le choix de la barrière d'arrivée.

Les LEDs sont allumées en fixe de la couleur correspondant à la prise, et restent de cette couleur tant qu'elles sont libres.
Lorsqu'une barrière est occultée, elle clignote rapidement (avec prédominance de la bonne couleur).
Du coup plus besoin du LCD : la LED DEFAUT suffit a indiquer qu'au moins une barrière est occultée de façon anormale.
Pour savoir laquelle ou lesquelles, il suffit de regarder les LEDs.
 

ddaweb

New Member
@BESQUEUT
Je viens de mettre en application votre bonne suggestion des noms de variables au lieu des pins du picaxe et supprimé des commentaires (vos noms ne me parlaient pas) :
Code:
; --------------- Variables : fonctionnalites
symbol repos=1            'barriere ou BP au repos
symbol active=0            'barriere coupee
symbol enfonce=0        'BP enfonce -> pour memoires ou START/STOP
J'ai encore réussi à diminuer mon code de +/- 30 lignes, sans vraiment altérer les affichages et pas du tout le fonctionnement.
Par exemple la vérification des barrières :
Code:
        ;================ verification barriere en alarme -> affichage 2me ligne
        do {                                        '---------- verification barriere(s) -> affichage 2me ligne
            if barriere1=active and barriere2=active then
                hserout LCD,(254,192,"VERIF BARRIERES ")
            else if barriere1=active then
                hserout LCD,(254,192,"VERIF BARRIERE 1")
            else if barriere2=active then
                hserout LCD,(254,192,"VERIF BARRIERE 2")
            endif
            }
        loop while barriere1=active or barriere2=active
J'ai bien réfléchi à votre proposition de faire un mode de programmation, je ne vais pas aller dans cette direction malheureusement (n'investissez donc pas de temps là dedans), mais je vous remercie de votre implication dans mon projet (ainsi que PieM) ... c'est super, et m'a beaucoup aidé à améliorer mon code et la vitesse du communiquant.
Je me doute d'avoir des réactions négative avec ma décision, mais cela ne nous empêche pas de continuer dans la direction que je souhaite : optimiser au max. le code du communiquant et mettre au point l'horloge.

Pourquoi cette solution ne m'agrée pas :
1. Elle n'est pas convivial pour l'utilisateur ... je pourrais, avec un très gros effort, encore y faire abstraction.
2. Vous allez devoir gérer ce bouton (+led) et une adaptation du boitier sera nécessaire ... cela est déjà plus compliqué sans devoir en refaire un nouveau.
Cette gestion ne revient-elle pas au même que moi surveiller la modification des interrupteurs des barrières (1 seule condition) ?
3. Ce n'est pas le communiquant qui déterminera le temps final ... enfin, je vais toutefois prévoir que si l'horloge ne fonctionne pas, c'est ce temps qui sera le bon, qui est certainement meilleur que le chrono manuel (un affichage sera nécessaire).
4. Enfin, la dernière version de ma programmation est exactement ce que je voulais faire en me lançant dans ce projet ... le compromis que je fais dans le code est compensé par l'horloge.
 

BESQUEUT

Senior Member
Code:
        ;================ verification barriere en alarme -> affichage 2me ligne
        do {                                        '---------- verification barriere(s) -> affichage 2me ligne
            if barriere1=active and barriere2=active then
                hserout LCD,(254,192,"VERIF BARRIERES ")
            else if barriere1=active then
                hserout LCD,(254,192,"VERIF BARRIERE 1")
            else if barriere2=active then
                hserout LCD,(254,192,"VERIF BARRIERE 2")
            endif
            }
        loop while barriere1=active or barriere2=active
Avec ce code, vous ne pouvez pas utiliser une seule barrière sans que les deux soient en ordre de marche.
Il va falloir mettre en ordre de marche la barrière inutile avant de pouvoir continuer.

Super convivial...,

A noter que le terme "active" prête à confusion. Pour moi, il peut y a avoir une ou deux barrières actives, chacune pouvant être libre ou occultée. Mais vous êtes probablement un adepte de l'horloge normande...
 
Last edited:

ddaweb

New Member
En fait, cela remplace le code du #180 et se situe au démarrage du chrono où toutes les barrières sont vérifiées, donc bien avant la boucle pour le start.

Le trou normand je connaissais, mais l'horloge normande ??? ... expression française ?
 

BESQUEUT

Senior Member
En fait, cela remplace le code du #180 et se situe au démarrage du chrono où toutes les barrières sont vérifiées, donc bien avant la boucle pour le start.
Ben ça n'empêche que pour en sortir il faut mettre en oeuvre une barrière qui ne sert à rien...

En fait, il y a confusion entre Barrière1 et Barrière2 qui sont des objets Physiques
et BarriereSTART, BarriereSTOP qui sont des concepts logiques.

Si on ne gère pas ça physiquement avec des interrupteurs, il faut écrire du code pour savoir si l'une ou l'autre, voire les deux barrières logiques sont occultées. Votre code #180 semble le faire et PieM a simplifié mais en restant au niveau physique...
Ca peut aussi s'écrire en 2 lignes en utilisant des masques sur les bits...

Du coup, il faut voir quelle ergonomie donner au message : vérifier Barriere1 ou Vérifier Barrière START
ce qui n'est pas la même chose...

Le trou normand je connaissais, mais l'horloge normande ??? ... expression française ?
C'est simple : quand la petite aiguille est sur le 3 et que la grande est sur le 7, alors il est 10h moins quart.

Il n'y a rien à comprendre : il suffit de le savoir, comme tous ceux qui sont nés là...
 
Last edited:

BESQUEUT

Senior Member
Illustration de l'utilisation des masques...
ATTENTION : non testé, c'est juste pour expliquer le principe...
Code:
' Au niveau Physique on a :
'symbol barriere1=pinB.0
'symbol barriere2=pinB.1

symbol Barrieres=pinsB



' Définissons les variables logiques suivantes :
symbol B_START=bxx
symbol B_STOP=bxx
symbol B_ALL=bxx
symbol Defaut=bxx

' Maintenant, dans la phse de CONFIGURATION, on peut renseigner ces variables en fonction de l'ergonomie prévue :

' Si ergonomie "SENS+NOMBRE"
'----------------------------

symbol choix_sens=pinB.3    'Pin B.3 (In)  : Sens des barrires : 1 = barrierre1 -> barriere2 - 0 = barriere2 -> barriere1
symbol choix_nbr=pinB.4
symbol Une=0
symbol Deux=1
symbol UneVersDeux=1
symbol DeuxversUne=0


if choix_nbr=Une then
    if choix_sens=Une then
        B_START=%00000001
        B_STOP =%00000001
        B_ALL  =%00000001
    else
        B_START=%00000010
        B_STOP =%00000010
        B_ALL  =%00000010
    endif

else
    if choix_sens=UneVersDeux then
        B_START=%00000001
        B_STOP =%00000010
        B_ALL  =%00000011
    else
        B_START=%00000010
        B_STOP =%00000001
        B_ALL  =%00000011
    endif
endif



' Si ergonomie "START+STOP"
'----------------------------

symbol choix_START=pinB.3
symbol choix_STOP=pinB.4

B_START=choix_START+1
B_STOP =choix_STOP+1
B_ALL  =B_START OR B_STOP



'Dans tous les cas, le test devient :
'-------------------------------------

DO
    defaut=B_ALL NAND Barrieres
    if defaut=%11 then
        "Vérifier les Barrieres"
    else
        "Vérifier Barriere " , #Defaut
    endif

LOOP UNTIL Defaut=0




' Si on a besoin de tester une seule barrière, on peut faire :
-------------------------------------------------------------
if B_START AND Barrieres >0 then...

' Mais pas vu l'utilité pour le moment, et donc B_START et B_STOP ne servent à rien...
Remarquez que dans ce cas, on ne reste bloqué que si la ou les barrières configurées pour être utilisées sont occultées.
Mais votre cahier des charges demandait à pouvoir revenir au paramétrage sans forcément rendre conforme ce qui a été paramétré. Dans ce cas, il faut un bouton pour demander à revenir au paramétrage. Si un bouton dédié n'est pas possible, J'ai déjà dit qu'on peut utiliser le bouton "MEMOIRES" qui du coup deviendrait "MEM+CONFIG".

La boucle devient alors :
DO
...
if MEM_CONF=Enfonce then Defaut=4
LOOP UNTIL Defaut=0

Ça permet de sortir de la boucle, mais il faut encore se taper toutes les autres boucles pour revenir au Parametrage.

Si on veut éviter ça, je ne vois pas d'autre solution qu'une state machine, seule façon de programmer qui permette de casser un programme linéaire...
 
Last edited:
Top