Comments (13)
Success!
I was able to perform all the steps using Arduino Mega!
The reason is quite obvious! Arduino Uno has only one serial port and simulates other serials on digital pins!
But the arduino Mega has 5 independent serial ports!
But attention: I do not know if I made a mistake or is a failure in the library, but only managed from the HardSerial example!
Follow my code!
I use an RTC1307, an SD card reader and a 20x4 LCD on my Datalogger!
/* **************************************************************************************************
SD - Se comunica por SPI
MOSI -> pino 51
MISO -> pino 50
SCK -> pino 52
CS (SS) -> Pino 53
Relógio RTC DS1307 - Se comunica por I2C no endereço 0x68
SDA -> pino 20
SCL -> pino 21
LCD se comunica por IC2 no endereço 0x27
SDA -> pino 20
SCL -> pino 21
Coleta de dados do Pzem 004
Pinos de comunicação Pzem (módulo Max485 RS 232 para Modbus)
Pino 14 TX fio verde
Pino 15 RX fio branco
Liga Backligth do LCD
pino digital 3 aciona o backligth
*/
#include <LiquidCrystal_I2C.h> // Biblioteca de configuração do LCD
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Inicializa o display no endereco 0x27
#include <SdFat.h> //Uso a biblioteca SdFat no lugar da original do arduino pois é mais otimizada.
SdFat SD; //Linha necessária para compatibilizar o programa escrito para SD.h (biblioteca original)
const int CS_SD = 53; //Pino do cartão SD
#include <DS1307RTC.h> //Biblioteca para controle do RTC DS1307
#include <PZEM004Tv30.h> //Biblioteca do monitor de energia Pzem
PZEM004Tv30 pzem(&Serial3); // TX(Verde),RX(Branco) conectados para RX,TX do PZEM
// Constantes variadas
const unsigned long intervaloLeitura = 2000; //inervalo de leitura [milisegundos]
const unsigned long intervaloEscritaSD = 300; //intervalo de escrita de dados no SD [milisegundos]
boolean temSD = 0; // Variável para indicar presença de cartão SD
const int intervaloSincro = 300; //Intervalo de sincronismo do arduino com o RTC [Seg.]. Sincronismo do RTC
//----------------------------------------------------------------------------------------------------------------
void setup()
{
lcd.begin (20, 4); //definição do LCD 20 colunas e 4 linhas
Serial.begin(115200); //Inicia a comunicação em 9600 kbps
//Inicializa cartão SD
// verifica se o SD está presente e pode ser inicializado:
if (!SD.begin(CS_SD)) {
temSD = 0; //Cartão SD não detectado
Serial.print("Cartão SD não detectado");
Serial.println();
}
else {
temSD = 1; //Cartão SD encontrado
Serial.print("Cartão está presente");
Serial.println();
}
//Inicializa o RTC e contagem de tempo
setTime(RTC.get());
setSyncProvider(RTC.get); //Estabelecemos o RTC como provedor do tempo
setSyncInterval(intervaloSincro); // Atualizamos seguindo intervalo definido
}
void loop() {
//iniciamos com as leituras dos dados do PZEM
float voltage = pzem.voltage();
if (voltage != NAN) {
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}
float current = pzem.current();
if (current != NAN) {
Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
Serial.println("Error reading current");
}
float power = pzem.power();
if (current != NAN) {
Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.println("Error reading power");
}
float energy = pzem.energy();
if (current != NAN) {
Serial.print("Energy: "); Serial.print(energy, 3); Serial.println("kWh");
} else {
Serial.println("Error reading energy");
}
float frequency = pzem.frequency();
if (current != NAN) {
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
Serial.println("Error reading frequency");
}
float pf = pzem.pf();
if (current != NAN) {
Serial.print("PF: "); Serial.println(pf);
} else {
Serial.println("Error reading power factor");
}
static unsigned long millisPrevio = intervaloLeitura;
static unsigned long millisPrevio2 = intervaloEscritaSD;
static String dados;
unsigned long millisActual = millis();
// Enviamos os dados de hora e leituras do Pzem para o LCD trocando a cada 5 segundos
lcd.clear();
lcd.setBacklight(HIGH);
lcd.setCursor(0, 0);
lcd.print("Usina AlfonsoLijo");
lcd.setCursor(0, 1);
lcd.print("Capacidade 2.9 kWp");
lcd.setCursor(0, 2);
lcd.print ("Data:");
lcd.setCursor(6, 2);
lcd.print(timeLabel1()); //funciona
lcd.setCursor(0, 3);
lcd.print("Hora:");
lcd.setCursor(6, 3);
lcd.print(timeLabel2());
delay(15000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(voltage);
lcd.setCursor(7, 0);
lcd.print("V");
lcd.setCursor(10, 0);
lcd.print(current);
lcd.setCursor(17, 0);
lcd.print("A");
lcd.setCursor(0, 1);
lcd.print(power);
lcd.setCursor(17, 1);
lcd.print("kW");
lcd.setCursor(0, 2);
lcd.print(energy);
lcd.setCursor(17, 2);
lcd.print("kWh");
lcd.setCursor(0, 3);
lcd.print(frequency);
lcd.setCursor(7, 3);
lcd.print("Hz");
lcd.setCursor(10, 3);
lcd.print(pf);
lcd.setCursor(17, 3);
lcd.print("PF");
delay(15000);
if (millisActual - millisPrevio >= intervaloLeitura) { //Executa as siguintes ações só se é cumprido o intervalo
dados = timeLabel(); // coloca a marca de tempo no String dados
dados = dados + ", " + String(voltage); //vai adicionando os valores medidos na string
dados = dados + ", " + String(current);
dados = dados + ", " + String(power);
dados = dados + ", " + String(energy);
dados = dados + ", " + String(frequency);
dados = dados + ", " + String(pf);
Serial.println(dados); //mostra resultado na porta serial para simples consulta
millisPrevio = millisActual;
}
if (millisActual - millisPrevio2 >= intervaloEscritaSD * 60UL) { //se cumprido o intervalo especificado, procede a gravação dos dados
if (gravardadosSD(dados)) { //grava os dados no SD - se houver erro, retorna 1
}
millisPrevio2 = millisActual;
}
}
//função que devolve um String com a Hora/data atual
//Adiciona um '0' na esquerda nos valores de uma casa decimal e formata a hora/data
String timeLabel() {
time_t t = now();
String tempoAtual = String();
tempoAtual = year(t);
if (month(t) < 10)
tempoAtual = String(tempoAtual + '-' + '0' + month(t));
else
tempoAtual = String(tempoAtual + '-' + month(t));
if (day(t) < 10)
tempoAtual = String(tempoAtual + '-' + '0' + day(t));
else
tempoAtual = String(tempoAtual + '-' + day(t));
tempoAtual = String(tempoAtual + ',');
if (hour(t) < 10)
tempoAtual = String(tempoAtual + '0' + hour(t));
else
tempoAtual = String(tempoAtual + hour(t));
tempoAtual = String(tempoAtual + ':');
if (minute(t) < 10)
tempoAtual = String(tempoAtual + '0' + minute(t) + ':');
else
tempoAtual = String(tempoAtual + minute(t) + ':');
if (second(t) < 10)
tempoAtual = String(tempoAtual + '0' + second(t));
else
tempoAtual = String(tempoAtual + second(t));
return tempoAtual;
}
String timeLabel1() {
time_t t = now();
String tempoAtual1 = String();
tempoAtual1 = String(tempoAtual1 + day(t) + '-');
tempoAtual1 = String(tempoAtual1 + month(t) + '-');
tempoAtual1 = String(tempoAtual1 + year(t));
return tempoAtual1;
}
String timeLabel2() {
time_t t = now();
String tempoAtual2 = String();
if (hour(t) < 10)
tempoAtual2 = String(tempoAtual2 + '0' + hour(t));
else
tempoAtual2 = String(tempoAtual2 + hour(t));
tempoAtual2 = String(tempoAtual2 + ':');
if (minute(t) < 10)
tempoAtual2 = String(tempoAtual2 + '0' + minute(t) + ':');
else
tempoAtual2 = String(tempoAtual2 + minute(t));
// if (second(t) < 10)
// tempoAtual2 = String(tempoAtual2 + '0' + second(t));
// else
// tempoAtual2 = String(tempoAtual2 + second(t));
return tempoAtual2;
}
// Função que registra as medições feitas em um arquivo "meulog.cvs"
// Se o arquivo existir, os dados serão adicionados e, se não forem criados, os mesmos
// Recebe uma String com o formato a ser gravado
// Retorna 0 se correu bem e 1 se houve um erro
boolean gravardadosSD(String data) {
time_t t = now();
String date = String(); //Geramos um string para usar de nome de arquivo com a data do dia.
date = year(t);
if (month(t) < 10)
date = String(date + '0' + month(t));
else
date = String(date + month(t));
if (day(t) < 10)
date = String(date + '0' + day(t));
else
date = String(date + day(t));
date = String(date + ".csv");
char fileName[13];
date.toCharArray(fileName, 13); //convertemos o string para uma array de caracteres (exigido pela biblioteca do SD)
if (!temSD) {
return 1; //termina a função se o SD não esta inicializado
}
if (SD.exists(fileName)) { //Se existe o arquivo "fileName" o abrimos e adicionamos os dados.
File meulog = SD.open(fileName, FILE_WRITE);
if (meulog) { //Se o arquivo se abre corretamente escrevemos nele ...
meulog.println(data);
meulog.close();
return 0;
}
else {
return 1; //Não se conseguiu abrir o arquivo ...
}
}
else { //se não existe o archivo "meulog.cvs" criamos um novo e gravamos os dados ...
File meulog = SD.open(fileName, FILE_WRITE);
if (meulog) { //Se o arquivo é aberto corretamente gravamos os dados ...
meulog.println(F("Data, Hora, Volt, Amp, Watt, kWh, Hz, FP"));
meulog.println(data);
meulog.close();
return 0;
}
else {
return 1;
}
}
}
from pzem-004t-v30.
I have a same problem! Now ! tri to put a external power supply.
from pzem-004t-v30.
I just change the PZEM004T.h line 34 (#define PZEM_DEFAULT_ADDR 0x0F to 0x001 and work now!
from pzem-004t-v30.
This library needs tweaking!
I've managed to keep up communication when I add the RTC and LCD control libraries, but sending anything to the LCD just ends communication!
from pzem-004t-v30.
Thank you so much mandulaj for the beautiful work!
from pzem-004t-v30.
I'm glad that it works well with mega.
I did software serial communication with two Arduinos. And one side
PZEM-004T v3.0 was installed and data was transferred to another Arduino. Other Arduinos were used by connecting Sd card, LCD, and RTC
from pzem-004t-v30.
I am a beginner in Arduino!
I am trying to improve my code so that the data sent to the LCD does not interfere with the data recording!
As it stands today, LCD display time directly interferes with the amount of recorded data!
Could someone help me sort this out so that I can record more data on the SD card while keeping the display time of the data on the LCD?
I would be very grateful!
from pzem-004t-v30.
from pzem-004t-v30.
@Alfonso-Lijo, thanks for using my library, I wasn't expecting many people to do so. I was having similar issues and honestly I have no idea how to make it work more elegantly on an UNO . If you have any suggestions, please feel free to open up a pull request!
from pzem-004t-v30.
@mandulaj I would not waste time with software serial, we all know it is a workaround for old devices.
Most of all new devices (esp32, stm32) have more than one HW Serial.
In the real-life, no one will (or should) put in production a device for monitoring power using software serial. It ends up most of the people using SW Serial it's bench test.
from pzem-004t-v30.
@pye222 Is this still something that needs work? Have you found a way to fix or some kind of work around?
from pzem-004t-v30.
It's working within my needs and I haven't made any more changes! Thanks!
from pzem-004t-v30.
Ok, in that case I will close this issue.
from pzem-004t-v30.
Related Issues (20)
- I can not read 3 pzem HOT 3
- Pzem-004t v3 + Esp32 DEVKITV1 HOT 2
- Mycropyton HOT 1
- HOW TO RESET PZEM004TV3 ESP32? HOT 1
- when I try to upload, I get an error like this: no matching function for call to 'PZEM004Tv30::PZEM004Tv30(int, int) HOT 7
- Seeed Wio LTE
- instantaneous value HOT 1
- Module PZEM-004T-100A-D-P HOT 1
- Issue with Teensy 4.1, using any of the hardware serials (Serial1...Serial8)
- Voltage measurement up to 500 volts HOT 2
- Pzem measuring wrong voltage values HOT 2
- Can you make this code non-blocking? HOT 10
- How to modify this code to only output certain values HOT 6
- is there possible to change the CT (Current Transformer)? HOT 1
- Check if module is connected HOT 2
- Is it possible to send one command to measure to all devices connected instead of sending multiple separated commands? HOT 2
- Issue with 16 current coils muxed together with a single PZEM HOT 1
- Inconsisten Byte order in CRC check sum HOT 6
- Lamp cannot dim by TRIAC when connect with PZEM 004T HOT 10
- More than 4 pzem-004t
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pzem-004t-v30.