PDA

View Full Version : Chenillard méthode du lapin fou !



dje8269
11-01-2014, 11:16
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 (http://www.picaxeforum.co.uk/showthread.php?19320-utilisation-du-timer-d-un-picaxe-28X1&p=184251&viewfull=1#post184251)

BESQUEUT
11-01-2014, 12:26
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...

jojojo
11-01-2014, 13:21
Et Alice, dans tout ça ? :cool:

BESQUEUT
11-01-2014, 13:31
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.

PieM
11-01-2014, 14:19
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é !)



#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
11-01-2014, 14:30
Et pour le fun 4 sorties qui clignotent à leur rythme sans utiliser la moindre pause.



#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
11-01-2014, 15:40
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
11-01-2014, 15:49
Y a rien du tout d'aléatoire !
Il y a 3 séquences imbriquées parfaitement déterminées.

dje8269
11-01-2014, 15:59
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)


#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
11-01-2014, 16:15
[
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
11-01-2014, 16:20
Et pour le fun 4 sorties qui clignotent à leur rythme sans utiliser la moindre pause.



#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é.

dje8269
11-01-2014, 16:30
@ 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
11-01-2014, 16:31
moi perso j'en suis la .
C'est plus simple que ça :


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
11-01-2014, 16:39
Ç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.



#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
11-01-2014, 16:49
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


#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
11-01-2014, 16:52
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
11-01-2014, 16:56
@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
11-01-2014, 16:59
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
11-01-2014, 16:59
@PieM

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

PieM
11-01-2014, 17:14
@ 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.

BESQUEUT
11-01-2014, 17:39
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
11-01-2014, 18:45
@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
11-01-2014, 19:30
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.


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
11-01-2014, 19:35
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
11-01-2014, 19:40
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
11-01-2014, 19:47
Pour moi oui .

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


#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

dje8269
11-01-2014, 19:54
Il faut arrêter avec la simulation et passer au mode réel !
J'espere lundi si ma commande est arrivée . En tout cas je pense être prêt pour debugger tout seul !!! ;)

BESQUEUT
11-01-2014, 21:29
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.

BESQUEUT
11-01-2014, 21:43
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œ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œufs pour dessiner chaque chiffre pixel par pixel...

dje8269
11-01-2014, 21:46
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
11-01-2014, 21:57
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
12-01-2014, 07:41
Sinon, cette solution qui utiliserait le timer et permettrait de faire autre chose : (j'ai fait un chenillard inversé !)



#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
12-01-2014, 08:05
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)

BESQUEUT
12-01-2014, 08:29
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 :


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.

PieM
12-01-2014, 08:37
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 :


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
12-01-2014, 08:46
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
12-01-2014, 08:53
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 ?


#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

PieM
12-01-2014, 08:53
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.

Exact. Sorry !!

dje8269
12-01-2014, 09:15
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
12-01-2014, 09:29
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.

BESQUEUT
12-01-2014, 09:33
Dans ce code . Je définie, pendant combien de temps et a quelle fréquence en allume b0
On peut le voir comme ça, mais ce n'est pas optimal car il y a deux tests alors qu'un seul suffit.
Voir mon post #4

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"

C'est effectivement assez déstabilisant de ne pas envisager l'ensemble du problème mais seulement ses événements intermédiaires...
En gros le programme se résume à :
Si je reçoit un signal de la télécommande, allumer la première lampe. POINT FINAL

Et c'est tout ?
Oui : c'est tout !

Par contre, quand on allume la première lampe, il faut poster un message pour l'éteindre dans n secondes et allumer la suivante...

dje8269
12-01-2014, 09:39
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é...)
Ok , j'ai compris le principe , mais j'ai du mal a visualiser , je vais bosser dessus .


On peut le voir comme ça, mais ce n'est pas optimal car il y a deux tests alors qu'un seul suffit.
??? comment un seul test peut définir si c'est l'heure d'allumer ou d'éteindre ? car il y as une différence entre durée d'allumage et fréquence d'allumage ..

BESQUEUT
12-01-2014, 09:43
??? comment un seul test peut définir si c'est l'heure d'allumer ou d'éteindre ? car il y as une différence entre durée d'allumage et fréquence d'allumage ..
Voir #41
Quand on planifie la tâche "allumer la lampe", on s'en fout de ce qui se passera plus tard !

C'est quand on planifie la tâche "éteindre la lampe" que l'on tient compte de cette autre durée


#PICAXE 28X2

settimer 34286


symbol Freq = 5 'Frequence d'allumage en secondes
symbol duree = 4 'Durée d'un allumage en seconde
symbol H1 = w27 'Heure tache 1

symbol D_E=b3 ' durée d'extinction
symbol Flag=bit0 ' vrai si période d'allumage. On peut aussi tester directement l'état de la broche.

D_E=Freq-duree
H1 = timer + D_E
flag=false



do

If H1>= Timer then
if flag=false then
flag=true
high 0
H1=timer + D_E
else
flag=true
low 0
H1=timer + duree
endif

endif

if Timer >32768 then
H1=H1-32767
Timer=Timer-32767
endif

loop
Exemple non testé : je n'ai pas PE sous la main...

On n'utilise plusieurs H1, H2, ... que si on a des tâches indépendantes.
Dans le cas de la lampe, elle ne peut être que allumée ou éteinte. Donc on peut programmer la suite à chaque rendez-vous, et une seule variable suffit, donc un seul test par boucle.

Ca parait dingue d'optimiser à ce point la boucle principale.
Pour des durées exprimées en seconde, c'est du luxe.
Pour tester des boutons avec des durées exprimées en tickcount sur un Picaxe, c'est nécessaire si on souhaite une bonne réactivité.
Pour lire plusieurs ports série "à la volée" (pas sur un PICAXE...) c'est crucial.

PieM
12-01-2014, 09:44
Attention a bien prendre des variable Word pour les heures!
sinon le lapin a la myxomatose...

BESQUEUT
12-01-2014, 10:04
Attention a bien prendre des variable Word pour les heures!
sinon le lapin a la myxomatose...
Excellente remarque !
Et raison de plus pour optimiser le nombre de variables H

dje8269
12-01-2014, 13:13
Bon voila environ une heure que je galere .

En fait votre code ne fonctionnais pas sous PE .
J'ai donc recherché a vous comprendre , puis a trouver l'erreur puis a corriger .
Et hop voila un nouveau code .


#PICAXE 28X2

settimer 34286
symbol false = 0
symbol true = 1
symbol H1 = w27 'Heure tache 1 stocke dans une variable word. car sinon probleme arrive a 255
symbol Freq = 5
symbol duree = 4 'Durée d'un allumage en seconde
symbol D_E=b3 'durée d'extinction
symbol flag=bit0 'vrai si période d'allumage. On peut aussi tester directement l'état de la broche.


flag=false 'mise du flag a 0 car la lumiere est eteinte au demarrage

D_E=Freq-duree

H1 = timer + D_E 'comme la lumiere est eteinte au depart. l'heure de la prochaine action seras la duree d'extinction

do

If H1 <= Timer then 'si c'est l'heure de faire quelque chose ou si l'heure a été depassée alors on agit

'######## On sait qu'il faut agir , mais on sait pas quoi faire encore

if flag = false then 'si la lumiere est eteinte alors
high 0 'On allume
flag=true 'on passe a 1 le flag pour dire qu'on a allumé
H1=timer + duree 'on determine l'heure de la prochaine action c'est a dire l'extinction ou la fin de l'allumage comme on veut( c'est pareil).
'qui est egale au temps + le temps que l'on veille quelle s'allume

else

'Comme la lumiere n'est pas eteinte , elle est forcemenet allumé donc
low 0 'On l'eteint
flag=false 'on passe le flag a 0 pour dire qu'on l'a eteinte
H1=timer + D_E 'on determine l'heure de la prochaine action qui seras de l'allumée ou la fin de l'extinction c'est aussi pareil
'qui est egale au temps + Duree d'extinction
end if

endif

if Timer >32768 then ' la je seche, -je sais pkoi il faut faire ca,
H1=H1-32767 ' je sais comment c'est fait
Timer=Timer-32767 ',mais je comprends pas comment ca marche
endif

loop

dje8269
12-01-2014, 13:23
Pour les erreurs . plusieurs choses .

déjà pour la détermination de l'heure . le signe était inversé .
C'est quand le temps "réel" est égal, mais aussi supérieur (c'est a dire qu'on l'as dépassé), à l'heure que l'on a déterminée, qu'il faut agir !!
Donc "If H1 <= Timer then"

Après quand on allume l'ampoule , le nouveau temps à calculer, c'est le temps + la durée qu'on veuille qu'elle reste allumée ou la durée quand on veut l'éteindre . Mais pas la durée du temps qu'elle doit rester éteinte .
Donc "H1=timer + duree"

et enfin dans la deuxième partie vous avez marque flag=true . dans ce cas le flag est toujours true . il faut donc le mettre à false quand on a éteint la lumière ..
Donc "low 0 : flag=false "

Voila, pkoi j'ai autant galeré !! en trouvant une erreur y'en avait une autre , puis une autre lol . je trouve ça déjà pas mal sans PE d'avoir écrit ces lignes ; Attention je me moque pas !!! car moi j'ai PE c'est plus facile

PieM
12-01-2014, 14:31
En outre, il y a un risque de dérive du temps puisqu'on incrémente l'heure par rapport au timer en cours:
Quand on test H1, timer peut avoir dépassé H1. (si on a une base de temps en 1/100 de s c'est facile ..)
ensuite on génère une action, ici mettre une sortie à 1 ou à 0, mais ça peut être une action plus longue.
quand on revient on ajoute une durée au temps en cours ... qui a changé. Donc en fait la durée réelle sera plus longue.

Si on veut que l'évènement se déroule toutes les X , il faut ajouter des durées à la valeur courante de l'horloge et non à la valeur du timer.
donc : H1=H1 + duree

Il faut savoir en fait si on veut respecter une horloge ou des durées ....

dje8269
12-01-2014, 15:00
Si on veut que l'évènement se déroule toutes les X , il faut ajouter des durées à la valeur courante de l'horloge et non à la valeur du timer.
donc : H1=H1 + duree

Je suis d'accord. Comme dirais un proverbe chinois " petit décalage peu devenir grand , à la longue" :D


Il faut savoir en fait si on veut respecter une horloge ou des durées ....
sans rentré dans la philosophie , il y as une relation . Étant donné qu'une durée est la différence entre deux horloges . si on respecte l'horloge, normalement on respecte les durées .

Je pense qu'il est préférable de respecter l'horloge quitte a accepté une petite erreur de durée . Car plusieurs petites erreurs de durée ne gène en rien(recalcul a chaque fois) voir même on peut les compenser.
Mais des petites erreurs d'horloge peuvent a la fin engendrer de grosses erreur car elles , elles s'accumulent, contrairement a la durée qui se recalcule a chaque fois

PieM
12-01-2014, 15:20
si on respecte l'horloge, normalement on respecte les durées .

non avec le test H <= timer , timer peut être en avance.
quand on fera H +durée , le test suivant s'il se fait à l'heure engendre une durée plus courte.
Soit on veut quelque chose de précis à court terme avec les durées, soit à long terme en ne calculant pas les heures à partir du timer en cours.

Sur du long terme, le calcul précis de l'instant de l'action répétitive sans avoir recours à des cumuls de temps est la méthode du modulo (//) . Il y en a d'autres...

BESQUEUT
12-01-2014, 17:21
Bravo pour toutes vos corrections !
Et je copierai 1000 fois :
"Quand on teste si une heure est dépassée, il faut changer le sens de l'inégalité"

Petite explication pour le test "Delorean"

#PICAXE 28X2

'Si on assimile la durée maximale du timer (65535) à une journée, de 0 à 24 h,
' sachant que si l'horloge atteint minuit, elle explose :

if Timer >32768 then ' Si l'heure dépasse midi
H1=H1-32767 ' On enlève 12 h à tous nos rendez-vous
' H2=H2-32767
' etc...
Timer=Timer-32767 ', et aussi à l'horloge.
endif

loop

Supposons qu'on ait planifié un rendez-vous à 2h de l'après-midi
A midi, le rendez-vous est donc dans 2h : OK ?

A midi une seconde,on retarde la montre de 12h, mais on enlève aussi 12h à tous les rendez-vous.
Du coup, notre rendez-vous est maintenant à 2 h du mat.
Notre horloge marque maintenant 0h et des broutilles. Notre rendez-vous est dans 2heures.
Tout va bien...
Le lapin peut continuer à tourner en rond avec sa montre sans risquer d'exploser.

dje8269
12-01-2014, 17:31
J'ai pas trop de merite , car je peut tester avec PE !!!! contrairement a vous .

mais je connais pas de meilleur exercice pour apprendre, comprendre, chercher, se creuser les méninges, bref merci a vous .

Mais quand même , cette façon de "penser" , de voir les choses, et vachement complexe !!! car même en ayant compris, je pense pas être capable de trop complexifier la chose . Ce demande une gymastique neuronnale extreme pour ma part lol .
Alors qu'avec un petite pause , ben c'est clair net et pas trop précis lol .

J'ai passé une heure a trouver les erreurs qui allume une ampoule , alors imaginez sur un programme complexe le debuggage dur trois jours

dje8269
12-01-2014, 17:51
Exemple parfais , j'ai tout compris. Le coup de 0 à 24h et de midi excellent .

Si je chipote un peu .

"if Timer >32768 then" signifie donc que timer est égale au minimum à 32769 ( strictement supérieur).

"H1=H1-32767" pkoi on ne déduis pas 32769 pour avoir un horloge au plus prêt de 0 plutôt qu'a 2 ( je sais c'est pas 2 secondes c'est 2/65536) ?

pour le moment vous faites 32769 - 32767 = 2 dans le meilleure des cas ! on peut gagner en precision non 32769 -32769 = 0 la il est vraiment minuit

BESQUEUT
12-01-2014, 17:56
Mais quand même , cette façon de "penser" , de voir les choses, et vachement complexe !!! car même en ayant compris, je pense pas être capable de trop complexifier la chose . Ce demande une gymastique neuronnale extreme pour ma part lol .
Les neurones, ça ne s'use que si l'on ne s'en sert pas !
Je reconnais que c'est un peu déstabilisant au début. D'ailleurs à la base, les gens qui programmaient les macs en "multitâche collaboratif" étaient pris pour des fous furieux ou de doux rêveurs par les tenants de l'algorithmie...
On s'y fait avec un peu de pratique, surtout quand on prends conscience de l'intérêt d'avoir un lapin toujours en éveil pour réagir très vite au moindre changement sur une broche.

dje8269
12-01-2014, 19:49
Après réflexion , pkoi remettre le timer à "0" a midi ? ce serais la valeur max possible acceptable pour effectuer 1 boucle . Car en fait on pourrait le remettre a zero a 20h00 et reculé de 20h , cela reviendrais au même non ?

BESQUEUT
13-01-2014, 09:10
Après réflexion , pkoi remettre le timer à "0" a midi ? ce serais la valeur max possible acceptable pour effectuer 1 boucle . Car en fait on pourrait le remettre a zero a 20h00 et reculé de 20h , cela reviendrais au même non ?
C'est arbitraire en effet, mais :
- si on fait la soustraction à 20h, on ne peut pas prendre de rendez-vous plus que 4 heures à l'avance.
- en la faisant à midi, on peut prendre des rendez-vous jusqu'à 12 h à l'avance.
- on pourrait faire encore mieux en faisant la soustraction à 6h du mat, ce qui permettrait de prendre des rendez-vous 18h à l'avance. Mais d'une part on n'en a pas besoin, et d'autre part, ça conduit à changer d'heure 2 fois plus souvent.

J'en profite pour exposer une amélioration potentielle : ça me gêne de faire le test Delorean à chaque boucle.
En fait, il me semble que ce serait suffisant de le faire uniquement avant de programmer un nouveau rendez-vous.
J'attends de retrouver mon PE pour voir si ça tient la route.

BESQUEUT
13-01-2014, 13:17
on peut gagner en precision non 32769 -32769 = 0 la il est vraiment minuit
Non : on ne gagne rien en précision ; on enlève la même chose au timer et aux rendez-vous.
On peut juste programmer un rendez-vous 2s plus tard, CAD au plus à 23h59mn59s au lieu de 23h59mn57s
Sachant qu'en général on ne planifie pas à plus que quelques minutes, ça n'a pas grande importance.
Par contre, juste avant, on a pu planifier un rendez-vous pour la prochaine boucle genre :
H1=Timer
Et pas de bol, on n'avait pas encore passé la seconde et Timer valait 32768
Du coup, quand on fait H1=H1-32769, on trouve 65535 et ça merdouille gravement... :(

A noter : si on souhaite planifier un rendez-vous "urgent" IE pour la prochaine boucle, il faut écrire :
H1=Timer
et pas H1=0 qui marcherait aussi, sauf 1 fois sur 32000...


Pour info, la vraie journée du Timer fait 18h (65536/3600) mais ça ne change pas grand chose au problème
NB : la "journée" d'un Picaxe fait 18h si le SetTimer est réglé à 1s
C'est un peu moins de 2h si on travaille en 1/10s. Dans ce cas, il ne faut pas planifier des tâches plus loin que 3/4 h

PieM
13-01-2014, 14:11
J'avoue ne pas trop comprendre.

Si ce principe général est destiné à éviter l'utilisation de l'instruction pause et éventuellement l'interruption pour ce cas précis, je ne vois pas pourquoi timer serait réglé sur 1 seconde ...
Quel serait l'intérêt d'utiliser un X2 et son settimer ?

BESQUEUT
13-01-2014, 14:17
J'avoue ne pas trop comprendre.

Si ce principe général est destiné à éviter l'utilisation de l'instruction pause et éventuellement l'interruption pour ce cas précis, je ne vois pas pourquoi timer serait réglé sur 1 seconde ...
Quel serait l'intérêt d'utiliser un X2 et son settimer ?

Vous avez raison : ma remarque prête à confusion et je la modifie en conséquence.

On a aussi vu que même en utilisant une interruption, il n'est pas évident de traiter rapidement un événement si le PICAXE est en PAUSE.

Cela dit, on peut utiliser la même technique avec Time ou avec des Tickcounts.

dje8269
13-01-2014, 20:30
Non : on ne gagne rien en précision ; on enlève la même chose au timer et aux rendez-vous.
Tout a fait exact , j'ai saisi la subtilité ; désolé je suis pas encore au point !!! lol . ( mais j'y travaille)


En fait, il me semble que ce serait suffisant de le faire uniquement avant de programmer un nouveau rendez-vous.
oui c'est vrai, mais ça ferais un paquet de fois quand même , a chaque programmation de RDV . ça rallongerais beaucoup le programme


si on souhaite planifier un rendez-vous "urgent" IE pour la prochaine boucle
Que voulez vous dire par "IE" je connais "internet explorer", mais je vois pas trop le rapport !!! lol


Pour infos, la vraie journée du Timer fait 18h (65536/3600)
Effectivement ça change pas grand chose au problème, mais ça mérite d'être dis je trouve .


Quel serait l'intérêt d'utiliser un X2 et son settimer ?
L'utilisation est simplement dûs au manque de broches entrées/sorties (18) du 20M2, contre 22 sur le 28X2. pour le settimer je sais pas !

BESQUEUT
14-01-2014, 07:58
oui c'est vrai, mais ça ferais un paquet de fois quand même , a chaque programmation de RDV . ça rallongerais beaucoup le programme Dans un GOSUB Delorean par exemple
Ce serait moins pénalisant de faire ça une fois de temps en temps qu'un test à chaque tour de boucle, même si le test est négatif 99,997 fois sur 100

Que voulez vous dire par "IE" je connais "internet explorer", mais je vois pas trop le rapport !!! lol
Oups : c'est de l'anglais ; ça m'a échappé ; c'est l'acronyme de "It Explain" qu'il faut traduire par "C'est à dire..."

Effectivement ça change pas grand chose au problème, mais ça mérite d'être dis je trouve .Le lapin vit sur une exoplanète dont la journée peut durer ce qu'on veut en fonction du SetTimer...

L'utilisation est simplement dûs au manque de broches entrées/sorties (18) du 20M2, contre 22 sur le 28X2. pour le settimer je sais pas !Le multitâche collaboratif est un principe assez universel applicable à n'importe quel processeur monotâche. Il ne nécessite pas une vraie montre, mais seulement un "ordonnanceur" qui permette de mettre les événements dans l'ordre. Bien sur, avec une montre, la chronologie est bien plus précise et il faut l'utiliser si on en dispose.

BESQUEUT
14-01-2014, 08:05
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 !!!!!


' Exemple de chenillard méthode "lapin fou"
' Le lapin tourne en rond à toute vitesse en regardant sa montre.
' Si c'est l'heure, il fait avancer le chenillard.

#picaxe 28X2
#simspeed 0


symbol H1=w27
symbol D1 = 10 ' durée d'allumage d'une ampoule en 1/10 s

symbol H2=W26
Symbol D2=30 ' Durée en 1/10 s
symbol Etat_Amp=bit0
symbol Allumee=1
symbol Eteinte=0

symbol H3=W25
Symbol D3=70 ' Durée en 1/10s


symbol Amp=b1 ' le numéro de l'ampoule

H1=Timer
H2=Timer
H3=Timer
Amp=0
high amp
'settimer t1s_8 ' Timer en s


settimer 63974 ' Timer en 1/10 s
settimer 62411 ' Timer en 1/10 s
' NB : c'est plus précis, mais le programme ne va pas plus vite et n'est pas plus réactif !
' Le problème Delorean se produit 10 fois plus souvent...


do
if timer>H1 then ' c'est l'heure du RDV N°1
H1=H1+D1
low amp
if amp=7 then
amp=0
else
inc amp
endif
high amp
endif

if timer>H2 then ' c'est l'heure du RDV N°2
if Etat_Amp=Eteinte then
H2=H2+D2 ' Durée d'allumage : 3s
Etat_Amp=Allumee
high C.3
else
' Durée d'extinction courte : ASAP
Etat_Amp=Eteinte
low C.3
endif
endif

if timer>H3 then ' c'est l'heure du RDV N°3
H3=H3+D3
toggle C.7
endif
loop

'NB sur ASAP
' On pourrait éteindre la lampe immédiatement après l'avoir allumée :
' ==> le flash serait encore plus rapide.

' Ici, on attends la prochaine boucle (le prochain TickCount) dans l'état d'esprit du "multitâche collaboratif" :
' ==> on rends la main à la boucle principale.
' ==> on continuera le traitement ASAP...

BESQUEUT
14-01-2014, 08:13
Le cahier des charges étant très répétitif, il serait possible de faire la même chose avec des modulos (méthode PieM).
De plus, les durées étant exprimées en secondes, il ne sert à rien d'être plus précis.
Pour compliquer un peu : le chenillard est du type "glaçon fondant" (comme on en trouve sur les sapins de Noël)
Les leds descendent de plus en plus vite.


' Exemple de chenillard méthode "lapin fou"
' Le lapin tourne en rond à toute vitesse en regardant sa montre.
' Si c'est l'heure, il fait avancer le chenillard.

#picaxe 28X2
#simspeed 0


symbol H1=w27
symbol D1 = b1 ' durée d'allumage d'une ampoule en 1/10 s

symbol H2=W26
Symbol D2=30 ' Durée en 1/10 s
symbol Etat_Amp=bit0
symbol Allumee=1
symbol Eteinte=0

symbol H3=W25
Symbol D3=70 ' Durée en 1/10s


symbol Amp=b4 ' le numéro de l'ampoule
symbol AmpP=b5 ' l'ampoule précédente

D1=64
H1=Timer +D1
H2=Timer
H3=Timer
Amp=7
high amp
'settimer t1s_8 ' Timer en s


settimer 63974 ' Timer en 1/10 s
settimer 62411 ' Timer en 1/10 s
' NB : c'est plus précis, mais le programme ne va pas plus vite et n'est pas plus réactif !
' Le problème Delorean se produit 10 fois plus souvent...


do
if timer>H1 then ' c'est l'heure du RDV N°1
low ampp
ampp= amp

if amp=0 then
amp=8
d1=50
else
dec amp
d1=d1*10/16
high amp
endif
H1=H1+D1
endif

if timer>H2 then ' c'est l'heure du RDV N°2
if Etat_Amp=Eteinte then
H2=H2+D2 ' Durée d'allumage : 3s
Etat_Amp=Allumee
high C.3
else
' Durée d'extinction courte : ASAP
Etat_Amp=Eteinte
low C.3
endif
endif

if timer>H3 then ' c'est l'heure du RDV N°3
H3=H3+D3
toggle C.7
endif
loop

'NB sur ASAP
' On pourrait éteindre la lampe immédiatement après l'avoir allumée :
' ==> le flash serait encore plus rapide.

' Ici, on attends la prochaine boucle (le prochain TickCount) dans l'état d'esprit du "multitâche collaboratif" :
' ==> on rends la main à la boucle principale.
' ==> on continuera le traitement ASAP...

Mon prochain CDC consistera à prendre en compte des événements extérieurs.
Mais le simulateur est trop lent pour ça : autour de la seconde par boucle.
Du coup, impossible de mettre en évidence l'intérêt statistique des tests qui sont négatifs la plupart du temps...
Il va falloir sortir le hardware... matériel...

Pour préparer ça, l'allumage de la deuxième lampe n'est plus symétrique :
elle ne reste éteinte que le temps d'une boucle.

ASAP : As Soon As Possible
Traduire : "Dès que possible"

PieM
14-01-2014, 08:52
Petite remarque :
le 28X2 tourne à 8 MHz, donc settimer pour 0.1s est de 62411 au lieu de 63974, et pour les secondes, son raccourci est t1s_8.
Mais en simu ça ne se voit pas trop!

dje8269
14-01-2014, 21:12
#simspeed 0

Je viens de regarder cette commande qui met la vitesse entre chaque lignes du simu a 0 . Ma question est : même si on est sur 20ms dans les options ?


settimer 63974 ' Timer en 1/10 s
settimer 62411 ' Timer en 1/10 s
Je comprends pas les deux settimer, Pourriez vous éclairer ma lanterne ?

BESQUEUT
15-01-2014, 08:00
Pour le simspeed, 0 ou 20 c'est pareil : c'est déjà tellement lent que rajouter 20ms ou rien entre chaque instruction ne change rien à l'affaire...

Je comprends pas les deux settimer, Pourriez vous éclairer ma lanterne ?
La première ligne est rayée : voir "Reason" en bas de post...

BESQUEUT
15-01-2014, 08:01
' Exemple de chenillard méthode "lapin fou"
' Le lapin tourne en rond à toute vitesse en regardant sa montre.
' Si c'est l'heure, il fait avancer le chenillard.

#picaxe 40X2


symbol H1=w27
symbol D1 = b1 ' durée d'allumage d'une ampoule en 1/10 s

symbol H2=W26
Symbol D2=30 ' Durée en 1/10 s
symbol Etat_Amp=bit0
symbol Allumee=1
symbol Eteinte=0
symbol S2=D.2



symbol H3=W25
Symbol D3=70 ' Durée en 1/10s
symbol S3=D.3

Symbol Coeur=D.0
symbol Travail=D.1



symbol Amp=b4 ' le numéro de l'ampoule
symbol AmpP=b5 ' l'ampoule précédente

D1=64
H1=Timer +D1
H2=Timer
H3=Timer
Amp=7
high amp

setfreq em32
settimer 53036 ' Timer en 1/10 s

' NB : c'est plus précis, mais le programme ne va pas plus vite et n'est pas plus réactif !
' Le problème Delorean se produit 10 fois plus souvent...


do
if timer>H1 then ' c'est l'heure du RDV N°1
high Travail
low ampp
ampp= amp

if amp=0 then
amp=8
d1=50
else
dec amp
d1=d1*10/16
high amp
endif
H1=H1+D1
low Travail
endif


if timer>H2 then ' c'est l'heure du RDV N°2
high Travail
if Etat_Amp=Eteinte then
H2=H2+D2 ' Durée d'allumage : 3s
Etat_Amp=Allumee
high S2
else
' Durée d'extinction courte : ASAP
Etat_Amp=Eteinte
low S2
endif
low Travail
endif


if timer>H3 then ' c'est l'heure du RDV N°3
high Travail
H3=H3+D3
toggle S3
low Travail
endif

toggle Coeur
loop

'NB sur ASAP
' On pourrait éteindre la lampe immédiatement après l'avoir allumée :
' ==> le flash serait encore plus rapide.

' Ici, on attends la prochaine boucle (le prochain TickCount) dans l'état d'esprit du "multitâche collaboratif" :
' ==> on rends la main à la boucle principale.
' ==> on continuera le traitement ASAP...

Et voici une petite étude basée sur ce programme :
15703
Je reste persuadé que ce genre de PICAXE est tout à fait capable de gérer le chenillard tout en réagissant à des événements en tâche de fond (port série et touches.)
La seule incompatibilité à ma connaissance, c'est sa capacité à recevoir une commande par un port série (télécommande...) pendant qu'il écrit sur le LCD.
Donc si on est en train de régler le chenillard, il est possible que la télécommande marche moins bien.

dje8269
15-01-2014, 08:50
Donc si on est en train de régler le chenillard, il est possible que la télécommande marche moins bien.
Bonjour à tous,

Si on régle le chenillard, la télécommande doit etre inhibé !!! Pour eviter un declecnhement