interruption à période configurable

Bonjour :slight_smile:

Je voudrais réaliser des pas pour piloter un moteur pap avec des interruptions. J'utilise pour le moment Flexitimer2. Cela fonctionne bien pour une vitesse constante, je souhaiterais maintenant réaliser une modification du temps pour laquelle l'interruption a lieu, pour réaliser une rampe d'accélération par exemple
Cas 1 : Une interruption toutes les 1500ms
Cas 2 : Une interruption toutes les 500 puis 300 ms...

Ma ligne de code "Flexitimer2::set(Periode, fonction()) étant dans le void setup(), la variable Periode n'est pas réactualisée. Sauriez-vous comment faire ?

Merci par avance pour toute réponse ou aide apportée :slight_smile:
Bonne journée

Bonjour,

Pourquoi ne pas utiliser une méthode ne nécessitant pas d'interruption, comme la fonction "tone", par exemple ?

Merci pour votre réponse :slight_smile:

Je n'utilise pas TONE, car je souhaite réaliser un calcul de PID et avoir des retours capteurs. Par conséquent, je réalise une interruption pour réaliser un front haut et un front bas, puis lArduino peut pendant le temps restant calculer.

Bonjour,

Et si tu fais un nouveau set pour changer de fréquence.
J'ai regardé rapidement le code et je pense que ça doit fonctionner.

Ca ne me semble pas incompatible.
A ta place, je chercherais du côté des librairies pour moteurs pas à pas, genre celle-ci:
http://www.airspayce.com/mikem/arduino/AccelStepper/

Je m'étonne quand même de la très faible fréquence de tes interruptions.

3Sigma : merci :slight_smile: j'ai déjà regardé dans cette direction, peut-etre ai-je mal vu, mais lorsque je programme une vitesse je ne peux pas en même temps effectué un retour capteur et un retour position du moteur pour l'asservir
C'est pourquoi j'essayais avec les interruptions!

Kamill : Merci pour ta réponse :slight_smile: ! Ya-t-il une procédure particulière? j'ai réécrit la ligne de code
"Flexitimer2::set(Periode, fonction())"
juste après mon nouveau calcul de la variable Periode mais cela ne fonctionne pas...
Qu'entends tu par fréquence de mes interruptions?

Ma variable Periode prend comme valeurs :
900./1000. pour faire tourner mon moteur (200 pas/tour) à 333 tours/min
et jusqu'à 300./1000. pour le faire tourner à 1000 tours/min

Isabelle_VP:
3Sigma : merci :slight_smile: j'ai déjà regardé dans cette direction, peut-etre ai-je mal vu, mais lorsque je programme une vitesse je ne peux pas en même temps effectué un retour capteur et un retour position du moteur pour l'asservir
C'est pourquoi j'essayais avec les interruptions!

Si tu utilises tone ou une commande plus intelligente, l'impulsion est exécutée par le hardware (par un timer), pas par le programme, donc tu peux faire ce que tu veux dans celui-ci en parallèle.
Là où tu auras besoin des interruptions avec Flexitimer2, c'est pour pouvoir exécuter ton PID à cadence fixe.

Il y a quelquechose que je ne comprends pas:
une interruption toutes les 1500ms ça fait un tour en 1,5*200=300 seconde (1 tour toutes le 5 minutes)???

3Sigma : je réalise pour l'instant le PID dans le void loop et l'interruption permet de créer un front haut pendant quelques microsecondes puis un front bas pour permettre de réaliser un pas....
Tu me conseilles de faire l'inverse. Si je l'ai fait dans cet ordre c'est qu'à 1000 tours/min, Periode_1pas=300µs et si j'effectue une interruption PID celle-ci durera plus longtemps que 300µs, et le moteur devra donc s'arrêter et redémarrer... ce que je ne souhaites pas.

Kamill : Excusez moi! Je veins de m'apercevoir en effet, que je me suis trompée dans les unités dans mon tout premier message ! Il s'agissait de µs et non de ms !

