Aller au contenu

Messages recommandés

Posté (modifié)

Bonjour à toutes et tous,

 

Ça fait (trop) longtemps que je n'ai plus rien posté sur ce forum et croyez moi, ce n'est pas l'envie qui m'en manque...

 

Alors voilà, je vais essayer de me faire pardonner en vous présentant mon nouveau bricolage!

 

Un porte oculaire motorisé (encore) cette fois avec un moteur pas à pas, il n'est pas pour moi, il a été réalisé pour un camarade du club astro.

 

Il s'agit d'un moteur pas à pas NEMA 200 pas, bipolaire avec un couple de 40Ncm... piloté par une carte Arduino UNO, d'un motorshield... Une interface graphique permet d'envoyer les instructions à l'arduino...

 

Le programme de l'arduino et de l'interface graphique son maison...

 

C'est compatible windows, linux et Mac comme ça tout le monde est content!

 

Toutes les photos sont sur mon site (en construction) http://185.13.39.92/laboratoire/cak/sfocus/

 

main_300_cw450_ch450_thumb.jpg

 

P1060104_300_cw450_ch450_thumb.jpg

 

P1060105_300_cw450_ch450_thumb.jpg

 

P1060106_300_cw450_ch450_thumb.jpg

 

P1060107_300_cw450_ch450_thumb.jpg

 

P1060108_300_cw450_ch450_thumb.jpg

 

A oui et le prix me direz vous? Moins de 100€ ! (Avec l'alimentation fixe de 2A, le câble usb de 2 mètres)

Modifié par DrThrax
Posté

Hello, je te remercie, à dire vrai...

 

Je ne sais pas comment on fait pour être "ascom", déjà ascom ne fonctionne que sous windows... nativement du moins...

Posté

Bravo,

Un truc costaud et moins cher que ce qu'on trouve au même niveau de robustesse sur le marché.

 

Cependant je m'interroge sur 2 choses:

 

Le moteur n'est-il pas surdimensionné?

J'ai les même pour piloter ma monture.

 

La résolution (calculée à la louche à 0,145 mm/pas pour un diamètre d'axe d'entrainement de 6mm) est-elle suffisante?

En clair, tu te retrouves pas avec la map idéale entre deux pas?

Posté

Hello...

 

Bah, j'ai testé un moteur pas à pas "bon marché" et le couple était largement insuffisant pour actionner le porte oculaire...

 

J'ai donc commandé un moteur pas à pas de 12v... avec un couple sur dimensionné, c'est un Nema, Nema fournit des démultipliées pour ses moteurs pas à pas... mais il y a toujours le risque d'être entre deux pas même avec une démultipliée...

 

Je n'ai pas installé de démultipliée sur ce modèle car dans le cahier des charges du demandeur, j'avais une largeur max pour le moteur et l'accouplement à ne pas déplacer (6cm...)

 

J'espère pour la map... mais bon 200 pas c'est déjà beaucoup...

Posté
Hello...

 

Bah, j'ai testé un moteur pas à pas "bon marché" et le couple était largement insuffisant pour actionner le porte oculaire...

 

J'ai donc commandé un moteur pas à pas de 12v... avec un couple sur dimensionné, c'est un Nema, Nema fournit des démultipliées pour ses moteurs pas à pas... mais il y a toujours le risque d'être entre deux pas même avec une démultipliée...

 

Je n'ai pas installé de démultipliée sur ce modèle car dans le cahier des charges du demandeur, j'avais une largeur max pour le moteur et l'accouplement à ne pas déplacer (6cm...)

 

J'espère pour la map... mais bon 200 pas c'est déjà beaucoup...

 

NEMA n'est pas une marque mais une sorte de norme caractérisant la taille du moteur.

A vue de nez, ton moteur est un NEMA17. Il existe les mêmes en plus petits et en plus grand.

 

Pour la map idéale, elle est plus ou moins tolérante et il est tout à fait possible qu'une résolution de 0,145mm/pas soit tout à fait suffisante.

Tout dépend du rapport F/D. En dessous de 4 la plage de map idéale est beaucoup moins grande qu'au dessus de F/d6.

Manifestement, c'est à installer sur une lulu alors il y a toutes les chances pour que cette résolution soit suffisante.

Posté
NEMA n'est pas une marque mais une sorte de norme caractérisant la taille du moteur.

A vue de nez, ton moteur est un NEMA17. Il existe les mêmes en plus petits et en plus grand.

 

Pour la map idéale, elle est plus ou moins tolérante et il est tout à fait possible qu'une résolution de 0,145mm/pas soit tout à fait suffisante.

Tout dépend du rapport F/D. En dessous de 4 la plage de map idéale est beaucoup moins grande qu'au dessus de F/d6.

Manifestement, c'est à installer sur une lulu alors il y a toutes les chances pour que cette résolution soit suffisante.

 

 

Hello,

 

Oui tout a fait, j'ai été un peu vite en besogne... je ne sais pas qui est le fabricant du moteur... c'est bien un 17...

 

Pour ce qui est du F/D, c'est bien supérieur à 6, je pense que c'est pour équiper un instrument à F/D 10, je demanderai au futur possesseur ce qu'il en pense...

  • 2 semaines plus tard...
Posté

/*tentative controle moteur pas à pas pour mise au point*/
/*30-11-2014*/

#include <AFMotor.h>

   AF_Stepper motor1(200, 1);
   char val;
   int vitesse = 10;
   int i = 0;
   int x = 0;
   int poszero = 0; //variable pour recevoir la position du PO au lancement de l'app
   int posfinal = 35; //longueur du po en mm
   int target = 0; //variable pour recevoir la position à atteindre
   int facteur = 15; //16 pas par mm en sortie de réducteur!

   void setup() {
     // initialize serial:
    Serial.begin(9600);
    motor1.setSpeed(vitesse);
   }

   void loop() {
     int a;
     a = 0;
     //poszero = 0;
     // if there's any serial available, read it:
     while (Serial.available() > 0) {
      int index=Serial.read(); // lire un premier caractère

      // controle éventuel : décommenter pour voir ce qui arrive
      //Serial.print("index : "); Serial.println(index);


      // filtrer : il doit etre une lettre minuscule ou majuscule
      if(index >= 'A' && index <= 'z'){
        int valeur = Serial.parseInt();

        // controle eventuel de la valeur
        //Serial.print("valeur : "); Serial.println(valeur);


        // traitement
        switch(index){
          //avancer dix fois nombres de pas envoyés en arrière
          case 'a':
            a = 10 * valeur;
            motor1.step(a, BACKWARD, DOUBLE);
            motor1.release();
          break;
          //avancer une fois nombre de pas envoyés en arrière
          case 'b':
            motor1.step(valeur, BACKWARD, DOUBLE);
            motor1.release();
          break;
          //avancer un pas en arrière
          case 'c':
            motor1.step(1, BACKWARD, DOUBLE);
            motor1.release();
          break;
          //avancer dix fois nombres de pas envoyés en avant
          case 'd':
            a = 10 * valeur;
            motor1.step(a, FORWARD, DOUBLE);
            motor1.release();
          break;
          //avancer une fois nombre de pas envoyés en avant
          case 'e':
            motor1.step(valeur, FORWARD, DOUBLE);
            motor1.release();
          break;
          //avancer un pas en avant
          case 'f':
            motor1.step(1, FORWARD, DOUBLE);
            motor1.release();
          break;
          //aller a la position
          case 'g':
          if(valeur <= posfinal)
          {
            a = valeur-poszero;
            a = a * facteur;
            Serial.print(poszero); 

            if(a > 0)
            {
              motor1.step(a, FORWARD, DOUBLE);
              motor1.release();
              poszero = valeur;
              Serial.print(poszero);   
            }
            else
            {
              a = abs(a);
              motor1.step(a, BACKWARD, DOUBLE);
              motor1.release();
              poszero = valeur;
             Serial.print(poszero);  
            }
          }

          break;
          //definition poszero
          case 'h':
            poszero = valeur;
          break;
          case 'i':
            facteur = valeur;
          break;
          case 'v':
            vitesse = valeur;
            motor1.setSpeed(vitesse);
            motor1.release();
          break;
         }

      }
    }
  delay(10); //pas la peine de tourner à plein régime
 }

 

code python

 

#! /usr/bin/env python
# -*- python -*-
import sys
import serial

py2 = py30 = py31 = False
version = sys.hexversion
if version >= 0x020600F0 and version < 0x03000000 :
   py2 = True    # Python 2.6 or 2.7
   from Tkinter import *
   import ttk
elif version >= 0x03000000 and version < 0x03010000 :
   py30 = True
   from tkinter import *
   import ttk
elif version >= 0x03010000:
   py31 = True
   from tkinter import *
   import tkinter.ttk as ttk
   from tkinter import messagebox 
else:
   print ("""
   You do not have a version of python supporting ttk widgets..
   You need a version >= 2.6 to execute PAGE modules.
   """)
   sys.exit()



def vp_start_gui():
   '''Starting point when module is the main routine.'''
   global val, w, root
   root = Tk()
   root.title('SFocus')
   root.geometry('368x266+479+376')
   w = SFocus (root)
   set_Tk_var()
   init()
   root.mainloop()

w = None
def create_SFocus (root):
   '''Starting point when module is imported by another program.'''
   global w, w_win
   if w: # So we have only one instance of window.
       return
   w = Toplevel (root)
   w.title('SFocus')
   w.geometry('368x266+479+376')
   w_win = SFocus (w)
   set_Tk_var()
   init()
   return w_win

def destroy_SFocus ():
   global w
   w.destroy()
   w = None

def set_Tk_var():
   # These are Tk variables used passed to Tkinter and must be
   # defined before the widgets using them are created.
   global delay
   delay = DoubleVar()

   global speed
   speed = DoubleVar()

   global true_delay
   true_delay = StringVar()

   global true_speed
   true_speed = StringVar()

   #definition de la variable po qui contient la course maximale du porte oculaire
   global po
   po = IntVar()
   po = 350


   global ser
   #ser = serial.Serial('/dev/ttyACM0', 9600, bytesize=8, parity='N', stopbits=1, timeout=None)
   ser = serial.Serial()
   ser.port= 4
   ser.baudrate = 9600
   ser.bytesize = 8
   ser.parity = 'N'
   ser.stopbits = 1
   ser.timeout = 200



def aideClick(p1) :
   print("aide")


def connexionClick(p1) :
   print ('connect_click')
   ser.open()
   print (ser.isOpen())


def deconnexionClick(p1) :
   print ('unconnect_click')
   ser.close()
   print (ser.isOpen())


def gotoClick(p1) :
   print("goto")
   if int(w.Entry2.get())>350:
       messagebox.showerror("Valeurs hors limite","La course du porte oculaire est de maxium "+str(po)+" mm")
   else:
       command = "g"+w.Entry2.get()
       print(command)
       ser.write(command.encode())
       ser.write('\n'.encode())


def m1Click(p1) :
   print("m1")
   command = "c"
   print(command)
   ser.write(command.encode())
   ser.write('\n'.encode())

def majClick(p1) :
   print("maj")
   if int(w.Entry1.get())>350:
       messagebox.showerror("Valeurs hors limite","La course du porte oculaire est de maxium "+str(po)+" mm")
   else:
       command = "h"+w.Entry2.get()
       print(command)
       ser.write(command.encode())
       ser.write('\n'.encode())

def mx10Click(p1) :
   print("mx10click")
   deplacement = (int(w.Entry3.get())) * 1
   command = "a"+str(deplacement)
   print(command)
   ser.write(command.encode())
   ser.write('\n'.encode())


def mx1Click(p1) :
   print("mx1click")
   deplacement = int(w.Entry3.get())
   command = "b"+str(deplacement)
   print(command)
   ser.write(command.encode())
   ser.write('\n'.encode())

def p1Click(p1) :
   print("p1click")
   command = "f"
   print(command)
   ser.write(command.encode())
   ser.write('\n'.encode())

def px10Click(p1) :
   print("px10click")
   deplacement = (int(w.Entry3.get())) * 1
   command = "d"+str(deplacement)
   print(command)
   ser.write(command.encode())
   ser.write('\n'.encode())

def px1Click(p1) :
   print("px1click")
   deplacement = int(w.Entry3.get())
   command = "e"+str(deplacement)
   print(command)
   ser.write(command.encode())
   ser.write('\n'.encode())

def init():
   pass




class SFocus:
   def __init__(self, master=None):
       # Set background of toplevel window to match
       # current style
       style = ttk.Style()
       theme = style.theme_use()
       default = style.lookup(theme, 'background')
       master.configure(background=default)

       self.Entry1 = Entry (master)
       self.Entry1.place(relx=0.05,rely=0.49,relheight=0.07,relwidth=0.16)
       self.Entry1.configure(background="white")
       self.Entry1.configure(disabledforeground="#a3a3a3")
       self.Entry1.configure(foreground="black")
       self.Entry1.configure(highlightbackground="#d9d9d9")
       self.Entry1.configure(highlightcolor="black")
       self.Entry1.configure(insertbackground="black")
       self.Entry1.configure(selectbackground="#c4c4c4")
       self.Entry1.configure(selectforeground="black")

       self.Button1 = Button (master)
       self.Button1.place(relx=0.27,rely=0.64,height=34,width=47)
       self.Button1.configure(activebackground="#f9f9f9")
       self.Button1.configure(activeforeground="black")
       self.Button1.configure(background="#d9d9d9")
       self.Button1.configure(disabledforeground="#a3a3a3")
       self.Button1.configure(foreground="black")
       self.Button1.configure(highlightbackground="#d9d9d9")
       self.Button1.configure(highlightcolor="black")
       self.Button1.configure(pady="0")
       self.Button1.configure(text='''x1''')
       self.Button1.bind('<Button-1>',mx1Click)

       self.Button2 = Button (master)
       self.Button2.place(relx=0.11,rely=0.64,height=34,width=47)
       self.Button2.configure(activebackground="#f9f9f9")
       self.Button2.configure(activeforeground="black")
       self.Button2.configure(background="#d9d9d9")
       self.Button2.configure(disabledforeground="#a3a3a3")
       self.Button2.configure(foreground="black")
       self.Button2.configure(highlightbackground="#d9d9d9")
       self.Button2.configure(highlightcolor="black")
       self.Button2.configure(pady="0")
       self.Button2.configure(text='''x10''')
       self.Button2.bind('<Button-1>',mx10Click)

       self.Button3 = Button (master)
       self.Button3.place(relx=0.6,rely=0.64,height=34,width=47)
       self.Button3.configure(activebackground="#f9f9f9")
       self.Button3.configure(activeforeground="black")
       self.Button3.configure(background="#d9d9d9")
       self.Button3.configure(disabledforeground="#a3a3a3")
       self.Button3.configure(foreground="black")
       self.Button3.configure(highlightbackground="#d9d9d9")
       self.Button3.configure(highlightcolor="black")
       self.Button3.configure(pady="0")
       self.Button3.configure(text='''x1''')
       self.Button3.bind('<Button-1>',px1Click)

       self.Button4 = Button (master)
       self.Button4.place(relx=0.76,rely=0.64,height=34,width=47)
       self.Button4.configure(activebackground="#f9f9f9")
       self.Button4.configure(activeforeground="black")
       self.Button4.configure(background="#d9d9d9")
       self.Button4.configure(disabledforeground="#a3a3a3")
       self.Button4.configure(foreground="black")
       self.Button4.configure(highlightbackground="#d9d9d9")
       self.Button4.configure(highlightcolor="black")
       self.Button4.configure(pady="0")
       self.Button4.configure(text='''x10''')
       self.Button4.bind('<Button-1>',px10Click)

       self.Button5 = Button (master)
       self.Button5.place(relx=0.19,rely=0.79,height=34,width=47)
       self.Button5.configure(activebackground="#f9f9f9")
       self.Button5.configure(activeforeground="black")
       self.Button5.configure(background="#d9d9d9")
       self.Button5.configure(disabledforeground="#a3a3a3")
       self.Button5.configure(foreground="black")
       self.Button5.configure(highlightbackground="#d9d9d9")
       self.Button5.configure(highlightcolor="black")
       self.Button5.configure(pady="0")
       self.Button5.configure(text='''1 Pas''')
       self.Button5.bind('<Button-1>',m1Click)

       self.Button6 = Button (master)
       self.Button6.place(relx=0.68,rely=0.79,height=34,width=47)
       self.Button6.configure(activebackground="#f9f9f9")
       self.Button6.configure(activeforeground="black")
       self.Button6.configure(background="#d9d9d9")
       self.Button6.configure(disabledforeground="#a3a3a3")
       self.Button6.configure(foreground="black")
       self.Button6.configure(highlightbackground="#d9d9d9")
       self.Button6.configure(highlightcolor="black")
       self.Button6.configure(pady="0")
       self.Button6.configure(text='''1 Pas''')
       self.Button6.bind('<Button-1>',p1Click)

       self.Button7 = Button (master)
       self.Button7.place(relx=0.24,rely=0.45,height=34,width=67)
       self.Button7.configure(activebackground="#f9f9f9")
       self.Button7.configure(activeforeground="black")
       self.Button7.configure(background="#d9d9d9")
       self.Button7.configure(disabledforeground="#a3a3a3")
       self.Button7.configure(foreground="black")
       self.Button7.configure(highlightbackground="#d9d9d9")
       self.Button7.configure(highlightcolor="black")
       self.Button7.configure(pady="0")
       self.Button7.configure(text='''MAJ Pos.''')
       self.Button7.bind('<Button-1>',majClick)

       self.Entry2 = Entry (master)
       self.Entry2.place(relx=0.46,rely=0.49,relheight=0.07,relwidth=0.17)
       self.Entry2.configure(background="white")
       self.Entry2.configure(disabledforeground="#a3a3a3")
       self.Entry2.configure(foreground="black")
       self.Entry2.configure(highlightbackground="#d9d9d9")
       self.Entry2.configure(highlightcolor="black")
       self.Entry2.configure(insertbackground="black")
       self.Entry2.configure(selectbackground="#c4c4c4")
       self.Entry2.configure(selectforeground="black")

       self.Button8 = Button (master)
       self.Button8.place(relx=0.68,rely=0.45,height=34,width=47)
       self.Button8.configure(activebackground="#f9f9f9")
       self.Button8.configure(activeforeground="black")
       self.Button8.configure(background="#d9d9d9")
       self.Button8.configure(disabledforeground="#a3a3a3")
       self.Button8.configure(foreground="black")
       self.Button8.configure(highlightbackground="#d9d9d9")
       self.Button8.configure(highlightcolor="black")
       self.Button8.configure(pady="0")
       self.Button8.configure(text='''Go To''')
       self.Button8.bind('<Button-1>',gotoClick)

       self.Entry3 = Entry (master)
       self.Entry3.place(relx=0.41,rely=0.68,relheight=0.07,relwidth=0.17)
       self.Entry3.configure(background="white")
       self.Entry3.configure(disabledforeground="#a3a3a3")
       self.Entry3.configure(foreground="black")
       self.Entry3.configure(highlightbackground="#d9d9d9")
       self.Entry3.configure(highlightcolor="black")
       self.Entry3.configure(insertbackground="black")
       self.Entry3.configure(selectbackground="#c4c4c4")
       self.Entry3.configure(selectforeground="black")

       self.Button9 = Button (master)
       self.Button9.place(relx=0.08,rely=0.04,height=34,width=78)
       self.Button9.configure(activebackground="#f9f9f9")
       self.Button9.configure(activeforeground="black")
       self.Button9.configure(background="#d9d9d9")
       self.Button9.configure(disabledforeground="#a3a3a3")
       self.Button9.configure(foreground="black")
       self.Button9.configure(highlightbackground="#d9d9d9")
       self.Button9.configure(highlightcolor="black")
       self.Button9.configure(pady="0")
       self.Button9.configure(text='''Connexion''')
       self.Button9.bind('<Button-1>',connexionClick)

       self.Button10 = Button (master)
       self.Button10.place(relx=0.08,rely=0.19,height=34,width=80)
       self.Button10.configure(activebackground="#f9f9f9")
       self.Button10.configure(activeforeground="black")
       self.Button10.configure(background="#d9d9d9")
       self.Button10.configure(disabledforeground="#a3a3a3")
       self.Button10.configure(foreground="black")
       self.Button10.configure(highlightbackground="#d9d9d9")
       self.Button10.configure(highlightcolor="black")
       self.Button10.configure(pady="0")
       self.Button10.configure(text='''Deconnexion''')
       self.Button10.bind('<Button-1>',deconnexionClick)

       self.Button12 = Button (master)
       self.Button12.place(relx=0.79,rely=0.08,height=44,width=55)
       self.Button12.configure(activebackground="#f9f9f9")
       self.Button12.configure(activeforeground="black")
       self.Button12.configure(background="#d9d9d9")
       self.Button12.configure(disabledforeground="#a3a3a3")
       self.Button12.configure(foreground="black")
       self.Button12.configure(highlightbackground="#d9d9d9")
       self.Button12.configure(highlightcolor="black")
       self.Button12.configure(pady="0")
       self.Button12.configure(text='''Aide''')
       self.Button12.bind('<Button-1>',aideClick)







if __name__ == '__main__':
   vp_start_gui()

Posté
merci bien :)

 

