ESP32 + Arduino Core + FreeRTOS + Blynk = maison avec les débuts de l'esprit

Objectifs du projet


D'une certaine manière, il s'est avéré que j'ai construit ma maison, un squelette. Dans mon aul de luxe, il n'y a pas de gaz et n'est pas prévu dans un avenir proche, c'est pourquoi j'ai choisi un squelette - tout le reste, pour moi, il serait très coûteux de chauffer à l'électricité. Eh bien, aussi parce que c'est l'une des technologies les moins chères.
D'accord, j'ai jeté des tuyaux autour de la maison, accroché des piles, une chaudière, il semblait chaud, mais quelque chose n'allait pas.


Après m'être écouté, j'ai réalisé que c'est un crapaud que je n'aime pas, que pendant que je ne suis pas à la maison (12-16 heures par jour), le chauffage fonctionne. Et cela pourrait ne pas fonctionner, ne l'allumez qu'avant l'arrivée, car le squelette a une légère inertie et vous permet d'augmenter rapidement la température. La même situation quand quelque part depuis longtemps pour quitter la maison. Eh bien, en général, courir, tourner la poignée de la chaudière avec des changements de température dans la rue n'est en quelque sorte pas casher.


Il est devenu clair que sans automatisation, nulle part, la chaudière est la plus simple, mais elle a des contacts pour connecter un relais de contrôle externe. Bien sûr, vous pouvez immédiatement acheter une chaudière avec toutes les fonctions nécessaires, mais pour moi, ces chaudières sont en quelque sorte inhumaines. De plus, je voulais m'accroupir avec le cerveau, faire pipi quelque chose pour l'âme, apprendre un petit C, bien que dans la version Arduino.


En fait sur les exigences:


  • contrôle de la température de consigne
  • contrôle de la température du liquide de refroidissement en fonction de la température extérieure ou manuellement
  • fuseaux horaires avec différents réglages, plus froid le jour, plus chaud la nuit
  • mode automatique, avec transition jour-nuit automatique
  • mode manuel, pas de transitions automatiques, pour le week-end
  • mode non automatique, où vous pouvez régler manuellement la température du liquide de refroidissement et allumer / éteindre la chaudière
  • contrôle du chauffage localement, depuis les boutons et l'écran et via le site web / l'application mobile

C'était au début, puis j'ai souffert et j'ai ajouté:


  • commande de réverbère (projecteur LED)
  • système d'alarme basé sur détecteur de mouvement, sirène et lampadaire
  • mesure de l'énergie consommée par la chaudière par jour / mois / année + pour chaque mois de l'année
  • mode alarme uniquement par clignotement lent d'une lampe
  • mode de signalisation par clignotement rapide d'une lampe et bips courts d'une sirène
  • mode de signalisation par clignotement rapide d'une lampe et hurlement constant d'une sirène

Le but de cet article est de partager l'expérience, de décrire quelque chose en russe que je n'ai pas trouvé sur Internet. Je pense que cet article sera utile aux bricoleurs débutants Arduino qui sont déjà un peu familiarisés avec la programmation, comme des choses absolument basiques que je n'ai pas décrites. J'ai essayé d'écrire le code aussi clairement que possible, j'espère avoir réussi.


Ce qui était au début


Initialement, le projet a été mis en œuvre sur un tas sauvage d'Arduino Nano + ESP8266, mais ESP n'est pas un bouclier, mais un appareil séparé. Pourquoi Oui, parce que j'avais déjà tout cela, mais il n'y avait pas d'argent du tout, donc je ne voulais pas acheter de fer neuf en principe. Pourquoi ESP n'est-il pas comme un bouclier? Maintenant, je ne me souviens même plus.


Arduino a dirigé tous les processus parce qu'il avait la quantité requise de GPIO, et ESP a envoyé toutes les données au serveur Blynk, car il connaissait Internet et n'avait pas assez de GPIO. Ils se sont connectés via UART et se sont envoyés des données avec JSON. Le régime est inhabituel, mais il a fonctionné pendant un an avec presque aucune plainte. Toute personne intéressée peut voir le codec .


Je ferai une réservation tout de suite, je n’étais pas très habile à ce moment-là (et même maintenant je voudrais le faire mieux), donc c'est mieux pour les femmes enceintes et les enfants de ne pas regarder. De plus, tout a été écrit dans l'IDE Arduino, on ne s'en souviendra pas de nuit, ce qui est très limité en termes de refactoring, tout y est très primitif.


Le fer


Ainsi, un an s'est écoulé, les finances ont permis d'acheter ESP32 devkit v1, qui a suffisamment de GPIO, peut accéder à Internet et généralement à un super contrôleur. En plus des blagues, je l'aimais beaucoup à la fin du travail.


Liste de fer:


  • ESP32 devkit v1 noname Chine
  • 3 capteurs de température DS18B20, température à l'intérieur de la maison, à l'extérieur et la température du liquide de refroidissement dans les tuyaux
  • bloc de 4 relais
  • capteur pir HC-SR501

Je ne dessinerai pas de schéma, je pense que tout sera clair à partir des macros avec les noms des broches.


Pourquoi FreeRTOS et Arduino Core


Un tas de bibliothèques sont écrites sur Arduino, en particulier le même Blynk, donc vous ne vous éloignerez pas d'Arduino Core.


FreeRTOS car il vous permet d'organiser le travail d'un petit morceau de fer similaire au travail d'un contrôleur industriel à part entière. Chaque tâche peut être déplacée dans sa propre tâche, arrêtée, démarrée, créée si nécessaire, supprimée - tout cela est beaucoup plus flexible que d'écrire une longue merde de code Arduino, quand à la fin tout se fait à son tour dans la fonction de boucle.


Lors de l'utilisation de FreeRTOS, chaque tâche sera exécutée à une heure strictement spécifiée, si seule la puissance du processeur est suffisante. Au contraire, dans Arduino, tout le code est exécuté dans une fonction, dans un thread, si quelque chose ralentit, le reste des tâches sera retardé. Ceci est particulièrement visible lors de la gestion de processus rapides, dans ce projet, ce clignotement d'une lampe de poche et d'un bip de sirène sera discuté ci-dessous.


À propos de la logique


À propos des tâches FreeRTOS


→ Lien vers l' ensemble du codec du projet


Ainsi, lorsque vous utilisez FreeRTOS, la fonction de configuration joue le rôle de la fonction principale, le point d'entrée de l'application, les tâches FreeRTOS (ci-après les tâches) y sont créées, la fonction de boucle ne peut pas être utilisée du tout.


Considérons une petite tâche pour calculer la température du liquide de refroidissement:


void calculate_water_temp(void *pvParameters) { while (true) { if (heating_mode == 3) {} else { if (temp_outside > -20) max_water_temp = 60; if (temp_outside <= -20 && temp_outside > -25) max_water_temp = 65; if (temp_outside <= -25 && temp_outside > -30) max_water_temp = 70; if (temp_outside <= -30) max_water_temp = 85; } vTaskDelay(1000 / portTICK_RATE_MS); } } 

Il est déclaré comme une fonction qui doit prendre _void pvParameters , une boucle sans fin est organisée à l'intérieur de la fonction, j'ai utilisé while (true) .


Un simple calcul de température est vTaskDelay(1000 / portTICK_RATE_MS) (si le mode de fonctionnement le permet) puis la tâche est euthanasiée par vTaskDelay(1000 / portTICK_RATE_MS) pendant 1 seconde. Dans ce mode, il ne consomme pas de temps CPU, les variables avec lesquelles la tâche a travaillé, en d'autres termes, le contexte, sont stockées sur la pile pour les sortir de là le moment venu.


La tâche suivante doit être créée dans la configuration. Cela se fait en appelant la méthode xTaskCreate :


