Pb servomoteur avec millis

Bonjour,
Je souhaite faire fonctionner un servomoteur en utilisant la fonction millis(). J'ai cherché des exemples et des cas pratiques sur le net et je suis arrivé à ce programme. Il me semble cohérent, mais les variables associées à millis() ne se mettent pas à jour, elles ne changent jamais. Ceci fait que mon programme ne fait pas du tout ce qu'il devrait faire.
Les deux raisons d'utiliser millis sont que d'autres mouvements seront gérés en simultané et que je souhaite un mouvement très lent du servomoteur.
Voici mon programme où il y a beaucoup de print pour suivre les évolutions des variables et constater que les myservo1 et previoustime ne changent pas.
merci pour vos conseils et solutions

#include <Servo.h>
Servo myservo;  
unsigned long currentTime = 0;
unsigned long previousTime = 0;
unsigned long myservo1 = 0;
unsigned long vit = 100;
int position1 = 0;
int vitesse = 400;
int valmin = 10; 
int valmax = 80;
int val = 0;


void setup() {
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(10);
  myservo1 = millis();
  previousTime = millis();
}

void loop() {
  currentTime = millis();
  Serial.print(" S0 ");
  Serial.print(millis() - myservo1);
  Serial.print(" myservo1 ");
  Serial.print(myservo1);
  Serial.print("  ");
  Serial.print(millis());
  Serial.print(" previousTime ");
  Serial.print(previousTime);
  Serial.print(" position1 ");
  Serial.println(position1);
  if (((millis() - myservo1) >= vitesse) && position1 <= 150) {
    Serial.print("     S1 ");
    Serial.print(millis() - myservo1);
    Serial.print(" millis() ");
    Serial.print(millis());
    Serial.print(" myservo1 ");
    Serial.println(myservo1);
    myservo1 = millis();
    val = valmin;
    //    previousTime = millis();
    if ((millis() - previousTime) > vit) {
      previousTime = millis();
      Serial.print("          SA ");
      Serial.print(millis() - previousTime);
      Serial.print(" previousTime ");
      Serial.print(previousTime);
      Serial.print(" val ");
      Serial.println(val);
      myservo.write(val);
      val++;
    }
    position1 = 0;
    delay(1000);
  }
  if (((millis() - myservo1) >= vitesse) && position1 > 150) {
    Serial.print(" s2 ");
    Serial.print(millis() - myservo1);
    Serial.print("   pos1 ");
    Serial.println(position1);
    myservo1 = millis();
    val = valmax;
    if ((millis() - previousTime) > vit) {
      previousTime = millis();
      Serial.print(" SB ");
      Serial.print(millis() - previousTime);
      Serial.print(" previousTime ");
      Serial.print(previousTime);
      Serial.print(" val ");
      Serial.print(val);
      myservo.write(val);
      val--;
      Serial.print(" previousTime ");
      Serial.println(previousTime);
    }
    position1 = 0;
  }
}

que voyez vous dans le terminal série ?

(c'est un peu un plat de spaghetti votre code, pourquoi autant de variables de gestion du temps et ces if imbriqués?)

Dans ce cas, il suffit d'envoyer une durée d'impulsion plutôt qu'un angle à servo.write() il y a ainsi beaucoup plus de pas entre le min et le max.

Bonjour jcg95

Avec la bibliothèque VarSpeedServo, tu peux régler la vitesse, faire bouger plusieurs servo en même temps et créer des séquences.

Cordialement
jpbbricole

+1
Mais il faut connaitre le temps min et le temps max.
Parce qu'il y a plusieurs normes.
J'ai lu partout que tmin 1ms et tmax = 2 ms.

Sauf que les servos du type S90 et autres grand public n'ont pas les même temps et que la bibliothèque servo fourni avec l'IDE arduino utilise les temps pour les S90
tmin = 0,544 ms
tmax = 2,4 ms

L'information n'est donnée nulle part, puisqu'Arduino trouve que c'est plus simple en degré et propose la conversion automatique, sauf que comme l'a signalé fdufnews, c'est au détriment de la sensibilité de positionnement.
Les informations se trouvent en ouvrant avec un éditeur de texte le fichier servo.h.

#define Servo_VERSION 2 // software version of this library
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds

Dans l'IDE 1.8.x ce fichier se trouvent dans le sous-répertoire libraries
Dans l'ide 2.2.x c'est plus compliqué
Repertoire arduino15 ou .arduino15 sous linux
image

En copiant servo-1.1.8.zip dans un autre répertoire (par sécurité) et en le dézipant on a accès au fichier d'entête servo. h et au fichier cœur de la bibliothèque, le fichier qui contient le code : servo.cpp

Ce que j'ai écrit est pour la bibliothèques fournie par Arduino.
Pour les autres bibliothèques je serais prudent et je t'engage à vérifier.

PS : NewServo c'est moi qui l'ai téléchargé pour voir, elle n'est pas fournie de base par arduino.

Merci à tous pour ces messages. Je vais essayer ces solutions demain et choisirai celle qui me conviendra le mieux.
Pourquoi tant de variables temps. Je pense que c’est parce qu’il y a plusieurs événements à gérer avec des pb de temps différents.
Entre temps j’ai simplifié le programme qui fonctionnerait presque si ce n’est ce pb de vitesse de rotation. Avec vos solutions ça ira sans doute mieux.
Je vous tiendrai au courant.

Apparement, la variable vitesse représente un temps. Ce nommage n'aide pas à la compréhension ! Par homogénéité, elle devrait être du type unsigned long.

Bonjour,
Voici le résultat de mes essais selon vos propositions. Mon choix s'est porté sur VarSpeedServo qui répond parfaitement à mes attentes quant à la vitesse très lente, à la précision du mouvement et à la simultanéité des mouvements.
Il me reste toute fois 2 petits soucis :

  • Comme à chaque fois, le servo moteur se réinitialise à la mise sous tension avec un mouvement brusque. Avez-vous une solution pour l'éviter ?
  • Plus étrange, quand je téléverse mon programme, ce mouvement de réinitialisation se répète une seconde fois, ensuite les mouvements sont corrects alors que quand le programme est chargé et que je débranche l'alimentation et la rebranche, ce phénomène ne se produit pas. Auriez-vous une explication ? Ceci est perturbant dans les phases de tests, car il y a une différence entre ce tout premier test (téléversement) et l'utilisation courante de l'application.
    Voici mon programme.
#include <VarSpeedServo.h>
VarSpeedServo myservo1;

int LEF = 0;
int RIG = 80;
int SPEED1 = 30;

void setup() {
  myservo1.attach(9);
//  Serial.begin(9600);
}

void aller() {
  myservo1.write(LEF, SPEED1, true);
}
void retour() {
  myservo1.write(RIG, SPEED1, true);
}

void loop() {
  aller();
  delay(1500);
  retour();
  delay(1500);
//  myservo1.detach();
}

Dans le programme définitif, j'utiliserai des interrupteurs pour déclencher les mouvements en passant par la gestion en millis().
J'utilise la version 2.2.1 d'IDE (toute récente).
Voici les références de mes servomoteurs, achetés il y a quelques jours pour remplacer des SG90 trop bon marché qui manquent de précision :
https://www.adeept.com/ad002-servo-motorx2_p0274.html
Merci encore à tous.

Je ne suis pas un spécialiste des servos, ni du C, mais peut-être qu'il y a quelque chose à faire au sujet de la ligne 119 du fichier varspeedservo.h

#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached`

Quelque chose comme :

Si DEFAUT_PULSE_WIDTH est défini, suprimer cette définition
Definir DEFAUT_PULSE_WIDTH= 544 (ou 2400) selon la position de départ que l'on veut.

Note : varspeedServo utilise les mêmes valeurs de temps min et max que Servo.h d'arduino.

Bien sûr il existe une syntaxe précise, je ne l'ai pas sous la main.
Il ne doit pas être obligatoire de modifier la bibliothèque, cela doit pouvoir se faire dans le fichier ino.
La modification devant se faire (je pense) après avoir inclu VarSpeedServo.h.

Merci 68tjs.
Je vais essayer de voir de ce côté si ça change qqchose.
Je te tiens au courant.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.