Arduino Forum

International => Français => Topic started by: ATOS_VQ on Mar 18, 2019, 08:43 pm

Title: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Mar 18, 2019, 08:43 pm
Bonjour à tous

Ci dessous un tout petit programme qui devait me servir à définir des temps d'exécution...
La boucle "for" n'introduit aucune différence dans l'affichage qui s'incrémente de 500ms à chaque boucle
Quelque soit le nombre de boucle for le résultat est toujours le même !!!
il faut croire que mon Arduino Nano est un processeur quantique !!
Quelqu'un aurait il une explication ?

Code: [Select]

unsigned long Temp;
unsigned long Data;

void setup() {
Serial.begin(9600);
 Serial.println("debut");
}

void loop() {
 
  Temp=millis(); 

      for(unsigned long i=0 ; i <= 3000000000 ; i++){    // j'ai mis le paquet
        Data= Data+1;
       }

Serial.println(Temp);

delay(500);
}
Title: Re: Fonction millis() ,boucle "for"
Post by: Zlika on Mar 18, 2019, 09:02 pm
Bonsoir,

Avec 3000000000ul, ça donne quoi ?
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 10:00 pm
Bonsoir Atos
Bonjour à tous


La boucle "for" n'introduit aucune différence dans l'affichage qui s'incrémente de 500ms à chaque boucle


Code: [Select]

unsigned long Temp;
unsigned long Data;

void setup() {
Serial.begin(9600);
 Serial.println("debut");
}

void loop() {
 


      for(unsigned long i=0 ; i <= 3000000000 ; i++){    // j'ai mis le paquet
        Data= Data+1;
       }


}

L'optimiseur voit que la variable Data ne sert à rien.  [n'a aucun rôle fonctionnel]
ET il supprime complétement la boucle for.
Essayez de désassembler le code.
Ou mettez des instructions no-op dans la boucle.

Cordialement,
bidouilleelec
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 18, 2019, 10:22 pm
Bonjour,

Chez moi ça fonctionne et dépend du nombre de boucles. Ça dépend peut être de la version.
Essaies de déclarer Data comme volatile pour éviter l'optimisation.
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 10:27 pm
Bonsoir kamill
Bonjour,

Chez moi ça fonctionne et dépend du nombre de boucles. Ça dépend peut être de la version.
Essaies de déclarer Data comme volatile pour éviter l'optimisation.
"Chez moi ça fonctionne"

Ahhhh?

Unix ou windows ?
Quelle version  ( non trafiquée) de l'IDE ?

Cordialement,
bidouilleelec
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 18, 2019, 10:47 pm
Version 1.8.3 Windows 7
Carte UNO
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 10:57 pm
Version 1.8.3 Windows 7
Carte UNO
Envoyez le code et le code désassemblé.

Je n'ai pas la 1.8.3

Je n'essaierais pas  "" déclarer Data comme volatile pour éviter l'optimisation "".

Mais on dérive.

Cordialement,
Bidouilleelec
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Mar 18, 2019, 11:08 pm
Bonsoir
Merci pour toutes vos réponses
J'ai tente un nbr de boucles dépassant la capacité d'un "unsigned long" dans ce cas la la boucle ne se fait pas
Je suis sous Windoqs10 avec un ARDUINO Nano chinois.....

Je souhaite connaitre les temps d'exécution car en regardant les programme pour le HX711 je me suis rendu compte que ces programmes ne tenaient pas compte du datasheet du Hx711 du point de vu chronologie.....à moins que je me sois trompé

Donc en résume le mystère demeure
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 11:18 pm
Bonsoir
Merci pour toutes vos réponses


Donc en résume le mystère demeure

Non : aucun mystère.
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 18, 2019, 11:20 pm
Envoyez le code et le code désassemblé.
Le code est le code de ATOS_VQ, mais j'ai supprimé deux zéros car je ne voulais pas attendre jusqu'à demain
Code: [Select]
unsigned long Temp;
unsigned long Data;

void setup() {
  Serial.begin(115200);
  Serial.println("debut");
}

void loop() {

  Temp = millis();

  for (unsigned long i = 0 ; i <= 30000000/*00*/ ; i++) { // j'ai mis le paquet
    Data = Data + 1;
  }

  Serial.println(Temp);

  delay(500);
}


Début désassemblage de la loop
Code: [Select]
void loop() {

 Temp = millis();
5bc: 20 93 29 01 sts 0x0129, r18 ; 0x800129 <Temp>
5c0: 30 93 2a 01 sts 0x012A, r19 ; 0x80012a <Temp+0x1>
5c4: 40 93 2b 01 sts 0x012B, r20 ; 0x80012b <Temp+0x2>
5c8: 50 93 2c 01 sts 0x012C, r21 ; 0x80012c <Temp+0x3>
5cc: 80 91 25 01 lds r24, 0x0125 ; 0x800125 <Data>
5d0: 90 91 26 01 lds r25, 0x0126 ; 0x800126 <Data+0x1>
5d4: a0 91 27 01 lds r26, 0x0127 ; 0x800127 <Data+0x2>
5d8: b0 91 28 01 lds r27, 0x0128 ; 0x800128 <Data+0x3>
5dc: 61 e8       ldi r22, 0x81 ; 129
5de: c6 2e       mov r12, r22
5e0: 63 ec       ldi r22, 0xC3 ; 195
5e2: d6 2e       mov r13, r22
5e4: 69 ec       ldi r22, 0xC9 ; 201
5e6: e6 2e       mov r14, r22
5e8: ff 24       eor r15, r15
5ea: f3 94       inc r15
5ec: 61 e0       ldi r22, 0x01 ; 1
5ee: c6 1a       sub r12, r22
5f0: d1 08       sbc r13, r1
5f2: e1 08       sbc r14, r1
5f4: f1 08       sbc r15, r1

 for (unsigned long i = 0 ; i <= 30000000/*00*/ ; i++) { // j'ai mis le paquet
5f6: d1 f7       brne .-12     ; 0x5ec <main+0x164>
5f8: 8f 57       subi r24, 0x7F ; 127
5fa: 9c 43       sbci r25, 0x3C ; 60
5fc: a6 43       sbci r26, 0x36 ; 54
5fe: be 4f       sbci r27, 0xFE ; 254
600: 80 93 25 01 sts 0x0125, r24 ; 0x800125 <Data>
604: 90 93 26 01 sts 0x0126, r25 ; 0x800126 <Data+0x1>
608: a0 93 27 01 sts 0x0127, r26 ; 0x800127 <Data+0x2>
60c: b0 93 28 01 sts 0x0128, r27 ; 0x800128 <Data+0x3>
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 11:28 pm
""Le code est le code de ATOS_VQ
"" !!!
Sous 1.8.3 ???

Version du compilateur?
De l'optimiseur?
Title: Re: Fonction millis() ,boucle "for"
Post by: lesept on Mar 18, 2019, 11:33 pm
@kamill @bidouillelec
Pouvez vous juste fournir les sorties console avec diverses valeurs de boucles ?
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 11:34 pm
@kamill @bidouillelec
Pouvez vous juste fournir les sorties console avec diverses valeurs de boucles ?
500ms
Title: Re: Fonction millis() ,boucle "for"
Post by: lesept on Mar 18, 2019, 11:40 pm
500ms
Quelle que soit la valeur que tu mets dans la boucle ? C'est la durée du delay...
C'est peut-être que ça pédale trop vite pour changer quoi que ce soit ?

Ceci dit, j'avais déjà remarqué un truc comme ça avec un ESP32, mais je pensais qu'il était trop rapide pour que mes boucles soient efficaces. Et pourtant j'avais mis le paquet ; trois boucles imbriquées pour multiplier les durées... Pas vu de différence.
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 18, 2019, 11:45 pm
Pour 30000000
debut
0
13704
27409
41114
Pour 3000000
debut
0
1819
3641
5462
7282
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 11:46 pm
i <= 30000000/*00*/
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 18, 2019, 11:48 pm
Quelle que soit la valeur que tu mets dans la boucle ? C'est la durée du delay...
C'est peut-être que ça pédale trop vite pour changer quoi que ce soit ?
Le compilateur peut optimiser en supprimant des instruction, mais dans mon essai, avec ma version, on voit bien dans le désassemblage que la boucle est effectivement exécutée.
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 18, 2019, 11:49 pm
Le compilateur peut optimiser en supprimant des instruction, mais dans mon essai, avec ma version, on voit bien dans le désassemblage que la boucle est effectivement exécutée.

avec ma version,
1.8.3
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 18, 2019, 11:51 pm
Quelle est ta version?
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Mar 19, 2019, 12:05 am
i <= 30000000/*00*/
avec ma version,1.8.3
????
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Mar 19, 2019, 11:46 am
Bonjour à tous

Le mystère persiste avec un  autre problème ou piège plus exactement.
J'ai tenté le nbr de boucle max soit 2^32-1 , et la aucun résultat !

En fait on pourrait penser que la boucle s'effectue jusqu'au débordement, mais non aucune boucle ne s'effectue
La toute dernière boucle serait pour i=2^32-1, mais i++ est incrémente et déborde ! On ne peut donc faire que 2^32-2 boucles

Mais le plus surprenant est que ces quelques 4 milliards d'opérations sont faites en un temps record, invisible !!!!

Je n'ai pas vérifier la fréquence d'horloge de l'Atmega ni le nbr d'opérations par cycle d'horloge, mais même à 1 opération élémentaire par cycle à 40Mhz , la sortie de boucle devrait se faire en gros après 100 secondes .
Ils sont forts ces chinois ils ont réussi à faire tourner l'Arduino Nano à plus de 1Ghz !!! ????
Trèfle de plaisanterie je suis preneur d'explications ....


Code: [Select]

unsigned long Temp;
unsigned long Data;
unsigned long MaxLong =pow(2,32)-1;
void setup() {
Serial.begin(9600);
 Serial.println("Debut");
}

void loop() {
 
  Temp=millis(); 
  Data=0;
      for(unsigned long i=1 ; i <= MaxLong-1; i++){    // j'ai mis le paquet de CHEZ PAQUET
        Data= Data+1;
       
       }

Serial.println(Data);

delay(500);
}
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Mar 19, 2019, 12:02 pm
.....suite ma version IDE Arduino = 1.8.8
Arduino Nano aux yeux bridés
Windows 10
Super PC ASUS bête de course
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 19, 2019, 12:04 pm
Bonjour ATOS__VQ
Bonjour à tous

Le mystère persiste avec un  autre problème ou piège plus exactement.


Il n'y a aucun mystère.
Voir le post #2.

Remplacez  "Data= Data+1;"  par des instructions no-op.

Cordialement,
bidouilleelec
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Mar 19, 2019, 12:41 pm
Merci bidouillelec

Je n'ai pas trouve cette instruction no-op qui est refusée par le compilateur et je ne l'ai pas trouvée dans les références Arduino, peux tu me donner la bonne syntaxe , merci beaucoup
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Mar 19, 2019, 12:49 pm
Comme Data ne sert nulle part, l'optimiseur, s'il fait bien son travail, va retirer la ligne (si j'ose dire) Data++;
La boucle ne servant plus à rien, l'optimiseur zélé va la retirer aussi, (et le stockage et le temps de calcul seront améliorés).
Deux solutions sont possibles:
a) Déclarer Data comme "volatile", pour ... éviter que l'optimiseur ne la volatilise.
b) forcer des instructions assembleurs (NOP ne fait rien) dans cette boucle cf https://www.nongnu.org/avr-libc/user-manual/inline_asm.html (https://www.nongnu.org/avr-libc/user-manual/inline_asm.html) et ... les déclarer comme volatiles.
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 19, 2019, 02:20 pm
Merci bidouillelec

Je n'ai pas trouve cette instruction no-op qui est refusée par le compilateur et je ne l'ai pas trouvée dans les références Arduino, peux tu me donner la bonne syntaxe , merci beaucoup
Je parlais de votre 1er code.

Dans le cas de votre second code :
"Serial.println(Data);" rend la donnée Data fonctionnelle.
Elle est utile à une sortie.
Et donc la boucle for devient effective et prise en compte..

A vous de voir la structure de votre second programme.
(au passage : la compilation comporte un warning, au moins sur IDE 1.8.8  ) .

no-op : ( instruction no operation)
https://whatis.techtarget.com/definition/no-op-no-operation
https://whatis.techtarget.com/definition/no-op-no-operation (https://whatis.techtarget.com/definition/no-op-no-operation)

Cordialement,
bidouilleelec
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 19, 2019, 02:23 pm
Deux solutions sont possibles:
a) Déclarer Data comme "volatile", pour ... éviter que l'optimiseur ne la volatilise.

