mathieucarbou / YaSolR-OSS

YaS☀️lR (Yet another Solar Router) Open Source version
https://yasolr.carbou.me/
GNU General Public License v3.0
7 stars 0 forks source link

Publish energy to MQTT #18

Closed benoit-cty closed 3 months ago

benoit-cty commented 3 months ago

Hello,

The topic yasolr/grid/power is nice but is it possible to have a yasolr/grid/energy to publish the energy measure from JSY to Home Assistant Energy dashboard ?

My understanding is that energy counter from JSY will be more accurate than an outside estimation based on power x time .

mathieucarbou commented 3 months ago

Hello, I never thought about this interesting use case of using the JSY to also act as an energy meter for the grid! Yes that's totally doable and really easy! Besides, I can also add yasolr/grid/energy_returned to measure the production excess returned to the grid. Doing so the router will be able to completely replace a Shelly EM.

mathieucarbou commented 3 months ago

Are now all available in Home Assistant (through auto discovery), RESP API, Website (in Statistics), and of course MQTT. The float precision sent to MQTT has been updated to 3 digits also.

benoit-cty commented 3 months ago

Great !

mathieucarbou commented 3 months ago

My understanding is that energy counter from JSY will be more accurate than an outside estimation based on power x time

Note that this is only true for the measured grid power and energy by the JSY.

JSYs and PZEMs are not capable of correctly measuring the active power of the routed current going to the resistive load when phase control is used (i.e. triac, robodyn, random ssr). A lot of DIY solar routers are incorrectly reporting the JSY power measurements.

But that is another story ;-)

florentbr commented 3 months ago

@mathieucarbou

JSYs and PZEMs are not capable of correctly measuring the active power of the routed current going to the resistive load when phase control is used (i.e. triac, robodyn, random ssr).

Are you saying that the modules them-self are incapable of measuring accurately the active power on a regulated line with phase control or is it just an issue with the implementation? The Renergy IC used by the JSY is pretty accurate, at least on paper.

Have you measured the response time of the JSY by switching on/off a load ? The datasheet of the Renergy mentions a 3.495Hz refresh rate by default for the RMS values, so a 300ms average. I'm currently using a DDS238 meters but it's quite slow with a 2 seconds rolling average updated every half second or so. This is not optimal for a responsive feedback loop and I'm looking for an alternative.

mathieucarbou commented 3 months ago

@florentbr : there are several metrics we get from the JSY: power, power factor and current. I omit energy because this is a function of the power, and I also omit voltage, because JSY is not measuring a voltage per channel but is basically sharing the same measurement with both channels. The supported voltage range is 1-300V, but the problem is that usually, JSY is used to measure both the grid and router output. So the same voltage is outputted for both channels.

The JSY simply does not give the real dimmed Vrms.

