Chrono Agility : nouveau

BESQUEUT

Senior Member
Voilà les premier test de comparaison du chrono : avec LCD et i2c.
Donc les mêmes BP actionnent les 2 chronos en même temps (en parallèle) et les 2 sur batterie.

On ne peut pas dire que ce soit excellent ... mais vraiment pas aussi catastrophique que cela en fin de compte.
La majorité des tests sont avec le settimer à 64915 que j'ai considéré comme plus proches les unes des autres ... à voir avec un quartz maintenant.
Dans la tranche 30 à 60 sec., c'est relativement stable.
La première colonne pour trouver la meilleure valeur pour commencer.
Je vais faire d'autres tests, dont avec 64916 (qui dévie fort avec des temps plus long) ... à voir donc

Rien ne garanti que l'autre chrono soit 100%, mais certainement plus stable.
Stable ??? qu'entendez vous par là ?
Sans quartz, avec LCD et I2C, et sans mise à l'échelle, il ne faut pas s'attendre à des miracles...
Au moins confirme-t-on que l'approche n'est pas satisfaisante pour un chronomètre digne de ce nom...
Pour moi, les seuls tests intéressants devraient s'affranchir des problèmes connus :
- quartz,
- pas d'I2C et autres communications pendant le chronométrage,
- code optimisé pour la vitesse (et en particulier un seul cas de figure !)
- étalonnage du chronométrage final.
==> sur cette base, on vérifie que chaque chronométrage est suffisamment précis.
===> on peut alors éventuellement compliquer le code,...
====> en vérifiant à chaque fois que la modification ne dégrade pas le chronométrage...

En gros : on part d'un truc qui marche, et on tente de l'améliorer sans dégrader ses performances...

Vous préférer partir d'un truc qui à priori ne peut pas marcher pour différentes raisons, puis tenter d'aller vers quelques chose de plus satisfaisant.
Mais du coup, il est impossible de savoir si une modification est bénéfique ou pas : une amélioration peut être masquée par un autre problème...

En se basant sur les 4 valeurs enregistrées dans les mêmes conditions (64915), et en étalonnant le temps sur la première mesure, on obtient :
Code:
K=1,00081
Chrono   Picaxe    * K    Delta
185,66   185,51   185,66    0,00
185,37   185,23   185,38   -0,01
185,44   185,33   185,48   -0,04
185,38   185,23   185,38    0,00
Il faudrait plus de mesures pour que les statistiques soient plus parlantes, mais en première approche :
On est presque dans le 1/100 pour 3 mesures,
De façon aléatoire, on peut avoir 4 centièmes dans la vue, sans doute à cause d'une communication au mauvais moment...

NB : il n'est pas possible de multiplier un temps par un coefficient K de 1,00081 avec un Picaxe (le tableau a été réalisé avec Excel).
Mais avec le Picaxe, il est possible de calculer un "correctif" "C" à ajouter au temps :
C=81* temps_Picaxe /1000
Pour des temps autour de 186 s, on obtient un correctif de 15 centièmes, qui ajouté aux temps mesurés donne les mêmes résultats qu'Excel...
Autrement dit :
temps_Picaxe=81* temps_Picaxe /1000+ temps_Picaxe
 
Last edited:

BESQUEUT

Senior Member
En théorie cela devrait fonctionner :
- Les entrées et BP ont un R de 10K au + 5V et si actives met à 0v
- La sortie est à 0v au repos et + 5v active ... une R sera nécessaire pour l'entrée du picaxe horloge, avec une diode probablement



Je veux bien mettre le code si vous le souhaitez, mais cela fait quelques (sss) lignes de codes ... je suis encore occupé de le modifier légèrement (simplifier) en fonction de ce que j'ai déjà fait durant mes vacances, sans en modifier le principe.

Le principe de la led défaut (sortie) est très simple (et complexe) ... elle s'allume :
- Si une des entrées est en alarme au démarrage où après remise à zéro : arrête l'interruption du START
- Si on change le mode de fonctionnement du chrono : arrête également l'interruption
- Si on fait un appel des mémoires : arrête également l'interruption
- Durant le blocage des barrières de 3 sec. après le START et si le STOP toujours en alarme après ce délai
En résumé, elle est éteinte que si le chrono est 100% prêt ... à l'arrêt ou après les 3 sec. de blocage.

Le picaxe horloge, je ne l'ai pas encore commencé, j'analyse le principe de fonctionnement pour l'instant.
Je vais commencé le code lorsque j'aurai fini le chrono lui-même et fait les tests avec les 2 chronos ... je viens de le ramener du club.
Pour le moment, le code avec le 2me picaxe en TX est toujours présent.
Juste une question de vocabulaire :
- pour vous, le Picaxe qui fait le chronométrage, c'est l'horloge,
- et celui qui affiche le temps et le distribue (celui que j'appelle le Communiquant) le chronomètre...
C'est Bien ça ?
 

ddaweb

New Member
Le chrono fait tout, c'est mon actuel ... affichage d'un temps approximatif en fonctionnement.
L'horloge sera le 2me picaxe, ne fait que cela et le chrono ira chercher ce temps au STOP pour mettre à jour le temps final (réel) au LCD et le reste.

Donc l'horloge : au START se met à compter et arrête de compter au STOP et le rend alors accessible via I2C (ne fait rien d'autre) ... au STOP, le chrono ira lire le temps de l'horloge via i2c pour l'afficher au LCD et l'afficheur extérieur (+ PC) = temps final réel, le stocker en mémoire. Durant le fonctionnement le chrono affiche son propre temps (nommé approximatif), au STOP met à jour avec celui de l'horloge.

Je tiens toutefois à vous signaler que si je déprogramme l'i2C ou LCD (à l'arrêt fait ses affichages et au stop affiche le temps final ... durant le fonctionnement : plus d'affichage) ou les 2, j'obtiens des écarts tout à fait similaire avec le chrono de référence ... je n'ai donc remarqué aucune incidence notable.

Je confirme également que le Picaxe sans quartz est fort sensible à la t° ambiante côté horloge : plus frais, j'ai obtenu des différences négatives au lieu de positives ... il a donc ralenti !!

J'avais également pensé au correctif du temps ... +/- 0.02 par 30 sec. que je devais encore mettre en formule mathématique comme vous avez fait.
Mais je m'attarderai à cela dès que j'ai les quartz et verrai si cela sera encore nécessaire.
Cette déviation est, à mon sens, plutôt due à l'horloge interne du Picaxe ... à voir avec un quartz !

Comme je l'ai déjà dit, ne soyons pas puriste, même si le temps n'est pas 100% précis (mais tout de même cohérent dans le temps) ... du moment que tous les chiens soient logés à la même enseigne ... que tout le monde ai 0.04 sec. en moins ou en plus ne va pas influencer le classement.
Déjà que le START de la cellule n'est pas toujours au même endroit du corps du chien en fonction de sa position au franchissement de la barrière : début de la tête, milieu de la tête ou le corps (voir patte s'il saute plus haut que les cellules) .... cette différence donne également des imprécisions similaires.
Je dois juste arriver à un décompte de temps stable, quel que soit la durée du parcours du chien, ne dois pas dévier : je parle bien de petits centièmes, pas de dixièmes !!
 

BESQUEUT

Senior Member
Je tiens toutefois à vous signaler que si je déprogramme l'i2C ou LCD (à l'arrêt fait ses affichages et au stop affiche le temps final ... durant le fonctionnement : plus d'affichage) ou les 2, j'obtiens des écarts tout à fait similaire avec le chrono de référence ... je n'ai donc remarqué aucune incidence notable.
Au vu des résultats précédemment publiés, j'ai un gros doute.
Merci de publier le programme utilisé et les résultats obtenus...

Dans votre tableau, vous affichez un écart de 1,5 dixième (du à l'absence d'étalonnage). Cet énorme écart masque les disparités entre les différents tests, par ailleurs trop peu nombreux pour déceler le caractère aléatoire des mesures.
Cette déviation est, à mon sens, plutôt due à l'horloge interne du Picaxe
Ce n'est pas une déviation mais un facteur d'échelle que vous ne pouvez pas régler uniquement avec le paramétrage du timer qui est un nombre entier.
En l'absence de quartz, le facteur de correction change sans arrêt de sorte qu'un étalonnage ne dure que quelques instants. Inutilisable en pratique.
Avec un quartz, vous ne pourrez pas obtenir un Picaxe qui donne directement le bon temps : il y aura toujours une valeur trop rapide et une trop lente.
La seule solution possible est de faire un étalonnage, qui lui sera stable dans le temps.
Comme je l'ai déjà dit, ne soyons pas puriste, même si le temps n'est pas 100% précis (mais tout de même cohérent dans le temps) ... du moment que tous les chiens soient logés à la même enseigne ... que tout le monde ai 0.04 sec. en moins ou en plus ne va pas influencer le classement.
Ce que vous décrivez est juste un facteur d'échelle, un étalonnage facile à corriger comme je l'ai montré dans mon post précédent (à condition d'utiliser un quartz bien sur).
Le problème est que cette erreur est à priori aléatoire. Pour s'en persuader, il faut faire plusieurs dizaines de mesures et bien sur corriger le facteur d'échelle.
Un chien peut arriver 3 centièmes (au moins, mais à mon avis potentiellement plus...) après un concurrent et néanmoins être déclaré vainqueur...
 
Last edited:

ddaweb

New Member
Au vu des résultats précédemment publiés, j'ai un gros doute.
Merci de publier le programme utilisé et les résultats obtenus...
Je pense qu'il y a eu une erreur d'interprétation des tests ...
Vous avez bien regardé avec le même settimer de 64915 (champs jaune) ... il y a de grosses différences avec les autres valeurs du settimer, mais celle avec la même valeur ne varient pas autant : 2me valeurs de la 1ère partie, 2me et 3me partie ... avec 2 barrières et 1 seule.
Je n'ai pas utilisé de programme, mais 2 chronos en parallèle (mêmes boutons), le résultat chrono est l'autre chrono et Picaxe c'est clair ... je fais la différences de temps entre l'autre chrono et le Picaxe en Excell.
Donc la 1ère colonne est le temps de l'autre chrono, la 2me celle du Picaxe et la 3me la différence des 2 temps obtenus.
J'ai fait des mesures pas tranches de +/- 10 sec.
En conclusion, la différence de temps est relativement constante, augmentant avec le temps plus long (3 min.) !
Champs gris est le mode de fonctionnement du chrono.

Oui on est bien d'accord sur le facteur d'étalonnage, il sera nécessaire quand j'aurai placé le quartz !

Je reviendrai quand le quartz sera placé avec des nouveaux tests plus complets ... j'achève le montage physique du boitier afin de ne faire qu'une commande avec le matériel éventuel manquant et ce que j'ai encore besoin (quartz, Picaxe 20x2 + support, peut-être les CI pour l'afficheur extérieur, etc...).
Il y avait déjà une erreur de l'entrée transistor qu'on m'avait transmise (issue de l'autre chrono) ... elle fonctionnait à l'envers, heureusement j'avais le pendant pour rectifier cela.
Je ferai des tests toujours par tranche de +/- 10 sec, mais jusque 3 min. ... et une valeur à 10 min.
Madame en a marre que la table soit encombrée d'outils :p ... je vais donc la vider au plus vite ... ce soir même ;)
Je serai tout de même curieux de faire le test avec 2 Picaxes en parallèle ... loool
 

BESQUEUT

Senior Member
Je pense qu'il y a eu une erreur d'interprétation des tests ...
Vous avez bien regardé avec le même settimer de 64915 (champs jaune) ... il y a de grosses différences avec les autres valeurs du settimer, mais celle avec la même valeur ne varient pas autant : 2me valeurs de la 1ère partie, 2me et 3me partie ... avec 2 barrières et 1 seule.
Ben non : pas de grosse différence...
Juste une absence de mise à l'échelle, et évidement un coefficient K différent suivant la valeur utilisée pour le timer.
Etalon.jpg
Une fois la mise à l'échelle faite, vous constatez des écarts de l'ordre de 3 à 4 centièmes. Je pense qu'ils sont aléatoires, ce qui me fait dire que vos classements sont eux-mêmes aléatoires...
Mais pour le prouver, il faudrait des conditions de tests plus fiables et plus de mesures...
Je n'ai pas utilisé de programme,
:) Elle est bien bonne celle là ! Le Picaxe, il tourne sans programme ?
En outre, vous faites une comparaison entre avec et sans les communications série : vous avez donc utilisé deux versions de ce programme...
mais 2 chronos en parallèle (mêmes boutons), le résultat chrono est l'autre chrono et Picaxe c'est clair ... je fais la différences de temps entre l'autre chrono et le Picaxe en Excell.
Donc la 1ère colonne est le temps de l'autre chrono, la 2me celle du Picaxe et la 3me la différence des 2 temps obtenus.
J'ai fait des mesures pas tranches de +/- 10 sec.
Ben non, pas d'erreur...
Je tente juste de vous faire comprendre que vous ne pouvez pas interpréter ces mesures sans mettre à l'échelle les résultats, et c'est ce que j'ai fait en #81 avec le coefficient K.
Une fois les temps mis à la même échelle, on peut comparer les temps donnés par le chronomètre de référence et ceux donnés par le Picaxe.
En conclusion, la différence de temps est relativement constante, augmentant avec le temps plus long (3 min.) !
Euhh : une constante ne peut pas augmenter...
En fait la différence est proportionnelle au temps... ce qui signifie qu'il existe un facteur d'échelle, que l'on peut donc corriger.

Oui on est bien d'accord sur le facteur d'étalonnage, il sera nécessaire quand j'aurai placé le quartz !
Je reviendrai quand le quartz sera placé avec des nouveaux tests plus complets ... j'achève le montage physique du boitier afin de ne faire qu'une commande avec le matériel éventuel manquant et ce que j'ai encore besoin (quartz, Picaxe 20x2 + support, peut-être les CI pour l'afficheur extérieur, etc...).
Il y avait déjà une erreur de l'entrée transistor qu'on m'avait transmise (issue de l'autre chrono) ... elle fonctionnait à l'envers, heureusement j'avais le pendant pour rectifier cela.
Je ferai des tests toujours par tranche de +/- 10 sec, mais jusque 3 min. ... et une valeur à 10 min.
Madame en a marre que la table soit encombrée d'outils :p ... je vais donc la vider au plus vite ... ce soir même ;)
Je serai tout de même curieux de faire le test avec 2 Picaxes en parallèle ... loool
Comme déjà dit, vous faites des tests sur un montage qui cumule les problèmes (pas de mise à l'échelle, variations liées à la température,...)
Du coup, impossible de voir si une modification apporte une amélioration ou pas :
C'était mauvais avant, et c'est toujours mauvais après...(mais peut-être pour une autre raison...)

Une série de mesures toutes les 10s permet de confirmer le facteur proportionnel.
Une série de plusieurs dizaines de mesures pour un temps de 10s permettrait de mettre en évidence le caractère aléatoire de la mesure, (sans prendre autant de temps que 20 mesures de 3 minutes...)
Quelques mesures au delà de 3 minutes pour le fun.
 
Last edited:

BESQUEUT

Senior Member
J'ai étalonné l'intégralité de vos mesures :
Etalon2.jpg
Etalon3.jpg
On constate des écarts (qui se confirment aléatoires...)
variant entre -5 et +6 centièmes...
Soit un caractère aléatoire dépassant le 1/10 dans vos classements...
 

ddaweb

New Member
Vu l'instabilité de la fréquence interne du Picaxe, il vaut mieux s'y attarder dès que le quartz sera placé ;)

Je vous met le code du picaxe en fonctionnement, qui pourrait poser des problèmes ... mais j'y ai déjà apporté des modification, mais pas encore revu 100% du code.

Code:
; ################################ Initialisation du chrono ################################
; *************** initialisation du sens des barrieres ***************
sensbarrieres:
    if choix_sens=1 then
        high A.2                    'led_sens allumee
        hintsetup %00000101            'Initialisation interrupt sur entree B.0 -> barriere1 ou B.2 -> BP START/STOP
        setint %00000001,%00000001        'trigger entree
        setintflags or %00000101,%00000101     'Activation flag interrupt -> "or" permet une entree OU l'autre
        pause 10
    else if choix_sens=0 then
        low A.2                    'led_sens eteinte
        hintsetup %00000110            'Initialisation interrupt sur entree B.1 -> barriere2 ou B.2 -> BP START/STOP
        setint %00000001,%00000001        'trigger entree
        setintflags or %00000110,%00000110     'Activation flag interrupt -> "or" permet une entree OU l'autre
        pause 10
    end if
   
    gosub affichage_start                'affichage du START

; *************** boucle attente demarrage et arret du chrono ***************
chrono_demarrage:
    ; --------------- demarrage du chrono : valeur temps a zero -> chrono a zero
    val_temps=0
    ; --------------- Mode de fonctionnement -> affichage du nombre de barrieres et sens : 1 seule fois/demarrage
    if status_chrono=99 or led_nbr<>choix_nbr or choix_sens<>led_sens then
        if choix_sens<>led_sens then    'changement du sens des barrieres
            SETINTFLAGS OFF        'Suppresssion "flags" pour "interrupt'
            gosub sensbarrieres    'reinitialisation sens des barrieres
        end if
        high A.1
        if choix_sens=1 and choix_nbr=1 and status_chrono<>12 then        '---------- barrieres 1 -> 2
            high A.3                                    'led_nbr allumee
            status_chrono=12
            barriere_stop=2
            hserout LCD,(254,137,"1 -> 2 ")                    'affichage LCD 1ere ligne
        else if choix_sens=0 and choix_nbr=1 and status_chrono<>21 then    '---------- barrieres 2 -> 1
            high A.3                                    'led_nbr allumee
            status_chrono=21
            barriere_stop=1
            hserout LCD,(254,137,"2 -> 1 ")                    'affichage LCD 1ere ligne
        else if choix_sens=1 and choix_nbr=0 and status_chrono<>11 then    '---------- barrieres 1 seule
            low A.3                                    'led_nbr eteinte
            status_chrono=11
            barriere_stop=1
            hserout LCD,(254,137,"1 seule")                    'affichage LCD 1ere ligne
        else if choix_sens=0 and choix_nbr=0 and status_chrono<>22 then    '---------- barrieres 2 seule
            low A.3                                    'led_nbr eteinte
            status_chrono=22
            barriere_stop=2
            hserout LCD,(254,137,"2 seule")                    'affichage LCD 1ere ligne
        end if
        pause 1000
        low A.1
    end if
    ; --------------- controle des barrieres
    if  barriere1=1 and barriere2=1 then                '---------- Attente demarrage : faire clignoter 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
    else if choix_nbr=1 then                        '---------- 2 barrieres
        if barriere1=0 or barriere2=0 then                'Au moins une barriere active
            low A.0
            SETINTFLAGS OFF                        'Suppresssion "flags" pour "interrupt'
            gosub controle2barrieres
        end if
    else if barriere1=0 and choix_sens=1 and choix_nbr=0 then    '---------- 1 barriere, barriere 1 active : avec sens = 1 -> 2
            low A.0
            SETINTFLAGS OFF                        'Suppresssion "flags" pour "interrupt'
            gosub controle1barrierre1
    else if barriere2=0 and choix_sens=0 and choix_nbr=0 then    '---------- 1 barriere, barriere 2 active : avec sens = 2 -> 1
            low A.0
            SETINTFLAGS OFF                        'Suppresssion "flags" pour "interrupt'
            gosub controle1barrierre2
    end if
    ; --------------- Affichage historique : max. 8 temps
    if memoires_temps=0 then
        low A.0
        SETINTFLAGS OFF                                'Suppresssion "flags" pour "interrupt'
        gosub liste_temps
    end if
   
    goto chrono_demarrage                                 'boucle d'attente pour le START
    Interrupt:
    if flag3=1 then                    '===== activation d'une entre interrupt suivant flag => B.0 a B.2 : START
        if val_temps=0 then                            '----- blocage des barrieres
            timer=0
            val_temps_mem=0
            high A.0                                'led_status allumee
            ;--------- Boucle 3 sec. de blocage barriere ----------
            do
                high A.1                            'led_defaut allumee
                if val_temps=0 then
                    high B.7                        'buzzer active
                    bintoascii val_temps,b1,b2,b3,b4,b5
                    hserout LCD,(254,128,"Bloc. : ")        'affichage LCD 1ere ligne
                    put 1, b1,b2,b3,b4,b5,flag2,1            'enregistrement des valeurs scratchpad (debut = 1->7) lues via i2c : TX = 1 (7)
                endif
                val_temps=timer
                gosub affichage_temps_chrono                'affichage du temps
                if val_temps>75 and val_temps<81 then
                    low B.7                        'buzzer arret
                end if
            loop while val_temps<300
            ;--------- Verification STOP actif, sinon START ----------
            if barriere_stop=2 and barriere2=0 then            'verifier STOP barriere2 en alarme : mode MANUEL
                gosub mode_manuel
            else if barriere_stop=1 and barriere1=0 then        'verifier STOP barriere1 en alarme : mode MANUEL
                gosub mode_manuel
            else
                hserout LCD,(254,128,"START ")            'affichage LCD 1ere ligne : mode AUTOMATIQUE
            low A.1                                'led_defaut etteinte
            endif
        endif
        val_temps=timer
        if val_start_alerte=1 then                '----- mode manuel
            do                              
                val_temps=timer
                gosub affichage_temps_chrono
                if start_stop=0 then
                    low B.7                        'arreter buzzer demarre par le mode MANUEL
                    goto chrono_arrete
                endif

                if val_temps>=450 and val_temps<456 then
                    low B.7                        'arreter buzzer demarre par le mode MANUEL
                endif

                if barriere_stop=1 and barriere1=1 then        'verifier si STOP barriere1 5 sec. consecutives au repos
                    gosub mode_manuel_verification
                else if barriere_stop=2 and barriere2=1 then    'verifier si STOP barriere2 5 sec. consecutives au repos
                    gosub mode_manuel_verification
                else
                    val_manuel_temps=val_temps            'maj du temps de 5 sec. si retour alarme avant d?lai
                endif
            loop while val_start_alerte=1
        endif
        val_temps=timer
        if status_chrono=12 or status_chrono=22 then    '----- mode AUTOMATIQUE : STOP = barriere2 ou BP START/STOP
            do
                val_temps=timer
                gosub affichage_temps_chrono
            loop while barriere2=1 and start_stop=1
            goto chrono_arrete
        else                                '----- mode AUTOMATIQUE : STOP = barriere1 ou BP START/STOP
            do
                val_temps=timer
                gosub affichage_temps_chrono
            loop while barriere1=1 and start_stop=1
            goto chrono_arrete
        endif
    endif
    '---------- reinitialisation flag interrupt : OBLIGATOIRE
    if led_sens=1 then                    '----- START = barriere1 ou BP START/STOP
        SetIntFlags or %00000101,%00000101
    else                                '----- START = barriere2 ou BP START/STOP
        SetIntFlags or %00000110,%00000110
    endif
    return
; *************** Affichage temps LCD, afficheur exterieur + PC via i2c ***************
affichage_temps_chrono:  
    bintoascii val_temps, b1,b2,b3,b4,b5        'decomposition ascii
    hserout LCD,(254,136,b1,b2,b3,",",b4,b5," s")    'affichage LCD 1ere ligne : temps
    put 1, b1,b2,b3,b4,b5,9,1                'valeurs dans scratchpad (1 -> 7) qui seront lues via i2c : TX = 1 (7)
    return
Je n'ai pas su mettre tout le code par la restriction du forum, si des morceaux manquent pour comprendre, demandez-les.
 

PieM

Senior Member
Heu ... 72 lignes pour une routine d'interruption, y a comme un problème!
Relire ce que j'ai écrit en #74. On se moque de connaitre quelle barrière est à l'origine de l'interruption.
le premier appel de la routine met le chrono à 0, le second appel mémorise le temps.
 

BESQUEUT

Senior Member
Vu l'instabilité de la fréquence interne du Picaxe, il vaut mieux s'y attarder dès que le quartz sera placé ;)
Ben NON : l'instabilité de la fréquence interne du Picaxe peut expliquer des écarts d'étalonnage sur plusieurs jours, voire sur plusieurs heures si la température change. Mais ça ne peut pas expliquer des écarts de -4 à +3 en quelques dizaines de secondes.
La seule explication pour les écarts que vous avez mesuré, c'est le caractère totalement aléatoire du code avec des valeurs dépassant 1/10 s ...
Je vous met le code du picaxe en fonctionnement, qui pourrait poser des problèmes ... mais j'y ai déjà apporté des modification, mais pas encore revu 100% du code.

Code:
; ################################ Initialisation du chrono ################################
; *************** initialisation du sens des barrieres ***************
LCD,(254,136,b1,b2,b3,",",b4,b5," s")    'affichage LCD 1ere ligne : temps
    put 1, b1,b2,b3,b4,b5,9,1                'valeurs dans scratchpad (1 -> 7) qui seront lues via i2c : TX = 1 (7)
    return
Je n'ai pas su mettre tout le code par la restriction du forum, si des morceaux manquent pour comprendre, demandez-les.
Vous pouvez mettre un fichier texte en pièce jointe...
et oui, ce serait mieux d'avoir la totale, même si je vois déjà pas mal de choses étranges :
- je ne reviendrais pas sur l'horreur absolue que constitue chaque GOTO...
- ce qui me choque le plus, c'est les boucles dans l'interrupt, sans parler des communications série...

A ce niveau, c'est un miracle que les chronométrages soient aussi peu médiocres. Chercher l'explication de ce miracle n'est pas simple. Il serait sans doute préférable de passer du temps à expliquer pourquoi un automate géré par interruption ne peut pas être programmé de cette façon, et encore plus comment le programmer de façon plus orthodoxe...
 

PieM

Senior Member
Heu ... 72 lignes pour une routine d'interruption, y a comme un problème!
Relire ce que j'ai écrit en #74. On se moque de connaitre quelle barrière est à l'origine de l'interruption.
le premier appel de la routine met le chrono à 0, le second appel mémorise le temps.
 

BESQUEUT

Senior Member
Heu ... 72 lignes pour une routine d'interruption, y a comme un problème!
Relire ce que j'ai écrit en #74. On se moque de connaitre quelle barrière est à l'origine de l'interruption.
le premier appel de la routine met le chrono à 0, le second appel mémorise le temps.
Non seulement c'est beaucoup trop de lignes, mais de plus il y a des boucles et des comm série dans l'interruption...
J'ai déjà vu du code d'interruption avec plusieurs tests imbriqués, mais en fait l'exécution restait assez rapide dans la mesure ou dans chaque cas une toute petite partie de l'arborescence était exécutée.
Dans ce code, j'ai l'impression qu'on attend la bascule de la barrière de fin dans une boucle d'attente...
ce qui court-circuite totalement la notion d'interruption.
Cas typique du programme "tombé en marche"...
 

BESQUEUT

Senior Member
Heu ... 72 lignes pour une routine d'interruption, y a comme un problème!
Relire ce que j'ai écrit en #74. On se moque de connaitre quelle barrière est à l'origine de l'interruption.
le premier appel de la routine met le chrono à 0, le second appel mémorise le temps.
Puisque vous suivez ce fil, partagez vous mon analyse des données recueillis ?
Ça semble en tout cas assez cohérents avec les estimations faites au départ sur le caractère aléatoire des mesures.
En voyant le code de l'interruption, j'ai tendance à penser que c'est finalement assez peu aléatoire ; sans doute un effet de l'étalonnage qui compense une partie du retard de prise en compte de l'interruption de fin, et d'un décalage dans le même sens entre les prises en compte du début et de la fin...
 

PieM

Senior Member
Puisque vous suivez ce fil, partagez vous mon analyse des données recueillis ?
Ça semble en tout cas assez cohérents avec les estimations faites au départ sur le caractère aléatoire des mesures.
En voyant le code de l'interruption, j'ai tendance à penser que c'est finalement assez peu aléatoire ; sans doute un effet de l'étalonnage qui compense une partie du retard de prise en compte de l'interruption de fin, et d'un décalage dans le même sens entre les prises en compte du début et de la fin...
Je ne peux pas dire que je suis ce fil ... sincèrement, je ne souhaite pas passer du temps à décoder ces programmes très confus et touffus.
Bien sûr que je partage à 100% votre analyse ! Mais je ne pense pas qu'elle soit partagée par le principal intéressé qui s'enferme dans un programme plat de nouilles.
 

BESQUEUT

Senior Member
Je ne peux pas dire que je suis ce fil ... sincèrement, je ne souhaite pas passer du temps à décoder ces programmes très confus et touffus.
Bien sûr que je partage à 100% votre analyse ! Mais je ne pense pas qu'elle soit partagée par le principal intéressé qui s'enferme dans un programme plat de nouilles.
OK merci ; tout le monde peut se tromper, mais nous sommes au moins 2 à penser la même chose...
 

ddaweb

New Member
Suite à vos commentaires, je me pose 2 questions :
- le SETINTFLAGS OFF ne met-il pas l'interruption hors service ?
- ce que vous appelez les GOTO inclue les GOSUB ?

Heu ... 72 lignes pour une routine d'interruption, y a comme un problème!
Relire ce que j'ai écrit en #74. On se moque de connaitre quelle barrière est à l'origine de l'interruption.
le premier appel de la routine met le chrono à 0, le second appel mémorise le temps.
Heuuuuu alors pourquoi les juges déterminent un START et un STOP ... démarrer le chrono sur n'importe quelle barrière va provoquer quelques démarrages intempestifs par le personnel de terrain, mais passons encore ce détail qui m'arrangerait bien en fin de compte.
 

BESQUEUT

Senior Member
Suite à vos commentaires, je me pose 2 questions :
- le SETINTFLAGS OFF ne met-il pas l'interruption hors service ?
- ce que vous appelez les GOTO inclue les GOSUB ?


Heuuuuu alors pourquoi les juges déterminent un START et un STOP ... démarrer le chrono sur n'importe quelle barrière va provoquer quelques démarrages intempestifs par le personnel de terrain, mais passons encore ce détail qui m'arrangerait bien en fin de compte.
Un GOTO est une horreur
Un GOSUB est d'usage courant et ne pose aucun problème...

Puisqu'on utilise les interruptions à la fois pour détecter le START et le STOP, il faut qu'il y ait en permanence une interruption active.
Par contre, les interruptions se déclenchent en boucle tant que l'entrée reste dans le même état...
Dans le cas d'un chronomètre, c'est la transition entre un état bas et un état haut (ou l'inverse) qui est l'événement déclencheur.
Donc on cherche en premier lieu à détecter ces transitions, par exemple en alternant les SETINT 1 avec des SETINT 0.
Voici un petit programme qui met en évidence ce principe :
Code:
#no_data
#picaxe 18m2

symbol Entree=bit0
symbol Haut=1
Symbol Bas=0

sertxd("Coucou",13,10)
setint %10000000,%10000000
Entree=Bas

do
    inc w1
loop

interrupt:
    sertxd("interrupt  ", #w1," " ,Entree,13,10)

    if Entree=Bas then
        setint %00000000,%10000000
        entree=Haut
    else
        setint %10000000,%10000000
        entree=Bas
    endif
return
A noter que l'incrémentation de la variable w1 permet de vérifier que les interruptions ne monopolisent pas le processeur
et que la boucle principale s’exécute normalement entre les interruptions.
Pas sur que ce soit le cas dans votre code...
 

ddaweb

New Member
Dans ce code, j'ai l'impression qu'on attend la bascule de la barrière de fin dans une boucle d'attente...
ce qui court-circuite totalement la notion d'interruption.
Le code de base pour l'interruption je l'ai pris d'un exemple vu qu'à mes débuts je ne savais pas comment elle fonctionnait sur le Picaxe ... je n'ai jamais modifier le principe de cette partie.
Si un des éléments est manquant, elle ne fonctionne plus en tout cas.
Il est vrai qu'il y a un goto chrono_demarrage ... je ne sais pas comment faire autrement.

Il y a un autre bout de code que je n'ai jamais compris à quoi il servait, mais sans lui, cela ne fonctionne plus non plus :
l’initialisation des flags :
SetIntFlags or %00000101,%00000101 en bas après Interupt:

Dans Interrupt:, c'est le if flag3=1 qui dit quelle est lancée.

Depuis pas mal de temps, je vous dit que j'ai du mal avec l'interruption !
 

BESQUEUT

Senior Member
Le code de base pour l'interruption je l'ai pris d'un exemple vu qu'à mes débuts je ne savais pas comment elle fonctionnait sur le Picaxe ... je n'ai jamais modifier le principe de cette partie.
Si un des éléments est manquant, elle ne fonctionne plus en tout cas.
C'est la définition même d'un programme "tombé en marche"
On ne sait pas pourquoi ça marche, alors surtout on ne change rien...
Mais du coup, si ça ne marche pas aussi bien que ça, il est impossible de corriger...
Il faut absolument décortiquer ce genre de code avec un exemple le plus simple possible jusqu'à ce que vous aillez compris exactement comment ça marche, au besoin en vous faisant aider.
Je viens de publier un tout petit code qui permet d'illustrer un aspect des interruptions. Avez-vous compris ?
Il est vrai qu'il y a un goto chrono_demarrage ... je ne sais pas comment faire autrement.
Celui ci peut facilement être remplacé par un DO...LOOP
Il y a aussi plusieurs "
goto chrono_arrete"
Là c'est un peu plus compliqué : il faut restructurer le code...

Il y a un autre bout de code que je n'ai jamais compris à quoi il servait, mais sans lui, cela ne fonctionne plus non plus :
l’initialisation des flags :
SetIntFlags or %00000101,%00000101 en bas après Interupt:
Des que le programme entre dans l'interruption, les interruptions sont désactivées pour éviter qu'une nouvelle interruption se produise pendant son execution...
Du coup, il faut penser à réactiver une interruption avant de passer dans le RETURN
C'est important de faire ça en dernier car toute instruction placée entre le SETINT et le RETURN est susceptible de ne pas être exécuter en cas de nouvelle interruption...
Dans Interrupt:, c'est le if flag3=1 qui dit quelle est lancée.

Depuis pas mal de temps, je vous dit que j'ai du mal avec l'interruption !
Certes,
Mais on vous dit aussi de commencer avec un code simplissime, que vous puissiez comprendre,...
et vous nous sortez une interruption de 72 lignes...
 
Last edited:

ddaweb

New Member
Oui en effet, il y a plusieurs goto chrono_arrete ... mais là il n'est plus sensé faire quoi que ce soit avec le temps vu qu'il est arrêté et n'aura plus d'incidence sur le temps du chrono qui est fixé avant d'y aller.
Là je traite l'arrêt du chrono, fait le FIFO des mémoires, etc ... et en fin réinitialise le chrono pour le START.

Je veux bien vous mettre le code complet en TXT ou PDF si le TXT ne passe pas ... mais j'ai cru comprendre que la lecture complète du code ne vous intéressait pas plus que cela, si c'est tout de même le cas, je le mettrai volontiers.

Vous n'avez pas répondu si le SETINTFLAGS OFF ne met-il pas l'interruption hors service ?
Si c'est le cas, comme je le pense ou pense en tout cas l'avoir compris, les 70 lignes dans l'interruption est fortement réduite pour ce qui concerne le traitement réel de l'interruption. la plupart des TX se font d'ailleurs durant ces OFF (il suffit de les retirer ... mais j'ai vu un endroit où ce n'est pas encore le cas).
J'ai pris beaucoup de soin à ce que l'interruption ne soit active que lorsque le chrono est réellement prêt à être démarré et plus de TX.
Si par contre ce n'est pas le cas, alors je me suis planté magistralement !

Par contre, je n'ai vraiment pas l'impression d'avoir une interruption sur le STOP, si c'est possible de faire les 2 ... je suis preneur.
Pour le START, le SETINT est initialisé sur un flanc descendant.

C'est la définition même d'un programme "tombé en marche"
On ne sait pas pourquoi ça marche, alors surtout on ne change rien...
Mais du coup, si ça ne marche pas aussi bien que ça, il est impossible de corriger...
Il faut absolument décortiquer ce genre de code avec un exemple le plus simple possible jusqu'à ce que vous aillez compris exactement comment ça marche, au besoin en vous faisant aider.
Je viens de publier un tout petit code qui permet d'illustrer un aspect des interruptions. Avez-vous compris ?
Il est vrai qu'au début je ne comprenais pas trop, mais j'ai lu le manuel sur les différentes paramètres et fait des essais pour comprendre en grande partie, ce qui m'a justement permis de le modifier.

Oui je pense avoir compris votre bout de code : si C.7 monte, l'interruption s'active et s'initialise alors sur le descendant ... ensuite sur le montant et ainsi de suite ... avec un compteur qui s'incrémente durant l'attente.

Haaa oui le Do loop ... je n'y avait pas pensé
 
Last edited:

BESQUEUT

Senior Member
PieM au secours !
J'ai pondu un code "tombé en marche" !
Code:
#no_data

symbol Entree=bit0
symbol Chrono=bit1
symbol Haut=1
Symbol Bas=0

Symbol Arrete=0
Symbol Lance=1

Symbol Temps=w10
symbol Temps_final=w11


sertxd("Coucou",13,10)
Entree=Bas
Chrono=Arrete
Temps_final=1
setint %10000000,%10000000

do
    inc Temps

   
    if Temps_final>0 then
        setint off
        sertxd("Temps_final  ", #Temps_final,13,10)
        Temps_final=Temps_final*2/10*8/10*16/10        ' K=256/1000
'        Temps_final=Temps_final*2/100*127/10        ' K=254/1000
        sertxd("Temps corrige ", #Temps_final,13,10)
        pause 3000
        sertxd("Chrono en attente",13,10)
        Temps_final=0
        Entree=Bas
        setint %10000000,%10000000
    endif
loop

interrupt:
'    sertxd("interrupt  ", #Temps," " ,Entree," ", Chrono,13,10)   
    pause 0
    if Entree=Bas then    ' on vient de détecter une transition bas => haut
        if Chrono=Arrete then
            Temps=0        ' l'urgence est de mettre à zéro le chronomètre
            chrono=Lance
        else
            Temps_final=Temps ' l'urgence est de noter le temps final
            chrono=Arrete
          endif

        entree=Haut
        setint %00000000,%10000000
       
       
    else    ' transition Haut vers Bas : on poubellise, et on attends la prochaine transition
        entree=Bas
        setint %10000000,%10000000 ' Le settint est toujours la dernière instruction de l'interruption
    endif

return
Hormis que j'utilise un 18M2 et donc que je n'ai pas de Timer,
ça fonctionne plutôt bien avec une mise à l'échelle sommaire.

Sauf qu'à priori la PAUSE 0 ne sert à rien,
mais si on l'enlève, les interruptions ne sont pas prises en compte !
Faudra que je teste sur un X2, mais si vous avez une explication, je suis preneur...

Le principe est le même que dans le code précédent :
- on poubellise les transitions haut vers bas,
- sur interruption bas vers haut :
---> si chrono arrêté, on le met en marche
---> si chrono en marche, on note le temps final.

La boucle principale ne fait qu'attendre qu'un temps final soit disponible.
Quand c'est le cas, on met à l'échelle, puis on affiche le temps en centièmes.
Pour faire plaisir à DDAWEB, on arrête les interruptions pendant 3 secondes pour éviter un départ intempestif.
Dans mon cas, j'en profite pour incrémenter mon pseudo timer, mais ce code doit disparaître sur un Picaxe ad hoc.
 
Last edited:

BESQUEUT

Senior Member
Oui en effet, il y a plusieurs goto chrono_arrete ... mais là il n'est plus sensé faire quoi que ce soit avec le temps vu qu'il est arrêté et n'aura plus d'incidence sur le temps du chrono qui est fixé avant d'y aller.
Là je traite l'arrêt du chrono, fait le FIFO des mémoires, etc ... et en fin réinitialise le chrono pour le START.
Le problème des GOTO n'est pas que ça ne marche pas...
mais que ça rends le code illisible.
Le cas du DO LOOP n'est pas gravissime : on s'y retrouve assez vite.
Par contre, pour savoir quand sont executées les lignes après le GOTO chrono_arrêté, ça tiens de la boule de cristal...
Puisque ce qui précède est un IF, il manque probablement un ELSE...

Je veux bien vous mettre le code complet en TXT ou PDF si le TXT ne passe pas ... mais j'ai cru comprendre que la lecture complète du code ne vous intéressait pas plus que cela, si c'est tout de même le cas, je le mettrai volontiers..
C'est pas que ce ne soit pas intéressant, mais c'est très pénible à lire.
Il me semble que l'urgence est plutôt d'établir un code simple, qui marche et dont vous compreniez le fonctionnement.
Une fois ce point acquis, on pourra éventuellement ajouter des choses en décryptant dans votre code ce que vous avez cherché à faire...
Vous n'avez pas répondu si le SETINTFLAGS OFF ne met-il pas l'interruption hors service ?
Si c'est le cas, comme je le pense ou pense en tout cas l'avoir compris, les 70 lignes dans l'interruption est fortement réduite pour ce qui concerne le traitement réel de l'interruption. la plupart des TX se font d'ailleurs durant ces OFF (il suffit de les retirer ... mais j'ai vu un endroit où ce n'est pas encore le cas).
J'ai pris beaucoup de soin à ce que l'interruption ne soit active que lorsque le chrono est réellement prêt à être démarré et plus de TX.
Si par contre ce n'est pas le cas, alors je me suis planté magistralement !

Par contre, je n'ai vraiment pas l'impression d'avoir une interruption sur le STOP, si c'est possible de faire les 2 ... je suis preneur.
Oui : le SETINTFLAGS OFF mets les interruptions hors service.
Mais j'ai répondu qu'il faut qu'une interruption soit active pour que le Picaxe puisse détecter le START. comme le STOP, donc quasiment en permanence... Voir mon dernier code et les explications qui vont avec...

Vous avez à peu près compris : vous attendez le STOP dans une boucle... Donc vous faites autre chose que de l'interruption.
Une interruption ne doit contenir qu'un code très simple qui sera exécuté à chaque interruption.
Il doit rendre la main le plus vite possible, sinon on risque de rater le prochain événement...
Ne pas oublier que jusqu'au prochain SETINT, les interruptions sont désactivées...

Tout le reste doit être dans le programme principal.
Pour le START, le SETINT est initialisé sur un flanc descendant.
Je ne crois pas : un Picaxe ne détecte que des états, pas des transitions...
Testez ça en modifiant le code posté en #97 : si vous simplifiez en supprimant l'alternance des SETINT, vous aurez des interruptions TANT QUE le bouton est enfoncé. Hors seule une transition défini un START ou un STOP.
Si on réinitialise le Timer TANT QUE le niveau est haut, on n'aura le départ que quand la barrière ne sera plus masquée, c'est à dire à la patte arrière du chien...
Il est vrai qu'au début je ne comprenais pas trop, mais j'ai lu le manuel sur les différentes paramètres et fait des essais pour comprendre en grande partie, ce qui m'a justement permis de le modifier.

Oui je pense avoir compris votre bout de code : si C.7 monte, l'interruption s'active et s'initialise alors sur le descendant ... ensuite sur le montant et ainsi de suite ... avec un compteur qui s'incrémente durant l'attente.

Haaa oui le Do loop ... je n'y avait pas pensé
Pour être précis : si l'entrée est au niveau haut, on active une interruption sur un niveau bas, ce qui permet de détecter une transition haut vers bas, et vace verci...
En tout cas bravo pour votre persévérance : on progresse...
 
Last edited:

ddaweb

New Member
Voici le TXT comment c'est maintenant ... il y a parfois du code en commentaire, c'est que je j'ai modifié une partie et le garde avant d'être certain des modifications ... je nettoie régulièrement.

Je suis assez curieux de voir ce que vous allez pouvoir en sortir ... plus que certainement plus court et surtout plus propre.

Afin de mieux comprendre : qu'entendez-vous pas interruption et programme principal ?
Interruption est après interrupt: ?
Le programme principal avant ?

En tout cas, un grand merci pour votre aide.

Oui, je suis persévérant et suis surtout conscient que ma méthode n'est pas idéale vu que je n'ai jamais appris à programmer des µC et je me base donc sur d'autres connaissances qui sur le principe fonctionne, mais pas pour l'optimisation du µc.
 

Attachments

MGU

Senior Member
Déjà que le START de la cellule n'est pas toujours au même endroit du corps du chien en fonction de sa position au franchissement de la barrière : début de la tête, milieu de la tête ou le corps (voir patte s'il saute plus haut que les cellules) .... cette différence donne également des imprécisions similaires.
Je dois juste arriver à un décompte de temps stable, quel que soit la durée du parcours du chien, ne dois pas dévier : je parle bien de petits centièmes, pas de dixièmes !!
Bonjour,

Je me suis aussi posé cette question.
Si le chien passe la barrière à une vitesse de 5m/s , c'est à dire 18km/h, ce qui est déjà rapide,
En prenant une distance de 50cm entre la truffe et la patte arrière en position allongée, ce qui n'est pas un grand chien.
Nous obtenons une erreur possible de 50/500 = 0,1 seconde
Et autant pour la barrière arrivée, ce qui porte l'erreur à 0,2 s, qui est du pur hasard et donc non compensable.

Dans ces conditions, une erreur de 1/100 de seconde sur le chronomètre est donc plutôt marginale. Mais je peux me tromper...

MM
 

BESQUEUT

Senior Member
Bonjour,

Je me suis aussi posé cette question.
Si le chien passe la barrière à une vitesse de 5m/s , c'est à dire 18km/h, ce qui est déjà rapide,
En prenant une distance de 50cm entre la truffe et la patte arrière en position allongée, ce qui n'est pas un grand chien.
Nous obtenons une erreur possible de 50/500 = 0,1 seconde
Et autant pour la barrière arrivée, ce qui porte l'erreur à 0,2 s, qui est du pur hasard et donc non compensable.

Dans ces conditions, une erreur de 1/100 de seconde sur le chronomètre est donc plutôt marginale. Mais je peux me tromper...

MM
1) les dernières mesures montrent une erreur aléatoire due au code supérieure à 1/10 s.
Si vous considérez que c'est acceptable il faut écrire cette tolérance sur l'appareil afin que les candidats en soient informés.
2) la position des cellules est connue des candidats. A eux de faire en sorte que le chronométrage leur soit favorable.
3) il existe des barrières à plusieurs faisceaux qui suppriment ce biais. Devrez vous changer de chronomètre pour rester cohérent ?
 

BESQUEUT

Senior Member
Voici le TXT comment c'est maintenant ... il y a parfois du code en commentaire, c'est que je j'ai modifié une partie et le garde avant d'être certain des modifications ... je nettoie régulièrement.

Je suis assez curieux de voir ce que vous allez pouvoir en sortir ... plus que certainement plus court et surtout plus propre.

Afin de mieux comprendre : qu'entendez-vous pas interruption et programme principal ?
Interruption est après interrupt: ?
Le programme principal avant ?

En tout cas, un grand merci pour votre aide.

Oui, je suis persévérant et suis surtout conscient que ma méthode n'est pas idéale vu que je n'ai jamais appris à programmer des µC et je me base donc sur d'autres connaissances qui sur le principe fonctionne, mais pas pour l'optimisation du µc.
Ce genre de programme comporte 3 parties :
1) initialisation
2) boucle principale
3) sous programmes
Les sous-programmes commencent par leur nom et se terminent par un RETURN
L'interruption est un sous-programme spécial qui n'est pas appelé par un GOSUB
 

PieM

Senior Member
Heuuuuu alors pourquoi les juges déterminent un START et un STOP ... démarrer le chrono sur n'importe quelle barrière va provoquer quelques démarrages intempestifs par le personnel de terrain, mais passons encore ce détail qui m'arrangerait bien en fin de compte.
Ce ne sont pas les juges qui déterminent un START et un STOP, mais c'est la chronologie des évènements qui engendrent la même interruption!
la différenciation se fait donc au sein de l'interruption.
Et si des touristes peuvent se promener sur le parcours après le début de l'épreuve, je ne vois pas comment le fait de définir avant qu'elle est la barrière de départ ou d'arrivée changera quelque chose.
L'indication des barrières départ et arrivée, si nécessaire, est purement cosmétique et n'a surtout rien à voir avec l'interruption.

Sauf qu'à priori la PAUSE 0 ne sert à rien,
mais si on l'enlève, les interruptions ne sont pas prises en compte !
Faudra que je teste sur un X2, mais si vous avez une explication, je suis preneur...
Ben non, je suis sec là! Je me souviens qu'il y a un pb avec le timing du picaxe avec lequel il faut introduire une ligne pause ou pauseus pour que ça marche, (si Michel s'en souvient?) mais on est pas dans ce cas ici, à priori. Bizarre.

Concernant l'interruption, si les barrières peuvent n'envoyer qu'un créneau inférieur à 3s, il serait possible de ne réarmer l'interruption que dans le programme principal après une pause d'inhibition de 3 s par exemple.
De plus il est inutile de faire une mise à 0:
à chaque interruption, on enregistre le temps qu'on met dans le scratchpad.
on revient au programme principal qui lui réarme l'interruption après 3s. Que ce soit le start ou le stop n'a pas d'importance

Il suffit de faire ensuite la différence des 2 valeurs.
L'interruption se limiterait donc à:

put index, WORD timer
index=index+2
Return


et dans le prog principal:
après initialisation de l'épreuve, avec un premier setint, et init de index
do
pause yyy
setint ....
loop

L'autre Picaxe va chercher les valeurs dans le scratchpad en fin d'épreuve, et fait le calcul.
 
Last edited:

BESQUEUT

Senior Member
Ce ne sont pas les juges qui déterminent un START et un STOP, mais c'est la chronologie des évènements qui engendrent la même interruption!
la différenciation se fait donc au sein de l'interruption.
Et si des touristes peuvent se promener sur le parcours après le début de l'épreuve, je ne vois pas comment le fait de définir avant qu'elle est la barrière de départ ou d'arrivée changera quelque chose.
L'indication des barrières départ et arrivée, si nécessaire, est purement cosmétique et n'a surtout rien à voir avec l'interruption..
Effectivement, dans le cas où il y a deux barrières, on peut imaginer que le chien fasse tomber la barrière au départ et que quelqu'un la remette debout avant son arrivée sur l'autre barrière, ce qui provoquerait une erreur de chronométrage.
Pas testé, mais s'il est possible de faire un SETINT B1,B2
il devrait être possible de gérer ces cas de figure en amont en renseignant correctement B1, B2
Ben non, je suis sec là! Je me souviens qu'il y a un pb avec le timing du picaxe avec lequel il faut introduire une ligne pause ou pauseus pour que ça marche, (si Michel s'en souvient?) mais on est pas dans ce cas ici, à priori. Bizarre..
OK : dans ce cas, je vais tenter de faire le code le plus minimaliste possible qui mette en évidence le problème et en anglais pour le poster sur le forum général...
Concernant l'interruption, si les barrières peuvent n'envoyer qu'un créneau inférieur à 3s, il serait possible de ne réarmer l'interruption que dans le programme principal après une pause d'inhibition de 3 s par exemple.
De plus il est inutile de faire une mise à 0:
à chaque interruption, on enregistre le temps qu'on met dans le scratchpad.
on revient au programme principal qui lui réarme l'interruption après 3s. Que ce soit le start ou le stop n'a pas d'importance

Il suffit de faire ensuite la différence des 2 valeurs.
L'interruption se limiterait donc à:

put index, WORD timer
index=index+2
Return


et dans le prog principal:
après initialisation de l'épreuve, avec un premier setint, et init de index
do
pause yyy
setint ....
loop

L'autre Picaxe va chercher les valeurs dans le scratchpad en fin d'épreuve, et fait le calcul.
SUPER !
Difficile d'optimiser plus...
 

PieM

Senior Member
Effectivement, dans le cas où il y a deux barrières, on peut imaginer que le chien fasse tomber la barrière au départ et que quelqu'un la remette debout avant son arrivée sur l'autre barrière, ce qui provoquerait une erreur de chronométrage.
Le problème existe de toute façon si on est dans le cas de départ et arrivée sur la même barrière!
Je ne connais pas l'organisation de tels concours, mais il me semble que des présences autres que celles du chien et de son maître doivent être interdites sur le parcours pendant une épreuve! Sinon, tout est possible même avec des déclarations de configuration.
Si la barrière tombe lors du passage, le passage est validé, ou bien il est annulé ?
 

BESQUEUT

Senior Member
Le problème existe de toute façon si on est dans le cas de départ et arrivée sur la même barrière!
Je ne connais pas l'organisation de tels concours, mais il me semble que des présences autres que celles du chien et de son maître doivent être interdites sur le parcours pendant une épreuve! Sinon, tout est possible même avec des déclarations de configuration.
Si la barrière tombe lors du passage, le passage est validé, ou bien il est annulé ?
On peut imaginer que le départ soit néanmoins pris en compte puisque le faisceau optique est effectivement coupé.
Avec votre proposition, il faut attendre que le chien soit arrivé pour relever la barrière, mais ça ne me semble pas rédhibitoire.
Comme indiqué, il est peut-être possible de prendre en compte l'existence d'une barrière de départ et d'une autre pour l'arrivée, mais ce sera la cerise sur le gâteau une fois que tout le reste fonctionnera.
Par contre, je n'ai toujours pas compris l'intérêt de 2>1 ou 1>2 : il faut une prise "départ" ou "unique" et une prise "arrivée".
Et si les positions départ et arrivées sont inversées, on inverse les prises...
 

PieM

Senior Member
On peut imaginer que le départ soit néanmoins pris en compte puisque le faisceau optique est effectivement coupé.
Oui bien sûr, (bien que ça reste à valider !), mais si on est dans le cas 1 > 1 ou 2>2, la remise en place de la barrière provoquerait aussi une interruption prise pour un stop.
 

ddaweb

New Member
@PieM : si ce sont bien les juges qui déterminent tout : quelle sera la barrière du Start et celle du Stop, nous en tant que club ont place tout le parcours en fonction de ses directives sans avoir de mot à dire, mais en effet du côté du chrono, c'est bien sa chronologie interne.
Ce soir je regarde à mon aise votre proposition sur les interruptions, pas trop bien compris mais pas le temps d'approndir cela au boulot.

C'est bien pour cela que j'avais opté sur sur l'interruption hardware du 28x2 (B.O et B.1 les barrières et B.2 le BP START/STOP) et que je configure alors quelle interruption il faut prendre : dans ma programmation, elle fonctionne de la sorte sans le moindre problème ... mais cela fait des lignes en plus (à voir si cela serait possible plus facilement).
L'idéal serait d'avoir l'interruption sur le START ou BP START/STOP et ensuite avoir une interruption sur le STOP et le BP : en fonction du mode de fonctionnement.
Dans le cas d'une seule barrière Start et Stop, le fait de bloquer les barrières et de regarder l'état du Stop après 1, 2 ou 3 sec. permet également de déterminer si elle est tombée ... alors attente +/- 5 sec. consécutives de repos avant de réactiver l'interruption.
Il est également très peu probable qu'un Stop arrive moins de 20 sec. après le Start ... 15 sec. jamais vu.

Sur le fait de valider ou non le parcours si une barrière tombe ... il me semble que le règlement a changé l'an dernier en attribuant une faute dans ce cas là. Avant le chien était éliminé, mais depuis quelques années ce n'était plus vraiment appliqué.
De toute façon le Start est validé et le chrono démarre !

Sur un parcours d'agility il y a régulièrement 5 à 8 personnes + 1 ou 2 juges : 1 chronomètre manuel de secours, un qui déplace la laisse du chien du Start vers le Stop (ces 2 personnes peuvent arrêter le chrono par mégarde, les autres, il y a moins de risque car plus éloignés des barrières), 4 à 6 personnes qui remettent les barres en places quand elles tombent (régulièrement une même haies est prise plusieurs fois durant le parcours -> égalité de difficultés pour tous les chiens : on essaie, si c'est possible, de remettre directement la barre pour le passage suivant) ... je ne parle pas encore du secrétaire de terrain qui est normalement à une table (certains clubs mettre également un préposé au chrono électronique).
Il y a donc en effet beaucoup de touristes sur un terrain ;)
J'ai tout de même pratiqué la discipline durant près de 30 ans et depuis +/- 20 ans j'aide aux concours du club ... des cas de figure j'en ai vu, tant que cela est pour les autres on s'en fou un peu, mais quand c'est pour soit ... beaucoup moins.
En sachant cela, vous pouvez aisément comprendre le but de ma programmation : essayer que le chrono électronique aie le moins de risque possible d'être mit en défaut.
 

jojojo

Senior Member
Je sens que je vais écrire une bêtise, mais tant pis.
Je trouve que pour l'instant, c'est un peu "usine à gaz".

En supposant, que l'on détermine la durée précise d'une instruction de base, afin de pouvoir appliquer le correctif qui va bien, on ne pourrait pas plutôt faire un truc de ce genre :



Do
Loop Until Start_Chro=1
Do
w0=w0+1
Loop until Stop_Chro=1
Tps_Chronometre= w0*n+k 'en deux ligne, hein...


Si vraiment le temps de comptage peut-être trop long, pour une variable word (65025), on peut chainer sur une deuxième, etc, etc.
On pourrait aussi choisir une instruction assez "lente" (pas trop, quand même, pour la précision).

J'y vois comme avantage, que l'erreur maximale, sur le temps de comptage sera le temps d’exécution de l'instruction choisie.

Pas d'usage de timer, pas d'interférence, durant le comptage.

Sais pas, hein ...
 

PieM

Senior Member
Alors la solution reste d'affecter une entrée spécifique pour chaque appel d'interruption.
Il y a 2 entrées chacune pour une barrière.
4 configurations de figure: 12 21 11 22

Dans le programme principal:
on initialise la config puis avec
select case
case 11 or 12 : setint ... entrée 1 'valide départ sur entrée 1
case 22 or 21 : setint ...entrée 2 'valide départ sur entrée 2
ensuite, après retour de la première interruption (donc départ)
après la pause
select case
case 11 or 21 : setint ... entrée 1 'valide arrivée sur entrée 1
case 12 or 22 : setint ...entrée 2 'valide arrivée sur entrée 2

Rien ne change pour l'interruption qui se contente de mémoriser les temps en scrachpad
 
Last edited:

ddaweb

New Member
Alors la solution reste d'affecter une entrée spécifique pour chaque appel d'interruption.
Il y a 2 entrées chacune pour une barrière.
4 configurations de figure: 12 21 11 22

Dans le programme principal:
on initialise la config puis avec
select case
case 11 or 12 : setint ... entrée 1 'valide départ sur entrée 1
case 22 or 21 : setint ...entrée 2 'valide départ sur entrée 2
ensuite, après retour de la première interruption (donc départ)
après la pause
select case
case 11 or 21 : setint ... entrée 1 'valide arrivée sur entrée 1
case 12 or 22 : setint ...entrée 2 'valide arrivée sur entrée 2