Bah! non
Title: Re: Fonction millis() ,boucle "for"
Post by: bidouilleelec on Mar 21, 2019, 10:37 am
Bonjour dbrion06

Bah! non
J'ai écris une bêtise :
""  Déclarer Data comme "volatile"  ""
règle effectivement le problème.

Cordialement,
bidouilleelec
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Mar 21, 2019, 10:46 am
Ce n'était pas une bêtise, mais une demi bêtise, à mettre en regard de l'idée brillante de mettre des NOP -prennent 1/16 us chacun sur Arduino-  pour tester le temps d'éxécution d'une boucle vide (à soustraire du temps d'éxécution d'une boucle faisant des calculs répétitifs).
Et qu'est une seule -dans le pire des cas-  bêtise face au désordre ambient?
Te av baxtalo.
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Apr 15, 2019, 09:54 am
Bonjour
Je reviens à la charge pour ce pb de durée instruction,je n'y suis jamais arrivé alors le recours à l'oscilloscope a été salutaire et très décevant,l'extrait du super programme ci dessous génère un signal en crenaux d'une période de 8.5 us !!!(micro seconde) sur Arduino Nano Atmega 328, soit environ 4us par instruction je suis loin des 33ns du dsPic4013
(Je suis débutant en Arduino)



void loop() {
digitalWrite(PD_SCK,HIGH);
digitalWrite(PD_SCK,LOW);
   
}

Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Apr 15, 2019, 10:04 am
Bonjour,

