{"id":594,"date":"2019-08-23T15:36:49","date_gmt":"2019-08-23T13:36:49","guid":{"rendered":"http:\/\/miniprojets.net\/?p=594"},"modified":"2026-02-24T15:09:25","modified_gmt":"2026-02-24T14:09:25","slug":"creation-dun-enregistreur-autonome-de-puissance-electrique-monophase-base-sur-un-wemos-d1-mini-dun-shield-rtc-sd-et-dun-pzem004t","status":"publish","type":"post","link":"https:\/\/miniprojets.net\/index.php\/2019\/08\/23\/creation-dun-enregistreur-autonome-de-puissance-electrique-monophase-base-sur-un-wemos-d1-mini-dun-shield-rtc-sd-et-dun-pzem004t\/","title":{"rendered":"Cr\u00e9ation d&#8217;un enregistreur autonome de puissance \u00e9lectrique monophas\u00e9 bas\u00e9 sur un Wemos D1 mini, d&#8217;un shield RTC\/SD et d&#8217;un PZEM004T (Capteur BB1)"},"content":{"rendered":"\n<p>Bonjour,<\/p>\n\n\n\n<p>Il y a quelques temps, j&#8217;ai re\u00e7u comme probl\u00e9matique de trouver une solution pour monitorer la puissance du r\u00e9seau monophas\u00e9 sur un site ne disposant pas d&#8217;une infrastructure r\u00e9seau. Je vous propose donc de vous partager ma solution que je nomme BB1 pour BlackBox1 afin que vous puissiez aussi en profiter. Elle sera capable de faire les choses suivantes: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>  \u00catre auto-aliment\u00e9e par le point de mesure et \u00eatre mise dans un boitier railDIN (ceux utilis\u00e9 pour les RaspberryPi) <\/li>\n\n\n\n<li> Mesurer le courant, la tension, la puissance et la consommation (je viens de recevoir la V3 du PZEM004 donc je pense pouvoir avoir le facteur de puissance) <\/li>\n\n\n\n<li> Horodatage des donn\u00e9es et sauvegarde de celles-ci sur une carte SD <\/li>\n\n\n\n<li>Embarquer son propre serveur wifi avec une page web qui         permet de : (voir capture d&#8217;\u00e9cran en pi\u00e8ce-jointe)\n<ul class=\"wp-block-list\">\n<li> R\u00e9cup\u00e9rer directement le fichier CSV des donn\u00e9es (je vous mettrai un exemple en fin d&#8217;article)  <\/li>\n\n\n\n<li> \u00c9crire directement dans un fichier texte des notes (exemple observations, endroit o\u00f9 est plac\u00e9 le mat\u00e9riel,&#8230;.) <\/li>\n\n\n\n<li>  Il sera possible dans une prochaine version de la connecter sur  un r\u00e9seau wifi et d&#8217;envoyer les donn\u00e9es directement sur un  serveur distant.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li> \u00catre OpenSource et anti-obsolescence programm\u00e9e (chaque          module de la carte peut-\u00eatre remplac\u00e9 ou upgrad\u00e9 ind\u00e9pendamment          tout en \u00e9tant r\u00e9trocompatible) <\/li>\n\n\n\n<li> Poss\u00e9der une sortie permettant de piloter un relais  si n\u00e9cessaire (exemple: lancer automatiquement la machine \u00e0 caf\u00e9  le matin avant l&#8217;arriv\u00e9e de l&#8217;\u00e9quipe ^^) <\/li>\n<\/ul>\n\n\n\n<p>Pour information, le code source et le typon pour le mat\u00e9riel final seront disponibles \u00e0 la fin de cet article.  Si vous faites un copier\/coller du code pr\u00e9sent dans cette page, les sources sont sous licence<strong> CC-BY-NC-SA<\/strong> <a href=\"https:\/\/creativecommons.org\/licenses\/by-nc-sa\/3.0\/fr\/\">https:\/\/creativecommons.org\/licenses\/by-nc-sa\/3.0\/fr\/<\/a><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"403\" height=\"141\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/licence.png\" alt=\"\" class=\"wp-image-796\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/licence.png 403w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/licence-300x105.png 300w\" sizes=\"auto, (max-width: 403px) 100vw, 403px\" \/><\/figure>\n<\/div>\n\n\n<p>Juste un dernier avertisseur, nous allons travailler avec du 220v donc si vous n&#8217;avez jamais suivi de formation d&#8217;\u00e9lectricien, je vous d\u00e9conseille fortement de continuer ce tutoriel et dans tous les cas, pensez toujours \u00e0 d\u00e9connecter votre installation de toute source de puissance lorsque vous travaillez sur celle-ci.<\/p>\n\n\n\n<p class=\"has-large-font-size\">Partie 0: Le mat\u00e9riel choisi<\/p>\n\n\n\n<p>Pour ce projet, nous allons utiliser le mat\u00e9riel suivant:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un Wemos D1 mini<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"612\" height=\"580\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-6.png\" alt=\"\" class=\"wp-image-599\" style=\"width:395px;height:374px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-6.png 612w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-6-300x284.png 300w\" sizes=\"auto, (max-width: 612px) 100vw, 612px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un Shield combinant une RTC (Real Time Clock) et un lecteur de carte SD<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"758\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-5.png\" alt=\"\" class=\"wp-image-598\" style=\"width:382px;height:358px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-5.png 809w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-5-300x281.png 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-5-768x720.png 768w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un Capteur de puissance PZEM004T (V1 ou V3 seul le code change)<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"647\" height=\"748\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-7.png\" alt=\"\" class=\"wp-image-600\" style=\"width:352px;height:406px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-7.png 647w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-7-259x300.png 259w\" sizes=\"auto, (max-width: 647px) 100vw, 647px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un transformateur 220V AC vers 5V DC<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"497\" height=\"509\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-4.png\" alt=\"\" class=\"wp-image-597\" style=\"width:241px;height:247px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-4.png 497w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-4-293x300.png 293w\" sizes=\"auto, (max-width: 497px) 100vw, 497px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un Transistor PNP 2N2907 (je vous expliquerai son utilit\u00e9 plus tard)<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"218\" height=\"320\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-8.png\" alt=\"\" class=\"wp-image-601\" style=\"width:110px;height:161px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-8.png 218w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-8-204x300.png 204w\" sizes=\"auto, (max-width: 218px) 100vw, 218px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un convertisseur TTL vers USB<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"727\" height=\"595\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-9.png\" alt=\"\" class=\"wp-image-608\" style=\"width:299px;height:244px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-9.png 727w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-9-300x246.png 300w\" sizes=\"auto, (max-width: 727px) 100vw, 727px\" \/><\/figure>\n\n\n\n<p class=\"has-large-font-size\">Partie 1: Lire l&#8217;heure sur un Wemos D1 mini<\/p>\n\n\n\n<p>Lorsque l&#8217;on veux enregistrer des donn\u00e9es (par exemple de consommation), il est important de pouvoir les dater pour pouvoir les analyser correctement. La RTC (Real Time Clock) est un circuit qui nous permet de faire cela. La RTC est une horloge qui est aliment\u00e9e avec un pile bouton afin de continuer \u00e0 garder l&#8217;heure \u00e0 jour m\u00eame quand le montage n&#8217;est plus sous tension.<\/p>\n\n\n\n<p>Pour cette premi\u00e8re partie, le montage est vraiment simple. Il suffit de placer le shield comportant la RTC sur le Wemos de la fa\u00e7on suivante:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"961\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0691-1024x961.jpg\" alt=\"\" class=\"wp-image-628\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0691-1024x961.jpg 1024w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0691-300x282.jpg 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0691-768x721.jpg 768w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0691.jpg 1824w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Maintenant il faut relier le Wemos \u00e0 l&#8217;ordinateur et lancer Arduino.<\/p>\n\n\n\n<p>Si vous n&#8217;avez jamais utilis\u00e9 de Wemos, il vous faudra d&#8217;abord prendre la biblioth\u00e8que esp8266 dans le Gestionnaire de carte<\/p>\n\n\n\n<p>Pour cela, je vous conseille ce wiki qui est vraiment bien fait:<\/p>\n\n\n\n<p><a href=\"http:\/\/www.wikidebrouillard.org\/index.php?title=Wemos_D1_mini\">http:\/\/www.wikidebrouillard.org\/index.php?title=Wemos_D1_mini<\/a><\/p>\n\n\n\n<p>Il vous faudra aussi la biblioth\u00e8que RTC. Elle est t\u00e9l\u00e9chargeable \u00e0 l&#8217;adresse suivante: <\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/adafruit\/RTClib\">https:\/\/github.com\/adafruit\/RTClib<\/a><\/p>\n\n\n\n<p>Pour inclure cette librairie, dans l&#8217;IDE Arduino, cliquez sur Croquis &#8211;&gt; Inclure une biblioth\u00e8que &#8211;&gt; Ajouter la biblioth\u00e8que .Zip et indiquez l&#8217;emplacement de votre librairie<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"597\" height=\"593\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-10.png\" alt=\"\" class=\"wp-image-631\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-10.png 597w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-10-150x150.png 150w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-10-300x298.png 300w\" sizes=\"auto, (max-width: 597px) 100vw, 597px\" \/><\/figure>\n\n\n\n<p>Maintenant que tout est OK, vous pouvez configurer l&#8217;IDE Arduino de la fa\u00e7on suivante:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"522\" height=\"593\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-11.png\" alt=\"\" class=\"wp-image-632\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-11.png 522w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-11-264x300.png 264w\" sizes=\"auto, (max-width: 522px) 100vw, 522px\" \/><\/figure>\n\n\n\n<p>Le code sera le suivant: <\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"Wire.h\"\n#include \"RTClib.h\"\n\n\/\/ RTC variables\nRTC_DS1307 rtc;\nconst int sclPin = D1;\nconst int sdaPin = D2;\nchar daysOfTheWeek[7][12] = {\"Dimanche\", \"Lundi\", \"Mardi\", \"Mercredi\", \"Jeudi\", \"Vendredi\", \"Samedi\"};\n\n\nvoid setup () {\n\/\/ Pinout Setup\n  Wire.begin(sdaPin, sclPin);\n\n\/\/Communication Setup\n  Serial.begin(57600);\n  if (! rtc.begin()) {\n    Serial.println(\"Couldn't find RTC\");\n    while (1);\n  }\n\n  if (! rtc.isrunning()) {\n    Serial.println(\"RTC is NOT running!\");\n    \/\/ following line sets the RTC to the date & time this sketch was compiled\n    \/\/ rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));\n    \/\/ This line sets the RTC with an explicit date & time, for example to set\n    \/\/ January 21, 2014 at 3am you would call:\n    rtc.adjust(DateTime(2019, 8, 28, 3, 15, 44)); \/\/ \n  }\n  \n}\n\nvoid loop () {\n\/\/ RTC Part\n   DateTime now = rtc.now();\n    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);\n    Serial.print(\",  \");\n   \n    if (now.day() < 10)    {Serial.print('0');}\n    Serial.print(now.day(), DEC);\n    Serial.print('.');\n    if (now.month() < 10)  {Serial.print('0');}\n    Serial.print(now.month(), DEC);\n    Serial.print('.');\n    Serial.print(now.year(), DEC);\n    Serial.print(\",  \");\n   \n    if (now.hour() < 10)   {Serial.print('0');}\n    Serial.print(now.hour(), DEC);\n    Serial.print(':');\n    if (now.minute() < 10) {Serial.print('0');}\n    Serial.print(now.minute(), DEC);\n    Serial.print(':');\n    if (now.second() < 10) {Serial.print('0');}\n    Serial.print(now.second(), DEC);\n    Serial.print(\",  \");\n    Serial.println(); \n    delay(1000);\n}  <\/pre>\n\n\n\n<p>Si c'est la premi\u00e8re fois que vous mettez en route votre RTC, pensez \u00e0 modifier la ligne rtc.adjust(DateTime(2019, 8, 28, 3, 15, 44)); \/\/  avec une date l\u00e9g\u00e8rement dans le futur afin de la calibrer une premi\u00e8re fois. <\/p>\n\n\n\n<p>Vous pouvez remarquer que l'on utilise aussi la librairie \"wire\" afin de forcer l'usage des pin D1 et D2 pour leur assigner la communication I2C.<\/p>\n\n\n\n<p>Flashez le Wemos, ouvrez votre terminal et normalement, vous devriez avoir le r\u00e9sultat suivant:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"648\" height=\"459\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-12.png\" alt=\"\" class=\"wp-image-635\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-12.png 648w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-12-300x213.png 300w\" sizes=\"auto, (max-width: 648px) 100vw, 648px\" \/><\/figure>\n\n\n\n<p>Tadam! vous avez maintenant la possibilit\u00e9 d'horodater vos donn\u00e9es!<\/p>\n\n\n\n<p class=\"has-large-font-size\">Partie 2: Enregistrer les donn\u00e9es sur une carte SD<\/p>\n\n\n\n<p>Maintenant, nous allons passer \u00e0 la partie enregistrement des donn\u00e9es sur une carte SD. <\/p>\n\n\n\n<p>Ce qui est cool avec le shield choisi, c'est qu'en plus de la RTC, il embarque aussi un support pour carte microSD.<\/p>\n\n\n\n<p>Donc vous l'aurez compris, le montage sera ...... le m\u00eame que pour la partie pr\u00e9c\u00e9dente!<\/p>\n\n\n\n<p>Pour cette \u00e9tape, il vous faudra aussi les librairies SD et SPI qui sont normalement embarqu\u00e9es nativement dans l'IDE Arduino gr\u00e2ce \u00e0 l'ajout de la carte Wemos lors de l'\u00e9tape pr\u00e9c\u00e9dente.<\/p>\n\n\n\n<p>Avant de charger le code, il faut pr\u00e9parer la carte SD. <\/p>\n\n\n\n<p>Pour cela, il faut la formater en FAT puis cr\u00e9er un fichier vide datalog.txt. Une fois cette op\u00e9ration faite, vous pouvez mettre la carte dans le shield et Flasher le programme suivant sur le Wemos.<\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"SPI.h\"\n#include \"SD.h\"\n\n\/\/ SDcard variables\nconst int chipSelect = D8;\n\nvoid setup () {\n\/\/Communication Setup\n  Serial.begin(57600);\n  Serial.print(\"Initializing SD card...\");\n\n\/\/SDcard Setup\n  \/\/ see if the card is present and can be initialized:\n  if (!SD.begin(chipSelect)) {\n    Serial.println(\"Card failed, or not present\");\n    \/\/ don't do anything more:\n    return;\n  }\n  Serial.println(\"card initialized.\");\n}\n\nvoid loop () {\n\/\/SDCARD Part\n    File dataFile = SD.open(\"datalog.txt\", FILE_WRITE);\n  \/\/ if the file is available, write to it:\n  if (dataFile) {\n    dataFile.print(\"toto\");\n    Serial.println(\"toto\");\n    dataFile.println();\n    dataFile.close();\n  }\n  \/\/ if the file isn't open, pop up an error:\n  else {\n    Serial.println(\"error opening datalog.csv\");\n  }\n  delay(10000); \/\/10secondes\n}    <\/pre>\n\n\n\n<p> Si vous lancez le terminal, vous devriez voir apparaitre toutes les 10 secondes un toto <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"462\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-13.png\" alt=\"\" class=\"wp-image-639\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-13.png 646w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-13-300x215.png 300w\" sizes=\"auto, (max-width: 646px) 100vw, 646px\" \/><\/figure>\n\n\n\n<p>Maintenant arr\u00eatez votre montage, enlevez la carte SD et mettez la sur votre PC. Si tout c'est bien pass\u00e9, vous devriez avoir le fichier datalog.txt  qui c'est rempli de totos.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"382\" height=\"313\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-14.png\" alt=\"\" class=\"wp-image-641\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-14.png 382w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-14-300x246.png 300w\" sizes=\"auto, (max-width: 382px) 100vw, 382px\" \/><\/figure>\n\n\n\n<p>C'est ok? Parfait!!!! Par contre, il est peu pratique de devoir arr\u00eater ses mesures pour les relever... Mais heureusement, le Wemos  embarque une puce wifi et nous offre la possibilit\u00e9 de faire notre propre point d'acc\u00e8s wifi!!!<\/p>\n\n\n\n<p class=\"has-large-font-size\">Partie 3: Cr\u00e9er un point d'acc\u00e8s Wifi<\/p>\n\n\n\n<p>Pour notre capteur, comme nous ne savons pas s'il y aura un routeur wifi accessible, j'ai d\u00e9cid\u00e9 de partir sur la cr\u00e9ation du point d'acc\u00e8s wifi directement embarqu\u00e9 dans le Wemos. <\/p>\n\n\n\n<p>Pour cela, il existe d\u00e9j\u00e0 un code tout fait dans les exemples de l'ESP8266<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"796\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-15.png\" alt=\"\" class=\"wp-image-646\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-15.png 730w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-15-275x300.png 275w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/figure>\n\n\n\n<p>Pensez \u00e0 changer le SSID ainsi que le mot de passe, flashez le code et ouvrez le terminal <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"661\" height=\"359\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-16.png\" alt=\"\" class=\"wp-image-647\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-16.png 661w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-16-300x163.png 300w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/figure>\n\n\n\n<p>Maintenant connectez vous sur le SSID que vous avez choisi (ici ESPap avec le mot de passe thereisnospoon)<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"364\" height=\"262\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/image.png\" alt=\"\" class=\"wp-image-806\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/image.png 364w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/image-300x216.png 300w\" sizes=\"auto, (max-width: 364px) 100vw, 364px\" \/><\/figure>\n\n\n\n<p>Ouvrez un navigateur internet et tapez l'adresse suivante: 192.168.4.1<\/p>\n\n\n\n<p>Normalement, vous devriez avoir cette page qui apparait.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"908\" height=\"308\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-18.png\" alt=\"\" class=\"wp-image-651\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-18.png 908w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-18-300x102.png 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-18-768x261.png 768w\" sizes=\"auto, (max-width: 908px) 100vw, 908px\" \/><\/figure>\n\n\n\n<p>Voil\u00e0, nous savons communiquer avec notre Wemos via le r\u00e9seau Wifi! <\/p>\n\n\n\n<p>Passons aux choses s\u00e9rieuses en mixant l'usage de la carte SD avec les possibilit\u00e9s du Wifi.<\/p>\n\n\n\n<p class=\"has-large-font-size\">Partie 4: R\u00e9cup\u00e9rer des fichiers sur une page Web embarqu\u00e9e<\/p>\n\n\n\n<p>Comme ce que l'on a vu pr\u00e9c\u00e9demment, ce qui nous int\u00e9resse, c'est de pouvoir r\u00e9cup\u00e9rer un fichier sans devoir arr\u00eater le capteur.<\/p>\n\n\n\n<p>Pour cela, nous allons mixer deux exemples de code et rajouter quelques fichiers sur la carte SD. <\/p>\n\n\n\n<p>Pour les codes qui seront m\u00e9lang\u00e9s, il s'agit du pr\u00e9c\u00e9dent avec le code SDWebServer qui se trouve dans les exemples ESP8266WebServer<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"693\" height=\"586\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-19.png\" alt=\"\" class=\"wp-image-654\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-19.png 693w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-19-300x254.png 300w\" sizes=\"auto, (max-width: 693px) 100vw, 693px\" \/><\/figure>\n\n\n\n<p>Pour faire simple, on va utiliser les parties de cr\u00e9ation d'un Point d'acc\u00e8s wifi avec la possibilit\u00e9 de pouvoir lire et modifier ce qui existe sur la carte SD via une page WEB.<\/p>\n\n\n\n<p>Le code \u00e0 Flasher sur le Wemos est le suivant:<\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"SPI.h\"\n#include \"SD.h\"\n#include \"ESP8266WiFi.h\"\n#include \"WiFiClient.h\"\n#include \"ESP8266WebServer.h\"\n\n\/\/ SDcard variables\nstatic bool hasSD = false;\nconst int chipSelect = D8;\nFile uploadFile;\n\n\/\/ Wifi Variables\n#ifndef APSSID\n#define APSSID \"ESPap\"\n#define APPSK  \"thereisnospoon\"\n#endif\n\/* Set these to your desired credentials. *\/\nint counter =0;\nconst char *ssid = APSSID;\nconst char *password = APPSK;\nESP8266WebServer server(80);\n\/* Just a little test message.  Go to http:\/\/192.168.4.1 in a web browser\n   connected to this access point to see it.\n*\/\n\nvoid returnOK() {\n  server.send(200, \"text\/plain\", \"\");\n}\n\nvoid returnFail(String msg) {\n  server.send(500, \"text\/plain\", msg + \"\\r\\n\");\n}\n\nbool loadFromSdCard(String path) {\n\n  Serial.print(path);\n  String dataType = \"text\/plain\";\n  if (path.endsWith(\"\/\")) {\n    path += \"index.htm\";\n  }\n\n  if (path.endsWith(\".src\")) {\n    path = path.substring(0, path.lastIndexOf(\".\"));\n  } else if (path.endsWith(\".htm\")) {\n    dataType = \"text\/html\";\n  } else if (path.endsWith(\".css\")) {\n    dataType = \"text\/css\";\n  } else if (path.endsWith(\".js\")) {\n    dataType = \"application\/javascript\";\n  } else if (path.endsWith(\".png\")) {\n    dataType = \"image\/png\";\n  } else if (path.endsWith(\".gif\")) {\n    dataType = \"image\/gif\";\n  } else if (path.endsWith(\".jpg\")) {\n    dataType = \"image\/jpeg\";\n  } else if (path.endsWith(\".ico\")) {\n    dataType = \"image\/x-icon\";\n  } else if (path.endsWith(\".xml\")) {\n    dataType = \"text\/xml\";\n  } else if (path.endsWith(\".pdf\")) {\n    dataType = \"application\/pdf\";\n  } else if (path.endsWith(\".zip\")) {\n    dataType = \"application\/zip\";\n  }\n\n  File dataFile = SD.open(path.c_str());\n  if (dataFile.isDirectory()) {\n    path += \"\/index.htm\";\n    dataType = \"text\/html\";\n    Serial.print(path.c_str());\n    dataFile = SD.open(path.c_str());\n  }\n\n  if (!dataFile) {\n\n    return false;\n  }\n\n  if (server.hasArg(\"download\")) {\n    dataType = \"application\/octet-stream\";\n  }\n\n  if (server.streamFile(dataFile, dataType) != dataFile.size()) {\n    Serial.println(\"Sent less data than expected!\");\n  }\n\n  dataFile.close();\n\n  return true;\n}\n\nvoid handleFileUpload() {\n  if (server.uri() != \"\/edit\") {\n    return;\n  }\n  HTTPUpload& upload = server.upload();\n  if (upload.status == UPLOAD_FILE_START) {\n    if (SD.exists((char *)upload.filename.c_str())) {\n      SD.remove((char *)upload.filename.c_str());\n    }\n    uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);\n    Serial.print(\"Upload: START, filename: \"); Serial.println(upload.filename);\n  } else if (upload.status == UPLOAD_FILE_WRITE) {\n    if (uploadFile) {\n      uploadFile.write(upload.buf, upload.currentSize);\n    }\n    Serial.print(\"Upload: WRITE, Bytes: \"); Serial.println(upload.currentSize);\n  } else if (upload.status == UPLOAD_FILE_END) {\n    if (uploadFile) {\n      uploadFile.close();\n    }\n    Serial.print(\"Upload: END, Size: \"); Serial.println(upload.totalSize);\n  }\n}\n\nvoid deleteRecursive(String path) {\n  File file = SD.open((char *)path.c_str());\n  if (!file.isDirectory()) {\n    file.close();\n    SD.remove((char *)path.c_str());\n    return;\n  }\n\n  file.rewindDirectory();\n  while (true) {\n    File entry = file.openNextFile();\n    if (!entry) {\n      break;\n    }\n    String entryPath = path + \"\/\" + entry.name();\n    if (entry.isDirectory()) {\n      entry.close();\n      deleteRecursive(entryPath);\n    } else {\n      entry.close();\n      SD.remove((char *)entryPath.c_str());\n    }\n    yield();\n  }\n\n  SD.rmdir((char *)path.c_str());\n  file.close();\n}\n\nvoid handleDelete() {\n  if (server.args() == 0) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(0);\n  if (path == \"\/\" || !SD.exists((char *)path.c_str())) {\n    returnFail(\"BAD PATH\");\n    return;\n  }\n  deleteRecursive(path);\n  returnOK();\n}\n\nvoid handleCreate() {\n  if (server.args() == 0) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(0);\n  if (path == \"\/\" || SD.exists((char *)path.c_str())) {\n    returnFail(\"BAD PATH\");\n    return;\n  }\n\n  if (path.indexOf('.') > 0) {\n    File file = SD.open((char *)path.c_str(), FILE_WRITE);\n    if (file) {\n      file.write((const char *)0);\n      file.close();\n    }\n  } else {\n    SD.mkdir((char *)path.c_str());\n  }\n  returnOK();\n}\n\nvoid printDirectory() {\n  if (!server.hasArg(\"dir\")) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(\"dir\");\n  if (path != \"\/\" && !SD.exists((char *)path.c_str())) {\n    return returnFail(\"BAD PATH\");\n  }\n  File dir = SD.open((char *)path.c_str());\n  path = String();\n  if (!dir.isDirectory()) {\n    dir.close();\n    return returnFail(\"NOT DIR\");\n  }\n  dir.rewindDirectory();\n  server.setContentLength(CONTENT_LENGTH_UNKNOWN);\n  server.send(200, \"text\/json\", \"\");\n  WiFiClient client = server.client();\n\n  server.sendContent(\"[\");\n  for (int cnt = 0; true; ++cnt) {\n    File entry = dir.openNextFile();\n    if (!entry) {\n      break;\n    }\n\n    String output;\n    if (cnt > 0) {\n      output = ',';\n    }\n\n    output += \"{\\\"type\\\":\\\"\";\n    output += (entry.isDirectory()) ? \"dir\" : \"file\";\n    output += \"\\\",\\\"name\\\":\\\"\";\n    output += entry.name();\n    output += \"\\\"\";\n    output += \"}\";\n    server.sendContent(output);\n    entry.close();\n  }\n  server.sendContent(\"]\");\n  dir.close();\n}\n\nvoid handleNotFound() {\n  if (hasSD && loadFromSdCard(server.uri())) {\n    return;\n  }\n  String message = \"SDCARD Not Detected\\n\\n\";\n  message += \"URI: \";\n  message += server.uri();\n  message += \"\\nMethod: \";\n  message += (server.method() == HTTP_GET) ? \"GET\" : \"POST\";\n  message += \"\\nArguments: \";\n  message += server.args();\n  message += \"\\n\";\n  for (uint8_t i = 0; i < server.args(); i++) {\n    message += \" NAME:\" + server.argName(i) + \"\\n VALUE:\" + server.arg(i) + \"\\n\";\n  }\n  server.send(404, \"text\/plain\", message);\n  Serial.print(message);\n}\n\/\/ WEBSERVER declaration end\n\n\n\nvoid setup () {\n\/\/Communication Setup\n  Serial.begin(57600);\n  Serial.print(\"Initializing SD card...\");\n\n\/\/SDcard Setup\n  \/\/ see if the card is present and can be initialized:\n  if (!SD.begin(chipSelect)) {\n    Serial.println(\"Card failed, or not present\");\n    \/\/ don't do anything more:\n    return;\n  }\n  Serial.println(\"card initialized.\");\n  hasSD = true;\n\n\n\/\/ Wifi setup    \n  Serial.print(\"Configuring access point...\");\n  \/* You can remove the password parameter if you want the AP to be open. *\/\n  WiFi.softAP(ssid, password);\n\n  IPAddress myIP = WiFi.softAPIP();\n  Serial.print(\"AP IP address: \");\n  Serial.println(myIP);\n  server.on(\"\/list\", HTTP_GET, printDirectory);\n  server.on(\"\/edit\", HTTP_DELETE, handleDelete);\n  server.on(\"\/edit\", HTTP_PUT, handleCreate);\n  server.on(\"\/edit\", HTTP_POST, []() {\n    returnOK();\n  }, handleFileUpload);\n  server.onNotFound(handleNotFound);  \n  \n  server.begin();\n  Serial.println(\"HTTP server started\");\n  \n}\n\nvoid loop () {\n server.handleClient();\n delay(100);\n}    <\/pre>\n\n\n\n<p>Il faut aussi mettre les fichiers ci-dessous sur la carte SD (ne pas mettre le dossier SDRoot mais directement les fichiers et dossiers qui sont dedans): <\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/SdRoot.7z\">SdRoot<\/a><a href=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/SdRoot.7z\" class=\"wp-block-file__button wp-element-button\" download>Download<\/a><\/div>\n\n\n\n<p>Vous pouvez aussi les retrouver dans le dossier de la librairie Arduino du  ESP8266 --&gt;  ESP8266Arduino-master\\Arduino-master\\libraries\\ESP8266WebServer\\examples\\SDWebServer\\SdRoot<\/p>\n\n\n\n<p>Maintenant que vous avez flash\u00e9 le Wemos, connectez vous sur le wifi de celui-ci. Une fois cela fais, allez sur la page web suivante: 192.168.4.1\/edit<\/p>\n\n\n\n<p>Vous tomberez sur cette page:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"903\" height=\"483\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-20.png\" alt=\"\" class=\"wp-image-658\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-20.png 903w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-20-300x160.png 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-20-768x411.png 768w\" sizes=\"auto, (max-width: 903px) 100vw, 903px\" \/><\/figure>\n\n\n\n<p>Si vous cliquez droit sur un fichier, vous aurez la possibilit\u00e9 de le modifier, de le t\u00e9l\u00e9charger ou de le supprimer. C'est plut\u00f4t cool non?<\/p>\n\n\n\n<p>Maintenant que l'on ai capable d'horodater une donn\u00e9e, de la stocker dans un fichier sur une carte SD et en plus de la r\u00e9cup\u00e9rer via une page WEB, il nous reste \u00e0 savoir comment communiquer avec un capteur PZEM004T. Vous \u00eates pr\u00eat? Oui? bon c'est parti!<\/p>\n\n\n\n<p class=\"has-large-font-size\">Partie 5: Mesurer les valeurs \u00e9lectriques avec un PZEM004T<\/p>\n\n\n\n<p>Le but de cette partie est de pouvoir lire un capteur de puissance \u00e9lectrique nomm\u00e9 PZEM004T. Mais que fait donc ce capteur me direz vous? Et bien \u00e7a d\u00e9pend de sa version.<\/p>\n\n\n\n<p><strong>La version 1:<\/strong> <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"769\" height=\"776\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-21.png\" alt=\"\" class=\"wp-image-659\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-21.png 769w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-21-150x150.png 150w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-21-297x300.png 297w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-21-768x775.png 768w\" sizes=\"auto, (max-width: 769px) 100vw, 769px\" \/><\/figure>\n\n\n\n<p>Cette version peut r\u00e9cup\u00e9rer comme informations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La tension du r\u00e9seau (en V)<\/li>\n\n\n\n<li>Le courant (en A)<\/li>\n\n\n\n<li>La puissance active (en W)<\/li>\n\n\n\n<li>La consommation (en kWh)<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Valeur<\/th><th>Plage de mesure<\/th><th>R\u00e9solution<\/th><th>Pr\u00e9cision<\/th><\/tr><\/thead><tbody><tr><td>Tension<\/td><td>80~260V<\/td><td>0.1V<\/td><td>0.5%<\/td><\/tr><tr><td>Courant<\/td><td>0~10A or 0~100A*<\/td><td>0.01A or 0.02A*<\/td><td>0.5%<\/td><\/tr><tr><td>Puissance<br>\n            <\/td><td>0~2.3kW or 0~23kW*<\/td><td>0.1W<\/td><td>0.5%<\/td><\/tr><tr><td>\u00c9nergie<br>             <\/td><td>0~9999.99kWh<\/td><td>1Wh<\/td><td>0.5%<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Elle se diff\u00e9rencie de la version 3 par son tore (la bobine noire qui permet d'avoir une image du courant qui ne peux pas s'ouvrir dans cette version) et sa possibilit\u00e9 de rajouter un afficheur directement sur le capteur.<\/p>\n\n\n\n<p><strong>La version 3:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"715\" height=\"630\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-22.png\" alt=\"\" class=\"wp-image-661\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-22.png 715w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-22-300x264.png 300w\" sizes=\"auto, (max-width: 715px) 100vw, 715px\" \/><\/figure>\n\n\n\n<p>Cette version est plus \u00e9volu\u00e9e car elle est capable de mesurer les valeurs suivantes: <\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Valeur<\/th><th>Plage de mesure<\/th><th>R\u00e9solution<\/th><th>Pr\u00e9cision <\/th><\/tr><\/thead><tbody><tr><td>Tension<\/td><td>80~260V<\/td><td>0.1V<\/td><td>0.5% <\/td><\/tr><tr><td>Courant<\/td><td>0~10A or 0~100A*<\/td><td>0.01A or 0.02A*<\/td><td>0.5%<\/td><\/tr><tr><td>Puissance<br>\n            <\/td><td>0~2.3kW or 0~23kW*<\/td><td>0.1W<\/td><td>0.5%<\/td><\/tr><tr><td>\u00c9nergie<br>             <\/td><td>0~9999.99kWh<\/td><td>1Wh<\/td><td>0.5%<\/td><\/tr><tr><td>Fr\u00e9quence<\/td><td>45~65Hz<\/td><td>0.1Hz<\/td><td>0.5%<\/td><\/tr><tr><td>Facteur de puissance<br>\n            <\/td><td>0.00~1.00<\/td><td>0.01<\/td><td>1%<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Et il a pour avantage de poss\u00e9der un tore s\u00e9cable donc plus besoin de d\u00e9monter le circuit complet pour l'installer.<\/p>\n\n\n\n<p>Maintenant que nous connaissons ces capacit\u00e9s, nous pouvons passer \u00e0 sa mise en \u0153uvre. Au niveau mat\u00e9riel, nous aurons besoin de rajouter un transistor PNP ainsi qu'un convertisseur FTDI TTL &lt;-&gt; USB<\/p>\n\n\n\n<p>Pour ce qui est du c\u00e2blage du point de mesure, les 2 versions sont identiques et s'effectue de la fa\u00e7on suivante:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"708\" height=\"253\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-27.png\" alt=\"\" class=\"wp-image-673\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-27.png 708w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-27-300x107.png 300w\" sizes=\"auto, (max-width: 708px) 100vw, 708px\" \/><\/figure>\n\n\n\n<p>En ce qui concerne le c\u00e2blage entre le PZEM et le Wemos il y a une l\u00e9g\u00e8re diff\u00e9rence selon la version utilis\u00e9e.<\/p>\n\n\n\n<p><strong>Version 1: <\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"653\" height=\"310\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-24.png\" alt=\"\" class=\"wp-image-668\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-24.png 653w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-24-300x142.png 300w\" sizes=\"auto, (max-width: 653px) 100vw, 653px\" \/><\/figure>\n\n\n\n<p>Une modification est aussi \u00e0 faire sur le PZEM004T v1 afin de le rendre compatible avec le TTL du Wemos qui est en 3.3v. Il faut rajouter une r\u00e9sistance de 1k \u03a9 comme la photo ci-dessous.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"998\" height=\"1024\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-26-998x1024.png\" alt=\"\" class=\"wp-image-672\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-26-998x1024.png 998w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-26-292x300.png 292w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-26-768x788.png 768w\" sizes=\"auto, (max-width: 998px) 100vw, 998px\" \/><\/figure>\n\n\n\n<p><strong> Version 3: <\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"596\" height=\"291\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-25.png\" alt=\"\" class=\"wp-image-669\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-25.png 596w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-25-300x146.png 300w\" sizes=\"auto, (max-width: 596px) 100vw, 596px\" \/><\/figure>\n\n\n\n<p>Pas besoin de modification du PZEM pour cette version.<\/p>\n\n\n\n<p>La pr\u00e9sence du transistor permet de mettre le GPIO15 du Wemos au 0 logique et lui permettre de booter sur le Flash SPI. Si l'on reliait directement les 2 connecteurs ensemble l'octocoupleur forcerait au 1 logique le GPIO15 ce qui ferait reseter tout le temps le Wemos. <\/p>\n\n\n\n<p>On utilise aussi le convertisseur FTDI TTL&lt;-&gt;USB car le Wemos poss\u00e8de 2 UARTs UART0 (qui servira pour la communication avec le PZEM) et UART1 (qui est unidirectionnel ce qui veux dire qu'il ne sert qu'\u00e0 envoyer des informations mais ne peux pas en r\u00e9cup\u00e9rer)<\/p>\n\n\n\n<p>Ces explications sont tir\u00e9es du site: <a href=\"https:\/\/github.com\/olehs\/PZEM004T\/wiki\/Connecting-PZEM-to-ESP8266\">https:\/\/github.com\/olehs\/PZEM004T\/wiki\/Connecting-PZEM-to-ESP8266<\/a><\/p>\n\n\n\n<p>Maintenant que le c\u00e2blage est fait, passons au code:<\/p>\n\n\n\n<p>Vous aurez besoin de 2 librairies en plus (Une par version de PZEM)<\/p>\n\n\n\n<p>La premi\u00e8re  pour la version1 se trouve ici: <a href=\"https:\/\/github.com\/olehs\/PZEM004T\">https:\/\/github.com\/olehs\/PZEM004T<\/a> <\/p>\n\n\n\n<p>La deuxi\u00e8me pour la version 3 se trouve ici: <a href=\"https:\/\/github.com\/mandulaj\/PZEM-004T-v30\">https:\/\/github.com\/mandulaj\/PZEM-004T-v30<\/a><\/p>\n\n\n\n<p>Utilisez la m\u00eame m\u00e9thode pour les inclurent que pour les librairies pr\u00e9c\u00e9dentes.<\/p>\n\n\n\n<p>Maintenant voici les codes pour chacune des versions:<\/p>\n\n\n\n<p>Version 1: <\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"PZEM004T.h\"\n\n\/\/ Pzem004 variables\nfloat v = 0;\nfloat i = 0; \nfloat p =0;\nfloat e = 0;\nHardwareSerial hwSerial(UART0);     \/\/ Use hwSerial1 UART0 at pins GPIO1 (TX) and GPIO3 (RX)\nPZEM004T pzem(&hwSerial);           \/\/ Attach PZEM to hwSerial1\nIPAddress ip(192,168,1,1);\nbool pzemrdy = false;\n\nvoid setup () {\n\/\/Communication Setup\n  Serial1.begin(57600);\n\n\/\/ PZEM004T Setup\n  while (!pzemrdy) {\n      Serial1.println(\"Connecting to PZEM...\");\n      pzemrdy = pzem.setAddress(ip);\n      delay(1000);\n   }\n}\n\nvoid loop () {\n\/\/PZEM Part\n  v = pzem.voltage(ip);\n  if (v < 0.0) v = 0.0;\n   Serial1.print(v);Serial1.print(\"V; \");\n   i = pzem.current(ip);\n   if(i >= 0.0){ Serial1.print(i);Serial1.print(\"A; \"); }\n  p = pzem.power(ip);\n   if(p >= 0.0){ Serial1.print(p);Serial1.print(\"W; \"); }\n   e = pzem.energy(ip);\n   if(e >= 0.0){ Serial1.print(e);Serial1.print(\"Wh; \"); } \n   Serial1.println();\n}    <\/pre>\n\n\n\n<p><strong>Version 3: <\/strong><\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"PZEM004Tv30.h\"\n\n\/\/ Pzem004 variables\nfloat v = 0;\nfloat i = 0; \nfloat p =0;\nfloat e = 0;\nfloat freq;\nfloat pf;\nHardwareSerial hwSerial(UART0);     \/\/ Use hwSerial1 UART0 at pins GPIO1 (TX) and GPIO3 (RX)\nPZEM004Tv30 pzem(&hwSerial);           \/\/ Attach PZEM to hwSerial1\nbool pzemrdy = false;\n\nvoid setup () {\n\/\/Communication Setup\n  Serial1.begin(57600);\n\/\/PZEM\npzem.setAddress(0x42);\n}\n\nvoid loop () {\n\/\/PZEM Part\n  v = pzem.voltage();\n  if (v < 0.0) v = 0.0;\n   Serial1.print(v);Serial1.print(\"V; \");\n   i = pzem.current();\n   if(i >= 0.0){ Serial1.print(i);Serial1.print(\"A; \"); }\n  p = pzem.power();\n   if(p >= 0.0){ Serial1.print(p);Serial1.print(\"W; \"); }\n   e = pzem.energy();\n   if(e >= 0.0){ Serial1.print(e);Serial1.print(\"Wh; \"); } \n  freq = pzem.frequency();\n  Serial1.print(\"Frequency: \");\n  Serial1.print(freq);\n  Serial1.print(\"Hz;\");\n  pf = pzem.pf();\n  Serial1.print(\"PF: \");\n  Serial1.println(pf);\n}    <\/pre>\n\n\n\n<p>Vous pouvez flasher le Wemos, d\u00e9brancher le c\u00e2ble USB, mettre en route votre installation \u00e9lectrique et brancher le FTDI sur votre PC. Choisissez ensuite le port COM correspondant et regardez sur le terminal ce que cela donne. <\/p>\n\n\n\n<p>Vous devriez avoir ce genre de r\u00e9sultat: <\/p>\n\n\n\n<p><strong>Version 1:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"675\" height=\"361\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-28.png\" alt=\"\" class=\"wp-image-684\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-28.png 675w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-28-300x160.png 300w\" sizes=\"auto, (max-width: 675px) 100vw, 675px\" \/><\/figure>\n\n\n\n<p><strong>Version 3:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"663\" height=\"366\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/v3.png\" alt=\"\" class=\"wp-image-685\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/v3.png 663w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/v3-300x166.png 300w\" sizes=\"auto, (max-width: 663px) 100vw, 663px\" \/><\/figure>\n\n\n\n<p>Voil\u00e0 maintenant nous maitrisons toutes les facettes du capteur. Nous pouvons maintenant les assembler.<\/p>\n\n\n\n<p class=\"has-large-font-size\">Partie 6: Montage \u00e9lectronique final<\/p>\n\n\n\n<p>J'ai r\u00e9uni tous les composants sur une plaque test pour tester ensemble et vous montrer les diff\u00e9rentes parties.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0703-1024x576.jpg\" alt=\"\" class=\"wp-image-697\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0703-1024x576.jpg 1024w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0703-300x169.jpg 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0703-768x432.jpg 768w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0703-1140x641.jpg 1140w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0703-720x405.jpg 720w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">A droite le transformateur 200v-&gt;5V, en haut le PZEM, en Bas le Wemos avec le shield RTC+SD<\/figcaption><\/figure>\n\n\n\n<p>Maintenant que tous les \u00e9l\u00e9ments sont test\u00e9s, il nous reste \u00e0  les assembler sur une \"carte m\u00e8re\" afin de cr\u00e9er notre capteur tout en un qui soit utilisable dans une armoire \u00e9lectrique.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"606\" height=\"735\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-29.png\" alt=\"\" class=\"wp-image-691\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-29.png 606w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-29-247x300.png 247w\" sizes=\"auto, (max-width: 606px) 100vw, 606px\" \/><\/figure>\n\n\n\n<p>Voici le pdf du typon<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/BB1_Typon.pdf\">BB1_Typon<\/a><a href=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/BB1_Typon.pdf\" class=\"wp-block-file__button wp-element-button\" download>Download<\/a><\/div>\n\n\n\n<p>Sur le design de la carte, j'ai laiss\u00e9 la possibilit\u00e9 d'avoir un bouton de reset ainsi que d'utiliser la pin D0 en signal d'entr\u00e9e ou de sortie.<\/p>\n\n\n\n<p>J'ai ajouter le mini transformateur 220v AC vers 5V DC<\/p>\n\n\n\n<p>J'ai aussi modifier le PZEM afin qu'il n'y ai pas de fil volant.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0702-1024x576.jpg\" alt=\"\" class=\"wp-image-698\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0702-1024x576.jpg 1024w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0702-300x169.jpg 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0702-768x432.jpg 768w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0702-1140x641.jpg 1140w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/DSC_0702-720x405.jpg 720w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>La carte finale normalement donne cela:<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/20190909_102437-1-e1568022546768-768x1024.jpg\" alt=\"\" class=\"wp-image-760\" style=\"width:390px;height:520px\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/20190909_102437-1-e1568022546768-768x1024.jpg 768w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/09\/20190909_102437-1-e1568022546768-225x300.jpg 225w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p class=\"has-large-font-size\">Partie 7: Code final<\/p>\n\n\n\n<p>Pour le code final, j'ai apport\u00e9 quelques menues modifications afin que les donn\u00e9es soient \u00e9crites dans un fichier .csv et non .txt. J'ai aussi modifi\u00e9 les fichiers de la carte SD afin de mettre le logo du laboratoire.<\/p>\n\n\n\n<p>Pour la version PZEM004T V1<\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"Wire.h\"\n#include \"PZEM004T.h\"\n#include \"RTClib.h\"\n#include \"SPI.h\"\n#include \"SD.h\"\n#include \"ESP8266WiFi.h\"\n#include \"WiFiClient.h\"\n#include \"ESP8266WebServer.h\"\n\n\/\/ Echantillonage\nint temps = 10; \/\/en secondes\n\n\/\/ Pzem004 variables\nfloat v = 0;\nfloat i = 0; \nfloat p =0;\nfloat e = 0;\nHardwareSerial hwSerial(UART0);     \/\/ Use hwSerial1 UART0 at pins GPIO1 (TX) and GPIO3 (RX)\nPZEM004T pzem(&hwSerial);           \/\/ Attach PZEM to hwSerial1\nIPAddress ip(192,168,1,1);\nbool pzemrdy = false;\n\n\/\/ RTC variables\nRTC_DS1307 rtc;\nconst int sclPin = D1;\nconst int sdaPin = D2;\nchar daysOfTheWeek[7][12] = {\"Dimanche\", \"Lundi\", \"Mardi\", \"Mercredi\", \"Jeudi\", \"Vendredi\", \"Samedi\"};\n\n\/\/ SDcard variables\nstatic bool hasSD = false;\nconst int chipSelect = D8;\nFile uploadFile;\n\n\/\/ Wifi Variables\n#ifndef APSSID\n#define APSSID \"ESPap\"\n#define APPSK  \"thereisnospoon\"\n#endif\n\/* Set these to your desired credentials. *\/\nint counter =0;\nconst char *ssid = APSSID;\nconst char *password = APPSK;\nESP8266WebServer server(80);\n\/* Just a little test message.  Go to http:\/\/192.168.4.1 in a web browser\n   connected to this access point to see it.\n*\/\n\n\/\/ Prototypes des fonctions\nvoid MesureLectureEcriture(void);\n\nvoid returnOK() {\n  server.send(200, \"text\/plain\", \"\");\n}\n\nvoid returnFail(String msg) {\n  server.send(500, \"text\/plain\", msg + \"\\r\\n\");\n}\n\nbool loadFromSdCard(String path) {\n\n  Serial1.print(path);\n  String dataType = \"text\/plain\";\n  if (path.endsWith(\"\/\")) {\n    path += \"index.htm\";\n  }\n\n  if (path.endsWith(\".src\")) {\n    path = path.substring(0, path.lastIndexOf(\".\"));\n  } else if (path.endsWith(\".htm\")) {\n    dataType = \"text\/html\";\n  } else if (path.endsWith(\".css\")) {\n    dataType = \"text\/css\";\n  } else if (path.endsWith(\".js\")) {\n    dataType = \"application\/javascript\";\n  } else if (path.endsWith(\".png\")) {\n    dataType = \"image\/png\";\n  } else if (path.endsWith(\".gif\")) {\n    dataType = \"image\/gif\";\n  } else if (path.endsWith(\".jpg\")) {\n    dataType = \"image\/jpeg\";\n  } else if (path.endsWith(\".ico\")) {\n    dataType = \"image\/x-icon\";\n  } else if (path.endsWith(\".xml\")) {\n    dataType = \"text\/xml\";\n  } else if (path.endsWith(\".pdf\")) {\n    dataType = \"application\/pdf\";\n  } else if (path.endsWith(\".zip\")) {\n    dataType = \"application\/zip\";\n  }\n\n  File dataFile = SD.open(path.c_str());\n  if (dataFile.isDirectory()) {\n    path += \"\/index.htm\";\n    dataType = \"text\/html\";\n    Serial1.print(path.c_str());\n    dataFile = SD.open(path.c_str());\n  }\n\n  if (!dataFile) {\n\n    return false;\n  }\n\n  if (server.hasArg(\"download\")) {\n    dataType = \"application\/octet-stream\";\n  }\n\n  if (server.streamFile(dataFile, dataType) != dataFile.size()) {\n    Serial1.println(\"Sent less data than expected!\");\n  }\n\n  dataFile.close();\n\n  return true;\n}\n\nvoid handleFileUpload() {\n  if (server.uri() != \"\/edit\") {\n    return;\n  }\n  HTTPUpload& upload = server.upload();\n  if (upload.status == UPLOAD_FILE_START) {\n    if (SD.exists((char *)upload.filename.c_str())) {\n      SD.remove((char *)upload.filename.c_str());\n    }\n    uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);\n    Serial1.print(\"Upload: START, filename: \"); Serial1.println(upload.filename);\n  } else if (upload.status == UPLOAD_FILE_WRITE) {\n    if (uploadFile) {\n      uploadFile.write(upload.buf, upload.currentSize);\n    }\n    Serial1.print(\"Upload: WRITE, Bytes: \"); Serial1.println(upload.currentSize);\n  } else if (upload.status == UPLOAD_FILE_END) {\n    if (uploadFile) {\n      uploadFile.close();\n    }\n    Serial1.print(\"Upload: END, Size: \"); Serial1.println(upload.totalSize);\n  }\n}\n\nvoid deleteRecursive(String path) {\n  File file = SD.open((char *)path.c_str());\n  if (!file.isDirectory()) {\n    file.close();\n    SD.remove((char *)path.c_str());\n    return;\n  }\n\n  file.rewindDirectory();\n  while (true) {\n    File entry = file.openNextFile();\n    if (!entry) {\n      break;\n    }\n    String entryPath = path + \"\/\" + entry.name();\n    if (entry.isDirectory()) {\n      entry.close();\n      deleteRecursive(entryPath);\n    } else {\n      entry.close();\n      SD.remove((char *)entryPath.c_str());\n    }\n    yield();\n  }\n\n  SD.rmdir((char *)path.c_str());\n  file.close();\n}\n\nvoid handleDelete() {\n  if (server.args() == 0) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(0);\n  if (path == \"\/\" || !SD.exists((char *)path.c_str())) {\n    returnFail(\"BAD PATH\");\n    return;\n  }\n  deleteRecursive(path);\n  returnOK();\n}\n\nvoid handleCreate() {\n  if (server.args() == 0) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(0);\n  if (path == \"\/\" || SD.exists((char *)path.c_str())) {\n    returnFail(\"BAD PATH\");\n    return;\n  }\n\n  if (path.indexOf('.') > 0) {\n    File file = SD.open((char *)path.c_str(), FILE_WRITE);\n    if (file) {\n      file.write((const char *)0);\n      file.close();\n    }\n  } else {\n    SD.mkdir((char *)path.c_str());\n  }\n  returnOK();\n}\n\nvoid printDirectory() {\n  if (!server.hasArg(\"dir\")) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(\"dir\");\n  if (path != \"\/\" && !SD.exists((char *)path.c_str())) {\n    return returnFail(\"BAD PATH\");\n  }\n  File dir = SD.open((char *)path.c_str());\n  path = String();\n  if (!dir.isDirectory()) {\n    dir.close();\n    return returnFail(\"NOT DIR\");\n  }\n  dir.rewindDirectory();\n  server.setContentLength(CONTENT_LENGTH_UNKNOWN);\n  server.send(200, \"text\/json\", \"\");\n  WiFiClient client = server.client();\n\n  server.sendContent(\"[\");\n  for (int cnt = 0; true; ++cnt) {\n    File entry = dir.openNextFile();\n    if (!entry) {\n      break;\n    }\n\n    String output;\n    if (cnt > 0) {\n      output = ',';\n    }\n\n    output += \"{\\\"type\\\":\\\"\";\n    output += (entry.isDirectory()) ? \"dir\" : \"file\";\n    output += \"\\\",\\\"name\\\":\\\"\";\n    output += entry.name();\n    output += \"\\\"\";\n    output += \"}\";\n    server.sendContent(output);\n    entry.close();\n  }\n  server.sendContent(\"]\");\n  dir.close();\n}\n\nvoid handleNotFound() {\n  if (hasSD && loadFromSdCard(server.uri())) {\n    return;\n  }\n  String message = \"SDCARD Not Detected\\n\\n\";\n  message += \"URI: \";\n  message += server.uri();\n  message += \"\\nMethod: \";\n  message += (server.method() == HTTP_GET) ? \"GET\" : \"POST\";\n  message += \"\\nArguments: \";\n  message += server.args();\n  message += \"\\n\";\n  for (uint8_t i = 0; i < server.args(); i++) {\n    message += \" NAME:\" + server.argName(i) + \"\\n VALUE:\" + server.arg(i) + \"\\n\";\n  }\n  server.send(404, \"text\/plain\", message);\n  Serial1.print(message);\n}\n\/\/ WEBSERVER declaration end\n\n\n\nvoid setup () {\n\/\/ Pinout Setup\n  Wire.begin(sdaPin, sclPin);\n  pinMode(16,INPUT);\n\n\/\/Communication Setup\n  Serial1.begin(57600);\n\n\/\/ PZEM004T Setup\n  while (!pzemrdy) {\n      Serial1.println(\"Connecting to PZEM...\");\n      pzemrdy = pzem.setAddress(ip);\n      delay(1000);\n   }\n   \n\/\/ RTC Setup \n  if (! rtc.begin()) {\n    Serial1.println(\"Couldn't find RTC\");\n    while (1);\n  }\n  if (! rtc.isrunning()) {\n    Serial1.println(\"RTC is NOT running!\");\n    \/\/ following line sets the RTC to the date &#038; time this sketch was compiled\n    \/\/rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));\n    \/\/ This line sets the RTC with an explicit date &#038; time, for example to set\n    \/\/ January 21, 2014 at 3am you would call:\n    \/\/ rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));\n    rtc.adjust(DateTime(2019, 8, 23, 10, 11, 0));\n  }\n  Serial1.print(\"Initializing SD card...\");\n\n\/\/SDcard Setup\n  \/\/ see if the card is present and can be initialized:\n  if (!SD.begin(chipSelect)) {\n    Serial1.println(\"Card failed, or not present\");\n    \/\/ don't do anything more:\n    return;\n  }\n  Serial1.println(\"card initialized.\");\n  hasSD = true;\n\n\n\/\/ Wifi setup    \n  Serial1.print(\"Configuring access point...\");\n  \/* You can remove the password parameter if you want the AP to be open. *\/\n  WiFi.softAP(ssid, password);\n\n  IPAddress myIP = WiFi.softAPIP();\n  Serial1.print(\"AP IP address: \");\n  Serial1.println(myIP);\n  server.on(\"\/list\", HTTP_GET, printDirectory);\n  server.on(\"\/edit\", HTTP_DELETE, handleDelete);\n  server.on(\"\/edit\", HTTP_PUT, handleCreate);\n  server.on(\"\/edit\", HTTP_POST, []() {\n    returnOK();\n  }, handleFileUpload);\n  server.onNotFound(handleNotFound);  \n  \n  server.begin();\n  Serial1.println(\"HTTP server started\");\n  \n}\n\nvoid loop () {\n server.handleClient();\n delay(100);\n counter = counter+1;\n if(counter==(10*temps)){\n MesureLectureEcriture();\n counter =0;\n }\n}\n\n\nvoid MesureLectureEcriture(){\n\/\/PZEM Part\n  v = pzem.voltage(ip);\n  if (v < 0.0) v = 0.0;\n   Serial1.print(v);Serial1.print(\"V; \");\n   i = pzem.current(ip);\n   if(i >= 0.0){ Serial1.print(i);Serial1.print(\"A; \"); }\n  p = pzem.power(ip);\n   if(p >= 0.0){ Serial1.print(p);Serial1.print(\"W; \"); }\n   e = pzem.energy(ip);\n   if(e >= 0.0){ Serial1.print(e);Serial1.print(\"Wh; \"); } \n   Serial1.println();\n   \n\/\/ RTC Part\n   DateTime now = rtc.now();\n    Serial1.print(daysOfTheWeek[now.dayOfTheWeek()]);\n    Serial1.print(\",  \");\n   \n    if (now.day() < 10)    {Serial1.print('0');}\n    Serial1.print(now.day(), DEC);\n    Serial1.print('.');\n    if (now.month() < 10)  {Serial1.print('0');}\n    Serial1.print(now.month(), DEC);\n    Serial1.print('.');\n    Serial1.print(now.year(), DEC);\n    Serial1.print(\",  \");\n   \n    if (now.hour() < 10)   {Serial1.print('0');}\n    Serial1.print(now.hour(), DEC);\n    Serial1.print(':');\n    if (now.minute() < 10) {Serial1.print('0');}\n    Serial1.print(now.minute(), DEC);\n    Serial1.print(':');\n    if (now.second() < 10) {Serial1.print('0');}\n    Serial1.print(now.second(), DEC);\n    Serial1.print(\",  \");\n    Serial1.println(); \n\n\/\/SDCARD Part\n    File dataFile = SD.open(\"datalog.csv\", FILE_WRITE);\n  \/\/ if the file is available, write to it:\n  if (dataFile) {\n    if (now.day() < 10)    {dataFile.print('0');}\n    dataFile.print(now.day(), DEC);\n    dataFile.print('-');\n    if (now.month() < 10)  {dataFile.print('0');}\n    dataFile.print(now.month(), DEC);\n    dataFile.print('-');\n    dataFile.print(now.year(), DEC);\n    dataFile.print(\"  \");\n    if (now.hour() < 10)   {dataFile.print('0');}\n    dataFile.print(now.hour(), DEC);\n    dataFile.print(':');\n    if (now.minute() < 10) {dataFile.print('0');}\n    dataFile.print(now.minute(), DEC);\n    dataFile.print(':');\n    if (now.second() < 10) {dataFile.print('0');}\n    dataFile.print(now.second(), DEC);   \n    dataFile.print(\";\");\n    dataFile.print(v);\n    dataFile.print(';');\n    dataFile.print(i);\n    dataFile.print(';');\n    dataFile.print(p);\n    dataFile.print(';');\n    dataFile.print(e);\n    dataFile.println();\n    dataFile.close();\n  }\n  \/\/ if the file isn't open, pop up an error:\n  else {\n    Serial1.println(\"error opening datalog.csv\");\n  }\n}\n    <\/pre>\n\n\n\n<p>Pour le PZEM004T V3<\/p>\n\n\n\n<pre class=\"lang:arduino decode:true\">#include \"Wire.h\"\n#include \"PZEM004Tv30.h\"\n#include \"RTClib.h\"\n#include \"SPI.h\"\n#include \"SD.h\"\n#include \"ESP8266WiFi.h\"\n#include \"WiFiClient.h\"\n#include \"ESP8266WebServer.h\"\n\n\/\/ Echantillonage\nint temps = 10; \/\/en secondes\n\n\/\/ Pzem004 variables\nfloat v = 0;\nfloat i = 0; \nfloat p =0;\nfloat e = 0;\nfloat freq;\nfloat pf;\nHardwareSerial hwSerial(UART0);     \/\/ Use hwSerial1 UART0 at pins GPIO1 (TX) and GPIO3 (RX)\nPZEM004Tv30 pzem(&hwSerial);           \/\/ Attach PZEM to hwSerial1\nbool pzemrdy = false;\n\n\/\/ RTC variables\nRTC_DS1307 rtc;\nconst int sclPin = D1;\nconst int sdaPin = D2;\nchar daysOfTheWeek[7][12] = {\"Dimanche\", \"Lundi\", \"Mardi\", \"Mercredi\", \"Jeudi\", \"Vendredi\", \"Samedi\"};\n\n\/\/ SDcard variables\nstatic bool hasSD = false;\nconst int chipSelect = D8;\nFile uploadFile;\n\n\/\/ Wifi Variables\n#ifndef APSSID\n#define APSSID \"ESPap\"\n#define APPSK  \"thereisnospoon\"\n#endif\n\/* Set these to your desired credentials. *\/\nint counter =0;\nconst char *ssid = APSSID;\nconst char *password = APPSK;\nESP8266WebServer server(80);\n\/* Just a little test message.  Go to http:\/\/192.168.4.1 in a web browser\n   connected to this access point to see it.\n*\/\n\n\/\/ Prototypes des fonctions\nvoid MesureLectureEcriture(void);\n\nvoid returnOK() {\n  server.send(200, \"text\/plain\", \"\");\n}\n\nvoid returnFail(String msg) {\n  server.send(500, \"text\/plain\", msg + \"\\r\\n\");\n}\n\nbool loadFromSdCard(String path) {\n\n  Serial1.print(path);\n  String dataType = \"text\/plain\";\n  if (path.endsWith(\"\/\")) {\n    path += \"index.htm\";\n  }\n\n  if (path.endsWith(\".src\")) {\n    path = path.substring(0, path.lastIndexOf(\".\"));\n  } else if (path.endsWith(\".htm\")) {\n    dataType = \"text\/html\";\n  } else if (path.endsWith(\".css\")) {\n    dataType = \"text\/css\";\n  } else if (path.endsWith(\".js\")) {\n    dataType = \"application\/javascript\";\n  } else if (path.endsWith(\".png\")) {\n    dataType = \"image\/png\";\n  } else if (path.endsWith(\".gif\")) {\n    dataType = \"image\/gif\";\n  } else if (path.endsWith(\".jpg\")) {\n    dataType = \"image\/jpeg\";\n  } else if (path.endsWith(\".ico\")) {\n    dataType = \"image\/x-icon\";\n  } else if (path.endsWith(\".xml\")) {\n    dataType = \"text\/xml\";\n  } else if (path.endsWith(\".pdf\")) {\n    dataType = \"application\/pdf\";\n  } else if (path.endsWith(\".zip\")) {\n    dataType = \"application\/zip\";\n  }\n\n  File dataFile = SD.open(path.c_str());\n  if (dataFile.isDirectory()) {\n    path += \"\/index.htm\";\n    dataType = \"text\/html\";\n    Serial1.print(path.c_str());\n    dataFile = SD.open(path.c_str());\n  }\n\n  if (!dataFile) {\n\n    return false;\n  }\n\n  if (server.hasArg(\"download\")) {\n    dataType = \"application\/octet-stream\";\n  }\n\n  if (server.streamFile(dataFile, dataType) != dataFile.size()) {\n    Serial1.println(\"Sent less data than expected!\");\n  }\n\n  dataFile.close();\n\n  return true;\n}\n\nvoid handleFileUpload() {\n  if (server.uri() != \"\/edit\") {\n    return;\n  }\n  HTTPUpload& upload = server.upload();\n  if (upload.status == UPLOAD_FILE_START) {\n    if (SD.exists((char *)upload.filename.c_str())) {\n      SD.remove((char *)upload.filename.c_str());\n    }\n    uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);\n    Serial1.print(\"Upload: START, filename: \"); Serial1.println(upload.filename);\n  } else if (upload.status == UPLOAD_FILE_WRITE) {\n    if (uploadFile) {\n      uploadFile.write(upload.buf, upload.currentSize);\n    }\n    Serial1.print(\"Upload: WRITE, Bytes: \"); Serial1.println(upload.currentSize);\n  } else if (upload.status == UPLOAD_FILE_END) {\n    if (uploadFile) {\n      uploadFile.close();\n    }\n    Serial1.print(\"Upload: END, Size: \"); Serial1.println(upload.totalSize);\n  }\n}\n\nvoid deleteRecursive(String path) {\n  File file = SD.open((char *)path.c_str());\n  if (!file.isDirectory()) {\n    file.close();\n    SD.remove((char *)path.c_str());\n    return;\n  }\n\n  file.rewindDirectory();\n  while (true) {\n    File entry = file.openNextFile();\n    if (!entry) {\n      break;\n    }\n    String entryPath = path + \"\/\" + entry.name();\n    if (entry.isDirectory()) {\n      entry.close();\n      deleteRecursive(entryPath);\n    } else {\n      entry.close();\n      SD.remove((char *)entryPath.c_str());\n    }\n    yield();\n  }\n\n  SD.rmdir((char *)path.c_str());\n  file.close();\n}\n\nvoid handleDelete() {\n  if (server.args() == 0) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(0);\n  if (path == \"\/\" || !SD.exists((char *)path.c_str())) {\n    returnFail(\"BAD PATH\");\n    return;\n  }\n  deleteRecursive(path);\n  returnOK();\n}\n\nvoid handleCreate() {\n  if (server.args() == 0) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(0);\n  if (path == \"\/\" || SD.exists((char *)path.c_str())) {\n    returnFail(\"BAD PATH\");\n    return;\n  }\n\n  if (path.indexOf('.') > 0) {\n    File file = SD.open((char *)path.c_str(), FILE_WRITE);\n    if (file) {\n      file.write((const char *)0);\n      file.close();\n    }\n  } else {\n    SD.mkdir((char *)path.c_str());\n  }\n  returnOK();\n}\n\nvoid printDirectory() {\n  if (!server.hasArg(\"dir\")) {\n    return returnFail(\"BAD ARGS\");\n  }\n  String path = server.arg(\"dir\");\n  if (path != \"\/\" && !SD.exists((char *)path.c_str())) {\n    return returnFail(\"BAD PATH\");\n  }\n  File dir = SD.open((char *)path.c_str());\n  path = String();\n  if (!dir.isDirectory()) {\n    dir.close();\n    return returnFail(\"NOT DIR\");\n  }\n  dir.rewindDirectory();\n  server.setContentLength(CONTENT_LENGTH_UNKNOWN);\n  server.send(200, \"text\/json\", \"\");\n  WiFiClient client = server.client();\n\n  server.sendContent(\"[\");\n  for (int cnt = 0; true; ++cnt) {\n    File entry = dir.openNextFile();\n    if (!entry) {\n      break;\n    }\n\n    String output;\n    if (cnt > 0) {\n      output = ',';\n    }\n\n    output += \"{\\\"type\\\":\\\"\";\n    output += (entry.isDirectory()) ? \"dir\" : \"file\";\n    output += \"\\\",\\\"name\\\":\\\"\";\n    output += entry.name();\n    output += \"\\\"\";\n    output += \"}\";\n    server.sendContent(output);\n    entry.close();\n  }\n  server.sendContent(\"]\");\n  dir.close();\n}\n\nvoid handleNotFound() {\n  if (hasSD && loadFromSdCard(server.uri())) {\n    return;\n  }\n  String message = \"SDCARD Not Detected\\n\\n\";\n  message += \"URI: \";\n  message += server.uri();\n  message += \"\\nMethod: \";\n  message += (server.method() == HTTP_GET) ? \"GET\" : \"POST\";\n  message += \"\\nArguments: \";\n  message += server.args();\n  message += \"\\n\";\n  for (uint8_t i = 0; i < server.args(); i++) {\n    message += \" NAME:\" + server.argName(i) + \"\\n VALUE:\" + server.arg(i) + \"\\n\";\n  }\n  server.send(404, \"text\/plain\", message);\n  Serial1.print(message);\n}\n\/\/ WEBSERVER declaration end\n\n\n\nvoid setup () {\n\/\/ Pinout Setup\n  Wire.begin(sdaPin, sclPin);\n  pinMode(16,INPUT);\n\n\/\/Communication Setup\n  Serial1.begin(57600);\n\/*\n\/\/ PZEM004T Setup\n  while (!pzemrdy) {\n      Serial1.println(\"Connecting to PZEM...\");\n      pzemrdy = pzem.setAddress(ip);\n      delay(1000);\n   }\n*\/\npzem.setAddress(0x42);\n   \n\/\/ RTC Setup \n  if (! rtc.begin()) {\n    Serial1.println(\"Couldn't find RTC\");\n    while (1);\n  }\n  if (! rtc.isrunning()) {\n    Serial1.println(\"RTC is NOT running!\");\n    \/\/ following line sets the RTC to the date &#038; time this sketch was compiled\n    \/\/rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));\n    \/\/ This line sets the RTC with an explicit date &#038; time, for example to set\n    \/\/ January 21, 2014 at 3am you would call:\n    \/\/ rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));\n    rtc.adjust(DateTime(2019, 8, 23, 10, 11, 0));\n  }\n  Serial1.print(\"Initializing SD card...\");\n\n\/\/SDcard Setup\n  \/\/ see if the card is present and can be initialized:\n  if (!SD.begin(chipSelect)) {\n    Serial1.println(\"Card failed, or not present\");\n    \/\/ don't do anything more:\n    return;\n  }\n  Serial1.println(\"card initialized.\");\n  hasSD = true;\n\n\n\/\/ Wifi setup    \n  Serial1.print(\"Configuring access point...\");\n  \/* You can remove the password parameter if you want the AP to be open. *\/\n  WiFi.softAP(ssid, password);\n\n  IPAddress myIP = WiFi.softAPIP();\n  Serial1.print(\"AP IP address: \");\n  Serial1.println(myIP);\n  server.on(\"\/list\", HTTP_GET, printDirectory);\n  server.on(\"\/edit\", HTTP_DELETE, handleDelete);\n  server.on(\"\/edit\", HTTP_PUT, handleCreate);\n  server.on(\"\/edit\", HTTP_POST, []() {\n    returnOK();\n  }, handleFileUpload);\n  server.onNotFound(handleNotFound);  \n  \n  server.begin();\n  Serial1.println(\"HTTP server started\");\n  \n}\n\nvoid loop () {\n server.handleClient();\n\n\n delay(100);\n counter = counter+1;\n\n if(counter==(10*temps)){\n MesureLectureEcriture();\n counter =0;\n }\n}\n\n\nvoid MesureLectureEcriture(){\n\/\/PZEM Part\n  v = pzem.voltage();\n  if (v < 0.0) v = 0.0;\n   Serial1.print(v);Serial1.print(\"V; \");\n   i = pzem.current();\n   if(i >= 0.0){ Serial1.print(i);Serial1.print(\"A; \"); }\n  p = pzem.power();\n   if(p >= 0.0){ Serial1.print(p);Serial1.print(\"W; \"); }\n   e = pzem.energy();\n   if(e >= 0.0){ Serial1.print(e);Serial1.print(\"Wh; \"); } \n  freq = pzem.frequency();\n  Serial1.print(\"Frequency: \");\n  Serial1.print(freq);\n  Serial1.print(\"Hz\");\n  pf = pzem.pf();\n  Serial1.print(\"PF: \");\n  Serial1.println(pf);\n   \n\/\/ RTC Part\n   DateTime now = rtc.now();\n    Serial1.print(daysOfTheWeek[now.dayOfTheWeek()]);\n    Serial1.print(\",  \");\n   \n    if (now.day() < 10)    {Serial1.print('0');}\n    Serial1.print(now.day(), DEC);\n    Serial1.print('.');\n    if (now.month() < 10)  {Serial1.print('0');}\n    Serial1.print(now.month(), DEC);\n    Serial1.print('.');\n    Serial1.print(now.year(), DEC);\n    Serial1.print(\",  \");\n   \n    if (now.hour() < 10)   {Serial1.print('0');}\n    Serial1.print(now.hour(), DEC);\n    Serial1.print(':');\n    if (now.minute() < 10) {Serial1.print('0');}\n    Serial1.print(now.minute(), DEC);\n    Serial1.print(':');\n    if (now.second() < 10) {Serial1.print('0');}\n    Serial1.print(now.second(), DEC);\n    Serial1.print(\",  \");\n    Serial1.println(); \n\n\/\/SDCARD Part\n    File dataFile = SD.open(\"datalog.csv\", FILE_WRITE);\n  \/\/ if the file is available, write to it:\n  if (dataFile) {\n    if (now.day() < 10)    {dataFile.print('0');}\n    dataFile.print(now.day(), DEC);\n    dataFile.print('-');\n    if (now.month() < 10)  {dataFile.print('0');}\n    dataFile.print(now.month(), DEC);\n    dataFile.print('-');\n    dataFile.print(now.year(), DEC);\n    dataFile.print(\"  \");\n    if (now.hour() < 10)   {dataFile.print('0');}\n    dataFile.print(now.hour(), DEC);\n    dataFile.print(':');\n    if (now.minute() < 10) {dataFile.print('0');}\n    dataFile.print(now.minute(), DEC);\n    dataFile.print(':');\n    if (now.second() < 10) {dataFile.print('0');}\n    dataFile.print(now.second(), DEC);   \n    dataFile.print(\";\");\n    dataFile.print(v);\n    dataFile.print(';');\n    dataFile.print(i);\n    dataFile.print(';');\n    dataFile.print(p);\n    dataFile.print(';');\n    dataFile.print(e);\n    dataFile.print(';');\n    dataFile.print(pf);\n    dataFile.print(';');\n    dataFile.print(freq);\n    dataFile.println();\n    dataFile.close();\n  }\n  \/\/ if the file isn't open, pop up an error:\n  else {\n    Serial1.println(\"error opening datalog.csv\");\n  }\n}    <\/pre>\n\n\n\n<p class=\"has-large-font-size\">Partie 8: Analyse des donn\u00e9es<\/p>\n\n\n\n<p>Maintenant que tout est fini, on peut brancher le datalogger BB1 sur son point de mesure final et venir de temps en temps chercher le fichier datalog.csv<\/p>\n\n\n\n<p>On peut ensuite extraire les donn\u00e9es fichier datalog.csv afin d'analyser celle-ci. (Attention en fonction de la version du logiciel que vous utilis\u00e9, il faudra remplacer les points par des virgules)<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"263\" src=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-30-1024x263.png\" alt=\"\" class=\"wp-image-701\" srcset=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-30-1024x263.png 1024w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-30-300x77.png 300w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-30-768x197.png 768w, https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/image-30.png 1122w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Voil\u00e0 ce tutoriel est fini. J'esp\u00e8re qu'il vous sera utile.<\/p>\n\n\n\n<p>Ci-dessous l'archive avec toutes les sources utilis\u00e9es.<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/BB1_Sources.7z\">BB1_Sources<\/a><a href=\"https:\/\/miniprojets.net\/wp-content\/uploads\/2019\/08\/BB1_Sources.7z\" class=\"wp-block-file__button wp-element-button\" download>Download<\/a><\/div>\n\n\n\n<p>N'h\u00e9sitez pas \u00e0 me faire des retours sur l'utilisation de vos dataloggeurs et je vous souhaite une bonne exp\u00e9rimentation. <\/p>\n\n\n\n<p>J\u00e9r\u00f4me Ferrari<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bonjour, Il y a quelques temps, j&#8217;ai re\u00e7u comme probl\u00e9matique de trouver une solution pour monitorer la puissance du r\u00e9seau&hellip;<\/p>\n","protected":false},"author":1,"featured_media":697,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[54],"tags":[82],"class_list":["post-594","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-capteurs","tag-capteurs"],"_links":{"self":[{"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/posts\/594","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/comments?post=594"}],"version-history":[{"count":1,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/posts\/594\/revisions"}],"predecessor-version":[{"id":4750,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/posts\/594\/revisions\/4750"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/media\/697"}],"wp:attachment":[{"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/media?parent=594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/categories?post=594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/miniprojets.net\/index.php\/wp-json\/wp\/v2\/tags?post=594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}