J'avais trouvé ça

à priori c'est un tuto pour rendre compatible des softs perso sous ASCOM

 

Mais de rien

Faut tout recoder avec le framework, je m'y mets dès que je ne suis plus malade

Posté

ya pas à dire je suis une quiche, même avec tout sous le nez je n'arrive pas à compiler sous python ca me dit que "import serial" est introuvable.

 

J'ai enlevé le import serial et j'ai eu des messages d'erreur mais la fenetre est apparue :) beau boulo

Posté (modifié)

Il faut installer pyserial, la librairie qui permet de communiquer avec les ports séries. https://pypi.python.org/pypi/pyserial

 

Tu devras aussi changer:

ser.port= 4

Le chiffre correspond au numéro du port série de l'arduino (visible dans le gestionnaire des périphérique de windows) moins 1.

Le port com1 = ser.port = 0

Modifié par DrThrax
Posté

Attention, le code est donné pour la V1 du motorshield... Mon code source arduino devra être modifier pour correspondre aux shields que vous utilisez

 

S'ils font que tic tic, c'est que les fils sont pas branchés dans le bon ordre ^^

Posté

c'est un 4 fils bipolaire j'ai tester avec le ohmmètre.

 

J'ai out1 out2 out3 out4 sur ma carte ça correspondrait pour OUT1+ OUT2- OUT3- OUT4+

si je ne me trompe point

Posté

Faut tester les combinaisons ^^ mais attention, si tu n'envois le signal que pour un pas, c'est normal que ça fasse tic, il faut aussi être certains du nombre de pas de ton moteur

Posté

Mhhhhhhh (le doute m'envahit)

 

J'ai testé avec le mode exemple/stepper/et rotation du moteur. Il me semble que mon moteur est un 48 pas j'arrive pas à savoir si c'est ça sur le net. C'est un 42pm48l d'une monture eq5.

Posté

j'ai trouvé mon problème en fait ce sont les pin de sortie moteur qui ne sont pas les mêmes j'ai trouvé ca :

#define MOTORSHIELD_IN1 8//8

#define MOTORSHIELD_IN2 11//11

#define MOTORSHIELD_IN3 12//12

#define MOTORSHIELD_IN4 13//13

#define CTRLPIN_A 9//9

#define CTRLPIN_B 10//10

 

keskecaveudire mdr

Rejoignez la conversation !

Vous pouvez répondre maintenant et vous inscrire plus tard. Si vous avez un compte, connectez-vous pour poster avec votre compte.

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

  • En ligne récemment   0 membre est en ligne

    • Aucun utilisateur enregistré regarde cette page.
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.