Problème pour faire tourner 2 moteurs nema17 avec NRF24L01+

Bonjour lilian2230

Wi-Fi "standard" ou via NRF24L01 ?
Qu'auras-tu comme Arduino aux 2 bouts ?

Cordialement
jpbbricole

ce sera 2 Arduino nano communiquant via les NRF24L01

(ce ne sont pas des modules de communication wifi ? je croie que WIFI est un protocole de communication non ?)
les modules au cas ou : NRF24L01

Avec ±200 c'est déjà dur de faire tournée qu'un moteur , j'ai qu'un tout petit joystick pour le moment. (joystick de manette , style ps4 ou Xbox) Je le remplacerait plus tard par un plus gros , si j'en trouve un .

Entre 200 et 1000 pas par second j'en compte envieront 4-5 , votre programme ne "génère" en revanche pas de "paliers" , ça dois donc être un problème lié au t1 et t2.

virez les :slight_smile:

le NRF24L01 ne fait pas du Wi-Fi, c'est un autre protocole radio, sur la même fréquence que le Wi-Fi (2.4GHz) et autres fours à µ-ondes

Les paliers peuvent venir des println(vitesse) . Si on a un chiffre à écrire cela prend du temps et ralentit un peu le moteur. Quand on passe de la vitesse 9 à 10, il y a un chiffre de plus et cela va ralentir un peu plus...

En fait je pensais pourquoi utiliser un pas à pas, il semblerait que l'on ai besoin d'une vitesse qui soit fonction du joystick. Dans ce cas un moteur CC conviendrait peut être. Mais sans savoir à quoi cela sert, on ne peut pas justifier l'utilisation du pas à pas... Cela ce justifierait si on devait compter les pas éventuellement.

J’y crois pas trop, c’est géré en asynchrone par interruptions. C’est le fait de ne pas appeler assez souvent run ou runSpeed qui doit faire cela. Comme il le dit mon code plus haut n’a pas le pb et affiche les changements de vitesse.

J'ai retiré les println(vitesse) , il y a toujours des pallier mais les moteurs tourne de manière plus "propre" , (il ne vibre plus de manière aléatoire)

hello
veux tu faire un test, j'ai respecté tes attributions de pins arduino, tu peux donc téléverser et tester sans modifier ton cablage

//               UNO   µ328p
#define toggle_pulse_Z digitalWrite (PULS_Z, !digitalRead(PULS_Z))
#define toggle_pulse_B digitalWrite (PULS_B, !digitalRead(PULS_B))

#define potar_Z    A0  // joystick axe Z 
#define PULS_Z      5 //6  // 12 pour les PULS axe Z 
#define DIR_Z       6//7  // 13 pour le sens axe Z
#define EN_Z        7//8  // 14 pour la validation du driver Z

#define potar_B    A1  // joystick axe B 
#define PULS_B      3//5  // pour les PULS axe B 
#define DIR_B       2//4  // pour le sens axe B
#define EN_B        4//3  // pour la validation du driver B

#define ALLER     HIGH
#define RETOUR    LOW
#define VALIDE    LOW
#define DEVALIDE  HIGH

int   potZ              =         0; //variable joystique Vertical
int   vitesse_Z         =       100; // nb périodes mere entre deux pulses
int   compteur_Z        =         0;
int   larg_puls_Z       =         2; // pulse en nb périodes Fréquence mère
int   compt_Z           = vitesse_Z;
long  compt_distance_Z  =         0;
byte  isr_Z             =     false; //
long  compteur_pulses_Z =         0;

int   potB              =         0; //variable joystique Horizontal
int   vitesse_B         =       200; // nb périodes mere entre deux pulses
int   compteur_B        =         0;
int   larg_puls_B       =         2; // pulse en nb périodes Fréquence mère
int   compt_B           = vitesse_B;
long  compt_distance_B  =         0;
byte  isr_B             =     false; //
long  compteur_pulses_B =         0;

