Communication via 2 arduino

Bonsoir,

Je suis sur un projet de communication entre 2 arduino (maitre/esclave)
Le but est que l'aduino maitre demande à l'arduino esclave de lire l'état de 10 broches de fonctions puis de les renvoyer au maitre pour l'afficher sur un écran lcd.

J'ai une idée avec des variables qui stock l'info reçu sur le port de série
Arduino Maitre :

      if(radio.available()){     // Si signal radio  

      radio.read(&boitier, sizeof(boitier));    // on met la valeur reçu dans la variable "boitier"
      
      if(boitier == 1){  //Si la variable reçu egale 1, mise à jour de la variable "boitier_1"
        boitier_1 = 1;
      }
      if(boitier == 2){  //Si la variable reçu egale 1, mise à jour de la variable "boitier_2"
        boitier_2 = 1;
      }
      if(boitier == 3){  //Si la variable reçu egale 1, mise à jour de la variable "boitier_3"
        boitier_3 = 1;
      }
      if(boitier == 4){  //Si la variable reçu egale 1, mise à jour de la variable "boitier_4"
        boitier_4 = 1;
      }
      
      }
      
      if(boitier_1 == 1){     // Fonction pour le boitier 1
        lcd.setCursor(12, 0);
        lcd.write(byte(1));   // affichage de Vrai
      }
      else{
        lcd.setCursor(12, 0); 
        lcd.write(byte(2));   // affichage d'une croix     
      }

      if(boitier_2 == 1){      // Fonction pour le boitier 2
        lcd.setCursor(12, 1);
        lcd.write(byte(1));   // affichage de Vrai
      }
      else{
        lcd.setCursor(12, 1); 
        lcd.write(byte(2));   // affichage d'une croix
      }
      
      if(boitier_3 == 1){      // Fonction pour le boitier 3
        lcd.setCursor(12, 2);
        lcd.write(byte(1));   // affichage de Vrai
      }
      else{
        lcd.setCursor(12, 2); 
        lcd.write(byte(2));   // affichage d'une croix
      }

      if(boitier_4 == 1){     // Fonction pour le boitier 4
        lcd.setCursor(12, 3);
        lcd.write(byte(1));   // affichage de Vrai
      }
      else{
        lcd.setCursor(12, 3); 
        lcd.write(byte(2));   // affichage d'une croix
      }

Mais avec 10 lignes le code est immense !
Comment simplifier le code ?

Pourrait-on le faire avec une variable sur 10 bits "(B1110111010)" par exemple ? et qui chaque byte soit une broche de fonction à l'état haut ou bas ?
Si oui, comment l'appliquer à l'ecran lcd ?

Merci par avance.

Un moyen comme un autre est d'utiliser l'opérateur d'égalité ==
cet opérateur que tu utilises déjà dans le IF, prend deux opérandes et renvois un booleen.

boitier_1 = (boitier == 1);

Les parentheses sont inutiles mais, permet de rendre plus lisible l'instruction.

Tu peux aussi bien sûre utiliser un champ bit et l'opérateur binaire & ou toujours l'opérateur ==.
L'interet d'un champ bit est surtout si tu peux avoir deux boitiers selectionné en même temps.

Bonjour,

Il faut utiliser un tableau

par exemple:

Déclaration du tableau

uint8_t boitiers[10];
const int nbBoitiers = sizeof boitiers;

Programme:

  if (radio.available()) {  // Si signal radio
    int numBoitier=-1;

    radio.read(&numBoitier, sizeof numBoitier);

    if (numBoitier >= 1 && numBoitier <= nbBoitiers) {  // Vérifie que la valeur reçue est valide
      boitiers[numBoitier - 1] = 1;                     // on soustrait 1 car l'indice dans le tableau commence à 0
    }
  }

  for (int i = 0; i < nbBoitiers; i++) {
    lcd.setCursor(12, i);
    if (boitiers[i] == 1) { 
      lcd.write(byte(1));    // affichage de Vrai
    } else {
      lcd.write(byte(2));  // affichage d'une croix
    }
  }

Bonjour JustinPirolley

Tu veux dire chaque bit?

Une solution est de traduire le contenu de boitier en chaine de caractère contenant l'état de chaque bit 1 ou 0 et d'afficher cette chaine en une fois sur ton afficheur, ainsi:

word boitier = 0b1110111010;     // Valeur reçue de l'Arduino esclave
String boitierBits = "";

void setup()
{
	Serial.begin(115200);

	boitierBits = wordToBits(boitier);

	Serial.println(boitierBits);

    lcd.setCursor(12, 0);
    lcd.print(boitierBits);   // affichage des bits de boitier

}

void loop()
{
}

String wordToBits(word  wValue)
{
	String wordBits = "";

	for (int b = 0; b < 10; b ++)
		{
		if (bitRead(boitier, b) == 1)
		{
			wordBits = "1" + wordBits;
		}
		else
		{
			wordBits = "0" + wordBits;
		}
	}
	return wordBits;
}

Le résultat de la conversion est dans String boitierBits

A+
Cordialement
jpbbricole

Bonsoir,

Merci pour vos réponses

Effectivement, peut-on faire en sorte que l'esclave envoi l'état de ses broches sous forme de bit.
Exemple : 10 broches de fonction (état haut = 1 / état bas = 0) sous forme de 10 caractères (1110010110)
Et que le maitre le reçoit, contrôle chaque caractère. Puis suivant le résultat, affiche des symboles (Vrai / Croix) sur l'écran lcd (Si 1 (Vrai) / si 0 (Croix)

Le souci de l'écran lcd, c'est qu'il faut afficher le caractère suivant sur le curseur suivant (de lcd.setCursor(12, 0) à lcd.setCursor(12, 3)) dans mon cas.

Je ne suis pas encore à l'aise avec ses fonctions (String, for, ...)

Dans ton code, chaque caractère reçu fera un tour dans la boucle for, pour l'afficher sur le curseur suivant de l'écran ?

Bonsoir JustinPirolley

Pas tout à fait, l'esclave envoie un mot de 16 bits (word) dont chaque bit est le reflet de l'état d'une pin.
J'ai pas bien compris ton affichage, tu affiches l'état des 10 pin de l'esclave ou l'une après l'autre ?

A+
Cordialement
jpbbricole

Oui chaque caractère est affiché à sa place grâce à l'index i.

Si la fonction peut afficher l'état des broches d'un seul coup c'est encore mieux

Peux tu mettre ton code coté esclave, en ligne?

A+
Cordialement
jpbbricole

Je ne l'ai pas encore réalisé.
Je m'en occupe demain :grin:

Alors, à demain! :wink:

Bonne nuit
jpbbricole

1 Like

Bonsoir jpbbricole,

J'ai fais un morceau de code avec 4 broches pour l'arduino esclave.

#include <RF24.h>

const byte CEPin = 8;
const byte CSNPin = 7;

RF24 radio(CEPin, CSNPin);
uint8_t adresse[] = {0xCC, 0xCE, 0xCC, 0xCE, 0xCC};

const int Pinbroche_1 = 2;
const int Pinbroche_2 = 3;
const int Pinbroche_3 = 4;
const int Pinbroche_4 = 5;
 
/*int broche1 = 0;
int lastbroche1 = 0;
int broche2 = 0;
int lastbroche2 = 0;
int broche3 = 0;
int lastbroche3 = 0;
int broche4 = 0;
int lastbroche4 = 0;*/

int info = 0;   // variable reçu
int action = 0;   // permet d'entré ou sortie du While

int a;   // variable de Pinbroche_1
int b;   // variable de Pinbroche_2
int c;   // variable de Pinbroche_3
int d;   // variable de Pinbroche_4

int Temps_sortie = 5000;
unsigned long Temps_actuel;
unsigned long Temps_precedent = 0;
unsigned long Temps_precedent2 = 0;

