Foros
Nuevos mensajes
Buscar en foros
Novedades
Nuevos mensajes
Nuevos recursos
Última actividad
Recursos
Últimas revisiones
Buscar recursos
Acceder
Registrarse
Novedades
Buscar
Buscar
Buscar sólo en títulos
De:
Nuevos mensajes
Buscar en foros
Menú
Acceder
Registrarse
Install the app
Instalar
Diseño digital
Microcontroladores y sistemas embebidos
Arduino y Raspberry Pi
Medidor de Potencia con Pzem-004T V3
JavaScript está desactivado. Para una mejor experiencia, por favor, activa JavaScript en el navegador antes de continuar.
Estás usando un navegador obsoleto. No se pueden mostrar este u otros sitios web correctamente.
Se debe actualizar o usar un
navegador alternativo
.
Responder al tema
Mensaje
[QUOTE="TomasBarreneche, post: 1369588, member: 585995"] Buen día Comunidad, les comparto un proyecto que realicé hace un tiempito, que me encontré con poca información o muy dispersa y creo que a alguien le puede servir. Parte del contenido fue tomado de otras personas o librerías. Se trata de una implementación de Datalogger de variables eléctricas utilizando un modulo Pzem-004T-V3 utilizando un Arduino Uno, un modulo SD y un RTC DS1302. La necesidad de realizar este equipo surge a raíz de la necesidad de contar con curvas diarias de consumo de un usuario (vivienda, establecimiento o pequeña instalación aislada) para realizar un análisis de mejora de eficiencia y optimización de un sistema de generación aislada a base de paneles solares y/o pequeños aerogeneradores. La definición de los materiales fue una elección de disponibilidad y económica. El datalogger propuesto se basa en una placa PZEM004T-V3, la cual realiza la medición de variables eléctricas y las envía a un Arduino UNO, este las almacena en una SD. Para conocer fecha y hora de la toma de los datos se utiliza un RTC (Real Time Clock) que mantiene la hora por más que el equipo se encuentre apagado o desenergizado. [CODE] #include <PZEM004Tv30.h> #include <stdio.h> #include <DS1302.h> #include <SPI.h> #include <SD.h> PZEM004Tv30 pzem(9,10); /// use Serial // el pin 9 va al Tx del Pzem y el 10 al Rx del Pzem DS1302 rtc(8, 7, 6); // rtc(kCePin, kIoPin, kSclkPin) //rtc(pin reset, pin data, pin Clock) // SD Card por defecto utilia SPI bus, como: //MOSI - pin 11; MISO - pin 12; CLK - pin 13; CS - pin 4. // Delcaración de Variables que se van a escribir en el SD float voltage_sd =0; float current_sd =0; float power_sd =0; float energy_sd =0; float frecuency_sd =0; float pf_sd =0; // Variables auxiliares que se usan en el promedio float vol =0; float cur =0; float pot =0; // Variables auxiliares para el manejo de los tiempos unsigned long lastMillis = 0; unsigned long lastMillisprom = 0; unsigned long nUnsignedLong = 4294967295; //Cifra máxima almacenable en un unsigned long unsigned long tiempo = 10000; //Tiempo de esctitura en la SD en ms. Time t = rtc.time(); const int chipSelect = 4; // selecciona el SD File dataFile; // Variables auxiliares para el Tamaño del Archivo guardado en SD unsigned long Archivosize = 3500000; // Tamaño del archivo que guardamos, en Byte. unsigned long Actualsize = 0; int Contador = 0; char filename[16]; int i = 0; void setup() { pinMode(3, OUTPUT); digitalWrite(3, LOW); //parpadeo de escritura ok pinMode(2, OUTPUT); //Led de no reconocimiento de la SD //No Debug console // Serial.begin(9600); // Note : Do not use Serial0 port, for serial debugging! // Serial.print("Initializing SD card..."); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { // Serial.println("Card failed, or not present"); digitalWrite(2, HIGH); //Led de no reconocimiento de la SD return; } else { // Serial.println("card initialized."); digitalWrite(2, LOW); //Led de no reconocimiento de la SD } // Creamos el fichero de registro for (i = 0; i < 100; i++) { sprintf(filename, "data%03d.csv", i); // Serial.print("Filename:"); Serial.println(filename); if (!SD.exists(filename)) { // Si no existe el fichero, lo creamos // Serial.println(SD.exists(filename)); dataFile = SD.open(filename, FILE_WRITE); // Serial.println(dataFile); if (dataFile) { // Serial.println("Escribiendo encabezado en el .csv"); dataFile.println("Fecha, Hora, Tensión[V], Corriente[I], Potencia[W], Energía[kW/h], Frecuencia[Hz], FP"); } Actualsize = dataFile.size(); dataFile.close(); break; // leave the loop! } else{ dataFile = SD.open(filename); Actualsize = dataFile.size(); dataFile.close(); } // Serial.println(Actualsize); if (SD.exists(filename)&& Actualsize<Archivosize) { // Si existe el fichero y pesa menos de Archivosize, lo abrimos y usamos break; // leave the loop! } } vol = vol + pzem.voltage(); } void loop(){ if ( (nUnsignedLong - millis()) > tiempo ){ //evitamos overflow de millis if (millis() - lastMillis > tiempo) { lastMillis = millis(); //Toma el valor del Reloj-RTC Time t = rtc.time(); //Abrimos el archivo en la SD dataFile = SD.open(filename, FILE_WRITE); // if the file is available, write to it: if (dataFile) { //prueba, ver que no lea si no hay SD digitalWrite(3, HIGH); //parpadeo de ok digitalWrite(2, LOW); //Led de no reconocimiento de la SD // Read meter PZEM float v = vol/Contador; float i = cur/Contador; float p = pot/Contador; float e = pzem.energy(); float fr = pzem.frequency(); float pf = pzem.pf(); vol = 0; cur = 0; pot = 0; Contador = 0; // Asigna los valores leídos si son mayor a cero, como medida de una lectura correcta if(v >= 0.0){voltage_sd =v;} //V if(i >= 0.0){current_sd =i;} //A if(p >= 0.0){power_sd =p;} //W if(e >= 0.0){energy_sd =e;} //kWh if(fr >= 0.0){frecuency_sd =fr;} //Hz if(pf >= 0.0){pf_sd =pf;} //Factor de Potencia // Escribir en la SD en CSV // Escribimos la fecha en la SD - AAAA/MM/DD dataFile.print(t.yr); dataFile.print("/"); dataFile.print(t.mon); dataFile.print("/"); dataFile.print(t.date); dataFile.print(","); //esta coma separa la fecha de la hora al momento de imporar el .csv // Escribimos la hora en la SD - hh:mm:ss dataFile.print(t.hr); dataFile.print(":"); dataFile.print(t.min); dataFile.print(":"); dataFile.print(t.sec); dataFile.print(","); // Escribimos la V , I , W , kWh , Hz , FP dataFile.print(v); dataFile.print(","); dataFile.print(i); dataFile.print(","); dataFile.print(p); dataFile.print(","); dataFile.print(e); dataFile.print(","); dataFile.print(fr); dataFile.print(","); dataFile.println(pf); Actualsize = dataFile.size(); // Cerramos el archivo para la escritura en la SD dataFile.close(); /* //imprimimos la en el puerto serie Serial.print("Fecha:"); Serial.print(t.yr); Serial.print(t.mon); Serial.print(t.date); Serial.print(" Hora:"); Serial.print(t.hr); Serial.print(":"); Serial.print(t.min); Serial.print(":"); Serial.print(t.sec);Serial.print(" "); Serial.print("V="); Serial.print(v); Serial.print("V, I="); Serial.print(i); Serial.print("A, P="); Serial.print(p); Serial.print("W, E="); Serial.println(e); */ digitalWrite(3, LOW); //parpadeo de ok lastMillisprom = millis(); } // if the file isn't open, pop up an error: else { // Serial.println("error opening datalog.txt"); digitalWrite(2, HIGH); //Led de no reconocimiento de la SD delay (2000); SD.begin(chipSelect); dataFile = SD.open(filename); Actualsize = dataFile.size(); dataFile.close(); } } // Toma de datos para promedio if (millis() - lastMillisprom > tiempo/6) { lastMillisprom = millis(); vol = vol + pzem.voltage(); cur = cur + pzem.current(); pot = pot + pzem.power(); Contador = Contador +1; } } else { delay(5000); //asegurarnos de que millis() vuelva a cero y arrancar de nuevo. Para evitar el overflow de la funcion millis lastMillis = millis(); } if (Actualsize >= Archivosize){ //partimos el archivo por pesar más de Archivosize for (i=i; i < 100; i++) { sprintf(filename, "data%03d.csv", i); // Serial.print("Filename:"); Serial.println(filename); if (!SD.exists(filename)) { // Si no existe el fichero, lo creamos // Serial.println(SD.exists(filename)); dataFile = SD.open(filename, FILE_WRITE); // Serial.println(dataFile); if (dataFile) { // Serial.println("Escribiendo encabezado"); dataFile.println("Fecha, Hora, Tensión[V], Corriente[I], Potencia[W], Energía[kW/h], Frecuencia[Hz], FP"); } Actualsize = dataFile.size(); dataFile.close(); break; // leave the loop! } } } } [/CODE] Para configurar el RTC, el siguiente: [CODE]// Example sketch for interfacing with the DS1302 timekeeping chip. // // Copyright (c) 2009, Matt Sparks // All rights reserved. // // http://quadpoint.org/projects/arduino-ds1302 #include <stdio.h> #include <DS1302.h> namespace { // Set the appropriate digital I/O pin connections. These are the pin // assignments for the Arduino as well for as the DS1302 chip. See the DS1302 // datasheet: // // http://datasheets.maximintegrated.com/en/ds/DS1302.pdf const int kCePin = 8; // Chip Enable const int kIoPin = 7; // Input/Output const int kSclkPin = 6; // Serial Clock // Create a DS1302 object. DS1302 rtc(kCePin, kIoPin, kSclkPin); String dayAsString(const Time::Day day) { switch (day) { case Time::kSunday: return "Sunday"; case Time::kMonday: return "Monday"; case Time::kTuesday: return "Tuesday"; case Time::kWednesday: return "Wednesday"; case Time::kThursday: return "Thursday"; case Time::kFriday: return "Friday"; case Time::kSaturday: return "Saturday"; } return "(unknown day)"; } void printTime() { // Get the current time and date from the chip. Time t = rtc.time(); // Name the day of the week. const String day = dayAsString(t.day); // Format the time and date and insert into the temporary buffer. char buf[50]; snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d", day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec); // Print the formatted string to serial so we can see the time. Serial.println(buf); } } // namespace void setup() { Serial.begin(9600); // Initialize a new chip by turning off write protection and clearing the // clock halt flag. These methods needn't always be called. See the DS1302 // datasheet for details. rtc.writeProtect(false); rtc.halt(false); // Make a new time object to set the date and time. // t(Año, Mes, Día, Hora, Minuto, Segundos, mombre del día); Time t(2021, 7, 15, 8, 42, 50, Time::kThursday); //colocar la fecha y hora al momento de cargar los datos. El programa tarda aproximadamente 10seg en cargarse. // Set the time and date on the chip. rtc.time(t); } // Loop and print the time every second. void loop() { printTime(); delay(1000); } [/CODE] [/QUOTE]
Verificación
Responder
Diseño digital
Microcontroladores y sistemas embebidos
Arduino y Raspberry Pi
Medidor de Potencia con Pzem-004T V3
Arriba