Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---

[Realisation] 4L1C3, soft de pilotage CNC en asm

Forum général sur l'Assembleur !

Modérateur : mazertoc

Avatar de l’utilisateur
Temps-x
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

Soft de commande CNC en asm

Messagepar Temps-x » jeu. 31 janv. 2019 19:17

Bonsoir paulfjujo, et tout le forum,

paulfjujo a écrit :Source du message Si le PIC commande les moteurs en envoyant des pulses à chacun, je ne vois pas comment cela puisse être simultané
à moins que le PIC maitre, sous traite l'envoi des corrections pulses à 2 petits PIC esclaves qui se chargeront chacun d'envoyer les pulses X et Y


Dans mon ancien programme, j'activais X, Y en même temps.

j'avais au total 10 fonctions

moteur Z aller
moteur Z retour

moteur X aller
moteur X retour

moteur Y aller
moteur Y retour

moteur X et Y diagonal à gauche en haut
moteur X et Y diagonal à droit en haut
moteur X et Y diagonal à gauche en bas
moteur X et Y diagonal à droit en bas

Comme pour un Pixel sur un écran, 2 moteurs pas à pas X, Y ne peut avoir plus de 8 directions à partir de son point d’origine
Pxel.jpg

Pour faire cette manœuvre avec deux moteurs unipolaires(en diagonal à 45° pris comme exemple).

il faut utiliser le même PORT sur le pic pour les axes X, Y (4 sorties par moteur unipolaire pour mon cas)

Faire 10 fonctions comme décrit plus haut, qui avance d'un pas pour chaque donnée

C'est l'ordinateur qui donne l'ordre des directions, chaque direction correspond à un pas moteur pour chaque choix.
On n'est pas obligé de prendre un ordinateur, une lecture de carte SD peut suffire.

Par exemple si on choisi la direction de : diagonal à gauche en haut

moteur X recul de 1 pas, et moteur Y recul d'un pas, mais tout se fait en même temps

En code ASM non optimisé, ça peut donner ça

Code : Tout sélectionner

;****************** actionner  moteur 1 et 2 en diagonal à gauche en haut  *******************
action_7
      bcf INTCON
,GIE                      ; couper toutes les interruptions
      
      call reactiver_A                    
; réactiver le PORTA  pour maintien des moteurs             

      movwf temps                         
; sauvegarde du PORTA dans temps pour utilisation
      movwf tmps                          
; sauvegarde du PORTA dans tmps pour utilisation
 
                                          
; bits qui sont utilisés pour moteur 1 sens gauche
                                          
;         | | | |
                                          ;         | | | |     
                                          
;         V V V V    
                                          
; 7 6 5 4 3 2 1 0  <---- emplacements des bits

      bcf temps
,7                         ; mettre le bit 7 à zéro
      bcf temps
,6                         ; mettre le bit 6 à zéro
      bcf temps
,5                         ; mettre le bit 5 à zéro
      bcf temps
,4                         ; mettre le bit 4 à zéro

      call recheche_gau                   
; sens de rotation à gauche   
                   
      btfsc tmps
,7          
      bsf temps
,
      btfsc tmps
,6
      bsf temps
,6
      btfsc tmps
,5
      bsf temps
,5
      btfsc tmps
,4
      bsf temps
,4    
    

      movf temps
,W                        ; transfère temps dans W 
      movwf tmps                          
; copie temps dans tmps pour utilisation
 
      swapf temps
,1                       ; mets les bits du poids faible dans les bits du poids fort 

                                          
; bits qui sont utilisés pour le moteur 2 sens gauche
                                          
; | | | |
                                          ; | | | |     
                                          
; V V V V    
                                          
; 7 6 5 4 3 2 1 0  <---- emplacements des bits

      bcf temps
,7                         ; mettre le bit 7 à zéro
      bcf temps
,6                         ; mettre le bit 6 à zéro
      bcf temps
,5                         ; mettre le bit 5 à zéro
      bcf temps
,4                         ; mettre le bit 4 à zéro
          
      call recheche_gau                   
; sens de rotation à gauche
                 
      swapf temps
,1                       ; mets les bits du poids faible dans les bits du poids fort 

      btfsc tmps
,3          
      bsf temps
,
      btfsc tmps
,2
      bsf temps
,2
      btfsc tmps
,1
      bsf temps
,1
      btfsc tmps
,0
      bsf temps
,0

      movf temps
,W
      movwf PORTA                         
; mets en fonctionnement les 2 moteurs d'un pas
      movwf toucherA                      ; sauvegarde pour coupure des ports si non utilisé 
     
      bsf INTCON,GIE                      ; on réactive les interruptions
      return



Les deux sont fait en même temps, avantage on peut régler la vitesse du déplacement des moteurs via l'ordinateur.

Il est vrai quand théorie cela reste impossible à réaliser de synchroniser 2 moteurs à la même vitesse, les deux méthodes
se discute, celle de F6FCO ou celle là.
==> ==> ==> ==> ==> ==> ==> ==> ==> ==> ==> ==> ==> ==> A suivre ......

==> A+
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Avatar de l’utilisateur
F6FCO
Expert
Expert
Messages : 1413
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

Soft de commande CNC en asm

Messagepar F6FCO » sam. 2 févr. 2019 14:40

Bonjour tous,
J'ai fais plus simple en employant la tangente(), je ne sais plus si j'en ai déjà parlé plus haut.
Les deux moteurs fonctionnent tour à tour en dessinant un escalier mais c'est si fin que çà se traduit par une ligne droite.
Comme le dit Paul il faut d'abord calculer les deltaX et deltaY, facile puisqu'on a les coordonnées XY de départ (la position actuelle) et les positions XY à atteindre (données par l'ordre gcode).
Donc commencer par faire deltaX=Xnew-Xold, ou Xold-Xnew suivant le sens de translation du chariot, il suffit d'inverser le sens du moteur. Pareil pour Y.
Une fois qu'on a çà il suffit de faire tan()=deltaY/deltaX. Mais on se retrouve avec un nombre à virgule, normal pour une tangente, il suffit de le multiplier par 800 (le nb pas pour un tour de moteur) pour avoir un nombre assez grand pour ne plus se soucier de ce qu'il y a derrière la virgule. Pour compenser on divise le nombre de pas à effectuer par 800 (1,25µ).
Ensuite comme on connait le deltaX qui nous donne le nombre de pas X à parcourir il suffit de les incrémenter et de recalculer Y(X) à chaque pas en faisant Y=X.tan().
Y'a plus qu'a dessiner l'escalier.

Au départ je voulais utiliser l'équation de droite Y=ax+b mais j'obtenais un b négatif pour certaines pentes. Et puis comme finalement le b n'est pas utilisable car la position à l'ordonnée et qu'on s'en fout parce qu'on y est déjà et que b est égal à 0 du coup. Ca nous donne y=ax. Et on revient à ce que j'ai fait parce que le calcul de la pente a c'est deltaY/deltaX, donc la tangente.

En asm c'est rapide car il n'y a qu'une division à faire en début de calcul de la pente, ensuite ce n'est plus qu'une multiplication à chaque pas de X.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Avatar de l’utilisateur
F6FCO
Expert
Expert
Messages : 1413
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

Soft de commande CNC en asm

Messagepar F6FCO » dim. 3 févr. 2019 16:56

Après relecture c'est pas très clair, je reformule.

J'ai fais plus simple en employant la tangente(), je ne sais plus si j'en ai déjà parlé plus haut.
Les deux moteurs fonctionnent tour à tour en dessinant un escalier mais c'est si fin que çà se traduit par une ligne droite.

Au départ je voulais utiliser l'équation de droite Y=ax+b. On commence par calculer la pente a en faisant deltaY/deltaX, puis il ne restait qu'à calculer b=y-(ax) et finalement Y=ax+b. Mais j'obtenais un b négatif pour certaines pentes donc çà n'allait pas. Et puis comme finalement le b n'est pas utilisable car la position à l'ordonnée et qu'on s'en fout parce qu'on y est déjà et que b est égal à 0 du coup. Ca nous donne y=ax. Et on revient à ce que j'ai fait parce que le calcul de la pente a c'est deltaY/deltaX, donc la tangente.

Donc deuxième façon:
Calculer tan()=deltaY/deltaX, puis ensuite il ne reste qu'à incrémenter X et calculer Y(X) pour chaque pas de X.
Comme le dit Paul il faut d'abord calculer les deltaX et deltaY, facile puisqu'on a les coordonnées XY de départ (la position actuelle) et les positions XY à atteindre (données par l'ordre gcode).
Donc commencer par calculer deltaX=Xnew-Xold, ou Xold-Xnew suivant le sens de translation du chariot, il suffit d'inverser le sens du moteur. On se retrouve toujours à soustraire le plus petit au plus grand et c'est tant mieux.
Pareil pour deltaY.

Une fois qu'on a çà il suffit de faire tan()=deltaY/deltaX, juste une division 16bits. Mais on se retrouve avec un nombre à virgule, normal pour une tangente. Pas glop. Pour remédier à çà il suffit de le multiplier par 800 (le nb pas pour un tour de moteur) pour obtenir un nombre assez grand pour ne plus se soucier de ce qu'il y a derrière la virgule et ne garder que la partie entière. Pour compenser on divise le nombre de pas à effectuer par 800 (1,25µ) et on retombe sur nos pattes.
Ensuite comme on connait le deltaX qui est le nombre de pas X à parcourir il suffit de les incrémenter et de recalculer Y(X) à chaque pas en faisant Y=X.tan(), multiplication 16bits.
Y'a plus qu'a dessiner l'escalier.

En asm c'est rapide car il n'y a qu'une division à faire en début de calcul de la pente, ensuite ce n'est plus qu'une multiplication à chaque pas de X.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Avatar de l’utilisateur
F6FCO
Expert
Expert
Messages : 1413
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

Soft de commande CNC en asm

Messagepar F6FCO » mer. 6 févr. 2019 23:07

Bonsoir tous,
Je suis bloqué par un petit souci, je suis sur que vous aurez la réponse :-)
Dans le calcul de mes deltaX et deltaY je dois comparer deux valeurs 24 bits et déterminer quelle est la plus forte, pour cela je fais une soustraction octet par octet (je ne vois pas d'autre méthode pour l'instant) et je branche si le résultat est négatif par un bn.
Par exemple, je dois comparer les nouvelles coordonnées X (0x01E240) et les anciennes (0x012122).
Je commence par comparer les octets de poids fort 0x01-0x01, pas négatif je ne branche pas et je passe à l'octet suivant.
Je fais 0xE2-0x21, résultat positif je ne devrais pas brancher et passer à la comparaison de l'octet faible. Et c'est là que j'ai un souci, j'obtiens bien la valeur 0xE2-0x21=0xC1 mais le bit N de STATUS est levé comme si c'est négatif :mur:

J'ai codé la soustraction en dur pour vérifier:
STATUS avant soustraction: 00000011 (bit N à zéro)

Code : Tout sélectionner


    movlw    0xE2
    movwf    tampon
    movlw    0x21
    subwf    tampon
,w

0xC1 dans w
STATUS après soustraction: 00010011(bit N à 1)


Du coup je suis bien embêté pour comparer mes valeurs.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Avatar de l’utilisateur
paulfjujo
Expert
Expert
Messages : 2589
Enregistré en : juillet 2015
Localisation : 01800
Contact :

Soft de commande CNC en asm

Messagepar paulfjujo » jeu. 7 févr. 2019 11:30

bonjour,

F6FCO a écrit :....0xE2-0x21=0xC1 mais le bit N de STATUS est levé comme si c'est négatif :mur:



le bit N du status , indique simplement que le MSB de l'octet est à 1
il faut tenir compte aussi du Carry
la notion de positif ou negatif est assez arbitraire
suivant qu'on considere l'octet signé ou pas
si signé .. le bit MSB à 1 => Negatif

soit la variable signe pour stocker le signe du resultat

Code : Tout sélectionner

  
      BCF Signe
,0
       movlw 0xE2
       movwf Tampon
       movlw 0x21
        subwf Tampon
,W
       btfsc   STATUS
,C      
       BRA  positif
 
; donc ici, negatif
       xorlw 0xFF   
; complement à 2 ! 
      ADDLW 1
     movwf Tampon
     BSF Signe
,0
positif
:
        movwf Tampon
        nop



0xE2-0x21=0xC1
226-33=193
mais signe=0 Positif

0x21 - 0xE2 => 0xC1
33-226 => -193
0xC1=193 mais signe=1 Negatif

pour la soustraction d'un nombre sur 24 bits 3 bytes : HSB MSB LSB
seul le bit de l'octet poids fort HSB , indique le signe du resultat
Aide toi, le ciel ou FantasPic t'aidera

Avatar de l’utilisateur
F6FCO
Expert
Expert
Messages : 1413
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

Soft de commande CNC en asm

Messagepar F6FCO » jeu. 7 févr. 2019 12:22

Bonjour Paul, et merci de ta réponse.
si signé .. le bit MSB à 1 => Negatif

Je travaille en entiers.

paulfjujo a écrit :pour la soustraction d'un nombre sur 24 bits 3 bytes : HSB MSB LSB
seul le bit de l'octet poids fort HSB , indique le signe du resultat

Oui mais comme subwf travaille sur un octet c'est le bit 7 qui est pris en compte, d’où mon souci.
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Avatar de l’utilisateur
paulfjujo
Expert
Expert
Messages : 2589
Enregistré en : juillet 2015
Localisation : 01800
Contact :

Soft de commande CNC en asm

Messagepar paulfjujo » jeu. 7 févr. 2019 15:32

un fichier interessant, que j'ai vu passé je ne sais plus où ,
et que j'avais mis de coté ..
vu peut être ici, sur Fantaspic ?

j'ai deja eu l'occasion de travailler en asm sur des add , sub mul 16 bits , mais pas encore 24 bits
neamoins , dans l'exemple ci joint, se trouve des subroutines , dont sub24 ! appropriée à ton cas ?..
On y voit d'ailleurs que c'est bien le flag Carry qui sert et non pas le flag N du STATUS.

il faut au prealable un travail de preparation pour les arguments
à passer à la subroutine !
du rangement , quoi .

:!!: nota: il risque d'y avoir des probleme d'alignement avec PIC18F .. adressage pair
d'ou l'eventuel avantage de travailler en 32 bits plutot que 24..
.. à verifier

Code : Tout sélectionner


sub24   
          MOVF    INDF
,W        ; tmp2..tmp0 -= FSR[2..0]
          SUBWF   tmp0,F
          INCF    FSR
,F
          MOVF    INDF
,W
          BTFSS   STATUS
,C
          INCFSZ  INDF
,W
          SUBWF   tmp1
,F
          INCF    FSR
,F
          MOVF    INDF
,W
          BTFSS   STATUS
,C
          INCFSZ  INDF
,W
          SUBWF   tmp2
,F
          DECF    FSR
,F
          DECF    FSR
,F
          RETLW   0             
; carry cleared at underflow
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Avatar de l’utilisateur
F6FCO
Expert
Expert
Messages : 1413
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

Soft de commande CNC en asm

Messagepar F6FCO » jeu. 7 févr. 2019 18:46

Merci pour cette routine. Mise de coté dans ma collection, elle servira certainement.
J'ai résolu mon problème grâce à tes dires de ce matin, j'ai laissé tomber le bit N et j'ai fais les tests de comparaison seulement avec C et Z et c'est bon çà roule.
Un truc foireux ce bit N, je l'oublie.

A-B
Z=1 les deux arguments égaux
Z=0 C=1 résultat positif
Z=0 C=0 résultat négatif

J'ai eu de la chance que la machine tourne correctement jusqu'à maintenant en testant le bit N, il y aurait forcément eu un gcode ou çà aurait planté, et va debugger un truc pareil.
Tu m'as tiré une fière chandelle du pied 8-)
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Avatar de l’utilisateur
F6FCO
Expert
Expert
Messages : 1413
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

Soft de commande CNC en asm

Messagepar F6FCO » ven. 8 févr. 2019 00:09

L'aventure continue, Je suis en train d'optimiser le code et le modifier pour rendre la machine précise au 1/100e.
J'ai commencé par modifier le gcode en lui rajoutant deux chiffres derrière la virgule, il est multiplié par 100 dés la sortie de l'uart pour rester en entier. Comme je l'ai expliqué un peu plus haut je calcule la tangente en divisant les deux deltas, ce qui me donne un nombre à virgule, toujours pour rester en entiers je commence par multiplier deltaY par 800, ce qui me donne un nombre sur 48bits suivant les valeurs calculées.
Il faut ensuite diviser ce deltaY 48bits par deltaX 24bits.
Donc le challenge continue, maintenant il faut soit que je trouve une division 48bits/24bits, soit que je la code moi-même.

Edit: trouvé deux, trop tard pour les tester ce soir:
http://www.piclist.com/techref/microchi ... by24ng.htm
http://www.piclist.com/techref/microchi ... by24al.htm
Une porte nand prend 2 bits en entrée... la cochonne !!! :langue:

Avatar de l’utilisateur
paulfjujo
Expert
Expert
Messages : 2589
Enregistré en : juillet 2015
Localisation : 01800
Contact :

Soft de commande CNC en asm

Messagepar paulfjujo » ven. 8 févr. 2019 10:42

bonjour F6FC0 et à tous,

A ce train là, on peut se poser la question
pourquoi pas utiliser de flottant ..32 bits.
si ton pic peut contenir le code de la lib MATH32 et a assez de RAM
mais si tu n'as que ce calcul de tangente , en effet ...ce serait surdimensioné.

manipuler des mots de 48 bits ..ou 24 bits n'est pas aussi evident que pour du 16 ou 32 bits

nota:
le coefficient multiplicateur de 800 pourrait etre ramené à 512 ou 1024 pour eviter
les problemes d'arrondi sur les calculs en entier des 2 valeurs DX et DY
avec un simple decalage pour multiplier par 512 : x1= X1 <<9 et y1=y1 <<9 Y ,X2= X2 <<9 et Y2= y2 <<9

d'ou l'idée d'utiliser un petit alogrithme t permettant de rester cadré sur 24 bits pour les calculs
si on cadre automatiquement les valeurs DX et DY au maxima possible sur 24 bits, via des decalage à gauche successifs.
avant cette division DX/DY
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 45 invités