Auteur Sujet: Arduino pilotage PN37  (Lu 52904 fois)

Dominique Donnat

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Arduino pilotage PN37
« le: février 16, 2016, 08:44:16 pm »
Bonjour,

comme abordé dans ma présentation, je compte utiliser un arduino uno pour les differentes commandes de mon modulino PN. Pour l'instant, je simule sur breadboard.

En furetant à droite à gauche, j'ai déniché une bibliothèque "Chrono" élaborée par le même auteur que Bounce (anti-rebond). Chrono présente un moyen simple pour écrire des séquences d'événements. Est-ce que quelqu'un utilise cette bibliothèque et les objets chrono concernés ? Une recherche sur le forum ne m'a rien renvoyé.
C'est là : https://github.com/thomasfredericks/Chrono

Je compte l'utiliser pour piloter le mouvement de fermeture et d'ouverture des barrières de PN, avec plusieurs phases (exemple à l'ouverture : accélération sur 5°, vitesse angulaire constante sur 80 °, léger freinage sur 5 °, deux rebonds). L'actionneur sera un servo.

Tout retour d'expérience me sera précieux. Merci.

[Edit] : Je viens de découvrir l'article sur la bibliothèque ScheduleTable qui me semble encore mieux adaptée, au moins pour les séquences d'allumage / extinction des lampes intérieures de la maison de PN. Je vais aussi essayer cette bibliothèque.

Finalement, que pensez-vous de chacune de ces deux bibliothèques ?

Dominique.
« Modifié: février 16, 2016, 09:18:29 pm par Dominique Donnat »

bricoleau

  • Jr. Member
  • **
  • Messages: 51
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #1 le: février 16, 2016, 11:05:18 pm »
Bonjour

ScheduleTable me semble immédiatement adaptée aux besoins d'animations cycliques.

Chrono est à mon sens une bibliothèque plus à destination des arduinistes débutants, pas forcément à l'aise avec l'utilisation directe de la fonction millis().
Dans le même genre, je te suggère de jeter un oeil aux bibliothèques que j'ai postées ici sur le forum, et en particulier la librairie simpleMinuteur (elles sont livrées avec plein d'exemples pour comprendre leur utilisation).

Pour la barrière, j'imagine que tu as déjà défini la fonction angulaire dépendante du temps écoulé.
Derrière je pense que tu devras gérer toi-même l'envoi de la consigne au servo et sa réactualisation à fréquence élevée.
Y aura quelques lignes de code à écrire, mais rien de bien méchant.

Cela doit être jouable pour mai  :D

Dominique Donnat

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #2 le: février 17, 2016, 08:55:43 am »
Oui, en creusant un peu plus, j'arrive aussi à la conclusion que ScheduleTable est ce qu'il me faut.

Pour le positionnement du servo, j'ai décrit le mouvement : une seconde pour passer de 0 à 5 ° avec une loi parabolique en fn du temps, puis 8 à 9 secondes à ~ 10 °/sec pour passer de 5 ° à 90 °, puis un rebond de 5 ° sur 1 seconde, puis un rebond de 2,5 ° sur une seconde, puis stop.
La question du temps de rafraîchissement : 1/10e de seconde, ça fait un pas de 1 °, et j'ai lu quelque part que cela pouvait paraître saccadé. Mais si je rafraîchis plus souvent, ça fait plus de valeurs à calculer. Je réfléchis en parallèle sur deux concepts :
- Tabuler toutes les valeurs de positionnement dans un tableau au setup, puis le positionnement est simple : au pas n, positionner le servo à l'angle n,
- ou, dans le loop, découper le temps par phase et calculer l'angle "en direct".

Y a-t-il des limitations de taille pour les tableaux ? Une séquence de 10 secondes au 1/20, ça fait 201 valeurs.

J'ai une autre réflexion en cours : j'ai un bouton poussoir qui commande le bouclage entre 4 cycles d'éclairage. Je voudrais l'utiliser pour, à la mise sous tension, ne démarrer le programme qu'après le premier appui (histoire d'être sûr que tout est bien configuré après l'installation du modulino au milieu de ses copains en début d'expo). Ma question : est-ce qu'on peut mettre ce test dans le setup, qui attendrait ce premier appui pour donner la main à la loop, ou bien ça ne marche pas et il faut un flag et un if .. else en début de loop ?

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #3 le: février 17, 2016, 09:21:07 am »
Pour déplacer ton servos tu peux utiliser SlowMotionServo. Il faut juste avoir la function qui donne la position en fonction du temps.

https://git.framasoft.org/locoduino.org/SlowMotionServo/tree/master
« Modifié: février 17, 2016, 09:22:59 am par Jean-Luc »
Cordialement

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Re : Arduino pilotage PN37
« Réponse #4 le: février 17, 2016, 09:25:03 am »
Ma question : est-ce qu'on peut mettre ce test dans le setup, qui attendrait ce premier appui pour donner la main à la loop, ou bien ça ne marche pas et il faut un flag et un if .. else en début de loop ?

On peut mettre ce que l'on veut dans setup.
Cordialement

bricoleau

  • Jr. Member
  • **
  • Messages: 51
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #5 le: février 17, 2016, 09:30:40 am »
Je mettrais directement le calcul dans le code.
Le nono tourne quand même à 16 Mhz, cela ne lui posera pas de pb.

La limite de tableau est celle de la ram. 201 octets cela reste raisonnable.
Et pour les tableaux constants on peut les laisser en flash.

Pas sur qu'on puisse aisément commander un servo depuis arduino avec une précision inferieure à 1 degré

Et aucun problème pour un bouton start intégré au setup

a+

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #6 le: février 17, 2016, 09:43:56 am »
Ça dépend de la qualité du servo. L'arduino se contente de construire une impulsion avec une résolution de 4μs. 0° correspondent grosso modo a 500μs et 180° à 2500μs. On a donc 2000μs pour 180° et donc environ 11μs par degré. La résolution doit être vers les 0,36°
Cordialement

bricoleau

  • Jr. Member
  • **
  • Messages: 51
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #7 le: février 17, 2016, 05:59:01 pm »
Les saccades peuvent provenir soit d'une imprécision angulaire, soit d'une fréquence de recalcul trop faible ou irrégulière.
Perso je partirais sur une précision au degré et un recalcul toutes les 10 ms soit 10 fois plus que nécessaire, de manière à réduire l'écart avec l'instant du pas théorique

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #8 le: février 17, 2016, 10:54:07 pm »
En fait dans SlowMotionServo je ne fais pas comme ça.

Plutot que de déplacer les servos d'un pas fixé et de faire varier l'intervalle de rafraîchissement pour faire varier la vitesse, la bibliothèque calcule la position de chaque servo selon la date lue via millis() à chaque fois que update est appelée. Il suffit juste d'appeler update le plus fréquemment possible dans loop et on ne s'embête pas avec l'intervalle de temps de rafraîchissement.

Ce n'est donc pas sensible à des appels irréguliers tant que l’intervalle de temps d'appel de update n'est pas trop long.
Cordialement

Dominique Donnat

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #9 le: février 18, 2016, 09:26:22 am »
Je n'ai peut-être pas bien cherché, mais je n'ai pas trouvé la doc de SlowMotionServo. Et la lecture du code est un peu ardue pour le newbie que je suis. Bref, on trouve un mode d'emploi quelque part ?

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #10 le: février 18, 2016, 09:39:01 am »
Effectivement je n'ai pas encore rédigés de documentation. Je peux faire ca rapidement. Si c'est en anglais ça va ? En attendant un article sur Locoduino.
Cordialement

Dominique Donnat

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #11 le: février 18, 2016, 11:52:07 am »
L'anglais me va très bien.

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #12 le: février 18, 2016, 04:02:46 pm »
Cordialement

Dominique Donnat

  • Newbie
  • *
  • Messages: 19
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #13 le: février 18, 2016, 07:13:45 pm »
Génial, ça marche très bien.

La classe Smooth me va bien telle quelle, je vais l'utiliser pour mes barrières sans changement. Reste à trouver les bonnes valeurs d'angle d'arrivée, le départ étant toujours à zéro.

J'ai essayé une instanciation avec rebond. Comme c'est programmé, le servo revient en arrière après 100 % et s'arrête à l'issue du rebond, à une position ~ 80 %. Moi j'avais imaginé un rebond qui revient à 100 %, et même deux rebonds successifs, un grand et un petit. Mais c'est un raffinement dont je peux me passer, je verrai dans un deuxième temps. C'est pour ça que la fonction sinusoïdale simple me va bien, et me laisse du temps pour le reste. Ça, c'est réglé.

Un truc bizarre quand même : pour bien observer le comportement du rebond, j'avais mis un délai de 2 secondes entre l'aller et le retour. Curieusement, le rebond se produit à l'aller, en fin de mouvement, mais pas au retour. Y a-t-il une explication logique ?

Mon code :
#include <Servo.h>
#include <SlowMotionServo.h>

SMSSmoothBounce myServo; /* Servo with sinusoidal trajectory with bounce */
float target = 0.0;

void setup() {
  myServo.setInitialPosition(target);
  myServo.setMinMax(544, 1500);
  myServo.setPin(2); /* the servo is connected to pin 2 */
}

void loop() {
  if (myServo.isStopped()) {
    delay(2000);
    target = 1.0 - target;
    myServo.goTo(target);
  }

  SlowMotionServo::update();
}


Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1714
    • Voir le profil
Re : Arduino pilotage PN37
« Réponse #14 le: février 18, 2016, 07:46:36 pm »
Oui c'est normal. SMSSmoothBounce n'a pas la même trajectoire de min vers max et de max vers min. Pour la première, il y a le rebond, pour la seconde, c'est un sinus comme dans SMSSmooth :

float SMSSmoothBounce::slopeUp(float time)
{
  if (time <= 0.79) {
    return (1.0 - cos(time * PI))/1.8;
  }
  else {
    float timeOff = 10.0 * (time - 0.55);
    return (0.834 + 1.0 / (timeOff * timeOff));
  }
}

float SMSSmoothBounce::slopeDown(float time)
{
  return (1.0 - cos(time * PI))/2.265;
}

Au lieu d'un simple bounce, on peut faire un sinus amorti. C'est très rapide à programmer
Cordialement