Chenillard méthode du lapin fou !

dje8269

Senior Member
Voila qui seras plus simple pour suivre la discussion sur le lapin fou .

Je propose de partir sur un exemple assez simple , car la méthode au premier abords parait complexe.

Donc on désire, sur la base d'un 28X2 : On désire faire un chenillard sur le port B ( B0 a B7) toutes les secondes une ampoule s'allume .
Pendant ce temps que le chenillard chenille , on désire (sur le port C) aussi allumé une ampoule toutes 3 secondes (C.3) et une autres toutes les 7 secondes (C.7)

Voila les bases sont posées . que le lapin fou tourne !!!!!

Voici un lien trés utile pour comprendre le settimer . par ici
 
Last edited:

BESQUEUT

Senior Member
ce thread est dédié à Karl Lewis et à Lewis Caroll.
Pour ceux qui ont suivi le thread précédent :
http://fr.wikipedia.org/wiki/Apple_Lisa
Et pour répondre au dernier message de notre ami :
l'idée n'est pas de noter à quelle heure ont a fait quelque chose, mais à quelle heure on devra faire quelque chose.
Comme expliqué plus haut, la boucle principale doit tourner le plus vite possible.
Donc il vaut mieux faire le calcul une fois au début, qu'à chaque tour de boucle...
 

BESQUEUT

Senior Member
Pour compléter l'article de Wiki sur Lisa :
J'ai au grenier la collection complète des classeurs dactylographiés (tapés à la main sur des machines à écrire !) par Steve Jobs et ses copains et qui décrivent la philosophie de l'informatique "orientée utilisateur". Leurs travaux découlent de ceux de Xerox (Palo Alto) qui ont inventé les concepts de souris et de fenêtre. Le langage de programmation était le Pascal...
A l'époque les ordinateurs étaient algorithmiques et ne savaient pas "réagir" à l'environnement.
D'où l'invention du concept de "multitâche collaboratif" : le travail est fait par des sous-programmes qui s'interdisent de monopoliser le processeur.
Il y a aussi un concept intéressant plus évolué que notre lapin qui regarde sa montre : c'est la pile de messages.
Chaque sous-programme peut poster un message à destination de la boucle principale ou d'un autre module.
La boucle principale dépile les messages dans l'ordre d'arrivée et distribue le travail.
Si on avait un besoin plus compliqué que ce chenillard, (et un PICAXE puissant) on pourrait considérer chaque changement d'état de lampe comme un message. L'appui sur le bouton de démarrage du chenillard provoque l'envoi du message "allumer la première lampe"
Notez qu'on ne donne pas la liste complète des opérations, mais seulement la première.
C'est seulement quand on a allumé la première lampe que l'on envoie un autre message "allumer la lampe suivante dans n secondes"
De même, on peut charger un programme séparé de détecter l'allumage de la dernière lampe et de mettre en service le Klaxon.
C'est vu comme un "événement" auquel il faut réagir...
Il est hors de question de faire ça sur un PICAXE, mais ça peut donner des idées.
 
Last edited:

PieM

Senior Member
dje8269 said:
Donc on désire, sur la base d'un 28X2 : On désire faire un chenillard sur le port B ( B0 a B7) toutes les secondes une ampoule s'allume .
Pendant ce temps que le chenillard chenille , on désire (sur le port C) aussi allumé une ampoule toutes 3 secondes (C.3) et une autres toutes les 7 secondes (C.7)
Pour faire ça il y a une solution très simple: c'est d'utiliser un 20 M2 et son multitâche (3 tâches)

