Motorisation d'un télescope de fabrication personnelle

Bonjour,

Je suis nouveau sur le forum et nouveau dans le monde de l'arduino. J'ai quelques bases en électronique et programmation de sorte que je me lance dans l'aventure de (re)motoriser mon télescope à l'aide de l'arduino. Il existe déjà une électronique que j'avais conçue et montée et qui rend de bons et loyaux services, mais comme je souhaite la faire évoluer, je préfère changer de système.

Vous pouvez voir le télescope, la caméra, la motorisation ici , des images prises avec ce télescope .

Sur le principe, le télescope suit le mouvement des étoiles grâce a une monture équatoriale qui compense la rotation de la terre. Donc à la base, il y a une rotation sur un axe, à la vitesse sidérale. Dans mon cas, c'est une vis qui doit tourner à 1 tour/mn (entraînement par secteur lisse).
Pour pointer finement un objet (le plus gros se fait à la main), on a besoin de vitesses de pointage sur deux les axes (ascension droite=AD et déclinaison=Dec).
Pour guider (compenser les variations du suivi pour différentes causes), on a besoin de vitesses de guidage sur les deux axes.

Dans l'avenir, je souhaite pouvoir rembobiner automatiquement le secteur lisse qui engendre la rotation du télescope à la vitesse sidérale, mais qui a comme défaut de devoir être rembobiné toutes les deux heures.

Je me suis équipé d'une carte MEGA 2560 REV3 et d'une carte RAMPS 1.4, de moteurs pas à pas et de pilotes DRV8825.

Et j'ai commencé à écrire du code (voir ci-dessous).

Voilà, j'aurais sans doute quelques questions à poser, donc à très bientôt!

Nathanaël

#define pas_AD          36           // pin pas ascension droite sur E1
#define direction_AD    34           // pin direction ascension droite sur E1
#define activer_AD      30           // pin activation ascension droite sur E1

#define pas_Dec         26           // pin pas déclinaison sur E0
#define direction_Dec   28           // pin direction déclinaison sur E0
#define activer_Dec     24           // pin activation déclinaison sur E0

#define bouton_AD_plus_guidage     4 // pin boutons raquettes
#define bouton_AD_moins_guidage    5
#define bouton_Dec_plus_guidage    6
#define bouton_Dec_moins_guidage   8
#define bouton_AD_plus_centrage    9
#define bouton_AD_moins_centrage  10
#define bouton_Dec_plus_centrage  11
#define bouton_Dec_moins_centrage 12

#include "Timer.h"                   // importe la librairie timer.h

Timer AD_siderale;                   // déclaration des timers d'ascension droite
Timer AD_plus_guidage;
Timer AD_moins_guidage;
Timer AD_plus_centrage;
Timer AD_moins_centrage;

Timer Dec_guidage;                   // déclaration des timers de déclinaison
Timer Dec_centrage;

void setup() {

Serial.begin(9600);                  // ouvre le port de communication avec l'arduino

pinMode( pas_AD,OUTPUT );                    // déclare les pins comme des sorties 
pinMode( direction_AD,OUTPUT );
pinMode( activer_AD,OUTPUT );

pinMode( pas_Dec,OUTPUT );       
pinMode( direction_Dec,OUTPUT );
pinMode( activer_Dec,OUTPUT );

pinMode( bouton_AD_plus_guidage,INPUT );     // déclare les pins comme des entrées
pinMode( bouton_AD_moins_guidage,INPUT );    
pinMode( bouton_Dec_plus_guidage,INPUT );    
pinMode( bouton_Dec_moins_guidage,INPUT );  
pinMode( bouton_AD_plus_centrage,INPUT );   
pinMode( bouton_AD_moins_centrage,INPUT );  
pinMode( bouton_Dec_plus_centrage,INPUT ); 
pinMode( bouton_Dec_moins_centrage,INPUT );

                                             // fonctions oscillation des pas en millisecondes:
                                                                          
AD_siderale.oscillate(pas_AD, 9.375, LOW);              // durée du pas : 1tr/mn/200pas/32microspas
                                    
AD_plus_guidage.oscillate(pas_AD, 8.4375, LOW);         // durée du pas : - 10%                                     
AD_moins_guidage.oscillate(pas_AD, 10.3125, LOW);       // durée du pas : + 10%                                     
Dec_guidage.oscillate(pas_AD, 93.75, LOW);              // durée du pas : 10 x AD_sidérale (1/10 vitesse sidérale)

AD_plus_centrage.oscillate(pas_AD, 4.6875, LOW);        // durée du pas : 1/2 x AD sidérale (2 x vitesse sidérale)                                   
AD_moins_centrage.oscillate(pas_AD, 1000, LOW);         // durée du pas : arrêt (ou presque)                                     
Dec_centrage.oscillate(pas_AD, 9.375, LOW);             // durée du pas : AD_sidérale
}

