Communication bidirectionnelle entre 2 nRF24L01+

Bonjour à toutes et à tous,

Je vous souhaite une bonne et heureuse année 2018.

Je viens tout juste de m' inscrire sur ce forum, afin de demander de l' aide pour un projet de planche de Surf électrique.

Autant être honnête et vous le dire tout de suite, je suis totalement nouveau dans le milieu de la programmation en C++.

j'ai déjà commencé à trouver des tutos pour faire des exercices et comprendre, mais je galère un peu au niveau de la syntaxe et du schéma structurel à adopter.

Le projet :

une board avec un moteur costaud est un esc 120 Ampères, la batterie sera composée d' éléments en Lithium-Ion (18650 LG ) avec un BMS elle sera en 14S 10P.

Afin de commander la board, je souhaite utiliser une liaison nRF24l01+ qui me permettrait d' envoyer les données de commande pour l'ESC, mais me permettrait aussi de récupérer les informations du niveau de batterie de la board ( j'ai vu qu' il était possible de faire un voltmètre en se servant d'un pont diviseur).

La tension a mesurer sur la batterie serait de 51.8 Volts en nominal et a 58.8 Volts max.

du côté de la télécommande, afin d avoir une bonne étanchéité, je vais partir sur un capteur hall honeywell ss495.

Première problématique: je me suis servi d' un sketch pour voir les bornes mini maxi du capteur Hall.

un terminal pour le TX où j'ai les valeur du capteur Hall allant de 512 à 517 sans aimant a proximité; à 1001 pour le max.

J'ai constaté sur l'autre terminal, des sauts a 242 parfois (valeur angulaire), ainsi qu'une réduction progressive de la vitesse de rotation du moteur jusqu'à l' arrêt, si je m'approche trop près du capteur Hall; si je recule légèrement, le moteur reprend les tours à fond !!

Ci -dessous, le code que j'utilise pour le TX

/* Transmitter Code
*  Code to read Joystick position and transmit it with a RF24L01+ to a receiver 
*/

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

// Radio Configuration

RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool radioNumber=1;
bool role = 1;  //Control transmit 1/receive 0

// Decide where you are going to plug the joystick into the circuit board.

int ForeAft_Pin = 3;        // Plug Joystick Fore/Aft into Analog pin 3
int LeftRight_Pin = 1;      // Plug Joystick Left/Right into Analog pin 1

// Create variables to read joystick values

float ForeAft_Input ;       // Variable to store data for Fore/Aft input from joystick
float LeftRight_Input ;     // Variable to store data for for Left/Right input from joystick

// Create variables to transmit servo value

int ForeAft_Output;       // Expected range 0 - 180 degrees
int LeftRight_Output;     // Expected range 0 - 180 degrees

// These variables allow for math conversions and later error checking as the program evolves.

int Fore_Limit = 800;       // High ADC Range of Joystick ForeAft (800)
int Aft_Limit = 220;        // Low ADC Range of Joystick ForeAft (220)
int Right_Limit = 800;      // High ADC Range of Joystick LeftRight
int Left_Limit = 226;       // Low ADC Range of Joystick LeftRight

void setup() {
    Serial.begin(9600);                   // Get ready to send data back for debugging purposes
    radio.begin();                        // Get the transmitter ready
    radio.setPALevel(RF24_PA_LOW);        // Set the power to low
    radio.openWritingPipe(addresses[1]);  // Where we send data out
    radio.openReadingPipe(1,addresses[0]);// Where we receive data back

}
void loop() {
    ForeAft_Input = analogRead(ForeAft_Pin) ;             // Read the Fore/Aft joystick value
    LeftRight_Input = analogRead(LeftRight_Pin) ;         // Read the Left/Right joystick value
    ForeAft_Output = convertForeAftToServo(ForeAft_Input) ;        // Convert the Fore/Aft joystick value to a Servo value (0-180)
    LeftRight_Output = convertLeftRightToServo(LeftRight_Input) ;  // Convert the Left/Right joystick value to a Servo value (0-180)

    //  Serial.print(ForeAft_Output);
    radio.stopListening();                                 // Stop listening and begin transmitting
    delay(20);                                            // quite a long delay -- causes jittering of servo
    if(radio.write(&ForeAft_Output, sizeof(ForeAft_Output)),Serial.println(ForeAft_Input));              //Send ForeAft data
    //if(radio.write(&LeftRight_Output, sizeof(LeftRight_Output)),Serial.println("sent LeftRight"));        //Send LeftRight data
    radio.startListening();                                // Get ready to receive confirmation from receiver
}

// Function to convert and scale the Fore/Aft data

float convertForeAftToServo(float y) {
    int result;
    result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180);
    return result;
}

// Function to convert and scale the Left / Right data
// Can be replaced with Map function
float convertLeftRightToServo(float x) {
    int result;
    result = ((x - Left_Limit) / (Right_Limit - Left_Limit) * 180);
    return result;
}

je n'arrive pas à déchiffrer comment fonctionne la formule de conversion des données du capteur, en valeur angulaires compréhensibles par l' ESC.

j' aurais souhaité avoir une bonne lecture du capteur hall, afin de ne pas avoir des réaction dangereuses du moteur de la board.

je pensais essayer la fonction map en essayant d'incorporer un " if ForeAft_Output >=180

result=180 " ; mais je ne sais pas comment m' y prendre .

/* Map hall sensor to Servo (0 to 180) */
void setup() {}

void loop()
{
  int val = ForeAft_Input();
  val = map(val, 512, 1001, 0, 180);
  ForeAft_Output();
}

Afin de visualiser les informations du niveau d' accélération, du niveau de batterie de la télécommande et surtout le niveau de batterie de la board, je souhaite les afficher sur ecran Oled SD1306, sous forme de bargraph. J'ai commencé a essayer des sketch avec la librairie u8g2, mais je ne sais pas si c'est la plus facile d' approche, je ne trouve pas de tuto. J' arrive a afficher un logo avec draw xbitmap mais je n'arrive pas a afficher sans passer par U8g2 first page

u8g2.firstPage();
  do {
    /* all graphics commands have to appear within the loop body. */    
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0,20,"Hello World!");
  } while ( u8g2.nextPage() );

Vu que je suis débutant, je vais y aller par étape et déjà fiabiliser la lecture du capteur Hall, avant d'aller plus loin.

Que pensez vous que cette écriture veuille dire ?

if(radio.write(&ForeAft_Output, sizeof(ForeAft_Output)),Serial.println(ForeAft_Input));              //Send ForeAft data

avant de jouer avec la radio, faites juste fonctionner vos capteurs et essayez de les maitriser. Commencez avec un code tout simple de lecture qui imprime ce que lit le capteur et progressez depuis cela.

(la barre espace est-elle cassée sur votre ordi ?)

Bonjour J-M-L,

merci de votre réponse, avant de commencer à construire un code, j'ai dejà utilisé des sketchs, afin de comprendre un petit peu comment cela fonctionnait. Afin de ne pas trop galérer au début, je n'ai pas commencé avec un ESC, mais avec un petit servo.

Pour l' input, j'avais soudé des fils sur le potard d' un vieux gimbal Turnigy 9x, avant d'essayer le capteur Hall.

le morceau de code que vous avez sélectionné dit : si il y a ecriture radio de ForeAft_Output, imprime sur le terminal la valeur analogique du capteur hall.
j'ai volontairement choisit d' avoir cette information, car côté RX j'ai choisit d'avoir la valeur agulaire, afin de comprendre le fonctionnement.

je ne comprends pas pourquoi vous me demandez si ma barre d'espace est cassée sur mon ordi ? :blush:

je peux mettre plus d'espace dans l' écriture du code, c'est ça ?

J'ai un peu avancé sur ce que je souhaite faire, mais je suis coincé sur le code du TX, même avec le if AFT_Output>=800

dès que je fais mes essais je vois sur le terminal que je peux dépasser le seuil des 800 en valeur Hall côté TX; côté RX sur le terminal je vois plus de 180 °.

sur le plan du fonctionnement, j'arrive a commander l'esc et le moteur, par contre si avec l'aiment je dépasse le seuil de la valeur 800, je commence a passer au dela des 180° , ce qui setraduit par une baisse graduelle du régime moteur, si je recule doucement l'aimant pour le ramener vers 800 , le moteur reprend des tours brusquement.

Ci dessous le code du TX:

/* Code TX
*  Code pour lire la position du capteur hall et la transmettre au TX 
*/

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

// Radio Configuration

RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool radioNumber=1;
bool role = 1;  // Definition du role : TX 1 / RX 0

// Broches de connection sur arduino nano
int ForeAft_Pin = 3;        // Capteur Hall sur broche analogique A3
int LeftRight_Pin = 1;      // mesure de tension de la batterie telecommandesur broche analogique 1

// Variables pour lire les valeur du capteur hall et la mesure de la tension de la batterie de la télécommande
float ForeAft_Input ;       // valeurs lues par le capteur hall a l' approche d' un aimant (min512 ; max 1001)
float LeftRight_Input ;     // valeurs de la tension de la batterie

// variables pour transmettre les valeurs angulaires à l'ESC 
int ForeAft_Output;       // (min 0° - max 180°)

// variables pour la conversion capteur hall - ESC
int Fore_Limit = 800;       // Valeur Max du capteur Hall
int Aft_Limit = 220;        // Valeur Max du capteur Hall

// creation de variables pour le monitoring batterie board
const float minVoltageBoard = 3.2;
const float maxVoltageBoard = 4.2;

void setup() {
    Serial.begin(9600);                   // initialisation port serie
    radio.begin();                        // demarrage radio
    radio.setPALevel(RF24_PA_LOW);        // transmission radio puissance basse
    radio.openWritingPipe(addresses[1]);  // adresse emission
    radio.openReadingPipe(1,addresses[0]);// adresse reception
       if (ForeAft_Input>800) 
    {(ForeAft_Input=800);}
}
void loop() {
    ForeAft_Input = analogRead(ForeAft_Pin) ;             // lecture valeur capteur hall
 
   
    ForeAft_Output = convertForeAftToServo(ForeAft_Input) ;        // formule pour match capteur hall - ESC

    radio.stopListening();                                 // arret réception et depart emission
    delay(20);                                            // delai (plus de delai pour debug mais besoin de moins pour eviter jitter)
    if(radio.write(&ForeAft_Output, sizeof(ForeAft_Output)),Serial.println(ForeAft_Input));              //envoi de la donnée angulaire (0-180)au RX et info serial de la valeur hall 
   
    radio.startListening();          // preparation pour reception confirmation bonne reception du RX
}

// fonction pour convertir et mettre a l' echelle les donnees du capteur Hall
// il est possible d'utiliser la fonction Map

float convertForeAftToServo(float y) {
    int result;
    result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180);
    if (result>=800)
    {
      (result=800);
    }
    else
    {
    return result;
    }   
}
    //int BoardbattLevel() {  // Fonction utilisée pour indiquer sur OLED le niveau de batterie de la planche en % a afficher sur TX
  //float voltageBoard = BoardBattVoltage();

  //if (voltageBoard <= minVoltageBoard) {
   // return 0;
 // } else if (voltageBoard >= maxVoltageBoard) {
  //  return 100;
 // } else {
   // return (voltageBoard - minVoltageBoard) * 100 / (maxVoltageBoard - minVoltageBoard);
 // }
//}
//}

ci dessous le code du RX :

/*  code recepteur AFT
*   Code pour recevoir les infos du TX et les transmettre a l 'ESC*/

#include <Servo.h>
#include <SPI.h>
#include <RF24.h>

//Radio Configuration

bool radioNumber=0;
RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool role = 0;  // Definition du role : TX 1 / RX 0


// Variable pour le servo ESC

Servo ForeAft;

unsigned int ForeAft_Output;       // valeur  0 - 180 degrees

float BoardBattVoltage = 0.0; // variable flottante pour la lecture de la tension batterie
float temp=0.0;

void setup() { 
    Serial.begin(9600);        // initialisation port serie
    ForeAft.attach(5);         // definition broche servo (ESC) sur la broche digitale 5 (PWM
    radio.begin();             // demarrage radio
    radio.setPALevel(RF24_PA_LOW);    // transmission radio puissance basse
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
    radio.startListening();


// l' esc demarre réellement a 10 ° 
  
for(ForeAft_Output = 10; ForeAft_Output <= 180; ForeAft_Output += 1) //va de 0 degrees a 180 degrees par pas de  1 degree
  {                                  
    ForeAft.write(ForeAft_Output);              // dis à l'ESC d' aller a la postion definit par la variable ForeAft_Output 
    delay(15);                       // delais de  15ms pour que le servo atteigne la postion ( pour protéger la boite de vitesse ) 
  } 
  for(ForeAft_Output = 180; ForeAft_Output>=10; ForeAft_Output-=1)     // va de 180 degrees a 0 degrees par pas de  1 degree
  {                                
    ForeAft.write(ForeAft_Output);              //  dis à l'ESC d' aller a la postion definit par la variable ForeAft_Output  
    delay(15);                       // delais de  15ms pour que le servo atteigne la postion ( pour protéger la boite de vitesse )
  }  

    
}
void loop() {

   // Formule de conversion pour le voltage
   int analogBoard_value = analogRead(A4);  // definition de la broche utilisée pour la lecture
   BoardBattVoltage = (((analogBoard_value * 5) / 1024.0)-0.3); 

   if (BoardBattVoltage < 0.1) 
   {
     BoardBattVoltage=0.0;
   } 

  
    delay(20);               // delai (plus de delai pour debug mais besoin de moins pour eviter jitter)
    if(radio.available()){
        radio.read(&ForeAft_Output,sizeof(ForeAft_Output));
      } else {Serial.print("No radio");
    }
    Serial.println(ForeAft_Output);
  Serial.println(BoardBattVoltage);
    Serial.print("\t");
 
    ForeAft.write(ForeAft_Output);                          // commande le servo avec la valeur angulaire

    }

je peux mettre plus d'espace dans l' écriture du code, c'est ça ?

oui ça aide :slight_smile: (ou appuyez sur ctrl-T)

le morceau de code que vous avez sélectionné dit : si il y a ecriture radio de ForeAft_Output, imprime sur le terminal la valeur analogique du capteur hall.

Non.... la bonne structure c'est

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

Pourquoi vous avez cela dans le sdtup()?

if (ForeAft_Input>800) 
    {(ForeAft_Input=800);}

le setup ne s’exécute qu’une seule fois

Pourquoi vous mettez tout plein d’expressions entre parenthèses?

Que retourne la fonction convertForeAftToServo() si vous êtes au dessus de 800?

Pourquoi vous avez cela dans le sdtup()?
Code: [Select]

if (ForeAft_Input>800)
{(ForeAft_Input=800);}

le setup ne s'exécute qu'une seule fois

j'ai mis cette expression dans le setup, car je souhaite "brider" la valeur analogique max du capteur hall.

en suivant un tuto dont je me suis inspiré pour faire mon code, il etait fait mention que les capteurs hall avaient souvent une plage mini - maxi de l'ordre de (220 à 800)

sur le terminal lorsqu'il n'y a pas d' aimant a proximité du capteur, j'ai 512 à 517 en valeur analogique.

si je met l'aimant tout contre le capteur j'ai dans les 1001 à 1002 .

le problème est qu'avec une valeur anlogique de 1001 j'ai approximativement 242 ° ce qui se traduit par une déccélération, dès que je revient dans la plage des 512 à 800 le moteur ce comporte normallement.

j'ai essayé d' intégrer à mon code un morceau de code qui permet de faire une calibration de capteur

/* Code TX
*  Code pour lire la position du capteur hall et la transmettre au TX 
*/

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

// Radio Configuration

RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool radioNumber=1;
bool role = 1;  // Definition du role : TX 1 / RX 0

// Broches de connection sur arduino nano
int ForeAft_Pin = 3;        // Capteur Hall sur broche analogique A3
int RemoteBatt_Pin = 1;      // mesure de tension de la batterie telecommandesur broche analogique 1

//  Broches pour la LED RGB 

#define RGBPin1 5 // Verte
#define RGBPin2 6 // Rouge

// Variables pour lire les valeur du capteur hall et la mesure de la tension de la batterie de la télécommande
float ForeAft_Input ;       // valeurs lues par le capteur hall a l' approche d' un aimant (min512 ; max 1001)
float RemoteBatt_Input ;     // valeurs de la tension de la batterie de la telecommande

// variables pour transmettre les valeurs angulaires à l'ESC 
int ForeAft_Output;       // (min 0° - max 180°)

// initialisation des données du capteur hall
int hallsens_lowest;
int hallsens_highest;
int measuredval;
int numofCalibratinsamples = 600; // nombre d' echantillons de calibration
int calibrationtime = 5000; // temps de calibration en millisecondes (5secondes)

// variables pour la conversion capteur hall - ESC
int Fore_Limit = 800;       // Valeur Max du capteur Hall
int Aft_Limit = 220;        // Valeur Max du capteur Hall

// Variable pour pour le programme
int message[2];  // tableau de 2 elements qui contiennent les infos

// creation de variables pour le monitoring batterie board
const float minVoltageBoard = 3.2;
const float maxVoltageBoard = 4.2;

void setup() {
    Serial.begin(9600);                   // initialisation port serie
    radio.begin();                        // demarrage radio
    radio.setPALevel(RF24_PA_LOW);        // transmission radio puissance basse
    radio.openWritingPipe(addresses[1]);  // adresse emission
    radio.openReadingPipe(1,addresses[0]);// adresse reception
    
    message[0]=26; // identifiant qui enverra une sorte d'identification pour la bonne télécommande.

//pinMode(redledpin, OUTPUT);
pinMode(RGBPin1, OUTPUT);
pinMode(RGBPin2, OUTPUT);

//indication with led
analogWrite(RGBPin1,0); // LED eteinte
analogWrite(RGBPin2, 0); // LED eteinte

//mesure du capteur Hall pendant 3 secondes ( defined in calibrationtime after power up)
//presser la gachette a fond et la relacher plusieurs fois
pinMode(ForeAft_Pin, INPUT);
measuredval = analogRead(ForeAft_Pin); //mesure la valeur et l'enregistre
hallsens_lowest = measuredval; // valeur min initiale première lecture
hallsens_highest = measuredval; // valeur max initiale première lecture
int calibrationsubsteptime = calibrationtime/numofCalibratinsamples;
int actualsubstepnumber = 0; //compteur pour la boucle While
int ledbrightnes = 0; // variable pour la brillance de la LED
// unsigned long actuallmills = millis(); //la capture se fait en millisecondes

// debut phase calibration
while (actualsubstepnumber <= numofCalibratinsamples){
  measuredval = analogRead(ForeAft_Pin); // mesure et enregistre la valeur
  hallsens_lowest = min(hallsens_lowest, measuredval); // enregistrement de la valeur minimale
  hallsens_highest = max(hallsens_highest, measuredval); // enregistrement de la valeur maximale 
  actualsubstepnumber++;
   
   // Indications de la LED
  ledbrightnes = ledbrightnes+10; // la brillance de la LED evoluera en fonction de la valeur de la boucle while
  //Indication avec la led
  analogWrite(RGBPin1,0); // LED ETEINTE (Verte)
  analogWrite(RGBPin2, ledbrightnes);  // LED variation puissance lumineuse sur LED ROUGE
  delay (calibrationsubsteptime);
  }
//indication with led
 analogWrite(RGBPin1, 200); //Led verte allumée  calibration réussie
 analogWrite(RGBPin2, 0); // Led rouge éteinte

delay(1000); // delais pour initialiser le capteur Hall ainsi que la radio

}
void loop() {

  //lecture du capteur Hall
  measuredval = analogRead(ForeAft_Pin);    // lecture capteur Hall sur broche A3 (analogique)
  
  ForeAft_Output = map(measuredval, hallsens_lowest, hallsens_highest, 20, 180 ); // map du resultat sur la valeur angulaire mini - maxi du servo (ESC)
  ForeAft_Output = constrain(ForeAft_Output, 20,180); // vérification si la valeur n'est pas en dehors de la plage
  

//debug
    // envoi de la valeur du capteur Hall
    Serial.println("Now sending...");
  
  bool transmissionseccess = 1; //radio.write( &message, sizeof(message) );

    if (transmissionseccess)
    {
            analogWrite(RGBPin1, (message[1])); // indique envoi et reception donnee avec led verte
            analogWrite(RGBPin2, 0); // eteint led rouge
            Serial.println("ok\n");
            Serial.println(measuredval);
    }
          else{
            analogWrite(RGBPin1, 0); // indication LED si calibration reussie 
            analogWrite(RGBPin2, 250); // led rouge eteinte
             Serial.println("failed\n\r");
    }

    delay(5); // Delai pour diminuer conso batterie- avec 5ms = 17mA , sans = 22 mA 
       
    //end of loop conr
    // dans le test dicorporation de la calibration 12_01_2018 , tout ce qui fonctionait avant  et que j'ai du enlevé est avec des **
    // ForeAft_Input = analogRead(ForeAft_Pin) ;             // lecture valeur capteur hall **
    //ForeAft_Output = convertForeAftToServo(ForeAft_Input) ;        // formule pour match capteur hall - ESC **

    radio.stopListening();                                 // arret réception et depart emission
    delay(20);                                            // delai (plus de delai pour debug mais besoin de moins pour eviter jitter)
    if(radio.write(&ForeAft_Output, sizeof(ForeAft_Output)),Serial.println(ForeAft_Input)); //envoi de la donnée angulaire (0-180)au RX et info serial de la valeur hall **
   
    radio.startListening();          // preparation pour reception confirmation bonne reception du RX
}

// fonction pour convertir et mettre a l' echelle les donnees du capteur Hall
// il est possible d'utiliser la fonction Map

//float convertForeAftToServo(float y) { // **
   // int result; //**
   // result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180); //**
   // return result; // **
    
    //int BoardbattLevel() {  // Fonction utilisée pour indiquer sur OLED le niveau de batterie de la planche en % a afficher sur TX
  //float voltageBoard = BoardBattVoltage();

  //if (voltageBoard <= minVoltageBoard) {
   // return 0;
 // } else if (voltageBoard >= maxVoltageBoard) {
  //  return 100;
 // } else {
   // return (voltageBoard - minVoltageBoard) * 100 / (maxVoltageBoard - minVoltageBoard);
 // }
//}
//}

cependant la plage de lecture se retrouve réduite au tiers de ce que j'avais avant et quand je plaque l'aimant contre le capteur les mêmes problème de baisse de régime moteur juqu'à l'arrêt apparaissent.

je ne comprend pas le fait que ma plage de fonctionnement soit réduite car lors de la phase d' acquisition, je fais en sorte d'avoir la plage la plus large possible.

c'est bien dommage car je trouvais cette fonctionnalité sympa, car elle permettrait si fonctionnelle de ne pas trop galérer pour la mise en place et les réglage dans la coque imprimée en 3D

j'ai mis cette expression dans le setup, car je souhaite "brider" la valeur analogique max du capteur hall.

Vous comprenez j’espère que vous n’êtes pas dans un système de programmation par contraintes dans lequel vous défìnissez des assertions et le système se charge de garantir que c’est toujours vrai... ? Le bout de codeif (ForeAft_Input>800) {(ForeAft_Input=800);} que vous avez écrit n’est en fait jamais exécuté: a variable ForeAft_Input est globale donc initialisée à 0 et cette expression de test du if est fausse et donc vous n’exécutez même pas ce qu’il y a entre accolades. comme après le setup() la loop() s’exécute et que la première instruction de la loop() estForeAft_Input = analogRead(ForeAft_Pin) ; vous vous empressez donc d’écraser immédiatement la valeur 0 avec celle lue sur la pin... bref ça ne sert donc absolument à rien...

Vous n’avez pas répondu à ma question - qui n’est pas là par hasard puisque c’est un de vos bugs - que retourne la fonction ?....

Bonjour,

je viens de faire un rapide calcul en mettant y = 810 en valeur analogique.

le resultat retourné serait de 183.1 °

Jokostyle:
Bonjour,
je viens de faire un rapide calcul en mettant y = 810 en valeur analogique.
le resultat retourné serait de 183.1 °

Le code de la fonction:

 float convertForeAftToServo(float y) {
    int result;
    result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180);
    if (result>=800)
    {
      (result=800);
    } else {
       return result;
    }   
}

je répète la question, qu'est-ce qui est retourné si result>=800 est vrai? (quelle instruction return est exécutée?)

c'est la valeur 800 qui est retourné ?

Jokostyle:
c'est la valeur 800 qui est retourné ?

où est le return?

return est entre les accolades du else

et donc ?

Il faut que je mettes dans mon code :

 float convertForeAftToServo(float y) {
    int result;
    result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180);
    if (result>=800)
    {
      return result=800;
    } else {
       return result;
    }   
}

?

Je viens d'essayer de réinjecter le code dans l'arduino nano du TX, le problème de cette décélération est toujours présent, si je place l'aimant tout contre le capteur.

le return de la fonction est corrigé.... pas le reste sans doute.

  • est-ce que la formule est bonne ?
  • est-ce que les mesures sont bonnes ?

re-postez tout le code utilisé et un schéma des branchements et alimentations

