Medição Un, In, Energia activa e calculo do Factor de Potência e Potência Total.

Utilizando um MCU ( microcontroller unit ) {https://en.wikipedia.org/wiki/Microcontroller} com alguns componentes electrónicos e interagindo com a página web conseguimos monitorizar um determinado aparelho.
Deste modo, utilizando o kit "PZEM004" que faz a leitura das quatro componentes principais, tais como, tensão [V], intensidade de corrente eléctrica [A], potência activa [W] e energia [Wh] e com determinadas fórmulas, podemos calcular a Potência total [VA] na instalação ou equipamento, o Factor de potência/cos(φ), a Energia reactiva [kVAr] e o ângulo de φ. De salientar que os cálculos deveriam ser, sob a forma de integrais e não por fórmulas.

.

instalação

Porque não fazer um site com isso??

Hardware: ESP12
Interface: Arduino IDE
Wireless Access Point (WAP)
PZEM
Sd card
RTC
converter 5/3Vdc

use Chrome Web Browser

#include <PZEM004T.h> // https://github.com/olehs/PZEM004T
#include <ESP8266WiFi.h> // https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/example-sketch-ap-web-server
//#include <SoftwareSerial.h> // C:\Users\Antonio\Documents\Arduino\libraries\PZEM004T-master
#include <SPI.h> // sdisk
#include <SD.h>  // sdisk
#include <Wire.h>       // RTC I2C library // https://github.com/Makuna/Rtc/tree/master/

...

verify program:

ino_PZEM29-nodemcu-AP-PZEM_sdisk.ino

...

void setupWiFi() {
  WiFi.mode(WIFI_AP); // Do a little work to get a unique-ish name. Append the last two bytes of the MAC (HEX'd) to "Thing"
  uint8_t mac[WL_MAC_ADDR_LENGTH];
  WiFi.softAPmacAddress(mac);
  String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
                 String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
  macID.toUpperCase();
//  String AP_NameString = "pzem04Wifi"; // + macID;

  char AP_NameChar[AP_NameString.length() + 1];
  memset(AP_NameChar, 0, AP_NameString.length() + 1);

  for (int i=0; i<AP_NameString.length(); i++) {
    AP_NameChar[i] = AP_NameString.charAt(i);
    Serial.print(AP_NameChar[i]);
  }
  WiFi.softAP(AP_NameChar, WiFiAPPSK);
  server.begin();
//  web = String(mac) + " " + String(AP_NameChar) + " " + String(AP_NameString) + " " + String(WiFiAPPSK);
//  Serial.println(""); web = " " + AP_NameString + " " + WiFiAPPSK; Serial.println(web);
}

nano_ESP12.pdf (124 KB)

ino_PZEM29-nodemcu-AP-PZEM_sdisk.ino (30.5 KB)

pagWeb.png

Adquirindo determinadas variáveis, tais como:
-Tensão U=[V];
-Intensidade de corrente eléctrica I=[A];
-Potência activa P=[W];
-Energia E=[W/h].

Poderemos com cálculos simples, determinar os seguintes parâmetros:
-Potência total ; { S = U x I }
-Factor de Potência cos(φ); { cos(φ) = P / S }
-Potência Reativa Q=[VAr]; { Q=√(S²-P²) }
-Ângulo do cos(φ). { acos(cos(φ))*180/pi }

Hardware: ESP12
Interface: Arduino IDE
Wireless Access Point (WAP)
PZEM (SDIC SD3004) {TTL 5V}
Sd card {SPI 3V}
RTC {I²C}
converter 5/3Vdc
DIY (Do It Yourself)
use Chrome Web Browser



~~https://pt.wikipedia.org/wiki/Industria_4.0~~
Indústria 4.0 ou Quarta Revolução Industrial é um termo que engloba algumas tecnologias para automação e troca de dados e utiliza conceitos de Sistemas ciber-físicos, Internet das Coisas e Computação em Nuvem.
Estamos perante a nova era, Quarta revolução industrial, marcada pela convergência de tecnologias digitais, físicas e biológicas.

Nesta versão (ino_PZEM-EXP12-AP-PZEM-20170918.ino) temos a possibilidade de ler os dados adquiridos pelo "pzem" e guardar no cartão sdisk diariamente.
Conseguimos ler os arquivos no modo "CSV" {excel 2007} num determinado dia.

Para aceder às funções escolha o menu: "sdisk : select directory or files", depois em "selection", apresenta-se o directório "/root sdisk drive" e click "selection".
É apresentado uma caixa de dialogo, com as leituras dos valores.
Por fim, poderemos guardar o ficheiro no computador ou no telemóvel usando a função "save to file".

outra função a salientar, obtenção da data no momento de carregamento na memória, usando a função DATE e TIME.

void rtcViaUSB() { // __DATE__=Sep 10 2017;__TIME__=21:47:21!Sep 10 2017!Sep! <24>  {9}  #10#  $10$  %2017%
 String dateFile="", str="", s=""; // http://192.168.4.1/utc=2017/9/8(5)T22:38:7 http://192.168.4.1/utc=2010/1/4(5)T2:3:7
 int a = 0, day = 0, month = 0, y = 0, hour=0, minute=0, second=0;
 String monthNames = "JanFebMarAprMayJunJulAugSepOctNovDec";
 str =__DATE__; // __DATE__=Sep 10 2017;__TIME__=21:47:21!Sep 10 2017!Sep! <24>  {9}  #10#  $10$  %2017%
 s = str.substring(0, 3); dateFile="{"+str+"("+s+")"; // extrai o mês
 a = monthNames.indexOf(s); month = (int)a/3+1 ; dateFile += "<" + String(a) + ">" + " {" + String(month) + "}";
 s = str.substring(4, 6); day = s.toInt(); dateFile +="#" + s + "#;$" + String(day) + "$ ";
 s = str.substring(str.length()-2, str.length()); year = s.toInt();
  if (year>9) {fileSdisk = String(year);} else fileSdisk = "0"+String(year);
  if (month>9) {fileSdisk += String(month);} else fileSdisk += "0"+String(month);
  if (day>9) {fileSdisk += String(day);} else fileSdisk += "0"+String(day);
  int dayOfWeek=daySemDate(day, month, year);
  fileSdisk +=".csv"; // fileSdisk = "20170503.csv";
 dateFile +=" %" + s + "%" + String(year);
 str =String(__TIME__); //
 s = str.substring(0, 2);  hour = s.toInt();
 s = str.substring(3, 5);  minute = s.toInt();
 s = str.substring(6, 8);  second = s.toInt();
 dateFile +=" time="+str+"{"+String(hour)+"|"+String(minute)+"|"+String(second)+"}";
  Serial.println(String("__DATE__=") + __DATE__ + ";__TIME__="+ __TIME__+";"+dateFile+";"+fileSdisk);
 rtcSetime(second, minute, hour, dayOfWeek, day, month, year);
}

Caso não tenha pilha no RTC, ou fonte de alimentação auxiliar, poderá verificar a função "sincronize" no carregamento da pagina web (de preferência, usar o browser chrome) que actualizará a data e hora.

void rtcConvTime(String str) { // "Sincronize" Serial.print("$"); Serial.print(web); Serial.print("$"); // https://www.tutorialspoint.com/arduino/arduino_strings.htm
 String s = "";
 year = str.substring(2, str.indexOf("/")).toInt(); // (byte)str.substring(0, str.indexOf("/")); // utc=2017/5/30(5)T9:10:25
  web = char(10)+str; str = str.substring(str.indexOf("/")+1, str.length()); web +="«" + str + "»";
 month = str.substring(0, str.indexOf("/")).toInt(); // http://192.168.4.1/utc=2017/9/7(4)T21:10:23
  str = str.substring(str.indexOf("/")+1, str.length()); web +="%" + str + "%";
 day = str.substring(0, str.indexOf("/")).toInt(); // (byte)str.substring(0, str.sizeof("/"));
 dayOfWeek = str.substring(str.indexOf("(")+1, str.indexOf(")")).toInt();
  str = str.substring(str.indexOf("/")+1, str.length());
   web += "&" + str.substring(str.indexOf("/")+1, str.length()) + "&";
 hour = str.substring(str.indexOf("T")+1, str.indexOf(":")).toInt(); // hour = (byte)str.substring(str.sizeof("T")+1, str.sizeof(":"));
  str = str.substring(str.indexOf(":")+1, str.length()); web += "|" + str + "|";
 minute = str.substring(0, str.indexOf(":")).toInt();
  str = str.substring(str.indexOf(":")+1, str.length()); web += "#" + str + "#";
 second = str.substring(0, str.length()).toInt(); //(byte)str.substring(0, str.length());
  str = str.substring(str.indexOf(":")+1, str.length());
   web +="!" + str.substring(0, str.length()) + "!"; // Serial.println(web);
 rtcSetime(second, minute, hour, dayOfWeek, day, month, year);
  if (year>9) {s = String(year);} else s = "0"+String(year);
  if (month>9) {s += String(month);} else s += "0"+String(month);
  if (day>9) {s += String(day);} else s += "0"+String(day);
  if (s == fileSdisk.substring(0, 6)) {
   if (year>9) {fileSdisk = String(year);} else fileSdisk = "0"+String(year);
   if (month>9) {fileSdisk += String(month);} else fileSdisk += "0"+String(month);
   if (day>9) {fileSdisk += String(day);} else fileSdisk += "0"+String(day); }
  fileSdisk = s + ".csv"; fileSdiskOn();
}

Também existirá, obtenção do dia da semana através do ano, mês e dia.

int daySemDate(byte day, byte month, byte year) {
 int sem=0; float mes=month, a, b, c, y=2000+year;
 if (month<=2){mes=month+12; y=y-1; }
 a=(int)(day+mes*2); Serial.print(String(a)+" ");
 a+=(int)(((mes+1)*3)/5); Serial.print(String(a)+" ");
 a+=y+(int)(y/4)-(int)(y/100); Serial.print(String(a)+" ");
 a+=(int)((y/400)+1); Serial.print(String(a)+" ");
 b=(int)(a/7); sem=(int)(a-b*7); // fórmula encontrada nas diversas linguagens programação de 1994
 Serial.println(" day="+String(day)+" month="+String(month)+" year="+String(year)+" y="+String(y)+" a="+String(a)+" b="+String(b)+" sem="+String(sem)+" ");
 return(sem);
}

veja o site:

ino_EXP12-PZEM-20171027.ino (64.9 KB)

Nesta versão temos a possibilidade de descrever o nome do circuito ou aparelho eléctrico aquando na extracção do ficheiro excel.

ino_EXP12-PZEM.ino (79.3 KB)