Rien ne change pour l'interruption qui se contente de mémoriser les temps en scrachpad
J'y avais pensée au case, sans pouvoir le mettre en oeuvre ... elle me semble excellente et à creuser.
De toute façon, le choix du mode de fonctionnement ne peut se faire qu'avant le départ, après doit être sans effet et rester dans le mode au départ activé.

Ce serait bien de pouvoir garder les entrées physiques actuelles :
- B.0 et B.1 pour les barrières (repos = 1)
- B.2 pour le BP Start/Stop (repos = 1)
- B.3 pour le choix du sens 1-2 ou 2-1 (sens 1-2 = 1)
- B.4 pour le nombre de barrière 1 ou 2 (nbr 2 = 1 ... pour 1 barrière, c'est la première du sens qui est prise par exemple)
- B.5 pour l'appel des mémoires (toujours si chrono n'est pas démarré : appel = 0) ... du moins j'espère pouvoir garder cela

Si je comprend bien, le temps ne serait plus affiché lorsque le chrono tourne ? Ou alors vous parler de 2 picaxes et de la partie horloge ?

NB :
@BESQUEUT :Je parlais de l'interruption, la précision est un autre problème ;)
J'ai fais le choix de 2 cellules espacée de 20 cm / barrières pour une détection plus rapide du chien et comme vous le dites si bien, les concurrents voient les cellules et peuvent prendre action en conséquence avec le chien pour le départ !
Par contre, j'ai fais un test avec un faisceau de cellules utilisée en système d'alarme pour protéger les fenêtres de 4 ou 6 faisceaux (émetteur et récepteur séparés) ... la vitesse de réaction était en dessous de tout : j'ai donc abandonné ce système, également à cause du câblage entre les 2 côtés de la haie.
 

PieM

Senior Member
Ce serait bien de pouvoir garder les entrées physiques actuelles :
- B.0 et B.1 pour les barrières (repos = 1)
- B.2 pour le BP Start/Stop (repos = 1)
- B.3 pour le choix du sens 1-2 ou 2-1 (sens 1-2 = 1)
- B.4 pour le nombre de barrière 1 ou 2 (nbr 2 = 1 ... pour 1 barrière, c'est la première du sens qui est prise par exemple)
- B.5 pour l'appel des mémoires (toujours si chrono n'est pas démarré : appel = 0) ... du moins j'espère pouvoir garder cela

Si je comprend bien, le temps ne serait plus affiché lorsque le chrono tourne ? Ou alors vous parler de 2 picaxes et de la partie horloge ?
B.0 et B.1, oui si ça correspond aux entrées interruption du picaxe choisi.
B.2 ne sert à rien car c'est une fonction ou avec les entrées B.0 et B.1. Donc 4 diodes avec le BP et il n'y a rien à gérer en entrée.
B.3 pour le sens et B.4 pour le nb de barrière: non, il est plus indiqué de choisir B.3 : départ barrière 1 ou 2 B.4 : arrivée barrière 1 ou 2 car un seul test à faire pour le départ et un seul pour l'arrivée.
B.5 n'a rien à voir dans ce programme. Les mémoires sont soit dans le scratchpad soit dans le second picaxe.

On est bien sûr dans le principe proposé par l'ami Besqueut, à savoir 2 picaxes, 1 exclusivement dédié au chronométrage en fonction des interruptions d'entrées. L'affichage en cours étant géré par l'autre avec sa propre horloge. Seul le résultat final est repris du chrono.
 

BESQUEUT

Senior Member
Voici une première version du code inspiré par PieM (sur un 40X2):
(Pour ce que j'appelle le chronomètre et que vous appelez l'horloge, en tout cas le Picaxe dont dépends la qualité du chronométrage.)
Code:
#no_data
#no_table
' port com : 19200 bauds= 4x 4800
' Interruption soft

symbol T1=w25
symbol T2=w26
symbol Temps=w27

symbol Barriere1=b1
symbol Barriere2=b2

setfreq m16
settimer 64912    ' 0,001 s
'settimer 65473    ' 0,010 s

Barriere1=%0000001
Barriere2=%0000001

setint Barriere1,Barriere1,B
temps=0

do
       do                    ' attente du START
    loop until temps>0

    T1=temps
    sertxd("T1=",#T1,13,10)
    pause 2000                ' 1s à 16 Mhz
    temps=0
    setint Barriere1,Barriere1,B

       do                    ' attente du STOP
    loop until temps>0

    T2=temps
    temps=t2-t1
    if temps>32768 then
        temps=temps+65535
    endif
    sertxd("T2=",#T2," chrono=",#temps,13,10)
    pause 2000                ' 1s à 16 Mhz
    temps=0
    setint Barriere2,Barriere2,B
loop


interrupt:
    Temps=Timer  
return
J'ai encore simplifié vu que la boucle principale sait si elle attends un START ou un STOP.
L'interruption ne contient qu'une seule ligne, et pendant le chronométrage, la boucle principale ne fait rien d'autre qu'un DO...LOOP.
Difficile de faire plus réactif...
Il y a une pause de 1s avant de réarmer l'interruption de façon à éviter les déclenchements multiples.
 
Last edited:

BESQUEUT

Senior Member
Voici les résultats du test du programme précédent.
Le générateur est un Picaxe 18M2 avec le programme suivant, à savoir une impulsion de 500 ms toutes les 10s.
Code:
#no_data
#picaxe 18M2

do
    high b.3    ' START
    pause 500
    low b.3
    pause 9500
   
    high b.3    ' STOP
    pause 500
    low b.3
    pause 2000
loop
Le Timer du chronomètre a été calé pour donner des millièmes ...
Code:
T1=1298  T2=11296 chrono=9998
T1=13666 T2=23663 chrono=9997
T1=26032 T2=36029 chrono=9997
T1=38399 T2=48399 chrono=10000
T1=50768 T2=60769 chrono=10001
T1=63139 T2=7605  chrono=10002
T1=9976  T2=19977 chrono=10001
T1=22347 T2=32349 chrono=10002
T1=34719 T2=44719 chrono=10000
T1=47088 T2=57089 chrono=10001
T1=59459 T2=3926  chrono=10003
T1=6297  T2=16303 chrono=10006
T1=18673 T2=28677 chrono=10004
T1=31047 T2=41052 chrono=10005
T1=43421 T2=53424 chrono=10003
T1=55794 T2=259   chrono=10001
T1=2629  T2=12633 chrono=10004
T1=15003 T2=25007 chrono=10004
T1=27378 T2=37381 chrono=10003
T1=39751 T2=49756 chrono=10005
T1=52125 T2=62127 chrono=10002
T1=64496 T2=8962  chrono=10002
T1=11331 T2=21332 chrono=10001
T1=23701 T2=33702 chrono=10001
T1=36072 T2=46073 chrono=10001
T1=48442 T2=58442 chrono=10000
T1=60812 T2=5279  chrono=10003
T1=7649  T2=17653 chrono=10004
T1=20023 T2=30026 chrono=10003
T1=32396 T2=42397 chrono=10001
T1=44767 T2=54770 chrono=10003
T1=57140 T2=1607  chrono=10003
T1=3977  T2=13978 chrono=10001
T1=16347 T2=26350 chrono=10003
T1=28721 T2=38724 chrono=10003
T1=41094 T2=51095 chrono=10001
T1=53464 T2=63467 chrono=10003
T1=300   T2=10304 chrono=10004
T1=12673 T2=22676 chrono=10003
On doit pouvoir faire mieux avec un quartz et donc un Picaxe 4 fois plus rapide.
Mais en l'état on peut tranquillement garantir le 1/100 s.
 
Last edited:

ddaweb

New Member
J'ai peut-être des bêtes questions :
qu'est-ce qui empêche de mettre timer=0 dans la boucle attente start -> le if temps>32768 n'est plus utile alors vu qu'il correspond au dépassement de la valeur word ?
Les 2 setint après chaque boucle ne sont-ils pas inversés ?

J'ai évidemment testé + en mettant Barriere2=%0000010 afin de voir si j'avais bien compris : le start sur B.0 et stop sur B.1
Vu que les 2 barrières étaient sur B.0 cela fonctionnais évidemment avec votre code.

Le résultat :
Code:
T1=14    T2=533 chrono=519
T1=14    T2=505 chrono=491
T1=14    T2=1249 chrono=1235
T1=14    T2=451 chrono=437
T1=14    T2=336 chrono=322
T1=14    T2=710 chrono=696
T1=14    T2=409 chrono=395
Edit : j'ai fait le test dans le simulateur du programme, demain, si j'ai le temps, je le fait avec un 28x2 (sans quartz malheureusement) + le générateur d'impulsion avec un 18m2
 
Last edited:
Top