digitalWrite() ce n'est pas une instruction, mais des dizaines d'instructions.
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Apr 15, 2019, 10:20 am
https://stackoverflow.com/questions/27496873/explanation-of-digitalwrite-in-arduino-toggling-led-of-digital-pin  (https://stackoverflow.com/questions/27496873/explanation-of-digitalwrite-in-arduino-toggling-led-of-digital-pin) confirme le post de Kamill:
l'appel à digitalWrite nécessite de calculer le port (groupe de 8 pattes), le numéro dans le port, et si c'est un timer (ceci fait déjà 3 appels de fonctions ...chaque appel nécessite de stocker/destocker des registres).
Il vérifie ensuite que le port est valide, que le numéro dans le port est valide, et que la patte n'est pas impliquée dans un timer ("montre patte blanche"). Alors, il invalide les interruptions, fait effectivement la mise à jour de la patte, revalide les interruptions... Toutes ces précautions sont chronophages...
Title: Re: Fonction millis() ,boucle "for"
Post by: lesept on Apr 15, 2019, 10:25 am
Il me semble que J-M-L (ou quelqu'un d'autre ?) avait posté sur ce forum une alternative à digitalWrite un peu plus rapide
Title: Re: Fonction millis() ,boucle "for"
Post by: hbachetti on Apr 15, 2019, 10:29 am
Si tu veux aller plus vite :

Code: [Select]

  #define PIN     2

  // pin = D0 à D7
  DDRC |= PIN;      // pinMode(PD_SCK, OUTPUT)
  PORTC |= PIN;     // digitalWrite(PD_SCK, HIGH)
  PORTC &= ~PIN;  // digitalWrite(PD_SCK, LOW)
  // pin = D8 à D13
  DDRD |= PIN;      // pinMode(PD_SCK, OUTPUT)
  PORTD |= PIN;     // digitalWrite(PD_SCK, HIGH)
  PORTD &= ~PIN;  // digitalWrite(PD_SCK, LOW)
  // pin = A0 à A5
  DDRC |= PIN;      // pinMode(PD_SCK, OUTPUT)
  PORTC |= PIN;     // digitalWrite(PD_SCK, HIGH)
  PORTC &= ~PIN;  // digitalWrite(PD_SCK, LOW)


Mais dans ce cas, tu n'est plus indépendant de la plateforme.

Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Apr 15, 2019, 10:44 am
Si tu veux aller encore plus vite
Code: [Select]
PIND=0x04;  // toggle pin 2
63ns pour inverser une sortie !
Title: Re: Fonction millis() ,boucle "for"
Post by: lesept on Apr 15, 2019, 11:38 am
Tu veux dire, pour mettre la sortie 2 à HIGH (et les autres de 0 à 7 à LOW):
Code: [Select]
PORTD = 0x04;ou
Code: [Select]
PORTD = B00000100;
PIND est en lecture seule, non ?

La méthode d'hbachetti permet de ne pas toucher aux autres IO:
Code: [Select]
PORTD |= 2;ou
Code: [Select]
PORTD |= B00000100;
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Apr 15, 2019, 11:44 am
PIND est en lecture seule, non ?
Oui, mais c'est une particularité des processeurs AVR: quand tu écris dans PINX ça inverse la (les) sortie(s) correspondante(s).
Il faut bien sur qu'elles soient déclarées en sortie.

Cette méthode aussi ne touche pas aux autres bits.
Title: Re: Fonction millis() ,boucle "for"
Post by: hbachetti on Apr 15, 2019, 12:53 pm
On en apprend tous les jours.
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Apr 15, 2019, 03:05 pm
Merci pour vos réponses
En fait moi qui tente de voir autre chose que l'assembleur ,je vais être contraint d'y retourner avec Atmega, je pensais innocemment que ce langage plus évolué était plus rapide
Merci encore
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Apr 15, 2019, 03:51 pm
Pourquoi veux tu retourner à l'assembleur? Quel est ton application?

un programme écrit à la main en assembleur sera plus optimisé qu'un programme en langage C/C++ (bien que les compilateurs actuels soient très performants coté génération de code et optimisation).
Par contre c'est au détriment du temps de développement qui est beaucoup plus long en assembleur (écriture et debug), et je ne parle pas de la maintenabilité qui est bien plus facile en C/C++.
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Apr 15, 2019, 04:24 pm
Quote
un programme écrit à la main en assembleur sera plus optimisé qu'un programme en langage C/C++
... a condition que ce soit de la main d'un expert en assembleur (prenez un débutant; donnez lui un bon livre d'assembleur et 3 mois de formation et quelque temps pour un sujet simple : je parierais que le code assembleur généré par ses mains sera plus lent et plus volumineux que le programme équivalent, écrit en C et compilé avec un optimiseur moderne)
Title: Re: Fonction millis() ,boucle "for"
Post by: fdufnews on Apr 15, 2019, 04:28 pm
si les IO sont fixés à la compilation, il y a la librairie digitalWriteFast qui est beaucoup plus rapide.
Title: Re: Fonction millis() ,boucle "for"
Post by: hbachetti on Apr 15, 2019, 04:36 pm
HEU ...

