Welcome to the Marine Electronics Forums presented by Panbo and SeaBits.

Reverse engineering...
Clear all

Reverse engineering Mastervolt Master Adjust protocol

8 Posts
3 Users
Etaoin Shrdlu
Active Member
Joined: 10 months ago
Posts: 6
Topic starter  

Hello fellow tinkerers!

I have installed a Mastervolt Mass Combi 12-2200-100 on my live-aboard which I'm quite happy with. But I would like to be able to monitor and control it from my on-board computer system, which is based on IBM's Node-RED. Because of its extensible open source nature this system is capable of talking to basically anything, and I am already monitoring the GPS, navionics, weather station, PV-array, bilge pumps, cameras, gas & fire alarms and a number of other things through it. So I started looking at the communication between Mastervolt's official software (MasterAdjust) and the Mass Combi, and quickly figured out most of what it does; I can now read voltage and current going in and out, as well as battery state, DC and inverter load, and the presence of shore power.

But I'm stumped by one particular command, which is the command to turn the inverter and the charger on/off (0xC1 0xF0 0x32 ...). This is something I would really like to be able to control remotely, but since Mastervolt have not published any documentation of the protocol, and because the MasterAdjust software drowns out the relevant packages in a steady stream of data, I haven't been able to fully figure this part out. This is in stark contrast to e.g. Victron, who go to great lengths to make their products easy to talk to from whatever system, and who publish detailed specifications of their communications protocols. It's a great pity that Mastervolt have not understood the need for this, particularly given the poor state of the official (Windows only) software - had I known about this I likely would have opted to buy a charger/inverter from one of their competitors instead.

I'm starting this thread with the intention of sharing what I've learned so far, and the hope that there will be others here who may be interested in helping me complete the picture.

This topic was modified 10 months ago by Etaoin Shrdlu

Etaoin Shrdlu
Active Member
Joined: 10 months ago
Posts: 6
Topic starter  

The first hurdle I faced was figuring out what kind of serial interface the Mass Combi uses; in the product literature it is referred to as a "QRS232" port, with the "Q" (as in "quasi") meaning it's a 5V TTL RS232 port. The manual for the Mastervolt PC Link adapter helpfully provides both pin-out and voltage of this port:

While RS232 normally signifies a 12V signalling schema, it was not difficult to find a cheap USB <> TTL level RS232 adapter like this one (£4 on the bay): 

Hooking up to the Mass Combi through this adapter (via an RJ11 plug) made it possible for the MasterAdjust software (running in a WinXP virtual machine) to talk to the unit:

Now I could start looking at the data. It's a 19200-8-N-1 link, and hooking my scope up to TX (blue) and RX (red) revealed traffic like this:

It turns out the MasterAdjust software works by going through all the commands needed to populate the interface with data twice a second, so there is a lot of traffic, and I was a little overwhelmed by this at first. But I assembled a list of requests and responses in a spreadsheet to try and tease things out (requests in red, responses in grey/black):

A few things immediately stood out: a request always starts with 0xC1 0xF0 and a response with 0xF0 0xC1. It seems the following two bytes are the command, and the following four (or five) the relevant value(s). The last byte is a modulo 256 checksum. I dug deeper, taking the four "value" bytes, in reverse order (which is common), and turning them into decimal:

"13573", could that be 13.573? Looks like it might be a battery voltage? By comparing values (with different scaling) to what the MasterAdjust software was showing I soon found a handful of commands I was sure of. It turned out that the "13573" above had nothing to do with any voltage, but was actually the "DC Current" scaled by 2560. And so on. Many values were scaled by 2560, but some by 256, some by 100, and many others were at scale 1. So I had a lot of fun. But I made headway and could confirm with 100% certainty that sending (for example)

0xC1 0xF0 0x24 0x00 0x00 0x00 0x01 0xD6

would reliably give me a value that matched the "DC Current" shown in MasterAdjust (e.g. 13573/2560=5.3019531 when "5.3 A" displayed in MasterAdjust). I now could start building dashboard components in Node-RED to plot and display some things:

This allowed me to graph the changing values while I exposed the unit to various conditions, such as unplugging the shore power, and adding load to the DC or inverter systems, which unlocked a few other secrets. I turned out some of the value bytes were actually individual bits corresponding to the LEDs on the remote control panel, so

would, for example, return the four (or five) value bytes 


- now taking the bits in the first two bytes 0xE0 0xF1 gives us 1110 0000 and 1111 0001 respectively, and the first byte happens to match that the lowest (5%) LED for "DC Load" on the remote control panel is lit, and the second byte that all five "State of Charge" are lit. I eventually mapped it out like this:

first byte

  1111 1000  discharged?
  1111 0101  Error mode? 

  1111 1110  100% DC-load (also when switched off)
  1111 1100   75% DC-load
  1111 1000   50% DC-load 
  1111 0000   25% DC-load 
  1110 0000    5% DC-load
  1100 0000    0% DC-load 

  0100 0000  Charger off, inverter off

  0011 1110  100% on inverter
  0011 1100   75% on inverter
  0011 1000   50% on inverter
  0011 0000   25% on inverter
  0010 0000    5% on inverter
  0000 0000  cut off / inverter off

second byte

  1111 0011  ???

  1111 0001  100%

  1110 0011   75% inverter soc
  1100 0011   50% inverter soc
  1000 0011   25% inverter soc
  0000 0011    5% inverter soc
  0000 0010    0% blinking

  1111 0001  charging (float)
  1110 0001  charging (abs 2)
  1100 0001  charging (abs 1)
  1000 0001  charging (bulk 2)
  0000 0001  charging (bulk 1)

This is copied raw from my notes, and as you can see there are still a few question marks, though I now know enough to replicate all of the indicator lights on the remote control panel:

(n.b. the remote panel picture is a stock image and its state does not match the values displayed in the Node-RED dashboard on the left)

This post was modified 10 months ago 6 times by Etaoin Shrdlu

Etaoin Shrdlu
Active Member
Joined: 10 months ago
Posts: 6
Topic starter  

Here is what I think I know about command 0x25, the response of which drives the remote control panel LEDs:


Quit a few gaps as you can see, and a few curiosities:

  • Due to the remote panel using combined LED arrays for "DC Load" / "Inverter Load" and "State of charge" / "Charger Stage", these are not sent as separate blocks of bits, but rather one has to look at the "Charger On" and "Inverter On" bits to determine what the values represent.
  • The five "DC/Inverter Load" LEDs are controlled by five bits in reverse order (here showing 5%, or only first LED lit), while the five "State of Charge/Charger Stage" LEDs use just four bits (again in reverse order, here showing 100%, or all five LEDs lit). The first LED in this array will blink when the LSB of the second byte goes low.
  • The "AC Input" LED is inverted, and lights up when the LSB of the fourth byte is low.

Ben Stein
Estimable Member Admin
Joined: 4 years ago
Posts: 143

Just a quick comment to say how impressed I am by what you've done. I love the work you've done and the resulting dashboard. Your level of persistence to get to this point is really impressive. I think I would have given up when I saw the flood of data produced.


Keep up the good work!




Etaoin Shrdlu
Active Member
Joined: 10 months ago
Posts: 6
Topic starter  

@ben-stein Oh, many thanks - I took this on as a challenge during Covid lock-down when I had little else to do, and thought it would be wrong not to share. After all, I have myself often benefited from similar detective work done by others. I'm also quite enthusiastic about what can be achieved with open source software these days, and the level of integration that this offers. For example, I now receive an SMS text message (and an email) whenever my boat loses shore power, which allows me to contact marina staff or a fellow berth holder and ask them to check what's caused it, and if possible restore the connection. This keeps my batteries in good shape, and ensures the dehumidifier keeps running (best piece of equipment I've ever bought). Key to all this is the Node-RED software, which ties together all the various bits of equipment and the data they generate, controls various outputs and alerts, and makes it a doddle to produce sexy looking dashboards like these (all work in progress, of course) :


I've got lots more coming for this thread; next up I'll share what I know about reading and setting the configuration options of the Mass Combi, which has a lot of settings for every aspect of its operation. Stay tuned! 

Edit: I should add that most of this is guesswork and I make no claim as to the accuracy of the information provided. It could well be that I've fundamentally misunderstood some aspects of the protocol. In fact this is partly why I've chosen to publish my findings; it is my hope that other Mass Combi owners may be able to help find the errors in my reasoning and that together we can build a more complete picture. Or, perhaps, that someone with real insight might chime in and correct me 🙂

This post was modified 10 months ago by Etaoin Shrdlu

Etaoin Shrdlu
Active Member
Joined: 10 months ago
Posts: 6
Topic starter  

Here's a teaser of the settings I've so far been able to identify:

This post was modified 10 months ago 2 times by Etaoin Shrdlu

Etaoin Shrdlu
Active Member
Joined: 10 months ago
Posts: 6
Topic starter  

The configuration options of the Mass Combi can be accessed with the commands 0x01 to 0x1B, which means there are 27 paramaters (or commands) in total. The last byte before the checksum specifies whether we are reading or writing the setting, with 0x01 to perform a read and 0x00 to perform a write. For example, to read the float voltage setting, the command is:


0xC1 0xF0 0x0A 0x00 0x00 0x00 0x00 0x01 0xBC

The response seems to contain the value in the first two bytes following the command, again in reverse byte order, so a typical response to the above command (on my 12V lead-acid system) would look like this:


0xF0 0xC1 0x0A 0x2D 0x05 0x00 0x00 0x00 0xED

If we take 0x2D and 0x05 in reverse order we get 0x052D, which is 1325 in decimal. Divide by 100 to get the float voltage, 13.25 V. I don't know what the next two bytes are used for, if anything; they always seem to be 0x00 0x00. It's possible that some commands use these for additional values, or higher precision, or that they're just left blank to keep all requests the same length. Here are all the settings I've been able to figure out:

dec  cmd  parameter             scaling
 8  0x08  Bulk Voltage              100
 9  0x09  Absorption Voltage        100
10  0x0A  Float Voltage             100
11  0x0B  Return To Bulk Voltage    100
12  0x0C  Force Float Voltage       100
15  0x0F  Gel Compensation          100
16  0x10  Return Amperes             10
17  0x11  Max Charge Current         10
18  0x12  Bulk Time                   1
19  0x13  Return To Bulk Time         1
20  0x14  Max Absorption Time         1
21  0x15  Min Absorption Time         1
22  0x16  Dc High On                100
23  0x17  Dc High Off               100
24  0x18  Dc Low On                 100
25  0x19  Dc Low Off                100

I'm still trying to determine what the commands in the gaps are for - I think some will be to get the serial number and firmware version numbers, as well as the DIP-switch settings, since these are all included on the "settings" tab of the official software:

To write a setting we need to perform the conversion to hex in reverse; we take the desired new value and multiply it with the scaling factor for the setting, convert it to an integer and swap the byte order.

For example, in JavaScript:

var val = 13.25;
var fac = 100;
var int = parseInt(val * fac);
var buf = Buffer.from(["0xC1","0xF0","0x00","0x00","0x00","0x00","0x00","0x00"]);

buf[2] = 10;                   // the command, 0x0A;
buf[3] = (int & 0x00FF);       // the value, low byte
buf[4] = (int & 0xFF00) >> 8;  // the value, high byte

To complete the command we of course also need to add the (mod256) checksum:

function addCsum(buf) {
  var sum = 0;
  for(var i = 0; i < buf.length; i++) {
    sum += buf[i];
  var csum = Uint8Array.from([(sum % 256)]);
  return Buffer.concat([buf, csum]);

var cmd = addCsum(buf);

Our command buffer is now ready to send to the Mass Combi, which would set the float voltage to 13.25 V:


0xC1 0xF0 0x0A 0x2D 0x05 0x00 0x00 0x00 0xED

In my next post I will show how I've implemented all this in Node-RED.

This post was modified 10 months ago 5 times by Etaoin Shrdlu

Nick Burrell
New Member
Joined: 4 years ago
Posts: 1

@etaoin - Thank you very much for this post. I have a need to adjust several parameters on my Mastervolt EVO 50 charger and have been unwilling to fork out for the 'official' Mastervolt PC Link connector.

Inspired by your topic, I've been trying to connect using a low-cost USB To RS232 TTL CH340G Converter Module connected to my MacBook with MasterAdjust running on Windows 7 virtual machine.

MasterAdjust can see the port but doesn't connect - I've checked the wiring and port settings.... Can you think of anything else that might be amiss?

Many thanks,