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 :

La librairie IRremote.


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut La librairie IRremote.
    Salut,

    J'ouvre ce fil pour "discuter" sur la librairie IRremote...
    J'ai vu qu'il y avait déjà ce fil : Problèmes nouvelle librairie IRremote version 3.0 mais je ne voulais pas faire de HS.

    ----------

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    J'ai une première question au sujet de la fonction bool IRrecv::decodeNEC ici.

    Regardez cette condition (ligne 188) : if (decodedIRData.rawDataPtr->rawlen == 4) si elle vraie on quitte forcément la fonction soit à la ligne 194 :return false; soit à la ligne 196 return true;, non ?

    Si oui alors à quoi sert cette partie (ligne 207):
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
        // Check for repeat
        if (decodedIRData.rawDataPtr->rawlen == 4) {
            if (MATCH_MARK(decodedIRData.rawDataPtr->rawbuf[3], NEC_BIT_MARK)) {
                decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST;
                decodedIRData.address = lastDecodedAddress;
                decodedIRData.command = lastDecodedCommand;
                return true;
            }
            return false;
        }

    C'est la même condition (que celle en ligne 188) or si on arrive à la ligne 207 c'est que cette condition est forcément fausse et donc je ne vois pas l’intérêt de ce bout de code ci-dessus (ligne 207)...

    Quelque chose doit m'échapper...

  3. #3
    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
    votre lien ne fonctionne pas

    Parlez Vous de ce fichier ir_NEC.cpp?

    vos N° de lignes ne correspondent pas à ceux de GitHub (votre if semble être ligne 184)

    pouvez vous clarifier?

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci.
    Citation Envoyé par Jay M Voir le message
    Parlez Vous de ce fichier ir_NEC.cpp?
    Oui mais c'est celui-là ici qui correspond au zip que j'ai téléchargé version 3.0.1...

    Ah je ne comprend pas les fichiers sont différents...

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    Ah ben j'ai une autre question à propos de la variable irparams...

    Apparemment la structure irparams_struct est définie ici :
    Code c++ : 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
    struct irparams_struct {
        // The fields are ordered to reduce memory over caused by struct-padding
        volatile uint8_t StateForISR;   ///< State Machine state
        uint8_t IRReceivePin;           ///< Pin connected to IR data from detector
        uint8_t FeedbackLEDPin;         ///< if 0, then take board specific FEEDBACK_LED_ON() and FEEDBACK_LED_OFF() functions
        bool LedFeedbackEnabled;        ///< true -> enable blinking of pin on IR processing
    #if RAW_BUFFER_LENGTH <= 255        // saves around 75 bytes program space and speeds up ISR
        uint8_t rawlen;                 ///< counter of entries in rawbuf
    #else
        unsigned int rawlen;            ///< counter of entries in rawbuf
    #endif
        uint16_t TickCounterForISR;     ///< Counts 50uS ticks. The value is copied into the rawbuf array on every transition.
        bool OverflowFlag;              ///< Raw buffer OverflowFlag occurred
        uint16_t rawbuf[RAW_BUFFER_LENGTH]; ///< raw data / tick counts per mark/space, first entry is the length of the gap between previous and current command
    };
     
    extern struct irparams_struct irparams;

    On a ensuite une instance de cette structure ici :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #include "IRremoteInt.h"
     
    struct irparams_struct irparams; // the irparams instance

    Mais j'aimerais savoir quand le champs StateForISR est initialisé ?
    Apparemment il vaut 0 au départ mais est-ce parce que c'est la valeur par défaut ?

    On utilise irparams quand on lance la fonction IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);, la fonction begin est définie ici :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void IRrecv::begin(uint8_t aReceivePin, bool aEnableLEDFeedback, uint8_t aFeedbackLEDPin) {
     
        irparams.IRReceivePin = aReceivePin;
        irparams.FeedbackLEDPin = aFeedbackLEDPin; // default is 0
        LEDFeedback(aEnableLEDFeedback);
     
        enableIRIn();
    }

    J'ai lu que lorsque un des champs d'une structure était initialisée les autres champs étaient "automatiquement" initialisés à 0 or ici c'est ce qu'on a à la première ligne : irparams.IRReceivePin = aReceivePin;...

    Mais bon j'ai fait un test et avant cette ligne on a déjà le champs StateForISR qui vaut 0 !

  6. #6
    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
    Une structure en variable globale est initialisée à 0 sauf si des valeurs sont données à la déclaration / définition (comme toute variables globale. Ce n’est pas le cas des variables locales). Ici il n’y en a pas donc le compilateur initialise tout la zone memoire de la structure à 0

    Lorsque vous affectez un membre de la structure ensuite dans une fonction/méthode comme begin, rien d’autre n’est touché (heureusement !!)

    StateForISR est utilisé lors des interruptions pour conserver l’état courant.

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci.

    Citation Envoyé par Jay M Voir le message
    Une structure en variable globale est initialisée à 0 sauf si des valeurs sont données à la déclaration / définition (comme toute variables globale. Ce n’est pas le cas des variables locales). Ici il n’y en a pas donc le compilateur initialise tout la zone memoire de la structure à 0
    Oui c'est ce que j'ai constaté et cela me semble logique mais j'ai été induit en erreur en lisant certaines réponses d'un autre forum, en gros j'avais compris que la règle pour les structures est la même que pour les variables primitives: en l'absence d'initialisation elles seraient indéfinies et un bon compilateur devrait lancer un avertissement si on utilise une variable avant qu'elle ne soit initialisée...

    Mais j'ai fait un test et le compilateur ne dit rien...

    Citation Envoyé par Jay M Voir le message

    Lorsque vous affectez un membre de la structure ensuite dans une fonction/méthode comme begin, rien d’autre n’est touché (heureusement !!)
    Oui heureusement !

    Citation Envoyé par Jay M Voir le message
    StateForISR est utilisé lors des interruptions pour conserver l’état courant.
    Oui j'ai vu ça et elle a changé de nom récrément... La librairie est active on a déjà plusieurs nouvelles versions depuis mon premier téléchargement...

  8. #8
    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
    un bon compilateur devrait lancer un avertissement si on utilise une variable avant qu'elle ne soit initialisée...
    comme c’est une variable globale elle est bien initialisée à 0, donc c’est normal de ne pas avoir de warning.

    Oui du changement en cours pour cette bibliothèque, c’est un peu dommage car ça va casser pas mal d’anciens codes. Ils auraient dû faire une version avec un nom différent

  9. #9
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par Jay M Voir le message
    Oui du changement en cours pour cette bibliothèque, c’est un peu dommage car ça va casser pas mal d’anciens codes. Ils auraient dû faire une version avec un nom différent
    Ouais du coup certains tuto se retrouvent vite dépassés, on peut voir que c'est une ancienne version de la lib qui est utilisée dans tel ou tel tuto...

  10. #10
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    J'ai encore une question...

    J'ai placé des Serial.print() dans les trois constructeurs de la classe IRrecv (cf. irReceive.cpp.h) ainsi que dans la méthode begin ... Mais seul le Serial.print() de la méthode IRrecv::begin est exécutée... Comment cela se fait-il ? Est-ce que cela signifie qu'aucun des trois constructeurs n'est exécutés ? Est-ce possible ?

    Merci.

  11. #11
    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
    Les constructeurs sont appelés avant que Serial soit activé dans le setup.

    C’est pour cela qu’il ne faut rien mettre dans les constructeurs qui dépende du hardware, et que l’on met cela dans begin() pour les bonnes bibliothèques (quand la classe est prévue d’être instanciée comme variable globale).

  12. #12
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci.

    Citation Envoyé par Jay M Voir le message
    Les constructeurs sont appelés avant que Serial soit activé dans le setup.
    Ouais je me suis aussi dit ça... Au début je croyais qu'on n'avait pas ce problème puisque Serial.begin(2000000); est placé avant IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); mais en fait je suppose que le constructeur est exécuté avant à cause du #include<IRremote.h> qui au début du fichier...

    J'ai aussi mis Serial.begin(2000000); dans les constructeurs mais cela ne fonctionne pas non plus...

    Ce qui m'étonne c'est qu'aucune erreur n'est signalée...

    Sinon oui finalement j'ai pu voir l'exécution du constructeur en déclarant une autre variable : IRrecv IrReceiver1; (à la place de IRrecv IrReceiver;), la déclaration étant placée après le #include<IRremote.h>...

  13. #13
    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
    Il n’y a pas d’erreur informatique si vous appelez Serial dans le constructeur mais ça ne sert à rien car init() n’a pas encore été appelé et donc ce que vous faites et qui touche au hardware peut être Ensuite défait.

    Ce n’est pas lié à la place dans le fichier mais vraiment au fonctionnement du C++.

    Quand vous déclarez une variable globale, l’allocation de sa mémoire se fait au tout début du code généré par le compilateur. Pour l’instance d’une classe ça veut dire que la mémoire est allouée dans le segment dédié aux données et le constructeur est appelé pour initialiser l’objet. Tout cela se passe avant même que main() ne soit appelé et donc avant l’execution de init() de la carte et bien avant donc le setup().

  14. #14
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci.

  15. #15
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut
    Bonjour,

    Je possède ces petits modules Infrarouge : https://www.amazon.fr/gp/product/B07...?ie=UTF8&psc=1

    Je pense utiliser les deux modules pour réaliser l'identification de quelques unes de mes télécommandes et des tests sur un Arduino dédié à cet usage.

    Ensuite, je compte utiliser seulement le module émetteur infrarouge sur mon server Arduino qui sera déjà bien "chargé" (shield Ethernet, RTC, ...)

    Il est probable que j'adapte la bibliothèque pour avoir une version simplifiée uniquement pour l'émission.

    Quelques petites choses m'inquiètent un peu :
    - usage d'une broche PWM en modifiant sa fréquence de base
    - usage hardware d'un timer
    - usage des interruptions (mais ce n'est que pour la réception donc à priori pas de problèmes)

    Il faudra être prudent et "encadrer" le fonctionnement du module infrarouge pour ne pas perturber le fonctionnement des autres périphériques connectés à l'Arduino :
    - initialiser les bons paramètres avant une émission IR
    - restaurer les paramètres "normaux" après une émission IR

    Etant donné que je vais simplement "copier et coller" certaines fonctions de mes télécommandes, je pense que je n'aurais pas besoin de connaitre le protocole ; juste trouver un moyen efficace et fiable d'enregistrer la liste des impulsions et leur durée.

    A bientôt

  16. #16
    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
    bravo - oui quand la place vient à manquer, aller faire un tour dans les bibliothèques et éliminer ce qui n'est pas pertinent pour son projet permet parfois de gagner pas mal de place.

  17. #17
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut
    Oui c'est nécessaire mais pas évident...

    Les développeurs de bibliothèques sont visiblement tous passés sur des cartes puissantes (ESP32...), on le voit car les versions anciennes occupaient beaucoup moins de place en flash et en RAM.

    Le pire c'est les fonctions de débug éparpillées partout (serial.print(), allumage de LEDs...) elles bouffent beaucoup de ressources, ça peut être utile certes mais il faudrait deux versions de bibliothèque :
    - une débug pour apprendre
    - une release pour la production

    Pour IR Remote, il faut ouvrir tous les fichiers source avec NotePad++ sans oublier le fichier IRremoteBoardDefs.h qui est dans le sous-répertoire "private".
    Ce n'était pas trop compliqué car heureusement, les fonctions sont relativement indépendantes.
    J'en avais bavé avec Ethernet et W5100 car tout était fortement imbriqué.

    Je suis quand même surpris que le compilateur ai autant de difficultés à éliminer les codes jamais appelés...
    Est-ce les niveaux abstractions du c++ qui lui donne autant de mal ?

    J'ai remarqué cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #pragma GCC diagnostic ignored "-Wunused-function"
    Je l'ai retiré de ma version épurée sans effet, mais j'imagine qu'elle a un effet non négligeable quand on utilise la bibliothèque normale.

    Peut-on espérer une amélioration avec la nouvelle version de l'EDI Arduino (le "noyau" sera le même ou y aura-t-il un nouveau compilateur) ?

    A bientôt

  18. #18
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    999
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 999
    Par défaut
    Cet épluchage de bibliothèque m'a fait remarqué quelque chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define IR_SEND_DUTY_CYCLE 30 // 30 saves power and is compatible to the old existing code
    Un rapport cyclique de 30% permet probablement d'économiser le fonctionnement sur piles (mais il faut, c'est évident, désactiver les LED de débug)

    Mais cela peut impacter la portée de la télécommande.

    Beaucoup d'acheteurs des modules infrarouge se plaignent de la faible portée de l'émetteur.

    Mettre le rapport cyclique à 50 devrait augmenter la portée.

    Ce qu'il faut savoir aussi, c'est qu'en alimentant la LED infrarouge avec l'Arduino on limite le courant à 40mA maximum ce qui est peu.

    Habituellement, dans les télécommandes, on envoie beaucoup plus sachant que ce sont de petites impulsions que la LED infrarouge supporte (il ne faut surtout pas l'Arduino plante et alimente la LED en permanence)

    Pour avoir une meilleure portée, il faut passer par un circuit de pilotage de LED infrarouge avec un petit monostable de sécurité (pour ne pas griller la LED en cas de plantage) suivit d'un transistor de commande alimentant la LED infrarouge via une résistance de faible valeur permettant des pointes de courant plus fortes. On peut aussi piloter plusieurs LED (pas mal de télécommandes ont deux LED).

    Ces modules "grand public" ont été conçus pour ne pas griller même en étant maltraités par des électroniciens amateurs, pas pour avoir une grande portée.

    A bientôt

  19. #19
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par electroremy Voir le message

    Le pire c'est les fonctions de débug éparpillées partout (serial.print(), allumage de LEDs...) elles bouffent beaucoup de ressources, ça peut être utile certes mais il faudrait deux versions de bibliothèque :
    - une débug pour apprendre
    - une release pour la production
    Tu es sûr que ces fonctions sont toujours présentes dans le code compilé ? Je pensais qu'il suffisait de jouer avec des #define ou les options de compilation pour qu'elles soient présentes ou non... Cette pratique semble répandue...


    Citation Envoyé par electroremy Voir le message
    Pour IR Remote, il faut ouvrir tous les fichiers source avec NotePad++ sans oublier le fichier IRremoteBoardDefs.h qui est dans le sous-répertoire "private".
    Ah ben t'es courageux. Avec le nouveau IDE (et aussi VSCODE ou Atmel Studio) tu peux naviguer dans la lib assez facilement : go to definition, reference, hover... Je ne sais pas si tu as cela avec NotePad++...


    Citation Envoyé par electroremy Voir le message
    Je suis quand même surpris que le compilateur ai autant de difficultés à éliminer les codes jamais appelés...
    Sur Atmel Studio 7 on peut choisir des options d'optimisation, parfois cela me surprend il peut supprimer des lignes complète de code... Je pense qu'on doit aussi pouvoir faire cela avec l'IDE Arduino... A voir...

Discussions similaires

  1. Problèmes nouvelle librairie IRremote version 3.0
    Par jmdel95 dans le forum Arduino
    Réponses: 10
    Dernier message: 09/02/2021, 23h25
  2. inclure une librairie *.lib
    Par darkbm dans le forum C
    Réponses: 2
    Dernier message: 16/12/2002, 22h48
  3. Réponses: 5
    Dernier message: 09/12/2002, 22h23
  4. [GTK]PB Librairie GTK+ sous dev-c++
    Par wozzy dans le forum Dev-C++
    Réponses: 15
    Dernier message: 05/11/2002, 14h55
  5. compatibilité des librairies directX8
    Par Freakazoid dans le forum DirectX
    Réponses: 3
    Dernier message: 23/05/2002, 21h33

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