Utiliser 2 PORT simultanément

Bonjour tout le monde.
Je vien vers vous pour vous demander de l’ aide . Car je debute dans le monde d’ Arduino. J’utilise actuellement un arduino uno et 3 stepper 28byj + uln2003 fourni avec .
Tout fonctionne très bien . Mais j’aimerai faire quelques ajustement vis à vis du câblage. Actuellement j’ai les trois stepper connectés sur A0,1,2,3 + D4,5,6,7 + D8,9,10,11. Donc j’ai encore 6 pins de dispo. Mais c’est 2 sur le PORTC, 2 PORTB, 2 PORTD . J’utilise le type de code pour le contrôle décrit ci-dessous … Je voudrais ajouter un 4ème stepper mais je dois le connecter sur 2 PORT en même temps. Par exemple j’aurai aimer de le connecter sur les pins A4,5 et les pins D2,3.
Est ce que c’est possible de faire un tel branchement ? Et comment je dois écrire mon code dans ce cas ?
Je vous remercie d’avance pour votre aide .
Vitaliy

    out_bits |= (1<<X_STEP_BIT);
     st.counter_x -= st.event_count;
     if (out_bits & (1<<X_DIRECTION_BIT)) { sys.position[X_AXIS]--; 
     costyx=costyx-1;
     if (costyx < 1) costyx=8;
     if (costyx==1)   PORTD=0B10000000;
     if (costyx==2)   PORTD=0B11000000;
     if (costyx==3)   PORTD=0B01000000;
     if (costyx==4)   PORTD=0B01100000;
     if (costyx==5)  PORTD=0B00100000;
     if (costyx==6)  PORTD=0B00110000;
     if (costyx==7)  PORTD=0B00010000;
     if (costyx==8) PORTD=0B10010000;
     }
     else { sys.position[X_AXIS]++; 
     costyx=costyx+1;
     if (costyx > 8 ) costyx=1;
     if (costyx==1)   PORTD=0B10000000;
     if (costyx==2)   PORTD=0B11000000;
     if (costyx==3)   PORTD=0B01000000;
     if (costyx==4)   PORTD=0B01100000;
     if (costyx==5)  PORTD=0B00100000;
     if (costyx==6)  PORTD=0B00110000;
     if (costyx==7)  PORTD=0B00010000;
     if (costyx==8) PORTD=0B10010000;
     }
   }

[/code]

Merci de corrigez votre post ci dessus et rajoutez les code tags autour du code:
[code]`` [color=blue]// votre code ici[/color] ``[/code].

ça doit ressembler à cela:// votre code ici
(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l'IDE avant de copier le code pour qu'il soit indenté correctement)

———
comme ils ne sont pas sur le même port vous devrez effectuer 2 affectations différentes en tenant compte du fait que vous ne voulez pas modifier des bits utilisés par les autres ports. à 16Mhz deux affectations séparées (copier 1 octet en mémoire même avec un masque ou un petit calcul) seront vues par vos moteurs comme "simultanées".

Soit vous calculez un instant t à quoi doivent ressembler les pins et c'est ce que vous affectez à un PORT, soit vous utilisez &= ainsi que |= pour faire des affectations "ciblées" de 0 ou 1 avec un masque, soit si vous connaissez l'état précédent vous pouvez utiliser le registre PINx pour inverser la valeur d'une pin donnée (par exemple PIND = 0b10000000; va inverser l'état de la pin 7 sans toucher les autres)

Merci pour votre réponse rapide. J'ai effectuer le changement vis à vis du code . Je pense que c'est correct là ?
Veuillez excuser mon ignorance, mais je ne comprend presque rien de ce que vous avez écrit a propos de mask et tout le reste.. je m'efforce de comprendre certaines choses et d'apprendre d autres, car le codage c'est quelque chose de nouveau pour moi..
Ce que j'ai compris , corrigez moi si je me trompe .
En gros je dois affecter le même stepper sur les deux PORT en même temps sauf que quand il arrive sur les bits correspondant aux pins qui ne doivent pas être utilisée je dois utiliser le fameux mask pour que les pins ne s'activent pas réellement ?

Comprenez vous ce que fait PORTD=0B11000000;

Oui, il active la pin D7 et D6 enfin active, façon de parler. Il la passe en état haut (5v) et les autres bits 0 (0v) , ça c'est chose acquise. .. hihi enfin je crois si je me trompe pas ? !
J'ai lu un tuto qui parle de Mask.. là j'ai bien compris le fonctionnement, enfin je pense , le mask il cache les donnes écrites de base pour transformer en donne que l'on souhaite . . .
Si j'ai bien compris dans mon cas mon code dois ressembler à quelque chose comme ça ?

PORTD=0B00011000&0B00001100

Cela me permet d'utiliser la pin D2 et D3 et pas les autres car elles sont masquées? Est ce que je suis dans la bonne lancée ?
Et pour activer le 5eme bit sur le PORTC je dois écrire ceci avec le même stepper

PORTC=0B011000&0B110000

Ce qui me permettra de passer le 5eme bit sur la pin A4 et de préserver les pins A0,1,2,3
Est ce que vous pouvez me dire si j'ai compris comme il faut ou je me trompe quelque part ?

Alors oui pour

PORTD=0b11000000;

si les broches sont en sorties, ça met à HIGH les pins 6 et 7 et à LOW les pin 0 à 5 mais le souci c’est que ce n’est pas top de jouer avec les pins du port série 0 et 1. (la notation 0b en C ou C++ introduit un nombre écrit en binaire. Arduino à introduit la notation 0B avec un B majuscule, ça ne sert à rien de l’utiliser et ne fonctionne pas avec des nombre de 32 bits par exemple, autant utiliser le standard)

Si on ne veut jouer qu’avec une partie des pins il ne faut pas changer la valeur des autres. Pour cela il faut se souvenir des tables de vérité et particulièrement des 4 cas suivant (ou x représente vrai ou faux)

  • VRAI OU x = VRAI
  • FAUX OU x = x
  • VRAI ET x = x
  • FAUX ET x = FAUX

traduit en binaire avec 1 (HIGH) pour vrai et 0 (LOW) pour faux et les opérateurs de bits (| pour OU et & pour ET)

  • 0 | x = x → inchangé
  • 1 | x = 1 → on force à HIGH
  • 0 & x = 0 → on force à LOW
  • 1 & x = x → inchangé

par exemple pour mettre la pin 6 à HIGH et la pin 7 à LOW sans toucher les autres, on pourra faire:

byte etatCourant = PORTD; // on lit la  valeur en cours
etatCourant = etatCourant | 0b01000000; // bit 6 à 1, les autres inchangés 
etatCourant = etatCourant & 0b01111111; // bit 7 à 0, les autres inchangés 
PORTD = etatCourant; // on stocke le résulat

dans ce code, ce qu’on appelle un masque ce sont les valeurs [color=blue]0b01000000[/color] ou [color=blue]0b01111111[/color] qu’on applique sur une variable (on dit qu’on “masque la variable” quand on applique le masque car on va jouer que sur certains bits, les autres étant “masqués”)

En procédant avec une variable intermédiaire (etatCourant) on n’écrit qu’une seule fois d’un coup dans le registre de PORT mais si ce n’est pas grave de faire les opérations en séquence on peut utiliser la notation |= et &= qui font la lecture du registre et l’application du masque

PORTD |= 0b01000000; // bit 6 à 1, les autres inchangés 
PORTD &= 0b01111111; // bit 7 à 0, les autres inchangés

Mettre à 0 revient donc à faire un ET avec un 0 au bon endroit et mettre à 1 revient à faire un OU avec un 1 au bon endroit.

Il y a dans le langage un certains nombre d’opérateurs qui vous simplifient cette écriture: les opérateurs bitwise ainsi que des macros utilitaires comme bitClear() et bitSet() qui sont définies dans Arduino.h

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))

mais dont on se passe allègrement quand on a compris le principe (ce qui permet aussi de maitriser la taille des opérateurs, les macros travaillant sur 32 bits)