Sinon, cette solution qui utiliserait le timer et permettrait de faire autre chose : (j'ai fait un chenillard inversé !)

Code:
#picaxe 28X2
symbol per1 = 3
symbol per2 = 7
symbol per3 = 2

symbol tfin1 = 2
symbol tfin2 = 3
symbol tfin3 = b4
symbol flag = bit0


flag = 0
b3 =0
settimer t1s_8
do
 
b10=timer//per1 
if b10 = 0 then: high C.3 :endif
if b10 = tfin1 then : low C.3 : endif

b11 = timer//per2
if b11 = 0 then: high C.7 : endif
if b11 = tfin2 then : low C.7 : endif

b12 = timer//per3
if b12 = 0 and flag = 0 then 
	high b3
	inc b3
	flag = 1
	tfin3 = timer +1
endif
if timer = tfin3 then
	flag = 0
	low b3
	if b3 = 8 then: b3 =0: endif
endif

loop
 

PieM

Senior Member
Et pour le fun 4 sorties qui clignotent à leur rythme sans utiliser la moindre pause.

Code:
#picaxe 28X2


settimer t1s_8
do
 
b10=timer//7 
if b10 = 0 then: high C.3 :endif
if b10 = 3 then : low C.3 : endif

b11 = timer//3
if b11 = 0 then: high C.7 : endif
if b11 = 2 then : low C.7 : endif

b12 = timer//2
if b11 = 0 then: high C.5 : endif
if b11 = 1 then : low C.5 : endif

b13 = timer//4
if b11 = 0 then: high C.4 : endif
if b11 = 1 then : low C.4 : endif

loop
Si tu trouves comment ça marche, jojojo te paie un verre d'élixir :rolleyes:
 

jojojo

Senior Member
Bon.
On part de 34286 Modulo 7, soit 0, donc, on allume.
Mais, pendant ce temps là le compteur tourne.
Jusqu'a ce que la valeur de xxxxx(le timer) modulo 7 passe à 3 (pas calculé à combien ça se produit, mais ...). Là, on éteint.
Fin du premier acte (vrai, sans pause).
Je suppose, que les actes suivant son destinés a assurer un certain coté aléatoire, d'ou les modulo's divers et variés (3,2,4).

Bon, j'ai soif, là :p
 

PieM

Senior Member
Y a rien du tout d'aléatoire !
Il y a 3 séquences imbriquées parfaitement déterminées.
 

dje8269

Senior Member
moi perso j'en suis la .

J'ai bon pour les 1 secondes niveau calcul c'est deja pas mal ;

Attention ceci est juste une ebauche , je suis a fond dessus ....... ca fonctionne pas encore ...... car je me mélange les pinceaux

PS : ton chenillard chenille pas PieM ( enfin sur mon PE)

Code:
#PICAXE 28X2

' 1 second à 8Mhz corresspond a 1000000/32 = 31250
' determination du settimer pour obtenir un flag toutes les secondes.65536-31250 = 34286
' avec settimer a 34286 , le timer s'incrementeras de 1 toutes les secondes voila ma base de depart

'Avec 1 secondes comme base , calcul de la difference de temps pour savoir quand travailler.



settimer 34286

do
b3 = timer - b2			' b3 est le resultat du temps actuel - moins la derniere prise de temps
					'Si b3 superieur ou egal a 1 cela singifie qu'une seconde est passée donc changement d'etat si on fait rien
if b3 >= 1 then
	low b1
	inc b1
	high b1
	b2 = timer
end if

b4 = timer - b5

if b4 > 3 then
toggle C.3
b5 = timer
end if
b5 = timer 

 

 
 


loop
 

PieM

Senior Member
[
PS : ton chenillard chenille pas PieM ( enfin sur mon PE)
Si je t'ai dit qu'il était inversé:
il allume tout le port B progressivement et il part en chenillard inversé avec temps d'extinction / allumage réglable.
pour le fun :rolleyes:
 

BESQUEUT

Senior Member
Et pour le fun 4 sorties qui clignotent à leur rythme sans utiliser la moindre pause.

Code:
#picaxe 28X2


settimer t1s_8
do
 
b10=timer//7 
if b10 = 0 then: high C.3 :endif
if b10 = 3 then : low C.3 : endif

b11 = timer//3
if b11 = 0 then: high C.7 : endif
if b11 = 2 then : low C.7 : endif

b12 = timer//2
if b11 = 0 then: high C.5 : endif
if b11 = 1 then : low C.5 : endif

b13 = timer//4
if b11 = 0 then: high C.4 : endif
if b11 = 1 then : low C.4 : endif

loop
Si tu trouves comment ça marche, jojojo te paie un verre d'élixir :rolleyes:
Ça m'étonnerait que ça marche en prenant le modulo dans b13, puis en testant b11...
Sinon, c'est bien le principe du lapin fou pour des tâches répétitives.

Si on souhaite vérifier qu'une touche est enfoncée pendant n tickcounts il faut planifier une tâche à exécuter à : maintenant+ n tickcounts
Du coup on peut utiliser un mécanisme universel en calculant l'heure du prochain événement qui est donc planifié à chaque fois.
La méthode PieM à le gros avantage d'être très simple pour des tâches répétitives.
En terme d'optimisation de la vitesse de la boucle principale, il faut calculer un modulo avant chaque test.
Avec le système de l'heure planifiée, il faut seulement tester si l'heure égale timer. C'est normalement sensiblement plus rapide.
Le principe de cette optimisation c'est qu'en général les tests ne sont pas positifs (Le lapin tourne en rond sans rien faire et regarde sa montre à chaque tour). Ils doivent être le plus simple possible.
Dans le dernier exemple de PieM, il y a pour chaque lampe un calcul de modulo et 2 tests.
On peut faire plus performant coté boucle principale avec un seul test par lampe, mais le code pour reprogrammer le prochain changement est un peu plus compliqué.
 
Last edited:

dje8269

Senior Member
@ PieM

Si je t'ai dit qu'il était inversé:
il allume tout le port B progressivement et il part en chenillard inversé avec temps d'extinction / allumage réglable.
J'insiste !!! je copie/colle ton programme , il n'allume pas le port B . seul B.0 s'allume de temps en temps !!!!!
 

BESQUEUT

Senior Member
moi perso j'en suis la .
C'est plus simple que ça :
Code:
   H_changement=timer + délai_entre_changement

do
    If Heure_changement=Timer then
        faire le travail
        Heure_changement=timer + délai_entre_changement
    endif
loop
NB : ce code marche dans 100% des cas.
C'est seulement si on teste
Timer > Heure_changement
que le retour à zéro pose problème.
 

PieM

Senior Member
Ça m'étonnerait que ça marche en prenant le modulo dans b13, puis en testant b11...
si, ça marche mais pas avec les bonnes valeurs. Pb de copié collé...


J'insiste !!! je copie/colle ton programme , il n'allume pas le port B . seul B.0 s'allume de temps en temps !!!!!
chez moi ça marche...
essaie celui là . j'ai ajouté un temps entre extinction et allumage du chenillard sinon la simulation se fait mal. il faudrait une base de temps plus faible.

Code:
#picaxe 28X2
symbol per1 = 3
symbol per2 = 7
symbol per3 = 2

symbol tfin1 = 2
symbol tfin2 = 3
symbol tfin3 = b4
symbol flag = bit0


flag = 0
b3 =0
settimer t1s_8
do
 
b10=timer//per1 
if b10 = 0 then: high C.3 :endif
if b10 = tfin1 then : low C.3 : endif

b11 = timer//per2
if b11 = 0 then: high C.7 : endif
if b11 = tfin2 then : low C.7 : endif

b12 = timer//per3
if b12 = 0 and flag = 0 then 
	high b3
	tfin3 = timer +1
	flag =1
endif
if timer = tfin3 then
	low b3
	b3 = b3+flag
	flag = 0
	
	if b3 = 8 then: b3 =0: endif
endif

loop
 

dje8269

Senior Member
Voila pour moi . pouvez vous me dire si ca fonctionne ! car je pense qu'avec le simu les valeurs de temps sont complètement faussées .

Je me suis donné a fond pour pas être ridicule

Code:
#PICAXE 28X2

' 1 second à 8Mhz corresspond a 1000000/32 = 31250
' determination du settimer pour obtenir un flag toutes les secondes.65536-31250 = 34286
' avec settimer a 34286 , le timer s'incrementeras de 1 toutes les secondes voila ma base de depart

'Avec 1 secondes comme base , calcul de la difference de temps pour savoir quand travailler.


high b1

settimer 34286

do

'############### Chenille toute les secondes
	b2 = timer - b3				' calcul le temps actuel moins le temps enregistrer .
		if b2>=1 then			' Si superieur ou egal a 1 , signifie qu'une seconde ou plus est passé
		
			toggle b1
			inc b1
				if b1=8 then	' remet a 0 pour la chenille quand on arrive a 8
					b1 = 0
				end if
			toggle b1
				
			b3 = timer			' enregistre le temps actuel dans une variable pour le temps temporaire
		end if
		
		
'############## Allumage toutes les 3 secondes		
b4 = timer - b5
	
		if b4>=3 then
			toggle C.3
			b5 = timer
		end if

'##############Allumage toutes les 7 secondes		
b6 = timer - b7
	
		if b6>=7 then
			toggle C.7
			b7 = timer
		end if
loop
 

PieM

Senior Member
C'est plus simple que ça :
Je ne comprends pas trop car si l'heure est définie dans un autre programme qui boucle en principe, elle va changer en permanence !
et quand sort-on de la boucle do loop ?

Un exemple ?
 

dje8269

Senior Member
@PieM
Ahhh ben c'est du propre !!!!!

Je copie/colle ton programme , meme probleme.....

je me dis , bon c'est PieM quand même , le ^probleme viens de moi .....

Je mets en cause le PE ( car je suis en V5 moi encore) . je regarde les options et je vois l'onglet je fonce dessus . la je vois vitesse entre chaques etape 100ms ..... je change en baissant a 50ms et paf ca fonctionne !!!!

A quelle valeur mettez vous ceci chez vous ? car je comprends maitenant je trouvais que c'etait nul car ca ramait la simu .... pfffffff
 

PieM

Senior Member
Voila pour moi . pouvez vous me dire si ca fonctionne ! car je pense qu'avec le simu les valeurs de temps sont complètement faussées .

Je me suis donné a fond pour pas être ridicule
Ben c'est loin d'être ridicule. ça fonctionne parfaitement. La seule chose c'est que les temps allumage extinction sont identiques avec ce principe.
 

dje8269

Senior Member
@PieM

Ton chenillard , chenille bizaremment je trouve !!!!!! les lumieres sont toutes eteintes pendant un cour instant .Bouhhh il as triché PieM :p
 

PieM

Senior Member
@ dje8269

pour expliciter ce que j'ai fait pour un (et plusieurs) clignotant:

En supposant un allumage tous les Periode pour une durée de Durée

j' écris :
b10=timer//periode
donc b10 est le reste de la division de timer par la période de mon clignotant.
Quand b10 est à 0, c'est que l'heure est arrivée car je suis sur un multiple de Periode.
d'où : if b10 = 0 then: high C.3 :endif

par contre si b10 est égal à x par exemple, c'est que j'ai passé ce temps de X secondes et si X correspond à ma Durée d'allumage, je peux éteindre.
if b10 = Durée then: LOW C.3 :endif

donc prog général:

b10=timer//periode
if b10 = 0 then: high C.3 :endif
if b10 = Durée then: low C.3 :endif


Ton chenillard , chenille bizaremment je trouve !!!!!! les lumieres sont toutes eteintes pendant un cour instant .Bouhhh il as triché PieM
Je t'ai expliqué pourquoi: je règle les temps d'allumage et d'extinction indépendamment sur le chenillard aussi . Tu peux simplifier bien entendu.
 
Last edited:

BESQUEUT

Senior Member
Je ne comprends pas trop car si l'heure est définie dans un autre programme qui boucle en principe, elle va changer en permanence !
et quand sort-on de la boucle do loop ?

Un exemple ?
Pas PE sous la main, mais quelque chose dans le genre #13 doit marcher.
Par contre, sans précautions, les codes qui utilisent le signe > merdent de temps en temps...
 

dje8269

Senior Member
@PieM

J'ai dus rajouter ceci a ton code .

b10=timer//per1
sertxd (#b10,"=",#timer,"/",#per1,13)
Je crois que j'ai compris . c'est extrêmement malin ...... le coup de la division pour voir les périodes je dis chapeau !! . Je suis tout de même allez voir ce que signifiait // car je ne connaissait pas , je croyais que c'était division . et en fait non , c'est justement le reste de la division . tout reside la dedans .

A quelle vitesse mettez vous la simulation entre chaque étapes ?
Que signifie "t1s_8" au lieu des chiffres que j'ai mis ?
quelle est la méthode la plus précise les pauses ou le timer ? car techniquement la septième led devrais s'allumée pile à 7 secondes du départ ?
Une autre question hors sujet , quelle est la vitesse "réel" du PICAXE entre chaque étapes ? par rapport au 20 ms ( minimum) de PE ( car je me rends compte que jai fais mon programme a 100ms, et donc les temps d'appui sur les BP pourront etre mal percus en vrai. je vais donc re-testé mon programme vitesse max !)
 

BESQUEUT

Senior Member
Je ne comprends pas trop car si l'heure est définie dans un autre programme qui boucle en principe, elle va changer en permanence !
et quand sort-on de la boucle do loop ? Un exemple ?
Désolé : je n'avais pas bien compris le sens de votre remarque.
Code:
   H_1=timer + délai_1
   H_2=timer + délai_2

do
    If H_1=Timer then
        'faire le travail N°1...
        low Amp
        if Amp=7 then
            Amp=0
        else
            inc Amp
        endif
        high Amp
        H_1=timer + délai_1
    endif

    If H_2=Timer then
        ' faire le travail N°2
        Toggle Sortie    ' autre led qui clignote à une vitesse différente...
        H_2=timer + délai_2
    endif

    if Flag=1 then 
         ' traiter ce qui a été reçu en tâche de fond
    endif

loop
Est-ce plus clair comme ça ?
 

PieM

Senior Member
Chez moi la simulation est au mini soit 20ms.
Mais cela n' aucun rapport avec ce que sera la vitesse avec un picaxe!
il faut se méfier de la simulation pour ce qui concerne les temps !

t1s_8 est une constante précalculée par Rev-Ed pour un settimer de 1 seconde avec une horloge à 8 MHz
t1s_4 est la même chose pour une horloge à 4 MHz.

timer est plus précis que pause si on utilise le timer normalement sans remise à zéro, car il n'y a pas d'erreur de cumul.

Ne compte pas avoir une précision en simulation; ce n'est pas possible !
Il faut arrêter avec la simulation et passer au mode réel !
c'est là que tu vas debugger ton programme.
 

BESQUEUT

Senior Member
Chez moi la simulation est au mini soit 20ms.
Mais cela n' aucun rapport avec ce que sera la vitesse avec un picaxe!
il faut se méfier de la simulation pour ce qui concerne les temps !
idem
timer est plus précis que pause si on utilise le timer normalement sans remise à zéro, car il n'y a pas d'erreur de cumul.

Ne compte pas avoir une précision en simulation; ce n'est pas possible !
Il faut arrêter avec la simulation et passer au mode réel !
c'est là que tu vas debugger ton programme.
Même avis :
La simulation permet de mettre au point la logique du programme ; le réel permet de régler les détails : tempo, ergonomie,...
 

dje8269

Senior Member
Pour moi oui .

Je me suis permis de compléter votre programme pour qu'il soit plus clair pour un débutant comme moi .

Code:
 #PICAXE 28X2
 
settimer 34286


symbol delai_1 = 1
symbol delai_2 = 5
symbol H_1 = b1
symbol H_2 = b2
 
 H_1=timer + delai_1
   H_2=timer + delai_2

do
    If H_2=Timer then
        sertxd ("5",13)
        H_2=timer + delai_2
    endif

    If H_1=Timer then
        sertxd ("1")
        H_1=timer + delai_1
    endif

loop
 

BESQUEUT

Senior Member
Je me suis permis de compléter votre programme pour qu'il soit plus clair pour un débutant comme moi .
BRAVO
C'est peut-être en faisant des erreurs que vous apprenez, mais c'est aussi en faisant de touts petits programmes que l'on pige des concepts pas évidents au départ.
Cela dit, à partir de ce concept de base, il va falloir complexifier un peu pour un "vrai" programme.
Le problème, c'est que si une tâche est un peu longue (sous-programme pas aussi "collaboratif" que prévu...)
le lapin risque de rater une heure ! (et après l'heure, c'est plus l'heure...)
La correction la plus simple est de remplacer le signe = par < (ou plutôt <= )
Mais que se passe-t-il si Timer = 65534 ?
H2= Timer + 5 = 3 (c'est le gag du retour vers le futur...)
Du coup H2 est tout de suite < à Timer et ça merdouille...
Bon ça ne se produit pas souvent et ce n'est peut-être pas grave.
Mais si c'est important, il faut gérer le débordement du timer.
 
Last edited:

BESQUEUT

Senior Member
Pour faire ça il y a une solution très simple: c'est d'utiliser un 20 M2 et son multitâche (3 tâches)
Eh oui... le vrai multitâches (VAX VMS puis UNIX et donc LINUX...) a fini par remplacer le "multitâches collaboratif"
En plus sont apparus les processeurs multi-c&#339;urs bien plus adaptés au multi-tâche.
Le seul regret pour le multi tâches des PICAXEs, c'est l'incompatibilité entre les commandes qui gèrent le port série.
Mais pour ce chenillard, ça devrait marcher.

NB qui n'a rien à voir à propos de l'article Wiki sur le Lisa :
Il est dit que les Macs étaient particulièrement lents à cause du multitâches collaboratif.
Je pense plutôt que c'était lié à la façon de gérer l'écran en bitmapping, seule solution pour faire du WYSIWIG.
A l'époque le concurrent (IBM pour ceux qui n'étaient pas nés)
était le roi des "numbers cruncher" (Multiplan)
L'affichage était super rapide grâce à des écrans de 25 lignes et 80 colonnes (qui soit dit en passant existent toujours dans Windows 7 : fenêtre DOS...)

A coté, les pauvres macs suaient comme des b&#339;ufs pour dessiner chaque chiffre pixel par pixel...
 

dje8269

Senior Member
La correction la plus simple est de remplacer le signe = par < (ou plutôt <= )
Waouhhhh, je me surprends moi même , car si vous regardez mon programme c'est exactement ce que j'ai fais ! en pensant exactement à ça . En fait on se rend compte que des fois, des horloges ne passe pas ou saute une etape, en les regardant avec le sertxd . C'est pkoi j'ai mis le signe >= car je me suis dis si jamais ça dépasse tant pis il prendras quand même en compte mais avec un tout petit peu de retard , ca vaut mieux que rien du tout .
 

BESQUEUT

Senior Member
Waouhhhh, je me surprends moi même , car si vous regardez mon programme c'est exactement ce que j'ai fais ! en pensant exactement à ça . En fait on se rend compte que des fois, des horloges ne passe pas ou saute une etape, en les regardant avec le sertxd . C'est pkoi j'ai mis le signe >= car je me suis dis si jamais ça dépasse tant pis il prendras quand même en compte mais avec un tout petit peu de retard , ca vaut mieux que rien du tout .
Encore bravo (et en plus vous avez corrigé mon énorme erreur de sens de l'inégalité) Reste le problème du retour vers le futur...
Mais là, je vais devoir vous quitter...
 

BESQUEUT

Senior Member
Sinon, cette solution qui utiliserait le timer et permettrait de faire autre chose : (j'ai fait un chenillard inversé !)

Code:
#picaxe 28X2
symbol per1 = 3
symbol per2 = 7
symbol per3 = 2

symbol tfin1 = 2
symbol tfin2 = 3
symbol tfin3 = b4
symbol flag = bit0


flag = 0
b3 =0
settimer t1s_8
do
 
b10=timer//per1 
if b10 = 0 then: high C.3 :endif
if b10 = tfin1 then : low C.3 : endif

b11 = timer//per2
if b11 = 0 then: high C.7 : endif
if b11 = tfin2 then : low C.7 : endif

b12 = timer//per3
if b12 = 0 and flag = 0 then 
	high b3
	inc b3
	flag = 1
	tfin3 = timer +1
endif
if timer = tfin3 then
	flag = 0
	low b3
	if b3 = 8 then: b3 =0: endif
endif

loop
PieM utilise le modulo pour définir les périodes d'extinction et d'allumage.
Le gros soucis, (outre le calcul du modulo et différents tests à chaque boucle)
c'est que à chaque boucle un test est positif !

Hors je rapelle que le principe du lapin fou, c'est de n'agir que si c'est l"heure.

En gros, le lapin de PieM est encore plus fou que celui de Lewis Caroll :
il passe son temps à allumer une ampoule déjà éclairée,
du coup, le temps de boucle moyen est certainement assez mauvais, et la réactivité très perfectible.
 

PieM

Senior Member
Mais que se passe-t-il si Timer = 65534 ?
il suffit de mettre à 0 le timer après qu'il a atteint un nombre entier de (delai_1 * delai_2 * ...) car on se retrouve dans les conditions de départ. (en fait il faudrait le PPCM, plus petit commun multiple pour certains puristes..)

il passe son temps à allumer une ampoule déjà éclairée,
Il ne le fait que si l'heure ne change pas !

c'est que à chaque boucle un test est positif !
ben non. Entre l'heure de début et l'heure de fin aucun test n'est positif. (et un test demande 550 µs)
 
Last edited:

BESQUEUT

Senior Member
il suffit de mettre à 0 le timer après qu'il a atteint un nombre entier de (delai_1 * delai_2 * ...) car on se retrouve dans les conditions de départ. (en fait il faudrait le PPCM, plus petit commun multiple pour certains puristes..)
Ca ne suffit pas : il faut aussi mettre à jour les heures planifiées :
Code:
 H_1=timer + délai_1
   H_2=timer + délai_2

do
    If H_1>=Timer then
        'faire le travail N°1...
        low Amp
        if Amp=7 then
            Amp=0
        else
            inc Amp
        endif
        high Amp
        H_1=timer + délai_1
    endif

    If H_2>=Timer then
        ' faire le travail N°2
        Toggle Sortie    ' autre led qui clignote à une vitesse différente...
        H_2=timer + délai_2
    endif

' Changement d'heure pour éviter le bug Delorean
    if Timer > 32768 then
            Timer=Timer-32767
            H_1=H_1-32767
            H_2=H_2-32767
            ' etc... pour toutes les heures planifiées
    endif

    if Flag=1 then 
         ' traiter ce qui a été reçu en tâche de fond
    endif

loop
En outre, votre technique conduit à refaire la mise à l"heure très souvent alors que ce n'est nécessaire que quelques fois par jour.
Il ne le fait que si l'heure ne change pas !
ben non. Entre l'heure de début et l'heure de fin aucun test n'est positif. (et un test demande 550 µs)
Je me suis mal exprimé :
Quand l'heure est atteinte, le lapin allume l'ampoule à chaque boucle pendant toute une seconde.

Dans votre exemple #14, le test sur b3 est positif une fois sur 2 ce qui en moyenne est énorme.
 
Last edited:

PieM

Senior Member
D'après le programme , H1 et H2 sont planifiés à l'initilisation, à partir de la même valeur timer et s'incrémentent chacun de delai1 et delai2.

quand vous écrivez :

Code:
 If H_1=Timer then
        'faire le travail N°1...
        low Amp
        if Amp=7 then
            Amp=0
        else
je suis désolé mais votre test est positif tout pendant que timer = H1 , donc votre lapin passe son temps à faire et refaire le travail N°1 tout pendant que l'heure n'a pas changé.

Un peu comme avec mon programme non ? :rolleyes:

En outre, votre technique conduit à refaire la mise à l"heure très souvent alors que ce n'est nécessaire que quelques fois par jour.
Il suffit de prendre un nombre entier de multiples, inférieur à 65535
 

BESQUEUT

Senior Member
je suis désolé mais votre test est positif tout pendant que timer = H1 , donc votre lapin passe son temps à faire et refaire le travail N°1 tout pendant que l'heure n'a pas changé.

Un peu comme avec mon programme non ? :rolleyes:
FAUX : vous n'avez pas cité tout mon code.
Dès la première exécution, on re-programme un nouveau rendez-vous dans le futur.
Donc le test n'est positif qu'une fois.
 

dje8269

Senior Member
Bonjour à tous,

Bon vous allez super vite pour moi !!!!!

Même pas le temps de boire un café , en me chauffant les neurones, pour faire un bout de code .

Donc pour résumé , le lapin doit executer une action a chaque foisque c'est l'heure de le faire .
Donc il doit verifier a chaque fois si c'est l'heure de faire une action .
Donc beaucoup de condition dans la boucle principal . mais qui ne doivent pas s'executer tout le temps . Seulement quand c'est l'heure , et faut pas que ce soit tout le temps l'heure!!! si j'ai compris

Voila ma contribution pour ce matin Est-ce bon ?

Code:
#PICAXE 28X2
 
settimer 34286


symbol Freq = 5		'Frequence d''allumage en secondes
symbol duree = 4		'Durée d'un allumage en seconde
symbol Heure_On = b1	'Heure d'allumage
symbol Heure_Off = b2	'Heured'exctinction


Heure_On = timer + Freq
Heure_off = Heure_On + Duree	



do

    	If Heure_ON <= Timer then
        high 0
        Heure_ON = timer + Freq		'Ré armement de l'heure
 	   endif
    
	If Heure_Off <= Timer then
        low 0
        Heure_off = Heure_On + Duree	'Ré armement de l'heure
	endif
    
loop
Dans ce code . Je définie, pendant combien de temps et a quelle fréquence en allume b0
 

dje8269

Senior Member
Désolé j'ai pas compris une partie . celle du changement d'heure .

J'ai bien compris qu'il fallait remettre l'heure a zéro a un moment. Mais j'étais comme PieM , la remettre a zéro quand elle arrive a la fin moins la plus grosse durée en fait !!
Je ne comprends pas le "32768" et a quoi correspond ce chiffre


if Timer > 32768 then
Timer=Timer-32767
H_1=H_1-32767
H_2=H_2-32767
' etc... pour toutes les heures planifiées
endif
 

BESQUEUT

Senior Member
Désolé j'ai pas compris une partie . celle du changement d'heure .

J'ai bien compris qu'il fallait remettre l'heure a zéro a un moment. Mais j'étais comme PieM , la remettre a zéro quand elle arrive a la fin moins la plus grosse durée en fait !!
Je ne comprends pas le "32768" et a quoi correspond ce chiffre
32768 est la moitié de 65536, c'est à dire 1 de plus que le plus grand nombre manipulable par un PICAXE (2^16)

Quand Timer dépasse 32768, il peut y avoir des rendez-vous programmés dans le futur, donc entre 32769 et 65535
En enlevant 32767, on est sur de ne pas passer en dessous de zéro (ce qui aurait l'effet inverse de celui recherché...)
La boucle principale doit être aussi indépendante que possible des différents sous-programme. Elle ne peut dépendre de valeurs annexes utiles seulement aux sous-programmes.
 
Top