xTaskCreate(calculate_water_temp, "calculate_water_temp", 2048, NULL, 1, NULL);


Il existe de nombreux arguments, mais pour nous, Calculate_water_temp est significatif - le nom de la fonction contenant le code de tâche et 2048 est la taille de la pile en octets.


La taille de la pile a initialement défini tout le monde à 1024 octets, puis j'ai calculé la méthode souhaitée en tapant, si le contrôleur commençait à tomber avec un débordement de pile (comme on peut le voir sur la sortie dans uart), j'ai juste augmenté la taille de la pile de 2 fois, si cela n'a pas aidé, de 2 fois et ainsi de suite jusqu'à ce que cela fonctionne. Bien sûr, cela n'économise pas trop de mémoire, mais ESP32 en a assez, dans mon cas, vous ne pourriez pas vous embêter avec cela.


Vous pouvez également spécifier un descripteur pour la tâche - un descripteur avec lequel vous pouvez contrôler la tâche après la création, par exemple - supprimer. Il s'agit du dernier NULL de l'exemple. Une poignée est créée comme ceci:


TaskHandle_t slow_blink_handle;


Ensuite, lors de la création d'une tâche, un pointeur vers le xTaskCreate transmis au paramètre xTaskCreate:


xTaskCreate(outside_lamp_blinks, "outside_lamp_blynk", 10000, (void *)1000, 1, &slow_blink_handle);


Et si nous voulons supprimer la tâche, nous le faisons:


vTaskDelete(slow_blink_handle);


Comment cela est utilisé peut être vu dans le code de panic_control panic_control.


FreeRTOS Mutex Pros


Mutex est utilisé pour éliminer les conflits entre les tâches lors de l'accès à des ressources telles que uart, wifi, etc. Dans mon cas, j'avais besoin de mutex pour le wifi et l'accès à la mémoire flash.


Créez un lien vers le mutex:


SemaphoreHandle_t wifi_mutex;


Dans la setup créez un mutex:


wifi_mutex = xSemaphoreCreateMutex();


De plus, lorsque nous avons besoin d'accéder à la ressource de tâche, il prend le mutex, informant ainsi le reste des tâches que la ressource est occupée et qu'il n'est pas nécessaire d'essayer de travailler avec elle:


xSemaphoreTake(wifi_mutex, portMAX_DELAY);


portMAX_DELAY - attendre indéfiniment jusqu'à ce que la ressource et le mutex soient libérés par d'autres tâches, pendant tout ce temps, la tâche va dormir.


Après avoir travaillé avec la ressource, nous donnons le mutex pour que d'autres puissent l'utiliser:


xSemaphoreGive(wifi_mutex);


Vous pouvez voir le code plus en send_data_to_blynk dans la send_data_to_blynk send_data_to_blynk.


En pratique, la non-utilisation de mutex n'était pas perceptible pendant le fonctionnement du contrôleur, mais lors du débogage JTAG, des erreurs disparaissaient constamment qui disparaissaient après l'utilisation des mutex.


Brève description de tasok


get_temps - recevoir la température des capteurs, toutes les 30 secondes, plus souvent ce n'est pas nécessaire.
get_time_task - récupère l'heure des serveurs NTP. Auparavant, le temps venait du module RTC DS3231, mais il a commencé à échouer après un an de travail, j'ai donc décidé de m'en débarrasser. J'ai décidé que cela n'avait pas de conséquences particulières pour moi, principalement le temps affectait la commutation du fuseau horaire de chauffage - jour ou nuit. Si Internet disparaît pendant le fonctionnement du contrôleur, l'heure se figera simplement, le fuseau horaire restera simplement le même. Si le contrôleur s'éteint et après avoir allumé, il n'y a pas d'Internet, l'heure sera toujours 0:00:00 - mode chauffage la nuit.
calculate_water_temp - considéré ci-dessus.
detect_pir_move - réception d'un signal de mouvement du capteur HC-SR501. Le capteur forme une unité logique + 3,3 V lorsqu'un mouvement est détecté, qui est détecté à l'aide de digitalRead , en passant, la broche de détection de ce capteur doit être tirée jusqu'à GND - pinMode(pir_pin, INPUT_PULLDOWN);
heating_control - commutation des modes de chauffage.
out_lamp_control - contrôle d'un réverbère.
panic_control - contrôle la sirène et le projecteur lorsqu'un mouvement est détecté. Pour créer l'effet des sirènes et des feux clignotants, des tâches distinctes sont utilisées, outside_lamp_blinks et siren_beeps . Lorsque vous utilisez FreeRTOS, le clignotement et les bips fonctionnent parfaitement, exactement aux intervalles définis, d'autres tâches n'affectent pas leur travail, car ils vivent dans des ruisseaux séparés. FreeRTOS garantit que le code de la tâche s'exécutera à l'heure spécifiée. Lors de la mise en œuvre de ces fonctions dans la loop tout ne fonctionnait pas si bien, car influencé par l'exécution d'un autre code.
guard_control - contrôle des modes de garde.
send_data_to_blynk - envoie des données à l'application Blynk.
run_blynk - tâche pour lancer Blynk.run() comme requis par le manuel d'utilisation de Blynk. Si je comprends bien, cela est nécessaire pour obtenir des données de l'application vers le contrôleur. En général, Blynk.run() devrait être dans une loop , mais je ne voulais essentiellement rien y mettre et j'en ai fait une tâche distincte.
write_setting_to_pref - enregistre les paramètres et les modes de fonctionnement afin de les rattraper après un redémarrage. A propos de pref sera décrit ci-dessous.
count_heated_hours - compter le temps de fonctionnement de la chaudière. Je l'ai fait simplement, si la chaudière est allumée au moment du lancement de la tâche (une fois toutes les 30 secondes), dans la mémoire flash la valeur de la touche souhaitée est incrémentée d'une unité.
send_heated_hours_to_app - dans cette tâche, les valeurs sont extraites et multipliées par 0,00833 (1/120 heures), les heures de fonctionnement reçues de la chaudière sont envoyées à l'application Blynk.
feed_watchdog - nourrit Watchdog. J'ai dû écrire un chien de garde, car une fois tous les quelques jours, le contrôleur peut geler. Ce avec quoi il est connecté n'est pas clair, il peut y avoir une sorte d'interférence avec l'alimentation, mais l'utilisation d'un chien de garde résout ce problème. Minuteur de surveillance 10 secondes, ce n'est pas grave si le contrôleur n'est pas disponible pendant 10 secondes.
heart_beat - tâche avec une impulsion. Lorsque je passe le contrôleur, je veux savoir que cela fonctionne bien. Parce que sur ma carte il n'y a pas de LED intégrée, j'ai dû utiliser la LED UART - installer Serial.begin(9600); et écrire une longue chaîne dans UART. Cela fonctionne plutôt bien.


Nivellement d'usure ESP32 NVS


Les descriptions suivantes sont assez grossières, littéralement sur les doigts, juste pour transmettre l'essence du problème. Plus de détails


Arduino utilise la mémoire EEPROM pour stocker des données dans une mémoire non volatile. Il s'agit d'une petite mémoire dans laquelle chaque octet peut être écrit et effacé séparément, tandis que la mémoire flash n'est effacée que par secteurs.


Il n'y a pas d'EEPROM dans ESP32, mais il y a généralement une mémoire flash de 4 Mo dans laquelle vous pouvez créer des partitions pour le microprogramme du contrôleur ou pour stocker les données utilisateur. Les sections pour les données utilisateur sont de plusieurs types - NVS, FATFS, SPIFFS. Il doit être sélectionné en fonction du type de données destinées à l'enregistrement.


Parce que toutes les données écrites dans ce projet sont de type Int, j'ai choisi NVS - Non-Volitile Storage. Ce type de partition est bien adapté au stockage de petites données, souvent écrasables. Pour comprendre pourquoi, vous devriez approfondir un peu l'organisation de NVS.


L'EEPROM et le FLASH ont une restriction sur l'écrasement des données, les octets de l'EEPROM peuvent être écrasés de 100 000 à 1 000 000 de fois, le secteur FLASH est le même. Si nous écrivons des données une fois par seconde, nous obtenons alors 60 secondes x 60 minutes x 24 heures = 86 400 fois / jour. Autrement dit, dans ce mode, l'octet durera 11 jours, ce qui est un peu. Après quoi l'octet ne sera pas disponible pour l'écriture et la lecture.


Pour atténuer ce problème, les fonctions update() put() de la bibliothèque Arduino EEPROM n'écrivent des données que lorsqu'elles changent. Autrement dit, vous pouvez écrire chaque seconde des paramètres et des codes de mode qui changent assez rarement.


NVS utilise une méthode différente pour contrôler le niveau d'usure. Comme mentionné ci-dessus, les données du secteur flash peuvent être écrites en parties, mais seul le secteur entier peut être effacé. Par conséquent, l'enregistrement des données dans NVS est effectué dans une sorte de journal, ce journal est divisé en pages, qui sont placées dans un secteur de la mémoire flash. Les données sont écrites par paires clé: valeur. En fait, c'est encore plus facile qu'avec l'EEPROM, car travailler avec un nom significatif est plus facile qu'avec une adresse en mémoire. Upd: la longueur de la clé ne dépasse pas 15 caractères!


Si vous écrivez d'abord la valeur 1 sur la clé somekey , puis écrivez la valeur 2 sur la même clé, la première valeur ne sera pas supprimée, elle sera uniquement marquée comme supprimée (effacée) et une nouvelle entrée sera ajoutée au journal:



Si vous essayez de lire des données par une somekey dernière valeur de cette clé sera retournée. Parce que Étant donné que le journal est commun, les valeurs des différentes clés sont stockées les unes à côté des autres au fur et à mesure qu'elles sont écrites.


La page a un statut, Vide - vide, sans entrées, Actif - les données y sont actuellement écrites, Complet - est plein, vous ne pouvez pas y écrire. Dès que la page manque d'espace, elle est de
Active passe à Complet et la page vide suivante devient Active.



D'après ce que j'ai compris de la documentation sur le site Web Espressif et divers forums, le nettoyage des pages commence lorsque les pages gratuites se terminent. Pour être plus précis, selon cela , l'effacement se produira lorsqu'il ne restera qu'une seule page libre.


Si la page doit être effacée, les enregistrements actuels (non effacés) sont déplacés vers une autre page et la page est remplacée.


Ainsi, l'opération d'effacement en écriture pour chaque page particulière est assez rare, plus il y a de pages - moins souvent. Sur cette base, j'ai augmenté la taille de la partition NVS à 1 Mo. À mon taux d'enregistrement, cela suffit pour 170 ans, ce qui est généralement suffisant. Le redimensionnement de la section NVS sera le suivant.


Pour un travail pratique avec NVS, ESP32 pour Arduino Core dispose d'une bibliothèque pratique de préférences écrites, comment l'utiliser est écrit ici .


Un peu sur VisualGDB


Dès que j'ai commencé à travailler avec l'IDE Arduino, j'ai été immédiatement surpris par la misérable fonctionnalité par rapport à Visual Studio. Ils disent que VS n'est pas non plus une fontaine, même si cela me convient, mais écrire quelque chose de plus de 50 lignes dans l'IDE Arduino est douloureusement douloureux et douloureusement long. Ainsi, la question s'est posée de choisir un IDE pour le développement. Parce que Je connais VS, je me suis installé sur VisualGDB .


Après l'IDE Arduino, le développement de l'ESP32 est tout simplement un havre. Quelle est la transition vers la définition, la recherche d'appels dans le projet et la possibilité de renommer la variable.


Modification de la table de partition ESP32 avec VisualGDB


Comme mentionné ci-dessus, la table peut être modifiée avec la partition ESP32; nous verrons comment cela peut être fait.
Le tableau est modifié en tant que fichier csv, par défaut VisualGDB écrit le tableau suivant:


 Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x140000, app1, app, ota_1, 0x150000,0x140000, spiffs, data, spiffs, 0x290000,0x170000, 

Ici, nous voyons une section sous NVS, deux sections pour les applications et quelques autres sections. Parmi les nuances, on peut noter que app0 (votre application) doit toujours être écrit à l'offset 0x10000, à partir de l'adresse zéro, sinon le chargeur de démarrage ne le détectera pas. En outre, les décalages doivent être sélectionnés de sorte que les sections ne se "chevauchent" pas. La table de partition elle-même est écrite à l'offset 0x8000. Comme vous pouvez le voir, la taille du NVS dans ce cas est 0x5000 - 20 Ko, ce qui n'est pas beaucoup.


J'ai modifié la table de partition comme suit:


 Name, Type, SubType, Offset, Size, Flags app0, app, ota_0, 0x10000, 0x140000, nvs, data, nvs, , 1M, otadata, data, ota, , 0x2000, spiffs, data, spiffs, , 0x170000, 

N'oubliez pas d'ajouter une grille avant Nom, si vous utilisez ce tableau, vous avez besoin que cette ligne soit considérée comme un commentaire.


Comme vous pouvez le voir, la taille du NVS est augmentée à 1 Mo. Si vous ne spécifiez pas de décalage, la section commencera immédiatement après la précédente, il suffit donc d'indiquer le décalage uniquement pour app0. Les fichiers CSV peuvent être modifiés dans le bloc-notes en tant que txt, puis changer l'autorisation en csv pour le fichier enregistré.


Ensuite, la table de partition doit être convertie en binaire, car il entre dans le contrôleur sous cette forme. Pour ce faire, exécutez le convertisseur:
c:\Users\userName\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3\tools\gen_esp32part.exe part_table_name.csv part_table_name.bin . Le premier paramètre est votre CSV, le deuxième paramètre est le binaire de sortie.


Le binaire résultant doit être placé dans c:\Users\userName\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3\tools\partitions\part_table_name.csv , après quoi il est nécessaire de spécifier que c'est lui qui a été amené à construire la solution, et pas de table de partition par défaut. Vous pouvez le faire en écrivant le nom de votre table dans le fichier c:\Users\userName\Documents\ArduinoData\packages\esp32\hardware\esp32\1.0.3\boards.txt . Dans mon cas, c'est esp32doit-devkit-v1.build.partitions=part_table_name
Après ces manipulations, VisualGDB lors de la création de l'application prendra exactement votre table de partition et la placera dans
~project_folder_path\Output\board_name\Debug\project_name.ino.partitions.bin , d'où il sera déjà versé dans la carte.


Débogueur JTAG CJMC-FT232H


Pour autant que je sache, c'est le débogueur le moins cher qui peut fonctionner avec ESP32, il m'a coûté environ 600 roubles, il y en a beaucoup sur Aliexpress.



Lorsque vous connectez le débogueur, Windows y installe des pilotes inadaptés qui doivent être modifiés à l'aide du programme Zadig, tout y est simple, je ne le décrirai pas.


Il se connecte à ESP32 devkit-v1 de la manière suivante:
FT232H - ESP32
AD0 - GPIO13
AD1 - GPIO12
AD2 - GPIO15
AD3 - GPIO14
Ensuite, dans Project -> VisualGDB Project Properties vous devez définir les paramètres suivants:



Cliquez ensuite sur Test. Parfois, il arrive que la connexion ne soit pas établie la première fois, le processus semble se figer, puis vous devez interrompre et répéter le test. Si tout est en ordre, le processus de test de la connexion prend environ 5 secondes.


J'ai généralement assemblé le projet et l'ai téléchargé via USB sur l'ESP32 lui-même (pas via le débogueur), après quoi j'ai commencé à déboguer avec Debug -> Attach to Running Embedded Firmware . Dans le code, vous pouvez définir des points d'arrêt, regarder les valeurs des variables au moment de la panne et dans la fenêtre Debug -> Windows -> Threads , vous pouvez voir dans quelle tâche FreeRTOS le code s'est arrêté, ce qui est utile si une erreur se produit pendant le débogage. Ces fonctions du débogueur me suffisaient pour travailler confortablement.
Lorsque j'ai commencé à travailler avec NVS, le débogage était constamment interrompu par des erreurs obscures. Si je comprends bien, c'est parce que le débogueur doit créer quelque chose comme un vidage dans la section NVS par défaut, mais à ce stade, le NVS est déjà utilisé par le contrôleur. Bien sûr, cela pourrait être contourné en créant 2 partitions NVS, l'une avec le nom par défaut pour le débogage et l'autre pour ses propres besoins. Mais il n'y avait rien de compliqué là-bas, dans le code ajouté, cela a fonctionné la première fois, donc je ne l'ai pas vérifié.


Glitches ESP32


Comme tout appareil avec Aliexpress, ma carte ESP32 avait la sienne, décrite nulle part. Quand elle est arrivée, j'ai alimenté certains périphériques qui fonctionnaient sur I2C à partir de la carte, mais après un certain temps, la carte a commencé à redémarrer si un équipement consommateur ou même juste un condensateur était attaché à la jambe + 5V. Pourquoi est-ce complètement incompréhensible?


Maintenant, j'alimente la carte à partir de la charge chinoise de 0,7 A, les capteurs ds18b20 du pied de la carte 3,3 V et le relais et le capteur de mouvement d'une autre charge de 2 A. Le pied GND de la carte est bien sûr connecté aux broches GND du reste du fer. Pas cher et gai est notre option.


À propos des résultats du projet


J'ai eu la possibilité de contrôler de manière flexible le chauffage de la maison, économisant ainsi de l'argent et de la sueur. À l'heure actuelle, si le chauffage maintient 23 degrés toute la journée à -5 - -7 à l'extérieur, c'est environ 11 heures de fonctionnement de la chaudière. Si pendant la journée pour maintenir 20 degrés et chauffer à 23 seulement le soir, alors c'est déjà 9 heures de fonctionnement de la chaudière. La capacité de la chaudière est de 6 kW, avec un prix actuel de kilowatts de 2,2 roubles, soit environ 26,4 roubles par jour. La durée de la saison de chauffage dans notre région est de 200 jours, la température moyenne de la saison de chauffage est d'environ -5 degrés. Ainsi, nous obtenons environ 5000r d'économies pour la saison de chauffage.


Le coût de l'équipement ne dépasse pas 2000r, c'est-à-dire qu'il sera repoussé dans quelques mois, sans parler du fait qu'un système prêt à l'emploi d'une telle automatisation coûterait au moins 20 000r. Une autre chose est que j'ai passé environ une semaine de pur temps de travail à écrire du firmware et à déboguer, mais au cours du travail, par exemple, j'ai finalement réalisé ce que sont les pointeurs en C ++ et j'ai acquis beaucoup d'autres expériences (par exemple, l'expérience de plusieurs heures de débogage de problèmes incompréhensibles). Et l'expérience, comme vous le savez, est difficile à surestimer.


Captures d'écran de l'application mobile Blynk:





Bien sûr, le code du projet n'est pas un chef-d'œuvre, mais je l'ai écrit dans des conditions de manque de temps et concentré principalement sur la lisibilité. Il n'y a tout simplement pas de temps pour refactoriser. En général, j'ai beaucoup d'excuses pour lesquelles mon code est si effrayant, mais c'est mon préféré, donc je vais m'y attarder, je ne développerai pas le sujet plus loin.


Si mon gribouillis aide quelqu'un, je serai sincèrement heureux. Je serai heureux de tout commentaire et suggestion.


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


All Articles