void setup()
{
  Serial.begin(115200);
  Serial.println(__FILE__);//pinMode(11,  OUTPUT);pinMode(3,  OUTPUT);
  pinMode(potar_Z, INPUT);
  pinMode(EN_Z,  OUTPUT); digitalWrite(EN_Z, HIGH);   // validation du driver Z
  pinMode(DIR_Z, OUTPUT); digitalWrite(DIR_Z, LOW);   // sens axe Z
  pinMode(PULS_Z, OUTPUT); digitalWrite(PULS_Z, LOW); // puls axe Z
  pinMode(potar_B, INPUT);
  pinMode(PULS_B, OUTPUT); digitalWrite(PULS_B, LOW); // puls axe B
  pinMode(DIR_B, OUTPUT); digitalWrite(DIR_B, LOW);   // sens axe B
  pinMode(EN_B, OUTPUT); digitalWrite(EN_B, HIGH);     // validation du driver B
  cli();              // interdit les interruptions pendant l'initialisation du timer2
  TCCR2A = 0b00000000;
  TCCR2B = 0b00000011;
  TIMSK2 = 0b00000010;
  sei();
}
void loop()
{
  potB = map(analogRead(potar_B), 0, 1023, -500, 500);//changement des valeurs min/max pour plus de faciliter

  if (potB < -100)
  {
    vitesse_B = map(potB, -100, -500, 100, 0);//Serial.print(potB);Serial.print(" B ");Serial.println(vitesse_B);
    digitalWrite(DIR_B, ALLER);
    digitalWrite(EN_B , VALIDE);
    isr_B = true;
  }
  else
  {
    if (potB > 100)
    {
      vitesse_B = map(potB, 0, 500, 100, 0);//Serial.print(potB);Serial.print(" B ");Serial.println(vitesse_B);
      digitalWrite(DIR_B, RETOUR);
      digitalWrite(EN_B , VALIDE);
      isr_B = true;
    }
    else
    {
      digitalWrite(EN_B , DEVALIDE);
      isr_B = false;
    }
  }

  //=======================================================

  potZ = map(analogRead(potar_Z), 0, 1023, -500, 500);

  if (potZ < -100)
  {
    vitesse_Z = map(potZ, 0, -500, 100, 0);//Serial.print(potZ);Serial.print(" Z ");Serial.println(vitesse_Z);
    digitalWrite(DIR_Z, ALLER);
    digitalWrite(EN_Z , VALIDE);
    isr_Z = true;
  }
  else
  {
    if (potZ > 100)
    {
      vitesse_Z = map(potZ, 0, 500, 100, 0);//Serial.print(potZ);Serial.print(" Z ");Serial.println(vitesse_Z);
      digitalWrite(DIR_Z, RETOUR);
      digitalWrite(EN_Z , VALIDE);
      isr_Z = true;
    }
    else
    {
      digitalWrite(EN_Z , DEVALIDE);
      isr_Z = false;
    }
  }
}

ISR (TIMER2_COMPA_vect)
{
  if (isr_Z )                          //si déplacement du moteur Z autorisé
  {
    if (compteur_Z++ >= compt_Z )      //compt_Z vaut larg_puls_Z pour la duree de la partie "utile"du PULSE_Z
    { //compt_Z vaut vitesse_Z pour la durée de la partie negative du PULSE_Z
      toggle_pulse_Z; compteur_Z = 0;  //à chaque bascule de la valeur de compt_Z, la macro "toggle_pulse_Z" est appelée
      if (compt_Z == larg_puls_Z)      //cette macro inverse l'état de la sortie affectée au PULS_Z
      {
        compt_Z = vitesse_Z;
      }
      else
      {
        compt_Z = larg_puls_Z;
        compt_distance_Z++;            //si centième débordement on incrémente le "compt_distance_Z"
      }
    }
  }
  if (isr_B )                          //si déplacement du moteur Z autorisé
  {
    if (compteur_B++ >= compt_B )     //compt_B vaut larg_puls_B pour la duree de la partie "utile"du PULSE_B
    { //compt_B vaut vitesse_B pour la durée de la partie negative du PULSE_B
      toggle_pulse_B; compteur_B = 0;
      if (compt_B == larg_puls_B)
      {
        compt_B = vitesse_B;
      }
      else
      {
        compt_B = larg_puls_B;
      }
    }
  }
  TCNT2 = 150;
}

c'est fait , ça marche nickel :grinning: , les moteurs vibrent un peu mais c'est largement acceptable , je crois avoir compris que ça utilise les timers interne de l'Arduino , astucieux , au moins plus de problème de décalage. il faut maintenant adapter cela pour une utilisation par radio (NRF24L01) , je vais adapter le code et reviendrais vers vous quand ce sera fais , je n'arrive pas à les utiliser , la variable (#NRF24) est complexe et les résultats sont aléatoires.(merci pour ton retour qui a réglé le problème efficacement)

Un moteur qui vibre d'est un moteur qui est en pas entier. Avec des A4988, passer en micro-pas permet de diminuer énormément les vibrations et les bruits. J'ai un 17HS4401 qui vibre tellement en pas entiers qu'à 30tr/mn et à 50 pas/mn il perd des pas à vide. Alors qu'en 16 micros-pas je peux le faire tourner sans problèmes. J'ai abandonné le mode pas entier.

Ok je prend ça en note merci (pour passer en micro pas il suffit de connectée la/les broche ns1 ns2 ou ns3 ?)

voir ICI, descendre en milieu de page pour voir le tableau des ms12,3 et les micros pas correspondants

j'ai créé un code d'essai sans la partie moteurs pour testé la communication entre Arduino :
émetteur :

#include <SPI.h>
#include "printf.h"
#include "RF24.h"

int potBB;
int potZZ;
int expedition[] = {0, 0};//variable d'envoi

uint8_t address[][6] = {"pipe1", "pipe2"};
RF24 radio(9, 10); // utilisation des pin 7 pour le pin CE , et 8 pour le pin CSN

void setup() {
  Serial.begin(115200);
  if (!radio.begin()) {
    Serial.println("la radio ne repond pas");
    while (1) {}//boucle infini(arret du programme)
  }
  else{
    Serial.println("la radio est connecter");
    // la radio est connectée
  }
  radio.setChannel(110);
  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_250KBPS);  
  radio.openWritingPipe(address[1]);
  radio.openReadingPipe(1, address[0]);

}

void loop() {
  potBB = map(analogRead(A1), 0, 1023, -500, 500);
  potZZ = map(analogRead(A0), 0, 1023, -500, 500);

  expedition[0] = potBB;//paramétrage de la variable
  expedition[1] = potZZ;
  
  radio.write(&expedition, sizeof(expedition));//envoi de la variable
  delay(2);
}

récepteur :

#include <SPI.h>
#include "printf.h"
#include "RF24.h"

uint8_t address[][6] = {"pipe1", "pipe2"};
RF24 radio(9, 10); // utilisation des pin 7 pour le pin CE , et 8 pour le pin CSN

int potB;
int potZ;
uint8_t expedition[] = {0, 0};
void setup() {
  Serial.begin(115200);
  if (!radio.begin()) {
    Serial.println("la radio ne repond pas");
    while (1) {}//boucle infini(arret du programme)
  }
  else{
    Serial.println("la radio est connecter");
    // la radio est connectée
  }
  radio.setChannel(110);
  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_250KBPS);  
  radio.openWritingPipe(address[0]);
  radio.openReadingPipe(1, address[1]);
  radio.startListening();
}

void loop() {
  if (radio.available()){
    radio.read(&expedition, sizeof(expedition));
  }

  potB = expedition[0];//récéption des variables
  potZ = expedition[1];

  Serial.print(potB);
  Serial.print("-");
  Serial.println(potZ);
}

comme je m'en douté ça ne marche pas bien , je reçois bien les données mais de manière bizarre
, les nombres reçus ne correspond à rien .je pense que le problème est liée au type de variable que j'envois mais je ne trouve pas d'exemple d'envois de données simple. Il y a peux être une erreur basique ? Ce n'est pas un problème d'alimentation des NRF car sinon je ne recevrez rien.

J’ai du code posté dans les tutos pour envoyer une structure. Essayez avec ça

(Et vous mettrez les 2 valeurs pour les potentiomètres dans la structure)

Avec 2 int en émission et 2 x uint8_t en réception ? ? ?
Il vaudrait mieux utiliser la même structure.