IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Moteur CC + encodeur


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Février 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Février 2022
    Messages : 7
    Par défaut Moteur CC + encodeur
    Bonjour à tous.

    Je possède un télescope Meade, le RCX400 .

    Une raquette de commande permet de gérer toutes les fonctions du télescope qui est installé en altazimutal :
    Deux gros moteurs permettent d'orienter le tube (pointage) : celui logé dans la base horizontale le fait pivoter selon un axe vertical (réglage de l'azimut), celui logé dans la fourche permet d'abaisser ou de relever le tube optique (réglage de l'altitude), plusieurs vitesses étant disponibles.
    Un processeur intégré et programmé associé à une mémoire permet de pointer automatiquement n'importe quel objet du ciel (planètes, galaxies, amas globulaires, nébuleuses, etc) et d'en assurer le suivi.

    Tout ceci fonctionne parfaitement.

    La raquette permet également la focalisation (autrement dit : la mise au point) - comme sur un objectif d'appareil photo - de manière à obtenir une image nette.

    Elle permet également la collimation, c'est à dire l'alignement optique du miroir parabolique - qui se trouve au fond du tube - et de la lame de fermeture (sorte de grosse lentille) qui se trouve à l'autre bout du tube.

    Le miroir parabolique est fixe
    Seule la lame de fermeture se déplace en avant ou en arrière pour permettre la focalisation.

    Ce déplacement, pour les deux fonctions de focalisation et de collimation, est assuré par 3 petits moteurs solidaires chacun d'un encodeur optique, disposés à 120° au fond du tube et reliés à la lame de fermeture par 3 tiges filetées.

    La rotation simultanée des 3 moteurs dans un sens ou un autre déplace la lame en avant ou en arrière pour permettre la focalisation.
    Pour cela, les 3 moteurs doivent tourner exactement du même nombre de tours lorsqu'ils sont activés.

    Par contre, la rotation d'un seul de l'un ou l'autre des 3 moteurs va incliner la lame de fermeture sur son axe optique, ce qui permet d'aligner avec précision cet axe avec l'axe optique du miroir parabolique qui, lui, est fixe : c'est la collimation.

    La commande de ces 3 moteurs via la raquette ne fonctionne plus (un composant HS au niveau de la carte mère gérant toutes les fonctions : irréparable au dire du SAV Meade).
    Et les encodeurs d'origine bas de gamme sont HS (testés).
    D'ou leur remplacement prévu par des encodeurs US DIGITAL, plus fiables :
    https://www.usdigital.com/products/e...ental/kit/e4t/
    Ce qui a été déjà réalisé par plusieurs possesseurs de cet instrument qui avaient des problèmes récurrents avec les encodeurs d'origine.

    En résumé et pour faire court, le problème à résoudre est le suivant :

    * 3 moteurs CC 5V

    * chaque moteur est couplé à un encodeur optique (US DIGITAL).

    * les 3 moteurs alimentés pendant un temps T doivent avoir tourné exactement du même nombre de tours, dans un sens ou dans l'autre, sans qu'il soit besoin de connaître ce nombre de tours.

    Plusieurs astronomes amateurs m'ont suggéré que la solution passait par l’utilisation d'un Arduino...
    D'ou ma présence sur ce forum.

    J'ai des connaissances de base en électronique et suis capable de me servir d'un multimètre, et d'un fer à souder pour installer des composants sur une carte.
    J'ai une petite expérience avec Arduino, ayant fabriqué pour mon petit-fils un système de commande train miniature HO trouvé sur le site :
    http://udelmas.e-monsite.com/pages/c...-wifi-d17.html

    Si quelqu'un peut me fournir un schéma, me dire quels circuits acheter, ou m'indiquer un site ou je trouverais une aide plus spécifique pour résoudre ce problème, ou simplement me conseiller sur ce projet, je lui en serais très reconnaissant.

  2. #2
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 641
    Par défaut Microcontrôleur face à l'univers
    Bonjour,

    Je ne connais pas les télescopes mais suis un peu moins nul après la lecture de ce message.

    Voilà ce que j'ai compris :
    • Les trois moteurs dont il s'agit sont ceux qui agissent sur la focalisation.
    • A part quant on modifie la collimation, ils doivent se déplacer en synchrone (c'est le problème à résoudre)

    Y a t'il un dispositif qui permette de s'assurer que les trois moteurs sont dans une position de référence : contact de fin de course, détection de consommation en butée, etc. ? Ne serait-ce que pour remettre à plat la lame de fermeture.

    Les 3 moteurs sont alimentés en tout ou rien ou en PWM ? En tout ou rien, il y aura des rattrapages de position donc des vibrations durant le déplacement mais ce n'est peut être pas important. En PWM le programme peut doser l'énergie fournie à chaque moteur pour compenser les rendements qui peuvent différer (ne serait-ce que par le graissage inhomogène des tiges filetées). Caractéristiques des moteurs ?

    Les dispositifs mécaniques ont une tendance à avoir une certaine fluctuation. Prenons un exemple, les capteurs optiques sont très difficiles à caler les uns par rapport aux autres. Sur les 3, même si les moteurs sont parfaitement synchrones, il y en aura toujours un qui changera d'état en avance et un en retard. Ce n'est pas très grave si la résolution de l'encodeur (avec ou sans démultiplication) est sensiblement supérieure à la précision souhaitée (je n'ai pu le voir car j'ai une erreur 404 sur le lien fourni).

    Un Arduino ou un autre microcontrôleur peut faire l'affaire mais il faut savoir exactement ce qu'il y a à faire d'où les questions. Et j'en oublie certainement.

    Une photo du mécanisme permettrait de mieux concrétiser le problème.

    Salutations

  3. #3
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonjour michel2001
    Citation Envoyé par michel2001 Voir le message
    * les 3 moteurs alimentés pendant un temps T doivent avoir tourné exactement du même nombre de tours, dans un sens ou dans l'autre, sans qu'il soit besoin de connaître ce nombre de tours.
    Pas facile de synchroniser 3 moteurs CC!
    Est-ce qu'il est nécessaire que ces 3 moteurs s'arrêtent pile-poil les 3 en même temps avec un nombre de tours identiques?
    Ou est-il plausible de faire tourner les 3 moteurs un temps x tout en comptant les tour puis, à la fin du temps, choisir un moteur "mâitre" sur lequel on alignerai les 2 autres?
    Ces moteurs ont il des réducteurs, si oui, le comptage des tours est-il à considérer au niveau de l'axe de sortie du réducteur ou au niveau du moteur?

    Lien sur le codeur E4T.

    Cordialement
    jpbbricole

  4. #4
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Février 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Février 2022
    Messages : 7
    Par défaut
    Par "exactement" je veux dire que les 3 moteurs doivent avoir tourné de la même valeur angulaire lorsqu'on relâche le bouton qui les alimente.
    Cette valeur n'a pas d'importance et n'a pas à être connue, puisque le résultat de cette rotation sur la focalisation ou la collimation s'apprécie visuellement, soit directement à l'oculaire de l'instrument, soit par une caméra qui affiche l'image sur l'écran du PC.

    Le fait de disposer de plusieurs vitesses (3 ou 4) permet de "dégrossir" la focalisation avec une vitesse rapide, et de l'affiner ensuite avec la vitesse la plus lente.
    Idem pour la collimation, sauf qu'on agit alors seulement sur l'un ou l'autre des 3 moteurs.

    Lorsque le système fonctionnait, à la vitesse la plus lente la roue de l'encodeur mettait environ 15 secondes pour faire un tour complet.
    A la vitesse la plus rapide, 2 tours en 1 s, environ, et arrêt instantané, sans aucune inertie décelable.

    Pour ce qui est de la précision, compte tenu de la finesse du filetage des 3 tiges, un tour complet des encodeurs ne semble faire avancer ou reculer la lame que d'une petite fraction de mm.
    Et donc pour la rotation d'un incrément (la roue des encodeurs primitifs compte environ 40 dents), 1/40° de cette valeur, ce qui donne une précision d'action plus que suffisante pour peaufiner la collimation ou la focalisation.

    L'idéal serait d'agir sur la collimation ou la focalisation aussi bien depuis le PC que depuis la nouvelle raquette, via une liaison USB.
    Si les deux sont incompatibles, la liaison USB serait à privilégier, car elle permet, en hiver, de contrôler le télescope en restant au chaud à l'intérieur, tout en gérant le suivi et l’acquisition des images ou des vidéos avec des logiciels dédiés.

    Nom : P1040872-2.jpg
Affichages : 317
Taille : 117,2 Ko

  5. #5
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonjour michel2001
    Citation Envoyé par michel2001 Voir le message
    Par "exactement" je veux dire que les 3 moteurs doivent avoir tourné de la même valeur angulaire lorsqu'on relâche le bouton qui les alimente.
    Comme il se peut, au cours de l'exploitation et du fait que ce n'est pas des moteurs pas à pas, y avoir des décalages, entre les 3 moteurs, qui peuvent s'accumuler, y a-t-il une possibilité de refaire "un zéro", comme des contacts de début de course?

    Citation Envoyé par michel2001 Voir le message
    A la vitesse la plus rapide, 2 tours en 1 s, environ, et arrêt instantané, sans aucune inertie décelable.
    Est-ce que la commande de puissance des moteurs fait partie de l'électronique "out" si non, quel est son modèle?

    Cordialement
    jpbbricole

  6. #6
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 641
    Par défaut Synchrone asynchrone
    Bonjour,

    Si j'ai bien compris ce n'est pas tant un synchronisme qui est recherché qu'un même nombre de pas. Comme je l'ai déjà signalé cela impliquera des variations (vibrations) lors du déplacement mais comme c'est du positionnement cela ne doit pas être très grave.

    Une approche pourrait être alors (avec des moteurs A, B, C) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Tant que la commande est active
       Début
       Activer A, B et C
       Tant qu'au moins un moteur est actif
          Début
          Lire les encodeurs des moteurs actifs
          Si un moteur a franchi un pas, le désactiver
          Fin
       Fin
    C'est le PWM du pauvre

    Il faudrait prévoir un time out. Si aucun pas ne se produit sur les trois moteurs actifs durant un temps donné (par exemple 400 ms > 15 s/40 si la vitesse des moteurs n'est pas contrôlée par un temp) il faudrait supposer être en butée et arrêter tous les moteurs. Avec le sens, on sait s'il s'agit d'une butée haute ou basse. Il convient de remarquer que cette situation altère la collimation.

    Implicitement, on considère qu'il n'y a pas d'inertie.

    Si j'en crois la photo, il n'y a que trois fils vers le capteur, ce qui incite à penser qu'il ne travaille pas en biphase (+, 0, phase 1, phase 2) le sens de rotation étant donné par l'alimentation des moteurs (ponts en H ?)

    Salutation

  7. #7
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 917
    Par défaut
    je ne suis pas compétent sur les moteurs, mais par curiosité quelle est la difficulté de synchroniser des moteurs CC en position si on a une mesure de leur rotation?

  8. #8
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Février 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Février 2022
    Messages : 7
    Par défaut
    Question à @michel2001, quelle est la vitesse de rotation des encodeurs et combien de tics/tour?


    Lorsque le système fonctionnait :

    * à la vitesse la plus lente la roue de l'encodeur mettait environ 15 secondes pour faire un tour complet.
    * A la vitesse la plus rapide, 2 tours en 1 s, environ, et arrêt instantané, sans aucune inertie décelable.

    Si tu entend par "tics/tour" le nombre d'interruption du faisceau pour un tour de l'encodeur la photo postée plus haut montre une quarantaine de dents, et les encodeur étant solidaires de l'axe du moteur...

    Je ne pense pas qu'il y ait des réducteurs sur les moteurs : à la vitesse d'1 tour toutes les 15 s, et vu la finesse du filetage de la tige qui déplace la lame, ce déplacement doit être infime, plus que suffisant comme précision en tous cas pour avoir une focalisation parfaite.

  9. #9
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonsoir michel2001

    Je me suis « attelé » à l’exercice avec un Arduino UNO, des ponts en H L9110S et 2 moteurs CC avec roue codeuse, première grande différence, la vitesse de rotation des moteurs, par rapport à
    Citation Envoyé par michel2001 Voir le message
    * à la vitesse la plus lente la roue de l'encodeur mettait environ 15 secondes pour faire un tour complet.
    * A la vitesse la plus rapide, 2 tours en 1 s, environ, et arrêt instantané, sans aucune inertie décelable.
    Les miens sont beaucoup rapides d’où problèmes d’inertie que l’on ne devrait pas avoir avec des moteurs plus lents comme ceux de @michel2001. Je n’avais que 2 moteurs identiques pour faire l’essai.
    L’idée de départ est de faire tourner les n moteurs en même temps (void motRunAll(int sensRot)), rotation déclenchée au moyen d’un joystick logique (joyUp et joyDown) (if (joyUp.wasPressed() && ...)tout en enregistrant leurs positions en permanence (mot[m].positionPas et mot[moteurA].positionTours).
    Au relâché du joystick, on compare la position respective de chaque moteur par rapport au moteur de référence (motReference) (void motSynchro()) et on leur envoie des impulsions (void motImpuse(int motIndex, int duration, int direction))(motSyncPulse milliSec.) afin d’aligner les positions en pas avec une tolérance de motSyncDeltaMax.
    Il est très facile d’ajouter un ou des moteurs, Si tu est intéressé, je t’en ferais le détail.
    Le brochage utilisé se trouve dans le tableau mot[] et pour les boutons de commande, joyUpPin et joyDownPin
    C’est un exercice très amusant à réaliser.
    Il y a plein de Serial.print( pour montrer l’activité du programme, il ne sont pas utiles au fonctionnement et peuvent aisément supprimés.

    Le programme reconnaît des commandes MOT et MOTALL introduites depuis la ligne de commande du moniteur série :
    MOT1=1 Fait tourner le moteur 1 direction CW (motDirSTOP, motDirCW, motDirCCW, motDirBREAK)
    MOT2=3 Stoppe le moteur 2 (Frein)
    MOTALL=2 Fait tourner tout les moteurs direction CCW
    MOTALL=0 Arrête tout les moteurs (Roue libre)
    Les commandes ne sont pas sensibles à la casse.

    Le programme : (C’est vraiment un « premier jet » !!)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    /*
        Name:       MoteursCCsynchro.ino
        Created:	26.02.2022
        Author:     jpbbricole 
    */
     
    #include <JC_Button.h>          // https://github.com/JChristensen/JC_Button
                                    // https://www.arduino.cc/reference/en/libraries/jc_button/
     
    //------------------------------------- Moteurs (mot)
    enum motDirectionsIndex {motDirSTOP, motDirCW, motDirCCW, motDirBREAK};
    enum moteursIndex {moteurA, moteurB};
     
    const int motReference = moteurA;
    const int motBreakPulse = 100;     // Durée impulsion de freinage
    const int motSyncPulse = 7;     // Durée impulsion de synchronisation
    long motSyncDeltaMax = 10;     // Durée impulsion de synchronisation
     
    struct motorDef
    {
    	const int hBridgeA;     // Port A du moteur
    	const int hBridgeB;     // Port B
    	const int rotEncPinA;     // Codeur rotatif entrée A
    	const int rotEncPinB;     // Codeur rotatif entrée A
    	const int rotEncincrement;     // Codeur rotatif entrée A
    	int rotEncPasTour;     // Codeur pas au tour
    	volatile long positionPas;     // Position en pas
    	volatile long positionTours;     // Position en tours
    	int direction;     // Sens de rotation CW ou CCW
    	boolean isRunning;    // Si en fonction
    };
     
    motorDef mot[] =     // Paramétrage des moteurs
    {// H-Br. A  H-Br. B   Encod A   Encod B   Incrément.   Enc pas/tourr   Pos. Pas   Pos. Tours   Direction   En fonction
    	{ A0,      A3,       2,        8,        -1,             11,            0,         0,         motDirCW,     false },      // Moteur A
    	{ 10,      11,       3,        9,         1,             11,            0,         0,         motDirCW,     false },      // Moteur B
    };
    const int motNumber = sizeof(mot)/sizeof(mot[0]);     // Nombre de moteurs
    const int motSpeedDefault = 250;     // Vitesse par défaut
     
    //------------------------------------- H-Bridgr (hbri)
    const int hbriCmdOn = HIGH;
     
    //------------------------------------- Joystick (joy)
    // ToggleButton(pin,  dbTime, puEnable, invert); 
    const int joyUpPin = A1;
    const int joyDownPin = A2;
     
    //            pin,       dbTime, puEnable, invert
    Button joyUp(joyUpPin);//,     20,     true,   true);
    Button joyDown(joyDownPin);//, 20,     true,   false);
     
    //------------------------------------- Ligne de commandes
    bool cmdNouvelleRecue = false;      // Si une nouvelle commande a été reçue
    String cmdTexte = "";               // Texte de la commande
     
    unsigned long displTimer = millis();
     
     
    void setup()
    {
    	Serial.begin(115200);
    	Serial.setTimeout(50);     // Pour fin des commandes depuis le moniteur
     
    	joyUp.begin();     // Initialisation des boutons des joysticks
    	joyDown.begin();
     
    	//--------------------------------- Entrées/Sorties
    	for (int m = 0; m < motNumber; m ++)
    	{
    		pinMode(mot[m].hBridgeA, OUTPUT);     // Initialisdation du pont H-Bridge
    		pinMode(mot[m].hBridgeB, OUTPUT);
    		digitalWrite(mot[m].hBridgeA, !hbriCmdOn);
    		digitalWrite(mot[m].hBridgeB, !hbriCmdOn);
     
    		pinMode(mot[m].rotEncPinA, INPUT_PULLUP);
    		pinMode(mot[m].rotEncPinB, INPUT_PULLUP);;
    	}
    	attachInterrupt(digitalPinToInterrupt(mot[moteurA].rotEncPinA), rotencAchangeHandling, FALLING);
    	attachInterrupt(digitalPinToInterrupt(mot[moteurB].rotEncPinA), rotencBchangeHandling, FALLING);
    }
     
    void loop()
    {
    	// Affichage périodique des positions moteurA, moteurB et moteurA-moteurB
    	if (millis()-displTimer >= 1000)
    	{
    		Serial.print(mot[motReference].positionPas);
    		Serial.print("\t");
    		Serial.print(mot[moteurB].positionPas);
    		Serial.print("\t");
    		Serial.println(mot[motReference].positionPas - mot[moteurB].positionPas);
     
    		displTimer = millis();
    	}
     
    	//--------------------------------- Lecture des joystick
    	joyUp.read();
    	joyDown.read();
     
    	if (joyUp.wasPressed() && !mot[motReference].isRunning)     // Si joystick UP pressé et moteur arrêté
    	{
    		motSynchroReStart();
    		motRunAll(motDirCW);
    		mot[motReference].isRunning = true;
    		Serial.println("Moteurs AVANT ON");
    	}
     
    	if (joyUp.wasReleased() && mot[motReference].isRunning)     // Si joystick UP relaché et moteur en fonction
    	{
    		motRunAll(motDirBREAK);
    		mot[motReference].isRunning = false;
    		Serial.println("Moteurs AVANT OFF");
    		motSynchro();
    	}
     
    	if (joyDown.wasPressed() && !mot[motReference].isRunning)     // Si joystick DOWN pressé et moteur arrêté
    	{
    		motSynchroReStart();
    		motRunAll(motDirCCW);
    		Serial.println("Moteurs ARRIERE ON");
    		mot[motReference].isRunning = true;
    	}
     
    	if (joyDown.wasReleased() && mot[motReference].isRunning)     // Si joystick DOWN relaché et moteur en fonction
    	{
    		motRunAll(motDirBREAK);
    		mot[motReference].isRunning = false;
    		Serial.println("Moteurs ARRIERE OFF");
    		motSynchro();
    	}
    	//--------------------------------- Ecoute du port serie
      //serialEvent();           // Enlever le commentaire si l'appel ne se fait pas automatiquement
      // Pour Leonardo, Micro ou Yún
      if (cmdNouvelleRecue)      // Si une nouvelle commande depuis le moniteur
      {
    	  cmdExecute(cmdTexte);
     
    	  cmdTexte = "";
    	  cmdNouvelleRecue = false;
      }
     
    }
     
    //--------------------------------- Moteur marche tous (0-100)
    void motImpuse(int motIndex, int duration, int direction)
    {
    	motRun(motIndex, direction);
    	delay(duration);
    	motRun(motIndex, motDirSTOP);
    }
     
    //--------------------------------- Moteur marche tous (0-100)
    void motRunAll(int sensRot)
    {
    	for (int m = 0; m < motNumber; m ++)
    	{
    		motRun(m, sensRot);
    	}
    }
     
    //--------------------------------- Moteur marche (0-100)
    void motRun(int motIndex, int motDir) //, boolean withBreak)
    {
    	int hbriCmdA;
    	int hbriCmdB;
     
    	switch (motDir) {
    		case motDirSTOP:
    			Serial.println("dir STOP " + String(motIndex));
    			hbriCmdA = !hbriCmdOn;     // Tout OFF
    			hbriCmdB = !hbriCmdOn;
    			break;
    		case motDirCW:
    			Serial.println("dir CCW " + String(motIndex));
    			hbriCmdA = hbriCmdOn;
    			hbriCmdB = !hbriCmdOn;
    			mot[motIndex].direction = motDirCW;
    			break;
    		case motDirCCW:
    			Serial.println("dir CCW " + String(motIndex));
    			hbriCmdA = !hbriCmdOn;
    			hbriCmdB = hbriCmdOn;
    			mot[motIndex].direction = motDirCCW;
    			break;
    		case motDirBREAK:
    			Serial.println("dir BREAK " + String(motIndex));
    			hbriCmdA = hbriCmdOn;     // Tout ON
    			hbriCmdB = hbriCmdOn;
    			break;
    		default:
     
    			break;
    	}
    	digitalWrite(mot[motIndex].hBridgeA, hbriCmdA);
    	digitalWrite(mot[motIndex].hBridgeB, hbriCmdB);
     
    	if (motDir == motDirBREAK)
    	{
    		delay(motBreakPulse);
    		digitalWrite(mot[motIndex].hBridgeA, !hbriCmdOn);
    		digitalWrite(mot[motIndex].hBridgeB, !hbriCmdOn);
    		Serial.println("dir BREAK OFF " + String(motIndex));
    	}
    }
     
    void motSynchro()
    {
    	for (int m = 0; m < motNumber; m ++)
    	{
    		if (m != motReference)     // Si pas moteur principal
    		{
    			boolean syncOk = false;
    			while(!syncOk)
    			{
    				long motPosDelta = mot[motReference].positionPas - mot[m].positionPas;
    				int syncDir = (motPosDelta < 0) ? motDirCCW : motDirCW;     // Si négatif direction CCW
     
    				if (abs(motPosDelta) <= motSyncDeltaMax)     // Si synchrone
    				{
    					syncOk = true;
    				} 
    				else
    				{
    					Serial.print("\t\tSYNC  " + String(motPosDelta));
    					Serial.print("\tMoteur " + String(m));
    					Serial.println("\t " + String(motPosDelta));
    					motImpuse(m, motSyncPulse, syncDir);
    					delay(5);
    				}
    			Serial.print(mot[motReference].positionTours);
    			Serial.print("\t");
    			Serial.println(mot[m].positionTours);
    			}
    		}
    	}
    }
     
    void motSynchroReStart()
    {
    	for (int m = 0; m < motNumber; m ++)
    	{
    		mot[m].positionPas = 0;
    		mot[m].positionTours = 0;
    	}
    }
     
    //------------------------------------- Rotary encoder Traitement des interruptions
    void rotencAchangeHandling()                                         // Sortie A
    {
    	if (!digitalRead(mot[moteurA].rotEncPinA) == !digitalRead(mot[moteurA].rotEncPinB))
    	{mot[moteurA].positionPas += mot[moteurA].rotEncincrement;} else {mot[moteurA].positionPas -= mot[moteurA].rotEncincrement;}
    	mot[moteurA].positionTours = mot[moteurA].positionPas / mot[moteurA].rotEncPasTour;
    }
    void rotencBchangeHandling()                                         // Sortie A
    {
    	if (!digitalRead(mot[moteurB].rotEncPinA) == !digitalRead(mot[moteurB].rotEncPinB))
    	{mot[moteurB].positionPas += mot[moteurB].rotEncincrement;} else {mot[moteurB].positionPas -= mot[moteurB].rotEncincrement;}
    	mot[moteurB].positionTours = mot[moteurB].positionPas / mot[moteurB].rotEncPasTour;
    }
     
    //===================================== Execution des commandes
    void cmdExecute(String commande)
    {
    	commande.toUpperCase();
    	commande.replace(" ", "");     // Supprimer les espaces
    	Serial.println("Execution de : " + commande);
     
    	int sepPos = commande.indexOf(",");
    	String cmd = commande.substring(0, sepPos);     // Extraction de la commande
    	String cmdParam = cmd.substring(cmd.indexOf("=")+1);     // Extraction du paramètre
    	int cmdParamInt = cmdParam.toInt();
    	int cmdObjectIndex = -1;     // Numéro de l'objet (MOT1 etc)
     
    	if (cmd.startsWith(F("MOTALL")))     // Commande moteur MOT1:50 ou MOT1:-50 (0-100)
    	{
    		motRunAll(cmdParamInt);
    	}
    	else if (cmd.startsWith(F("MOT")))     // Commande moteur MOT1:50 ou MOT1:-50 (0-100)
    	{
    		int cmdObjectIndex = cmdExtractObjectIndex("MOT", cmd)-1;
     
    		motRun(cmdObjectIndex, cmdParamInt);
    	}
    	//--------------------------------- Pour test
    	else if (cmd.startsWith(F("TEST")))     
    	{
    		Serial.print(F("Commande TEST"));
     
    	}
    	else
    	{
    		Serial.print(F("Commande inconnue!!! ")); Serial.println(commande);
    	}
    }
    /*-----------------------------------------------------------------------------
    	Retourne l'index de l'objet en commande qui se trouve en fin de commande
    	MOT2 retourne 2   MOT11 retourne 11
    '*-----------------------------------------------------------------------------
    */
    int cmdExtractObjectIndex(String cmd, String cmdWindex)     
    {
    	cmdWindex.replace(cmd, "");
    	return cmdWindex.toInt();
     
    }
     
    /*-----------------------------------------------------------------------
      Réception de commandes depuis le moniteur
    '*------------------------------------------------------------------------
    */
    void serialEvent()                                       
    {
      if (Serial.available())
      {
    	  cmdTexte = Serial.readString();
    	  cmdTexte.replace("\n", "");
    	  cmdTexte.replace("\r", "");
    	  cmdNouvelleRecue  = true;
      }
    }
    Mon « sentiment » après cet exercice, est qu'il faudrait profiter de ce que la partie électronique est défectueuse pour passer à des moteurs pas à pas, on gagnerai en simplicité et en précision.

    A+
    Cordialement
    jpbbricole

  10. #10
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 917
    Par défaut
    Est-ce qu’il y a un gros décalage en fin de course sur le nombre de tours?

  11. #11
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonjour Jay M

    Ca dépend du temps de fonctionnement, dans ma configuration, avec des moteurs qui tournent vite, en 10 secondes, j'ai eu jusqu'à 100 pas de différence, j'ai 11 tics/tour. En plus, ces moteurs ne tournent pas à la même vitesse dans les 2 sens. Par exemple, si les 2 moteurs tournent CCW, j'ai beaucoup moins de décalage que les 2 en CW.
    Les moteurs de @michel2001 tournent lentement, il y aura peut être moins de décalage, mais ça reste des moteurs "analogiques".
    Je verrais assez un remplacement des dits moteurs par des moteurs pas à pas.

    Cordialement
    jpbbricole

  12. #12
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 641
    Par défaut Progresser pas à pas
    Bonjour JPBbricole,

    Citation Envoyé par jpbbricole Voir le message
    ...Je verrais assez un remplacement des dits moteurs par des moteurs pas à pas...
    C'est également ce que j'avais conclu en regardant le schéma de commande. Mais est-ce que les moteurs pas à pas s'intégreront mécaniquement dans le télescope ?

    Salut

  13. #13
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonjour Guesset
    Citation Envoyé par Guesset Voir le message
    Pourquoi, dans les gestionnaires d'interruptions, écrire !digitalRead(mot[moteurA].rotEncPinA) == !digitalRead(mot[moteurA].rotEncPinB) il n'y a, à mon sens, aucun intérêt à mettre
    C'est même essentiel, ça permet de définir le sens de rotation donc incrémenter ou décrémenter!

    Citation Envoyé par Guesset Voir le message
    Pourquoi un capteur incrémente tandis que l'autre décrémente ? Câblage ?
    Les 2 capteurs sont traités de manière absolument identique dans void rotencAchangeHandling() respectivement void rotencBchangeHandling(), seul l'index du moteurs change (moteurA et moteurB).

    Cordialement
    jpbbricole

  14. #14
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 641
    Par défaut Précisions
    Bonjour jpbbricole,

    Citation Envoyé par jpbbricole Voir le message
    C'est même essentiel, ça permet de définir le sens de rotation donc incrémenter ou décrémenter!
    Ce n'est pas le test qui m'interroge mais le "!" de négation logique devant chaque terme de l'égalité qui ne change rien (les arguments ayant le même type et une égalité reste une égalité).

    Citation Envoyé par jpbbricole Voir le message
    Les 2 capteurs sont traités de manière absolument identique dans void rotencAchangeHandling() respectivement void rotencBchangeHandling(), seul l'index du moteurs change (moteurA et moteurB).
    Le traitement est le même mais les incréments sont inversés dans la déclaration.

    Salut

  15. #15
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 917
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 917
    Par défaut
    Citation Envoyé par jpbbricole Voir le message
    Ca dépend du temps de fonctionnement, dans ma configuration, avec des moteurs qui tournent vite, en 10 secondes, j'ai eu jusqu'à 100 pas de différence, j'ai 11 tics/tour. En plus, ces moteurs ne tournent pas à la même vitesse dans les 2 sens. Par exemple, si les 2 moteurs tournent CCW, j'ai beaucoup moins de décalage que les 2 en CW.
    Effectivement c’est beaucoup. Une approche en PID pour conserver l’écart minime et ne pas le laisser dériver pourrait s’avérer intéressante

  16. #16
    Membre à l'essai
    Homme Profil pro
    retraité
    Inscrit en
    Février 2022
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Février 2022
    Messages : 7
    Par défaut
    Bonsoir à tous.

    "un remplacement des dits moteurs par des moteurs pas à pas"

    C'est absolument inenvisageable, pour moi en tous cas : il faudrait pour cela démonter entièrement la partie optique pour accéder aux tiges filetées fixées sur l'axe des moteurs.
    Je ne me risquerai pas à faire cette manip.

    Par ailleurs, je dois dire que le système conçu par Meade avec des moteurs CC fonctionne parfaitement (enfin, fonctionnait...) et avec une grande précision : on pouvait mémoriser plusieurs focalisations différentes en fonction de la configuration optique choisie (caméra, oculaire, barlow, réducteur de focale, etc).
    Et pour la collimation, le réglage d'usine fait au laser était en mémoire : après avoir voulu améliorer la collimation plusieurs fois en croyant bêtement mieux faire que Meade, je me suis aperçu que je n'avais réussi qu'à la dérégler fortement.
    Chaque fois il m'a suffit de faire un reset de la collimation et j'ai retrouvé un alignement parfait des optiques.

    "Mais est-ce que les moteurs pas à pas s'intégreront mécaniquement dans le télescope ?"

    J'ai la quasi-certitude que non, et je n'ai aucune idée de la manière dont les tiges filetées sont fixées sur les axes des moteurs : ça risquerait de devenir un sacré chantier !

  17. #17
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 641
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 641
    Par défaut Propositions
    Bonjour,

    Il y a plusieurs éléments qui me semblent étranges :
    • Pourquoi, dans les gestionnaires d'interruptions, écrire !digitalRead(mot[moteurA].rotEncPinA) == !digitalRead(mot[moteurA].rotEncPinB) il n'y a, à mon sens, aucun intérêt à mettre !.
    • Pourquoi un capteur incrémente tandis que l'autre décrémente ? Câblage ?
    • Calculer positionTours dans l'interruption, c'est faire une opération lourde (il n'y pas de division dans le CPU) et inutile dans 90% des cas (10/11). Si on veut garder cela dans l'interruption, il faudrait par exemple ajouter un positionPas0 utilisable ainsi : if( abs(mot[moteurA].positionPas - mot[moteurA].positionPas0) > 10) { mot[moteurA].positionTours += mot[moteurA].positionPas > mot[moteurA].positionPas0 ? 1: -1; mot[moteurA].positionPas0 = 0; }

    La solution de régler les écarts à la fin marche avec des moteurs non contraints réciproquement. Mais elle ne semble pas adaptée s'il faut respecter une limite de différence (ce qui doit être le cas avec le télescope). Aussi j'ajouterais dans les interruptions un dif_AB = int8_t(moteurA].positionPas - mot[moteurB].positionPas & $FF) pour pouvoir corriger le tir au fil du processus sans se soucier d'arrêter les interruptions. Il faut espérer être capable de limiter l'écart à 127 pas. L'usage du PWM serait peut être pratique ? Une autre approche pourrait être de créer des auto-répétitions de touches par exemple tous le 1/10 s qui utiliseraient le processus de recalage prévu à la fin de commande.

    That's all folks !

Discussions similaires

  1. Code asservissement position moteur cc avec encodeur
    Par Loupote dans le forum Arduino
    Réponses: 10
    Dernier message: 01/02/2023, 09h41
  2. Commande PWM moteur CC, lecture encodeur
    Par Horus68 dans le forum Arduino
    Réponses: 49
    Dernier message: 30/04/2021, 18h39
  3. Réponses: 6
    Dernier message: 08/12/2020, 20h29
  4. Programme Arduino de commande de moteur+encodeur.
    Par loquet38 dans le forum Arduino
    Réponses: 7
    Dernier message: 15/03/2018, 20h20
  5. [Technique] Index, comment font les moteurs de recherche ?
    Par bat dans le forum Décisions SGBD
    Réponses: 4
    Dernier message: 25/10/2002, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo