Expérience dans l'utilisation d'écrans LCD basés sur les produits MELT

Cet article est consacré à une quête d'aventure passionnante que j'ai dû traverser dans le processus de création d'un capteur externe mis à jour pour la station météo décrite ici dans cet article il y a un an et demi. Selon l'expérience de fonctionnement de la version précédente, je voulais vraiment créer un capteur avec un écran de contrôle afin qu'il soit possible de vérifier périodiquement (et vérifier) ​​le composant le plus capricieux de la station - le capteur de vitesse du vent. Les aventures ont commencé lorsque j'ai commencé à sélectionner un présentoir à cet effet et, pour un certain nombre de raisons, à propos desquelles, j'ai choisi les produits de mon MELT natif. Mais avant de continuer à décrire les techniques des manières sexuelles non traditionnelles pour faire face aux produits de cette entreprise que j'ai choisie, il vaut la peine de s'attarder brièvement sur la raison principale de toute cette modernisation grandiose que j'ai commencée.

Dans les commentaires de cet article, j'ai été souligné à juste titre au sujet de la conception des capteurs que l'axe d'un tel appareil devrait avoir une pointe solide et reposer sur une base également solide (rappelez-vous une montre-bracelet "sur tant de pierres"). Bien sûr, je le savais, mais je ne pouvais pas penser à un moyen de fournir un axe léger avec un point pointu de dureté suffisante, donc, au contraire, j'ai pris le chemin de minimiser les frottements en plongeant une pointe en laiton (pour girouette) ou en dural (pour capteur de vitesse) dans un PTFE doux (voir .Dessinateur dans l'article spécifié). En toute connaissance de cause, cette décision est temporaire et de courte durée et, dans un proche avenir, il faudra trouver quelque chose de plus substantiel.

Le résultat des deux dernières saisons de fonctionnement a néanmoins montré qu'une telle solution est tout à fait adaptée à une girouette, qui, bien sûr, a scié la base fluoroplastique sur le métal avec un axe en laiton, mais cela ne l'a pas blessé du tout - un frottement minimal n'y est pas nécessaire, même partiellement inversement. C'était pire avec un capteur de vitesse, dans lequel non seulement le fluoroplastique était scié à la base, mais aussi la pointe elle-même d'un duralumin doux effacé de deux millimètres de longueur. En conséquence, tout d'abord, le seuil de démarrage a été augmenté de manière inacceptable et le capteur a dû être modernisé. L'anémomètre lui-même a également subi une modernisation, car le disque compact laser sur la base duquel il a été fabriqué stratifié à partir du soleil et a acquis une apparence désordonnée (enfin, je ne savais pas plus tôt que les disques compacts se composaient de deux couches).

J'espère vous en dire plus sur le nouveau capteur plus tard, après qu'il soit au moins un peu en fonctionnement et vous pouvez vous assurer que vous n'aurez rien à modifier en même temps (c'est-à-dire au plus tôt au début de l'été). Et maintenant seulement quelques détails sur les changements dans le circuit de mesure, car ils sont liés au sujet principal de cet article.

À propos du circuit de mesure du capteur


Dans le cadre de l'abaissement du seuil de démarrage, la question s'est posée du temps considérable qu'il faut pour mesurer les basses fréquences provenant du capteur de vitesse (pour plus de détails, voir cette publication sur les méthodes de mesure des basses fréquences). Afin de ne pas limiter le seuil de démarrage artificiel, dans ce cas il faut mesurer des fréquences à partir de 1-2 hertz: en tenant compte du fait que le capteur a 16 trous dans un cercle (voir photo du capteur dans l'article d'origine ), cela correspond à environ une révolution en 8-16 secondes, ce qui est évidemment inférieur à tout seuil de démarrage. Autrement dit, le délai d'attente pour l'arrivée de la prochaine impulsion de fréquence doit être d'au moins 1 s (voir l'article indiqué sur les méthodes de mesure), ce qui donne un sens à l'histoire d'économie d'énergie: afin d'obtenir un temps de mise à jour acceptable et en même temps, gérer la moyenne des données pour éviter les bavardages sur l'écran, nous devons réveiller le contrôleur toutes les deux secondes. Et si la moitié d'entre eux prend le temps d'attendre les impulsions, il n'y aura pas d'économie d'énergie - compte tenu du fait que la LED émettrice du capteur a fonctionné tout ce temps, consommant environ 20 mA.

Quelques détails entre parenthèses
Je note entre parenthèses que dans le cadre de ce problème, je me suis immédiatement souvenu du compteur actuel qui avait été conçu dans notre bureau d'études au début des années 80, avant même l'apparition de toutes sortes de contrôleurs. De véritables moyennes vectorielles y ont été implémentées: à savoir, l'enregistrement de toutes les lectures était cadencé par le signal de la platine du capteur de vitesse lui-même - un analogue approximatif du sillage d'une interruption externe. En d'autres termes, s'il n'y a pas de courant, aucun enregistrement n'a été effectué et le circuit n'a consommé rien - seules les horloges en temps réel ont fonctionné. Le seuil pour le début de cette plaque tournante, faite sous la forme d'une roue à flottabilité nulle, était, à vrai dire, de 2-3 cm / sec, et le compteur indiquait la direction en tournant tout le corps. C'est donc dans l'eau, 700 fois plus dense que l'air! Pendant le temps moyen, qui se chiffrait en heures, un tel moulinet se retournerait au moins une fois, car il n'y avait presque pas de mesures vides là-bas. Et pour une station météorologique, comme déjà mentionné , une méthode de calcul mathématiquement correcte ne convient pas, car en l'absence de vent, elle devrait montrer quelque chose de réel. Par conséquent, ici, nous ne pouvons pas nous passer d'un délai d'attente artificiellement limité pour attendre les impulsions du capteur.

Il est possible d'équiper un contrôle complexe de l'éveil du contrôleur à partir de deux sources: normalement à partir d'une interruption externe du capteur de vitesse (c'est-à-dire qu'en attendant les impulsions du capteur, le contrôleur passe également en mode d'économie d'énergie), et en l'absence de vent, il est forcé de Watchdog. Cela n'aurait de sens que lors du changement du principe de lecture du capteur de vitesse de circuits optiques à des circuits moins énergivores (qui doivent encore être recherchés - le capteur Hall, par exemple, consomme 5-10 mA, ce qui est fondamentalement inférieur à la conception optique). Mais tout a été simplifié du fait que mon capteur est désormais alimenté par une batterie solaire, ce qui m'a permis d'abandonner tout simplement le mode économie d'énergie.

Pour lire les horloges, je ne me suis pas soucié des minuteries ou des compteurs Arduino millis (), mais j'ai simplement mis en place un générateur de fréquence externe primitif avec une période d'environ 1,5 seconde sur la minuterie 555:


Comme nous le rappelons, le circuit du capteur utilise le contrôleur Atmega328 «nu» dans le package DIP, programmé via Uno et installé sur la prise, Arduino lui-même est utilisé uniquement pour le prototypage. La sortie du générateur était connectée à la broche d'interruption INT0, la broche 4 du microcircuit (broche D2 de la carte Uno). L'interruption de différence positive (RISING) définit un certain indicateur, selon lequel la lecture suivante est prise dans le cycle principal. La fréquence du capteur est également mesurée par la méthode d'interruption (la sortie du capteur est connectée à l'entrée d'interruption INT1, broche 4 (D3), voir la dernière méthode dans le même article ), car le temps d'attente total maximum est le double de la période de la fréquence mesurée. Avec une temporisation de 1 seconde, la fréquence minimale mesurée est donc de 2 Hz (un tour de l'anémomètre en 8 secondes). À chaque quatrième cycle, la moyenne se produit et les données finies sont envoyées au module principal, c'est-à-dire que les lectures sont mises à jour toutes les 6 secondes environ.

L'histoire entière avec un capteur mis à jour devra être calibrée et vérifiée périodiquement pour voir si la friction a augmenté, en comparant les lectures avec un anémomètre manuel. Par conséquent, il est très gênant lorsque les lectures sont affichées en un seul endroit (dans la maison) et que le capteur externe est installé dans un endroit complètement différent - sur le gazebo de jardin. La question s'est posée de l'installation d'un écran LCD de contrôle dans le boîtier du capteur. La beauté n'étant pas requise ici, les informations requises sont minimes: un affichage à 10 caractères sur une seule ligne suffit. Mais les exigences géométriques sont assez strictes: l'écran doit tenir dans le boîtier existant en largeur, qui est de 70 mm. Je dois dire qu'en raison de mon aversion organique pour les écrans LCD (faible, faible contraste, avec de petites lettres, qualité dégoûtante du rétro-éclairage, et aussi consommer beaucoup, plus sur cela plus tard), je ne suis presque pas au courant de la gamme disponible dans la vente au détail. Et donc, il est immédiatement devenu clair que les écrans dont j'avais besoin devaient être très recherchés en vente: l'écran LCD standard 16x2, qui est dominant dans les magasins, a une carte de 80 mm et ne peut pas tenir dans mon capteur, et tous les autres types sont encore plus grands, indépendamment de de l'entreprise. Dans la nature, bien sûr, il existe des variétés plus petites, mais dans la nature, et non dans le commerce de détail national.

Solution: oh MELT!


En fin de compte, j'ai découvert deux MELT à la fois qui correspondent à merveille à ma tâche. Le premier d'entre eux est un MT-10S1 à 10 lignes avec un contrôleur qui, selon les fabricants, "est similaire au HD44780 de HITACHI et au KS0066 de SAMSUNG ". Il a des caractères assez grands: plus de 8 mm de hauteur, ce qui est en fait caractéristique des écrans chinois de tailles beaucoup plus grandes. La largeur de la planche est de 66 mm, les dimensions de l'écran saillant (externe) sont de 62x19,5. La consommation dans ce cas ne me dérange pas beaucoup (parce que le capteur externe est alimenté par une batterie solaire de puissance évidemment plus grande que nécessaire), mais par habitude, en regardant la ligne dans la fiche technique, j'ai trouvé qu'elle est également plus petite que d'habitude - 0,7 mA (tous les écrans LCD ordinaires les affichages sur les analogues du HD44780 consomment à partir de 1,2 mA et plus). Il y a toujours un rétro-éclairage dans le tas, comme cela est habituel pour tous ces types - plutôt misérable et en même temps consommant beaucoup d'énergie.



Le deuxième écran du MT-10T7 est encore plus étonnant: exactement dans les mêmes dimensions, il peut contenir 10 chiffres à sept segments avec une hauteur pouvant atteindre 13 mm. Certains soupçons ont été causés par une interface non standard, et, apparemment, une self-made (pour laquelle l'exemple de la programmation en pseudocode verbal est même donné dans la fiche technique). L'affichage ne contient pas de véritable contrôleur: il existe un ensemble de déclencheurs de verrouillage statiques contrôlés par une logique combinatoire. Mais grâce à une telle simplicité, toute cette conception ne consomme que 30 μA, c'est-à-dire qu'elle convient vraiment aux appareils fonctionnant sur batterie 24h / 24 (la consommation de 1,4 mA dans les écrans conventionnels et même de 0,7 mA dans le MT-10S1 est beaucoup plus élevée que ce qui est autorisé pour de tels appareils). application de la valeur - calculez vous-même combien de temps un tel écran fonctionnera, même sans tenir compte des autres composants de l'appareil, par exemple, à partir de piles AAA d'une capacité d'environ 1500 mAh).



Bref, donnez-en deux!

MT-10T7


Une tentative de reproduire indépendamment l'algorithme pour MT-10T7, décrit dans la fiche technique (à la fois sur Arduino et en assembleur pur), n'a pas abouti. Ce qui a été mal fait, je ne l'ai pas compris, car je suis tombé sur cette publication , où l'auteur (eshkinkot) a donné un exemple très bien écrit et soigneusement exécuté de la manipulation du MT-10T7, après quoi tout a fonctionné immédiatement. Si quelqu'un est intéressé, voici un exemple modifié d'eshkinkot, complété par tous les symboles significatifs valables sur des indicateurs à sept chiffres, y compris les lettres qui ne correspondent pas aux chiffres:






Dans ces images, le contraste de l'écran est légèrement déformé en réglant le diviseur sur la sortie Vo - 18 kOhm (à l'alimentation): 10 kOhm (à la masse), bien que sans lui, le contraste «par défaut» est tout à fait acceptable.

J'ai ensuite ajouté à l'exemple indiqué une fonction qui reproduit un nombre arbitraire sur l'affichage entre trois et quatre décimales - positive ou négative, entier ou virgule flottante, c'est-à-dire que le nombre total de caractères peut atteindre cinq: "-12,7", par exemple. Étant donné que le point dans le code à sept segments n'occupe pas une familiarité distincte, le nombre maximal de bits à afficher est de 4. Les paramètres d'entrée pour cette fonction sont: a) un tableau (char buf [5]) contenant une représentation ACSII du nombre, b) le nombre réel de caractères qu'il contient (ii de 1 à 5) et c) la position (pos de 0 à 9) où placer le premier signe (gauche) du nombre (pour les fonctions et la notation utilisées en cours de route, voir la publication indiquée par eshkinkot ou dans l'exemple par référence):

Code de fonction
void writeASCIIdig_serial(char buf[5], byte ii, byte pos) //      { boolean dot; //     //  ,   pos: pos=pos+(4-ii); //  ,    : for (byte i=0; i <= ii; i++) if (buf[i]=='.') pos++; // : for (byte i=0; i <= ii; i++){ // .  ,    : if (buf[i+1]=='.') dot=true; else dot=false; switch (buf[i]) { //decoder ASCII -> 7-  case '0': writeSymbol(pos, DIGIT_ZERO, dot); break; case '1': writeSymbol(pos, DIGIT_ONE, dot); break; case '2': writeSymbol(pos, DIGIT_TWO, dot); break; case '3': writeSymbol(pos, DIGIT_THREE, dot); break; case '4': writeSymbol(pos, DIGIT_FOUR, dot); break; case '5': writeSymbol(pos, DIGIT_FIVE, dot); break; case '6': writeSymbol(pos, DIGIT_SIX, dot); break; case '7': writeSymbol(pos, DIGIT_SEVEN, dot); break; case '8': writeSymbol(pos, DIGIT_EIGHT, dot); break; case '9': writeSymbol(pos, DIGIT_NINE, dot); break; case '-': writeSymbol(pos, SYMBOL_MINUS, dot); break; } //end decoder if (buf[i]!='.') pos++; //  ,  +1  }//end for i } 


Le module MT-10T7 pour la sortie de contrôle des valeurs numériques est plus pratique que les écrans matriciels ordinaires: il a de grands nombres, et la virgule décimale n'occupe pas une familiarité distincte et, par conséquent, on peut adapter un caractère de plus aux mêmes positions. Mais pour mes besoins, il est plus pratique s'il existe la possibilité de sortir des lettres (sinon la direction devra être affichée en degrés boussole, ce qui est quelque peu inhabituel). Par conséquent, pour ce cas, j'ai tourné mes yeux vers la matrice monoligne de taille identique MT-10S1, qui, malgré un certain nombre d'inconvénients, a migré vers la conception finale. En même temps, il a déjà un rétro-éclairage qui manque au MT-10T7 (pour cela il fallait acheter immédiatement le MT-10T8), et j'ai décidé que dans ce cas sa présence ne ferait pas de mal.

MT-10S1


L'écran MT-10S1 a des lettres une fois et demie plus petites, mais aussi une taille assez décente. De plus, son écran est économiquement compact dans ses dimensions globales: il n'y a pas d'homologues d'importation à 10 chiffres, mais dans le Winstar WH1601L (où les caractères sont même un peu plus courts en hauteur), toute la longueur de la planche et de l'écran par caractère est plus longue d'un millimètre. Eh bien, la consommation du contrôleur est presque divisée par deux (par rapport au même WH1601L). En fait, les avantages s'arrêtent là, puis les «fonctionnalités» commencent.

Le module possède, comme déjà mentionné, un contrôleur compatible avec le HD44780 de HITACHI. Autrement dit, il devrait travailler avec son cristal liquide bien-aimé sans stress excessif. De plus, la page d'encodage «par défaut» coïncide avec la page anglais-cyrillique du HD44780 et ses nombreux analogues, c'est-à-dire que le MT-10S1 devrait fonctionner sans problème avec Liquid Crystal Rus, aucune page de code n'est requise pour que cela soit commuté. Et il fait vraiment tout cela, mais avec des nuances.

La première mise en garde - dans la version à ligne unique, les développeurs économisent apparemment sur les registres, et seuls 8 caractères d'une chaîne (adresses 00h - 07h) sont en mémoire par registre (et les deux caractères restants sont déjà dans un autre registre (40h-41h). Autrement dit, l'affichage de facto est sur deux lignes, seules les deux lignes sont physiquement situées sur une seule ligne. Après un examen plus approfondi, il s'est avéré que la même chose est vraie pour WH1601 (seulement là, le deuxième registre prend huit chiffres complets). La raison pour laquelle cela est si peu pratique est complètement inconnue, dans les écrans 16x2 ordinaires, les registres sont à seize bits, et une telle troncature ne rend guère le produit moins cher, au contraire, en raison de la nécessité de produire différentes versions du contrôleur (si elles sont différentes, dont je ne suis pas du tout sûr). Je pensais qu'il était associé à une consommation inférieure à la normale du MT-10S1, mais le même WH1601 consomme 1,2 à 1,4 mA, c'est-à-dire qu'il n'est pas différent de ses homologues avancés.

Eh bien, il semblerait, d'accord - dans Liquid Crystal Rus, la fonction setDRAMModel () et la constante correspondante LCD_DRAM_WH1601 ont été trouvées. Pour ce mode, la bibliothèque a une traduction d'adresse évidente:

 if (ac>7 && ac<0x14) command(LCD_SETDDRAMADDR | (0x40+ac-8)); 

Mais je ne sais pas comment cela fonctionne sur les autres écrans unifilaires, et le MT-10S1 refuse complètement de fonctionner dans ce mode - l'écran reste simplement vide. Puisque nous parlons d'adressage, vous ne pourrez pas résoudre ce problème avec une simple fonction auto-écrite au-dessus de la bibliothèque, mais je n'ai pas fouillé dans la bibliothèque et découvert ce qui se passait - j'ai déjà plus d'une demi-douzaine d'options corrigées par cristal liquide, je ne veux pas les produire et plus loin.

L'affichage du MT-10S1 doit être déclaré sur deux lignes: lcd.begin (16, 2); (au lieu de 16, vous pouvez remplacer 10 ou 12, rien ne changera, car le nombre réel de caractères sur une ligne est toujours de 8). Une tentative d'initialisation en une seule ligne (numéro 1 en deuxième position) entraînera un échec - l'arrière-plan deviendra sombre. Et les nombres à plusieurs chiffres ne peuvent être affichés que sur 8 caractères, pour les lignes plus longues, les caractères extrêmes au-delà de 8 disparaîtront tout simplement. Par conséquent, les 9 et 10 caractères ne conviennent qu'à l'affichage des quantités auxiliaires (unités de mesure, par exemple), ou vous devez diviser le numéro de ligne en chiffres séparés, et lorsque vous allez au-delà du 8ème caractère, changez la position du curseur sur le premier caractère de la deuxième ligne.

Pour les patients , vous pouvez télécharger ici un croquis d'essai pour cet affichage (connexion des fils - dans le texte du croquis ou dans le schéma ci-dessous). Soit dit en passant, le contraste (à propos duquel il n'y a pas de mot dans le jeu de données d'usine et la sortie Vo est désignée comme NC) est ajusté de la manière habituelle ici, mais vous n'avez vraiment pas besoin de le faire: en l'absence de rétro-éclairage, l'arrière-plan semble un peu sombre, mais lorsque vous essayez de l'éclairer en connectant le séparateur à la sortie Vo le contraste est sensiblement perdu lorsque le rétroéclairage est activé.

Interface avec contrôleur


Après avoir vérifié que tout fonctionne comme il se doit, la question s'est posée de savoir comment connecter tout cela au contrôleur du capteur. Bien sûr, il n'y avait pas suffisamment de conclusions libres pour que le contrôleur de capteur puisse en contrôler le contrôle, mais je ne voulais pas vraiment clôturer la ville avec des contrôleurs de grande taille - c'est plus pratique lorsque la construction du système est modulaire et que l'écran n'interfère pas avec l'algorithme de base déjà débogué plus tôt. Il restait à utiliser l'une des interfaces série.

Cela demande la solution I 2 C basée sur PCF8574 (ou ses nombreux analogues), d'autant plus que cette puce elle-même n'est qu'un registre à décalage trompé, et consomme donc plusieurs dizaines de μA en fonctionnement et moins de 10 μA au repos. Avec le MT-10T7, ils forment une excellente paire pour créer des appareils à faible puissance avec des indicateurs, et MELT a même une option prête à l'emploi pour ce cas: le MT-10T11 avec une consommation totale de 30 μA.

Mais pour le MT-10S1, il n'y a pas de solution aussi pratique - pour une raison quelconque, seules les versions avec une configuration 20x4 sont fournies avec un ajout sous la forme d'un analogue de PCF8574 parmi les écrans de ligne MELT ( UPD: dans les commentaires, ils ont suggéré qu'il existe également une configuration MT-16S2H de 16x4 avec la même interface, bien que , ses dimensions dépassent celles dont j'ai besoin). Le module fini du type décrit dans cet article n'est pas pratique à utiliser dans ce cas, car la deuxième caractéristique désagréable de l'affichage MT-10S1 est son brochage non standard. Les conclusions sont les mêmes (HD44780, néanmoins, plus précisément, son homologue domestique, KB1013VG6), mais elles se situent dans un ordre totalement non standard. Par souci d'intérêt, j'ai vérifié les deux importés 16x1 et MELT deux lignes / quatre lignes - ils ont tous un ordre de sortie standard, et le MT-10S1 se démarque dans ce contexte pour une raison quelconque. Vous devez donc prendre une décision personnelle.

En conséquence, j'ai mis trivialement le même contrôleur ATmega328 à l'écran, programmé de la même manière - via UNO, puis inséré dans la prise sur une carte séparée, équipée uniquement des accessoires nécessaires au démarrage: quartz avec conducteurs, alimentation et circuit RC Réinitialiser la sortie (voir le circuit du capteur dans l'article d'origine , où le contrôleur est connecté de manière similaire).

En parlant de réinitialisation de chaînage
À propos, sur le circuit de réinitialisation: j'ai un condensateur aussi petit que 1 μF sur la résistance de plusieurs kOhms, c'est-à-dire que le temps de retard à la mise sous tension est de quelques millisecondes. Combien? Le manuel nous apprend que, comme pour toute la famille Mega, une chaîne externe n'est pas du tout nécessaire ici, le démarrage correct est censé être effectué par le circuit interne, et beaucoup plus rapidement. Mais l'habitude de mettre une chaîne RC externe sur la broche 1 du contrôleur pour un démarrage retardé lorsque je l'ai allumé est restée avec moi à l'époque de la famille AVR Classic déjà oubliée, où le contrôleur pourrait ne pas démarrer correctement si la tension d'alimentation n'augmentait pas assez rapidement. Et dans la famille des détecteurs Mega Brown-out, cela peut ne pas fonctionner très bien. Dans les cas critiques, il vaut toujours la peine d'installer un moniteur d'alimentation externe, mais ici, la chaîne RC ne fait rien de mal, mais elle peut aider dans les cas avec de mauvaises sources d'alimentation. Les développeurs de cartes Arduino, au fait, le savent bien, car sur la carte Uno, par exemple, il y a la même chaîne de 10 kOhm / 100 nF.

Et Dieu lui-même a ordonné que deux contrôleurs AVR identiques soient ancrés via l'interface série habituelle, qui de toute façon, à l'exception du processus de programmation, n'est utilisée nulle part ailleurs dans ce projet, et pour l'utilisation de laquelle tout est déjà à portée de main. À propos, une telle solution ne diffère pas du prix des composants basés sur PCF8574 et peut rivaliser avec elle en termes d'économie d'énergie dans la variante avec MT-10T7 - au cas où le MT-10T11 mentionné ci-dessus n'est pas à portée de main.

Au total, le circuit du module MT-10S1 avec le contrôleur est le suivant (dans le schéma, la désignation des conclusions de l'ATmega328 est donnée entre parenthèses après les conclusions de la carte Arduino):



Dans le contrôleur, j'ai appliqué le mode d'économie d'énergie (enfin, oui, ce n'est pas vraiment nécessaire ici, mais pourquoi garder la puce allumée inutilement?). De plus, le réveil se produit selon le signal du même générateur d'ondes carrées sur la puce 555 que l'horloge du contrôleur principal, mais cette fois le long du front descendant (FALLING) afin de séparer légèrement les fonctions de mesure et de transfert de données.

Le mystère de la nature
Un mystère de la nature est lié à cela, que je n'ai pas pu résoudre. Il est connu que Mega ne peut être retiré du sommeil profond que par une interruption asynchrone externe, car l'horloge est éteinte et une interruption synchrone ne peut tout simplement pas se produire. Et toute la famille des contrôleurs AVR 28 broches, menant leur arbre généalogique à partir d'ATmega8 (48/88/168/328), n'a en tant que tel que des interruptions de bas niveau INT0 et INT1 (et une interruption PCINT, mais elle n'est pas utilisée dans Arduino). Toutes les recommandations officielles sont liées à cela à la fois dans les matériaux Atmel et sur les sites Arduino. L'exemple sur le site arduino.cc dit explicitement: " Dans tous les modes de veille, sauf IDLE, seul LOW peut être utilisé ." Et cela, pour ainsi dire, ne fait aucun doute, par exemple, Monk répète la même chose plus en détail dans son livre : « Notez que le type d'interruption LOW est sélectionné. Il s'agit du seul type d'interruption pouvant être utilisé dans cet exemple. Les types RISING, FALLING et CHANGE ne fonctionneront pas . »

Une interruption à un niveau bas est très peu pratique à utiliser, car une fois qu'elle se produit, avec ce niveau le plus bas en sortie, elle se reproduira encore et encore, et des mesures spéciales doivent être prises pour se débarrasser des déclencheurs inutiles. Donc, en fouillant sur les forums à la recherche de diverses solutions à ce problème, je suis soudainement tombé sur quelques exemples de code dans lesquels INT0 du type RISING ou FALLING est explicitement utilisé pour sortir du sommeil. Bien sûr, j'ai attribué cela à l'analphabétisme des auteurs. Mais quand je suis tombé sur la phrase: " Bien que vous puissiez utiliser n'importe quel autre type d'interruption (RISING, FALLING, CHANGE) - ils sortiront tous le processeur du sommeil ", j'ai décidé, malgré les ennemis, de mener une expérience en direct - c'était bon pour ça à la main.

Et, à ma grande surprise, tout a parfaitement fonctionné. Mode d'économie d'énergie - SLEEP_MODE_PWR_DOWN; en raison de l'inutilité, ici, je n'ai pas pris de mesures pour réduire davantage la consommation en désactivant toutes les autres fonctions, mais le générateur d'horloge est toujours évidemment éteint. Néanmoins, le contrôleur se réveille régulièrement sur le front descendant, demande des données, les affiche à l'écran et s'endort à nouveau. Pour la pureté de l'expérience, j'ai retiré le MK de la carte UNO et l'ai inséré dans ma prise avec le quartz connecté, et tout a continué à fonctionner. Cela peut être vu à partir de la consommation: près de 17 mA en mode normal et 0,9-1 mA avec l'économie d'énergie activée (dont 0,7 mA doit être attribué à l'affichage).

Sans sortir de mon étonnement, j'ai relu les fiches techniques d’Atmel, j’ai regardé le livre d’Evstifeev (avec leur traduction), j’ai même parcouru le vieux manuel d’Atmel sur la famille Classic, puis passé une demi-journée à chercher au moins quelques explications sur ce qui se passait (en russe et en anglais) dans deux moteurs de recherche bien connus, mais nulle part n'a trouvé même un indice. À moins que cela ne soit utile dans les notes d'application d'Atmel, car il est douteux que tout ce qui est contraire aux fiches techniques y soit publié. Je serai heureux si quelqu'un qui sait sait ce que je comprends mal.
UPD: la vérification de l'assembleur en direct (ATmega8) a montré une pleine conformité avec les fiches techniques, c'est-à-dire que seules les interruptions de niveau fonctionnent. La seule explication qui me vient à l'esprit est que Arduino a en quelque sorte connecté l'interruption PCINT à une interruption régulière. Une tentative de clarifier la situation en étudiant le texte des bibliothèques du système Arduino n'a rien donné - là, le diable lui briserait la jambe.

Le transfert de données du contrôleur de capteur au contrôleur d'affichage via UART est organisé sous la forme d'une boîte de dialogue. Au réveil, toutes les 4 interruptions, le contrôleur d'affichage demande à son tour les données:

 . . . . . if (flag==1) { //   4-  ~6  Serial.print('T'); //   while(!Serial.available()); //  T iit = Serial.readBytes(buft,5); //  5  , //  ii    Serial.print('H'); //   while(!Serial.available()); //  iihh=Serial.readBytes(bufhh,5); //  5  , //  ii    Serial.print('S'); //   while(!Serial.available()); //  iiss=Serial.readBytes(bufss,5); //  5  , //  ii    Serial.print('D'); //   while(!Serial.available()); //  iid=Serial.readBytes(bufd,5); //  5  , //  ii    flag=0; //   } . . . . . 

Ici buft, bufhh, bufss et bufd sont des tableaux (pas des chaînes!) De cinq octets qui contiennent des données sur la température, l'humidité, la vitesse et la direction sous la forme d'une décomposition ASCII des nombres correspondants. Afin de ne pas en accepter trop, le setup'e spécifie un timeout abrégé pour la réception:

 . . . . . Serial.begin(9600); Serial.setTimeout(10); //   10  . . . . . 

Il est plus pratique d'afficher: d'une part, vous avez immédiatement la longueur du numéro reçu, et d'autre part, la fonction Serial.print () envoie une chaîne ASCII du côté du contrôleur de capteur, avec des pauses définies juste dans les 10 ms entre les envois :

 . . . . . //     : if (Serial.available()>0) //  { char ch=Serial.read(); if (ch=='T') { Serial.print(temperature,1); delay(10);} if (ch=='H') { Serial.print(humidity,0); delay(10);} if (ch=='S') { float wFrq=(3+0.8*f)/10; //   / if (wFrq>0.3) Serial.print(wFrq,1); else Serial.print(0.0,1); delay(10);} if (ch=='D') { // Serial.println(wind_G); Serial.println(wind_Avr); delay(10); }//end ch }//end serial . . . . . 

Le calcul de la vitesse en m / s ici est identique à celui effectué dans le module principal de la station (le seuil de démarrage est fixé au hasard à 0,3 m / s) et il devra également être modifié en fonction des résultats de l'étalonnage.

Si vous essayez d'accepter les données avec le Serial.read () habituel, puis affichez le résultat de la réception sur un écran avec une fonction comme lcd.print (t, 1), où t est la température en degrés, égale, par exemple, à 12,7, puis MT-10S1 en réponse à cela la commande affichera "49,5". Deviné, ou suggérer? Ce sont les trois premiers caractères de la séquence «49 50 46 55», c'est-à-dire dans l'extension ASCII du nombre «12,7». Par conséquent, il est plus facile de prendre immédiatement un tableau de caractères et d'afficher directement autant de caractères qu'il a été envoyé (count est un compteur qui augmente d'une unité à chaque interruption):

 . . . . if (count%8==0){ // 8   lcd.clear(); if (buft[0]!='-') lcd.print("+"); for (byte i = 0; i < iit; i++) lcd.print(buft[i]); //  lcd.setCursor(6, 0); for (byte i = 0; i < iihh; i++) lcd.print(bufhh[i]); //  lcd.setCursor(0, 1); lcd.print("%"); } if ((count+4)%8==0){ //  4  lcd.clear(); lcd.setCursor(0, 0); for (byte i = 0; i < iiss; i++) lcd.print(bufss[i]); //  lcd.setCursor(5, 0); dir_dd(bufd); //  } . . . . . 

La dernière ligne doit être déchiffrée. Le fait est que les données de direction sont envoyées dans le code 0-15 (auquel elles sont toujours transférées à partir du code Gray lors de la mise en œuvre de la moyenne vectorielle ). Dans le cas de l'affichage à sept segments MT-10T7, ils ont été convertis en degrés boussole:

 . . . . . dd=atoi(bufd); //   dd=dd*22.5; //   itoa(dd,bufd,10); //    . . . . . 

Et ici, nous pouvons écrire directement en lettres russes, de la même manière que dans le module principal de la station météo (à cause duquel cet affichage, en fait, a été choisi):

 . . . . . void dir_dd(char dd[]) {switch(atoi(dd)) { case 0: {lcd.print(""); break;} case 1: {lcd.print("C"); break;} case 2: {lcd.print("C"); break;} case 3: {lcd.print("C"); break;} case 4: {lcd.print(""); break;} case 5: {lcd.print(""); break;} case 6: {lcd.print(""); break;} case 7: {lcd.print(""); break;} case 8: {lcd.print(""); break;} case 9: {lcd.print(""); break;} case 10: {lcd.print(""); break;} case 11: {lcd.print(""); break;} case 12: {lcd.print(""); break;} case 13: {lcd.print("C"); break;} case 14: {lcd.print("C"); break;} case 15: {lcd.print("C"); break;} }//end switch }//end dir . . . . . 

Apparence


La photo montre l'apparence de l'écran avec le contrôleur connecté en état de fonctionnement:



Voici à quoi ressemble le capteur modifié:



Les paramètres de rétro-éclairage sont ceux indiqués dans le schéma ci-dessus. Étant donné que la chute de tension à travers le rétroéclairage dans les modules MELT est de 4,5 V, avec une alimentation 12 V, le courant de rétroéclairage est de 50 mA (au maximum pour ce module, 60 mA).

Le boîtier est scellé au maximum pour éviter de pénétrer de l'air humide à l'intérieur (le cadre noir de l'écran d'affichage provient de la gaine en caoutchouc d'un câble mince). La plaque blanche à droite est le boîtier du capteur d'humidité-température SHT-75, retiré du boîtier (le capteur lui-même est situé derrière). Le fil jaune ci-dessus est l'antenne de l'émetteur 433 MHz. À gauche se trouvent les connecteurs où les capteurs de vitesse et de direction sont connectés.

Et donc les lectures sur l'affichage du module principal de la station météo ressemblent (le module noir avec l'antenne blanche à droite est le récepteur 433 MHz):

Source: https://habr.com/ru/post/fr430828/


All Articles