Communiquer entre 2 Arduinos

Bonsoir,

Pour un projet, je dois communiquer entre 2 cartes Arduino. J'ai donc trouvé sur internet un tuto qui fonctionne à merveille. Je le branche, je téléverse les deux programmes sur les deux cartes respectives, et c'est bon.
Voici les programmes:

Transmetteur

char mystr[5] = "Hello"; //String data

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  Serial.write(mystr,5); //Write the serial data
  delay(1000);
}

Recepteur

char mystr[10]; //Initialized variable to store recieved data

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  Serial.readBytes(mystr,5); //Read the serial data and store in var
  Serial.println(mystr); //Print data on Serial Monitor
  delay(1000);
}

Donc comme dit, ça fonctionne, mais moi je ne veux pas simplement transférer un texte, mais une variable quelconque, du style un voltage de batterie.

Alors j'essaie de modifier mon code:

Transmetteur

uint8_t joy = analogRead(A0); //String data

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  Serial.write(joy); //Write the serial data
  delay(1000);
}

Recepteur

uint8_t joy; //Initialized variable to store recieved data

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  Serial.read(joy); //Read the serial data and store in var
  Serial.println(joy); //Print data on Serial Monitor
  delay(1000);
}

Mais j'ai une erreur: no matching function for call to 'HardwareSerial::read(uint8_t&)'

Malheureusement, les tutos sur la toile ne foisonnent pas ! Donc si jamais vous avez un programme à vous, ou une solution, merci de votre aide :smiley:

Bonne soirée à tous !

Essayes peut-être avec la fonction :

Serial.readBytes(&joy, 1);

EDIT : encore plus simplement (parce que tu transfers qu'un octet à la fois) avec : joy=Serial.read();

supercc:
Essayes peut-être avec la fonction :

Serial.readBytes(&joy, 1);

Ça a pour fonction de lire en base une c'est ça ?
Car j'avais essayé avec DEC
Waiiit !! J'avais oublié le "&"

supercc:
EDIT : encore plus simplement (parce que tu transfers qu'un octet à la fois) avec : joy=Serial.read();

Ça par contre j'avais essayé, ça m'avait dit (dans le Serial)
255
0
0
0
0
etc...

Je pense qu'il Il faudrait que tu protèges tes read par des if(Serial.available()) { joy=Serial.read(); ... } ou que tu t'intéresses à la valeur de retour de tes read pour savoir si tu as réellement lu un octet. Le 255 c'est équivalent au -1 (quand il ne lit rien, 255 est la valeur non signée de l'octet -1), les 0 après je ne sais pas. Quand au readBytes il retourne le nombre d'octets lus donc 0 s'il échoue à lire.

D'accord,
Mais ça va faire la différence entre un 0 du joystick et un 0 (paquet vide ?)

Merci en tout cas de votre aide, j'essaie ça Demain

Vous devriez transmettre un peu plus vite: 9600 bauds est lent de nos jours et plus fiablement (une chaîne de caractères (au maximum 4+ retour lignes :6 caractères est facile à lire sur un terminal (lors du debugging), facile à tester (les caractères ne doivent être que des espaces, des '0' ...'9', des retours lignes divers (\10 et \13)
Si vous transmettez les résultats d'une conversion analogique décimale en binaire, si l'arduino recepteur n'est pas prêt et que vous perdez un (ou un nobre impair) d'octets, vous transmettrez une suite potentiellement infinie de valeurs fausses;
OTOH, si vous transmettez en ASCII (avec, certes, un foisonnement d'un facteur 3), si une ligne est fausse, la suivante sera très vraisemblablement juste (et vous pouvez *** partiellement*** detecter une ligne fausse)

dbrion06:
Vous devriez transmettre un peu plus vite: 9600 bauds est lent de nos jours et plus fiablement (une chaîne de caractères (au maximum 4+ retour lignes :6 caractères est facile à lire sur un terminal (lors du debugging), facile à tester (les caractères ne doivent être que des espaces, des '0' ...'9', des retours lignes divers (\10 et \13)
Si vous transmettez les résultats d'une conversion analogique décimale en binaire, si l'arduino recepteur n'est pas prêt et que vous perdez un (ou un nobre impair) d'octets, vous transmettrez une suite potentiellement infinie de valeurs fausses;
OTOH, si vous transmettez en ASCII (avec, certes, un foisonnement d'un facteur 3), si une ligne est fausse, la suivante sera très vraisemblablement juste (et vous pouvez *** partiellement*** detecter une ligne fausse)

Je n'ai pas trop compris comment détécter qu'une ligne est fausse ??

J'ai un peu modifié le programme, et ça me retourne ça:

⸮W⸮⸮⸮{⸮⸮⸮⸮⸮⸮⸮⸮⸮(⸮U⸮⸮⸮⸮yꄯ⸮⸮⸮ϫU⸮⸮⸮>⸮y⸮⸮U⸮⸮⸮⸮۩@⸮U⸮⸮⸮~y⸮⸮U⸮⸮⸮⸮}⸮⸮⸮⸮⸮U⸮⸮⸮⸮⸮⸮⸮U⸮⸮⸮⸮{`U⸮⸮⸮⸮⸮⸮ӫ⸮⸮⸮>⸮y⸮⸮⸮⸮⸮⸮ϫU⸮⸮⸮⸮^⸮⸮⸮⸮⸮⸮}⸮@⸮⸮⸮⸮⸮y⸮⸮շ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮ϫЫ⸮⸮⸮>⸮y⸮⸮U⸮⸮⸮⸮۩⸮⸮u⸮⸮⸮⸮⸮⸮}⸮⸮⸮⸮y⸮⸮⸮⸮⸮⸮ϫ ⸮u⸮⸮⸮⸮˩@

Je pense qu'il y a un problème de conversion, ou j'ai trouvé la solution au langage des égyptiens ? :smiley:

Voici mon code:

Transmetteur

uint8_t joy = analogRead(A0); //String data

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  map(joy, 0, 1023, 8, 0);
  Serial.write(&joy, DEC); //Write the serial data
  delay(1000);
}

Recepteur

uint8_t joy; //String data

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {

Serial.write(&joy, DEC); //Write the serial data

  if (Serial.available()) {
  Serial.println(joy);
  delay(1000);
  }
}

Transmettez en ASCII (c'est 3 à 6 fois plus lent, mais c'est -relativemnt- fiable.
Regardez ce que fait votre emetteur:
[codee]
uint8_t joy = analogRead(A0); //String data non; c'est un 16 bits tronqué à l'arrache et initialisé une fois

void setup() {
// Begin the Serial at 9600 Baud
Serial.begin(9600);
}

void loop() {
map(joy, 0, 1023, 8, 0); // il a déjà été tronqué
Serial.write(&joy, DEC); //Write the serial data
delay(1000);
}[/code]
et ce que je vois propose

// tester sur une console série à 9600 bauds
void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
Serial.println(  analogRead(A0)); // on mettra le map plus tard, quand la conversion sera comprehensible
  delay(1000);
}

D'accord, mais je ne vois pas l'intérêt, là ça va juste afficher la valeur en Analog sur la même carte, non ?

Ca va les transmettre de façon lisible, sans perdre d'info (map dégrade la mesure) (si vous transmettez des byte aleéatoires, vous aurez ... n'importe quo, et ce, vous le savez déjài) sur la liaison série; la tension analogique pourra varier d'une seconde à l'autre (votre initialisation est affreuse).

ensuite, il vous faudra écrire la partie réception pour lire sur le port série (et sauter les lignes éventuelles ayant des défauts: prenez auparavant un papier, un crayon, une gomme et dessinez 2 arduino, l'un allumé et qui transmet des octets, l'autre éteint; desinez le premier octet qui part, le second; allumez l'arduino, dessinez le troisième octet. Que voit l'arduino allumé tardivement?
Maintenant, si vous avez un retour ligne, tout rentrera dans l'ordre, sans perte d'info... sauf au démarrage)

dbrion06:
Ca va les transmettre de façon lisible, sans perdre d'info (map dégrade la mesure) (si vous transmettez des byte aleéatoires, vous aurez ... n'importe quo, et ce, vous le savez déjài) sur la liaison série; la tension analogique pourra varier d'une seconde à l'autre (votre initialisation est affreuse).

ensuite, il vous faudra écrire la partie réception pour lire sur le port série (et sauter les lignes éventuelles ayant des défauts: prenez auparavant un papier, un crayon, une gomme et dessinez 2 arduino, l'un allumé et qui transmet des octets, l'autre éteint; desinez le premier octet qui part, le second; allumez l'arduino, dessinez le troisième octet. Que voit l'arduino allumé tardivement?
Maintenant, si vous avez un retour ligne, tout rentrera dans l'ordre, sans perte d'info... sauf au démarrage)

Ok, donc dans ce cas, il faut faire 2 retours à la ligne pour ne pas lire les deux valeurs qui seront fausses c'est ça ??

Et comment écrire sur Arduino ce retour à la ligne?

Vous vous synchronisez sur les retours lignes (avant le premier retour ligne, la valeur est vraisemblablement fausse).
si les caractères reçus ne sont pas '0', '1', .... '9', \10, \13 (éventuellement, pour les deux derniers) -notez le "'"; considerer que la ligne est fausse.
PS (Post Scriptum, bien sûr; sans contre façon) : amazon ne livre -t-elle pas des crayons, bouts de papier et gommes?

Le problème, c'est que je suis un noob en communication, c'est une horreur pour moi !
J'ai littéralement passé mon après-midi à essayer de faire fonctionner ça, et je pense que je ne suis vraiment pas loin ...
J'ai tout de même réussi à recevoir des valeurs, mais aléatoires ...
Après un analogRead(A0) reçu, ça me donnait:

403
296
285
264
...

Ca à l'air de lire le A0 sur ma deuxième carte qui est normalement le recepteur, ce qui n'est pas le but (Ou alors j'ai vraiment rien compris)

Si tu veux, poste, tes 2 codes pour qu'on voit ou tu en es.

supercc:
Si tu veux, poste, tes 2 codes pour qu'on voit ou tu en es.

En fait je les ai pas enregistrés ...
j'ai l'impression que ça mène à rien à chaque fois ...

Je suis revenu au code de base...
C'est pourtant pas sorcier de remplacer un char par un int non ? ???

Ok. A la relecture de ton post initial et la la lecture des programmes j'ai un peu de mal à comprendre ce que tu cherches à faire et ou tu en es ?

Les 2 programmes que tu donnes dans le premier post ne font pas communiquer les 2 arduinos, on est d'accord ? Tes 2 arduinos n'ont pout l'instant jamais communiqué entre eux. D'ailleurs, qu'elles cartes arduinos utilises-tu ? Quels branchements comptes-tu effectuer entre les 2 arduinos ?

perso, Il faut que je sache ou tu veux aller....

Un bon tuto de Nick Gammon

supercc:
Ok. A la relecture de ton post initial et la la lecture des programmes j'ai un peu de mal à comprendre ce que tu cherches à faire et ou tu en es ?

Les 2 programmes que tu donnes dans le premier post ne font pas communiquer les 2 arduinos, on est d'accord ? Tes 2 arduinos n'ont pout l'instant jamais communiqué entre eux. D'ailleurs, qu'elles cartes arduinos utilises-tu ? Quels branchements comptes-tu effectuer entre les 2 arduinos ?

perso, Il faut que je sache ou tu veux aller....

Bah, si, ils communiquent bien apperemment ! Quand je suis sur le COM11 (récepteur), ça affiche bien la ligne de caractères que j'ai entrée dans l'arduino du COM10 (Transmetteur).

J'utilise une carte uno et une nano, mais c'est un test préliminaire à un projet plus poussé, celui de faire un drone dans son intégralité grâce à Arduino.

L'avantage de ce drone est son système FPV (= First person view). J'utilise pour celà un OSD (=On screen display) qui a pour role de "prendre" le retour vidéo de la caméra sur le drone, de rajouter du texte (ou variables :smiley: ) et l'envoyer grâce à un transmetteur (pour avoir le retour vidéo en VR).

Cet OSD là est basé sur une arduino nano cf photo jointe. Je voudrais donc envoyer les données (ex: voltage de la batterie, coordonnées GPS, vitesse, altitude, ...) de l'unité centrale (Ma carte arduino nano) à cet OSD grâce aux ports série. Je m'exerce donc d'abord sur les cartes classiques.

Pour créer cet Overlay, j'utiliserais un port FTDI (car j'ai vu qu'il fallait déssouder le processeur de ma carte donc moyen envie) et la bibliothèque MAX7456 qui est la puce de l'OSD.