Communication serie entre 2 cartes !

Bonjour à tous !

Je reviens encore une fois vous embeter avec un probleme qui parait simple (pour certains en tout cas) sauf pour moi !

commençons par ce qui fonctionne, ça sera sans doute le plus rapide :cold_sweat:

Alors actuellement, j'envois d'une carte mega à une carte uno un "int" (les cartes sont reliées avec les pins Rx et Tx croisées).
voici "une partie" du code qui fonctionne actuellement:

// COTE TRANSMISSION SUR CARTE MEGA
void setup() {
  Serial1.begin(115200);
  pinMode(2, INPUT); //Entrée état carte UNO
  }
void loop() {
  // divers calculs pour "val" que l'on doit envoyer
  
Serial1.flush();  
    Serial1.write(val & 0xFF);           
    Serial1.write((val >> 8) & 0xFF);
 while(digitalRead(2));// attend LOW. (UNO a bien reçu et va TRAITER)
 while (!digitalRead(2));// attendre HIGH. (UNO a fini)
}



//COTE RECEPTION SUR CARTE UNO
void setup() {
  Serial.begin(115200);
  pinMode(3, OUTPUT); //Sortie état carte
  digitalWrite(3, HIGH); //Carte prête
  }
void loop() {
 while (Serial.available() <2 ); 
  int val = (Serial.read() + (Serial.read() << 8 ));
  digitalWrite(3, LOW); delay(10); //confirme à la MEGA(pin2) qu'on a bien reçu 
  //
  //
  // JE FAIS CE QUE J'AI A FAIRE AVEC "val"
  //
  //
  digitalWrite(3, HIGH);  //DIS A LA MEGA QUE L'OPERATION EST TERMINEE
  
}

je reçois bien mon "int", et je bloque le deroulement sur la MEGA tant que la UNO n'a pas fini (je sais ça fait dresser les poils de certains d'attendre mais cela me va bien.

mon problème est maintenant d'envoyer un "int" supplémentaire dans la meme sequence, c'est à dire que la UNO attendra d'avoir reçu les 2 "int" avant de traiter.
Je précise que le 1° "int" variera entre -10000 et +10000 et le 2° de 1 à 100.

J'ai bien parcouru les topics qui parlent de chaine à envoyer, mais ça me met la chair de poule rien que d'y penser..

voila donc si quelqu'un pourrait m'éclairer en m'expliquant bien comment procéder, et si on pourrait eventuellement supprimer le dialogue par E/S pour confirmer et le remplacer par la transmission série..

l'envoi d'infos n'est vraiment pas mon fort, et le traitement de chaines non plus !!

merci d'avance..

salut a toi,

à mon avis moi j'aurai fait une chaine de byte et je l'aurai rempli avec tes valeur regarde :

 Serial1.write(val & 0xFF);           
    Serial1.write((val >> 8) & 0xFF);

//-------------------

byte val[8]={0x00};

val[0]=val1 & 0xFF;
val[1]=(val1>>8) & 0xFF;
val[2]=(val1>>16) & 0xFF;//grosse valeur
val[3]=(val1>>24) & 0xFF;

val[4]=val2 & 0xFF;
val[5]=(val2>>8) & 0xFF;//petite valeur

et donc apres:

val1=recu[0] +recu[1]<<8+recu[2]<<16+recu[3]<<24;
val2=recu[4]+recu[5]<<8

et quand tu fait read tu mets un tableau de byte = serial.read(); .. j'éspere que ca te va :s

Skizo !

Merci beaucoup Skizo, expliqué comme ça, le principe me parait comprehensible,

par contre pourrais-tu developper un peu plus ?

je ne demande pas forcément le code complet je te rassure, mais avec mon niveau, il me faudrait un peu plus d'explications :slight_smile:

merci !

lol pas de souçi, quand tu fait un write il y a un read qui va avec, si tu write un tableau de byte de 12 il y aura 12 byte qui arriverons de l'autre coté, donc tu compose une tram (tableau de byte) en placan tes variable les une après les autre et quand tu reçois tu décompose ta tram et tu récupère tes variables la je t'ai fait composition décomposition de tram te reste plus qu'a les placer dans un read ou un write maintenant..