ça me semble un problème electronique; être certain que le capteur capte bien (test avec une led).. que le moteur soit en harmonies avec ses batteries (test avec voltmetre et un voltage divider, noter la valeur du voltmètre versus l'intensité du moteur brute... apres brancher le moteur dans l'arduino et faire des tests simples, comme si c'était une led..

noter la valeur du voltmètre versus l'intensité du moteur brute

LOL... une fois noté vous en faites quoi? :slight_smile:

apres brancher le moteur dans l'arduino et faire comme si c'était une led

C'est le meilleur moyen de griller son arduino... on ne branche pas un moteur directement sur un Arduino...

(en plus ici c'est un moteur mega patate - qui va tirer sans doute plus de 100 Ampères...)

bref - désolé mais.... conseils totalement foireux !!

le moteur que je vais utiliser sera un moteur 56104 500 Kv avec un esc 120 Ampères, je compte ne pas tirer plus que 80 Ampères, car je n'ai ^pas trouvé de BMS lithium ion 18650 avec plus de 80 Ampères.

pour mes tests, j'utilise un esc 40 A avec un moteur BL250 1800 Kv, mes lipos sont des 3 s et elles sont bien chargées .

je viens de faire les schémas de cablage TX et RX .

le TX :

/* Code TX
*  Code pour lire la position du capteur hall et la transmettre au TX 
*/

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

// Radio Configuration

RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool radioNumber=1;
bool role = 1;  // Definition du role : TX 1 / RX 0

// Broches de connection sur arduino nano
int ForeAft_Pin = 3;        // Capteur Hall sur broche analogique A3
int LeftRight_Pin = 1;      // mesure de tension de la batterie telecommandesur broche analogique 1

// Variables pour lire les valeur du capteur hall et la mesure de la tension de la batterie de la télécommande
float ForeAft_Input ;       // valeurs lues par le capteur hall a l' approche d' un aimant (min512 ; max 1001)
float LeftRight_Input ;     // valeurs de la tension de la batterie

// variables pour transmettre les valeurs angulaires à l'ESC 
int ForeAft_Output;       // (min 0° - max 180°)

// variables pour la conversion capteur hall - ESC
int Fore_Limit = 800;       // Valeur Max du capteur Hall
int Aft_Limit = 220;        // Valeur Max du capteur Hall

// creation de variables pour le monitoring batterie board
const float minVoltageBoard = 3.2;
const float maxVoltageBoard = 4.2;

void setup() {
    Serial.begin(9600);                   // initialisation port serie
    radio.begin();                        // demarrage radio
    radio.setPALevel(RF24_PA_LOW);        // transmission radio puissance basse
    radio.openWritingPipe(addresses[1]);  // adresse emission
    radio.openReadingPipe(1,addresses[0]);// adresse reception
}
void loop() {
    ForeAft_Input = analogRead(ForeAft_Pin) ;             // lecture valeur capteur hall
    ForeAft_Output = convertForeAftToServo(ForeAft_Input) ;        // formule pour match capteur hall - ESC

    radio.stopListening();                                 // arret réception et depart emission
    delay(20);                                            // delai (plus de delai pour debug mais besoin de moins pour eviter jitter)
    if(radio.write(&ForeAft_Output, sizeof(ForeAft_Output)),Serial.println(ForeAft_Input));              //envoi de la donnée angulaire (0-180)au RX et info serial de la valeur hall 
    radio.startListening();          // preparation pour reception confirmation bonne reception du RX
}

// fonction pour convertir et mettre a l' echelle les donnees du capteur Hall
// il est possible d'utiliser la fonction Map

float convertForeAftToServo(float y) {
    int result;
    result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180);
    if (result>=800)
    {
     return result=800;
    }
    else
    {
    return result;
    }   
    }
    //int BoardbattLevel() {  // Fonction utilisée pour indiquer sur OLED le niveau de batterie de la planche en % a afficher sur TX
  //float voltageBoard = BoardBattVoltage();

  //if (voltageBoard <= minVoltageBoard) {
   // return 0;
 // } else if (voltageBoard >= maxVoltageBoard) {
  //  return 100;
 // } else {
   // return (voltageBoard - minVoltageBoard) * 100 / (maxVoltageBoard - minVoltageBoard);
 // }
//}
//}

Le RX:

/*  code recepteur AFT
*   Code pour recevoir les infos du TX et les transmettre a l 'ESC*/

#include <Servo.h>
#include <SPI.h>
#include <RF24.h>

//Radio Configuration

bool radioNumber=0;
RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool role = 0;  // Definition du role : TX 1 / RX 0


// Variable pour le servo ESC

Servo ForeAft;

unsigned int ForeAft_Output;       // valeur  0 - 180 degrees

float BoardBattVoltage = 0.0; // variable flottante pour la lecture de la tension batterie
float temp=0.0;

void setup() { 
    Serial.begin(9600);        // initialisation port serie
    ForeAft.attach(5);         // definition broche servo (ESC) sur la broche digitale 5 (PWM
    radio.begin();             // demarrage radio
    radio.setPALevel(RF24_PA_LOW);    // transmission radio puissance basse
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
    radio.startListening();


// l' esc demarre réellement a 10 ° 
  
for(ForeAft_Output = 10; ForeAft_Output <= 180; ForeAft_Output += 1) //va de 0 degrees a 180 degrees par pas de  1 degree
  {                                  
    ForeAft.write(ForeAft_Output);              // dis à l'ESC d' aller a la postion definit par la variable ForeAft_Output 
    delay(15);                       // delais de  15ms pour que le servo atteigne la postion ( pour protéger la boite de vitesse ) 
  } 
  for(ForeAft_Output = 180; ForeAft_Output>=10; ForeAft_Output-=1)     // va de 180 degrees a 0 degrees par pas de  1 degree
  {                                
    ForeAft.write(ForeAft_Output);              //  dis à l'ESC d' aller a la postion definit par la variable ForeAft_Output  
    delay(15);                       // delais de  15ms pour que le servo atteigne la postion ( pour protéger la boite de vitesse )
  }  

    
}
void loop() {

   // Formule de conversion pour le voltage
   int analogBoard_value = analogRead(A4);  // definition de la broche utilisée pour la lecture
   BoardBattVoltage = (((analogBoard_value * 5) / 1024.0)-0.3); 

   if (BoardBattVoltage < 0.1) 
   {
     BoardBattVoltage=0.0;
   } 

  
    delay(20);               // delai (plus de delai pour debug mais besoin de moins pour eviter jitter)
    if(radio.available()){
        radio.read(&ForeAft_Output,sizeof(ForeAft_Output));
      } else {Serial.print("No radio");
    }
    Serial.println(ForeAft_Output);
  Serial.println(BoardBattVoltage);
    Serial.print("\t");
 
    ForeAft.write(ForeAft_Output);                          // commande le servo avec la valeur angulaire

    }

Mon conseil pourtait surtout sur les pré requis à effectuer avant de commencer à programmer. Je prenais pour aquis que Jokostyle savais déjà comment interfacer son moteur avec le Arduino..

Les mesures pourraient servir à dessiner un tableau de tension / force du moteur..

Bonsoir,

mon problème est à mon avis dans l' écriture du code, car le montage est fonctionnel pour l' instant, c'est juste que la lecture du capteur hall à besoin d' être fiabilisée .

Si quelqu'un sait comment fonctionne la librairie u8g2 , je suis preneur, je n'arrive pas a afficher des frames.

voici la dernière mouture du code du TX :

/* Code TX
*  Code pour lire la position du capteur hall et la transmettre au TX 
*/

#include <SPI.h>
#include <RF24.h>
#include <U8g2lib.h>

// Radio Configuration

RF24 radio(9,10);
byte addresses[][6] = {"1Node","2Node"};
bool radioNumber=1;
bool role = 1;  // Definition du role : TX 1 / RX 0

// Definition de l'ecran OLED (128x64)
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// Broches de connection sur arduino nano
int ForeAft_Pin = 3;        // Capteur Hall sur broche analogique A3
int LeftRight_Pin = 1;      // mesure de tension de la batterie telecommandesur broche analogique 1

// Variables pour lire les valeur du capteur hall et la mesure de la tension de la batterie de la télécommande
float ForeAft_Input ;       // valeurs lues par le capteur hall a l' approche d' un aimant (min512 ; max 1001)
float LeftRight_Input ;     // valeurs de la tension de la batterie

// variables pour transmettre les valeurs angulaires à l'ESC 
int ForeAft_Output;       // (min 0° - max 180°)

// variables pour la conversion capteur hall - ESC
int Fore_Limit = 800;       // Valeur Max du capteur Hall
int Aft_Limit = 220;        // Valeur Max du capteur Hall

// creation de variables pour le monitoring batterie board
const float minVoltageBoard = 3.2;
const float maxVoltageBoard = 4.2;
float BoardBattVoltage ();

void setup() {
    Serial.begin(9600);                   // initialisation port serie
    radio.begin();                        // demarrage radio
    radio.setPALevel(RF24_PA_LOW);        // transmission radio puissance basse
    radio.openWritingPipe(addresses[1]);  // adresse emission
    radio.openReadingPipe(1,addresses[0]);// adresse reception
      u8g2.begin(); // demarrage U8g2 librairie
}
void loop() {
    ForeAft_Input = analogRead(ForeAft_Pin) ;             // lecture valeur capteur hall
    ForeAft_Output = convertForeAftToServo(ForeAft_Input) ;        // formule pour match capteur hall - ESC

    radio.stopListening();                                 // arret réception et depart emission
    delay(20);                                            // delai (plus de delai pour debug mais besoin de moins pour eviter jitter)
    if(radio.write(&ForeAft_Output, sizeof(ForeAft_Output)),Serial.println(ForeAft_Input));              //envoi de la donnée angulaire (0-180)au RX et info serial de la valeur hall 
    radio.startListening();          // preparation pour reception confirmation bonne reception du RX
}

// fonction pour convertir et mettre a l' echelle les donnees du capteur Hall
// il est possible d'utiliser la fonction Map

float convertForeAftToServo(float y) {
    int result;
    result = ((y - Aft_Limit) / (Fore_Limit - Aft_Limit) * 180);
    if (result>=800)
    {
     return result=800;
    }
    else
    {
    return result;
    }   
    }
    int BoardbattLevel() 
    {  // Fonction utilisée pour indiquer sur OLED le niveau de batterie de la planche en % a afficher sur TX
    float voltageBoard = BoardBattVoltage();

    if (voltageBoard <= minVoltageBoard) 
    {
    return 0;
    } 
    else if (voltageBoard >= maxVoltageBoard) 
    {
    return 100;
    }
    else 
    {
    return (voltageBoard - minVoltageBoard) * 100 / (maxVoltageBoard - minVoltageBoard);
    }
    }
//}
void drawBatteryLevel() 
{
  int level = round5(BoardbattLevel());

  // Position sur  OLED
  int x = 108; int y = 4;

  u8g2.drawFrame(x + 2, y, 18, 9);
  u8g2.drawBox(x, y + 2, 2, 5);

  for (int i = 0; i < 5; i++) {
    int p = round((100 / 5) * i);
    if (p <= level)
    {
      u8g2.drawBox(x + 4 + (3 * i), y + 2, 2, 5);
    }
  }
}

int round5(int n) 
{
  return (n/5 + (n%5>2)) * 5;
}