Closed Miq1 closed 3 years ago
I examined the PCB and found it is definitely a BL0937 being used here. So I assume the reference voltage must be difgferent as will be the multipliers.
If someone is interested:
@Miq1 can you please give more details for BL0937? I want to measure only RMS current and active power every 200ms. Can you please share how much pulses do you have for a current of 100mA or so, for example? And 16A ?
Hi, I have no consumer yet to get up to 16A 😀 What I can do is give you my code - I completely abandoned the hlw8012 lib and am using the bare functions only:
Globally:
...
// Energy monitor GPIOs for Gosund SP1
#define SEL_PIN 12
#define CF_PIN 4
#define CF1_PIN 5
// Energy monitor settings
#define UPDATE_TIME 5000
#define HIGH_PULSE 38
...
// Time between reads of the energy monitor im milliseconds
constexpr unsigned int update_interval = (UPDATE_TIME >= 2000) ? UPDATE_TIME : 2000;
// Number of intervals since system boot
unsigned long tickCount = 0;
// Spent Watt hours (Wh) since system boot
double accumulatedWatts = 0.0;
// Calculation helpers for hours and minutes since system boot
constexpr unsigned int ticksPerHour = 3600000 / update_interval;
constexpr unsigned int ticksPerMinute = 60000 / update_interval;
...
In setup():
...
// Configure energy meter GPIOs
pinMode(CF_PIN, INPUT);
pinMode(CF1_PIN, INPUT);
pinMode(SEL_PIN, OUTPUT);
tickCount = 0;
accumulatedWatts = 0.0;
...
void updateEnergy() {
static unsigned long last = millis(); // time of last read
static bool select = false; // Toggle for voltage/current
static double volt = 0.0; // Last read voltage value
static double amps = 0.0; // Last read current value
static double watt = 0.0; // Last read power value
unsigned long int cf; // CF read value (power pulse length)
unsigned long int cf1; // CF1 read value (voltage/current pulse length)
// New read due?
if ((millis() - last) > update_interval) {
// Yes. Read pulse lengths. Note: current reading may take a long time (up to 2.5 seconds)
cf1 = pulseIn(CF1_PIN, LOW, 2500000); // Read voltage or current
cf = pulseIn(CF_PIN, LOW, 200000); // Read power
// Calculate watts according the BL 0937 specs
// Vref^2 cycle length v-specs resistors
// watt = cf ? (1483524.0 / (cf + HIGH_PULSE) / 1721506.0 * 2001000.0) : 0.0;
watt = cf ? (1724380.585/(cf + HIGH_PULSE)) : 0.0;
accumulatedWatts += watt * (millis() - last) / 3600000.0;
// Did we read current?
if (select) {
// Yes. Calculate amps according to specs
// Vref cycle length v-specs shunt
// amps = cf1 ? (1218000.0 / (cf1 + HIGH_PULSE) / 94638.0 * 1000.0) : 0.0;
amps = cf1 ? (12870.0/(cf1 + HIGH_PULSE)) : 0.0;
// Toggle SEL pin to read the other value next time around
digitalWrite(SEL_PIN, HIGH);
select = false;
} else {
// No. Calculate volts according to specs
// Vref cycle length v-specs resistors
// volt = cf1 ? (1218000.0 / (cf1 + HIGH_PULSE) / 15397.0 * 2001.0) : 0.0;
volt = cf1 ? (158299.656/(cf1 + HIGH_PULSE)) : 0.0;
// Toggle SEL pin to read the other value next time around
digitalWrite(SEL_PIN, LOW);
select = true;
}
tickCount++;
last = millis();
}
}
I doubt that you will be lucky reading the current every 200ms. The data sheet specifies a measuring time of up to 2s for a single sample. I experienced something similar with low currents, where the pulse length may reach 100ms and more. It may be better with higher currents and shorter pulse lengths.
thank you for sharing your code. Anyway, I will try with an oscilloscope to check by myself. You also mentioned that the datasheet specifies 2s for measuring, but I cannot find this info in the v1.4 datasheet in Chinese.. where did you read this? In my case I will only measure current, so will not toggle with voltage.
Yes, I already read this. Anyway other users reports that lower times are possible, see https://github.com/xoseperez/hlw8012/issues/13#issue-433756980
I would say: just try it! I will appreciate if you could share your results.
I am getting many 0A results when using a timeout of 250000 (250ms) with pulseIn()
. I need a second at least to read low wattages around 5W.
I am trying to make a sense out of the readings the HLW8012 library gives me for the Gosund SP1 plug.
The raw values I get with the default settings:
are quite off. These are the values from the lib (with a soldering station attached to the plug):
A cheap power meter set in between shows these readings (varying a bit, as the soldering station is levelling the tip temperature):
What are the multipliers required to correct the values?