void setup() {

  Serial.begin(9600);
  pinMode(Pinbroche_1, INPUT);
  pinMode(Pinbroche_2, INPUT);
  pinMode(Pinbroche_3, INPUT);
  pinMode(Pinbroche_4, INPUT);

  if (!radio.begin()) {
  Serial.println(F("radio absente!!"));  // contrôle de fonctionnent de la radio
  while (true) ; // erreur
  }

  radio.begin();
  radio.setPALevel(RF24_PA_LOW);
  radio.openReadingPipe(1, adresse);      // Fonction pour écouter
  radio.startListening();
  Serial.println(F("**** RECEPTEUR PRET ****"));

}


void loop() {

  Temps_actuel = millis();

  if(radio.available()){         // Si une info sur la radio
    
    radio.read(&info, sizeof(info));
    Serial.print("Valeur reçu ");
    Serial.println(info);
  }

  if(info == 50){   // 50 est la valeur pour la demande du contrôle des broches de fonction
    
    Temps_precedent2 = Temps_actuel;
    
    radio.setPALevel(RF24_PA_LOW);    // Fonction qui permet d'écrire sur le port de COM
    radio.openWritingPipe(adresse);
    radio.stopListening();

    action = 1;

    while (action == 1){

      a = digitalRead(2);   // a est l'état de la broche 2 (HIGH - 1 / LOW - 0)
      b = digitalRead(3);   // b est l'état de la broche 3 (HIGH - 1 / LOW - 0)
      c = digitalRead(4);   // c est l'état de la broche 4 (HIGH - 1 / LOW - 0)
      d = digitalRead(5);   // d est l'état de la broche 5 (HIGH - 1 / LOW - 0)

      radio.write(&a, sizeof(a));    // envoi la variable a
      radio.write(&b, sizeof(b));    // envoi la variable b
      radio.write(&c, sizeof(c));    // envoi la variable c
      radio.write(&d, sizeof(d));    // envoi la variable d

    Temps_actuel = millis();   // permet d'actualisé la valeur dans le while 
    
    if(Temps_actuel - Temps_precedent2 >= Temps_sortie){     // variable qui permet de sortir du While au bout de "Temps_sortie" 5000 ms
       action = 0;
       info = 0;               
       break;
       }
    }
    Temps_precedent = Temps_actuel;
    Temps_precedent2 = Temps_actuel;    
  }    

}

Bonjour JustinPirolley

J'ai "rectifié" ton programme pour le rendre plus pratique, j'ai laissé, en remarque, les lignes devenues inutiles. J'ai mis des liens pour des explications.
Tu verra que l'état de tout les bits sont envoyés en une fois au moyen de la variable PinBrochesEtats.

Pour recevoir, côté master:
déclarer une variable globale
word PinBrochesEtats = 0; // Etat des broches
et lire:
radio.read(&PinBrochesEtats, sizeof(PinBrochesEtats));

Pour rendre ces bits affichables, inspires toi du bout de programme du post#4
String wordToBits(word wValue)

Le programme:

#include <RF24.h>

const byte CEPin = 8;
const byte CSNPin = 7;

RF24 radio(CEPin, CSNPin);
uint8_t adresse[] = {0xCC, 0xCE, 0xCC, 0xCE, 0xCC};

//const int Pinbroche_1 = 2;
//const int Pinbroche_2 = 3;
//const int Pinbroche_3 = 4;
//const int Pinbroche_4 = 5;

const int Pinbroche[] {2, 3, 4, 5};  // Tableau des broches https://www.locoduino.org/spip.php?article227
const int PinbrocheNombre = sizeof(Pinbroche) / sizeof(Pinbroche[0]);  // Nombre de broches
const int PinbrocheEtatOn = LOW;  // Etat OOn de la broche
/*int broche1 = 0;
int lastbroche1 = 0;
int broche2 = 0;
int lastbroche2 = 0;
int broche3 = 0;
int lastbroche3 = 0;
int broche4 = 0;
int lastbroche4 = 0;*/

int info = 0;   // variable reçu
int action = 0;   // permet d'entré ou sortie du While
word PinBrochesEtats = 0;  // Etat des broches
//int a;   // variable de Pinbroche_1
//int b;   // variable de Pinbroche_2
//int c;   // variable de Pinbroche_3
//int d;   // variable de Pinbroche_4

int Temps_sortie = 5000;
unsigned long Temps_actuel;
unsigned long Temps_precedent = 0;
unsigned long Temps_precedent2 = 0;


void setup() {

	Serial.begin(9600);
	
	for (int p = 0; p < PinbrocheNombre; p ++)  // Initialisation des broches
	{
		pinMode(Pinbroche[p], INPUT);
	}
	////pinMode(Pinbroche_1, INPUT);
	////pinMode(Pinbroche_2, INPUT);
	////pinMode(Pinbroche_3, INPUT);
	////pinMode(Pinbroche_4, INPUT);
//
	//if (!radio.begin()) {
		//Serial.println(F("radio absente!!"));  // contrôle de fonctionnent de la radio
		//while (true) ; // erreur
	//}
//
	//radio.begin();
	//radio.setPALevel(RF24_PA_LOW);
	//radio.openReadingPipe(1, adresse);      // Fonction pour écouter
	//radio.startListening();
	Serial.println(F("**** RECEPTEUR PRET ****"));
	Serial.print(F("Nombre de broches: "));
	Serial.println(PinbrocheNombre);

}


void loop() {

	Temps_actuel = millis();

	if(radio.available()){         // Si une info sur la radio
		
		radio.read(&info, sizeof(info));
		Serial.print("Valeur reçu ");
		Serial.println(info);
	}

	if(info == 50){   // 50 est la valeur pour la demande du contrôle des broches de fonction
		
		PinBrochesEtats = PinBrochesLecture();  // Lecture des broches
		Temps_precedent2 = Temps_actuel;
		
		radio.setPALevel(RF24_PA_LOW);    // Fonction qui permet d'écrire sur le port de COM
		radio.openWritingPipe(adresse);
		radio.stopListening();

		action = 1;

		while (action == 1){

			//a = digitalRead(2);   // a est l'état de la broche 2 (HIGH - 1 / LOW - 0)
			//b = digitalRead(3);   // b est l'état de la broche 3 (HIGH - 1 / LOW - 0)
			//c = digitalRead(4);   // c est l'état de la broche 4 (HIGH - 1 / LOW - 0)
			//d = digitalRead(5);   // d est l'état de la broche 5 (HIGH - 1 / LOW - 0)

			radio.write(&PinBrochesEtats, sizeof(PinBrochesEtats));    // envoi des bit

			//radio.write(&a, sizeof(a));    // envoi la variable a
			//radio.write(&b, sizeof(b));    // envoi la variable b
			//radio.write(&c, sizeof(c));    // envoi la variable c
			//radio.write(&d, sizeof(d));    // envoi la variable d

			Temps_actuel = millis();   // permet d'actualisé la valeur dans le while
			
			if(Temps_actuel - Temps_precedent2 >= Temps_sortie){     // variable qui permet de sortir du While au bout de "Temps_sortie" 5000 ms
				action = 0;
				info = 0;
				break;
			}
		}
		Temps_precedent = Temps_actuel;
		Temps_precedent2 = Temps_actuel;
	}

}

word PinBrochesLecture()  // Retourne un word où chaque bit est le reflèt de son état
{
	word bitsLecture = 0;
	for (int p = 0; p < PinbrocheNombre; p ++)  // Initialisation des broches
	{
		if (digitalRead(Pinbroche[p]) == PinbrocheEtatOn)
		{
			bitsLecture += bitsLecture << p;  // https://www.arduino.cc/reference/cs/language/structure/bitwise-operators/bitshiftleft/
		}
	}
}

Je n'ai pas pu essayer "en vrai" :woozy_face: mais reste à ta disposition :wink:

A+
Cordialement
jpbbricole

Bonsoir,

Merci pour ta réponse jpbbricole :grin:

Je n'est pas eu le temps d'essayer ton code, avec un week end charger :partying_face:
Je te tiens au courant

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.