Communication radio entre Micro Pro et Nano

Bonjour,

Je possède un émetteur et un récepteur radio. L'émetteur est connecté à l'Arduino Nano et le récepteur est connecté à l'Arduino Micro Pro.

Pour une raison inconnue, je n'arrive pas à les faire communiquer. Mais bizarrement, tout fonctionne parfaitement lorsque le récepteur est connecté à l'Arduino Uno.

D'après ce que j'ai compris, la communication se fait par SPI, donc je suis censé utiliser le pin 12 sur le Nano (MISO) et le pin 16 (MOSI) sur le Micro Pro, qui est l'équivalent du pin 11 (MOSI) sur le Uno.

Pinout Arduino Nano

Pinout Arduino Micro Pro

Pinout Arduino Uno

Je voudrais l'utiliser en tant que souris donc je suis obligé d'utiliser le Micro Pro (je ne trouve pas de boutiques vendant d'Arduino Micro et le Leonardo n'est pas très transportable)

Je me dis que le problème vient des micro-contrôleurs (Nano -->ATmega328 ; Uno --> ATmega328P ; Micro Pro --> ATmega32u4)

Est-ce correct? Si oui y a-t-il une solution?

Petite question en plus: Sur certaines cartes, il y a 6 ou 8 pins regroupé (ICSP?) Est-ce que les 6/8 pins regroupé sont différents des pins MISO, MOSI, SS et SCK répartis sur la carte?

Merci :slight_smile:

Quelle radio?
Quelles librairies ?
Quel code ?
Quelle alimentation ?
Détail des connexions ?

Un micro-pro ça n’existe pas - c’est un Pro Micro—> quelle version (3.3V ou 5V? 8MHz ou 16MHz?) ?

J-M-L:
Quelle radio?
Quelles librairies ?
Quel code ?
Quelle alimentation ?
Détail des connexions ?

Un micro-pro ça n’existe pas - c’est un Pro Micro—> quelle version (3.3V ou 5V? 8MHz ou 16MHz?) ?

Radio : Emetteur :CHJ-R315A ; Recepteur :CHJ-9921

Librairie : Récepteur :RadioHead, SPI, Mouse ; Emetteur :RadioHead, SPI, Wire

Code : Emetteur :

#include <RH_ASK.h>
#include <SPI.h>
#include <Wire.h>

//<============================== RADIO =================================
RH_ASK rf_driver;
String str_out;
String str_rotX, str_rotY, str_rotZ;
String str_gForceX, str_gForceY, str_gForceZ;
//<======================================================================


//<============================== ACCEL ==================================
long accelX, accelY, accelZ;
float gForceX, gForceY, gForceZ;

long gyroX, gyroY, gyroZ;
float rotX, rotY, rotZ;
//========================================================================>

int mouseClickFlag;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  setupMPU();
  if (!rf_driver.init())
         Serial.println("init failed");
}


void loop() {
  recordAccelRegisters();
  recordGyroRegisters();
  printData();
  sendData();
}
//<=========================== ACCEL ========================== ACCEL =========================== ACCEL ==============================
void setupMPU(){
  Wire.beginTransmission(0b1101000); //This is the I2C address of the MPU (b1101000/b1101001 for AC0 low/high datasheet sec. 9.2)
  Wire.write(0x6B); //Accessing the register 6B - Power Management (Sec. 4.28)
  Wire.write(0b00000000); //Setting SLEEP register to 0. (Required; see Note on p. 9)
  Wire.endTransmission();  
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x1B); //Accessing the register 1B - Gyroscope Configuration (Sec. 4.4) 
  Wire.write(0x00000000); //Setting the gyro to full scale +/- 250deg./s 
  Wire.endTransmission(); 
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x1C); //Accessing the register 1C - Acccelerometer Configuration (Sec. 4.5) 
  Wire.write(0b00000000); //Setting the accel to +/- 2g
  Wire.endTransmission(); 
}

void recordAccelRegisters() {
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x3B); //Starting register for Accel Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,6); //Request Accel Registers (3B - 40)
  while(Wire.available() < 6);
  accelX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
  accelY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
  accelZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processAccelData();
}

void processAccelData(){
  gForceX = accelX / 16384.0;
  gForceY = accelY / 16384.0; 
  gForceZ = accelZ / 16384.0;
}

void recordGyroRegisters() {
  Wire.beginTransmission(0b1101000); //I2C address of the MPU
  Wire.write(0x43); //Starting register for Gyro Readings
  Wire.endTransmission();
  Wire.requestFrom(0b1101000,6); //Request Gyro Registers (43 - 48)
  while(Wire.available() < 6);
  gyroX = Wire.read()<<8|Wire.read(); //Store first two bytes into accelX
  gyroY = Wire.read()<<8|Wire.read(); //Store middle two bytes into accelY
  gyroZ = Wire.read()<<8|Wire.read(); //Store last two bytes into accelZ
  processGyroData();
}

void processGyroData() {
  rotX = gyroX / 131.0;
  rotY = gyroY / 131.0; 
  rotZ = gyroZ / 131.0;
}

void printData() {
  Serial.print("Gyro (deg)");
  Serial.print("\t");
  Serial.print(" X= ");
  Serial.print(rotX);
  Serial.print("\t");
  Serial.print(" Y= ");
  Serial.print(rotY);
  Serial.print("\t");
  Serial.print(" Z= ");
  Serial.print(rotZ);
  Serial.print("\t");
  Serial.print(" Accel (g)");
  Serial.print(" X=");
  Serial.print(gForceX);
  Serial.print(" Y=");
  Serial.print(gForceY);
  Serial.print(" Z=");
  Serial.println(gForceZ);
}
//===================================================================================================================================>



//<============================================================ RADIO ===============================================================
void sendData() {
  str_rotX = String(rotX);
  str_rotY = String(rotY);
  str_rotZ = String(rotZ);

  str_gForceX = String(gForceX);
  str_gForceY = String(gForceY);
  str_gForceZ = String(gForceZ);

  str_rotX.remove(4);
  str_rotY.remove(4);
  str_rotZ.remove(4);
  
  str_gForceX.remove(4);
  str_gForceY.remove(4);
  str_gForceZ.remove(4);
  str_out = str_rotX + "," + str_rotY + "," + str_rotZ + "," + str_gForceX + "," + str_gForceY + "," + str_gForceZ;

  static char *msg = str_out.c_str();
  rf_driver.send((uint8_t *)msg, strlen(msg));
  rf_driver.waitPacketSent();
  Serial.println(str_out);


  
}

Recepteur:

#include <RH_ASK.h>
#include <SPI.h>
#include <Mouse.h>
//<============================== MOUSE =================================
int vertZero, horiZero;  // Stores the initial value of each axis, usually around 512
int vertValue, horzValue;  // Stores current analog output of each axis
const int sensitivity = 200;  // Higher sensitivity value = slower mouse, should be <= about 500
int mouseClickFlag_R, mouseClickFlag_L;
//=======================================================================>

//<============================== RADIO =================================
String str_out;
String str_rotX, str_rotY, str_rotZ;
String str_gForceX, str_gForceY, str_gForceZ;
RH_ASK rf_driver;
//=======================================================================>



float rotX, rotY, rotZ;
float gForceX, gForceY, gForceZ;

void setup() {
  Serial.begin(115200);
  if (!rf_driver.init())
         Serial.println("init failed");
  vertZero = rotX;
  horiZero = rotY;
}

void loop() {
  dataReception();
  mouseProcessing();
}

//====================================== dataReception() =======================================
void dataReception() {

    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);

    if (rf_driver.recv(buf, &buflen))
    {
      str_out = String((char*)buf);

      //rf_driver.printBuffer("Message: ", buf, buflen);
      Serial.println(str_out);

      str_rotX = str_out.substring(0, 4);
      str_rotY = str_out.substring(5, 9);
      str_rotZ = str_out.substring(10, 14);
      str_gForceX = str_out.substring(15, 19);
      str_gForceY = str_out.substring(20, 24);
      str_gForceZ = str_out.substring(25, 29);

      rotX = str_rotX.toFloat();
      rotY = str_rotY.toFloat();
      rotZ = str_rotZ.toFloat();
      gForceX = str_gForceX.toFloat();
      gForceY = str_gForceY.toFloat();
      gForceZ = str_gForceZ.toFloat();
      

  Serial.print("Gyro (deg)");
  Serial.print("\t");
  Serial.print(" X= ");
  Serial.print(rotX);
  Serial.print("\t");
  Serial.print(" Y= ");
  Serial.print(rotY);
  Serial.print("\t");
  Serial.print(" Z= ");
  Serial.print(rotZ);
  Serial.print("\t");
  Serial.print(" Accel (g)");
  Serial.print(" X=");
  Serial.print(gForceX);
  Serial.print(" Y=");
  Serial.print(gForceY);
  Serial.print(" Z=");
  Serial.println(gForceZ);
  }
}

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

//========================================= mouseProcessing() ==========================================

void mouseProcessing() {
  gForceZ = str_gForceZ.toFloat();
  gForceX = str_gForceX.toFloat();
  
  vertValue = gForceZ;  // read vertical offset
  horzValue = gForceX;  // read horizontal offset

  if (vertValue != 0) {
    Mouse.move(0, vertValue, 0);  // move mouse on y axis
  }
   
  if (horzValue != 0) {
    Mouse.move(horzValue, 0, 0);  // move mouse on x axis
  }

  if (mouseClickFlag_R == 1) {
    Mouse.press(MOUSE_RIGHT);
  }
  else if (mouseClickFlag_R == 0) {
    Mouse.release(MOUSE_RIGHT);
  }

  if (mouseClickFlag_L == 1) {
    Mouse.press(MOUSE_LEFT);
  }
  else if (mouseClickFlag_L == 0) {
    Mouse.release(MOUSE_LEFT);
  }  


}

Alimentation : 5V

Connexion :

Récepteur Pro Micro

Vcc --> Vcc
DATA --> 16
GND --> GND

Emetteur Nano

Vcc --> Vcc
DATA --> 11
GND --> GND

Pro Micro 5V ; 16MHz

Radio : Emetteur :CHJ-R315A ; Recepteur :CHJ-9921

Récepteur Pro Micro
Vcc --> Vcc
DATA --> 16
GND --> GND

Vos modules ne sont pas en SPI --> Ne connectez pas sur la pin 16, connectez sur la pin 12. (c'est pas du SPI - RH_ASK utilise un timer pour piloter les pins et 11 et 12 sont celles par défaut dans le constructeur de votre RH_ASK rf_driver;)

Si j'étais vous je n'utiliserais pas la classe String. Elle prend plein de place et risque de fragmenter la mémoire et de faire planter votre systeme. De plus vous transmettez 6 float, vous êtes peut être un peu limite suivant les valeurs de float (j'ai pas regardé en détail si vous tronquez) pour le buffer qui est limité à une 60aine d'octets.

--> vous avez un buffer à transmettre, vous connaissez exactement le nombre d'octets (6 floats = 6 x 4 = 24 octets) à transmettre pour vos data
--> mettez les data dans une structure, mettez directement dedans vos valeurs et transmettez la structure en binaire. ce sera bcp plus compact et donc réactif (pourquoi vous ennuyez à passer par de l'ASCII pour avoir à reconvertir dans l'autre sens).

J-M-L:
Vos modules ne sont pas en SPI --> Ne connectez pas sur la pin 16, connectez sur la pin 12. (c'est pas du SPI - RH_ASK utilise un timer pour piloter les pins et 11 et 12 sont celles par défaut dans le constructeur de votre RH_ASK rf_driver;)

C'est ce que je comptais faire mais il n'y a pas de pin 11 sur le Pro Micro, c'est sûrement pour ça que la transmission se fait sur le Uno mais pas sur celui-là. Est-ce possible de changer le pin par défaut (pin 16 au lieu de 11 par exemple?)

J-M-L:
Si j'étais vous je n'utiliserais pas la classe String. Elle prend plein de place et risque de fragmenter la mémoire et de faire planter votre systeme. De plus vous transmettez 6 float, vous êtes peut être un peu limite suivant les valeurs de float (j'ai pas regardé en détail si vous tronquez) pour le buffer qui est limité à une 60aine d'octets.

--> vous avez un buffer à transmettre, vous connaissez exactement le nombre d'octets (6 floats = 6 x 4 = 24 octets) à transmettre pour vos data
--> mettez les data dans une structure, mettez directement dedans vos valeurs et transmettez la structure en binaire. ce sera bcp plus compact et donc réactif (pourquoi vous ennuyez à passer par de l'ASCII pour avoir à reconvertir dans l'autre sens).

Merci pour votre conseil, honnêtement je n'y avais pas pensé :slight_smile:

tyann77090:
C'est ce que je comptais faire mais il n'y a pas de pin 11 sur le Pro Micro, c'est sûrement pour ça que la transmission se fait sur le Uno mais pas sur celui-là. Est-ce possible de changer le pin par défaut (pin 16 au lieu de 11 par exemple?)

ah oui j'avais oublié ce point :slight_smile:

oui il suffit de passer les pins souhaités lors de l'initialisation par exemple si vous faites unRH_ASK driver(2000, 2, 4, 5);ça veut dire
speed = 2000 (n'allez pas au dela)
rxPin = 2
txPin = 4
pttPin = 5
(et pttInverted sera à faux par défaut false)

MERCI J-M-L !!! Ça fonctionne maintenant ! :smiley:

Reste plus qu'à le finaliser...

cool :slight_smile: