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

Raspberry Pi Discussion :

Protocole I2C smbus2 communication vers Arduino


Sujet :

Raspberry Pi

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut Protocole I2C smbus2 communication vers Arduino
    Bonjour,
    Je souhaite transmettre des informations ( valeurs integer de 0 à 65535 ) en i2c d'un raspberry pi4 vers un arduino MEGA 2560.
    J'ai installé smbus2 sur le raspberry et essayé les codes en exemple sur le net (notamment sur pypi.org), mais cela n'a pas l'air de fonctionner.
    J'ai aussi bien activé l'i2c sur le rpi. Le cablage entre arduino et Rpi est aussi correct.
    Pour info j'arrive bien a faire communiquer en i2c 2 arduinos.

    le code utilisé est le suivant :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    from smbus2 import SMBus
     
    with SMBus(1) as bus:
        data = 45
        bus.write_byte_data(8, 0, data)

    l'adresse attribuée à l'arduino est la 8. Est-ce qu'il y a quelque chose que j'aurai oublié ? un paramétrage du raspberry ? existe-t'il une commande qui me permette de vérifier que l'arduino est connecté au raspberry (i2c detect ?) ?

    Merci pour votre aide.

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Bonjour,

    Citation Envoyé par erwannoo Voir le message
    Est-ce qu'il y a quelque chose que j'aurai oublié ?
    J'espère que tu n'as pas oublié que l'Arduino est susceptible de tirer ses sorties en 5V et qu'elles peuvent être connectées à des entrées 3,3V du Pi
    A priori ça n'arrivera pas si le Pi est maître sur le bus, mais il faut faire attention...

    Il y a bien une commande i2cdetect, voir ici par exemple.
    Nom : i2c-rpi2.png
Affichages : 524
Taille : 58,3 Ko

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    Bonjour,
    Merci pour cette recommandation. Effectivement cela peut être embêtant.
    En faisant i2cdetect -y 1 j'ai bien une réponse (tableau à moitié rempli) lorsque l'Arduino est connecté et tableau vide lorsqu'il n'est pas connecté. Mais ce n'est vraiment pas parlant...

    Passer par le port série ne serait-il pas plus facile ?

  4. #4
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Citation Envoyé par erwannoo Voir le message
    Merci pour cette recommandation. Effectivement cela peut etre embetant.
    Bon, a priori il n'y a pas de soucis si le Rpi est toujours maître sur le bus et l'Arduino toujours esclave.


    Citation Envoyé par erwannoo Voir le message
    En faisant i2cdetect -y 1 j'ai bien une réponse (tableau a moitié rempli) lorsque l'arduino est connecté et tableau vide lorsqu'il n'est pas connecté. Mais ce n'est vraiment pas parlant...
    Il devrait être très parlant au contraire, sur la copie d'écran de mon message précédent j'ai aussi un composant esclave à l'adresse 0x08.
    Si tu vois le 0x08 dans le tableau, cela prouve que ton Arduino est bien identifié à cette adresse sur le bus et donc que tout va bien au niveau de la communication. Est-ce que tu vois bien l'adresse 0x08 dans le tableau ?

    Les autres adresses dans le tableau sont sans doute des composants internes au Pi qui sont aussi sur le bus (eeprom et autres).

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    bah c'est que non, il n'y a rien à l'adresse 0x08,
    mais peut-être qu'il n'est pas bien adressé coté Arduino...

    dans mon code Arduino l'attribution des adresse est de la forme :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    wire.begin(8)
    wire.request(8, ... )

    8 étant pour moi l'adresse de l'équipement... mais le format n'est peut être pas bon coté Raspberry

  6. #6
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Donc le souci premier n'est pas du côté du programme Python.
    Soit il y a un souci matériel (mais tu me dis que le câblage est correct), soit l'Arduino est mal configuré.

    Peux-tu poster le code complet côté Arduino ?

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    coté arduino, le code complet, avec la partie communication i2c dans le loop.

    Code arduino : 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
    #include <Wire.h>
    #define LED_BUILTIN 12
     
    //int pinState = LOW;                   // etat de la PIN qui sert a générer le signal carré
    char prescaler[12];            // variable d'ajustement du prescaler en fonction de la valeur de frequence
    unsigned short frequenceInt;           // frequenceInt 
     
    void setup () {
      Wire.begin();                             // join i2c bus (address optional for master)
      Serial.begin(2000000);              // terminal speed
      pinMode (LED_BUILTIN, OUTPUT);
     
      // ======================================================================================================================================================
      // Paramétrage du timer1, pour qu'il déclenche une interruption, à chaque fois que sa valeur sera égale à celle qu'on aura indiqué dans le registre OCR1A  
      // ======================================================================================================================================================
      noInterrupts();                 // On désactive les interruptions, pour commencer
      TCCR1A = 0b00000000;            
      //TCCR1B = 0b00001001;            // TCCR1B = 0b00001001 pour desactiver prescaler  et  TCCR1B = 0b00001101 pour prescaler = 1024
      TIMSK1 = 0b00000010;
     
      bitSet(TIMSK1, OCIE1A);         // On met le bit OCIE1A à 1 (contenu dans le registre TIMSK1)
     
      // Enfin, on met le compteur à zéro, on entre la valeur déclenchant l'interruption (nos "31250" coups d'horloge), et on réactive les interruptions
      TCNT1 = 0;            // Mise du timer1 à zéro
      interrupts();         // Et, on ré-active les interruptions
    }
     
     
    // ======================
    // Routine d'interruption
    // ======================
    ISR(TIMER1_COMPA_vect) {
      digitalWrite (LED_BUILTIN, !digitalRead(LED_BUILTIN));
      TCCR1B = prescaler;
      OCR1A = frequenceInt;			// mise à jour de la valeur OCR1A en fonction de la valeur envoyée par arduino master (valeur OCR1A calculée en fonction de frequence horloge, prescaler)
     
    }
     
    // =================
    // Boucle principale
    // =================
    void loop () {
      Wire.requestFrom(8, 4);         // request 6 bytes from peripheral device #8
      unsigned long value = 0;        // v = value
      int i = 0;
      while (Wire.available()) {            // peripheral may send less than requested
        unsigned long c = Wire.read();      // receive a byte and store it in unsigned long so it can be shifted later
        value |= (c << (i*8));              // shift the received byte value and store it with the previous value
        i++;
      }
     
      frequenceInt = value;                   // value
      Serial.println(frequenceInt);
      if (value<2430) {
        char prescaler[12] = "0b00001101 ";
        Serial.println("valeur inferieure à 2430");
        Serial.println(prescaler);
      }
      else {
        char prescaler[12] = "0b00001001 ";
        Serial.println("valeur supérieure à 2430");
        Serial.println(prescaler);
      }
     
    }

  8. #8
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Là il y a un souci protocolaire...

    Code arduino : Sélectionner tout - Visualiser dans une fenêtre à part
     Wire.requestFrom(8, 4);         // request 6 bytes from peripheral device #8
    Il n'y a que le composant maître (master) qui peut réclamer des données au composant esclave (slave) comme tu le fais. Ton code montre que l'Arduino est maître, et qu'il requiert des données au composant esclave à l'adresse 0x08. Et ton Rpi se comporte aussi en maître (RPi en esclave i2c doit être possible mais c'est pas prévu par défaut).
    Classiquement, le RPi est maître (est à l'initiative des demandes) et l'Arduino est esclave (répond aux demandes du maître).
    Tel quel ça ne peut pas fonctionner. Et du coup c'est même dangereux pour le Pi si les connecteurs (SDA, SCL) sont directement reliés entre eux, car l'Arduino va tirer les lignes à son 5V alors que les entrées du Pi supportent du 3,3V maxi.

    Pour comprendre le principe, on trouve des docs sur la communication i2c entre deux Arduino (1 Arduino maître et l'autre esclave) :


    Bon, va falloir aussi que j'adapte le vocabulaire maître/esclave en quelque chose de politiquement plus correct comme ces controller reader et Peripheral Sender que j'ai du mal à traduire...

  9. #9
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    Le code utilisé pour la communication des arduino provient effectivement de ces sources... mais effectivement je n'ai pas pris en compte l'adresse pour l'arduino slave..
    Cela étant, après mise à jour, la commande "i2cdetect -y 1" depuis le terminal du raspberry renvoie bien le tableau avec l'adresse de l'arduino connecté ( 08 ) ==> donc c'est top !

    De la même manière, lorsque j'execute le programme d'envoie d'une valeur, le programme me renvoie " transmit " ==> donc ça aussi c'est top !

    Par contre, l'arduino ne relit pas la valeur.. enfin pour l'instant. Certainement un problème de type...

    En tout cas, merci pour vos conseils et remarques...

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    Bonjour,

    Donc l'arduino relit bien une valeur, mais c'est bizarre, quand je suis censé envoyer la valeur 45 depuis le rasperry, l'arduino relit plusieurs valeurs... mais pas 45..

  11. #11
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut Arduino MEGA 2560 W5500 réception variable par ethernet
    Bonjour, en appliquant le code suivant, pour l'arduino 2560 Slave, ça fonctionne. J'envoie la valeur depuis le raspberry et la valeur s'affiche bien sur le moniteur de l'arduino !! cool !


    Code Arduino : 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
    #include <Wire.h>
     
    void setup()
    {
      Wire.begin(8);                // join i2c bus with address #4
      Wire.onReceive(receiveEvent); // register event
      Serial.begin(2000000);           // start serial for output
    }
     
    void loop()
    {
      delay(100);
    }
     
    void receiveEvent(int howMany)
    {
      while(1 < Wire.available()) 
      {
        char c = Wire.read(); 
        Serial.print(c);         
      }
      int x = Wire.read();    
      Serial.println(x);         
    }

  12. #12
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut Arduino MEGA 2560 W5500 réception variable par ethernet
    Question,

    comment puis-je faire pour transmettre des valeurs de 0 à 65350 ?

    Merci.

  13. #13
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Citation Envoyé par erwannoo Voir le message
    comment puis-je faire pour transmettre des valeurs de 0 à 65350 ?
    En transmettant 2 octets, octet de poids fort et octet de poids faible.
    En Python, voir la doc smbus2 (write_word_data ou write_block_data ?)

    Côté Arduino, avec deux read :

    Code arduino : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    uint16_t value = Wire.read(); // octet de poids fort en 1er
    value = value << 8 // décalage de 8 bits à gauche;
    value |= Wire.read(); // OU logique avec octet de poids faible

    Faudra modifier un peu si c'est l'octet de poids faible qui est transmis en 1er.

  14. #14
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    Merci pour vos réponses,
    Après essai, le résultat semble similaire, c'est à dire que lorsque j'envoie des valeurs entre 0 et 255 il n'y a pas de soucis (je rappelle que les valeurs sont envoyés avec le programme python du raspberry).
    programme d'envoie des valeurs :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    with SMBus(1) as bus:
        data = 254
        bus.write_byte_data(addr, 0, data)
        data = 255
        bus.write_word_data(addr, 0, data, force=None)

    par contre quand j'envoie des valeurs au dessus de 255 alors ça repart de 0.

    par exemple, pour la valeur envoyée 1244, avec le code : ça me retourne les valeurs :

    => value = 220
    => value = 220
    => value = 65535

    raspberry :
    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    with SMBus(1) as bus:
        data = 1244
        bus.write_byte_data(addr, 0, data)
        data = 1244
        bus.write_word_data(addr, 0, data, force=None)


    Code Arduino : 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
    #include <Wire.h>
     
    void setup()
    {
      Wire.begin(8);                
      Wire.onReceive(receiveEvent); 
      Serial.begin(2000000);           
    }
     
    void loop()
    {
      delay(100);
    }
     
    void receiveEvent(int howMany)
    {
      while(Wire.available()) 
      {
        uint16_t value = Wire.read();
        value |= Wire.read();
        Serial.print("=> value = ");
        Serial.println(value);
      }
    }


    en testant l'autre config, ça retourne :

    => value = 0
    => value = 56320
    => value = 0
    => value = 56320
    => value = 1024


    Code Arduino : 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
    #include <Wire.h>
     
    void setup()
    {
      Wire.begin(8);                
      Wire.onReceive(receiveEvent); 
      Serial.begin(2000000);           
    }
     
    void loop()
    {
      delay(100);
    }
     
    void receiveEvent(int howMany)
    {
      while(Wire.available()) 
      {
        uint16_t value = Wire.read();
        value = value << 8;
        Serial.print("=> value = ");
        Serial.println(value);
      }
    }

    Je ne sais pas trop quoi en penser...

  15. #15
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 324
    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 324
    Points : 4 134
    Points
    4 134
    Par défaut
    Bonjour,

    Avec le | : 1244 = 1024 + 220 = 0b0000_0100 << 8 + 0b1101_1100 donc le ou binaire fait 0b1101_1100 | 0b0000_0100 = 0b1101_1100 = 220
    Avec le << 8 : 220 << 8 = 220 * 256 = 56320 si on écrit qu'un octet , avec un word on retrouve bien sur le 56320 suivi du 0b0000_0100 << 8 soit 1024, c'est mieux

    Pourquoi ne pas utiliser howMany ?

    Par ailleurs, Wire.available() est assez mal utilisée pour récupérer deux octets. Soit il lance la lecture d'au moins 2*n octets alors que le nombre peut être impair, soit il mange tous les octets pour n'en garder qu'un seul.

    Une proposition improvisée (et non testée).

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     void receiveEvent(int howMany) {
       uint16_t  r = 0;
       for( ; howMany > 2; --howMany) r = Wire.read();    // Vider les octets en trop
       if(howMany   > 0)  r  = uint16_t(Wire.read());
       if(howMany  == 2)  r |= uint16_t(Wire.read()) << 8;
       Serial.print(r);         
    }
    On pourrait également utiliser un tableau (éventuellement circulaire) d'octets pour avoir une boucle unifiée (i.e. sans décalage). Version a minima.
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     void receiveEvent(int howMany) {
       uint8_t b[2];
       int * p = b;
       *p = 0;
       for(int i = 0 ; i < howMany; ++i) b[i & 1] = Wire.read(); // Attention ! si howMany impair *p = b[(howmany-2) & 1] << 8 + b[(howmany - 1) & 1]
       Serial.print(*p);         
    }

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  16. #16
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Bonjour,

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        data = 1244
        bus.write_byte_data(addr, 0, data)

    Je suis quand même surpris qu'un étudiant qui attaque l'I2C soit mis en difficulté par un problème de numération...

    1 byte = 1 octet = 8 bits, soit 28 valeurs entre 0 et 255 pour un entier non signé.

    1244 = (0100 1101 1100)2, et quand la fonction Python tronque la valeur avec les 8 premiers bits en rouge, tu trouves... 220 en décimal

    En fait, en reprenant tes valeurs et ton code, je suis entièrement d'accord avec tes résultats, déjà ça montre que la communication I2C est bien établie mais il faut remettre les bits et les octets dans le bon ordre...

    En plus il y a un piège, car le 2è paramètre des fonctions Python est un numéro de registre du composant esclave, paramètre toujours mis à 0 ici, mais qui fait partie de la trame envoyée.
    Quand tu écris bus.write_byte_data(addr, 0, data), il y a deux octets de données écrits sur la ligne : 0 (register address) et data.
    Trame :
    master : START SLAVE_ADDRESS+WRITE     REGISTER_ADDRESS      DATA     STOP
    slave  :                           ACK                  ACK       ACK
    
    ACK = Acquittement de l'esclave

    Guesset a déjà repéré tout ça, et je n'ai pas eu le temps de tout voir mais je reviens plus tard au besoin

  17. #17
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut raspberry protocole I2C smbus2 communication vers arduino
    Bonjour,

    Merci pour vos commentaires.

    Bon j'ai maintenant bien compris la problématique, mais la ou je bloque c'est comment identifier le 1er byte et le 2d byte dans le message reçu. En effet lorsque je code :

    Code Arduino : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void receiveEvent(int howMany)
    {
      uint16_t r=0;
      r = Wire.read();
      r = uint16_t(Wire.read());
      Serial.println(r);

    je reçois bien les valeurs 220 et 4 et correspondent bien à ce qui est écrit précédemment ... 220 : 1101 1100 et 4 : 0100
    et effectivement j'aimerai bien faire 4 | 220 pour obtenir 0000 0100 1101 1100 qui correspond en décimal à la valeur envoyée soit 1244

    la ou je galère maintenant c'est "comment identifier et différencier 220 et 4 ??" car en effet je n'arrive pas à écrire seulement 220 ou seulement 4. Le code me renvoi a chaque fois les 2 valeurs, du coup je n'arrive pas à effectuer le 4 | 220... je pense que ça ne doit pas être compliqué, mais pour moi ... cela étant je continue de chercher. Merci et bonne journée.

  18. #18
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut Arduino MEGA 2560 W5500 réception variable par ethernet
    Peut-on utiliser un paramètre pour : " Wire.available() " afin de sélectionner un byte spécifique ? ou bien avec " Wire.onReceive() " ?

    Merci.

  19. #19
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2021
    Messages
    116
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2021
    Messages : 116
    Points : 49
    Points
    49
    Par défaut Arduino MEGA 2560 W5500 réception variable par ethernet
    Bonjour,

    Je continue a chercher, sans encore arriver à obtenir la valeur de départ. Avec ce code :

    Code Arduino : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    voir receiveEvent(int howMany)
    {
     if(howMany == 2)
     {
       int r1 = Wire.read();             qui correspond à 220
       int r2 = Wire.read();             qui correspond à 4
       int valeur = r2<<8 + r1;       ça me retourne -9216 et 1024
       Serial.println(valeur);
       }
    }

    rien ne correspondant a ma valeur de départ qui est 1244... enfin je n'arrive pas a recoller les morceaux...

  20. #20
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 601
    Points : 56 698
    Points
    56 698
    Billets dans le blog
    40
    Par défaut
    Il faut utiliser des entiers non signés : uint16_t (uint pour unsigned integer) et non int.

    Et en Python il faut utiliser :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    data = 1244
    bus.write_word_data(addr, 0, data)

    Et dans ce cas-là, il y a 3 octets à récupérer : 0, 4 et 220
    Le 1er zéro est à lire mais sera ignoré.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Embarqué] Communication avec le port série vers Arduino
    Par YannGTT dans le forum Plateformes
    Réponses: 0
    Dernier message: 05/04/2020, 04h45
  2. GPRS communication vers IP par protocole TCP
    Par g_escande81 dans le forum Réseau
    Réponses: 6
    Dernier message: 31/08/2011, 04h20
  3. [EJB3] Communication vers un EJB depuis un client standalone
    Par Aldian dans le forum Java EE
    Réponses: 3
    Dernier message: 29/05/2009, 11h24
  4. Comment partager la communication vers un port USB ?
    Par petitclem dans le forum C++Builder
    Réponses: 1
    Dernier message: 07/05/2009, 15h35

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