void loop() {
digitalWrite( activer_AD,HIGH);
digitalWrite( activer_Dec,HIGH);
digitalWrite( direction_AD,HIGH);

if (bouton_AD_plus_guidage,HIGH){AD_plus_guidage.update();};
if (bouton_AD_moins_guidage,HIGH){AD_moins_guidage.update();};
if (bouton_Dec_plus_guidage,HIGH){Dec_guidage.update();digitalWrite(direction_Dec,HIGH);};
if (bouton_Dec_moins_guidage,HIGH){Dec_guidage.update();digitalWrite(direction_Dec,LOW);};
if (bouton_AD_plus_centrage,HIGH){AD_plus_centrage.update();};
if (bouton_AD_moins_centrage,HIGH){AD_moins_centrage.update();};
if (bouton_Dec_plus_centrage,HIGH){Dec_centrage.update();digitalWrite(direction_Dec,HIGH);};
if (bouton_Dec_moins_centrage,HIGH){Dec_centrage.update();digitalWrite(direction_Dec,LOW);};
}

Bonjour, bienvenue sur le forum

Sympa les photos !

côté code, n'hésitez pas à appuyer sur CTRL-T (ou CMD-T sur Mac) pour que l'indentation soit "propre"

Serial.begin(9600); --> passez à 115200 bauds ça sert à rien de parler lentement à votre PC

ça ce n'est pas terrible:  if (bouton_AD_plus_guidage, HIGH) { si vous voulez tester si la valeur est HIGH il faut écrire   if (bouton_AD_plus_guidage == HIGH) {

Je vois que vous avez un certains nombre de boutons (bouton_AD_plus_guidage, ...) qui sont déclarés comme INPUT pinMode( bouton_AD_plus_guidage, INPUT );Je suppose que vous avez donc mis les boutons en série avec une résistance et connecté à 5V. si vous voulez simplifier le montage, connectez vous à GND, enlevez la résistance et utilisez un pinMode [url=https://www.arduino.cc/en/Reference/pinMode]INPUT_PULLUP[/url] et au lieu de faire if (bouton_AD_plus_guidage, HIGH) // (attention code pas bon)il faudra tester avec LOW qui dira si le bouton est appuyéif (bouton_AD_plus_guidage == LOW)

Si 2 boutons ne peuvent pas être appuyés en même temps, vous pouvez éventuellement mettre des else entre vos if

attention aussi au rebonds du bouton. avez vous un montage hardware qui filtre les rebonds (capacité?)

Bonjour,

J-M-L, merci pour ce retour. J'ai modifié quelques lignes selon vos préconisations.

Pour l'instant je n'ai rien branché, mais j'envisageais effectivement le bouton poussoir sur 5v (avec une résistance dont j'ignore la valeur requise). Mais je vais plutôt opter pour la solution INPUT_PULLUP, si c'est mieux (c'est moins intuitif mais c'est pour ça que je me suis mis sur le forum :wink: ).

Il faut donc un condensateur en parallèle sur le bouton poussoir? Quelle valeur? Pour info, mes boutons vont être sur une "raquette de commande" reliée à la carte arduino avec un cable de 2m de long environ. Des précautions à prendre?

Merci,

Nathanaël

vous pouvez voir les schémas ici

PULL-UP

PULL-DOWN

La résistance est simplement une résistance de limitation de courant pour ne pas faire de court-circuit entre 5V et GND quand vous fermez l'interrupteur (U=RxI si R est quasiment 0 (résistance du fil) et U=5V alors I devient très très grand, c'est à dire que vous avez un appel massif de courant ce qui n'est pas recommandé). Le courant passera dans la résistance et l'énergie sera dissipée sous forme de chaleur.

Vous pouvez en lire plus (en anglais) par exemple ici

Pour éviter les rebonds des boutons (lisez le tuto sur le phénomène ici par exemple) vous pouvez utiliser une librairie toute faite ou alors coder cela vous même, ou encore rajouter une capacité qui va absorber les oscillations. Il y a les 2 camps, les "hardeux" qui vous diront que c'est mieux de mettre la capacité pour avoir un signal propre et les "softeux"qui vous diront que c'est gérable par le logiciel... (et les "ceinture bretelles" qui feront les deux :slight_smile: )

En matériel vous pourriez avoir un branchement du genre (expliqué sur ce site par exemple)

Pour déporter cela à 2m de l'arduino, ça ne pose pas de soucis particulier la résistance des fils restera faible au regard de ce que vous voudrez mesurer (tout ou rien), il est souvent recommandé de tortiller les fils avec le fil de masse (GND) pour éviter des interférence mais ça joue plutôt si vous avez des hautes fréquences.

Je viens de poster cela dans une autre discussion sur la gestion d'un appui et relâchement, ça pourra vous donner des idées.


voici un exemple de code qui va regarder l'appui et le relâchement du bouton et capturer l'instant d'appui dans la variable debut et l'instant de relâchement dans la variable fin. Ce code gère le "debounce" en ce sens qu'il attend une stabilisation du changement d'état du bouton avant de considérer que l'action est prise --> cela veut dire qu'on mesure l'appui qu'après debounceDelay milli-secondes de stabilité et idem pour le relâchement. 15ms est généralement suffisant avec la majorité des boutons.

Vous pouvez tester ce code en mettant juste un fil sur la pin 8 et en le connectant, déconnectant de Ground (vu que je suis configuré en INPU_PULLUP). Mettez la console à 115200 bauds.

const byte pinBouton = 8;
unsigned long debut, fin;

void setup() {
  Serial.begin(115200);
  pinMode(pinBouton, INPUT_PULLUP);
}

boolean verifierBouton()
{
  boolean mesureEffectuee = false;

  // la mémoire de ce qu'il se passe sur le bouton; static pour conserver les valeurs entre 2 appels
  const unsigned long debounceDelay = 15; // millisecondes
  static unsigned long debounceMoment = 0;
  static boolean etatBoutonPrecedentAppuye = false;
  static boolean etatBoutonCourantAppuye = false;
  
  boolean boutonAppuye = digitalRead(pinBouton) == LOW; // LOW parce que input pullup

  if (boutonAppuye != etatBoutonPrecedentAppuye) {
    // un changement d'état remet à zéro la capture du temps de stabilité
    debounceMoment = millis();
    etatBoutonPrecedentAppuye = boutonAppuye ;
  }

  if (millis() - debounceMoment >= debounceDelay) {
    // on est dans une position stable depuis debounceDelay millisecondes

    if (boutonAppuye != etatBoutonCourantAppuye) {
      // l'état du bouton a changé
      etatBoutonCourantAppuye = boutonAppuye;

      if (boutonAppuye) {
        // appui bouton = on mesure l'heure de début
        debut = micros();
      } else {
        // on a relâché, on mesure l'heure de fin
        fin = micros();
        mesureEffectuee = true;
      }
    }
  }
  return mesureEffectuee;
}

void loop() {
  if (verifierBouton()) {
    Serial.print(F("appui bouton\nt0 = "));
    Serial.print(debut);
    Serial.print(F(" microsecondes\nt1 = "));
    Serial.print(fin);
    Serial.print(F(" microsecondes\nsoit "));
    Serial.print(fin - debut);
    Serial.println(F(" microsecondes\n-------------------"));
  }

  // ici vous pouvez faire ce que vous voulez du moment que ça ne dure pas trop longtemps
  // pour pouvoir vérifier l'état du bouton assez souvent



}

Bonjour,
J'ai réécrit mon code. En ce qui concerne les rebonds, à la lecture des documents, je n'ai pas l'impression que ça concerne les entrées PULLUP? Je me trompe?
Merci,
Nathanaël

#define pas_AD          36               // pin pas ascension droite sur E1
#define direction_AD    34               // pin direction ascension droite sur E1
#define activer_AD      30               // pin activation ascension droite sur E1

#define pas_Dec         26               // pin pas déclinaison sur E0
#define direction_Dec   28               // pin direction déclinaison sur E0
#define activer_Dec     24               // pin activation déclinaison sur E0

#define port_ST4_AD_plus_guidage     4     // pin boutons raquettes
#define port_ST4_AD_moins_guidage    5
#define port_ST4_Dec_plus_guidage    6
#define port_ST4_Dec_moins_guidage   8
#define bouton_AD_plus_centrage    9
#define bouton_AD_moins_centrage  10
#define bouton_Dec_plus_centrage  11
#define bouton_Dec_moins_centrage 12

#include "Timer.h"                             // importe la librairie timer.h

Timer AD_siderale;                             // déclaration des timers d'ascension droite
Timer AD_plus_guidage;
Timer AD_moins_guidage;
Timer AD_plus_centrage;
Timer AD_moins_centrage;

Timer Dec_guidage;                             // déclaration des timers de déclinaison
Timer Dec_centrage;

void setup() {

  Serial.begin(115200);                        // ouvre le port de communication avec l'arduino

  pinMode( pas_AD, OUTPUT );                   // déclare les pins comme des sorties
  pinMode( direction_AD, OUTPUT );
  pinMode( activer_AD, OUTPUT );

  pinMode( pas_Dec, OUTPUT );
  pinMode( direction_Dec, OUTPUT );
  pinMode( activer_Dec, OUTPUT );

  pinMode( port_ST4_AD_plus_guidage, INPUT_PULLUP);          // déclare les pins comme des entrées
  pinMode( port_ST4_AD_moins_guidage, INPUT_PULLUP);
  pinMode( port_ST4_Dec_plus_guidage, INPUT_PULLUP);
  pinMode( port_ST4_Dec_moins_guidage, INPUT_PULLUP);
  pinMode( bouton_AD_plus_centrage, INPUT_PULLUP);
  pinMode( bouton_AD_moins_centrage, INPUT_PULLUP);
  pinMode( bouton_Dec_plus_centrage, INPUT_PULLUP);
  pinMode( bouton_Dec_moins_centrage, INPUT_PULLUP);

  // fonctions oscillation des pas en millisecondes:

  AD_siderale.oscillate(pas_AD, 9.375, LOW);              // durée du pas : 1tr/mn/200pas/32microspas

  AD_plus_guidage.oscillate(pas_AD, 8.4375, LOW);         // durée du pas : - 10%
  AD_moins_guidage.oscillate(pas_AD, 10.3125, LOW);       // durée du pas : + 10%
  Dec_guidage.oscillate(pas_AD, 93.75, LOW);              // durée du pas : 10 x AD_sidérale (1/10 vitesse sidérale)

  AD_plus_centrage.oscillate(pas_AD, 4.6875, LOW);        // durée du pas : 1/2 x AD sidérale (2 x vitesse sidérale)
  AD_moins_centrage.oscillate(pas_AD, 1000, LOW);         // durée du pas : arrêt (ou presque)
  Dec_centrage.oscillate(pas_AD, 9.375, LOW);             // durée du pas : AD_sidérale
}

void loop() {

  digitalWrite( activer_AD, HIGH);
  digitalWrite( activer_Dec, HIGH);
  digitalWrite( direction_AD, HIGH);

  if (bouton_AD_plus_centrage == LOW) {                    // centrage AD
    AD_plus_centrage.update();
  } else {
    if (bouton_AD_moins_centrage == LOW) {
      AD_moins_centrage.update();
    } else {
      if (port_ST4_AD_plus_guidage == LOW) {                 // guidage AD
        AD_plus_guidage.update();
      } else {
        if (port_ST4_AD_moins_guidage == LOW) {
          AD_moins_guidage.update();
        } else {
          AD_siderale.update();
        };
      };
    };
  };

  if (bouton_Dec_plus_centrage == LOW) {                   // centrage Dec
    Dec_centrage.update();
    digitalWrite(direction_Dec, HIGH);
  } else {
    if (bouton_Dec_moins_centrage == LOW) {
      Dec_centrage.update();
      digitalWrite(direction_Dec, LOW);
    } else {
      if (port_ST4_Dec_plus_guidage == LOW) {                // guidage Dec
        Dec_guidage.update();
        digitalWrite(direction_Dec, HIGH);
      } else {
        if (port_ST4_Dec_moins_guidage == LOW) {
          Dec_guidage.update();
          digitalWrite(direction_Dec, LOW);
        };
      };
    };
  };
}

Non le rebond est lié simplement la physique de votre bouton

(Pas besoin de ; après une } dans le code)

Bonjour,

Afin de tester mes cartes méga 2560 et ramps 1.4 j’ai écrit le programme ci-dessous. Le but étant de pouvoir tester la valeur des différentes broches.
Toutes les valeurs étaient ok sur le DRV 8825, gnd, +13.7v, 5v sur la broche de direction, 0 ou 5v sur la broche step, Vréf à 1.05 sur le potentiomètre, sauf les broches A1 A2 B1 B2 qui restaient fixes à 1.2v environ. Pourtant en pas complet et avec une fréquence de 1Hz j’aurais du voir quelque chose…
J’ai enlevé puis remis le DRV8825 puis rebranché l’alimentation et ce coup là c’est la carte mega2560 qui a fumé…
Donc j’arrête les tests pour ce week-end et plus, le temps de recevoir une autre carte mais je voudrais savoir si l’ensemble de ce matériel est à peu près fiable en général, ou si ça arrive souvent et qu’il faut prévoir plusieurs cartes. Je me suis pourtant installé sur un tapis antistatique et il me semble avoir pris assez de précautions.
Merci par avance pour votre éclairage.
Nathanaël

#define pinStep    36 // Signal de PAS (avancement)
#define pinDir     34 // Direction  
#define pinEnable  30 //Enable

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600); // ouvre le port com avec l'arduino
pinMode( pinEnable, OUTPUT );
pinMode( pinDir   , OUTPUT );
pinMode( pinStep  , OUTPUT );
}

void loop() {
  // put your main code here, to run repeatedly:
Serial.println("test");
 int i = 0;
   digitalWrite( pinEnable,HIGH);
   digitalWrite( pinDir,HIGH); // Direction avant
   digitalWrite( pinStep,LOW);  // Initialisation de la broche step
  
  // Avance de 6400 pas
  for( i=0; i<200; i++){
    Serial.println( i );
    digitalWrite( pinStep,HIGH );
    delay( 100 );
    digitalWrite( pinStep,LOW );
    delay( 1000);
  } 
}

Bonjour,

A la réflexion, j’ai quand même fait une chose qui ne doit pas être très orthodoxe : j’ai soudé les fils du moteur sur les broches A1 A2 B1 B2 de la Ramp1.4

Cela peut-il expliquer mes déboires? Provoquer des courts-circuits internes?

Merci par avance,

Nathanaël

Ça dépend si vous y êtes allé au chalumeau pour vos soudures? (Faut pas trop chaud, pendant pas trop longtemps - avez vous testé la continuité entre 2 pins contigües pour voir si vous n'avez pas créé de court circuit ? )

Sinon une erreur classique est dans le sens de montage des pilotes de chacun des moteurs - il varie en fonction du type utilisé. vous êtes sûr d'avoir bien branché tout cela? (Cf un bon article sur les drivers)

Ben non, rien de tout ça, j'avais vérifié sur le site que vous proposez justement, le sens du montage. Je ne comprends pas. La carte ramp1.4 n'a aucune trace de surchauffe apparente. Pas de continuité anormale au voltmètre.

J'ai pu esquinter le DVR8825 en prenant les tensions avec les pointes du voltmètre, mais une fois endommagé, celui-ci peut-il faire griller la mega 2560?

Avant que ça fume le microprocesseur, deux diodes sur la RAMP1.4 sont devenues rouges (dans le coin vers l'indication + et D10). Pas eu le temps de débrancher...

Bonjour,
Chouette projet :slight_smile:

Pour information, il existe pas mal de chose sur le sujet sur Arduino. Je te propose notamment mon projet qui a bien avancé :
https://github.com/Dinastro/MonoMot-Telescope-Driver

ou le projet onstep plus abouti :
http://stellarjourney.com/index.php?r=site/equipment_onstep

Cordialement

Et bien on est nombreux sur le coup! :slight_smile:

A noter que le A4988 a meilleur presse que le DVR8825 en terme de précision...

Si cela peut aider, voici quelques librairies perso dispo sur mon blog... :wink:
http://em10-usd-arduino-takahashi.eliotis.com/librairies-arduino/index.html

Pour les boutons poussoirs, je recommande de laisser tomber la gestion à la mano et d'en passer par une manette de jeu vidéo de récup. On a ainsi aucun problème de rebond car leur conception est prévue pour...

De mon côté, j'en suis à la gestion des accélérations moteur avec gestion du backlash en AD et Dec. Le premier proto (photo ci-jointe) est opérationnel pour ça mais à terme le projet final sera plus riche (GPS, Bluetooth, Goto, PEC, etc).

J'ai aussi mis au point un analyseur d'erreur périodique pour me faciliter à terme le contrôle du développement de l'algorithme de PEC intégré...
http://em10-usd-arduino-takahashi.eliotis.com/blog/index_files/analyseur-de-precision-moteur-pas-pas-au-taquet.html

Au plaisir d'échanger sur le sujet, :slight_smile:
Seb.

Bonsoir,

J'ai réussi à faire tourner mon moteur mais j'ai deux problèmes:

Le premier est que le moteur ne tourne pas à la vitesse souhaitée. En effet, il me faut 1 tr/mn, je fonctionne en 32 micropas pour 200 pas par tour, j'ai donc fixé la demi-période à 60000/200/32/2 = 4.6875 millisecondes et le moteur fait un tour en 52s au lieu de 60s...
De plus, le mouvement n'est pas très fluide, du moins j'ai cette sensation.

Le deuxième problème, c'est que je n'arrive pas à arrêter la boucle avec un interrupteur de fin de course.

Le matériel est décrit dans le #1

J'ai écrit le code ci-dessous pour sérier les problèmes.

Merci par avance,

Nathanaël

#define pas_AD          36               // pin pas ascension droite sur E1
#define direction_AD    34               // pin direction ascension droite sur E1
#define activer_AD      30               // pin activation ascension droite sur E1

#define interrupteur_fin_de_course  29   // interrupteur fin de course entre la masse et la D29 de l'aux-4 de la ramps 1.4

#include "Timer.h"                       // importe la librairie timer.h

Timer AD_siderale;                       // déclaration des timers d'ascension droite

void setup() {

  Serial.begin(115200);                  // ouvre le port de communication avec l'arduino

  pinMode( pas_AD, OUTPUT );             // déclare les pins comme des sorties
  pinMode( direction_AD, OUTPUT );
  pinMode( activer_AD, OUTPUT );

  pinMode( interrupteur_fin_de_course, INPUT_PULLUP);

  AD_siderale.oscillate(pas_AD, 4.6875, LOW);  // fonctions oscillation des pas en millisecondes:

  digitalWrite( activer_AD, LOW);              // active le DVR8825
  digitalWrite( direction_AD, HIGH);           // fixe le sens de rotation du moteur
}

void loop() {
  if (interrupteur_fin_de_course != LOW) {
    AD_siderale.update();
  }
}

Bonjour,

J'ai réussi à résoudre mon deuxième problème mais peut-être pas de la meilleure façon. Le problème c'est que j'utilise #define pour déterminer le numéro de la broche de l'arduino et qu'il me retournait ce numéro dans le test plutôt que la valeur (haut ou bas) de la broche.
Je peux donc utiliser mon contact de fin de course avec le code ci-dessous, mais est-ce optimisé?

En revanche, rien trouvé qui puisse expliquer la vitesse non conforme du moteur.

Merci par avance,

Nathanaël

#define pas_AD          36               // pin pas ascension droite sur E1
#define direction_AD    34               // pin direction ascension droite sur E1
#define activer_AD      30               // pin activation ascension droite sur E1

#define interrupteur_fin_de_course 29    // pin interrupteur fin de course

#include "Timer.h"                       // importe la librairie timer.h

Timer AD_siderale;                       // déclaration des timers d'ascension droite

int valeur_interrupteur_fin_de_course;   // valeur de la broche 29

void setup() {

  Serial.begin(115200);                  // ouvre le port de communication avec l'arduino

  pinMode( pas_AD, OUTPUT );             // déclare les pins comme des sorties
  pinMode( direction_AD, OUTPUT );
  pinMode( activer_AD, OUTPUT );

  pinMode( interrupteur_fin_de_course, INPUT_PULLUP); // déclare une entrée PULLUP

  AD_siderale.oscillate(pas_AD, 4.6875, LOW);  // fonctions oscillation des pas en millisecondes:

  digitalWrite( activer_AD, LOW);              // active le DVR8825
  digitalWrite( direction_AD, HIGH);           // fixe le sens de rotation du moteur

}

void loop() {
  valeur_interrupteur_fin_de_course = digitalRead(interrupteur_fin_de_course);

  if (valeur_interrupteur_fin_de_course != LOW) {
    AD_siderale.update();
  }
}

Réponse rapido avant l'apéro:

  1. la méthode oscillate prend en paramètre un unsigned long (entier long non signé) donc exit tout ce qui est après la virgule. Ici la période va donc être de 4 millisecondes.
  2. La librairie Timer utilise une approche logicielle (d'où le update nécessaire dans le boucle loop). C'est un très mauvais choix pour gérer un moteur pas à pas. Par exemple, un simple delay() dans la boucle loop et le moteur va s'arrêter temporairement. Il faut utiliser les timers hardware (Timer1, Timer2, etc) qui vont garantir la régularité des pulsations par le biais d'interruptions.

Bonjour,

Ok c'est bien ça, je l'ai vérifié en changeant graduellement les valeurs jusqu'à 4ms, pas de changement. Puis 5ms, vitesse dans le rapport 4/5.

Donc il faut que je change mon fusil d'épaule, je vais regarder ton histoire de timer harware sur internet.

J'ai de nombreuses valeurs de fréquence dans mon programme mais une seule a besoin d'être précise et très stable : c'est la vitesse sidérale. Les autres peuvent souffrir quelques approximations ou dérives.

Merci!

Nathanaël

Bonsoir,

Sur ton blog, ça a l’air simple mais je n’ai pas le niveau pour l’instant... J'ai gratté un peu sur le web et commencé à écrire quelques lignes avec timer1.h. Il me manque des bases, si quelqu'un peut combler des trous ça ira plus vite. Notamment comment commander la broche 36 (step du DRV8825) avec la 9 qui sort de timer1...

Merci beaucoup, heureusement qu'il y a les forums et des gens qui répondent!

Nathanaël

#define pas_AD          36               // pin pas ascension droite sur E1
#define direction_AD    34               // pin direction ascension droite sur E1
#define activer_AD      30               // pin activation ascension droite sur E1

#define interrupteur_fin_de_course 29    // pin interrupteur fin de course
int valeur_interrupteur_fin_de_course;

#include "TimerOne.h"                    // importe la librairie timerone.h

void setup() {
  Serial.begin(115200);                  // ouvre le port de communication avec l'arduino
  pinMode( pas_AD, OUTPUT );             // déclare les pins comme des sorties / entrées
  pinMode( direction_AD, OUTPUT );
  pinMode( activer_AD, OUTPUT );
  pinMode( interrupteur_fin_de_course, INPUT_PULLUP);
  digitalWrite( activer_AD, LOW);              // active le DVR8825
  digitalWrite( direction_AD, HIGH);           // fixe le sens de rotation du moteur

  pinMode(10, OUTPUT);                   // timer one
  Timer1.initialize(4688);               // pas en microsecondes
  Timer1.pwm(9, 512);                    // sur 10 bits 1024 donc 50% cycle de marche

// Timer1.attachInterrupt(rappel);       // attache le rappel () en tant qu'interruption de débordement de la minuterie 
???
}
//void rappel() {
//  digitalWrite(10, digitalRead (10) ^ 1); //???
//}
void loop() {
  valeur_interrupteur_fin_de_course = digitalRead(interrupteur_fin_de_course);

  if (valeur_interrupteur_fin_de_course != LOW) {
    digitalWrite (36, digitalRead (9));               // ça ça ne fonctionne pas
    Serial.println (digitalRead(pas_AD));
   }
}

Bonjour.

Super votre idée, j'y avait déjà pensé, j'ai perso un télescope de 300, je fonctionnait en "Dobson" avec une monture équatoriale, j'ai jamais pris le temps de mettre en place la monture équatoriale.

Je n'ai pu faire que du planétaire, j'ai vu Uranus, je suis sur, rapidement, je m'en souviens verdâtre

J'ai récupéré ce télescope de mon frangin, qui lui à construit un 800 en Dobson, il connait bien le ciel...

Je suis super occupé en ce moment je suis boulanger, je répare une machine, je suivrais votre post pour voir les évolution.
Je regarderai demain, et si je peux vous aider sur le C++, volontiers, si c'est dans mes capacité, j'ai un niveau moyen
Salutation Gilles

Si la fonction Sleep est disponible sur une arduino, elle fige le programme pendant un temps donné.

Je l'utilise pour réguler mon four, c'est Super pratique, je fait des Sleep (2000), et je récupère le programme à la volée.

Je sais pas si c'est adaptable, vous lancez le moteur en alimentation, vous figez le le programme avec la fonction Sleep, et vous le récupérez pour le couper .

Nathanaël, j’ai regardé ton code vite fait. Je te propose de laisser de côté la librairie TimerOne et autre et d’utiliser ma librairie RunLoop qui regroupe tous les timers dispos. tu peux la télécharger ici…
https://github.com/MarScaper/runloop

Et voici un bout de code vite fait en aveugle qui devrait marcher pour ton télescope…

/*
* TelescopeNathanael.ino
*
* Copyright (c) 2017 by Sebastien MARCHAND (Web:www.marscaper.com, Email:sebastien@marscaper.com)
*/
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * This sample code shows the way to use hardware timers alone with a simple C function call back.
 * The only change compared to software_timer_callback.ino is the class instantiation.
 *
 * Hardware timers inherit from RunLoopTimer and work exactly in the same way (see inheritance 
 * diagram for details). As a result, they are perfectly interchangeable. :)
 *
 * RunLoop library embed RunLoopHardwareTimer0, RunLoopHardwareTimer1, RunLoopHardwareTimer2, 
 * RunLoopHardwareTimer3, RunLoopHardwareTimer4, RunLoopHardwareTimer5. Timers 3,4,5 are only
 * availables with Arduino Mega.
 */

#include <RunLoop.h>

#define pas_AD          36               // pin pas ascension droite sur E1
#define direction_AD    34               // pin direction ascension droite sur E1
#define activer_AD      30               // pin activation ascension droite sur E1

#define interrupteur_fin_de_course 29    // pin interrupteur fin de course
int valeur_interrupteur_fin_de_course;

// Timer d'ascension droite.
RunLoopTimer *timerAD   = NULL;

// Timer de declinaison.
RunLoopTimer *timerDec  = NULL;

void setup() 
{
 Serial.begin(115200);                  // ouvre le port de communication avec l'arduino
 pinMode( pas_AD, OUTPUT );             // déclare les pins comme des sorties
 pinMode( direction_AD, OUTPUT );
 pinMode( activer_AD, OUTPUT );
 pinMode( interrupteur_fin_de_course, INPUT_PULLUP);
 digitalWrite( activer_AD, LOW);              // active le DVR8825
 digitalWrite( direction_AD, HIGH);           // fixe le sens de rotation du moteur


 // Note: le arduino Mega dispose de 6 timer hardware:
 //  Timer0 (A éviter de manipuler car il est dédié au comptage du temps: millis(), etc)
 //  Timer1 qui compte sur 16 bits.
 //  Timer2 qui compte sur 8 bits (un peu moins précis).
 //  Timer3 qui compte sur 16 bits (Arduino Mega uniquement).
 //  Timer4 qui compte sur 16 bits (Arduino Mega uniquement).
 //  Timer5 qui compte sur 16 bits (Arduino Mega uniquement).
 
 // Nous utilisons le Timer1 pour une précision de 16bits.
 timerAD = new RunLoopHardwareTimer1();
 timerAD->attachInterrupt(fire);
 timerAD->setMicroDelay(4688);

 // Nous utilisons le Timer3 pour une précision de 16bits.
 timerDec = new RunLoopHardwareTimer3();
 timerDec->attachInterrupt(fire);
 //timerDec->setMicroDelay(XXX); - A coder par la suite avec la gestion de boutons -
}

// La fonction fire est levée par une interruption (Elle stop le loop le temps de s'executer).
// Note: aucun print ou autre ici. On doit aller le plus vite possible et rendre la main au loop.
void fire(RunLoopTimer *sender)
{
 if( sender == timerAD )
 {
   // Cas du timer pour l'ascencsion droite si le moteur tourne

   // On envoie une impulsion haute
   digitalWrite (pas_AD, HIGH);

   // Et on repasse à un niveau bas
   digitalWrite (pas_AD, LOW);
 }
 else if( sender == timerDec )
 {
   // Cas du timer pour la déclinaison si le moteur tourne

   // A coder...
 }
}

void loop() 
{
 valeur_interrupteur_fin_de_course = digitalRead(interrupteur_fin_de_course);

 if (valeur_interrupteur_fin_de_course == HIGH) 
 {
   // On arrête le timer si butée de fin de course
   timerAD->setIdle(true);
 }
}

Je ne gère pas en PWM. Je passe directement par une levée d’interruption qui lance du code (ici la fonction fire()). C’est beaucoup plus modulable. On a ainsi tout loisir de compter les pas pour gérer le rattrapage de jeu par exemple.

@+,
Seb.

PS: là j’ai fais une version C avec callback. La librairie permet aussi de le faire en C++ soit par héritage, soit par délégation. Ce serait plus clean mais peut être un peu hors de portée pour l’instant donc j’ai préféré faire au plus simple en C. Plus de doc sur ma librairie ici…
http://em10-usd-arduino-takahashi.eliotis.com/librairies-arduino/runloop/index.html