forked from olehs/PZEM004T
-
Notifications
You must be signed in to change notification settings - Fork 2
/
_P171_PZEM-004T.ino
188 lines (168 loc) · 5.87 KB
/
_P171_PZEM-004T.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#ifdef USES_P171
//#######################################################################################################
//################### Plugin 171 PZEM-004T AC Current and Voltage measurement sensor ####################
//#######################################################################################################
//
// This plugin is interfacing with PZEM-004T Sesor with softserial communication as the sensor
// has an UART pinout (TX/RX/VCC/GND)
//
// XXX To compile with new version : https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=4007&p=33674#p33674
#include <ESPEasySerial.h>
#include <PZEM004T.h>
PZEM004T *Plugin_171_pzem;
IPAddress pzemIP(192,168,1,1); // required by the library but not used (dummy value)
#define PLUGIN_171
#define PLUGIN_ID_171 171
#define PLUGIN_171_DEBUG false //activate extra log info in the debug
#define PLUGIN_NAME_171 "Voltage & Current (AC) - PZEM-004T"
#define PLUGIN_VALUENAME1_171 "Voltage"
#define PLUGIN_VALUENAME2_171 "Current"
#define PLUGIN_VALUENAME3_171 "Power"
#define PLUGIN_VALUENAME4_171 "Energy"
// local parameter for this plugin
#define PZEM_MAX_ATTEMPT 3
boolean Plugin_171(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_171;
Device[deviceCount].Type = DEVICE_TYPE_DUAL;
Device[deviceCount].VType = SENSOR_TYPE_QUAD;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 4;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = false;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_171);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_171));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_171));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_171));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_171));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
addFormNote(F("SoftSerial: 1st=RX-Pin, 2nd=TX-Pin"));
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
success = true;
break;
}
case PLUGIN_READ:
{
if (PLUGIN_171_DEBUG) {
String log = F("PZEM004T: Reading started.");
addLog(LOG_LEVEL_INFO, log);
}
float pzVoltage = Plugin171_ReadVoltage();
float pzCurrent = Plugin171_ReadCurrent();
float pzPower = Plugin171_ReadPower();
float pzEnergy = Plugin171_ReadEnergy();
//-------------------------------------------------------------------
// readings can be ZERO if there's no AC input on the module.
// in this case V A and W are reported correctly as ZERO but
// the accumulated Energy paramenter will not be saved so to
// preserve previous value
//-------------------------------------------------------------------
UserVar[event->BaseVarIndex] = pzVoltage;
UserVar[event->BaseVarIndex + 1] = pzCurrent;
UserVar[event->BaseVarIndex + 2] = pzPower;
if (pzEnergy>=0) UserVar[event->BaseVarIndex + 3] = pzEnergy;
if (PLUGIN_171_DEBUG) {
String log = F("PZEM004T: Reading completed.");
addLog(LOG_LEVEL_INFO, log);
}
success = true;
break;
}
case PLUGIN_INIT:
{
if (!Plugin_171_pzem)
{
int pzemRXpin = Settings.TaskDevicePin1[event->TaskIndex];
int pzemTXpin = Settings.TaskDevicePin2[event->TaskIndex];
Plugin_171_pzem = new PZEM004T(pzemRXpin, pzemTXpin);
if (PLUGIN_171_DEBUG) {
String log = F("PZEM004T: Object Initialized");
log += F(" - RX-Pin="); log += pzemRXpin;
log += F(" - TX-Pin="); log += pzemTXpin;
addLog(LOG_LEVEL_INFO, log);
}
Plugin_171_pzem->setAddress(pzemIP); // This initializes the PZEM004T library using a (useless) fake IP address
if (PLUGIN_171_DEBUG) {
String log = F("PZEM004T: setup address (dummy)");
log += F(" - "); log += pzemIP;
addLog(LOG_LEVEL_INFO, log);
}
}
success = true;
break;
}
}
return success;
}
//************************************//
//***** reading values functions *****//
//************************************//
// NOTE: readings are attempted only PZEM_AMX_ATTEMPT times
float Plugin171_ReadVoltage() {
int counter = 0;
float reading = -1.0;
do {
reading = Plugin_171_pzem->voltage(pzemIP);
wdt_reset();
counter++;
} while (counter < PZEM_MAX_ATTEMPT && reading < 0.0);
if (reading == -1) reading = 0;
return reading;
}
float Plugin171_ReadCurrent() {
int counter = 0;
float reading = -1.0;
do {
reading = Plugin_171_pzem->current(pzemIP);
wdt_reset();
counter++;
} while (counter < PZEM_MAX_ATTEMPT && reading < 0.0);
if (reading == -1) reading = 0;
return reading;
}
float Plugin171_ReadPower() {
int counter = 0;
float reading = -1.0;
do {
reading = Plugin_171_pzem->power(pzemIP);
wdt_reset();
counter++;
} while (counter < PZEM_MAX_ATTEMPT && reading < 0.0);
if (reading == -1) reading = 0;
return reading;
}
float Plugin171_ReadEnergy() {
int counter = 0;
float reading = -1.0;
do {
reading = Plugin_171_pzem->energy(pzemIP);
wdt_reset();
counter++;
} while (counter < PZEM_MAX_ATTEMPT && reading < 0.0);
return reading;
}
#endif // USES_P171