Isabelle_VP:
3Sigma : je réalise pour l'instant le PID dans le void loop et l'interruption permet de créer un front haut pendant quelques microsecondes puis un front bas pour permettre de réaliser un pas....
Tu me conseilles de faire l'inverse. Si je l'ai fait dans cet ordre c'est qu'à 1000 tours/min, Periode_1pas=300µs et si j'effectue une interruption PID celle-ci durera plus longtemps que 300µs, et le moteur devra donc s'arrêter et redémarrer... ce que je ne souhaites pas.

Pourquoi le moteur devrait-il s'arrêter ? A partir du moment où tu génère ton train d'impulsion de façon matérielle avec, par exemple, la fonction tone, le moteur continuera à tourner.
Le problème d'exécuter le PID dans le loop, c'est que tu ne maîtrise pas sa cadence d'exécution. Or, le réglage du PID dépend de cette cadence.

Isabelle_VP:
Merci pour ta réponse :slight_smile: ! Ya-t-il une procédure particulière? j'ai réécrit la ligne de code
"Flexitimer2::set(Periode, fonction())"

Il faut refaire un Flexitimer2::start(); après

Kamill : J'ai essayé en remettant un start comme tu me le conseilles après mais cela ne fonctionne pas.
Il n'existe pas un timer où l'on peut modifier en cours de programme la fréquence d'interruption/échantillonnage?

3Sigma : mon projet global est la rotation d'un moteur pap en fonction d'une commande utilisateur (potentiomètre) => donc réactivité et nb de tours prédéfinis. Vitesse de rotation souhaitée = 1000 tours/min. Par conséquent j'ai fait un programme avec une rampe d'accélération, une vitesse à 1000 tr/min et une décélération et un autre programme de retour capteur de position et PID. Je souhaiterais maintenant concaténer tout cela mais j'ai un peu du mal à le coder correctement avec les interruptions.

Je vous ai mis mon code en PJ si jamais.

Code Position.txt (9.63 KB)

Je ne comprends pas à quoi sert ton capteur.

il sert à vérifier si le moteur ne saute pas des pas. et s'il en saute, à effectuer la correction nécessaire...

Tu veux faire un asservissement de position ou de vitesse ?

Bonjour,

voici la déclaration de FlexiTimer2::set()

void set(unsigned long ms, void (*f)());

set prend comme paramètre un entier et non un flottant
donc pour 1500 µS le parametre est 1500/1000 -> 1 en entier
pour des valeurs <1000 par exemple 900 900/1000 -> 0 en entier (dans set il y a un test si 0 alors on met 1)

Conclusion -> la période ne varie jamais et est toujours de 1ms

Il faut que tu utilises la 2eme forme de set

Comme 3Sigma, je pense que FlexiTimer n'est pas le mieux adapté à ce que tu veux faire.

void set(unsigned long units, double resolution, void (*f)());

En prenant en compte le fait que le résolution n'est pas infinie.

Comme 3Sigma, je pense que FlexiTimer n'est pas le mieux adapté à ce que tu veux faire.

3Sigma : J'aimerais tout d'abord faire un asservissement en position, puis ajouter un deuxième moteur pas à pas et les asservir en vitesse. Je suis donc toujours bloquée à l'étape asservissement en position.

Kamill : Je comprends mieux alors pourquoi cela ne fonctionne pas. Merci! Du coup à ta connaissance, il n'existe pas de Timer avec un unsigned long units que l'on peut faire varier au cours du programme?

Si j'avais décidé d'utiliser les interruptions c'est parce que celles ci me permettent de réaliser mes pas à des instants précis et laissent le temps après de faire le retour capteurs... et de calculer la nouvelle consigne.
Tous ces calculs mettant plus de temps que la durée d'une pulse à 1000 tours/min, si je réalise une interruption pour réaliser le PID, le moteur ne va plus recevoir de pulses pendant une ou deux périodes et donc décrocher...
=> Que me conseillez-vous dans ce cas si vous pensez que FlexiTimer n'est pas approprié? un autre timer? une autre logique e programmation? Merci d'avance :wink:

Qu'utilises-tu comme driver de moteur pas à pas ?

J'utilise un DRV8825, une carte Arduino Mega et un moteur stepper 39SH38-0806A :wink: