IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

ESP32 Arduino Nano et radio nRF24


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut ESP32 Arduino Nano et radio nRF24
    Bonjour à tous

    J'essaie de transmettre une structure entre un ESP32 et un Arduino Nano via une connexion radio nRF24. A la réception, les données sont changées!
    Si je fais la même chose, mais entre 2 Arduino Nano, avec les mêmes programmes, tout fonctionne très bien?

    Voici le programme de l'émetteur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
     
    //===================================== RF24
    #define rf24CePin 9  // Nano
    #define rf24CsnPin 10
    //#define rf24CePin 16   // ESP32 Rev1
    //#define rf24CsnPin 17
     
    RF24 radioRF24(rf24CePin, rf24CsnPin);
    const uint64_t rf24PipeAddressTx = 0xFDB975468ACE0000LL;             // Pipes addresses.
    const uint64_t rf24PipeAddressRx = 0xFDB975468ACE0001LL;
     
    unsigned long rf24TempoTimer = millis();
    //------------------------------------- RF24 packet definition
    struct rf24PacketDef
    {int packetIndex; long packetPayloadLong; float packetPayloadFloat; char packetPayloadStr[25];};
    rf24PacketDef rf24PackTx;
     
    void setup() {
    	Serial.begin(115200);
     
    	radioRF24.begin();
    	radioRF24.setPALevel(2);
    	radioRF24.setChannel(112);
    	radioRF24.setPayloadSize(sizeof(rf24PackTx)+2);
    	radioRF24.setDataRate(RF24_250KBPS);
     
    	radioRF24.openWritingPipe(rf24PipeAddressTx);        // Both radios listen on the same pipes by default, and switch when writing
    	radioRF24.openReadingPipe(1,rf24PipeAddressRx);
     
    	radioRF24.startListening();
    }
     
    void loop()
    {
    	if (millis()-rf24TempoTimer > 1000)
    	{
    		rf24PackTx.packetIndex ++;
    		Serial.println("\nSent Structure #" + String(rf24PackTx.packetIndex));
    		rf24PackTx.packetPayloadLong = 32768 - rf24PackTx.packetIndex;
    		rf24PackTx.packetPayloadFloat = (float)rf24PackTx.packetIndex/3.14;
    		String messagePLstr = "PlStr packet #" + String(rf24PackTx.packetIndex);
     
    		messagePLstr.toCharArray(rf24PackTx.packetPayloadStr, sizeof(rf24PackTx.packetPayloadStr));
     
    		radioRF24.stopListening();
    		radioRF24.write( &rf24PackTx, sizeof(rf24PackTx) );
    		radioRF24.startListening();
     
    		Serial.print("Packet Index =\t");
    		Serial.println(rf24PackTx.packetIndex);
    		Serial.print("Payload Long =\t");
    		Serial.println(rf24PackTx.packetPayloadLong);
    		Serial.print("Payload Float =\t");
    		Serial.println(rf24PackTx.packetPayloadFloat);
    		Serial.print("Payload Str =\t");
    		Serial.println(rf24PackTx.packetPayloadStr);
     
    		rf24TempoTimer = millis();
    	}
    }
    Ici le programme du récepteur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
     
    //===================================== RF24
    #define rf24CePin 9  // Nano
    #define rf24CsnPin 10
    //#define rf24CePin 16   // ESP32 Rev1
    //#define rf24CsnPin 17
     
    RF24 radioRF24(rf24CePin, rf24CsnPin);
    const uint64_t rf24PipeAddressTx = 0xFDB975468ACE0000LL;              // Pipes addresses base.
    const uint64_t rf24PipeAddressRx = 0xFDB975468ACE0001LL;              // Pipes addresses base.
     
    unsigned long rf24TempoTimer = millis();
    //------------------------------------- RF24 packet definition
    struct rf24PacketDef
    {int packetIndex; long packetPayloadLong; float packetPayloadFloat; char packetPayloadStr[25];};
    rf24PacketDef rf24PackRx;
     
    void setup() {
    	Serial.begin(115200);
     
    	radioRF24.begin();
    	radioRF24.setPALevel(2);
    	radioRF24.setChannel(112);
    	radioRF24.setPayloadSize(sizeof(rf24PackRx)+2);
    	radioRF24.setDataRate(RF24_250KBPS);
     
    	radioRF24.openWritingPipe(rf24PipeAddressRx);        // Both radios listen on the same pipes by default, and switch when writing
    	radioRF24.openReadingPipe(1,rf24PipeAddressTx);
     
    	radioRF24.startListening();                                    // Now, continue listening
    }
     
    void loop()
    {
    	if( radioRF24.available())
    	{
    		Serial.println("\nReceives structure ");
    		radioRF24.read( &rf24PackRx, sizeof(rf24PackRx) );
     
    		Serial.print("Packet Index =\t");
    		Serial.println(rf24PackRx.packetIndex);
    		Serial.print("Payload Long =\t");
    		Serial.println(rf24PackRx.packetPayloadLong);
    		Serial.print("Payload Float =\t");
    		Serial.println(rf24PackRx.packetPayloadFloat);
    		Serial.print("Payload Str =\t");
    		Serial.println(rf24PackRx.packetPayloadStr);
    	}
    }
    Les traces de l'émission et de la réception.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    //------------------------------------- Envoyé depuis un Arduino Nano ou  ESP32
    Sent Structure #1
    Packet Index =	1
    Payload Long =	32767
    Payload Float =	0.32
    Payload Str =	PlStr packet #1
     
    Sent Structure #2
    Packet Index =	2
    Payload Long =	32766
    Payload Float =	0.64
    Payload Str =	PlStr packet #2
     
    Sent Structure #3
    Packet Index =	3
    Payload Long =	32765
    Payload Float =	0.96
    Payload Str =	PlStr packet #3
     
    Sent Structure #4
    Packet Index =	4
    Payload Long =	32764
    Payload Float =	1.27
    Payload Str =	PlStr packet #4
     
    Sent Structure #5
    Packet Index =	5
    Payload Long =	32763
    Payload Float =	1.59
    Payload Str =	PlStr packet #5
     
    //------------------------------------- Reçus avec un Arduino Nano à l'émission
    Receives structure 
    Packet Index =	1
    Payload Long =	32767
    Payload Float =	0.32
    Payload Str =	PlStr packet #1
     
    Receives structure 
    Packet Index =	2
    Payload Long =	32766
    Payload Float =	0.64
    Payload Str =	PlStr packet #2
     
    Receives structure 
    Packet Index =	3
    Payload Long =	32765
    Payload Float =	0.96
    Payload Str =	PlStr packet #3
     
    Receives structure 
    Packet Index =	4
    Payload Long =	32764
    Payload Float =	1.27
    Payload Str =	PlStr packet #4
     
    Receives structure 
    Packet Index =	5
    Payload Long =	32763
    Payload Float =	1.59
    Payload Str =	PlStr packet #5
     
    Receives structure 
    Packet Index =	6
    Payload Long =	32762
    Payload Float =	1.91
    Payload Str =	PlStr packet #6
     
    //------------------------------------- Reçus avec un ESP32 à l'émission
    Receives structure 
    Packet Index =	1
    Payload Long =	2147418112
    Payload Float =	0.00
    Payload Str =	?>PlStr packet #1
     
    Receives structure 
    Packet Index =	2
    Payload Long =	2147352576
    Payload Float =	0.00
    Payload Str =	#?PlStr packet #2
     
    Receives structure 
    Packet Index =	3
    Payload Long =	2147287040
    Payload Float =	-0.00
    Payload Str =	t?PlStr packet #3
     
    Receives structure 
    Packet Index =	4
    Payload Long =	2147221504
    Payload Float =	0.00
    Payload Str =	??PlStr packet #4
     
    Receives structure 
    Packet Index =	5
    Payload Long =	2147155968
    Payload Float =	ovf
    Payload Str =	??PlStr packet #5
    Merci par avance de votre aide.

    Cordialement
    jpbbricole

  2. #2
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 624
    Par défaut Entier petits et gros
    Bonjour,

    Quand on regarde les 3 premiers longs en hexadécimal on observe ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Réçus depuis Nano   Réçus depuis ESP32
       32767 soit 0x7FFF   2147418112 soit 0x7FFF0000
       32766 soit 0x7FFE   2147352576 soit 0x7FFE0000
       32765 soit 0x7FFD   2147287040 soit 0x7FFD0000
    Donc finalement cela ne semble pas si grave. Mais d'où viennent tous ces 0000 ?
    Ce n'est pas une histoire de Big ou Little endians car les changements seraient des inversion de l'ordre des octets pas des mots de 16 bits.

    Je crois que packetIndex est défini comme int (ou unsigned). Il en résulte l'émission de 2 octets pour le Nano et 4 octets pour l'ESP32. En réception, le Nano attend 2 octets quelque soit l'émetteur. Pas de problème avec une émission Nano, mais avec une émission depuis un ESP32 il reste 2 octets (à zéro ici) qui seront interprétés comme la partie basse du long suivant. Et ainsi de suite pour les suivants.

    A vérifier.

    Salutations

  3. #3
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonjour
    Merci à vous deux
    Dans ma GRANDE naïveté j'ai cru que tout ça était transparent...
    Citation Envoyé par Guesset Voir le message
    En réception, le Nano attend 2 octets quelque soit l'émetteur. Pas de problème avec une émission Nano, mais avec une émission depuis un ESP32 il reste 2 octets (à zéro ici) qui seront interprétés comme la partie basse du long suivant. Et ainsi de suite pour les suivants.
    Citation Envoyé par Jay M Voir le message
    Faire imprimer un sizeof() de la structure des 2 cotés finira par confirmer que le int est bien en cause (2 octets versus 4) ou du padding intempestif sur architecture 32 bits
    Vaut mieux figer les choses dans les structures en utilisant des types de longueur connue - uint8_t, uint16_t, uint32_t,... et déclarer la structure en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct __attribute((__packed__)) xxx_t{ ....};
    Voire forcer l’alignement sur x octets
    J'ai transformé les variables de int et long à uint16_t et uint32_t, ça donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Avant
    Taille des variables ESP32
    rf24PackRx	48
    varInt		4 (int)
    varLong		4
    varUnsignedLong	4
    varFloat		4
    varArrayChar25	25
     
    Après
    Taille des variables ESP32
    rf24PackRx	48
    varInt		2 (uint16_t)
    varLong		4
    varUnsignedLong	4
    varFloat		4
    varArrayChar25	25
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Taille des variables Nano
    rf24PackRx	38
    varInt		2
    varLong		4
    varUnsignedLong	4
    varFloat		4
    varArrayChar25	25
    On voit du côté ESP32 la variable int a perdu 2 en longueur comme indiqué par @Guesset.
    Par contre, si l'on regarde la taille de la structure rf24PackRx, elle fait 38 côté Nano et 48 du côté ESP32?

    Je vais modifier mon programme et vous redonne des nouvelles.
    Encore merci!

    Cordialement
    jpbbricole

  4. #4
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    Faire imprimer un sizeof() de la structure des 2 cotés finira par confirmer que le int est bien en cause (2 octets versus 4) ou du padding intempestif sur architecture 32 bits

    Vaut mieux figer les choses dans les structures en utilisant des types de longueur connue - uint8_t, uint16_t, uint32_t,... et déclarer la structure en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct __attribute((__packed__)) xxx_t{ ....};
    Voire forcer l’alignement sur x octets

  5. #5
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    Bonsoir JP
    Par contre, si l'on regarde la taille de la structure rf24PackRx, elle fait 38 côté Nano et 48 du côté ESP32?
    Si otre structure est définie ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct rf24PacketDef {
      uint16_t packetIndex; 
      long packetPayloadLong;
      float packetPayloadFloat; 
      char packetPayloadStr[25];
    };
    Sans attributs packed ou voire d’alignement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     struct __attribute__((packed, aligned(4)))  {...}
    Vous laissez au compilateur le soin d’organiser les octets comme il le veut en mémoire

    Sur certaines architectures 32 bits c’est plus rapide de lire des données si elles sont alignées sur un multiple de 32 voire 64 bits, car les registres et le pointeur mémoire sont optimisés pour cela et le compilateur peut donc rajouter des octets vides après les données, voire réorganiser les variables au sein de la structure. Dans ce cas l’entier sur 16 bits serait bien sûr 2 octets mais les 2 octets après seraient ignorés. De même le buffer de caractères pourrait être étendu afin que la prochaine structure mémoire tombe bien sur une frontière de mots

    Pour savoir quelle organisation a été retenue imprimez l’adresse mémoire de chacune des variables de la structure ainsi que l’adresse du début de la structure. ça vous permettra de voir ce qu’il en est. Une adresse sur le Nano sera sur 16 bits et sur l’ESP sur 32 bits mais vous pouvez l’imprimer sur 32 bits dans les 2 cas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Serial.println((uint32_t) &(rf24PackRx)); // l’adresse de la structure
    Serial.println((uint32_t) &(rf24PackRx. packetIndex)); // celle du champ packetIndex
    Serial.println((uint32_t) &(rf24PackRx. packetPayloadLong)); // celle du champ packetPayloadLong
    Serial.println((uint32_t) &(rf24PackRx. packetPayloadFloat)); // celle du champ packetPayloadFloat
    Serial.println((uint32_t) &(rf24PackRx. packetPayloadStr)); // celle du champ packetPayloadStr

    Bien sûr elles ne seront pas rangées à la même adresse mais vous verrez l’offset par rapport au début de la structure pour chaque champ

    Je suis sur ma tablette donc je ne peux pas tester

    Les attributs packed et align vous permettent de demander au compilateur de ne pas rajouter d’espaces, de ne pas changer l’ordre ou de forcer un certain alignement , donc ça vaut le coup si vous voulez être tranquille entre 2 architectures différentes

  6. #6
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonsoir Jay M

    Merci, SUPER boulot! je vais étudier ces attributs.

    Cordialement
    jpbbricole

  7. #7
    Membre Expert
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 017
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 1 017
    Par défaut
    Bonjour!
    Ca
    Citation Envoyé par Jay M Voir le message
    Vaut mieux figer les choses dans les structures en utilisant des types de longueur connue - uint8_t, uint16_t, uint32_t,...
    plus ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     struct __attribute__((packed, aligned(4)))  {...}
    = la formule magique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct __attribute__((packed, aligned(4))) rf24PacketDef
    {uint8_t msIndexInNet;
     uint8_t packetIndex;
     uint8_t packetFunction;
     uint32_t packetPayloadLong;
     float packetPayloadFloat;
     char packetPayloadStr[20];};
    Et ça fonctionne.

    Merci à vous tous.

    Bon dimanche (Chez nous, un vent à décorner les c...s!)
    Cordialement
    jpbbricole

Discussions similaires

  1. Conflit Arduino nano "clone" Yosemite 10.10.5
    Par Kogoro dans le forum Arduino
    Réponses: 0
    Dernier message: 20/06/2017, 12h57
  2. Réponses: 5
    Dernier message: 27/04/2017, 09h44
  3. A propos de LED_BUILTIN sur Arduino Nano
    Par Chamac dans le forum Arduino
    Réponses: 10
    Dernier message: 10/01/2017, 11h59
  4. Réponses: 8
    Dernier message: 23/12/2016, 19h06
  5. Thermocouple avec Arduino Nano v3.0
    Par redui dans le forum Arduino
    Réponses: 13
    Dernier message: 13/12/2016, 12h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo