Problème MultiSerial (software Serial) et SoftEasyTransfert sur Arduino Mega

Bonjour à tous,

J'ai un code qui tourne sur un Arduino Mega. Pour expliquer rapidement le principe, j'ai un uno qui decode les signaux d'une radiocommande et qui transfert via un port Série un numéro de séquence à jouer.
Le Mega qui reçoit le numéro est chargé de faire de l'affichage et de distribuer des commandes à d'autres UNO aussi par des ports Séries.

Donc dans le méga, j'ai une trame de reception (pour récupérer mon numéro de sequence) et une trame d'emission qui me permet de discuter avec les UNO Esclaves (si possible avec une trame unique qui marche pour chaque Arduino esclave).

Pour simplifier, si avec la radiocommande, j'envois le code "Haut-Bas-Gauche-Droit", je n'aurais pas le même code qu'avec "Haut-Bas-Droit-Gauche). Le Mega récupère l'info et dis à un autre uno, OK joue tel son ou allume telle lumière. L'objectif final est de dessiner des lettres sur ma radiocommande et que mon robot joue des séquces programmés.

Voilà pour l'explication.

Donc dans mon mega, j'ai 4 Serial (qui sous sont SoftSerial car les pinoches classiques 0, 1, 14 à 19 pour les ports Séries ne sont physiquement pas accessibles à cause de l'écran).

