[RESOLU] Arduino Mega & NRF24L01 +

Salut,

je suis en phase quasi terminale d'une interface avec 8 boutons, 1 encodeur et 16 entrées analogiques transmises via des modules NRF24L01+

je transmets mes données en RF à un récepteur qui crache du MIDI dans un ordi, pour une application musicale.

le tout est branché sur un shield créé exprès, pluggé sur une arduino MEGA 2560 et tout est alimenté par une batterie Li Po.

après avoir parcouru les forums ici et ailleurs, j'ai ajouté un condensateur de 100nF entre le 3,3V et la masse du module radio parce qu'il semblait qu'il faille faire ça pour que les modules radio fonctionnent bien sur les Mega (une histoire d'alimentation).

ça marche très bien MAIS: petit problème (qui m'énerve parce que je sens que je suis à un cheveu de réussir):

parfois la transmission commence à lagger... et ça se met IMMEDIATEMENT à fonctionner vraiment impeccablement lorsque je pose mon doigt sur la connectique du module radio ou que je touche du doigt le PCB du module radio.

dès que je lache... ça relagge.

auriez vous une suggestion à faire ?

est ce que je décharge ce condo de 100 nF quand je touche ? est il trop gros ?

merci d'avance ! :slight_smile:

Aucun visuel ça va être dur de t'aider. En plus lagger je vois pas trop comment ça peut se traduire ici

et bien sur la photo (moche), vous voyez le petit condo et le module avec le petit header 8 points.

c’est sur ces points que lorsque je mets le doigt tout se remet à marcher.

:slight_smile:

et par "lagger" j'entends des latences, des "freeze" de mes données, une transmission moins fluide quoi...

Bonjour,

"Lag", "freeze", ... et nRF24L01 = signe d'une transmission de données pourrie.
(la gestion matériel des paquets, de l'acquittement et des checksum c'est à double tranchant, quand la transmission est mauvaise plus rien ne marche car le module passe son temps à retransmettre des paquets perdu)

Un schéma de ta shield et un lien vers ton module nRF ?

merci de ta réponse,

j'ai résolu le problème de transmission, dû au fait que l'arduino Mega fournit un 3.3V instable, en mettant un condensateur de 47 uF entre le 3.3V et la masse du module radio.

ça marche PARFAITEMENT maintenant.

je posterai le schéma un peu plus tard !

Skywodd, je tiens d’ailleurs à te remercier, c’est ton blog qui m’a orienté vers ces modules radio.

en gros mon shield utilise le branchement décrit sur ton blog, mais adapté à l’arduino mega.

le shield est très simple: il lit les 16 entrée analogiques, avec des pull downs de 10K pour chaque entrée (y sont branchés des capteurs de pression, des potentiomètres, et des télémètres sharp pour lesquels il faut enlever les pull downs) , il lit aussi 8 entrées digitales (des boutons ou des switches, là aussi avec pull down) et enfin un encodeur incrémental.

les données lues sont ensuite converties en control change MIDI (valeurs de 0 à 127) et sont transmises à un récepteur lui aussi doté de son nrf24l01+ (mais monté sur une arduino Uno) qui recrache les données via le Tx en MIDI.

ensuite ça rentre dans mon ordi, et je traite tout ça dans max/msp, pour en faire du son.

voilà le code émetteur:

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

//////////////////////////USER DEFINE VARIABLES
int inter=20;//interval en ms entre envois
boolean debug=false; //true activate serial debug
#define numDig 8 //nombre d'entrée digitale
#define numAna 16//nombre d'entrée analogiques
int midiChannel = 1; // Midi Channel
//! les interrupts ne sont pas pris en compte comme entrée digitales
int encoderCC=100;
int digmidiCCselect[] = {
  28,29,30,31,32,33,34,35};
// select the midi Controller Number for each analogue input
int midiCCselect[] = {
  1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
  

// select threshold for each analog input
int thresh[numAna]={
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};   // was 1 on the 8*4original program
//select the digital input pins (starting from 4)
int digInput[]={
  4,5,6,7,8,9,10,11};
//////////////////////////////////////////////////////////////

// Variables
int AnalogValue[numAna];
int lastAnalogValue[numAna]; 
int DigitalValue[numDig];
int lastDigitalValue[numDig];

//rotary encoder
int xa=2; //input xa et xb
int xb=3;
volatile int xaLast;//last state of xa
volatile int val=0;  //LA variable X entre -6 et +6
boolean tag=false;



void setup() {
  if(debug) Serial.begin(9600);
  //set port dir
  for(int i=0; i<numDig; i++) pinMode(digInput[i],INPUT);
  //encoder init
  pinMode(xa,INPUT);
  pinMode(xb,INPUT);
  attachInterrupt(0, encoderX, CHANGE);  // envois sur encodeX quand pin2 aka 0 change
  //Mirf init
  Mirf.cePin = 49; // CE sur Digital pin dispo de l'arduino Mega
  Mirf.csnPin = 53; // CSN sur Digital pin dispo de l'arduino Mega
  Mirf.spi = &MirfHardwareSpi; 
  Mirf.init();
  Mirf.channel = 1; 
  Mirf.payload = 3*sizeof(byte); 
  Mirf.config(); 
  Mirf.setTADDR((byte *)"singer02t"); //a checker ds sketch recepteur
  Mirf.setRADDR((byte *)"singer02r"); //a checker
  Mirf.configRegister(RF_SETUP,0x06); 
}

// main program loop
void loop() {

  //scan the digital inputs 
  for(int i=0;i<numDig;i++) {
    DigitalValue[i] = digitalRead(digInput[i])*127; //scale 0-1 digital inputs to have a midi value 0-127
    if ( DigitalValue[i] != lastDigitalValue [i] ) {
      //send control change on cc#i on midiChannel
      midiCC( (175+midiChannel), digmidiCCselect[i], DigitalValue[i]); 
      // update lastAnalogValue variable
     lastDigitalValue[i] = DigitalValue[i];
    } //end if
  }//end for 

  //scan the analog inputs and send CC

  for(int i=0;i<numAna;i++){
    AnalogValue[i] = (analogRead(i))/8;    // read the value from the analog input and divide by 8 for range 0-127
    // check if value is greater than defined threshold (good for resistive touchpads etc)
    if ( AnalogValue [i]>thresh[i] ) {
      // check if analog input has changed
      if ( AnalogValue[i] != lastAnalogValue[i] ) {
      //send control change on cc#i on midiChannel
      midiCC((175+midiChannel), midiCCselect[i], AnalogValue[i]); 
      // update lastAnalogValue variable
      lastAnalogValue[i] = AnalogValue[i];
        }  //End if
    }//End if
    //A ESSAYER POUR STABILISER LES VALEURS
    else if (AnalogValue [i]<=thresh[i] ) {
   //   midiCC((175+midiChannel), midiCCselect[i], 0);
    midiCC((175+midiChannel), midiCCselect[i], AnalogValue[i]);
    } //endif  
  }//End for 

//encoder, send on change, 
if(val>127)val=0;
if(val<0)val=127;
  if(tag){
    midiCC((175+midiChannel),encoderCC,val);
    tag=false;
  }
delay(inter);
}//End Loop



// This function sends a Midi CC over the NRF20L01+ transceiver
void midiCC(char CC_data, char c_num, char c_val){
  if(debug){
    Serial.print(CC_data,DEC);
    Serial.print(" ");
    Serial.print(c_num,DEC);
    Serial.print(" ");
    Serial.print(c_val,DEC);
    Serial.println(" ");
  }
  byte data[Mirf.payload];
  data[0] = CC_data;
  data[1] = c_num;
  data[2] = c_val;
  Mirf.send((byte*)&data);
  while(Mirf.isSending()); 
}


//encoder interrupt fonction
void encoderX(){
  boolean ra=digitalRead(xa);
  boolean rb=digitalRead(xb);
if(!xaLast && ra){
  if(!rb) val++;
  else val--;  
}
  xaLast=ra;
  tag=true;
}

et le code du récepteur:

/**********************************************************

Recepteur MIDI sans fil.
Réachemine par la pin 1 (Tx) les messages MIDI reçus
par le module rf NRF24L01.
*/


#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

void setup(){
  Serial.begin(31250);
  
 //Serial.begin(9600);
  
   //Notes: :)
 /* Pins:
 * Hardware SPI:
 * MISO -> 12 on arduino UNO // 50 on Arduino Mega.
 * MOSI -> 11 on UNO // 51 on Arduino Mega.
 * SCK -> 13 on UNO // 52 on Arduino Mega.
 *
 * Configurable:
 * CE -> 8
 * CSN -> 7
 */
  
  Mirf.cePin = 9; // CE sur D9
  Mirf.csnPin = 10; // CSN sur D10
  Mirf.spi = &MirfHardwareSpi; 
  Mirf.init(); 
  

//channel 1 for the machine 2

  Mirf.channel = 1; 
  Mirf.payload = 3*sizeof(byte);
  Mirf.config();
  

    

  
  Mirf.setTADDR((byte *)"singer02r"); 
  Mirf.setRADDR((byte *)"singer02t"); 

//a essayer: 0x06 = 1Mbs data rate - 0x26 = 250 Kbs data rate (longest range)
  Mirf.configRegister(RF_SETUP,0x06); 
}

void loop(){

  byte data[Mirf.payload]; 
  
  if(!Mirf.isSending() && Mirf.dataReady()){ 

    Mirf.getData(data); // on récupére le message
    
    Serial.write(data[0]);
    Serial.write(data[1]);
    Serial.write(data[2]);

  }
}