ca te va? sinon précise ce qu'il te manque.

skizo !

re! merci de ces réponses si rapides !

je comprends la suite de char que tu me décris,mais c'est le "reste à placer ça dans un write/ read qu'il me manque en fait :grin:

Une fois que j'aurai enfin compris les communications en série ça sera un grand soulagement pour moi, (et mes boutons disparaitrons !)

Que c'e'st compliqué et prise de tête :wink:

Utilise un tableau ou une structure.

Avec une structure, tu peux mélanger plusieurs types :

struct MaStructure
{
  int entier1;
  int entier2;
  float un_flottant;
  char chaine[10];
} trame;

et tu envoi avec :

Serial.write( (uint8_t*)&trame, sizeof(trame) );

et tu reçoit avec

Serial.readBytes( (char*)&trame, sizeof(trame) );

C'est pas plus lisible ?

Mais de toute façon tu es partit pour une transmission non fiable : pas de synchro, pas de vérification.
Au moindre défaut sur la liaison série, tu t'envoie en l'air.

Jette un coup d'oeil sur mon tutu sur les protocoles de communication.

Salut barbudor, j'ai regardé ton tuto,

alors j'ai bien compris la partie gestion du temps mais j'ai du mal sur les transmissions !!
et oui je suis peut être parti sur une liaison pas top car je découvre juste le série...

Je veux bien faire une liaison tip top mais il faut m'expliquer de A à Z..

merci à toi et à ceux qui veulent bien m’éclairer.

par exemple

Serial.write( (uint8_t*)&trame, sizeof(trame) );

c'est du chinois pour moi..

La fonction write() à plusieurs formes.

write( char c ) pour envoyer un char
write( uint8_t *ptr , int nbbytes ) pour envoyer un ensemble d'octets dont ptr est le pointeur et nbbytes le nombre d'octets

Donc &trame est le pointeur sur la structure trame. Mais le pointeur sur trame est du type struct MaStructure *
Donc je fais un "cast" (changement de type forcé) de pointeur sur MaStructure en pointeur sur uint8_t sui tes le type attendu par l'autre forme de write afin d'envoyer tous les octets d'un coup. (Enfin, les uns derrière les autres).

Bonjour,

La méthode du "découpage" du type en une suite d'octets à la main est lourde, mais permet de faire communiquer deux systémes pouvant avoir une architecture différente (µc 8 bits qui envoi, avec µc 32 bit qui reçois) car tu découpe et recolle les morceaux toi même.

La méthode du cast de pointeur sur structure vers un pointeur de tableau de byte est beaucoup plus simple mais attention, le compilateur aime bien les nombre pairs, une structure telle que celle ci :
struc {
uint32_t aa; // 2 octets
uint32_t aa;
uint8_t aa; // 1 octets
} Test_t;

Ne fera pas 2 + 2 + 1 = 5 octets mais 6 octets ! (c'est ce que l'on appelle le padding).

Il y aura donc des données caché en plus a envoyer, et la taille, disposition, alignement de la structure dépendra directement du compilateur et de l'architecture utilisé.

Il existe une librairie qui permette de communiquer entre deux carte arduino de manière simple :

La seul vrai solution reste de concevoir son propre protocole, avec (c'est mieux) une checksum pour valider la bonne réception des données.

skywodd:
La seul vrai solution reste de concevoir son propre protocole, avec (c'est mieux) une checksum pour valider la bonne réception des données.

Et une synchro pour se recaler en cas de perte.

barbudor:
Et une synchro pour se recaler en cas de perte.

Un entête sur chaque début de paquet et hop :grin:

Re !

Merci à tous pour votre aide, je regarde le traitement de chaine de char, les structures aussi, je comprends le fonctionnement mais faut pratiquer :wink:

J'ai regardé aussi la lib easy transfert, qui est facile à utiliser, mais il faudrait l’intégrer dans une autre lib, ça doit être faisable..

En tout cas je comprends bien le principe, étant donné que dans mon travail je fais souvent dialoguer plusieurs machines automatisées
(ligne d'assemblage oblige), mais j'ai encore du mal avec les char et tout..

merci bien ça avance en tout cas !!