Sur AVR il y a une subtilité avec le registre PINx. écrire un 1 à un bit particulier revient à dire “inverser” l’état de la sortie associée à ce bit alors qu’un 0 laissera l’état (HIGH ou LOW) inchangé. Si vous savez part exemple que le bit 7 doit être inversé dans le PORT D il suffit de fairePIND = 0b10000000; // inverser bit 7l’avantage c’est que ça se fait super rapidement une fois traduit en assembleur. Quand (comme dans votre cas) on a une séquence connue d’état des pins qui se répète, on sait celles qui étaient à 0 ou 1 avant et que l’on veut conserver ou inverser. Le registre PINx devient alors super pratique pour laisser inchangé ce que l’on ne veut pas toucher et inverser les autres.

Pour revenir à votre cas, si les pins à manipuler sont sur 2 ports il vous faut donc mettre à 1 et 0 certaines pins de certains port et donc faire plusieurs opérations du type ci dessus sur plusieurs ports

Merci pour l'explication. L'effet du mask ça je crois que j'ai compris . En tout cas j'ai fait un essai et ça as marcher . J'ai réussi à masquer 2 pins sur 4 .. maintenant je bloque sur comment affecter 2 PORT pour le même stepper . J ai essayer de plusieurs manières différentes , deux d'entres elles , j'ai réussi à compiler et télécharger sur l arduino mais mon stepper ne fonctionne pas a mon avis conflit ou alors il ne sait pas ou donner de la tete car 2 pins a tous les coups sont à 0.5v ,1 pin à 1.4v et la dernière à 0.3v quoi que je fasse ça ne change pas et ça reste ainsi .. et les autres essais , BEH erreur de compilation , impossible a télécharger.
Si c'est pas trop vous demander est ce que vous pourriez m'expliquer comment on fait pour affecter 2 PORT au même stepper ?
Je vous remercie d'avance pour votre aide , grâce à vous j'ai déjà avancer d'un point ..
Bonne soirée

vitaliberty:
maintenant je bloque sur comment affecter 2 PORT pour le même stepper .

il suffit de mettre plusieurs instructions dans votre if, je ne vois pas la difficulté

un truc du genre (j'écris n'importe quoi)

if (costyx==1) {
   PORTD |=0B10000000; // bit 7 à 1, reste inchangé sur le port D
   PORTB |=0B01000000; // bit 6 à 1, reste inchangé sur le port B
}

ou dans le switch/case

switch (costyx) {
  ...

  case 1:
    PORTD |=0B10000000; // bit 7 à 1, reste inchangé sur le port D
    PORTB |=0B01000000; // bit 6 à 1, reste inchangé sur le port B
  break;

  ...
}

comme dit précédemment, les pins de commande ne sont plus mis instantanément et simultanément à la bonne valeur mais séquentiellement puisque vous avez plusieurs instructions mais c'est tellement rapide par rapport à l'inertie de votre moteur et driver que ça sera imperceptible. (par prudence commencez éventuellement par mettre les pins à LOW avant de mettre les HIGH de manière à ne pas avoir des ordres contradictoires)

Ok merci. J'avais fait if et ensuite toutes les commandes du PORT D ensuite une fois les commandes finies du PORTD j'avais remis un autre if avec les commandes du PORTC.. il suffit de mettre les commandes dans le même if. . Je ne pensait pas qu'on pouvais faire cela .. Je pense que j'ai compris où était mon erreur . Je vais essayer cela tout à l'heure et vous dit quoi.
Merci beaucoup pour les explication . Comme je l'avais dit avant. Je suis un bleu dans le domaine . J'apprend tout seul avec Google.. jamais au part avant j'avais eu affaire avec quelconque codage.. tout cela pour moi est nouveau. Et très passionnant ! En tout cas merci pour votre aide et votre patience d'expliquer ..

N'oublez pas d'utiliser des {} pour grouper vos commandes dans le if

if (condition) {
  instruction1;
  instruction2;
  instruction3;
  instruction4;
}

si vous écrivez sans les accolades

if (condition) 
  instruction1;
  instruction2;
  instruction3;
  instruction4;

seule instruction1 est liée au if, les autres seront toujours exécutées. En indentant le code (ctrl-T) ça se voir mieux

if (condition) 
  instruction1;
instruction2;
instruction3;
instruction4;

bonjour ,
Merci pour le coup de main. J'ai réussi a brancher et faire fonctionner mon stepper sur les deux PORT C et D .
Je m'etais aperçu que sans les accolades ca ne fonctionnait pas correctement. Ensuite après quelques differents essai j'ai compris comment fonctionne le code avec le mask et comment assigner deux PORT en même temps. voici ce que j'ai pondu :

      if (costyz==1) { PORTC  =  0B100100 & 0B100000;
                               PORTD  =  0B00100100 & 0B00000100;  }
      if (costyz==2) { PORTC  =  0B110000 ;
                               PORTD  =  0B00000000;  }
      if (costyz==3) { PORTC  =  0B011000 & 0B010000;
                               PORTD  =  0B00011000 & 0B00001000;  }
      if (costyz==4) { PORTD  =  0B00001100 ;
                               PORTC  =  0B000000;  }
      if (costyz==5) { PORTC  =  0B100100 & 0B100000;
                               PORTD  =  0B00100100 & 0B00000100;  }
      if (costyz==6) { PORTC  =  0B110000 ;
                               PORTD  =  0B00000000;  }
      if (costyz==7) { PORTC  =  0B011000 & 0B010000;
                               PORTD  =  0B00011000 & 0B00001000;  }
      if (costyz==8) { PORTD  =  0B00001100 ;
                               PORTC  =  0B000000;  }

et après mures réflexions , en activant un peux de logique je me suis dit pourquoi je me prend la tête a faire un mask alors que je connais la séquence exacte de mon stepper et je sait a quel moment quel pin doit être active et la quelle désactive. Je n'ai qu'a mettre directement non pas la séquence complete mais une partie de la séquence concernant le PORT en question et en combinant le deux PORT ca fait une séquence complete , eureka!!!! hihi tout a coup, tout est si simple et logique que le code que j'ai refait coulait de source, tout seul... voici ce que j'ai réécrit ;

      if (costyz==1) { PORTC  =  0B100000;
                               PORTD  =  0B00000100;  }
      if (costyz==2) { PORTC  =  0B110000;
                               PORTD  =  0B00000000;  }
      if (costyz==3) { PORTC  =  0B010000;
                               PORTD  =  0B00001000;  }
      if (costyz==4) { PORTD  =  0B00001100;
                               PORTC  =  0B000000;  }
      if (costyz==5) { PORTC  =  0B100000;
                               PORTD  =  0B00000100;  }
      if (costyz==6) { PORTC  =  0B110000;
                               PORTD  =  0B00000000;  }
      if (costyz==7) { PORTC  =  0B010000;
                               PORTD  =  0B00001000;  }
      if (costyz==8) { PORTD  =  0B00001100 ;
                               PORTC  =  0B000000;  }

et il fonctionne a merveille , il y a juste un truc qui me chiffonne .
J'ai du coup 3stepper qui sont connecter sur les PORT C et D .
Les deux stepper qui ont leur PORT séparer après fonctionnement gardent leurs "dernière position " (les bobines restent sous tention ) mais une fois que j'utilise le 3eme stepper qui est a cheval sur les deux memes PORT , les deux stepper perdent leurs "derniers position" il ne sont plus alimenter quoi. et inversement le stepper qui est a cheval perd l'alimentation du PORT sur le quel un des deux stepper est actif ou les deux en même temps .. je ne sait pas si je m'exprime assez clairement , j'espère que oui ..
et si j'active le stepper qui est a cheval sur les deux PORT et un des deux autres stepper en même temps , il y a un beug, ils avancent tout les deux coup par coup , c'est pas sensé arriver car si j'utilise les deux stepper de deux PORT differents en même temps , le fonctionnement est fluide sans acros ...
je ne vais jamais utiliser le Stepper a cheval en même temps que les autres mais je trouve que ca ne devrais pas arriver et que c'est pas normal .. et ca le fait avec le mask ou sans ..
je me demande si ca n'arrive pas a cause du fait que j'ai mit des 0 sur les autres pin du coup les deux codes de mouvements pour les deux stepper differents sur le même PORT se chevauchent et des 0 se mélangeant avec des 1..
exemple stepper a cheval;