Code: [Select]

  PORTC |= 0x04;
  PORTC &= ~0x04;
  PIND = 0x04;


Ceci est du C, et non pas de l'assembleur.
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Apr 15, 2019, 10:39 pm
Super toutes vos contributions.....

Pourquoi retourner à l'assembleur , en fait je ne le quitte pas mais j'aurais souhaité pouvoir faire des programmes plus facilement , je reconnais que c'est le cas bien sur, quand on maitrise.! C'est pas mon cas

Toute fonction plus évoluée est comme une recette de cuisine dont on ne connait pas tous les secrets
sans s'être cassé les dents, bien plus difficile à appréhender qu'une instruction assembleur

En assembleur on maitrise tout sans exception, dans les langages plus évolues il faut toujours se référer à une doc pas toujours facile ,pour connaitre les méandres des fonctions ,objet ou autres, cf la recherche des objets et de leur utilisation .En C# par exemple je m'inspire d'exemples dans différents documents sans vraiment maitriser
En assembleur je n'ai pas de doute sur l'efficacité du code ,par contre pas sur que la taille du programme soit plus court mais à notre époque on s'en fou !
J'ai fait un drone programmé en assembleur sur dsPic4013 (16bit) en faisant tous les calculs en 32 bit, il m'a fallu redécouvrir la roue , faire des programmes de multiplication d'addition ,division racine trigo, tout ca avec des entiers 16 bit alors qu'il m'a fallu représenter tout type de nbr ,petit, grand ,décimaux...un enfer mais je sais exactement à 33ns prés tout ce qui se passe....
Par contre pour visualiser le fonctionnement de 'l'IMU c'est avec C# sur ordi mais je ne comprends pas tout ce que j'ai fait !!!
Pour répondre à hbachetti qui dit que le code qui n'est pas de l'assembleur mais du C, je ne me prononce pas trop mais sur les PIC c'est ce genre d'instruction.....
Naïvement je pensais par exemple qu'un digitalwrite aurait fait après compilation ce que j'aurais pu faire en assembleur....mais c'est comme si le langage était interprété , l'instruction digitalwrite est transformé en une succession d'instructions, même si cette instruction a déjà été utilisé ....(?)

merci encore
 
Title: Re: Fonction millis() ,boucle "for"
Post by: lesept on Apr 15, 2019, 10:53 pm
Ici (https://garretlab.web.fc2.com/en/arduino/inside/arduino/wiring_digital.c/digitalWrite.html), le code de digitalWrite décortiqué (et d'autres aussi intéressantes si vous voulez)
Title: Re: Fonction millis() ,boucle "for"
Post by: fdufnews on Apr 16, 2019, 09:12 am
Naïvement je pensais par exemple qu'un digitalwrite aurait fait après compilation ce que j'aurais pu faire en assembleur....mais c'est comme si le langage était interprété , l'instruction digitalwrite est transformé en une succession d'instructions, même si cette instruction a déjà été utilisé ....(?)
digitalWrite(), c'est une fonction issue d'une librairie. Cette librairie a été développée pour être fonctionnelle sur différents processeurs cibles. Elle crée une couche d'abstraction entre l'appellation D0, D1, D2, ... et les ports matériels desdits processeurs. Tu peux utiliser D0 sur un ATmega328, ATmega2560 ou même un processeur ARM SAM3X8E et cela va fonctionner.
Il ne faut pas perdre de vue que le "langage" Arduino n'a pas été développé pour être performant en vitesse d'exécution mais pour être facile à utiliser par des néophytes. Et d'ailleurs cela suffit pour de nombreuses personnes.

Le C permet de manipuler directement les registres du processeur comme l'a proposé hbachetti mais cela nécessite d'avoir mis le nez dans la documentation.
Il y a, comme je l'ai proposé un peu plus haut, la librairie digitalWriteFast qui à une syntaxe similaire à digitalWrite mais qui est plus rapide car l'identification des registres est faite à la compilation au lieu d'être faite à l'exécution. Mais cela impose une contrainte, si un numéro de port est variable à l'exécution on perd cette optimisation.
Code: [Select]
digitalWrite(D2,HIGH); // sera optimisé
for(i= 2;i<8;i++){
    digitalWrite(i,HIGH);  // ne sera pas optimisé et déroulera le code "standard"
}
Title: Re: Fonction millis() ,boucle "for"
Post by: hbachetti on Apr 16, 2019, 09:54 am
Et il ne faut pas oublier :

Code: [Select]

  PORTC |= 0x07;
  PORTC &= ~0x07;


Pilotage de plusieurs sorties simultanément.
Ce que ne permet pas digitalWrite().
Intéressant pour piloter un afficheur à 7 segments multiplexé.
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Apr 16, 2019, 10:14 am
" , l'instruction digitalwrite est transformé en une succession d'instructions, même si cette instruction a déjà été utilisé "
Elle verifie que la patte ne sert pas comme pwm.
Elle recalcule le port et la patte (sert si on veut faire un chenillard ou si on veut du code portable).
Toutes ces operations sont nécessaires dans le cas général, même si elles ralentissent d'un facteur 100 l'operation proprement dite.

Si on juge ces étapes de recalcul du port et de la patte, d'inhibition (puis reactivation) des interruptions, et de detection d'un autre usage inutile, le code source est disponible, prêt à être utilisé en C pour les 4 dernières lignes de la fonction....
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Apr 16, 2019, 10:29 am
Super merci pour vos contributions , le site de garretlab est super et permet d'y voir plus clair sur ces instructions
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Apr 16, 2019, 11:20 am
...petit complément concernant la rapidite....

Code: [Select]
void setup() {
pinMode(3,OUTPUT);
}

void loop() {
 digitalWrite(3,HIGH);
digitalWrite(3,LOW);
}


Duree instruction 4.3us

Code: [Select]
void setup() {
DDRD= 0x08;
}

void loop() {
PORTD=0x08;
PORTD =0x00;
}


Duree instruction 187ns (oscillo)

Je n'ai pas trouve les 63 ns de kamill, pourtant c'est lui qui doit avoir raison l'ATMEGA 328 fonctionne à 20MIPS donc 50ns par instruction
Mon Arduino Nano est bride (chinois !)
Title: Re: Fonction millis() ,boucle "for"
Post by: kamill on Apr 16, 2019, 11:25 am
A l'exécution des instructions PORTD=... il faut ajouter le temps du call de la fonction loop(), par contre 187ns ne parait pas beaucoup car le call/ret prend plusieurs cycles d'horloge.
Sur une UNO ou une Mega2560 l'horloge est à 16MHz.
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Apr 16, 2019, 11:30 am
"Je n'ai pas trouve les 63 ns de kamill, pourtant c'est lui qui doit avoir raison l'ATMEGA 328 fonctionne à 20MIPS donc 50ns par instruction"

C'est en fait 62.5 ns sur un arduino à 16Mhz (le temps d'un cycle) ....
Title: Re: Fonction millis() ,boucle "for"
Post by: ATOS_VQ on Apr 16, 2019, 01:04 pm
J'ai trouvé la faille....les durées incluaient le loop donc revu et corrige la durée est de  62ns environ
le loop prend 2 cycles 125 en gros....pas d'Arduino sous alimente!
Title: Re: Fonction millis() ,boucle "for"
Post by: dbrion06 on Apr 16, 2019, 01:14 pm
" il faut ajouter le temps du call de la fonction loop(), par contre 187ns ne parait pas beaucoup car le call/ret prend plusieurs cycles d'horloge."

loop , normalement, est appelé une fois (dans un while(1==1) , IIRC): l'optimiseur est assez malin pour s'en rendre compte, normalement, et en faire une fonction inline (i.E un copie coller) .