Limiter inverter with RS485 load setting

Cell-King

Member
Joined
Sep 23, 2019
Messages
42
>Hi @Cell-King outputting 0W still draws power. Maybe you can have a simple sonoff at the AC output to allow completely disabling the inverter.
Edit: I use a Sonoff POW R2 at the AC output to achieve this. It also measures output power quite accurately.

Thanks @CarlosGS I have a simple timer plug that turns the unit off when it reaches night time rate, just to save a bit of juice. I will look into the sonoff and integrate some control into my python control service so that I have more control over it.

Hi @grundholm After a lot of initial problems i've been able to get these devices working for months at a time. The main problems I was having stemmed from allowing the battery voltage to drop too low. The inverters would start to act erratically so now I keep the cell voltages at about 3.5 volts and it works fine for now. My batteries drift a lot at lower voltages so I think it's probably safer that I keep them at that level anyway. My plan is to double my battery pack shortly and also add a wind turbine so I think that will bring more stability down the road anyway.

Something I will say is that I think it's absolutely necessary to create your own control plane with a raspberry pi and a serial connection, I've been able to add a lot more logic features to the device that I wouldn't be able to have otherwise to the point that I wouldn't use these inverters without it.

Examples of the extra logic I made-

I turn output to 0 watts when electricity is night rate and back on when its morning again.

Increase the AC output watts when I have over 900 watts on the panels, as this maximises power to the house and minimises amps entering the battery (my thinking goes- I might as well use the power from the panels directly and take pressure off the battery charge rate).

When the battery is fully charged output maximum watts, then when I drop to lower battery state of charge reduce output accordingly. I have four stages of output, from maximum to zero output based on state of charge.

To get this working I have a relay board regularly "power cycles" the serial port that's connected to the raspberry pi. I found that the serial would often lock up. This may be due to the RS232 chip that I currently have and I've other models that I'm going to build and try the same with them, so this may not be needed. My CT signals come from a Emonpi over JSON, which I think is a great piece of kit. I preferred having a digital signal sent across my network instead of the supplied external limiter that is shipped.

In summary, to answer your question I think if you can learn from the mistakes of us and get a good control platform running, and avoid the costs of the external limiter, these devices are very cheap and seem to work well once you iron out the kinks.

I think I linked to a version of my python code here in this thread but if you want an updated version let me know.
 

grundholm

New member
Joined
Oct 3, 2020
Messages
12
Thank you, I will probably order one of these inverters, I currently have a SUN GTIL 2000W with limiter connected to my solarpanels, now I want to add batteries (48V) and the Soyo seems like the right 'discharger' for that. The SUN inverter requires a higher input voltage and I like the Soyo because of the full control / logic we can make now, because of your work. Thanks! - I would probably make my own limiter with an Arduino because I know C language better than Python.

I looked at your Python code and maybe the serial lockup can be avoided by adding a serial.flush() after you send your command in your writeToSerial def. - are you sure the baudrate is 4800 and not 9600 ? -and try to change the timeout to something higher or try with 0
 

completelycharged

Well-known member
Joined
Mar 7, 2018
Messages
1,053
Basic issues I had to sort out were :

Don't let the low voltage cut-off be triggered by the inverter as this is what causes the problems and lockup of communication, manage the output and voltage levels externally via the serial port

Serial ports work fine with a good adapter and don't need power cycling

Fractional data packets (noisy serial line caused by low or wrong voltage levels) can create issues if packet spacing is tight as a reset timeout cant take effect

Low output efficiency is quite bad so I don't let the output drop below about 70W and just switch off instead

Simmilarly when energy is low I also avoid the top end

I had setup separate cooling fans for the units as the internal fans kick in at around 42C and I prefer to keep them way cooler than that as a 10C drop may end up increasing the capacitor life considerably...

My units have run for months without the need for any power cycling and held at zero for days on end (reduced solar into winter)