PZEM v3 as the problem that the supported voltage range is 80+V. So it is not made to measure a dimmed voltage (also PZEM being powered by 230V, I really don't know what will happen to its electronics if it directly undergoes the dimmed voltage ;-)

So same, thing, the PZEM cannot give the dimmed Vrms.

The CEO of Shelly's once answered me that Shelly's won't be good to accurately measure a dimmed voltage with phase angle because of the fact that even if it could correctly measure the current with its tore and ADC, it is fed with the grid voltage and won't be able to output the Vrms of the dimmed voltage.

Since I am doing some LUT to compute the firing angle and delays based on the power % (0-100), I am also able to generate a LUT which is the Vrms factor to apply to the currently measured grid voltage to get the theoretical Vrms based on the current firing angle. From that, I compute the theoretical active power (and power factor) with the measured current from JSY.

Here are my observations, for a load of about 360W dimmed at 50% (90 degree angle).

So my findings are that it is more accurate to base our calculation from the Vrms computed from the firing angle and grid current measured by the JSY, and then compute the active (dimmed) power sent by applying the measured current by JSY. Same for power factor.

I do not have an electronic background, so I don't know how devices outputting power are doing it by putting in relation the measured current and voltage, and don't know how the Renergy IC works, and I don't know from where these differences come, but I conclude from my observations that it is more accurate to not used the power and power factor from the JSY or PZEM for a dimmed current, conclusion which seems logical to me and also would corroborate what I was told regarding Shelly devices.

Although they can be good at measuring a dimmed current (because this is just a mater of converting a tore voltage with an ADC), I suspect that it would require for them to be able to measure the Vrms of each channel (and output this metric) in order to correctly also output a power. The JSY only has one voltage input at the moment...

That is why, for my router implementation, I am relying on the firing angle and measured grid voltage to compute the Vrms, and from that, with the measured current, I am computing the other metrics (and a more correct THDi).

I suspect that this inaccuracy is also why some routers have a routing threshold use to decide when to start the routing.

As for the JSY, I wrote some ESP32 libs more optimised for JSY and PZEM which supports non-blocking and also improving the com speed with the JSY. With its default baud rate, each query takes about 120-140ms if I remember. I am automatically switching it to the fastest baud rate available in YaSolR and a query lasts about 45ms. I am querying in a loop without pause, so I get about a measurement each 50ms.

But I feel your pain also because we often see router reactiveness linked to the algorithm used, and we often forget the measuring part, which is far less reactive than the other hardware parts. So by the time we get a JSY measurement and react, a 3kWc production could have injected 2kW of power in the grid during 40ms before we see it.

Thanks by the way for you answer (https://github.com/fabianoriccardi/dimmable-light/issues/58#issuecomment-2000024933) ! I plan on implementing that and create new LUT to test a bit more when I'll work back on YaSolR. Right now I am working on https://beelance.carbou.me, for beekeepers. It starts to attract a lot of people already and I am currently working on a partnership with Onomondo for the com part... I will probably have some questions to your about the relationship and how I can translate them to generate LUT ;-)

I also plan to adapt the dimmable lib because I am also testing with a good ZCD circuit, which is putting the zero cross exactly in the middle of the pulse, but the pulse is 1.1ms width, which is long enough to create a "shift" in output power of about 1% since the delay calculated by the LUT is not applied at the right time. I would need to delay by 500us. I published some oscilloscope views of the Robodyn pulse vs this ZCD circuit here: https://forum-photovoltaique.fr/viewtopic.php?f=110&t=40617&start=440#p758654

florentbr commented 3 months ago

The instantaneous power is simply V I. So in theory, you get exactly the same power whether the voltage is taken before the dimmer or after. When the triac is not conducting, the current is 0 amps. So no matter what the voltage is, the instantaneous power is still zero. The active power is just an average of all the sampled V I.

Now in practice the JSY uses two current transformers, a clamp for the current and a ZMPT107 for the voltage. Theses produce some delays and their responses may be distorted when the triac is turning ON depending on their quality and frequency response. It's a bad idea to take the voltage after the dimmer since it will add the distortion of the cut voltage. This can be verified by checking the output of the current transformers with a scope when the dimmer is at 50%.

The measured power from the JSY differs from the theoretical power by about 30W

Is it with voltage plugged before or after the dimmer? That's an 8% error (30W/360W). It is indeed quite high.

the problem is that usually, JSY is used to measure both the grid and router output. So the same voltage is outputted for both channels

The JSY should be plugged on main voltage, not after the dimmer. If you need the RMS voltage of a phase cut resistive load, then simply use: Vrms_dimmer = ActivePower / Irms or Vrms_dimmer = Vrms_grid * PowerFactor or Vrms_dimmer = Vrms_grid * sqrt(power_duty)

This doesn't apply to inductive or capacitive loads like a led bulb.

Although they can be good at measuring a dimmed current (because this is just a mater of converting a tore voltage with an ADC), I suspect that it would require for them to be able to measure the Vrms of each channel (and output this metric) in order to correctly also output a power. The JSY only has one voltage input at the moment...

This can't be right, the voltage measured by the meter is not dimmed, so you can't have both accurate current and power at 100% and then just inaccurate power and accurate current at 50%. It's more likely that the tor is not converting accurately the dimmed current due to the steep edge when the triac is turning on. Any cheap energy meter using a shunt resistor should be more accurate compared to a cheap current clamp meter.

I am querying in a loop without pause, so I get about a measurement each 50ms.

No need to query that fast if the board is updating the RMS values every 500ms. The first step is to measure the time it takes for the meter to report a change when a resistive load is turned on. Then use this value to tune a PID.

But I feel your pain also because we often see router reactiveness linked to the algorithm used, and we often forget the measuring part, which is far less reactive than the other hardware parts. So by the time we get a JSY measurement and react, a 3kWc production could have injected 2kW of power in the grid during 40ms before we see it.

A 40ms delay would be great, but I doubt that the JSY is capable of such feat. The Renergy IC refresh rate of the RMS values is 3.495Hz (290ms) by default or 13.982Hz (14ms). It is driven by an MCU, so there's no way to know from the specs.

I have an oven which is regulating by turning ON and OFF repetitively over a short time period. This makes the routing quite challenging with a slow power meter.

So my findings are that it is more accurate to base our calculation from the Vrms computed from the firing angle and grid current measured by the JSY, and then compute the active (dimmed) power sent by applying the measured current by JSY. Same for power factor.

My system is first determining the dimmer max power once by turning it 0%/100% a few times and by reading the active power from the grid. It is used to compute and store the heating element resistance (R = ((Vrms grid) ^ 2) / ActivePower). During the routing, I measure the grid's power, compute the power error + PID, add/remove it from the duty and then lookup an interpolated phase delay.

My lookup table has 80 unit16 generated from the duty2phase function I posted earlier. The error is less then 0.001 with a perfect sine wave. The heating element max power is Router_PowerMax = (Grid_Vrms ^ 2) / R The reported routed power is Router_Power = duty * Router_PowerMax The reported routed voltage is Router_Vrms = Grid_Vrms * sqrt(duty) The reported routed current is Router_Irms = Router_Power / Router_Vrms The reported routed power factor is Router_PowerFactor = sqrt(duty)

I also plan to adapt the dimmable lib because I am also testing with a good ZCD circuit, which is putting the zero cross exactly in the middle of the pulse, but the pulse is 1.1ms width, which is long enough to create a "shift" in output power of about 1% since the delay calculated by the LUT is not applied at the right time.

I use the MCPWM module of the ESP32 to drive a MOC3023 and BTA24-600CWRG . It's much more reliable and accurate since it doesn't require interrupt. It however requires a ZC detector with a good squared signal, not like those shitty Robodyn.

I use the same kind of ZCD circuit you are mentioning but with modifications. I replaced the 1nF capacitor in front of the bridge rectifier by a 10nF to reduce the delay of the zero crossing. I also added a 10nF in parallel of the diode and reduced the 1k resistor to 330ohms to improve the triggering edge.

mathieucarbou commented 3 months ago

Thanks for the comprehensive answer :-)

The active power is just an average of all the sampled V * I.

That's what I was expecting but my observations are not in line with that...

It's a bad idea to take the voltage after the dimmer since it will add the distortion of the cut voltage.

I completely agree and this is not what I am doing also. Voltage is taken at router input (before the dimmer). The dimmer output is only connected to the load. I have the jSY clamp measuring the current before the dimmer and a PZEM clamp measuring the current after the dimmer (I am using 1 PZEM for each output). They both measure the same current, which is logical.

Is it with voltage plugged before or after the dimmer? That's an 8% error (30W/360W). It is indeed quite high.

Plugged before of course ;-) I agree the error is large. That's why I've changed course in the way I compute things.

The JSY should be plugged on main voltage, not after the dimmer.

Agree

simply use: Vrms_dimmer = ActivePower / Irms or Vrms_dimmer = Vrms_grid * PowerFactor or Vrms_dimmer = Vrms_grid * sqrt(power_duty)

Which is what I was doing before, until I discover that the reported Vrms was wrong, because this relation depends on the assumption that the power is accurately reported, which is not.

It's more likely that the tor is not converting accurately the dimmed current due to the steep edge when the triac is turning on

That's interested... Yes that is a possibility I did not even consider because I thought I could rely on the tore measurement. I could compare the reported current in amps with the reported amp I get from the curernt clamp of my portable oscilloscope. Do you know otherwise a better way to assert whether the reported current is incorrect ?

No need to query that fast if the board is updating the RMS values every 500ms. The first step is to measure the time it takes for the meter to report a change when a resistive load is turned on. Then use this value to tune a PID.

👍

A 40ms delay would be great, but I doubt that the JSY is capable of such feat. The Renergy IC refresh rate of the RMS values is 3.495Hz (290ms) by default or 13.982Hz (14ms). It is driven by an MCU, so there's no way to know from the specs.

So if I understand correctly, reading twice the JSY at 100ms interval would just give me the same result over time until 500ms elapsed ? That's big, half a second! On the other end it puts less pressure on the ESP32 :)

I have an oven which is regulating by turning ON and OFF repetitively over a short time period. This makes the routing quite challenging with a slow power meter.

That's a very interesting use case!

My system is first determining the dimmer max power once by turning it 0%/100% a few times and by reading the active power from the grid. It is used to compute and store the heating element resistance (R = ((Vrms grid) ^ 2) / ActivePower). During the routing, I measure the grid's power, compute the power error + PID, add/remove it from the duty and then lookup an interpolated phase delay.

I thought about having such calibration phase also but I fought hard trying to avoid it. I think it complexifies the setup (for user). He also has to think about recalibrating if required. And when we support 2 routing outputs, each output has to be calibrated individually.

But I understand the goals behind that...

My lookup table has 80 unit16 generated from the duty2phase function I posted earlier. The error is less then 0.001 with a perfect sine wave. The heating element max power is Router_PowerMax = (Grid_Vrms ^ 2) / R The reported routed power is Router_Power = duty * Router_PowerMax The reported routed voltage is Router_Vrms = Grid_Vrms * sqrt(duty) The reported routed current is Router_Irms = Router_Power / Router_Vrms The reported routed power factor is Router_PowerFactor = sqrt(duty)

So if I understand correctly, you are doing the same thing: you are calculating the routed power, routed Vrms, etc based on a LUT. The calculations from your LUT all lead to coherent values with what the JSY reports ?

Why are you not using the measured routed current by the JSY instead of calculating it with Router_Irms = Router_Power / Router_Vrms ?

I also plan to adapt the dimmable lib because I am also testing with a good ZCD circuit, which is putting the zero cross exactly in the middle of the pulse, but the pulse is 1.1ms width, which is long enough to create a "shift" in output power of about 1% since the delay calculated by the LUT is not applied at the right time.

I use the MCPWM module of the ESP32 to drive a MOC3023 and BTA24-600CWRG . It's much more reliable and accurate since it doesn't require interrupt. It however requires a ZC detector with a good squared signal, not like those shitty Robodyn.

I use the same kind of ZCD circuit you are mentioning but with modifications. I replaced the 1nF capacitor in front of the bridge rectifier by a 10nF to reduce the delay of the zero crossing. I also added a 10nF in parallel of the diode and reduced the 1k resistor to 330ohms to improve the triggering edge.

Thanks for the tip! I shared it to the author of this ZCD circuit so that he can improve his schema if he wants.

Thanks a lof for all these insights! It gives me a lot of idea how to rework and improve the current code!

florentbr commented 3 months ago

Do you know otherwise a better way to assert whether the reported current is incorrect ?

Any power meter using a shunt resistor and not a tor should be more accurate. A good RMS multimeter in series/amp mode will give you an accurate reading. I'd trust a cheap plug-in/socket watt-meter with CE certification more than a cheap PZEM or JSY.

I noticed that the JSY has two meters with two types of current transformer. Maybe the clamp is more accurate than the soldered tor ? If the issue is just with low power, try with more turns around the tor.

So if I understand correctly, reading twice the JSY at 100ms interval would just give me the same result over time until 500ms elapsed ? That's big, half a second! On the other end it puts less pressure on the ESP32 :)

That's just an assumption from reading the datasheet. That's why I asked you if you measured the response time by turning a load ON/OFF. It just requires a loop to turn the triac 100% and read the meter as fast as possible. The response time is the time it takes to read the maximum power from the moment the triac is turned ON.

I thought about having such calibration phase also but I fought hard trying to avoid it. I think it complexifies the setup (for user). He also has to think about recalibrating if required. And when we support 2 routing outputs, each output has to be calibrated individually.

It doesn't require any user intervention. The measuring/calibrating process is performed only once if the dimming is required. The calibration is cleared when the ESP32 starts. In the event I need to change the heating element, I just need to restart the ESP32 by switching a breaker.

Why are you not using the measured routed current by the JSY instead of calculating it with

I don't have a JSY nor PZEM. I only have one meter for the grid (CT 1:3000) and one for the photovoltaic (shunt resistor) and that's all. I don't measure the output from the triacs. I just calculate all the metrics based on the applied duty cycle. That's why I needed an accurate LUT and why I automatically measure the resistance of the heating element. The accuracy of the reported dimmed power mainly depends on how distorted the grid is compared to the LUT. I designed it that way since it was the simplest at the time and I didn't want to install another meter in a limited space.

From what I understand you are trying to correct the current/power reading from a dimmer with a reading from the grid with the same type of inaccurate meter. I think you are chasing your tail. Assuming it fixes the distorted reading created by the triacs, you'd still have the same issue with the other meter ahead since the same shape of current goes through both of them. What if the grid is distorted differently to begin with or if the triac itself is distorting the grid depending on the load? It's just a thought, I could be wrong.

mathieucarbou commented 3 months ago

Any power meter using a shunt resistor and not a tor should be more accurate. A good RMS multimeter in series/amp mode will give you an accurate reading.

Oh right and I have just one I could use (AstroAI 6000 True RMS)

I noticed that the JSY has two meters with two types of current transformer. Maybe the clamp is more accurate than the soldered tor ? If the issue is just with low power, try with more turns around the tor.

Tried the clamp, same thing. About the load, maybe, but routing also suppose being accurate at with lower power so...

That's just an assumption from reading the datasheet. That's why I asked you if you measured the response time by turning a load ON/OFF. It just requires a loop to turn the triac 100% and read the meter as fast as possible. The response time is the time it takes to read the maximum power from the moment the triac is turned ON.

I didn't do this test but I will rework the project to add this calibration phase. Calculating the resistance might also help for other features. What I noticed though is that the JSY readings are gradually. In the UI, I have a slider to automatically control de dimmer and when at 100%, it takes a few seconds, maybe around 3, for the power to stabilise to its maximum. This is when I am reading the JSY continuously. The UI is refreshed in another task each 1 sec. The lights are at their full power immediately though. So I fear that if I calibrate the JSY readings with a delay calculated based on when the maximum power stabilises, it will be a delay in terms of seconds and not milliseconds. But I will do some more testing once I am back on this project.

It doesn't require any user intervention. The measuring/calibrating process is performed only once if the dimming is required.

I prefer to ask the user to do this calibration phase each tine he changes the resistance and save the value because there could be external factors preventing this to be done (i.e. water heater reaching its max value).

I don't have a JSY nor PZEM. I only have one meter for the grid (CT 1:3000) and one for the photovoltaic (shunt resistor) and that's all. I don't measure the output from the triacs. I just calculate all the metrics based on the applied duty cycle. That's why I needed an accurate LUT and why I automatically measure the resistance of the heating element. The accuracy of the reported dimmed power mainly depends on how distorted the grid is compared to the LUT. I designed it that way since it was the simplest at the time and I didn't want to install another meter in a limited space.

Thanks! This is a very good design indeed. Less hardware. I started to use LUT when I saw that the Vrms I was computing from the measured active power and current of the JSY was not in line with the measurements I got from the multimeter and oscilloscope.

From what I understand you are trying to correct the current/power reading from a dimmer with a reading from the grid with the same type of inaccurate meter. I think you are chasing your tail. Assuming it fixes the distorted reading created by the triacs, you'd still have the same issue with the other meter ahead since the same shape of current goes through both of them. What if the grid is distorted differently to begin with or if the triac itself is distorting the grid depending on the load? It's just a thought, I could be wrong.

I am not trying to correct the current: I am only considering the current read from the JSY / PZEM and from that I calculate the active power and others thanks to the Vrms (calculated based on a LUT and the grid current). So my inputs are: %power (gives phase angle), grid voltage, measured current. From that I derive the PF, power, apparent power, THDi.

But like I said, at 50%, 90 degree angle, if I calculate Vrms == JSY measured active power / JSY measured current, then this value is completely out of line compared to the Vrms I get from a multimeter and from calculations based on the LUT. So I need first to do some more testing and see what is causing that.... And I do not think of a tore measurement issue because the same thing is reported by the PZEM also.

Thanks a lot for your help and insights 👍

florentbr commented 3 months ago

Thanks for the feedback. Looks like the JSY is not that fast after all. I'm tempted to order one and try to connect an ESP32 directly to the Renergy metering IC but the accuracy is bugging me.

mathieucarbou commented 3 months ago

I'm tempted to order one and try to connect an ESP32 directly to the Renergy metering IC but the accuracy is bugging me. That's not a big loss and could be reused ;-) There is the PZEM v3 also ?

If that can help you, I am profiling the readings (data binning) and here are some times:

[247799][D][MycilaTaskManager.cpp:377] log(): [TASK-MAN] | output1PZEM.read()             |     0 < 2^1 ms |     0 < 2^2 ms |     1 < 2^3 ms |     0 < 2^4 ms |     0 < 2^5 ms |   354 < 2^6 ms |  1544 < 2^7 ms |     0 >= 2^7 ms | count: 1899
[247821][D][MycilaTaskManager.cpp:377] log(): [TASK-MAN] | output2PZEM.read()             |     1 < 2^1 ms |     0 < 2^2 ms |     0 < 2^3 ms |     0 < 2^4 ms |     0 < 2^5 ms |   969 < 2^6 ms |   929 < 2^7 ms |     0 >= 2^7 ms | count: 1899
[247843][D][MycilaTaskManager.cpp:377] log(): [TASK-MAN] | jsy.read()                     |     0 < 2^1 ms |     0 < 2^2 ms |     1 < 2^3 ms |     0 < 2^4 ms |     0 < 2^5 ms |  5255 < 2^6 ms |     3 < 2^7 ms |     0 >= 2^7 ms | count: 5259

You can see how slow the ramp up time is (about 1-2 sec)

https://github.com/mathieucarbou/YaSolR-OSS/assets/61346/73350bda-7344-48a3-8da6-b6ddf3ea85e3

I did a second try by adding a 100ms delay between readings. So each 100ms, JSY and PZEM will be read. And if I do that it takes a whole 3 seconds to get the maximum values.

These are not accurate tests at all but enough to feel the reactiveness.

What I can measure for the JSY is:

florentbr commented 3 months ago

That's not a big loss and could be reused ;-) There is the PZEM v3 also ?

It's a loss for me if the CT / tor are of poor quality and not capable to measure the current/power/energy accurately. It's not to measure the dimmer but the grid. The DDS238 I'm using is quite accurate. I don't want to increase the speed at the cost of accuracy since I aggregate these values in a dashboard with multiple stats.

From what you posted, the MCU on the board is likely performing a moving average over a second or 2. The JSY behaves more or less like a DDS238 meter for the same price, but without casing and power supply.

mathieucarbou commented 2 months ago

@florentbr : FYI I got some time today to run some perf test at different bauds with the JSY, with a resistive load of about 650W connected to a random SSR to turn on/off faster.

https://oss.carbou.me/MycilaJSY/#performance-tests

So like you suspected, there must be a sort of averaging or filtering because the time it takes to go from 0 to the nominal load, and from the nominal load to 0 is a little more than 1 second.

But the detection time (time to detect the first watts) is about 300ms.

The fastest way to get the data is to read at 38400 bauds to get them in 42 ms on average.

florentbr commented 2 months ago

@mathieucarbou

But the detection time (time to detect the first watts) is about 300ms.

That's pretty much the refresh rate from the specs of the Renergy IC on the JSY board. At 38400 bauds, you are likely pulling the exact same cached value every 42ms until it is updated as a moving average every 300ms on a 1 second window.

What matter is not so much how fast you can read the JSY, but how responsive and stable the feedback loop driving the triacs is. I had a look at the source code but I couldn't figure-out how the JSY reading is handled to adjust the triacs.

mathieucarbou commented 2 months ago

At 38400 bauds, you are likely pulling the exact same cached value every 42ms until it is updated as a moving average every 300ms on a 1 second window.

Exactly! I introduced a callback mechanism this morning to show that better:

https://oss.carbou.me/MycilaJSY/#callbacks

We can clearly see the readings versus when the values are changing.

I had a look at the source code but I couldn't figure-out how the JSY reading is handled to adjust the triacs.

Yes, the automatic dimming feature is still to be implemented. That's the last remaining piece, before improving perf with all the hints you gave me :-) I had to pause the project to work on another project (remotely connected scale for beehives - https://beelance.carbou.me).

I am in the process of updating the JSY and PZEM code to support callbacks, to allow reading the JSY and PZEM in a dedicated task, in a loop, at higher possible bauds, and then send an event as soon as it sees a change. This will allow a more reactive adjustment of the routing.

I will handle the routing code in another dedicated task too.

florentbr commented 1 month ago

@mathieucarbou

Were you using incandescent lamps for your measures? Note that they are non-Ohmic. The resistance of the tungsten filament is not linear and varies significantly with the applied voltage and temperature. A 50% duty cycle won't produce 50% power. It would explain the discrepancy with your measures.

Heating elements on the other hand are made with nickel chrome alloys with a lower coefficient of resistance and lower temperature range. So the resistance should be stable and the variation negligible.

https://www.electronics-notes.com/articles/basic_concepts/resistance/why-is-filament-incandescent-lamp-nonohmic.php https://midimagic.sgc-hosting.com/nonohmic.htm

mathieucarbou commented 1 month ago

@mathieucarbou

Were you using incandescent lamps for your measures? Note that they are non-Ohmic. The resistance of the tungsten filament is not linear and varies significantly with the applied voltage and temperature. A 50% duty cycle won't produce 50% power. It would explain the discrepancy with your measures.

Heating elements on the other hand are made with nickel chrome alloys with a lower coefficient of resistance and lower temperature range. So the resistance should be stable and the variation negligible.

https://www.electronics-notes.com/articles/basic_concepts/resistance/why-is-filament-incandescent-lamp-nonohmic.php https://midimagic.sgc-hosting.com/nonohmic.htm

That's funny because I am currently reworking the code and redoing some measurements and yes - I was using incandescent bulbs with the dimmable light library, which is doing a lot of modifications on the timer and delay to account for start time, end time, triac gate close time, etc.

I thought about that this week also while reworking the code that what I was using to compare the measurements was not right. And funny enough I went today to a recycle place to grab some used résistances for my testing 😅

The dimmable light lib is good to get a beautiful transition for lights but I think it is not really suitable for resistance. I have in my plans to use the esp pwm feature like you do.

I've grabbed your code for the lut and it works very well! Thanks a lot for all your tips - they really help bringing this big project to life 👍

florentbr commented 1 month ago

I noticed a few weeks ago that the water valve of my dish washer was buzzing. I'm pretty sure it was due to the router. So I started to look into the skip cycle mode and some kind of mixed mode with the phase angle to reduce the harmonics. I have the math and simulation and was looking into light bulbs to determine the flickering threshold when I noticed in some doc that the IV curve was not straight.

with the dimmable light library, which is doing a lot of modifications on the timer and delay to account for start time, end time, triac gate close time, etc.

I wrote a low level dimmer with group timer last year. It should be more reactive than the one you are using and generic enough for your usage: triac_timer.zip

I have in my plans to use the esp pwm feature like you do.

Be aware that the MCPWM peripheral (Motor Control PWM) is only available with the ESP32 and ESP32-S3 and the implementation is kind of tricky, but it's the only way to output synchronized pulses without interrupt.

I also experimented with the LEDC PWM peripheral but it's not reliable since the assigned duty is updated only at the end of the cycle. It will not update if the sync resetting the timer occurs just before. One way to overcome this issue would be to set a frequency slightly under 100Hz but it could still glitch if the ZC interrupt is delayed.

mathieucarbou commented 1 month ago

Thanks! I'll look into that. By the way, on another note, I've been talking to a guy in UK who is designing some circuits on PCBWay. He makes some standalone ZCD modules that could be put into a DIN Rail (so coupled with a random SSR and an ESP these are good building bricks for a simple router). He will create a new one based on the recent ZCD chips like the BM1Z102FJ (https://www.rohm.com/products/power-management/ac-voltage-zero-cross-detection-ics/bm1z102fj-product#productDetail), which is able to have a pulse (eventually with a shift applied to account for processing time) that is matching the whole semi-period but also the voltage. image

mathieucarbou commented 1 month ago

@florentbr : I found a broken iron at this recycle place. I tested its resistance to at 24 ohms with a multimeter and both JSY and PZEM give me 23.9 Ω when the dimmer is set at 100% (4095), and both also now give me the right values and also the same resistance when I dim to lower duty cycles! I am super happy lol it will facilitate a lot the testing! It gives me 2000W of power to play with (hopefully I never let the current flowing for a long time).

I will work on this auto-calibration phase like you did, but I will do it only when user request it because if they decide to install a PZEM on the output to have a device that is measuring but also storing energy data, then the calibration won't be necessary.

Thanks a lot of your kind help!

florentbr commented 1 month ago

He will create a new one based on the recent ZCD chips like the BM1Z102F

I find the BM1Z102FJ kind of overkill. A ZC with discrete/common components is precise enough for a fraction of the cost. The hard part is not so much about the precision, it's about filtering the noise and harmonics. A passive low pass filter will add a delay which can vary depending on the precision of the capacitors. It's only an issue if you don't have an oscilloscope to measure this delay.

Note that most of the metering IC have a zero crossing output. There's one on your JSY but it's likely not activated (Renergy IC). So If I were to use a dedicated IC I would use a metering IC to get the ZC and to measure the energy/power at the same time.

I have another ZC design similar to the one you already have but with half the pulse width (200us ahead, 400us width) and still symmetric with just one more transistor. It should be possible to automatically find the zero crossing by measuring the rising and the falling of the pulse. The simulation is promising, I haven't tested it yet. I was also thinking about adjusting the zero crossing by targeting the exact 50% power. It should work in theory unless the grid is too distorted and no longer symmetric.

both also now give me the right values and also the same resistance when I dim to lower duty cycles!

Great ! So the JSYs and PZEMs are capable after all.

mathieucarbou commented 1 month ago

I find the BM1Z102FJ kind of overkill.

I agree for that usage. But I was planning on a further iteration of the router to also add burst mode and also maybe a mix of semi-period control and I was thinking that it could help to know when the voltage curve is positive or not. He told me the cost and the addition is not so much compared to the rest: for exemple the DIN rail enclosure plus the addition of the AC isolator to isolate the module from the AC line. Anyway... This is not for now - just some ideas at the moment.

It should be possible to automatically find the zero crossing by measuring the rising and the falling of the pulse.

I did exactly that today. I've updated the dimmer code I am currently using to set the interrupt on CHANGE and I am measuring the last 5 pulse width in a cyclic buffer, and I keep the maximum value seen and latest one. The Robodyn ZCD pulse is horrible for exemple, the reported width can go from 250us to more than 450us. I will use this to further adapt the library because the pulse width of the ZCD I have is about 1200us, which is quite big, so I will compute the middle.

florentbr commented 1 month ago

and I was thinking that it could help to know when the voltage curve is positive or not

You don't really need to know if the half cycle is positive or negative. All you need is a boolean or counter to switch between odd and even half cycles to keep it balanced.

I did exactly that today. I've updated the dimmer code I am currently using to set the interrupt on CHANGE and I am measuring the last 5 pulse width in a cyclic buffer, and I keep the maximum value seen and latest one.

Have a look at the RMT peripheral. It can record pulses without CPU interference or interrupt. I used it to implement a driver for the DS18B20 sensor to avoid bit banging.

The Robodyn ZCD pulse is horrible for exemple, the reported width can go from 250us to more than 450us

I would not recommend the Robodyn for this type of project since it also has an undersized heat-sink. Not to mention that it consumes almost a full Watt just to detect the ZC.

mathieucarbou commented 1 month ago

Thanks! Will do. You're right avout the boolean flag...

mathieucarbou commented 1 month ago

Hello @florentbr,

Thank you for the hint about the RTM peripheral.... I didn't know about it. I've changed to an implementation for DS18 which is also even smaller in code size.

Now I am looking at implementing a PID control, but I am wondering about its value in the case of this project.

I am reading the JSY continuously, so every ~300 ms, the JSY async task is calling a callback to notify about data changes. If the user wants to go with MQTT, then a cb is called to notify about incoming new value.

The routing adjustment code is then called right away once a new grid power value is received, and I need to set the new dimmer levels.

Considering I know the nominal loads thanks to the resistance, and the currently routed power, I can already guess the "best" new possible duty to apply to the dimmers. But there will always be some inconsistencies with reality because of:

So I was wondering how do you use your PID ? Is it only to stabilise once the adjustment is done ?

I was think of doing something like this:

  1. new power received (jsy or mqtt)
  2. if grid power has changed by more than a minimal amount (TBD - maybe 4-6 watts ?) -> recompute the dimmer levels
  3. if grid power did not change and is not close to 0, apply a correction (which one ? don't know yet)

In theory, if the resistance value is about correct, the correction to apply should be rather small, so I fear that the use of a PID could overshoot or create oscillations more than needed.

edit

Or... You are instead using the PID controller for the target temperature ?

benoit-cty commented 1 month ago

Hello, As I understand it, the goal of a PID is to avoid overshoot : to reduce the power of the resistance before reaching the 0 injection.

Like in car where the acceleration is reduced before reaching speed limit, to avoid overshooting.

But yes, incorrect tuning of PID values could lead to oscillations.

I don't know if PID is the solution in our case, maybe we also need to apply some filter on the input to handle the lack of precision of the measure ?

Edit : an online simulator https://grauonline.de/alexwww/ardumower/pid/pid.html

mathieucarbou commented 1 month ago

Hello, As I understand it, the goal of a PID is to avoid overshoot : to reduce the power of the resistance before reaching the 0 injection.

Like in car where the acceleration is reduced before reaching speed limit, to avoid overshooting.

But yes, incorrect tuning of PID values could lead to oscillations.

I don't know if PID is the solution in our case, maybe we also need to apply some filter on the input to handle the lack of precision of the measure ?

Edit : an online simulator https://grauonline.de/alexwww/ardumower/pid/pid.html

Hello,

The PID algorithm itself will overshoot depending on the Kp value: it's just that some libraries are providing min/max output limiters, hopefully :-) But that's not really a big concern: I was much more concerned about how a PID reacts to errors, and what could be called errors in this case.

Note: there is a new version of the simulator but without the ability to adapt the JS code: https://tech-uofm.info/pid/pid.html

An example of what I suspect will happen (I need to verify)

T0:

T+300 ms

T+600ms

T+900ms

T+1200ms

T+1500ms

T+1800ms

T+2100ms

etc.

So:

And I am not sure it would be better to react after 1 sec, to let time for the JSY to do its moving average considering the new dimmer value. Because during this whole 1 sec I will not react on 2 JSY readings which can contain some adjustment because there has been a spike in home consumption or solar production.

I think all the solar routers out there have the same issue due to the JSY doing a moving average over 1 sec. it's not possible to precisely react I think.

I don't know if there is a way to make that better.... Because even if I could track the last 3 grid power and ajustement I did, any change reported by JSY could also be because of a change in Ps and Ph.

edit

One solution to fix the above could be to decrease the reactivity and react on a JSY power only once every second and let 3 readings pass before reacting again. But i've simulated that and found that the spikes over 1 sec are merely equal in terms of cumulated energy to reacting on each measurement...

florentbr commented 1 month ago

@mathieucarbou

Considering I know the nominal loads thanks to the resistance, and the currently routed power, I can already guess the "best" new possible duty to apply to the dimmers. But there will always be some inconsistencies with reality because of:

The precision of the reading/resistance/voltage should have no effect on the result since the feedback loop is expected to converge to the desired wattage.

So I was wondering how do you use your PID ? Is it only to stabilise once the adjustment is done ?

I simply use the PID coefficients without the timing and integral.

When the grid meter reports -800 Watts (injection), I consider the error to be 800 watts. If the previous error was 0, then I will add to the triac:

correction = error * kp + (error - error_previous) * kd
correction = 800 * 0.4 + (800 - 0) * 0.2
correction = 480 watts

If the previous error was 800 watts:

correction = error * kp + (error - error_previous) * kd
correction = 800 * 0.4 + (800 - 800) * 0.2
correction = 320 watts

The correction is then added to the duty:

duty12bits += correction TRIAC_MAX / (V_grid V_grid / R_load)

I was think of doing something like this: new power received (jsy or mqtt) if grid power has changed by more than a minimal amount (TBD - maybe 4-6 watts ?) -> recompute the dimmer levels if grid power did not change and is not close to 0, apply a correction (which one ? don't know yet)

I would not bother with the minimal amount. Just compute and apply the correction when the new power is received.

I don't know if there is a way to make that better....

PID There's decades of research on the subject. https://www.google.com/search?q=pid+research+paper

Or a neural network if you up to the challenge. There's a lib for the ESP32: https://docs.espressif.com/projects/esp-dl/en/latest/esp32s3/introduction.html

Some tips: Some meters behave weirdly around zero. Do your testing with a targeted wattage at +100 or -100 watts. Make sure your JSY reports the correct power sign when crossing from positive to negative and from negative to positive power. Cached values will mess up you feedback loop, ignore the modbus frames with the same CRC.

mathieucarbou commented 1 month ago

@florentbr the problem is that the JSY is doing a moving average so I fear that applying a PID correction and computing an error based on a value which is averaged will make things worse. I know that at the end it will reach the setpoint, but the problem is in what time, and during this effort, the solar production can change and the home consumption can change. What is called error in a reading may not be an error in reality but an artifact due to the jsy moving average. For example as soon as we turn on the dimmer to 100% the current and voltage are flowinf at 100% but the jsy takes about 1sec to ramp up and read the full value, and outputs less each 330ms. So of I were to compute a PID on a jsy reading, I will slowdown even more the time taken to reach the 0. But I will try to simulate that over real data.

florentbr commented 1 month ago

What's the alternative? One way or another you'll have to rely on those reading artefacts to divert the power. You'll face the exact same issue by waiting 300ms, a second or a minute since the load or production can change at any time just before, just after or in the middle of a ramping average. I use a PID to solve this problem, not because it looks fancy. A PID can be configured any way you want toward responsiveness or stability.

Here's a simulation with a 2.3 kW production:

solar: 2300  load:    0  grid:-2300  meter_avg:-2300
solar: 2300  load: 1380  grid: -920  meter_avg:-1840
solar: 2300  load: 2024  grid: -276  meter_avg:-1165
solar: 2300  load: 2355  grid:   55  meter_avg: -380
solar: 2300  load: 2350  grid:   50  meter_avg:  -56
solar: 2300  load: 2308  grid:    8  meter_avg:   37
solar: 2300  load: 2274  grid:  -25  meter_avg:   10
solar: 2300  load: 2275  grid:  -24  meter_avg:  -14
solar: 2300  load: 2285  grid:  -14  meter_avg:  -21
solar: 2300  load: 2295  grid:   -4  meter_avg:  -14
solar: 2300  load: 2300  grid:    0  meter_avg:   -5
solar: 2300  load: 2300  grid:    0  meter_avg:    0
solar: 2300  load: 2300  grid:    0  meter_avg:    0
solar: 2300  load: 2299  grid:    0  meter_avg:    0

The PID use the meter which is an average of the 3 previous grid values. Most of the power is diverted in less than a second and I didn't even try to tune the coefs (kp=0.4 kd=0.2 ki=0).

mathieucarbou commented 1 month ago

I need to visualise that on real data. I well understand the concept of PID but found it hard to see how it could work in such use case.

I did some simulations with real data (SIM 4 tabs):

https://docs.google.com/spreadsheets/d/1yhAtoMrZABxP1YO5Jzy9OYDmGM_ThWpgdNcqQGvkFs8/edit?gid=1361092379#gid=1361092379

Looking at the table, I highlighted the placed where the cumulative errors would become bigger. We can see that it happens when the current error and previous error are nearly the same (because the home consumption and solar production changed). So the effect of Kd is canceled and Kp might not be enough to correct.

The graph updates itself, with the total energy, when we try different values of Kp, Ki and Kd.

So trying to tune all that, Kd and Ki at 0, I found that Kp == 0.66 was the optimal value - which is also like applying a correction after each 2 JSY read out of 3.

From that, I've looked at the highlighted rows to find where the cumulated errors were higher and tweaked kd in order to even reduce the total energy exported and imported. I found that Kd == 0.8 was the best for this simulation, and helped reduced the amount of cumulated errors.

To even reduce the quantity of cumulated errors, I've tried to bump a little Ki, but not by much because it quickly worsens I found that Ki == 0.005 was the best value.

With this settings, I get a minimal import / export and only 5-6 cases where the cumulated error remains above 500W or below -500W, and only for a maximum time of 1 sec.

image

So definitely it is worth using a PID -like algorithm !

florentbr commented 1 month ago

Thanks a lot for the simulation and detailed analysis !

Histograms from your data (grid power during routing) :

image image https://colab.research.google.com/drive/1_tQYi2wQbjrJlBgzZG_aYqW1umFzaMmQ?authuser=0#scrollTo=anoFrSjOl7s_

The simulation is unexpectedly stable without PID. My DDS238 is jumping all over the place in a real setup without PID correction. It could be because there's no big deference/jump between consecutive readings in your dataset.

mathieucarbou commented 1 month ago

I noticed that too.

The source of the data comes from Home Assistant. I have extracted all the recorded state changes, roughly put them in a Google Sheet and compressed the time: state changes in HA could happen at any time. So in order to stress a bit more the algorithm by putting some state change near together, I've compressed them in a 16min window where each point is for 330 ms (when in reality they were spread across the day).

So the reality will probably be even better than my simulation because when I look at the grid power, it usually stays put for 1-2 sec, and the jSY is "helping", doing a moving average.

I might have a situation like you in the case where a user would chose to use MQTT to get the power and voltage, and don't use a JSY. In that case, MQTT updates are coming at a different rate, depending on how quickly the power changes. I can get 1 update per second like I can get 1 update every 10 second. So in this case I will have more bumps.

history.csv image

mathieucarbou commented 1 month ago

Hello @florentbr,

I've been reading your dimmer code and I was impressed how skilled you are! I wish I had your level of expertise!

I am also curious to see how it behaves with lights: the library I use made quite some efforts to avoid noise and get to a smooth transition because it is focusing on lights. But as soon as I try to simplify this code, I run into some noise issues where the pulse could be off or on for a semi period and the lights are flickering a little. Of course, on a resistance, it matters less.

I have other things to do first before improving the dimmer library I use, but I was curious to understand why you directly use the registers instead of using the provided Arduino / ESP-IDF API like other libs are usually doing ? Is there an advantage other than reducing the call stack ?

Thanks!

update

Oh! I think it might be because of that ?

florentbr commented 1 month ago

I was curious to understand why you directly use the registers instead of using the provided Arduino / ESP-IDF API like other libs are usually doing ?

I had a flickering issue and I suspected the timing of the ISR. Even an expert is only half right when it comes to concurrency, CPU caching and compiler optimisation all mixed together. Since it's a critical part of my project, I just implemented a solution from scratch at the lowest level and as optimized as possible. I wanted to be done with it. I didn't want to spend hours trying to figure if the issues were due to the implementation of someone else. Turned out to be quite easy since the lowest level is already present and used in the IDF code base (Arduino > IDF > registry > SOC). Not to mention that the registry is well documented (https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf).

I am also curious to see how it behaves with lights

I use the IDF framework, but the lowest level is accessible from the Arduino framework since it's basically just a header with no implementation. It shouldn't be too hard to port it to Arduino, I think it's just a mater of replacing the initialisation methods with the ones provided by Arduino. I saw an Arduino/RGB light library using the lowest level to reduce the pin latency, so it's definitely possible. The interrupts should work as is without any modifications. Feel free to modify it any way you want.

Is there an advantage other than reducing the call stack ?

All the instructions executed by the interrupts are stored in RAM and not in flash. Lower latency. The lower API doesn't change at every major IDF/Arduino release !

mathieucarbou commented 1 month ago

Thanks a lot for all these explanations and help!

I've asked this question also after reading this comment: https://github.com/espressif/esp-idf/issues/2408#issuecomment-421869837. And since I am using NVS (but I am caching the key-values for reads) and I am using LittleFS a little to serve some config file, I have some I/O operations running which could happen at the same time.

mathieucarbou commented 1 month ago

Until I rewrite the dimmer lib, I was able to modify Dimmable Light to account for the pulse width and shift the timers.

Below: Duty 10, 2047 (50%) and 4096.

duty_10 duty_2047 duty_4090

florentbr commented 1 month ago

Nice, is it a 14bits oscilloscope? I connect my 8 bits scope to two diodes back to back in series with a resistor to clearly see the exact zero crossing. How do you acquire the voltage? transformer? 100x probe? differential probe?

Note that the AC mode of the oscilloscope is a high pass filter to remove any DC offset. There's no reason to use it here. It adds a phase shift and attenuates the amplitude at lower frequencies. Make sure to use the DC mode when calibrating/checking the delay.

One cool feature I like about the OWON is the Pass/Fail mode. I used it to check the stability of the interrupts. First set-up two outputs at 50%, no load connected, trigger on ZC. In the Pass/Fail menu add the first output. Then play with the duty of the second output. The oscilloscope automatically count the number of time the first output is outside of its position due to a delayed interrupt.

mathieucarbou commented 1 month ago

Nice, is it a 14bits oscilloscope?

I wish it were 😆 But this is the OWON VDS6104 with a 100X 100MHz probe. The extra money to go for the VDS6104A 12 / 14 bits was not justified by my usage since I rarely do electronic stuff and at the time I bought it I didn't find a VDS6104A cheaper or used. So I used the extra money for the current clamp.

I went with this after a lot of hesitation with the VDS1022I, which is 400V (PK - PK) and easier to use, but also because I saw your unofficial firmware for the VDS1022 that I really liked. This is nice that the soft is in Java (my goto language for 20 years now) and that it can be easily decompiled and improved. So on my project idea list I added an item to see if I can port some of your improvements to this one.

But the ability to have 4 probes and a LAN port won. I am using it completely in standalone / isolated mode, powered by a battery and attached to a small GL.iNet device (although the official WiFi dongle would be better but I had this one at home). So I have the software on my computer connected to the AP and accessing the device remotely.

PXL_20240614_193732697 NIGHT~2

I don't have the Pass/fail mode on the VDS6104. This is something I only noticed when comparing the software features after. And overall, I must say I am not very pleased with the software for the VDS6104: it is less polished with a few features than the VDS1022. That's my only regret that they didn't push it to the level of the VDS1022.

But I think these are things that could be added / modified like you did so I am not terribly unsatisfied. Another "hack" project to do lol!

mathieucarbou commented 2 weeks ago

@florentbr : I have implemented the PID loop in YaSolR and tested that, also implemented a dashboard + websocket output to be able to see the data and tune the PID more easily.

I've made a Youtube video of PID Tuning in YaSolR, accessible in he PID section of the manual https://yasolr.carbou.me/manual#dashboard--pid-controller

finally, I've chose by default a proportional on measurement PID, but the user is able to tune any parameter in real-time.

I need to finish a couple of things and I am soon ready to release a first beta.

The dimmer algo is still dimmable light, tweaked a little , I think I will definitely use parts of your code with some modifications because I find the library quite brittle - sometimes I have some undetected pulses - I wonder if the interrupts (or some delays) are causing that.

Anyway :-) I am quite happy of what I've achieved so far, and this is also partly thanks to your help!

mathieucarbou commented 1 week ago

Something Fun...

I've put YaSolR project in pause a few days to work on a Diverter / Router based on Shelly devices, as part of the Shelly IoT Innovation Challenge.

Shelly released a new dimmer, the Dimemr Gen 3, which works in current sourcing mode and allows to dim an output DC voltage from 0/1 - 10V DC. Which is the range commonly used for industrial stuff like the LSA voltage regulator!

So I've made a Shelly router based on this dimmer and the LSA, wrote a script to control the dimmer through the EM with the same PID algorithm used in YaSolr.

This works pretty well! And even better than the F1ATB ;-)

Article, script and demo videos: https://yasolr.carbou.me/blog/2024-07-01_shelly_solar_diverter

shelly_solar_diverter_poc2

florentbr commented 1 week ago

@mathieucarbou

I have implemented the PID loop in YaSolR and tested that, also implemented a dashboard + websocket output to be able to see the data and tune the PID more easily.

Keep in mind that the PID is there for the meter response time and not a delayed output response . You are using the same meter for control, so there's a chance that what you are seeing on your graphs is not really what a Linky is seeing (aggregation occurs at a different time). If I were to optimize the PID, I would plot/check the current/power/energy with a least a second meter.

So I've made a Shelly router based on this dimmer and the LSA, wrote a script to control the dimmer through the EM with the same PID algorithm used in YaSolr.

That's impressive, they managed to squeeze a tiny Javascript VM in the implementation for a flash size under 2Mb. https://github.com/user-attachments/files/16019711/diff_esp32c3.txt

I'm less impressed by the over-whole price. All these accessories quickly add-up and the dimmer is not even rated for 16A. So using it to measure the output power or to bypass the triac module or to force the output directly is likely a fire hazard. Well, it should be all right if it's installed in a metallic box and used in parallel of the LSA-H3P50YB just like a hybrid relay (fist output in series with the LSA to monitor the power and second output in parallel to bypass the LSA).

Funny, the Shelly description claims a precise power measurement but indicate +- 10% in the specs, far from precise by any western standard.

mathieucarbou commented 1 week ago

Keep in mind that the PID is there for the meter response time and not a delayed output response .

I don't understand what you mean by delayed ? In relation to the moving average ? Or the read delay ?

You are using the same meter for control

No: the input of the PID is the measurements (JSY or MQTT or else) The output of the PID (a power) is used to calculate the duty, based on the metrics of the router output (voltage, resistance value, etc) - this is the control. Exactly like your algorithm, but with little more complexity since I apply some limitations, excess sharing, etc.

Or maybe I didn't understand what you meant ?

If I were to optimize the PID, I would plot/check the current/power/energy with a least a second meter.

What do you mean ? To have a sort of second view which is on another moving average than the JSY ? But this view would still be based on a moving average, eventually larger than the 1 sec of the JSY, so it could even be worse ?

Right now, te PID Tune "tools" allows to stream each metric change received from the JSY, so we have at least one each 330 ms on average.

So using it to measure the output power or to bypass the triac module or to force the output directly is likely a fire hazard.

The dimmer is only used to send a dimmed voltage (1-8V DC) to the LSA. I do not use the dimmer output, neither its measurement capability. In this PoC, I am using the A clamp of the EM for the grid and its B clamp for the voltage regulator output. The contactor (25A) through which goes the full power of the load, is controlled by the output of the EM.

mathieucarbou commented 1 week ago

That's impressive, they managed to squeeze a tiny Javascript VM in the implementation for a flash size under 2Mb. https://github.com/user-attachments/files/16019711/diff_esp32c3.txt

How did you manage to get their source code and build it ? The isp-idf repo on their github does not contain any shelly source code... ;-)

florentbr commented 1 week ago

I don't understand what you mean by delayed ? In relation to the moving average ? Or the read delay ?

Yes the delay created by the meter (moving average). Correcting the grid power has a negligible delay in comparison since it's the time it takes to fire the triac + period. On PID systems like temperature or trajectory correction, it's the opposite, the measure is real-time but the physical effect of a corrected output is delayed.

No: the input of the PID is the measurements (JSY or MQTT or else)

Why do you provide all those graph in the advanced PID web interface? Is it not to evaluate the performance/stability of the PID in regard of the grid real power/consumption? Those graph also rely on the JSY, the same meter used to compute a correction. You are therefore using the same meter for control (qualification, verification of exactitude...)

What do you mean ? To have a sort of second view

I'm not saying that they are useless or that you should have a second view. I just think that those graphs should be used with caution as they might not be an exact representation of the grid power.

which is on another moving average than the JSY ? But this view would still be based on a moving average, eventually larger than the 1 sec of the JSY, so it could even be worse ?

Exactly, a second meter which you would act as a Linky, not permanently, but at least once to see the impact/correlation. The difference might be negligible or not. If significant, that would make any precise tuning by relying on those graphs useless.

The dimmer is only used to send a dimmed voltage (1-8V DC) to the LSA. I do not use the dimmer output, neither its measurement capability. In this PoC, I am using the A clamp of the EM for the grid and its B clamp for the voltage regulator output. The contactor (25A) through which goes the full power of the load, is controlled by the output of the EM.

I got that. I was just exploring the features offered by the module+shield to justify the 40€ and get as much value as possible from the device. There's no dimmer output, but there's two relays. Adding a contactor requires another power supply.

How did you manage to get their source code and build it ? The isp-idf repo on their github does not contain any shelly source code... ;-)

I don't have their sources, though I'd love to have a look. One of their dev posted an issue on github recently, complaining about the increasing size of the IDF framework.

mathieucarbou commented 1 week ago

Ok I understand more now! Yes I agree that theoretically to be 100% correct we should check with another source.

I just think that those graphs should be used with caution as they might not be an exact representation of the grid power.

Of course! They are relative to the input. The goal of these graph is to check for the effect of Kp / KI / Kd. If the user switches for exemple to proportional on error and set a too high Ki, he will directly see the graph jumping. These graph are not meant to tell the user if he reached a descent grid output (reality). There are not at all for that, but only to see the effect of the different settings. These graph are here to help him tweak his terms.

But I agree with you that once done, a counter verification can be done, on the lInky itself for example because it does not make sense to complexity the router for the sake of a feature that will be used by only a few people.

The current settings have been tested with the JSY which causes a PID calculation about 3 times per second, and also with the Shelly PoC, which is 1 measurement per second. And they work pretty well. And in my case, since I have already a Shelly EM (small one) installed, I am verifying the effect with this Shelly EM and Home Assistant, like in the video.

florentbr commented 1 week ago

@mathieucarbou

There's no dimmer output, but there's two relays

I misread the schematic on the dimmer, I thought it was representing the internals when it's the externals. What I took for relays outputs are switch inputs. I see now why you are not using the output.