if (costyz==1) { PORTC  =  0B100000;
                         PORTD  =  0B00000100;  }

le stepper sur un seul port

if (costyx==1)   PORTD  =  0B10010000 ;

la si on prend les deux PORT D il doit y avoir un souci de lecture ... sur une ligne je désigne certains bit a 0 et sur l'autre c'est l'opposer 1... je pense que c'est du a cela que ca avance coup par coup ... dans mon codage je ne peux pas travailler juste sur une pin précise sans affecter les autres a un certain moment ? l'écriture ex.; 0x70 sert a cela ou c'est juste pour éviter d'écrire tous les 0B10000000 ? Ou alors c'est le fameux PINx ? mais la aussi je dois écrire 0B10000000 du coup je touche aux autres pins aussi ? et quand il y a lecture de deux stepper en même temps il y a le même souci ?

Ce truc là me dit qu’il faut que vous travaillez encore un peu cette histoire PORTC  =  0B100100 & 0B100000;ca ne faisait sans doute pas ce que vous vouliez. C’était comme faire PORTC  =  0b00100000;car le ET binaire entre 0B100100 et 0B100000 va conserver uniquement les bits qui sont à 1 des 2 cotés. C’était peut être un OU que vous vouliez faire ?

Sinon Quand vous affectez d’un coup tout un port du genre PORTC  =  0B100000 vous mettez des 0 partout et juste un 1. Toutes les pins donc qui ne pilotent pas votre moteur (mais peut être un autre) sont impactées

Relisez un peu mes explications sur |= et &=

