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.
----------
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.
----------
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...
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?
Merci.
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...
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 !
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.
Merci.
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...
Oui heureusement !
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...
comme c’est une variable globale elle est bien initialisée à 0, donc c’est normal de ne pas avoir de warning.un bon compilateur devrait lancer un avertissement si on utilise une variable avant qu'elle ne soit initialisée...
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
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.
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).
Merci.
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>...
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().
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
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.
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 :
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part #pragma GCC diagnostic ignored "-Wunused-function"
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
Cet épluchage de bibliothèque m'a fait remarqué quelque chose :
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)
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
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
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...
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++...
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...
Partager