Reducing MPPT Charge Voltage Using Node Red

I’ve got a system with three SmartSolar MPPTs and a hydro generator charging an AGM battery bank, and often when the sun is out, the hydro generator (which has its own uninformed charge controller) will read the batteries at being higher than its target output voltage, which causes it to start freewheeling and making noise.

It can be difficult, and sometimes even unsafe for us to remove the hydro generator from the water and re-deploy it, so in the short term, we’ve just been manually disabling one or more of the MPPTs when we can’t take the hydro generator out of the water. This is a pretty brute force solution, though, and sometimes it drops the voltage lower than necessary, or requires constant management to toggle MPPTs back on if clouds come by.

I’d love to instead take advantage of the Cerbo and custom Node Red dashboard we have to tell the solar when we want to prioritize the hydro generator and to charge the system at a lower voltage. We could even do this programmatically based on hydro generator activity (we’ve got a SmartShunt monitoring its output voltage and current), but in the short term, I’m starting by looking for a way to do it with a manual toggle.

I tried looking through the available options with Node Red, and there doesn’t seem to be any voltage control offered over the MPPTs, either via the provided MPPT node, or even looking at the extended settings available with a custom node. There’s a way to adjust the charge current limit for each MPPT, but not the voltage settings, nor a way to force the controller into Float mode.

The broader system settings available in a custom node also don’t look helpful, with only the ability to adjust the DVCC current parameter (the adjustable voltage parameter seems to be for ‘managed’ batteries only, and has no effect for our AGM system).

A couple of ideas I’ve tried so far have been:

  1. Use a switch to disable shared current sense and manually send a current value lower than tail current to ‘trick’ the MPPTs into changing over to Float. This doesn’t respond immediately, however, as the MPPTs wait a minute or so to validate the current before changing modes, and it also doesn’t seem to work consistently across all three of our controllers. Adjusting the shared current sense setting also gets a bit messy and is something I’d like to avoid.

  2. Try and create a voltage-based PID control for the system current limit. This seems to get a bit messy, though, with the solar input constantly changing, and I don’t like constantly altering the system current limit to try and catch the voltage that’s controlled by the MPPTs own feedback loops.

I don’t really like either of these two solutions, and I’d much rather do something like tell the MPPTs to maintain a lower voltage temporarily, so their own feedback loops could handle providing the right amperage.

Does anyone know of a way to control voltage with Node Red?
Perhaps some way to mimic a BMS and just temporarily set a system-wide voltage limit when we want to prioritize the hydro generator?

Without a multiplus you cant do much, maybe try this and disable if you get an over voltage,

[
{
“id”: “6c963b77f26d98ec”,
“type”: “victron-input-solarcharger”,
“z”: “1112bdc43019f870”,
“service”: “com.victronenergy.solarcharger/293”,
“path”: “/Dc/0/Voltage”,
“serviceObj”: {
“service”: “com.victronenergy.solarcharger/293”,
“name”: “BlueSolar Charger MPPT 100/50 rev3”
},
“pathObj”: {
“path”: “/Dc/0/Voltage”,
“type”: “float”,
“name”: “Battery voltage (V)”
},
“name”: “”,
“onlyChanges”: false,
“roundValues”: “2”,
“x”: 1070,
“y”: 700,
“wires”: [
[
“c66a0d7900c605f3”
]
]
},
{
“id”: “3cadf84927788a1d”,
“type”: “victron-output-solarcharger”,
“z”: “1112bdc43019f870”,
“service”: “com.victronenergy.solarcharger/293”,
“path”: “/Mode”,
“serviceObj”: {
“service”: “com.victronenergy.solarcharger/293”,
“name”: “BlueSolar Charger MPPT 100/50 rev3”
},
“pathObj”: {
“path”: “/Mode”,
“type”: “enum”,
“name”: “Charger on/off”,
“enum”: {
“1”: “On”,
“4”: “Off”
},
“writable”: true
},
“initial”: “1”,
“name”: “”,
“onlyChanges”: false,
“x”: 1600,
“y”: 780,
“wires”:
},
{
“id”: “6c8aea65627761ff”,
“type”: “inject”,
“z”: “1112bdc43019f870”,
“name”: “”,
“props”: [
{
“p”: “payload”
},
{
“p”: “topic”,
“vt”: “str”
}
],
“repeat”: “”,
“crontab”: “”,
“once”: false,
“onceDelay”: 0.1,
“topic”: “”,
“payload”: “1”,
“payloadType”: “num”,
“x”: 1250,
“y”: 760,
“wires”: [
[
“3cadf84927788a1d”
]
]
},
{
“id”: “5c71e8b06bd41022”,
“type”: “inject”,
“z”: “1112bdc43019f870”,
“name”: “”,
“props”: [
{
“p”: “payload”
},
{
“p”: “topic”,
“vt”: “str”
}
],
“repeat”: “”,
“crontab”: “”,
“once”: false,
“onceDelay”: 0.1,
“topic”: “”,
“payload”: “4”,
“payloadType”: “num”,
“x”: 1250,
“y”: 800,
“wires”: [
[
“3cadf84927788a1d”
]
]
},
{
“id”: “1a540da040c2867a”,
“type”: “function”,
“z”: “1112bdc43019f870”,
“name”: “Check Battery Voltage”,
“func”: “// Extract the battery voltage from the message payload\nvar batteryVoltage = msg.payload;\n\n// Check the voltage and set the payload accordingly\nif (batteryVoltage < 13.9) {\n msg.payload = 1;\n} else if (batteryVoltage >= 14.0) {\n msg.payload = 4;\n}\n\n// Return the modified message\nreturn msg;\n”,
“outputs”: 1,
“timeout”: 0,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 1620,
“y”: 700,
“wires”: [
[
“3cadf84927788a1d”,
“9f32d1498c830fc1”
]
]
},
{
“id”: “9f32d1498c830fc1”,
“type”: “debug”,
“z”: “1112bdc43019f870”,
“name”: “debug 14”,
“active”: true,
“tosidebar”: true,
“console”: false,
“tostatus”: false,
“complete”: “false”,
“statusVal”: “”,
“statusType”: “auto”,
“x”: 1860,
“y”: 700,
“wires”:
},
{
“id”: “c66a0d7900c605f3”,
“type”: “delay”,
“z”: “1112bdc43019f870”,
“name”: “”,
“pauseType”: “rate”,
“timeout”: “5”,
“timeoutUnits”: “seconds”,
“rate”: “1”,
“nbRateUnits”: “5”,
“rateUnits”: “second”,
“randomFirst”: “1”,
“randomLast”: “5”,
“randomUnits”: “seconds”,
“drop”: true,
“allowrate”: false,
“outputs”: 1,
“x”: 1420,
“y”: 700,
“wires”: [
[
“1a540da040c2867a”
]
]
}
]

Thanks for the suggestion and the helpful example! Yes, unfortunately our Multiplus is too old to network at the moment (18xxx firmware), so we don’t have the additional control from that part of the system.

I still don’t want to fully disable the solar chargers if I can avoid it, so if there really isn’t another way to adjust voltage, I might mess try tuning the PID loop for system current again.

You should try it. Reducing the charge volta will throttle the controllers to 0 anyway. You need to consider the system response. When you disable the charge controller the current will ramp down to 0 in about 30 sec. When the voltage drops back below your setting the charger will take about 30 secs for the MPPT to kick and current will slowly ramp up. If you have multiple chargers you can even disable them with different settings.

Found a hacky workaround for now, but would love a better option:

When I want to prioritize the hydro generator, I have a single switch that turns off the DVCC shared voltage sense setting and then manually shares the battery voltage to each of the MPPTs using a custom node, while adding 0.5V. This makes them operate normally while trying to maintain a slightly lower voltage than actual because they think the voltage is higher than it really is. Turning off the switch re-enables system voltage sharing and stops the manual + added voltage update.

This works for now, because the MPPTs are the only DVCC-enabled chargers in the system, and I get that I’d need to completely revise the solution if more system components were added, or I switched from AGM to lithium with a BMS.