Bonjour,
Voilà j'ai fait plusieurs test avec le & et | . A chaque fois le même résultat. Une fois que j utilise le stepper qui est à cheval sur les deux PORT il désactive les deux autres stepper sur ses PORT et inversement. Sauf une combinaison | 0b101111 par ex. Il active toutes les pins .. logique . Enfin est ce qu'il y a peut être un autre type de code ou je peux contrôler une seule pin précise a la fois sans passer par les bits des autres pins?
Du style ( j'invente )

if (costyx==3)   PORTD= 3 & 4 (High); // active Digital Pin 2 et 3

Faut pas inventer en informatique... il y a un langage très précisif (costyx==3)  PORTD= 3 & 4 (High); // active Digital Pin 2 et 33 en binaire c'est 0b011 et 4 c'est 0b100 donc en faisant 3 & 4 ça donne (0b011 & 0b100) donc ça fait 0b000 ==> 0, nada, rien du tout :slight_smile:
et le High entre parenthèse c'est quoi ??

bref - mettez vite cela au rebus...

———————

j'ai mentionné |= et &=... Notez bien qu'il y a un symbole = après le ET ou le OU binaire.

si vous faites PORTD [color=red]|=[/color] 0b10000000;c'est un raccourci pour écrire PORTD = PORTD | 0b10000000; donc on ne touche QUE le bit 7 en le forçant à 1, les autres sont inchangés.

idem si vous si vous faites PORTD [color=red]&=[/color] 0b01111111;c'est un raccourci pour écrire PORTD = PORTD & 0b01111111; donc on ne touche QUE le bit 7 en le forçant à 0, les autres sont inchangés.

==> comme mentionné plusieurs fois auparavant, c'est TRES important de ne toucher QUE les pins impliquées dans l'action courante, sinon vous risquez de changer la configuration d'autres pins.

OK?

Ah ok c'est peut être pour cela que ça ne fait pas ce que je veux car je ne mettais pas de = et en plus, moi je met ceci

     // exemple 
     // axe Z
      ...
    {  PORTD = 0B00000100 | 0B00000000
       PORTC = 0B100000 | 0B000000 }
      ... 
     // axe X
       PORTD = 0B10010000 | 0B00000000

de cette manière je pensait que les bits après le signe | représentait le vrais ou faux ... si 1 je passe 1 si 0 je reste 0 en pensant que par exemple l'axe X et Z sont dans cette position(exemple ci dessus) et au final le PORTD ça ressemblerait a cela 0b10010100.. et que si je bouge d'un pas le X, cela deviendra ceci 0b11000100 .. car le 3bit (pin2) fait partie de l'axe Z et reste inchangé. .
Ce que je comprend pas c'est que vous vous mettez le signe | avant le = 0b10000000 juste après le PORTD... mais moi c'est ma séquence d'activation de bobines . Ce que je met apres le PORTD = c'est un ordre d allumage qui ne dois pas etre changer .. il va tres biens . Comment le | ou le & peuvent savoir ce que je veux changer dans mon ordre d ' allumage de bobines de mon stepper ? La je suis déconnecter et je ne comprend pas le fonctionnement du tout alors ...

// Quel est la différence entre cette ligne là  ; 
PORTD = 0B10010000
// et celle ci?
PORTD |= 0B10010000

Pour moi il n y a aucune différence dans les deux cas là pin 4 et 7 sont actives et les autres non .. à quoi cela me sert alors de faire ceci? Je suis persuadée il me manque une partie de quelque chose pour comprendre tout ceci ou alors je m'exprime mal pour vous faire comprendre mon problème. .

Ou alors je ne dois pas le mettre dans la séquence et je dois refaire un truc à part rien que pour le mask ? Car moi j’essaye d’intégrer cela directement dans ma séquence. . Et si je dois refaire le mask hors de ma séquence. Dans ce cas là je comprend pourquoi votre signe se trouve avant le = et non pas entre dans la ligne de la séquence. . En fait je crois que je suis complètement embrouiller et plus j’essaye de comprendre plus je m’embrouille …

Ok on dirait que vous n’avez pas compris comment fonctionnent les ports ni l’affectation des bit ni un masque...

Reprenons à la base: expliquez moi en français, sans code, quels sont les enchaînements à effectuer pour chacun des moteurs

Par exemple:

pour le moteur 1, je commence avec les pins x et y a HIGH et w et z à LOW, puis t ms plus tard je passe x à LOW et z à HIGH puis....

Ok je veux bien que vous m’expliquez les choses du début, peut être réellement, j’ai manquer quelque chose . . .
1er question. Ça veux dire quoi “t ms” ?
En ce qui concerne les moteurs et les pins …
Admettons que l’ordre des pins est w, x, y, z .
X,Y a HIGH , W,Z a LOW,
W,X a LOW, Y,Z a HIGH
X,Y a LOW, Z,W a HIGH
Y,Z a LOW, W,X a HIGH
Et puis le cycle redememare ceci en full step
Et en half step ça resemblerais a cela
X,Y a HIGH, Z,W a LOW
Y a HIGH, Z,W,X a LOW
Y,Z a HIGH, W,X a LOW
Z a HIGH, W,X,Y a LOW
Z,W a HIGH, X,Y a LOW
W a HIGH, X,Y,Z a LOW
W,X a HIGH, Y,Z a LOW
X a HIGH, Y,Z,W a LOW
C’est bien juste ?

OK donc on affecte 2 pins à HIGH et 2 pins à LOW de manière circulaire dans le registre qui définit l'état des pins pour activer les bobines dans un certain ordre.

imaginons que votre premier moteur soit sur D7,D6,D5,D4 (W,X,Y,Z)
Imaginons que votre second moteur soit sur D3,D2,A1,A0 (A,B,C,D)

le PORTD contrôle les pins de D0 à D7 et le PORTC contrôle les pins analogiques A0 à A5, donc le premier moteur est entièrement sur le PORTC alors que le second moteur est à cheval sur deux ports PORTC et PORTD

Tant que vous pilotez seulement le premier moteur vous pouvez faire des affectations directes dans PORTD: (en supposant que vous n'utilisiez pas le port série)

Tant que vous pilotez seulement le second moteur vous pouvez faire des affectations directes dans PORTD et le PORTC

Le souci cependant d'affecter la valeur directement dans le port, c'est que vous écrasez tout ce qu'il y avait avant dans le registre.

et donc en jouant sur le second moteur en écrivant dans PORTD pour toucher D3 et D2 vous écrasez D7-D4 et en mettant ces pins à 0 vous arrêtez le premier moteur....

Dit autrement, si vous voulez mettre un HIGH sur D6 et D4 (X,Z) et LOW sur D7 et D5 (W,Y) par exemple SANS MODIFIER le reste du PORTD (notamment ce que vous avez sur D3 et D2 qui correspond à l'ordre en cours sur le second moteur) vous ne POUVEZ PAS écrire directement dans le registre la valeur PORTD = 0b[color=red]0101[/color][color=blue]0000[/color];car autant les 4 bits rouges vont bien affecter les HIGH et LOW comme il faut sur W,X,Y,Z mais les 4 bits bleus vont eux aussi être affectés et donc vous écrasez ce qu'il y a en D3 et D2 (A,B) et donc envoyez une modification d'ordre à l'autre moteur...

La solution consiste à ne pas ECRASER le contenu existant du registre mais de ne MODIFIER QUE les pins qui nous intéressent. C'est là que la notion de masque et d'opérations logiques binaire rentre en ligne de compte.

  • il faut commencer par lire le contenu du registre pour connaître la valeur des pins que l'on ne veut pas touche, puis
  • quand on veut mettre un 1 quelque part, j'ai expliqué précédemment que l'on fait un masque avec OU
  • quand on veut mettre un 0 quelque part, j'ai expliqué précédemment que l'on fait un masque avec ET
  • puis on remet ce que l'on a calculé dans le registre du PORT, les bits originaux sont préservés

pour reprendre l'exemple ci dessus (HIGH sur D6 et D4 (X,Z) et LOW sur D7 et D5 (W,Y)) on doit faire

byte valeurEnCoursDuPort  = PORTD; // on lit ce qu'il y a dans le port
valeurEnCoursDuPort = valeurEnCoursDuPort & 0b01011111; //  LOW sur D7 et D5 (W,Y). RESTE INCHANGÉ
valeurEnCoursDuPort = valeurEnCoursDuPort | 0b01010000; //  HIGH sur D6 et D4 (X,Z). RESTE INCHANGÉ
PORTD = valeurEnCoursDuPort;

(en commençant par LOW pour éviter d'envoyer des commandes potentiellement conflictuelles)

Les masques 0b0[color=red]1[/color]0[color=red]1[/color]0000 et 0b[color=red]0[/color]1[color=red]0[/color]11111 ont des 1 et des 0 "savamment" placés pour ne MODIFIER QUE les pins concernées, avec l'opération & ou | adéquate.

Pour modifier 2 PORT on procède de la même façon sauf qu'on le fait deux fois de suite une fois pour le PORTC et une fois pour le PORTD

La notation |= et & =simplifie l'écriture de ce que j'ai mis ci dessus, elle fait en même temps la lecture du contenu puis l'opération binaire. On peut donc se passer de la variable intermédiaire si le fait de ne pas modifier les pins d'un coup n'est pas un souci et faire

PORTD &= 0b01011111; //  LOW sur D7 et D5 (W,Y). RESTE INCHANGÉ
PORTD |= 0b01010000; //  HIGH sur D6 et D4 (X,Z). RESTE INCHANGÉ

j'espère que c'est plus parlant avec un petit dessin...

PS/

Ça veux dire quoi "t ms" ?

t c'était pour un certain temps et ms ce sont des millisecondes

  1. Au vu de la grosse difficulté de faire le code pour faire tourner le quatrième moteur, je ne comprends pas bien pourquoi ne pas utiliser digitalWrite au lieu de PORD=… Si c’est une question de vitesse digitalWriteFast est équivalent avec PORD=…

PORTD |=0B10000000; // bit 7 à 1, reste inchangé sur le port D

Cela s’écrit avec une Ardino, sachant que Le bit 7 du portD est la broche N°7: digitalWriteFast(7,1);

  1. Au vu
  • de la grosse difficulté de faire le code pour faire tourner le quatrième moteur.
  • le nombre de pin utilisées pour 4 moteurs (16 au total!)
  • de la simplicité d’utiliser les commandes Step et Dir des drivers genre A4988
    ne serait-il pas malin d’utiliser des drivers type A4988 pour commander les moteurs. Je sais qu’il y a des ULN2003 “gratuits”, mais changer de driver permet de
  • simplifier énormément le code
  • libérer la moitié des broches