Re: Support for "Sonoff Pow" (from ITead) with Power Consumption Measurement via HLW8012 (HLW 8012) IC?
Posted: 23 Jun 2017, 00:51
Have fun with controlling everything!
https://www.letscontrolit.com/forum/
Then let's start every item with a warning: everything you do can kill you and everything posted on this forum is no acception to that!
Thank god cars don't yell at me (in german) that a car is dangerous and might kill you every time i start the car...
Join the club, i blew up a zenerdiode on my Sonoff TH16 due to a faulty breadboard voltage regulator spitting out 16V instead of the promised 5V. An AMS1117-5 DOA, go figure that...papperone wrote: ↑23 Jun 2017, 19:17 Well to be openly honest I did a mistake during the test even myself, and swapped Live and Neutral... As a results at next power up of the module small sparks and 2 resistors on the module got burnt (all ok after I replaced them!).
Nobody was killed and I can oly balme myslef that overlooked the connections...![]()
Code: Select all
C:\Users\kniazio\Desktop\ESP Releases\ESPEasy_v2.0.0-dev10\Source\ESPEasy\_P170_HLW8012.ino:17:21: fatal error: HLW8012.h: No such file or directory
#include <HLW8012.h>
^
compilation terminated.
What makes things worse is that wiring colors are relevant only when hard-wired. When using a wall socket and power cord with mains plug to connect the POW it is very easy to to switch Live and Neutral because in many countries the mains plug fits in two ways (normal and 180 degrees rotated).
All right.papperone wrote: ↑25 Jun 2017, 12:45 you need to install HLW8012 library --> http://www.electrodragon.com/w/File:HLW ... 0_1281.zip
Directly from ESPEasy it should be possible.but not sure how much ram it will eat.kniazio wrote: ↑26 Jun 2017, 06:19 I mean, is it possible to send readings to Thingspeak
https://thingspeak.com
I have to admit, that it's not running in test-mode but normal mode. I've removed the #if test condition from the ino file.papperone wrote: ↑03 Jul 2017, 08:38 that's weird, as the first time the plugin init itself it shoudl be saving the calibration values if they are equal to zero.
Can you try to send the command "HLWCalibrate" to calibrate manually and recalculate the multipliers?
By the way the default multipliers must be:
Power Mult: 10343611.74
Current Mult: 14484.49
Voltage Mult: 408636.51
Will check the code deeply later today but I just tried again 2 times in the 2 test modules and after erasing completely the SPIFF I've the deafult multipliers when I enable this device![]()
Please also check out my update:
Code: Select all
Update: The flash size seems odd, 4MB instead of the usual 1MB. I'll look into that...
AFAIK ESPEasy needs to be compiled with 3Mb firmware / 1Mb SPIFF (for 4Mb units); about 1Mb I'm not sure which are the right build options...LisaM wrote: ↑03 Jul 2017, 09:58Please also check out my update:This might also be the cause of the problems.Code: Select all
Update: The flash size seems odd, 4MB instead of the usual 1MB. I'll look into that...
Maybe the POW is 4MB?Flash Size: 4096 kB
Code: Select all
Unit: 5 : DEBUG: String size:8366
Unit: 5 : DEBUG: String size:2632
Exception (29):
epc1=0x402130a8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x0000001c depc=0x00000000
ctx: cont
sp: 3fff3960 end: 3fff3f90 offset: 01a0
>>>stack>>>
3fff3b00: 3fff3c30 00000008 3fff1ed8 4021309f
3fff3b10: 40100296 00000023 3fff6da8 ffff8000
3fff3b20: 00000000 00000000 00000000 00000000
3fff3b30: 00000000 00000000 00000000 00000000
3fff3b40: 00000000 00000000 00000000 00000000
3fff3b50: 3fff67e4 0000001f 00000012 3fff67cc
3fff3b60: 0000000f 00000004 3fff3bd4 4023df6e
3fff3b70: 3ffea97c 3fff3d04 00000000 4010053d
3fff3b80: 3ffe88d8 3fff3c10 3ffea97c 00000001
3fff3b90: 3fff0b3c 00000008 3fff3c30 4020ebf5
3fff3ba0: 00000010 3fff3d9c 00000000 4010053d
3fff3bb0: 3ffea97c 00000000 3fff3d04 4023deeb
3fff3bc0: 3fff6e54 00000002 3fff6ddc 0000000f
3fff3bd0: 00000000 3fff6df4 0000000f 00000000
3fff3be0: 3ffea97c 00000000 3fff3d9c 00000001
3fff3bf0: 00000024 00000032 00000000 40201020
3fff3c00: 3fff6e55 00000004 3fff3d9c 4023df6e
3fff3c10: 3ffea97c 00000004 3fff1ed8 00000001
3fff3c20: 00000004 3fff0b3c 00000000 40220e37
3fff3c30: 3ffe0055 400056cf 3ffee7e0 00000030
3fff3c40: 40103105 3ffee7e0 3fff3c70 4010068c
3fff3c50: 00007fff 01c24c18 3fff6a84 0000000f
3fff3c60: 00000000 3fff69f4 0000000f 00000000
3fff3c70: 00000000 3fff6e0c 0000000f 00000001
3fff3c80: 3fff6e24 0000000f 00000001 3fff6e3c
3fff3c90: 0000000f 00000001 3fff6e54 0000000f
3fff3ca0: 00000001 3fff6c8c 0000000f 0000000b
3fff3cb0: 3fff6dc4 0000000f 0000000b 3fff677c
3fff3cc0: 0000001f 00000010 3fff67a4 0000001f
3fff3cd0: 00000010 3fff65f4 0000000f 00000000
3fff3ce0: 3fff6c44 0000000f 00000000 3fff6c5c
3fff3cf0: 0000000f 00000000 3fff6c74 0000000f
3fff3d00: 00000000 65776f50 61462072 726f7463
3fff3d10: 29252820 3fffda00 3fff2f68 00000030
3fff3d20: 40000f83 00000030 00000010 ffffffff
3fff3d30: 3fff6e6c 0000000f 00000002 3fff6e84
3fff3d40: 0000000f 00000000 3fff6e9c 0000000f
3fff3d50: 00000000 3fff6cec 0000000f 00000001
3fff3d60: 3fff715c 0000000f 00000000 3fff65dc
3fff3d70: 0000000f 00000000 00000000 00000000
3fff3d80: 00000000 00000000 00000000 00000000
3fff3d90: 00000000 00000000 00000000 3fff6eb4
3fff3da0: 0000000f 00000000 3fff6efc 0000000f
3fff3db0: 00000001 3fff6ee4 0000000f 00000000
3fff3dc0: 3fff6ecc 0000000f 00000000 3fff6c2c
3fff3dd0: 0000000f 00000000 3fff6c14 0000000f
3fff3de0: 00000000 3fff6bfc 0000000f 00000000
3fff3df0: 3fff6be4 0000000f 00000000 3fff6bcc
3fff3e00: 0000000f 00000002 3fff6624 0000000f
3fff3e10: 00000002 3fff660c 0000000f 00000002
3fff3e20: 3fff7144 0000000f 00000002 3fff7594
3fff3e30: 0000000f 00000003 3fff6cbc 0000000f
3fff3e40: 00000001 00000476 00000476 3fff2e84
3fff3e50: 00000001 3fff17ec 00000001 3fff17ec
3fff3e60: 00000010 3fff3ec0 00000003 000002bc
3fff3e70: 3fff70bc 00000008 3fff3ec0 4023623c
3fff3e80: 00000002 00000001 3fff4a24 40221d59
3fff3e90: 00000002 00000001 3fff3ec0 4023fe6a
3fff3ea0: 00000000 00000000 3fff4a24 40236232
3fff3eb0: 3fff4a24 3fff1f18 3fff4a24 4023626e
3fff3ec0: 00000000 00000000 00000000 4023e04c
3fff3ed0: 3fff4a24 3fff1f18 3fff1ed8 40236301
3fff3ee0: 3fff70bc 0000000f 00000008 3fff2f70
3fff3ef0: 00000000 00000132 00000132 00000001
3fff3f00: 00000002 00000132 00000019 402403c4
3fff3f10: 00000000 00000000 3fff27b4 3fff2f68
3fff3f20: 00000001 3fff1efc 3fff1ed8 4023653b
3fff3f30: 3fffdad0 3fff2f68 4023edbc 3fff2f70
3fff3f40: 00000000 3fff70d4 00000000 4023d17e
3fff3f50: 3fffdad0 00000000 3fff0b38 40223173
3fff3f60: 00000000 00000000 3fff0b38 40228444
3fff3f70: 3fffdad0 00000000 3fff2f62 4023ee08
3fff3f80: feefeffe feefeffe 3fff2f70 40100718
<<<stack<<<
ets Jan 8 2013,rst cause:1, boot mode:(3,7)
load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v09826c6d
~ld
⸮U
INIT : Booting version: (custom)
FS : Mount successful
INIT : Free RAM:26016
INIT : SPI not enabled
bcn 0
del if1
usl
add if1
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
bcn 100
bcn 0
del if1
usl
mode : sta(5c:cf:7f:20:db:c2)
add if0
WIFI : Connecting... 1
f r-1, scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1
cnt
I see no debug changes here: https://github.com/letscontrolit/ESPEas ... l/51/files
None of the debug statements in P170 is listed...Unit: 0 : EVENT: System#Boot
Unit: 0 : INIT : Normal boot
Unit: 0 : Subscribed to: domoticz/out
Unit: 0 : MQTT : Connected to broker
Unit: 0 : WIFI : Connected! IP: 192.168.178.89
It completes the plugin device add function and then resets itself...Unit: 5 : MQTT : Payload: Connection Lost
Unit: 5 : MQTT : Topic: domoticz/out
Unit: 5 : MQTT : Payload: Connected
Unit: 5 : MQTT : Topic: domoticz/out
Unit: 5 : EVENT: Processing time:16 milliSeconds
Unit: 5 : WD : Uptime 0 ConnectFailures 0 FreeMem 22104
Unit: 5 : EVENT: Processing time:19 milliSeconds
Unit: 5 : EVENT: System#Boot
Unit: 5 : NTP : NTP replied: 21 mSec
Unit: 5 : NTP : NTP send to 194.109.6.2
Unit: 5 : NTP : NTP sync request:1
Unit: 5 : INIT : Normal boot
Unit: 5 : Subscribed to: domoticz/out
Unit: 5 : MQTT : Connected to broker
Unit: 5 : HLW8012: End PLUGIN_DEVICE_ADD
Unit: 5 : HLW8012: Begin PLUGIN_DEVICE_ADD
Unit: 5 : WIFI : Connected! IP: 192.168.178.89
Unit: 5 : HLW8012: Begin PLUGIN_WEBFORM_SAVE
Code: Select all
//#######################################################################################################
//#################### Plugin 170 HLW8012 AC Current and Voltage measurement sensor #####################
//#######################################################################################################
//
// This plugin is interfacing with HLW8012 IC which is use with some commercial devices:
// -- Sonoff POW
// -- ElectroDragon HLW8012 Breakout board
//
// The Sonoff POW uses the following PINs: SEL=GPIO05(D1), CF1=GPIO13(D8), CF=GPIO14(D5)
// The ED Module has pinheaders so any available PIN on the ESP8266 can be used.
//
// HLW8012 IC works with 5VDC (it seems at 3.3V is not stable in reading)
//
//#ifdef PLUGIN_BUILD_TESTING
#include <HLW8012.h>
HLW8012 *Plugin_170_hlw;
#define PLUGIN_170
#define PLUGIN_ID_170 170
#define PLUGIN_170_DEBUG true //activate extra log info in the debug
#define PLUGIN_NAME_170 "Voltage & Current (AC) - HLW8012"
#define PLUGIN_VALUENAME1_170 "Voltage (V)"
#define PLUGIN_VALUENAME2_170 "Current (A)"
#define PLUGIN_VALUENAME3_170 "Active Power (W)"
#define PLUGIN_VALUENAME4_170 "Power Factor (%)"
//----------------- HLW8012 Default parameters --------------------------------------------------
// Set SEL_PIN to HIGH to sample current
// This is the case for Itead's Sonoff POW, where the SEL_PIN drives a transistor that pulls down
// the SEL pin in the HLW8012 when closed
#define HLW_CURRENT_MODE HIGH
// These are the nominal values for the resistors in the circuit
#define HLW_CURRENT_RESISTOR 0.001
#define HLW_VOLTAGE_RESISTOR_UP ( 5 * 470000 ) // Real: 2280k
#define HLW_VOLTAGE_RESISTOR_DOWN ( 1000 ) // Real 1.009k
//-----------------------------------------------------------------------------------------------
byte StoredTaskIndex;
boolean Plugin_170(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_DEVICE_ADD");
addLog(LOG_LEVEL_INFO, log);
}
Device[++deviceCount].Number = PLUGIN_ID_170;
Device[deviceCount].Type = DEVICE_TYPE_TRIPLE;
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;
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_DEVICE_ADD");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_GET_DEVICENAME:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_GET_DEVICENAME");
addLog(LOG_LEVEL_INFO, log);
}
string = F(PLUGIN_NAME_170);
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_GET_DEVICENAME");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_GET_DEVICEVALUENAMES");
addLog(LOG_LEVEL_INFO, log);
}
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_170));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_170));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_170));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_170));
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_GET_DEVICEVALUENAMES");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_WEBFORM_LOAD:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_WEBFORM_LOAD");
addLog(LOG_LEVEL_INFO, log);
}
addFormNote(string, F("Sonoff POW: 1st(SEL)=GPIO-5, 2nd(CF1)=GPIO-13, 3rd(CF)=GPIO-14"));
addFormSubHeader(string, F("Calibration Values"));
double hlwMultipliers[3];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
addFormTextBox(string, F("Current Multiplier"), F("plugin_170_currmult"), String(hlwMultipliers[0], 2), 25);
addFormTextBox(string, F("Voltage Multiplier"), F("plugin_170_voltmult"), String(hlwMultipliers[1], 2), 25);
addFormTextBox(string, F("Power Multiplier"), F("plugin_170_powmult"), String(hlwMultipliers[2], 2), 25);
success = true;
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_WEBFORM_LOAD");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_WEBFORM_SAVE:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_WEBFORM_SAVE");
addLog(LOG_LEVEL_INFO, log);
}
double hlwMultipliers[3];
String tmpString, arg1;
arg1 = F("plugin_170_currmult"); tmpString = WebServer.arg(arg1);
hlwMultipliers[0] = atof(tmpString.c_str());
arg1 = F("plugin_170_voltmult"); tmpString = WebServer.arg(arg1);
hlwMultipliers[1] = atof(tmpString.c_str());
arg1 = F("plugin_170_powmult"); tmpString = WebServer.arg(arg1);
hlwMultipliers[2] = atof(tmpString.c_str());
SaveCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Saved Calibration from Config Page");
addLog(LOG_LEVEL_INFO, log);
}
Plugin_170_hlw->setCurrentMultiplier(hlwMultipliers[0]);
Plugin_170_hlw->setVoltageMultiplier(hlwMultipliers[1]);
Plugin_170_hlw->setPowerMultiplier(hlwMultipliers[2]);
success = true;
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_WEBFORM_SAVE");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_READ:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_READ");
addLog(LOG_LEVEL_INFO, log);
}
Plugin_170_hlw->setMode(MODE_CURRENT); delay(200); double hcurrent = Plugin_170_hlw->getCurrent();
Plugin_170_hlw->setMode(MODE_VOLTAGE); delay(200); unsigned int hvoltage = Plugin_170_hlw->getVoltage();
unsigned int hpower = Plugin_170_hlw->getActivePower();
//unsigned int happpower = Plugin_170_hlw->getApparentPower();
unsigned int hpowfact = (int) (100 * Plugin_170_hlw->getPowerFactor());
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Read values");
log += F(" - V="); log += hvoltage;
log += F(" - A="); log += hcurrent;
log += F(" - W="); log += hpower;
log += F(" - Pf%="); log += hpowfact;
addLog(LOG_LEVEL_INFO, log);
}
UserVar[event->BaseVarIndex] = hvoltage;
UserVar[event->BaseVarIndex + 1] = hcurrent;
UserVar[event->BaseVarIndex + 2] = hpower;
UserVar[event->BaseVarIndex + 3] = hpowfact;
//Plugin_170_hlw->toggleMode();
success = true;
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_READ");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_INIT:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_INIT");
addLog(LOG_LEVEL_INFO, log);
}
if (!Plugin_170_hlw)
{
Plugin_170_hlw = new HLW8012;
// This initializes the HWL8012 library.
Plugin_170_hlw->begin(Settings.TaskDevicePin3[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex], Settings.TaskDevicePin1[event->TaskIndex], HLW_CURRENT_MODE, false, 1000000);
if (PLUGIN_170_DEBUG) addLog(LOG_LEVEL_INFO, F("HLW8012: Init object done"));
Plugin_170_hlw->setResistors(HLW_CURRENT_RESISTOR, HLW_VOLTAGE_RESISTOR_UP, HLW_VOLTAGE_RESISTOR_DOWN);
if (PLUGIN_170_DEBUG) addLog(LOG_LEVEL_INFO, F("HLW8012: Init Basic Resistor Values done"));
// If multipliers are empty load default ones and save all of them as "CustomTaskSettings"
double hlwMultipliers[3];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
if (hlwMultipliers[0] == 0) { hlwMultipliers[0] = Plugin_170_hlw->getCurrentMultiplier(); }
if (hlwMultipliers[1] == 0) { hlwMultipliers[1] = Plugin_170_hlw->getVoltageMultiplier(); }
if (hlwMultipliers[2] == 0) { hlwMultipliers[2] = Plugin_170_hlw->getPowerMultiplier(); }
SaveCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
if (PLUGIN_170_DEBUG) addLog(LOG_LEVEL_INFO, F("HLW8012: Saved Calibration after INIT"));
StoredTaskIndex = event->TaskIndex; // store task index value in order to use it in the PLUGIN_WRITE routine
}
success = true;
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_INIT");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
case PLUGIN_WRITE:
{
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin PLUGIN_WRITE");
addLog(LOG_LEVEL_INFO, log);
}
if (Plugin_170_hlw)
{
String tmpString = string;
int argIndex = tmpString.indexOf(',');
if (argIndex)
tmpString = tmpString.substring(0, argIndex);
if (tmpString.equalsIgnoreCase(F("hlwreset")))
{
Plugin_170_hlw->resetMultipliers();
Plugin170_SaveMultipliers();
if (PLUGIN_170_DEBUG) addLog(LOG_LEVEL_INFO, F("HLW8012: Reset Multipliers to DEFAULT"));
success = true;
}
if (tmpString.equalsIgnoreCase(F("hlwcalibrate")))
{
String tmpStr = string;
unsigned int CalibVolt = 0;
double CalibCurr = 0;
unsigned int CalibAcPwr = 0;
int comma1 = tmpStr.indexOf(',');
int comma2 = tmpStr.indexOf(',', comma1+1);
int comma3 = tmpStr.indexOf(',', comma2+1);
if (comma1 != 0) {
if (comma2 == 0) {
CalibVolt = tmpStr.substring(comma1+1).toInt();
} else if (comma3 == 0) {
CalibVolt = tmpStr.substring(comma1+1, comma2).toInt();
CalibCurr = atof(tmpStr.substring(comma2+1).c_str());
} else {
CalibVolt = tmpStr.substring(comma1+1, comma2).toInt();
CalibCurr = atof(tmpStr.substring(comma2+1, comma3).c_str());
CalibAcPwr = tmpStr.substring(comma3+1).toInt();
}
}
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Calibration to values");
log += F(" - Expected-V="); log += CalibVolt;
log += F(" - Expected-A="); log += CalibCurr;
log += F(" - Expected-W="); log += CalibAcPwr;
addLog(LOG_LEVEL_INFO, log);
}
if (CalibVolt != 0) { Plugin_170_hlw->expectedVoltage(CalibVolt); }
if (CalibCurr != 0) { Plugin_170_hlw->expectedCurrent(CalibCurr); }
if (CalibAcPwr != 0) { Plugin_170_hlw->expectedActivePower(CalibAcPwr); }
// if at least one calibration value has been provided then save the new multipliers //
if ((CalibVolt + CalibCurr + CalibAcPwr) != 0) { Plugin170_SaveMultipliers(); }
success = true;
}
}
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End PLUGIN_WRITE");
addLog(LOG_LEVEL_INFO, log);
}
break;
}
}
return success;
}
void Plugin170_SaveMultipliers() {
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Begin Plugin170_SaveMultipliers");
addLog(LOG_LEVEL_INFO, log);
}
double hlwMultipliers[3];
hlwMultipliers[0] = Plugin_170_hlw->getCurrentMultiplier();
hlwMultipliers[1] = Plugin_170_hlw->getVoltageMultiplier();
hlwMultipliers[2] = Plugin_170_hlw->getPowerMultiplier();
SaveCustomTaskSettings(StoredTaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: End Plugin170_SaveMultipliers");
addLog(LOG_LEVEL_INFO, log);
}
}
//#endif
Code: Select all
SaveCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
this is the official way to save variables in the SPIFF file; it's been used by various plugins (OLED, LCD, etc) and I was pointed to use that due to the fact I need "DOUBLE" variable instead of "FLOAT".LisaM wrote: ↑08 Jul 2017, 01:30 It looks like something in here is horribly wrong:It causes the function to abort, i suspect that the reboot is due to the fact that you're saving a local function variable pointer in a global area...Code: Select all
SaveCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
Code: Select all
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings size: ");
log += sizeof(ghlwMultipliers);
addLog(LOG_LEVEL_INFO, log);
}
SaveCustomTaskSettings(event->TaskIndex, (byte*)&ghlwMultipliers, sizeof(ghlwMultipliers));
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Saved Calibration from Config Page");
addLog(LOG_LEVEL_INFO, log);
}
So it really reboots after calling SaveCustomTaskSettings. I have renamed hlwMultipliers to ghlwMultipliers and moved to line 46:Unit: 5 : HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings size: 24
Unit: 5 : WIFI : Connected! IP: 192.168.178.89
Code: Select all
boolean success = false;
double ghlwMultipliers[3];
It's working fine until i send the HLW8012 form...
Code: Select all
SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
Code: Select all
char deviceTemplate[8][64];
Code: Select all
char hlwMultipliers[3][32];
String tmpString, arg1;
arg1 = F("plugin_170_currmult"); tmpString = WebServer.arg(arg1);
strncpy(hlwMultipliers[0], tmpString.c_str(), sizeof(hlwMultipliers[0])-1);
arg1 = F("plugin_170_voltmult"); tmpString = WebServer.arg(arg1);
strncpy(hlwMultipliers[1], tmpString.c_str(), sizeof(hlwMultipliers[1])-1);
arg1 = F("plugin_170_powmult"); tmpString = WebServer.arg(arg1);
strncpy(hlwMultipliers[2], tmpString.c_str(), sizeof(hlwMultipliers[2])-1);
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings size: ");
log += sizeof(hlwMultipliers);
addLog(LOG_LEVEL_INFO, log);
}
SaveCustomTaskSettings(event->TaskIndex, (byte*)&hlwMultipliers, sizeof(hlwMultipliers));
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: Saved Calibration from Config Page");
addLog(LOG_LEVEL_INFO, log);
}
Plugin_170_hlw->setCurrentMultiplier(atof(hlwMultipliers[0]));
Plugin_170_hlw->setVoltageMultiplier(atof(hlwMultipliers[1]));
Plugin_170_hlw->setPowerMultiplier(atof(hlwMultipliers[2]));
success = true;
break;
And then rebootUnit: 5 : HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings size: 96
Code: Select all
/********************************************************************************************\
Save Custom Task settings to SPIFFS
\*********************************************************************************************/
boolean SaveCustomTaskSettings(int TaskIndex, byte* memAddress, int datasize)
{
if (datasize > DAT_TASKS_SIZE)
return false;
return SaveToFile((char*)"config.dat", DAT_OFFSET_TASKS + (TaskIndex * DAT_TASKS_SIZE) + DAT_TASKS_CUSTOM_OFFSET, memAddress, datasize);
}
Code: Select all
/********************************************************************************************\
Save data into config file on SPIFFS
\*********************************************************************************************/
boolean SaveToFile(char* fname, int index, byte* memAddress, int datasize)
{
boolean success = false;
if (RTC.flashDayCounter > MAX_FLASHWRITES_PER_DAY)
{
String log = F("FS : Daily flash write rate exceeded!");
addLog(LOG_LEVEL_ERROR, log);
return false;
}
fs::File f = SPIFFS.open(fname, "r+");
if (f)
{
f.seek(index, fs::SeekSet);
byte *pointerToByteToSave = memAddress;
for (int x = 0; x < datasize ; x++)
{
f.write(*pointerToByteToSave);
pointerToByteToSave++;
}
f.close();
String log = F("FILE : File saved");
addLog(LOG_LEVEL_INFO, log);
success = true;
flashCount();
}
return success;
}
String log = F("FILE : File saved");
addLog(LOG_LEVEL_INFO, log);
Code: Select all
if (PLUGIN_170_DEBUG) {
String log = F("HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings taskindex: ");
log += event->TaskIndex;
addLog(LOG_LEVEL_INFO, log);
String log2 = F("HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings hlwMultipliers: ");
log2 += hlwMultipliers[0];log2 += F(":");log2 += hlwMultipliers[1];log2 += F(":");log2 += hlwMultipliers[2];
addLog(LOG_LEVEL_INFO, log2);
String log3 = F("HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings size: ");
log3 += sizeof(hlwMultipliers);
addLog(LOG_LEVEL_INFO, log3);
}
Everything looks ok...HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings taskindex: 0
HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings hlwMultipliers: 10343611.74:14484.49:408636.51
HLW8012: PLUGIN_WEBFORM_SAVE - SaveCustomTaskSettings size: 96
Congrats! It's working flawless now:
Are these the right ones?Current Multiplier: 10343611.74
Voltage Multiplier: 14484.49
Power Multiplier: 408636.51
I'm currently using a custom sensor, but the syslog shows an error on the receiving side (domoticz):1820292 : HLW8012: Read values - V=7 - A=0.00 - W=0 - Pf%=0
1820293 : EVENT: Pomp#Voltage (V)=7.00
1820314 : EVENT: Pomp#Current (A)=0.00
1820330 : EVENT: Pomp#Active Power (W)=0.00
1820347 : EVENT: Pomp#Power Factor (%)=0.00
Looks like the power usage data is not sent...MQTT: Topic: domoticz/in, Message: {"idx":1172}
Error: MQTT: Invalid data received!
Code: Select all
UserVar[event->BaseVarIndex] = hvoltage;
UserVar[event->BaseVarIndex + 1] = hcurrent;
UserVar[event->BaseVarIndex + 2] = hpower;
UserVar[event->BaseVarIndex + 3] = hpowfact;
Code: Select all
UserVar[event->BaseVarIndex] = (float) hvoltage;
UserVar[event->BaseVarIndex + 1] = (float) hcurrent;
UserVar[event->BaseVarIndex + 2] = (float) hpower;
UserVar[event->BaseVarIndex + 3] = (float) hpowfact;
I don't have a clamp, but do have two multimeters. I'll put both of them to work to measure (V) and (I) at the same time... A 60W light bulb should do the trick being the load.papperone wrote: ↑12 Jul 2017, 07:32 good to hear reboot issue is confirmed fixed!!
about your points:
1) Even the ElectroDragon reads around 200/210 without calibration and default multipliers
2) You did not have controller setup for the AC Current sensor plugin so it's normal data are not sent out
In order to calibrate I do as follows:
- I connect a known load (a bulb, either filament or LED)
- I measure the real voltaga (V) with a DVM (multimeter) an current (A) with an Amperometric Clamp
- I run then when load is ON the calibration command "hlwcalibrate,VVV,AAA,WWW" where VVV is voltage measured before, AAA is current measured before, WWW is nominal bulb power in Watts (as written on the bulb)
This will recalculate the multipliers automatically with that given load and since then the readings are more accurate and realistic, even thou time to time the HLW8012 chip gives some wrong readings...
Last point is correct, the readings are not "doubles" variables, only the multipliers are.
surely you can, I do have a clamp and it's easier