Go Down

Topic: Timer en µs qui compte quand on le décide (Read 416 times) previous topic - next topic

FrizzJack

Bonsoir,
Je souhaiterais que la fonction micros() commence à compter au moment où j'en ai envie et non pas dès le début du lancement du programme.
J'ai écris ce code pour tester:
Code: [Select]
     
for (i=1 ; i<=dn ; i++) //avec dn=2
      delay(1000);
      micros()==0;
      tmicros=micros();
      Serial.println(tmicros);
     
      delay(1000);
      tmicros=micros();
      Serial.println(tmicros);
      Serial.println();

Avec ca, je m'attendais à avoir
0
1000

0
1000
Apparemment ca ne marche pas, ca commence à compter depuis le lancement du programme.
Existe-t-il une méthode pour obtenir ce que je veux sans devoir bidouiller la fonction?

bricoleau

Bonjour

Mauvaise recette  :)

Comment fais-tu pour mesurer une durée de cuisson avec l'horloge murale de ta cuisine ?

Tu la remets à zéro avant de lancer la cuisson?
Evidemment non : tu regardes l'heure au début, puis l'heure à la fin, et la différence entre les deux est la durée de cuisson.

Ben là c'est pareil : micros() ou millis() est ton horloge murale.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

bidouilleelec

#2
Jun 26, 2019, 06:43 am Last Edit: Jun 26, 2019, 04:01 pm by bidouilleelec
Bonjour FrizzJack


Code: [Select]
micros() == 0;

n'est pas une affectation.
Cela pourrait être utilisé, par exemple, dans une expression comme:
Code: [Select]
if (micros() == 0){...};

Pour votre souhait il faudrait  :
Code: [Select]
micros() = 0;
avec un seul =.

Mais cela ne compilerait pas.

Cordialement,
bidouilleelec

J-M-L

#3
Jun 26, 2019, 07:52 am Last Edit: Jun 26, 2019, 05:48 pm by J-M-L
Et quand je lis cela
Code: [Select]
micros()==0;Je me dis que vous avez d'abord  essayé avec = et comme vous vous êtes fait jeter par le compilateur vous vous êtes dit allez j'essaye avec == et miracle le compilateur ne met qu'un warning donc je ne vais pas en tenir compte...

Faut réfléchir à ce qu'on écrit c'est une science exacte; micros() et un appel de fonction qui vous renvoie le nombre de microsecondes écoulées depuis l'allumage de votre arduino (modulo 4294967296), sous forme d'un type uint32_t ==>comment voulez vous que ça représente une zone mémoire où stocker une valeur (avec =)...

avec == vous lui dites de comparer ce nombre de microsecondes avec 0 mais vous ne faites rien de la valeur de vérité obtenue et le code n'a pas d'effets de bord, donc c'est tout simplement viré par le compilateur...
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

FrizzJack

Merci de vos réponses :) je comprends mieux grâce à vous ce qui clochait. De plus j'ai aussi compris comment faire pour compter quand je le souhaite.
Le problème est que j'ai besoin d'émettre une impulsion, disons d'un signal carré, toutes les 8 microsecondes. Je crains qu'avec le temps de calcul, malgré qu'il ne s'agisse que d'addition / soustraction, cela écarte les impulsions.

dbrion06

#5
Jun 26, 2019, 04:50 pm Last Edit: Jun 26, 2019, 05:25 pm by dbrion06
Si vous voulez faire des impulsions très courtesavec un UNO -le cas géral est encore plus affreux-, sachez que

a) les instructions digitalWrite (qui verifient scrupuleusement à chaque fois que vous ne faites pas de bêtise) sont très lentes:https://forum.arduino.cc/index.php?topic=4324.0 trouvait une période maximum de 1/106 = 9.4 microseconde (un plateau haut de 4.7 us, un bas de 1us) ce qui est très juste.
l'accès direct aux ports -qui resiste aux changements de version de la librairie arduino- permet de passer à 0.37 microseconde 0.18 hautes, 0.18 basses) ce qui vous laisse un peu de marge de manoeuvre

b)Vous avez interet à savoir/determiner/faire determiner le nombre de cycles que votre bout de programme mangera( une comparaison d'un uint32_t à zero demandera au pire des cas -égalité- 4 comparaisons et sauts sur 8 bits, si le code généré est ce que je pifomètre....; même si mon pifomètre est bon, suffit -il?

c)Arduino n'est pas équipé pour ce genre de sport . Avr Studio a une possibilité d'activer un simulateur et un compteur de cycles (il est gratuit, sait gérer des projets arduino,  mais plus difficile à prendre en main qu'arduino).
d) vous n'êtes pas au bout de vos peines: arduino a toutes sortes d'interruptions qui vous simplifient la vie, ne serait-ce que en gérant un timer et une jonction série. Vous pouvez retirer ces interruptions simplement (mise de tout le code en section critique/ blocatomique https://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html , mais alors là, ne vous étonnez pas que votre vie devienne compliquée.

e) pour pouvoir apprécier pleinement le résultat de vos efforts, et eventuellement vous corriger, il vous faut quelques instruments de mesure: avez vous un oscilloscope ou analyseur logique (les deux fonctions sont souvent dans la même boîte) ou, au pire, un frequencemètre? Savez vous vous en servir?
Edité: je parle du cas de génération d'impulsions par logiciel...

kamill

#6
Jun 26, 2019, 05:52 pm Last Edit: Jun 26, 2019, 05:53 pm by kamill
Bonjour,

Tu n'as  pas précisé la carte que tu utilises, mais sur une une la résolution de micros() est de 4 microsecondes, ce qui risque d'être très  pénalisant.
Le mieux serait de générer ton signal avec un timer en mode ETC.

68tjs

#7
Jun 26, 2019, 10:05 pm Last Edit: Jun 26, 2019, 10:06 pm by 68tjs
+1
Mais ne serait-ce pas plutôt le mode CTC.
La fréquence max atteignable est la moitié de la fréquence horloge.

Un signal carré de type horloge convient-il où faut-il un créneau très fin ?

Quand à la vitesse de digitalWrite/Read j'avais fait des mesures :  écriture comme lecture prennent autour de 60 cycles horloge.

Je dis "autour" car le temps est plus long avec les sorties "PWM" ce qui est anormal et qui ne se voit pas en agissant directement sur les registres.

La commande par les registres ne prend que 8 cycles horloge.

Les différents contrôles anti connerie prennent autour de 30 cycles horloge (vérifiable en comparant le nombre de cycles horloge avec la bibliothèque digitalFast qui les a supprimé)

Les quelques 20 cycles horloge restant sont pris par la conversion entre la numérotation arduino et la numérotation Atmel (PORT et numéro dans le PORT)
Car au final digitalRead/Write utilise les registres et la dénomination Atmel.

Un cycle horloge à 16MHz = 62,5 nano seconde

kamill

#8
Jun 26, 2019, 10:10 pm Last Edit: Jun 26, 2019, 10:16 pm by kamill
Mais ne serait-ce pas plutôt le mode CTC.
Oups, effectivement, je ne me suis pas relu.
J'ai écrit sur ma tablette et je soupçonne le correcteur orthographique.

FrizzJack

Bonsoir!

Ca y est, après un long moment à cogiter j'ai enfin intégré toutes les histoires de tick d'horloge, oscillateur, overflow, ISR etc :)

Ce genre de signal me convient parfaitement.

Quelqu'un pourrait-il m'écrire la liste de tous les registres et les bits associés au fonctionnement de chaque timer disponible sur l'ATmega2560 s'il vous plaît? J'ai tenté de la faire moi meme à partir du datasheet mais j'ai l'impression que je vais y laisser mes yeux, donc si l'un d'entre vous s'est déjà sacrifié et peut me l'éviter ça m'arrangerait :D

J-M-L

Cherchez sur Internet il y a des dizaines de tutos
Il y a des infos intéressantes dans cet article sur la PWM par exemple
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

trimarco232

Bonjour,
pour pouvoir générer des impulsions de largeur et de période changeantes, il faut utiliser le mode ctc en générant une interruption à la fin de chaque impulsion, afin de définir la longueur de la suivante

dans certains cas on peut aussi utiliser le pwm, ce qui permet de diviser par 2 le nombre d'interruptions, mais il faudrait que FrizzJack précise son besoin pour que j'en dise +

Go Up