The units also output the voltage and current draw, which you can use if you don't have any external sensors, but the accuracy is not that great

Cheap and cheerful, work, just.
 

gtrdriver

New member
Joined
Feb 25, 2021
Messages
2
OK, when they said "all items from Soyosource are not available now as they don't work now" they meant the factory was temporarily closed :D

They resumed operations today.

Also sharing my code, I hope it helps!
Code:
import struct
import time
import serial

ser_in = serial.Serial('/dev/ttyUSB0',4800)
ser_out = serial.Serial('/dev/ttyUSB1',4800)

def computeCRC(power):
  pu = power >> 8
  pl = power & 0xFF
  return (264 - pu - pl) & 0xFF

def read_consumed_power(ser):
  time.sleep(0.1) # Wait and clear input buffer to ensure proper packet synchronization
  ser.reset_input_buffer()
  try:
    raw = ser.read(8) # Read 8 bytes
  except: return -1
 
  (a,b,divider,c,consumed_power,d,crc) = struct.unpack('>BBBBHBB', raw)
  if computeCRC(consumed_power) != crc: return -2 # Checksum mismatch
 
  return consumed_power

def set_generated_power(ser, power):
  a = 0x24
  b = 0x56
  divider = 0x00
  c = 0x21
  d = 0x80
 
  crc = computeCRC(power)
  out = struct.pack('>BBBBHBB', a,b,divider,c,power,d,crc)
  ser.write(out)
  ser.flush() # Wait for data to be written out

while True:
  consumed_power = read_consumed_power(ser_in)
  if consumed_power < 0: continue
  print(consumed_power)
 
  desired_power = consumed_power + 6 # Add 6 extra watts, for example to compensate and completely null out the utility meter
 
  set_generated_power(ser_out, desired_power)

ser_in.close()
ser_out.close()
Hi

im trying to use your Python Script on a Raspberry PI using a USB/RS485 Dongle - but dont get a connect - can anyone help me please ?
 

completelycharged

Well-known member
Joined
Mar 7, 2018
Messages
1,053
Hi

im trying to use your Python Script on a Raspberry PI using a USB/RS485 Dongle - but dont get a connect - can anyone help me please ?
Without any additional information :
Read through the full thread, then...
Is your port set to 4800 baud ?
Can you recieve the meter values on the USB/RS485 as a test ?
Is the inverter set to battery / auto mode so it will respond to messages ?
 

completelycharged

Well-known member
Joined
Mar 7, 2018
Messages
1,053
As an update I purchased another unit and now have 5 of these setup. All together they have output 7,200kWh since I started.

One of the units does not have the RS485 port (oldest unit) so I use that for "basel oad" and it's just set to output about 180W all day
One of the units is only capable of 800W sustained and the other 3 are 900W
The older meters that come with the units are barely decent and at the moment I don't know if the meters are inaccurate or the output is inaccurate.

Overall output looks like the image below.. which you will notice is not a web page. The charts show the last hour of operation.

I have 3 of the meters that came with the unit setup and connected, one is mainly showing the lighting load, the other sockets and the third unit is the main incomming supply which then gives me an indication as to any excess/deficit. I need to replace these with non split core CT's and a meter that is more reliable, which can also tell the difference between import and export.

What I'm noticing is that the meters may be really-really bad at any reactive equipment / power factor. I had some things running which ended up with a relatively large deficit, part of that was due to low voltage and a unit going offline. They do pickup the load spikes up when the fridge or freezer turns on which in my case is an over 1000W spike.

The efficiency (with a low battery input voltage) would appear to be around 80%.

1614297526611.png


Yes, the units do (or did with the older firmware) have issues, but nothing that has not been noted and worked around in this thread.

They are a relatively small output, but if the majority of your house load is on 24x7 then you only need a small output over 24 hours a day, If you have 200W on all day then your starting position is covering 4.8kWh per day (1,752kWh per year) or over 5kWh from any solar / battery.

I added another unit to reduce average loading and to cover the inability of the house to work in appliance binary mode (only one on at a time) and so that I can run some more of my equipment.

Balancing load changes out over more units also helps, although I have not tried to look at how long a unti at 0W takes to syncronise to the grid and start outputting power. There is a delay, although it may be in the order of 0.5 - 1.0 seconds. This shows up as some of the noise on the green line in the import/export chart with the bigger single spikes being the load to output delay.

Keeping them cooler in sumer may be worth while as well, I added an external fan / airflow as well to try and avoid the internal temperature picking up and it can work quite well. The heatsink has a bit of a store so having the airflow on all the time brings the temperature right down. Overall efficiency wise the extra 5W per unit for the fan will add up, but I'm looking to add temperature sensors (because the manufacturer will not even reply to an email in Chinese - and the additional data might be accesible over RS485) and then switch the fans on and off with the overall inverter control. Might extend the operational life a year or two.

Overall they work as long as you work around the bugs. Not ideal, not perfect, but they output kWh as and when required (just / almost).

Nothing else that I have found "yet" will work as easily to control via a signal without hardware hacking. The GTIL units "may" have a way to control them via the RS485 port and waiting to see if someone will try the method out I suggested in another thread.
 

gtrdriver

New member
Joined
Feb 25, 2021
Messages
2
As an update I purchased another unit and now have 5 of these setup. All together they have output 7,200kWh since I started.

One of the units does not have the RS485 port (oldest unit) so I use that for "basel oad" and it's just set to output about 180W all day
One of the units is only capable of 800W sustained and the other 3 are 900W
The older meters that come with the units are barely decent and at the moment I don't know if the meters are inaccurate or the output is inaccurate.

Overall output looks like the image below.. which you will notice is not a web page. The charts show the last hour of operation.

I have 3 of the meters that came with the unit setup and connected, one is mainly showing the lighting load, the other sockets and the third unit is the main incomming supply which then gives me an indication as to any excess/deficit. I need to replace these with non split core CT's and a meter that is more reliable, which can also tell the difference between import and export.

What I'm noticing is that the meters may be really-really bad at any reactive equipment / power factor. I had some things running which ended up with a relatively large deficit, part of that was due to low voltage and a unit going offline. They do pickup the load spikes up when the fridge or freezer turns on which in my case is an over 1000W spike.

The efficiency (with a low battery input voltage) would appear to be around 80%.

View attachment 24033

Yes, the units do (or did with the older firmware) have issues, but nothing that has not been noted and worked around in this thread.

They are a relatively small output, but if the majority of your house load is on 24x7 then you only need a small output over 24 hours a day, If you have 200W on all day then your starting position is covering 4.8kWh per day (1,752kWh per year) or over 5kWh from any solar / battery.

I added another unit to reduce average loading and to cover the inability of the house to work in appliance binary mode (only one on at a time) and so that I can run some more of my equipment.

Balancing load changes out over more units also helps, although I have not tried to look at how long a unti at 0W takes to syncronise to the grid and start outputting power. There is a delay, although it may be in the order of 0.5 - 1.0 seconds. This shows up as some of the noise on the green line in the import/export chart with the bigger single spikes being the load to output delay.

Keeping them cooler in sumer may be worth while as well, I added an external fan / airflow as well to try and avoid the internal temperature picking up and it can work quite well. The heatsink has a bit of a store so having the airflow on all the time brings the temperature right down. Overall efficiency wise the extra 5W per unit for the fan will add up, but I'm looking to add temperature sensors (because the manufacturer will not even reply to an email in Chinese - and the additional data might be accesible over RS485) and then switch the fans on and off with the overall inverter control. Might extend the operational life a year or two.

Overall they work as long as you work around the bugs. Not ideal, not perfect, but they output kWh as and when required (just / almost).

Nothing else that I have found "yet" will work as easily to control via a signal without hardware hacking. The GTIL units "may" have a way to control them via the RS485 port and waiting to see if someone will try the method out I suggested in another thread.
Hi

First of all. Great work

I have some questions

1 the Inverter I had was damaged so no communication
2 can you post where you have buyed the inverter with working RS485.
3 can you also read values from the inverter like dc voltage load and so on?
 

alpha60

New member
Joined
Mar 9, 2021
Messages
2
Hello everyone, I am interested in this inverter, @completelycharged how do you communicate with the inverter in rs485 with a ras pi, I saw that you change the watt limit parameters you do it with which software?
1615306623821.png

do you have the source?
 

completelycharged

Well-known member
Joined
Mar 7, 2018
Messages
1,053
I use Visual Basic using community edition of visual studio

I have re-writen the earlier single app and split it into multiple bits of code so that I run one instance per inverter and use RabbitMQ as the messaging. That way I can hook up and control from multiple displays, the downside though is that I can't just bring up a web page.

This is the code for the inverter controller


Imports System.Timers
Imports WattsShared.cStructures

Public Class cInverter

Public WithEvents TimPoll As New Timers.Timer

Public MyState As InStatus
Public MyCommand As InCommand

Public ControlBytes(7) As Byte
Public StatusBytes(14) As Byte

Public InverterActive As Boolean = False
Public InverterEnabled As Boolean = True

Public myPortName As String
Public PollDelay As Integer
Public WithEvents MyRS485 As New cRS485port

Public Event InverterStatus(InverterState As InStatus)

Public Sub SetupInverter()

TimPoll.Interval = PollDelay
TimPoll.AutoReset = True

ControlBytes(0) = 36
ControlBytes(1) = 86
ControlBytes(2) = 0
ControlBytes(3) = 33
ControlBytes(6) = 128

If MyState.Adjustable Then
MyRS485.SetPort(myPortName, 4800)
MyRS485.StartPort()
End If

TimPoll.Enabled = True

End Sub
Public Sub SetInverterOutput()

If MyState.Adjustable Then
ControlBytes(4) = Int(MyState.WattsOut / 256)
ControlBytes(5) = MyState.WattsOut - (ControlBytes(4) * 256)
CalculateChecksum()
MyRS485.SendBytes(ControlBytes)
End If

End Sub
Private Sub CalculateChecksum()

ControlBytes(7) = (264 - ControlBytes(4) - ControlBytes(5)) And 255

End Sub
Private Sub MyRS485_RS485packet(ReturnBytes() As Byte) Handles MyRS485.RS485packet

If ReturnBytes.Length = 15 Then

MyState.Volts = ((ReturnBytes(5) * 256) + ReturnBytes(6)) / 10
MyState.Amps = ((ReturnBytes(7) * 256) + ReturnBytes(8)) / 10
MyState.Watts = MyState.Volts * MyState.Amps

RaiseEvent InverterStatus(MyState)
End If

End Sub
Private Sub TimPoll_Elapsed(sender As Object, e As ElapsedEventArgs) Handles TimPoll.Elapsed

While MyRS485.PortBusy
Thread.Sleep(5)
End While

SetInverterOutput()

RaiseEvent InverterStatus(MyState)

End Sub
End Class
 

completelycharged

Well-known member
Joined
Mar 7, 2018
Messages
1,053
2 can you post where you have buyed the inverter with working RS485.
3 can you also read values from the inverter like dc voltage load and so on?
2 - Aliexpress - typically any seller with a >90% rating and some prior sales
3 - see above BUT the newer inverter I recieved does not appear to return the same infrequent data packet or any. I have not found any message to allow the unit to be polled for these values. The manufacturer won't even be polite as to reply to any request, even in Chinese.
 

Maggi80

New member
Joined
Mar 14, 2021
Messages
1
Code:
import struct
import time
import serial

ser_in = serial.Serial('/dev/ttyUSB0',4800)
ser_out = serial.Serial('/dev/ttyUSB1',4800)

def computeCRC(power):
  pu = power >> 8
  pl = power & 0xFF
  return (264 - pu - pl) & 0xFF

def read_consumed_power(ser):
  time.sleep(0.1) # Wait and clear input buffer to ensure proper packet synchronization
  ser.reset_input_buffer()
  try:
    raw = ser.read(8) # Read 8 bytes
  except: return -1
 
  (a,b,divider,c,consumed_power,d,crc) = struct.unpack('>BBBBHBB', raw)
  if computeCRC(consumed_power) != crc: return -2 # Checksum mismatch
 
  return consumed_power

def set_generated_power(ser, power):
  a = 0x24
  b = 0x56
  divider = 0x00
  c = 0x21
  d = 0x80
 
  crc = computeCRC(power)
  out = struct.pack('>BBBBHBB', a,b,divider,c,power,d,crc)
  ser.write(out)
  ser.flush() # Wait for data to be written out

while True:
  consumed_power = read_consumed_power(ser_in)
  if consumed_power < 0: continue
  print(consumed_power)
 
  desired_power = consumed_power + 6 # Add 6 extra watts, for example to compensate and completely null out the utility meter
 
  set_generated_power(ser_out, desired_power)

ser_in.close()
ser_out.close()
@CarlosGS
Hi, i will try your code and try to understand it.
Is it a code which read a Device via Modbus and send a signal to the inverter with a second Modbus connection.
Where do you read the value from a Power Meter and which Powermeter do you take?
Thank You.
 

Stefanseiner

Active member
Joined
Apr 16, 2020
Messages
115
Hello,
I am using this Soyo Source inverters too at my garage to charge my electric car with the DIY 18650 powerwall
phoca_thumb_l_KW05_DIY_18650_Powerwall_Spind2_24.jpg


They run well since a few month, both inverters are in parallel at the same phase because the charger is single phase.

Now I want to build a little photovoltaik system + 18650 powerwall for my mother, with the Soyo Source inverter too.
But therefore it would be much better with the ability to measure all three phases of the house.

Does anybody have an idea how to simple do this?
It is not necessary to control the inverter via RS485, I think it would be helpful to have a small mcu which can handle three clamps, sum the wattages and export a single signal to the inverter with the voltage he expects from his origin clamp.

Yesterday I stumbled over this board for ESP8266 and 4 clamps -> 4 Channel ESP8266 Mains Current Sensor - Wemos - Current - SCT013 - 100A/50mA
Would this be possible?
 

Stefanseiner

Active member
Joined
Apr 16, 2020
Messages
115
I saw this just two weeks ago. For me it seems like it's nearls the same like the "old" one.
Identical connections, identical clamp sensor, identical values are shown.
Just new case and I guess they improved the possibility to add more inverters in parallel because of the four new LEDS at the bottom side. I tried several days to adjust my limiter box until I finally had success with setting up a second limiter
 

grundholm

New member
Joined
Oct 3, 2020
Messages
12
This is a reply to your previous post. The idea is good as long as we don't have a smart meter! I'm in Germany too and we still have the old meter with a disc. I looked at the 4 Channel module and it looks good, it collects the values from the 4 inputs and returns the mV (watt) or a int value, because it's based on an ADS1115.... Anyway, the current sensor from Soyo is based on mA and not mV - so 70A (Imax) is equal to 16.67mA aka. 3000:1 - I don't know how to imitate this with and Arduino. Another option would be to collect the 3xWatt with the 4 Channel module, add them to one value and then output a RS485 value straight to the Soyo.
 

Polle

New member
Joined
Feb 9, 2021
Messages
7
Hello everyone,
This looks like a very interesting solution for me.
I already have a growatt solar inverter so i am looking for a "battery inverter" which i can control via RS485.
This is the first one i see..
Does anyone know other battery inverters (so only battery connected to it) where the output can be regulated?
(i have a plc so i can do anything from modbus, Can, ... to simple 0-10V outputs to control the output of the inverter)
So i am looking for an inverter that i can controle myself :)
 

grundholm

New member
Joined
Oct 3, 2020
Messages
12
Today I connected the powermeter/limiter to an RS485 -> USB to serial converter on Windows and made quick and 'dirty' C# app. It reads the data and shows the watt in the console. I just want to share this code in case someone can use it to get startet or something like that. This powermeter/limiter could be used without the Inverter as a 'Kill A Watt' ... Does anyone know if it's possible to set it as Unit 2 or 3 without the Inverter, I would like to see if the modbus data changes.


C#:
using System;
using System.IO.Ports;
using System.Threading;

namespace ConsoleModbusReader1
{
    class Program
    {
        static SerialPort sp;

        static void Main(string[] args)
        {
            //Create bytearray to hold serialdata
            byte[] data = new byte[8];
            //Init. serialport
            SerialPort sp = new SerialPort
            {
                PortName = ("COM3"),
                BaudRate = 4800,
                Parity = Parity.None,
                StopBits = StopBits.One
            };

            //Check if serialport open
            if (!sp.IsOpen)
            {
                sp.Open();
            }
           
            while (true)
            {
                try
                {
                    //Read serial port, insert into data
                    sp.Read(data, 0, 8);

                    //Calculate checksum, if not true clear array and discard serial buffer
                    if (((264 - data[4] - data[5]) & 255) != data[7])
                    {
                        Array.Clear(data, 0, 8);
                        sp.DiscardInBuffer();
                    }

                    //Calculate watt
                    var b4 = data[4] * 256;
                    var b5 = (int)data[5];
                    var w = b4 + b5;
                   
                    Console.Write("Watt: ");
                    Console.WriteLine(w);
                    Console.WriteLine("----------");
                   
                    //printToScreen(data);              
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }

                Thread.Sleep(1000);
                Console.Clear();
                Array.Clear(data, 0, 8);
            }
        }
        public static void printToScreen(byte[] dataArray)
        {
            Console.WriteLine(dataArray[0]);
            Console.WriteLine(dataArray[1]);
            Console.WriteLine(dataArray[2]);
            Console.WriteLine(dataArray[3]);
            Console.WriteLine(dataArray[4]);
            Console.WriteLine(dataArray[5]);
            Console.WriteLine(dataArray[6]);
            Console.WriteLine(dataArray[7]);
            Console.WriteLine("----------");
        }    
    }
}
 
Last edited:

completelycharged

Well-known member
Joined
Mar 7, 2018
Messages
1,053
All that the meter does when switching the number of units is it reduced the value in the output RS485 data stream by dividing the metered value by the number of units.
Say you have 1500W of demand / meter showing and you set it to 3 units the RS485 stream would then report 500.
Effectively it just divides up the output and assumes all connected units are the same (not mixing 1200W and 100W units)

The meters also seem to read a spot reading of the voltage/power value which can show up some errors and strange outputs when connected to high power factor devices. Resistive loads seem to be ok (for a very cheap meter) upto a few kW but anything with reactive power the value starts to drift by a few hundred watts at times for 3kW loading.

The freezer starting up will usually create a >1kW spike in the meter readings for 1-2 seconds. This then causes the inverter to try to ramp up (and miss the load) because the response on these seems to be about a second to target loading, which is sort of a bit slow.

The update speed by default seems to be 1 per second, although I have 2 which are once every second and one which is every 500mS. These are the older meters, which I'm looking to replace at some point.

The more I have used these and played around with them I'm noticing a few different things. The curious one is that when used as a solar config the maximum output is a few hundred watts higher (1200W vs 900W) and this is purely limited in software as a way of preventing prolonged high temperature operation at full output from degrading the capacitors too quickly. I'm still hoping that they wil release some of the other bits of the protocol (or someone reverse engineers the firmware) becasue I think these are more useful than the current "limited" mode of operation.
 
Top