Bonsoir
j'ai réalisé ce programme qui pilote un moteur. Tout fonctionne sur atttiny 85. Je veux simplement rajouter une led clignotante par le biais de la fonction milli, mais impossible de la faire fonctionner.
J'ai essayé dans différents niveau du loop mais rien n'y fait : le moteur fonctionne mais la led ne s'allume pas.
Pouvez-vous m'aider ?
[code]
// Accélération et ralentissement automatique moteur + clignotement led
// Variables clignotement led
int led1=2; //broche 7
unsigned long currentTime;
boolean ledState = 0;
int Moteur_sens1=3; // Broche 2 vers broche A+ du L293D
int Moteur_sens2=4; // Broche 3 vers broche A- du L293D
int moteur1_PWM = 1; // Broche 6 PWM vers EN1 du L293D
int PWM=0; // Variable PWM image de la vitesse
// Broches variation moteur et led
void setup() {
pinMode(led1, OUTPUT);// Broches clignotement led
pinMode(moteur1_PWM, OUTPUT);
pinMode(Moteur_sens1, OUTPUT);
pinMode(Moteur_sens2, OUTPUT);
delay( 100 ); // Attendre 1 secode avant le lancement de la fonction accélération
Acceleration(); // Lance la fonction Acceleration()
}
void loop(){
if (millis() - currentTime > 500)
currentTime = millis();
ledState=!ledState;
digitalWrite(2, ledState);
}
// Le temps d'accélération est réglage avec le changement du delay
void Acceleration(){
for (PWM = 0; PWM <= 255; PWM++){ // Boucle pour augmenter PWM de 0 jusqu'à 255
delay(100); // Attendre 10ms avant la prochaine incrémentation du PWM
digitalWrite(Moteur_sens1,HIGH); // Activation de la broche A+ du L293D
digitalWrite(Moteur_sens2,LOW); // Désactivation de la broche A- du L293
analogWrite(moteur1_PWM,PWM); // Envoi du signal PWM sur la sortie analogique 10
}
delay( 1000); // Attente de 1 seconde
Deceleration();
}
// Le temps de décélération est réglage avec le changement du delay
void Deceleration(){
for (PWM = 255; PWM >= 0; --PWM){// Boucle pour dminuer PWM de 255 jusqu'à 0
delay( 100 ); // Attendre 10ms avant la prochaine décrémentation du PWM
digitalWrite(Moteur_sens1,HIGH); // Activation de la broche A+ du L293D
digitalWrite(Moteur_sens2,LOW); // Désactivation de la broche A- du L293D
analogWrite(moteur1_PWM,PWM); // Envoi du signal PWM sur la sortie analogique 10
}
// Arrêt du moteur
digitalWrite(Moteur_sens1,LOW); // Désactivation de la broche A+ du L293D
digitalWrite(Moteur_sens2,LOW); // Désactivation de la broche A- du L293D
delay( 3000 ); // Attente de 3 secondes
Acceleration(); // On relance l'accélération du moteur
}
[/code]
Bonsoir
C'est bizarre, ne t'est-tu pas trompé dans ton code au niveau des variables stockant la broche ?
Car les commentaires n'indiquent pas la même chose...
Je n'ai pas regardé en profondeur ton code mais est-ce qu'une broche est utilisée deux fois ?
merci pour ces réponses rapides, mais là je suis un peu perdu car je suis assez novice ds la programmation. Je ne peux donc pas utiliser l'attiny avec le rajout de cette ligne ?
Non, ça ne fonctionne pas correctement.
Comme l'a dit @techvij il y a un appel récursif dont on ne sort jamais.
Ton programme n'entre jamais dans la loop.
Peut être que ton programme semble fonctionner car au bout d'un moment la pile va être pleine et peut être que par un coup de bol ça provoque un reset du programme.
l'optimiseur a peut-être aussi viré la récursion pour faire une boucle simple. Mais comme tout se passe dans le setup, c'est vrai qu'un crash ne sera sans doute pas perceptible
donc il n'atteint jamais la loop, c'est pour cela que quoi que vous mettiez dans la loop, ça ne s'exécutera pas
le code a besoin d'être repris, une utilisation de millis() pour gérer le temps et éviter de tout bloquer sera nécessaire si vous voulez faire clignoter une LED ou quelque chose pendant que le moteur accélère ou décélère
Il se peut aussi que comme l’enchaînement accélération/décélération dure environ 60 secondes @philiou n'ai pas attendu assez longtemps pour que le programme crashe.
Je ne peux pas tester mais Essayez de faire un bout de code avec deux fonctions qui s’appellent mutuellement et impriment Ping et Pong par exemple (prenez 1000000 pour le débit de serial pour que ça avance vite).
Lancez le programme ça devrait crasher super rapidement - 2 octets au moins sur la pile à chaque appel si vous êtes sur un UNO vous explosez la pile en moins de 1000 appels. Vous pouvez même mettre un paramètre qui augmente pour alourdir la pile.
Je ne serais pas surpris que ça ne crashe pas du tout.
Je veux dire testez un truc comme cela. Je suis prêt à parier que ça ne plante pas même au bouts de centaines de millers d'appels récursifs alors que je passe un unsigned long (4 octets) en paramètre par valeur à chaque fois, donc en théorie mis sur la pile en plus de l'adresse de retour (6 octets donc au minimum par appel).
void pong(uint32_t p) {
Serial.print("PONG "); Serial.println(p);
ping(++p);
}
void ping(uint32_t p) {
Serial.print("PING "); Serial.println(p);
pong(++p);
}
void setup() {
Serial.begin(1000000);
Serial.println("début du ping pong");
Serial.flush();
delay(2000); // pour avoir le temps de voir si le code crashe
ping(1ul);
}
void loop() {}
➜ si ça ne crashe pas, c'est que l'optimiseur a enlevé la récursion pour mettre une boucle à la place.
A la fin de void Acceleration() tu appelles void Deceleration() ce qui crée, à l'intérieur de setup(), une boucle infinie. Ainsi on n'entre jamais dans loop()
Ton programme accélération, décélération fonctionne bien, sauf qu'il faut l'architecturer différemment;
Il faut supprimer Deceleration(); en fin de setup()
Dans void Acceleration(), supprimer:
delay( 1000); // Attente de 1 seconde
Deceleration();
Dans void Deceleration(), supprimer:
delay( 3000); // Attente de 1 seconde
Acceleration();
Et ta loop() doit ressemblet à ceci:
void loop()
{
if (millis() - currentTime > 500)
{
currentTime = millis();
ledState=!ledState;
digitalWrite(2, ledState);
}
Acceleration(); // Lance la fonction Acceleration()
delay( 1000); // Attente de 1 seconde
Deceleration();
delay( 3000 ); // Attente de 3 secondes
}
Ta LED ne clignote pas au rythme de 500millisecoondes puisque les remps d'attente des 2 sens de rotation sont plus longs.
Alors que pour la récursivité la pile est utilisée, en cas d'itération ce n'est pas le cas !
De même, alors qu'une récursion infinie peut bloquer le système, la boucle infinie va utiliser les cycles du processeur de manière répétée.
En fait lorsque j'ai lu ce fil de discussion je pensais comme @techvij et @kamill mais j'ai appris grâce à @J-M-L que le compilateur était capable d'optimiser le code de sorte qu'il ne soit pas bloquant en terme de gestion de la mémoire. C'est ainsi qu'il est capable de remplacer la récursivité d'une fonction infinie par l'itération d'une boucle infinie.
J'ai cherché un peu histoire d'être un peu moins bête mais je n'ai trouvé aucun document expliquant ce processus d'optimisation. Et c'est bien dommage !
mais si vous prenez un code avec une sortie de récursion définie et des actions liées à la récursion, par exemple
bool fin = false;
void pong(uint32_t p) {
Serial.print("PONG "); Serial.println(p);
fin = (p >= 100);
if (! fin) ping(++p);
Serial.print("FIN DU PONG "); Serial.println(p);
}
void ping(uint32_t p) {
Serial.print("PING "); Serial.println(p);
if (! fin) pong(++p);
Serial.print("FIN DU PING "); Serial.println(p);
}
void setup() {
Serial.begin(1000000);
Serial.println("\ndébut du ping pong");
Serial.flush();
delay(2000); // pour avoir le temps de voir si le code crashe
ping(1ul);
Serial.println("fin du ping pong");
}
void loop() {}
alors le compilateur détecte qu'il ne peut plus appliquer sa recette magique
Avec fin = (p >= 100); ça devrait passer sur un UNO car la pile sera assez profonde mais si vous mettez 350 (à la louche) au lieu de 100 alors on va dépasser les 2Ko de RAM et avoir un stack overflow sans doute et le programme va rebooter
EDIT:
je tapais pendant que @terwal a répondu. Oui pour le TCO