Cela fonctionnait parfaitement jusqu'à hier et depuis hier je n'ai plus de réception sur le port Série (j'ai peut-être touché quelque chose, mais je ne comprends pas trop). Afin de d'isoler le problème, j'ai pris un uno en tant qu'emmeteur sur lequel j'envois toujours le même code toutes les 150 ms. J'ai pris un mega comme récepteur et la comm fonctionne.
Ensuite , j'ai épuré mon code avec des "/" et "/" et j'ai vérifié que mon mega réceptionne bien ma comm en isolant des bouts de code. Après en enlevant mes "*/" je me suis aperçu que la communication ne marche plus dès que j'initialise un second port série (R2_Sound.begin() ou R2_Light.begin()).

Auriez-vous, une idée sur mon problème ? J'avoue complètement séché et surtout je ne comprends pas pourquoi il marchait dimanche et plus maintenant... Evidemment, comme un gros naze, je travaille toujours sur un seul et unique programme, donc je n'ai pas de sauvegarde de la version de dimanche...

Ci-joint un bout de code pour comprendre ma problématique :


#include <SoftEasyTransfer.h> // Easy Transfert sous SoftSerial
#include <SoftwareSerial.h>
#include "R2Logo.h"
#include "R2Display.h" 
// Initialise les variables
int Volume;
bool EtatDemo;

// On introduit le temps comme évènement supplémentaire
unsigned long chrono; // attention, type unsigned long comme millis()
 
////////////////
// SOFTSERIAL //
////////////////
// Créer les objets SOFT SERIAL du nom de Serial_Stroke, Serial_Sound, Serial_Light, Serial_Dome  
SoftwareSerial Serial_Stroke(52, 48); // RX : Jaune , TX : Vert
SoftwareSerial Serial_Sound(53,49); // RX : Bleu , TX : Violet 
SoftwareSerial Serial_Light(50, 46); // RX : Gris , TX : Blanc
SoftwareSerial Serial_Dome(51, 47); // RX : Noir , TX : Marron


////////////////////////
// SOFTEASY TRANSFERT //
////////////////////////
// Créer les objets EASY TRANSFERT du nom de R2_Stroke
SoftEasyTransfer R2_Stroke;
SoftEasyTransfer R2_Sound;
SoftEasyTransfer R2_Light;
SoftEasyTransfer R2_Dome;


struct RECEIVE_DATA_STRUCTURE_STROKE{
  //Définie la trame à recevoir. Attention elle doit être strictement identique à celle de l'emission
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  char Fonction;                // Char pour M (comme main)
  long Stroke;                  // String à remplacer par bool quand travail sur un seul arduino
}; 
 
struct SEND_DATA_STRUCTURE_EMISSION{
  //Définie la trame à envoyer. Attention elle doit être strictement identique à celle de l'emission
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  char Fonction;
  int Etat;
  int Var1;
  int Var2;
  int Var3;
  int Ack;              // int à remplacer par bool quand travail sur un seul arduino
};


//Donne un nom au groupe de données Stroke
RECEIVE_DATA_STRUCTURE_STROKE MaTrame_Stroke;

//Donne un nom au groupe de données Emission
SEND_DATA_STRUCTURE_EMISSION MaTrame_Emission;

//--------------------------------------------------------------------------------------
///////////
// SETUP //
///////////
void setup() {

// Initialise les ports Serie
Serial.begin(9600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }



Serial_Stroke.begin(9600);
//Serial_Sound.begin(9600);   **C'EST ICI QUE JE NE RECOIS PLUS LE MESSAGE SI JE DECOMMENTE UNE DES TROIS LIGNE**
//Serial_Light.begin(9600);
//Serial_Dome.begin(9600);

  
// Démarre les librairies, avec les données et le nom du port Série associés
R2_Stroke.begin(details(MaTrame_Stroke), &Serial_Stroke);
R2_Sound.begin(details(MaTrame_Emission), &Serial_Sound);
R2_Light.begin(details(MaTrame_Emission), &Serial_Light);
R2_Dome.begin(details(MaTrame_Emission), &Serial_Dome);
  
  Serial.println("Carte MAIN démarrée !");
 
// Initialise l'ecran
// ... je passe cette partie pas intéressante

}


//--------------------------------------------------------------------------------------
//////////
// LOOP //
//////////

void loop() {


  if(R2_Stroke.receiveData()){
    //Pour accéder au valeur, il faut utiliser la structure [Nom de la structure].[nom de variable]. Par exemple, MaTrame.Fonction 

    // Si le stroke est un "F", il faut mettre la case Communication Stroke en Noir. SI non en Vert.
    if (MaTrame_Stroke.Fonction == 'F') {
     Serial.print("Stroke recu");
    }

Merci par avance pour votre aide. Je sèche complètement...

Mike

Pour continuer mes essais, j'ai fait l'inverse. Cette fois-ci, je force la lecture d'un son (en forçant mon mega à envoyer un son tous les 5s.

J'ai bien un son qui est envoyé toutes les 5 secondes, donc la comm en émission marche, mais pas toujours la réception...

le petit bout de code modifié (biensur en activant le R2_Sound.begin(); :

void loop() {

JoueSon('S',1,11,255,1,1);

delay(5000);

  if(R2_Stroke.receiveData()){
    //Pour accéder au valeur, il faut utiliser la structure [Nom de la structure].[nom de variable]. Par exemple, MaTrame.Fonction 

    // Si le stroke est un "F", il faut mettre la case Communication Stroke en Noir. SI non en Vert.
    if (MaTrame_Stroke.Fonction == 'F') {
     Serial.print("Stroke recu");
     
    }
/*

L'ordre d'appel des begin() a un impact sur le fonctionnement. Si j'initialise le R2_Sound avant le R2_Stroke, cela marche, mais pas dans l'autre sens.

Je ne comprend pourquoi, mais cela à l'air de tomber en marche :frowning:

Serial_Light.begin(9600);
//Serial_Dome.begin(9600);
Serial_Sound.begin(9600);
Serial_Stroke.begin(9600);

Bonsoir MikeLaMenace2005

C'est quel type d'écran qui "pique" 3 ports série sur un Mega?
Personnellement, un tel projet, je l'aurai fait en i2C.

Tu est sous Windows?

Cordialement
jpbbricole

Bonjour jpbbricole,

En fait, c'est un écran LCD classique qui n'utilise pas les pinoches (elles ne sont pas reliées electriquement), mais l'écran que j'utilise en "shield" est devant les pinoches... Je ne peux pas mettre de photo, mais mon ecran ne me laisse que les pinoches 22 à 53 de libre.

Effectivement, l'I2C aurait été plus pratique pour les "esclaves". Pourquoi pas une prochaine evolution :slight_smile:

Je travaille sous Mac. Mais, en fait, j'ouvre le dernier programme, je le modifie et j'écrase... Maintenant, le soir je fais une archive, c'est plus malin.

A+

Mike

Bonjour MikeLaMenace2005
Il faudrait que tu mettes l'entier de ton programme sur le forum, c'est plus pratique pour investiguer.

C'est assez vite fait de passer en i2C et ton câblage s'en trouverai simplifié. Quelle est la distance entre les divers modules?

Cordialement
jpbbricole