<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>QModMaster</title>
	<atom:link href="https://qmodmaster.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://qmodmaster.com</link>
	<description>A powerful, portable, and cross-platform Modbus master for industrial automation and PLC testing.</description>
	<lastBuildDate>Fri, 16 Oct 2026 03:17:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://qmodmaster.com/wp-content/uploads/2026/04/favicon-150x150.png</url>
	<title>QModMaster</title>
	<link>https://qmodmaster.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>pymodbus vs QModMaster: Script or GUI?</title>
		<link>https://qmodmaster.com/pymodbus-vs-qmodmaster-when-to-use/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:17:43 +0000</pubDate>
				<category><![CDATA[Comparisons]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/pymodbus-vs-qmodmaster-when-to-use/</guid>

					<description><![CDATA[pymodbus vs QModMaster: Script or GUI? pymodbus is the go-to open-source Python library for Modbus (BSD-3-Clause) — it even shows up in roundups of free Modbus Poll alternatives as the &#8220;build your own&#8221; option (see the ranaliz.com 2026 list). So: script it in Python, or point-and-click in QModMaster? The honest answer is not either/or. Probe...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">pymodbus vs QModMaster: Script or GUI?</h1>

<p class="wp-block-paragraph"><a href="https://github.com/pymodbus-dev/pymodbus" rel="nofollow noopener" target="_blank">pymodbus</a> is the go-to open-source Python library for Modbus (BSD-3-Clause) — it even shows up in roundups of free Modbus Poll alternatives as the &#8220;build your own&#8221; option (see the <a href="https://ranaliz.com/en/blog/free-modbus-poll-alternatives" rel="nofollow noopener" target="_blank">ranaliz.com 2026 list</a>). So: script it in Python, or point-and-click in QModMaster? The honest answer is not either/or. <strong>Probe with your eyes first, automate with code second.</strong></p>

<h2 class="wp-block-heading">When each one wins</h2>

<ul class="wp-block-list">
<li><strong>QModMaster wins</strong> at first contact with an unknown device: trying slave IDs, flipping between function codes, watching values update live, and opening the Bus Monitor when the bytes look wrong. Ten minutes in the GUI beats an hour of print-debugging.</li>
<li><strong>pymodbus wins</strong> the moment the setup works and needs to keep working: scheduled polling, logging to CSV or a database, threshold alerts, and CI tests that verify a device still answers after a firmware update.</li>
</ul>

<h2 class="wp-block-heading">The workflow: probe in QModMaster, freeze in pymodbus</h2>

<ul class="wp-block-list">
<li><strong>1. Probe interactively in QModMaster.</strong> Find the slave ID, the right function code and start address, and confirm the values look sane. If floats come back as astronomical numbers, fix the byte order first — see our <a href="/modbus-float-wrong-value-byte-order-fix/">float byte-order guide</a>.</li>
<li><strong>2. Copy those exact parameters into a pymodbus script.</strong> Same host, same port, same slave ID, same addresses — the script below is the direct translation of a working QModMaster session.</li>
<li><strong>3. When the script misbehaves at 3 a.m., reopen QModMaster</strong> and its Bus Monitor to see the raw frames again. GUI for diagnosis, script for the daily grind.</li>
</ul>

<h2 class="wp-block-heading">Minimal pymodbus script (Modbus TCP)</h2>

<p class="wp-block-paragraph">The direct translation of &#8220;read 10 holding registers from slave 1&#8221; into pymodbus 3.x:</p>

<pre class="wp-block-code"><code>from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient("192.168.1.100", port=502)
if not client.connect():
    raise SystemExit("TCP connect failed")

# holding registers (FC03), start address 0, 10 registers, slave id 1
rr = client.read_holding_registers(address=0, count=10, device_id=1)
if rr.isError():
    raise SystemExit(f"read failed: {rr}")

print(rr.registers)  # e.g. [9997, 10034, ...]
client.close()</code></pre>

<p class="wp-block-paragraph">Version note: current pymodbus (3.10+) names the slave parameter <code>device_id</code>. On older 3.x releases it was called <code>slave</code>, and on the 2.x line <code>unit</code> — if you copy examples from the internet, check which name your installed version expects.</p>

<p class="wp-block-paragraph">For a serial RTU link, the equivalent client is <code>ModbusSerialClient</code> (same <code>pymodbus.client</code> module):</p>

<pre class="wp-block-code"><code>from pymodbus.client import ModbusSerialClient

client = ModbusSerialClient("/dev/ttyUSB0", baudrate=9600,
                            parity="N", stopbits=1, bytesize=8)
client.connect()
rr = client.read_holding_registers(address=0, count=10, device_id=1)
print(rr.registers if not rr.isError() else rr)
client.close()</code></pre>

<h2 class="wp-block-heading">What to automate first</h2>

<ul class="wp-block-list">
<li><strong>Logging:</strong> poll every N seconds, append timestamped rows to CSV. This is the script every solar and energy-meter owner ends up writing.</li>
<li><strong>Alerting:</strong> read a status register in a loop and send a notification when a fault bit flips.</li>
<li><strong>Regression checks:</strong> a CI job that reads a known register map and fails the build when a firmware update moves something.</li>
</ul>

<p class="wp-block-paragraph">And keep QModMaster installed next to your scripts. The day a device stops answering, the fastest path back to green is still: open the GUI, read one register by hand, and look at the raw frame.</p>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Should I learn pymodbus or just use QModMaster?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Use QModMaster for interactive debugging and first contact with a device. Learn pymodbus when you need the same reads to happen automatically — logging, alerting, or scheduled polling. The recommended workflow is to probe in QModMaster first, then freeze the working parameters into a pymodbus script."
      }
    },
    {
      "@type": "Question",
      "name": "What is the pymodbus equivalent of a QModMaster holding-register read?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "ModbusTcpClient(host, port=502) followed by read_holding_registers(address=0, count=10, device_id=1) for slave 1. Current pymodbus 3.10+ uses device_id; older 3.x used slave and 2.x used unit."
      }
    },
    {
      "@type": "Question",
      "name": "Is pymodbus free?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. pymodbus is open source under the BSD-3-Clause license and installable via pip."
      }
    }
  ]
}
</script>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list">
<li><a href="/qt-libmodbus-master-example/">Build a Qt Modbus Master with libmodbus (QModMaster-style)</a></li>
<li><a href="/qmodmaster-vs-mbpoll-command-line/">QModMaster vs mbpoll: GUI or Command Line?</a></li>
<li><a href="/test-modbus-with-qmodmaster-before-home-assistant/">Test Modbus with QModMaster Before Writing Your Home Assistant Config</a></li>
<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows Wrong Value? Fix the Byte Order</a></li>
<li><a href="/download/">Download QModMaster</a></li>
</ul>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Build a Qt Modbus Master with libmodbus (QModMaster-style)</title>
		<link>https://qmodmaster.com/qt-libmodbus-master-example/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:17:36 +0000</pubDate>
				<category><![CDATA[Platforms]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/qt-libmodbus-master-example/</guid>

					<description><![CDATA[Build a Qt Modbus Master with libmodbus (QModMaster-style) This is a real scenario from qtcentre.org (thread 61749, &#8220;QT and Libmodbus&#8221;): a developer read QModMaster&#8217;s source code and wanted to build their own Qt GUI Modbus master application on top of libmodbus — targeting a Raspberry Pi. This page sketches the same architecture QModMaster uses, with...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">Build a Qt Modbus Master with libmodbus (QModMaster-style)</h1>

<p class="wp-block-paragraph">This is a real scenario from <a href="https://www.qtcentre.org/threads/61749-QT-and-Libmodbus" rel="nofollow noopener" target="_blank">qtcentre.org (thread 61749, &#8220;QT and Libmodbus&#8221;)</a>: a developer read QModMaster&#8217;s source code and wanted to build their own Qt GUI Modbus master application on top of libmodbus — targeting a Raspberry Pi. This page sketches the same architecture QModMaster uses, with a minimal but complete example: connect, read holding registers, and deliver the values to the GUI thread.</p>

<h2 class="wp-block-heading">The architecture: GUI thread + blocking worker</h2>

<p class="wp-block-paragraph">libmodbus calls such as <code>modbus_read_registers()</code> are synchronous — they block until the reply arrives or the timeout fires. QModMaster-style applications therefore do <strong>all</strong> Modbus I/O in a worker thread and push results to the GUI through signals and slots. The one rule that matters: never call libmodbus from the GUI thread, or your interface will freeze on every poll.</p>

<h2 class="wp-block-heading">Minimal example: connect → read → emit</h2>

<p class="wp-block-paragraph">One file, Qt5, C++17. The poller lives in a <code>QThread</code>; a <code>QTimer</code> in that same thread triggers each poll; results travel back via signals:</p>

<pre class="wp-block-code"><code>// Build with:  QT += widgets   and   LIBS += -lmodbus
// Debian / Raspberry Pi OS:  sudo apt install qtbase5-dev libmodbus-dev

#include &lt;QCoreApplication&gt;
#include &lt;QThread&gt;
#include &lt;QTimer&gt;
#include &lt;QVector&gt;
#include &lt;QDebug&gt;
#include &lt;cerrno&gt;
#include &lt;modbus/modbus.h&gt;

class ModbusPoller : public QObject {
    Q_OBJECT
public:
    explicit ModbusPoller(QObject *parent = nullptr) : QObject(parent) {}
    ~ModbusPoller() override {
        if (ctx) { modbus_close(ctx); modbus_free(ctx); }
    }

    bool openRtu(const char *device, int slaveId) {
        ctx = modbus_new_rtu(device, 9600, 'N', 8, 1);
        if (!ctx) return false;
        modbus_set_slave(ctx, slaveId);
        struct timeval timeout{2, 0};               // 2 s response timeout
        modbus_set_response_timeout(ctx, &amp;timeout);
        if (modbus_connect(ctx) == -1) {
            qWarning() &lt;&lt; "connect failed:" &lt;&lt; modbus_strerror(errno);
            modbus_free(ctx);
            ctx = nullptr;
            return false;
        }
        return true;
    }

public slots:
    void poll() {                                   // runs in the worker thread
        uint16_t regs[10] = {};
        int rc = modbus_read_registers(ctx, 0, 10, regs); // 0-based PDU address
        if (rc == -1) {
            emit failed(QString::fromUtf8(modbus_strerror(errno)));
            return;
        }
        QVector&lt;quint16&gt; out;
        out.reserve(rc);
        for (int i = 0; i &lt; rc; ++i) out.append(regs[i]);
        emit valuesReady(out);
    }

signals:
    void valuesReady(const QVector&lt;quint16&gt; &amp;values);
    void failed(const QString &amp;message);

private:
    modbus_t *ctx = nullptr;
};

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);

    auto *thread = new QThread;
    auto *poller = new ModbusPoller;
    poller-&gt;moveToThread(thread);

    auto *timer = new QTimer;          // no parent yet: move it before wiring
    timer-&gt;setInterval(1000);
    timer-&gt;moveToThread(thread);

    QObject::connect(thread, &amp;QThread::started, [=]() {
        if (!poller-&gt;openRtu("/dev/ttyUSB0", 1)) {
            qWarning() &lt;&lt; "could not open Modbus link";
            app.quit();
        }
    });
    QObject::connect(timer, &amp;QTimer::timeout, poller, &amp;ModbusPoller::poll);
    QObject::connect(thread, &amp;QThread::started,
                     timer, static_cast&lt;void (QTimer::*)()&gt;(&amp;QTimer::start));
    QObject::connect(poller, &amp;ModbusPoller::valuesReady,
                     [](const QVector&lt;quint16&gt; &amp;v) { qDebug() &lt;&lt; "registers:" &lt;&lt; v; });
    QObject::connect(poller, &amp;ModbusPoller::failed,
                     [](const QString &amp;m) { qWarning() &lt;&lt; "poll failed:" &lt;&lt; m; });
    QObject::connect(&amp;app, &amp;QCoreApplication::aboutToQuit, thread, &amp;QThread::quit);
    QObject::connect(thread, &amp;QThread::finished, poller, &amp;QObject::deleteLater);
    QObject::connect(thread, &amp;QThread::finished, timer, &amp;QObject::deleteLater);
    QObject::connect(thread, &amp;QThread::finished, thread, &amp;QObject::deleteLater);

    thread-&gt;start();
    return app.exec();
}

// If everything lives in one .cpp file, add at the end:
// #include "main.moc"</code></pre>

<p class="wp-block-paragraph">For a TCP device instead of serial, swap <code>modbus_new_rtu()</code> for <code>modbus_new_tcp("192.168.1.100", 502)</code> — everything else stays identical.</p>

<h2 class="wp-block-heading">Build notes</h2>

<ul class="wp-block-list">
<li><strong>Debian / Raspberry Pi OS / Ubuntu:</strong> <code>sudo apt install qtbase5-dev libmodbus-dev</code></li>
<li><strong>.pro file:</strong> add <code>QT += widgets</code> and <code>LIBS += -lmodbus</code></li>
<li><strong>Qt6:</strong> the same code works; install the Qt6 base dev package instead of <code>qtbase5-dev</code> and adjust the <code>QT +=</code> line for your Qt6 setup</li>
<li><strong>Windows:</strong> build libmodbus first (see the libmodbus documentation), then link your Qt project against it the same way</li>
</ul>

<h2 class="wp-block-heading">Gotchas QModMaster already solved for you</h2>

<ul class="wp-block-list">
<li><strong>Timeouts:</strong> always set a response timeout (<code>modbus_set_response_timeout</code>) — without one, a dead slave hangs your worker thread.</li>
<li><strong>Slave ID:</strong> call <code>modbus_set_slave()</code> before <code>modbus_connect()</code>; the default unit ID is not always what your device expects.</li>
<li><strong>Address base:</strong> libmodbus uses 0-based PDU addresses — the &#8220;40001&#8221; in a device manual is address <code>0</code> here. See our <a href="/modbus-register-address-offset-guide/">register address offset guide</a> for the full story.</li>
<li><strong>Error messages:</strong> <code>modbus_strerror(errno)</code> turns a failed call into a human-readable reason — log it, don&#8217;t swallow it.</li>
</ul>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Where is QModMaster's source code?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "The upstream project publishes its source alongside its project page on SourceForge. Studying it is exactly how other developers learned the Qt + libmodbus master architecture."
      }
    },
    {
      "@type": "Question",
      "name": "Why put libmodbus calls in a worker thread instead of calling them from the GUI?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "libmodbus I/O functions block until the reply arrives or the timeout fires. Called from the GUI thread, every poll would freeze the interface. A QThread worker with signals and slots keeps the UI responsive — this is the architecture QModMaster itself follows."
      }
    },
    {
      "@type": "Question",
      "name": "Will a Qt + libmodbus app run on a Raspberry Pi?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes — that was the original poster's target on qtcentre.org. Qt5 and libmodbus both install cleanly from the Raspberry Pi OS / Debian repositories, and the example above polls a serial RTU device with no display-specific code."
      }
    }
  ]
}
</script>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list">
<li><a href="/pymodbus-vs-qmodmaster-when-to-use/">pymodbus vs QModMaster: Script or GUI?</a></li>
<li><a href="/qmodmaster-vs-mbpoll-command-line/">QModMaster vs mbpoll: GUI or Command Line?</a></li>
<li><a href="/modbus-register-address-offset-guide/">Modbus Register Address Offset Guide</a></li>
<li><a href="/download/">Download QModMaster</a></li>
</ul>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>QModMaster vs mbpoll: GUI or Command Line?</title>
		<link>https://qmodmaster.com/qmodmaster-vs-mbpoll-command-line/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:17:29 +0000</pubDate>
				<category><![CDATA[Comparisons]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/qmodmaster-vs-mbpoll-command-line/</guid>

					<description><![CDATA[QModMaster vs mbpoll: GUI or Command Line? QModMaster gives you a Qt graphical interface with live register tables and a Bus Monitor for watching raw frames. mbpoll, by Pascal JEAN, is a command-line utility that talks to Modbus slaves over RTU or TCP, built on libmodbus and released under the GPL-3.0 license. Both are free,...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">QModMaster vs mbpoll: GUI or Command Line?</h1>

<p class="wp-block-paragraph">QModMaster gives you a Qt graphical interface with live register tables and a Bus Monitor for watching raw frames. <a href="https://github.com/epsilonrt/mbpoll" rel="nofollow noopener" target="_blank">mbpoll</a>, by Pascal JEAN, is a command-line utility that talks to Modbus slaves over RTU or TCP, built on libmodbus and released under the GPL-3.0 license. Both are free, both read and write Modbus registers — so which one should you reach for? It depends on where you sit: at a desktop, or on a headless box.</p>

<h2 class="wp-block-heading">The short answer</h2>

<p class="wp-block-paragraph"><strong>Desktop, interactive debugging, first contact with an unknown device → QModMaster.</strong> Fill in the connection dialog, see values update live, flip the display between hex, integer and float, and open the Bus Monitor when something looks wrong.</p>

<p class="wp-block-paragraph"><strong>Raspberry Pi, headless server, cron job, automated test script → mbpoll.</strong> It is a single tiny binary (Debian and Ubuntu ship it as the <code>mbpoll</code> package; macOS users can <code>brew install mbpoll</code>), it runs fine with no display attached, and its output pipes straight into your scripts.</p>

<h2 class="wp-block-heading">Side by side</h2>

<ul class="wp-block-list">
<li><strong>Interface:</strong> QModMaster — graphical register tables and dialogs. mbpoll — one-liners in the terminal.</li>
<li><strong>Best for:</strong> QModMaster — exploring an unknown device, watching values change, teaching. mbpoll — scheduled polling, logging, CI checks, remote SSH sessions.</li>
<li><strong>Frame-level debugging:</strong> QModMaster&#8217;s Bus Monitor shows raw request/response frames in the GUI. mbpoll prints poll statistics when you stop it with Ctrl-C, and you can capture its traffic with standard network tools.</li>
<li><strong>Footprint:</strong> QModMaster is a full Qt GUI application. mbpoll is a single small command-line binary that runs on Linux (x86, x86_64, armhf, arm64 — including Armbian/Raspbian on the Pi), Windows and macOS.</li>
<li><strong>What it can do:</strong> both read discrete inputs, read and write coils, read input registers, and read and write holding registers, with values shown in decimal, hexadecimal or single-precision float.</li>
<li><strong>License:</strong> QModMaster — LGPLv3 (upstream project). mbpoll — GPL-3.0.</li>
</ul>

<h2 class="wp-block-heading">The same read, two ways</h2>

<p class="wp-block-paragraph">Reading 10 holding registers from slave 1 over a serial link at 9600 baud. In QModMaster: open the connection dialog, pick the serial port, set the unit ID to 1, choose &#8220;Read Holding Registers&#8221;, start address and count — the values appear in the table. In mbpoll, the equivalent is one command (flags follow the documented <code>mbpoll -h</code> help):</p>

<pre class="wp-block-code"><code># Read 10 holding registers (-t 4) of slave 1 (-a 1),
# start reference 1 (-r 1), count 10 (-c 10), 9600 baud RTU:
mbpoll -a 1 -b 9600 -t 4 -r 1 -c 10 /dev/ttyUSB0

# Same idea over Modbus TCP (TCP is mbpoll's default mode):
mbpoll -m tcp -a 1 -t 4 -r 1 -c 10 -p 502 192.168.1.100

# Poll just once instead of looping, quieter output:
mbpoll -1 -a 1 -t 4 -r 1 -c 10 192.168.1.100</code></pre>

<p class="wp-block-paragraph">Handy flags worth knowing: <code>-t 4:float</code> reads a 32-bit float pair, <code>-B</code> switches 32-bit values to big-endian word order, <code>-l</code> sets the poll interval in milliseconds, and <code>-o</code> sets the timeout. Run <code>mbpoll -h</code> (or <code>man mbpoll</code> on Linux) for the complete list — the syntax deliberately resembles the classic proconX modpoll tool, though mbpoll is an independent codebase.</p>

<h2 class="wp-block-heading">Use them together: the practical workflow</h2>

<ul class="wp-block-list">
<li><strong>1. Probe interactively in QModMaster.</strong> Find the right slave ID, the right function code and addresses, and confirm the byte order of multi-register values (see our <a href="/modbus-float-wrong-value-byte-order-fix/">float byte-order guide</a> if numbers look insane).</li>
<li><strong>2. Freeze the working parameters into an mbpoll one-liner</strong> for cron, logging scripts or a Pi that has no monitor.</li>
<li><strong>3. When the script misbehaves, go back to QModMaster&#8217;s Bus Monitor</strong> to see the raw frames again. GUI for diagnosis, CLI for automation — they complement each other.</li>
</ul>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Is mbpoll a clone of Modbus Poll?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "No. mbpoll's command-line syntax resembles the classic proconX modpoll tool, but it is an independent project built on libmodbus and licensed GPL-3.0. It is free software maintained by Pascal JEAN."
      }
    },
    {
      "@type": "Question",
      "name": "Can mbpoll replace QModMaster?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "For scripted or headless polling — yes, that is exactly what it is for. For interactive debugging of an unknown device, a GUI like QModMaster with live register tables and a Bus Monitor is faster. Most people end up using both."
      }
    },
    {
      "@type": "Question",
      "name": "Which is better on a Raspberry Pi?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "mbpoll: it is a tiny single binary, installable from the Debian package repositories, and needs no display. Use QModMaster on your desktop for the initial exploration, then run mbpoll on the Pi for unattended polling."
      }
    }
  ]
}
</script>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list">
<li><a href="/qt-libmodbus-master-example/">Build a Qt Modbus Master with libmodbus (QModMaster-style)</a></li>
<li><a href="/pymodbus-vs-qmodmaster-when-to-use/">pymodbus vs QModMaster: Script or GUI?</a></li>
<li><a href="/test-modbus-with-qmodmaster-before-home-assistant/">Test Modbus with QModMaster Before Writing Your Home Assistant Config</a></li>
<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows Wrong Value? Fix the Byte Order</a></li>
<li><a href="/usb-to-rs485-adapter-buying-guide/">USB-to-RS485 Adapter Buying Guide</a></li>
</ul>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Home Assistant Modbus &#8216;No Response&#8217; but QModMaster Works</title>
		<link>https://qmodmaster.com/home-assistant-modbus-no-response-fix/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:17:14 +0000</pubDate>
				<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/home-assistant-modbus-no-response-fix/</guid>

					<description><![CDATA[Home Assistant Modbus &#8216;No Response&#8217; but QModMaster Works You wired up a Modbus device — say, an Aqotec controller behind a Waveshare RS485-to-Ethernet gateway — and QModMaster reads its registers without a hitch. Then Home Assistant logs No response received from the remote unit or Unable to decode response, and nothing updates. This exact &#8220;QModMaster...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">Home Assistant Modbus &#8216;No Response&#8217; but QModMaster Works</h1>

<p class="wp-block-paragraph">You wired up a Modbus device — say, an Aqotec controller behind a Waveshare RS485-to-Ethernet gateway — and QModMaster reads its registers without a hitch. Then Home Assistant logs <code>No response received from the remote unit</code> or <code>Unable to decode response</code>, and nothing updates. This exact &#8220;QModMaster works, HA doesn&#8217;t&#8221; situation comes up regularly in the <a href="https://community.home-assistant.io/t/modbus-connection-to-aqotec-no-response-received-from-the-remote-unit-unable-to-decode-response/611054" rel="nofollow noopener" target="_blank">Home Assistant community</a>. The good news: QModMaster just proved your hardware chain is fine. The fault is almost certainly in the HA configuration — and there is a systematic way to find it.</p>

<h2 class="wp-block-heading">The bisection rule: if QModMaster reads, the wire is fine</h2>

<p class="wp-block-paragraph">A successful QModMaster read proves, in one shot, that the serial parameters (baud rate, parity, stop bits) or the TCP host and port, the gateway&#8217;s operating mode, the wiring, the slave address, and the device itself all work — with exactly the settings you typed in. So stop re-crimping cables and swapping adapters. From here on, the only remaining suspect is how the Home Assistant modbus integration is configured. Keep the working QModMaster session open next to your HA config; you will compare the two value by value.</p>

<h2 class="wp-block-heading">Step 1 — Write down the four values that worked in QModMaster</h2>

<ul class="wp-block-list">
<li><strong>Connection mode:</strong> RTU on a serial port, or TCP to the gateway&#8217;s IP and port (e.g. <code>192.168.1.100:8899</code> for a transparent bridge, <code>:502</code> for a Modbus-TCP gateway).</li>
<li><strong>Unit identifier / slave address:</strong> the slave ID the read succeeded with.</li>
<li><strong>Function code and start address:</strong> e.g. Read Input Registers (FC04) starting at address 0, or Read Holding Registers (FC03).</li>
<li><strong>Register count and display format:</strong> how many registers you read, and whether the value was 16-bit, 32-bit float, etc.</li>
</ul>

<h2 class="wp-block-heading">Step 2 — Match each value to an HA config key</h2>

<p class="wp-block-paragraph">These five mismatches cause nearly every &#8220;QModMaster works, HA doesn&#8217;t&#8221; case:</p>

<ul class="wp-block-list">
<li><strong>Wrong slave / unit ID → &#8220;No response received from the remote unit&#8221;.</strong> The HA <code>slave:</code> key must equal the Unit Identifier that worked in QModMaster. If a TCP gateway serves several slaves, every sensor entry needs its own <code>slave:</code> — one shared value silently breaks the rest.</li>
<li><strong>Wrong count → &#8220;Unable to decode response&#8221;.</strong> HA&#8217;s <code>count:</code> must equal the number of registers the device actually returns. If QModMaster read 10 registers, the sensor needs <code>count: 10</code>; a 32-bit float needs <code>count: 2</code>.</li>
<li><strong>Wrong data_type → decode errors or garbage values.</strong> Match <code>data_type:</code> (int16, uint16, int32, uint32, float32, string…) to the device manual. If floats come back as astronomical numbers, check the byte order too — see our <a href="/modbus-float-wrong-value-byte-order-fix/">float byte-order fix guide</a>.</li>
<li><strong>Holding vs. input mix-up.</strong> QModMaster&#8217;s &#8220;Read Holding Registers&#8221; (FC03) maps to HA <code>input_type: holding</code>; &#8220;Read Input Registers&#8221; (FC04) maps to <code>input_type: input</code>. Reading the wrong table produces exception responses the decoder cannot handle.</li>
<li><strong>Polling too fast.</strong> Some devices drop off the bus if polled aggressively. Start with <code>scan_interval: 30</code> and only speed up once the device proves it tolerates it.</li>
</ul>

<h2 class="wp-block-heading">Minimal working HA modbus config to compare against</h2>

<p class="wp-block-paragraph">Use this as a reference skeleton, then replace every value with what worked in your QModMaster session and your device&#8217;s manual:</p>

<pre class="wp-block-code"><code>modbus:
  - name: hub1
    type: rtuovertcp   # tcp, rtuovertcp, or serial — must match QModMaster's mode
    host: 192.168.1.100
    port: 8899
    sensors:
      - name: "Voltage"
        slave: 1              # = the Unit Identifier that worked in QModMaster
        address: 0
        input_type: input     # input = FC04, holding = FC03
        data_type: float32
        count: 2
        scan_interval: 30
        unit_of_measurement: "V"</code></pre>

<p class="wp-block-paragraph">Key names follow the Home Assistant modbus integration documentation; always double-check them against the HA version you run, since integration options evolve.</p>

<h2 class="wp-block-heading">If it still fails after the config matches</h2>

<ul class="wp-block-list">
<li>Open <strong>Settings → System → Logs</strong> in HA and read the exact frame-level error — it usually names the register or the slave that failed.</li>
<li>Some gateways need a small <code>delay</code> between requests, and some devices need a longer response timeout than HA&#8217;s default.</li>
<li>Capture both directions: compare a Wireshark capture of QModMaster&#8217;s request frame against HA&#8217;s request frame. The first byte that differs is your bug.</li>
</ul>

<p class="wp-block-paragraph">And if you haven&#8217;t done the probe-first workflow yet, start here: <a href="/test-modbus-with-qmodmaster-before-home-assistant/">test your Modbus link with QModMaster before writing the Home Assistant config</a> — five minutes with the GUI saves hours of YAML guessing.</p>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Why does QModMaster read my device fine but Home Assistant says 'No response received'?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A working QModMaster read proves the wiring, gateway, baud rate and slave address are all correct, so the problem is in the Home Assistant modbus configuration. The most common cause is a wrong slave/unit ID in the HA config — it must match the Unit Identifier that worked in QModMaster."
      }
    },
    {
      "@type": "Question",
      "name": "What does 'Unable to decode response' mean in Home Assistant Modbus?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "It usually means the device answered, but Home Assistant could not parse the reply: the count, data_type or input_type (holding vs input registers) in the HA config does not match what the device actually returns. Compare each value against a working QModMaster read."
      }
    },
    {
      "@type": "Question",
      "name": "Which settings must match between QModMaster and Home Assistant?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Connection mode (RTU/TCP), host and port, slave/unit ID, function code mapped to input_type (FC03 = holding, FC04 = input), start address, register count, and data type. Write down the four values from the working QModMaster session and mirror them one by one in the HA YAML."
      }
    }
  ]
}
</script>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list">
<li><a href="/test-modbus-with-qmodmaster-before-home-assistant/">Test Modbus with QModMaster Before Writing Your Home Assistant Config</a></li>
<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows Wrong Value? Fix the Byte Order</a></li>
<li><a href="/usb-to-rs485-adapter-buying-guide/">USB-to-RS485 Adapter Buying Guide</a></li>
<li><a href="/qmodmaster-tutorial/">QModMaster Tutorial: Your First Modbus Read</a></li>
<li><a href="/download/">Download QModMaster</a></li>
</ul>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>QModMaster View Menu: Float/Int/Hex/Binary Explained</title>
		<link>https://qmodmaster.com/qmodmaster-view-menu-data-format-guide/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:16:15 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/qmodmaster-view-menu-data-format-guide/</guid>

					<description><![CDATA[QModMaster View Menu: Float/Int/Hex/Binary Explained The View menu in QModMaster does not change what your device sends — it changes how the same raw bytes are interpreted and displayed. Pick the wrong format and a perfectly healthy reading looks broken; pick the right one and half of all &#8220;wrong value&#8221; mysteries solve themselves. This page...]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">QModMaster View Menu: Float/Int/Hex/Binary Explained</h1>



<p class="wp-block-paragraph">The <strong>View menu</strong> in QModMaster does not change what your device sends — it changes <em>how the same raw bytes are interpreted and displayed</em>. Pick the wrong format and a perfectly healthy reading looks broken; pick the right one and half of all &#8220;wrong value&#8221; mysteries solve themselves. This page is the hub: what each format means, when to use it, and the exact switching sequence to run when a reading looks wrong.</p>



<h2 class="wp-block-heading">What the formats actually do</h2>



<p class="wp-block-paragraph">Every Modbus register is 16 bits. The View menu decides how those bits (and groups of them) are decoded for display:</p>



<ul class="wp-block-list">

<li><strong>Hex (16-bit):</strong> shows each register exactly as it arrived, e.g. <code>0x04D2</code>. This is the <strong>ground truth</strong> — no interpretation, no surprises. Always start here when something looks wrong.</li>



<li><strong>Binary (16-bit):</strong> the same bits as 0s and 1s. Useful when you are debugging individual status flags / bit fields packed into one register.</li>



<li><strong>INT16 / signed 16-bit:</strong> interprets one register as −32,768…32,767. Right for counters and small signed quantities — wrong for anything that exceeds 32,767 (it will flip negative).</li>



<li><strong>UINT16 / unsigned 16-bit:</strong> interprets one register as 0…65,535. Right for raw ADC counts, status words, and protocol fields.</li>



<li><strong>INT32 / UINT32 (32-bit):</strong> combines <em>two consecutive registers</em> into one 32-bit integer. Right for energy totals and large counters — but sensitive to <strong>word order</strong> (ABCD vs CDAB).</li>



<li><strong>Float (32-bit):</strong> combines two consecutive registers and decodes them as an IEEE-754 floating-point number. Right for voltages, temperatures, and power with decimals — but sensitive to <strong>byte order</strong> (four possible orders).</li>

</ul>



<h2 class="wp-block-heading">Which format, when: the cheat sheet</h2>



<ul class="wp-block-list">

<li>Debugging <em>anything</em> and unsure → <strong>Hex</strong>. Read raw first, interpret second.</li>



<li>Status flags, alarms, bit-packed coil images → <strong>Binary</strong> or Hex.</li>



<li>Small counters, setpoints, temperatures as integers → <strong>INT16/UINT16</strong>.</li>



<li>Energy totals (kWh), large counters → <strong>INT32/UINT32</strong>, then check word order.</li>



<li>Voltage, current, power, temperature with decimals → <strong>Float</strong>, then check byte order.</li>

</ul>



<h2 class="wp-block-heading">The &#8220;reading looks wrong&#8221; switching drill</h2>



<p class="wp-block-paragraph">Run this sequence top to bottom. Stop at the first step that explains the value — most cases resolve at step 2 or 3.</p>



<ul class="wp-block-list">

<li><strong>Step 1 — Hex.</strong> Switch to Hex and read the raw register(s). If the raw words already look wrong (all <code>0xFFFF</code>, all zeros, unchanging), the problem is upstream: wiring, address, or slave — not the format.</li>



<li><strong>Step 2 — match the documented type.</strong> Check the device&#8217;s register map: does it say this address is INT16, UINT32, or Float? Set the View format to match <em>exactly</em>. A UINT32 read as INT32 flips negative past 2,147,483,647; a Float read as INT32 is garbage.</li>



<li><strong>Step 3 — test word/byte order.</strong> If a 32-bit integer is ~65,536× off, the words are swapped → <a href="/modbus-32bit-integer-word-swap/">word-swap fix</a>. If a float shows astronomical values, try the other byte orders → <a href="/modbus-float-wrong-value-byte-order-fix/">float byte-order fix</a>.</li>



<li><strong>Step 4 — apply scale and offset.</strong> If the value is off by 10×/100×/1000× or a round constant, it is scaling or an offset → <a href="/modbus-scale-factor-offset-values/">scale factor &amp; offset guide</a>.</li>



<li><strong>Step 5 — verify the address.</strong> If the value is plausible but belongs to a <em>different</em> measurement, you are reading the wrong register: check 0-based vs 1-based addressing in your device&#8217;s manual.</li>

</ul>



<h2 class="wp-block-heading">Common mistakes</h2>



<ul class="wp-block-list">

<li>Reading a <strong>Float register as INT32</strong> (or vice versa) — the two decodings of the same bytes look nothing alike, and both look &#8220;broken.&#8221;</li>



<li>Reading an <strong>unsigned</strong> quantity as signed INT16 — values over 32,767 wrap negative.</li>



<li>Forgetting that 32-bit formats consume <strong>two registers</strong> — if you request only one register and display INT32, the second half is missing.</li>



<li>&#8220;Fixing&#8221; the format when the real problem is the <strong>address</strong> — always confirm raw Hex values against the device&#8217;s own display first.</li>

</ul>



<h2 class="wp-block-heading">Deep dives</h2>



<ul class="wp-block-list">

<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows a Wrong Value? Byte-Order Fix</a> — four byte orders, Schneider&#8217;s official guidance, QModMaster workflow.</li>



<li><a href="/modbus-32bit-integer-word-swap/">Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix</a> — the 65,536× signature and the EM24 little-endian trap.</li>



<li><a href="/modbus-scale-factor-offset-values/">Modbus Values Off by 10x? Scale Factor &amp; Offset</a> — the Deye temperature offset-1000 example and 60-second mental-math check.</li>

</ul>



<h2 class="wp-block-heading">FAQ</h2>



<h3 class="wp-block-heading">Does changing the View menu change what QModMaster requests from the device?</h3>



<p class="wp-block-paragraph">No. The View menu only changes how received bytes are decoded for display. The Modbus request (function code, address, register count) is unaffected.</p>



<h3 class="wp-block-heading">Which View format should I start with when debugging?</h3>



<p class="wp-block-paragraph">Hex. It shows the raw register contents with zero interpretation, so you can tell whether the problem is the data on the wire or merely how it is decoded.</p>



<h3 class="wp-block-heading">Why does my float show a huge wrong number in QModMaster?</h3>



<p class="wp-block-paragraph">Almost always a byte-order mismatch: the device sends the four bytes in a different order than the Float decoder expects. See the <a href="/modbus-float-wrong-value-byte-order-fix/">float byte-order fix</a> for the four orders and how to identify yours.</p>


<script type="application/ld+json">
{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[
{"@type":"Question","name":"Does changing the QModMaster View menu change the Modbus request?","acceptedAnswer":{"@type":"Answer","text":"No. The View menu only changes how received bytes are decoded for display; the Modbus request itself is unaffected."}},
{"@type":"Question","name":"Which QModMaster View format should I use when debugging?","acceptedAnswer":{"@type":"Answer","text":"Start with Hex, which shows raw register contents with zero interpretation, separating wire problems from decoding problems."}},
{"@type":"Question","name":"Why does my float show a huge wrong number in QModMaster?","acceptedAnswer":{"@type":"Answer","text":"Almost always a byte-order mismatch between the device's byte order and the Float decoder's expectation; testing the four byte orders identifies the correct one."}}
]}
</script>


<h2 class="wp-block-heading">Related Guides</h2>



<ul class="wp-block-list">

<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows a Wrong Value? Byte-Order Fix</a></li>



<li><a href="/modbus-32bit-integer-word-swap/">Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix</a></li>



<li><a href="/modbus-scale-factor-offset-values/">Modbus Values Off by 10x? Scale Factor &amp; Offset</a></li>



<li><a href="/download/">Download QModMaster</a> — free, open-source (LGPLv3) Modbus master.</li>

</ul>



<p class="wp-block-paragraph"><em>Learning Modbus data encoding properly pays off on every device you touch: <a href="/go/modbus-book" rel="nofollow">recommended Modbus protocol book</a>.</em></p>


<style>
.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}
.related-guides{margin-top:2.5em;border-top:1px solid #e5e5e5;padding-top:1.5em}
</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Modbus Values Off by 10x? Scale Factor &#038; Offset</title>
		<link>https://qmodmaster.com/modbus-scale-factor-offset-values/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:16:07 +0000</pubDate>
				<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/modbus-scale-factor-offset-values/</guid>

					<description><![CDATA[Modbus Values Off by 10x? Scale Factor &#38; Offset QModMaster shows 2355 but your inverter&#8217;s display says 235.5 V. Or a temperature reads 1025 when the room is clearly 25 °C. Before you blame the wiring, the address, or the byte order — check the two most boring explanations in Modbus: scale factors and offsets....]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">Modbus Values Off by 10x? Scale Factor &amp; Offset</h1>



<p class="wp-block-paragraph">QModMaster shows <strong>2355</strong> but your inverter&#8217;s display says <strong>235.5 V</strong>. Or a temperature reads <strong>1025</strong> when the room is clearly 25 °C. Before you blame the wiring, the address, or the byte order — check the two most boring explanations in Modbus: <strong>scale factors</strong> and <strong>offsets</strong>. They account for a huge share of &#8220;wrong value&#8221; reports, and they are verified with mental math in under a minute.</p>



<h2 class="wp-block-heading">Scale factor: the register holds an integer, the value has decimals</h2>



<p class="wp-block-paragraph">Modbus registers are 16-bit integers — they cannot store a decimal point. So device makers store <strong>235.5 V as the integer 2355</strong> and document a <strong>scale factor of 0.1</strong> (or &#8220;divide by 10&#8221;). Common variants:</p>



<ul class="wp-block-list">

<li><strong>÷ 10</strong> — voltages, currents with one decimal (2355 → 235.5 V).</li>



<li><strong>÷ 100</strong> — two decimals (23550 → 235.50 V).</li>



<li><strong>÷ 1000</strong> — power/energy with three decimals, or millivolt-native sensors.</li>



<li><strong>× 10 / × 100</strong> — the reverse: some devices store a multiplied value (rare, but documented in a few meter maps).</li>

</ul>



<p class="wp-block-paragraph">The scale factor is always in the device&#8217;s <strong>register map / protocol document</strong> — look for columns labeled &#8220;scale,&#8221; &#8220;factor,&#8221; &#8220;multiplier,&#8221; &#8220;gain,&#8221; or a unit like &#8220;0.1 V&#8221;. If your reading is off by <em>exactly</em> 10×, 100×, or 1000×, scaling is guilty until proven innocent.</p>



<h2 class="wp-block-heading">Offset: the register value is shifted by a constant</h2>



<p class="wp-block-paragraph">Some devices add a fixed offset so that an unsigned register can represent a signed quantity. The documented real-world example is <strong>Deye inverters</strong>: certain temperature registers carry an <strong>offset of 1000</strong>, i.e.</p>



<p class="wp-block-paragraph"><code>actual temperature = raw register value − 1000</code></p>



<p class="wp-block-paragraph">So a raw reading of <strong>1025</strong> means <strong>25 °C</strong>, and a raw reading of <strong>985</strong> means <strong>−15 °C</strong> — the offset lets the unsigned register express temperatures below zero. If your temperature is off by a suspiciously round constant (not a round <em>multiple</em>), look for an &#8220;offset&#8221; column in the register map.</p>



<h2 class="wp-block-heading">The 60-second verification in QModMaster</h2>



<ul class="wp-block-list">

<li><strong>Step 1 — read raw.</strong> In QModMaster, read the register with a plain integer View format (no float interpretation yet). Write down the raw integer.</li>



<li><strong>Step 2 — divide first.</strong> Divide the raw value by 10, 100, and 1000 in your head. Does one of the results exactly match the device&#8217;s own display? Then you have found the scale factor.</li>



<li><strong>Step 3 — subtract second.</strong> If division does not fit but the value is off by a round <em>constant</em>, subtract candidate offsets (1000 is the classic for temperatures). A raw 1025 → 25 °C after −1000 confirms the offset.</li>



<li><strong>Step 4 — confirm in the manual.</strong> Find the scale/offset columns in the official register map and note them next to the address in your own notes. <strong>Always let the device manual win</strong> over any rule of thumb on this page.</li>

</ul>



<h2 class="wp-block-heading">Telling scaling apart from byte-order problems</h2>



<ul class="wp-block-list">

<li>Off by <strong>10× / 100× / 1000×</strong> → scale factor (this page).</li>



<li>Off by a round <strong>constant</strong> (e.g. always 1000 too high) → offset (this page).</li>



<li>Off by <strong>65,536×</strong> → word swap: <a href="/modbus-32bit-integer-word-swap/">Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix</a>.</li>



<li>Float showing <strong>astronomical garbage</strong> → byte order: <a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows a Wrong Value? Byte-Order Fix</a>.</li>



<li>Reading a <strong>completely different register&#8217;s</strong> value → address off-by-one: check your device&#8217;s 0-based vs 1-based addressing.</li>

</ul>



<h2 class="wp-block-heading">FAQ</h2>



<h3 class="wp-block-heading">Why does my Modbus reading show 2355 instead of 235.5?</h3>



<p class="wp-block-paragraph">Modbus registers hold integers only, so the device stores 235.5 V as 2355 with a documented scale factor of 0.1. Divide the raw value by 10. The scale factor is listed in the device&#8217;s register map.</p>



<h3 class="wp-block-heading">What is the Deye temperature offset of 1000?</h3>



<p class="wp-block-paragraph">Certain Deye inverter temperature registers add an offset of 1000 so an unsigned register can represent negative temperatures: actual °C = raw value − 1000. A raw reading of 1025 means 25 °C.</p>



<h3 class="wp-block-heading">How do I know whether it&#8217;s scale, offset, or byte order?</h3>



<p class="wp-block-paragraph">Divide the raw value by 10/100/1000 — an exact match means scaling. If it is off by a round constant, suspect an offset. If it is off by 65,536× or shows garbage floats, it is a word/byte-order problem instead.</p>


<script type="application/ld+json">
{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[
{"@type":"Question","name":"Why does my Modbus reading show 2355 instead of 235.5?","acceptedAnswer":{"@type":"Answer","text":"Modbus registers hold integers only, so the device stores 235.5 V as 2355 with a documented scale factor of 0.1. Divide the raw value by 10; the scale factor is listed in the device's register map."}},
{"@type":"Question","name":"What is the Deye inverter temperature offset of 1000?","acceptedAnswer":{"@type":"Answer","text":"Certain Deye inverter temperature registers add an offset of 1000 so an unsigned register can represent negative temperatures: actual temperature in °C equals the raw value minus 1000."}},
{"@type":"Question","name":"How do I tell scaling apart from byte-order problems in Modbus?","acceptedAnswer":{"@type":"Answer","text":"Off by 10x/100x/1000x means a scale factor; off by a round constant means an offset; off by 65536x means word swap; garbage float values mean byte-order problems."}}
]}
</script>


<h2 class="wp-block-heading">Related Guides</h2>



<ul class="wp-block-list">

<li><a href="/modbus-32bit-integer-word-swap/">Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix</a> — when the error is 65,536×, not 10×.</li>



<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows a Wrong Value? Byte-Order Fix</a> — garbage floats, four byte orders.</li>



<li><a href="/qmodmaster-view-menu-data-format-guide/">QModMaster View Menu: Float/Int/Hex/Binary Explained</a> — pick the right display format first.</li>



<li><a href="/download/">Download QModMaster</a> — free, open-source (LGPLv3) Modbus master.</li>

</ul>



<p class="wp-block-paragraph"><em>Want the full encoding story? The <a href="/go/modbus-book" rel="nofollow">Modbus protocol book</a> covers scaling, offsets, and data representation in one place.</em></p>


<style>
.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}
.related-guides{margin-top:2.5em;border-top:1px solid #e5e5e5;padding-top:1.5em}
</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Arduino + MAX485 Timeout? DE/RE Control Fix</title>
		<link>https://qmodmaster.com/arduino-max485-modbus-timeout-fix/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:16:03 +0000</pubDate>
				<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/arduino-max485-modbus-timeout-fix/</guid>

					<description><![CDATA[Arduino + MAX485 Timeout? DE/RE Control Fix Here&#8217;s the classic maker trap: your Arduino Modbus slave sketch answers perfectly when the PC talks to it over a USB-to-TTL cable — every read in QModMaster succeeds. Then you swap in a MAX485 module for real RS485, and QModMaster just says timeout, no response. The sketch didn&#8217;t...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">Arduino + MAX485 Timeout? DE/RE Control Fix</h1>

<p class="wp-block-paragraph">Here&#8217;s the classic maker trap: your Arduino Modbus slave sketch answers perfectly when the PC talks to it over a USB-to-TTL cable — every read in QModMaster succeeds. Then you swap in a MAX485 module for real RS485, and QModMaster just says <strong>timeout, no response</strong>. The sketch didn&#8217;t change. The slave ID didn&#8217;t change. What changed is the physics of the bus — and the fix is two wires. This exact failure was reported on the <a href="https://forum.arduino.cc/t/modbus-slaves-with-arduino/146650" rel="nofollow noopener" target="_blank">Arduino Forum</a> (a user&#8217;s slave worked via USB but timed out over a MAX485 module), and the diagnosis there is still the right one: <strong>it&#8217;s the MAX485 transceiver direction control — the DE/RE pins</strong>.</p>

<h2 class="wp-block-heading">Why USB works and MAX485 doesn&#8217;t</h2>

<p class="wp-block-paragraph">A USB-to-TTL cable is full-duplex: transmit and receive have their own wires, so the Arduino can listen and talk at the same time. RS485 is <strong>half-duplex</strong>: the A/B pair is shared, and the MAX485 chip needs to be told which direction it&#8217;s going. That&#8217;s what the <strong>DE</strong> (Driver Enable, transmit) and <strong>RE</strong> (Receiver Enable, receive) pins do:</p>

<ul class="wp-block-list"><li><strong>DE = HIGH:</strong> the MAX485 drives the bus — the Arduino is <em>transmitting</em>.</li><li><strong>DE = LOW (RE = LOW):</strong> the MAX485 listens — the Arduino is <em>receiving</em>.</li></ul>

<p class="wp-block-paragraph">If DE/RE are left floating, tied to the wrong level, or toggled by a library that doesn&#8217;t wait for transmission to finish, the Arduino&#8217;s reply never actually makes it onto the bus — and QModMaster sees a timeout. Per the forum diagnosis, the library must hold the MAX485 in transmit mode <em>for the whole time the reply is being sent</em>; simply pushing bytes into the serial buffer and flipping back to receive too early is enough to break it.</p>

<h2 class="wp-block-heading">The wiring (text diagram)</h2>

<p class="wp-block-paragraph">Wire DE and RE <strong>together</strong> to one Arduino digital pin (D2 is the common choice). One pin then controls the direction: HIGH = transmit, LOW = receive.</p>

<pre class="wp-block-code"><code>MAX485 module          Arduino
-----------          -------
  VCC        ----    5V
  GND        ----    GND
  DI         ----    TX  (Arduino transmit → MAX485 data in)
  RO         ----    RX  (MAX485 data out → Arduino receive)
  DE + RE    ----    D2  (tied together; direction control pin)
  A          ----    RS485 bus A
  B          ----    RS485 bus B

  120 Ω resistor across A–B at EACH END of the bus (termination)</code></pre>

<p class="wp-block-paragraph">Two practical notes: on an Arduino Uno the hardware serial port is shared with USB, so use a software serial port for the MAX485 side and keep hardware serial free for USB debugging. And A/B are differential — if everything is wired right but you still get timeouts, try swapping A and B once (a reversed pair fails silently).</p>

<h2 class="wp-block-heading">The code fix: drive the direction pin properly</h2>

<p class="wp-block-paragraph">Your Modbus library must know about the direction pin and hold it HIGH for the <em>entire</em> reply transmission — including waiting for the last byte to physically leave the UART — before dropping back to receive. Libraries built for RS485 expose this as a &#8220;TX enable pin&#8221; setting or pre/post-transmission callbacks. If your current library has no direction-pin support at all, that&#8217;s your answer: switch to one that does, set the TX enable pin to D2 (or whichever pin you wired), and retest. Don&#8217;t try to toggle the pin manually around library calls — the timing (waiting for the transmit buffer to fully drain) is exactly what goes wrong.</p>

<h2 class="wp-block-heading">QModMaster-side checklist</h2>

<p class="wp-block-paragraph">Once DE/RE is wired and the library handles it, verify from the PC side:</p>

<ul class="wp-block-list"><li><strong>Slave ID</strong> in QModMaster must match the ID in the sketch.</li><li><strong>9600 8N1 on both ends</strong> — QModMaster&#8217;s serial options and the sketch&#8217;s baud rate must agree.</li><li><strong>Read one register first.</strong> A single-register read is the smallest possible transaction; get that working before scanning ranges.</li><li><strong>No duplicate slave IDs</strong> on the bus — two devices answering the same ID produces intermittent garbage, not clean timeouts, but rule it out anyway.</li><li><strong>Termination:</strong> 120 Ω across A–B at both bus ends. Missing termination mostly bites on longer runs.</li></ul>

<h2 class="wp-block-heading">The adapter for the PC side</h2>

<p class="wp-block-paragraph"><a href="https://qmodmaster.com/go/usb-rs485" rel="nofollow sponsored">USB-to-RS485 adapter (Amazon)</a> — your PC needs one to join the RS485 bus at all. Pick an FTDI-based adapter; this is the page where a flaky adapter will waste the most of your time, because its symptoms look exactly like the DE/RE problem above.</p>

<h2 class="wp-block-heading">FAQ</h2>

<p class="wp-block-paragraph"><strong>My Arduino Modbus slave works over USB-to-TTL but times out with MAX485. What&#8217;s wrong?</strong><br>The DE/RE direction pins. USB-to-TTL is full-duplex and needs no direction control; RS485 is half-duplex, and if the MAX485 isn&#8217;t held in transmit mode for the whole reply, the response never reaches the bus.</p>

<p class="wp-block-paragraph"><strong>Can I just tie DE high and RE low permanently?</strong><br>No — then the module transmits constantly and can never receive the master&#8217;s request. DE and RE must be tied together to a GPIO and driven HIGH only while transmitting, LOW while receiving.</p>

<p class="wp-block-paragraph"><strong>I fixed DE/RE and still get timeouts. What next?</strong><br>Verify the slave ID matches the sketch, 9600 8N1 on both sides, try swapping A/B once, and confirm the library waits for the UART transmit buffer to drain before dropping DE back to receive. Then try a single-register read in QModMaster.</p>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list"><li><a href="https://qmodmaster.com/qmodmaster-tutorial/">QModMaster tutorial: your first register read</a></li><li><a href="https://qmodmaster.com/usb-to-rs485-adapter-buying-guide/">USB-to-RS485 adapter buying guide</a></li></ul>

<p class="wp-block-paragraph"><em>The USB-works/MAX485-times-out symptom and the transceiver-control diagnosis come from a real Arduino Forum thread (&#8220;MODBUS Slaves with Arduino&#8221;). Pin choices (D2) and wiring conventions are standard maker practice — adapt to your board and library. qmodmaster.com is an independent community resource for the upstream QModMaster project (LGPLv3) and is not affiliated with Arduino.</em></p>

<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"My Arduino Modbus slave works over USB-to-TTL but times out with MAX485. What is wrong?","acceptedAnswer":{"@type":"Answer","text":"The DE/RE direction pins. USB-to-TTL is full-duplex and needs no direction control; RS485 is half-duplex, and if the MAX485 is not held in transmit mode for the whole reply, the response never reaches the bus and QModMaster times out."}},{"@type":"Question","name":"Can I just tie MAX485 DE high and RE low permanently?","acceptedAnswer":{"@type":"Answer","text":"No. Then the module transmits constantly and can never receive the master's request. Tie DE and RE together to a GPIO pin and drive it HIGH only while transmitting, LOW while receiving."}},{"@type":"Question","name":"I fixed DE/RE on my Arduino MAX485 setup and still get timeouts. What next?","acceptedAnswer":{"@type":"Answer","text":"Verify the slave ID matches the sketch, 9600 8N1 on both sides, try swapping A and B once, and confirm the library waits for the UART transmit buffer to drain before dropping DE back to receive. Then try a single-register read in QModMaster."}}]}</script>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Solis Inverter Modbus: Register Offset Trap</title>
		<link>https://qmodmaster.com/solis-inverter-modbus-register-offset/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:16:01 +0000</pubDate>
				<category><![CDATA[Hardware & Devices]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/solis-inverter-modbus-register-offset/</guid>

					<description><![CDATA[Solis Inverter Modbus: Register Offset Trap You&#8217;ve got your Solis inverter wired to a USB-to-RS485 adapter, QModMaster is talking to it (wrong slave address gives timeouts, the right one answers) — but every register read comes back Exception Code 02: Illegal Address. The wiring is fine, the baud rate is fine, and the slave ID...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">Solis Inverter Modbus: Register Offset Trap</h1>

<p class="wp-block-paragraph">You&#8217;ve got your Solis inverter wired to a USB-to-RS485 adapter, QModMaster is talking to it (wrong slave address gives timeouts, the right one answers) — but every register read comes back <strong>Exception Code 02: Illegal Address</strong>. The wiring is fine, the baud rate is fine, and the slave ID is right. The trap is in the register address itself, and it&#8217;s documented by a real Solis owner&#8217;s debugging session on the <a href="https://diysolarforum.com/threads/solis-ginlong-modbus-comms.47711/" rel="nofollow noopener" target="_blank">DIY Solar Forum</a>: <strong>Solis&#8217;s official documentation lists register addresses like 33025 with the note &#8220;no further offset or other conversion is required&#8221; — and it means it literally. Type the full address.</strong></p>

<h2 class="wp-block-heading">The trap: 33025 means 33025, not 3025</h2>

<p class="wp-block-paragraph">Most Modbus tools and tutorials teach you to strip the leading digit off 3xxxx/4xxxx addresses: &#8220;input register 33025&#8221; becomes protocol address 3024 (or 3025, depending on the tool&#8217;s convention). For Solis inverters, that habit breaks everything. The forum poster (RHI-5K-48ES-5G) got Illegal Address errors on every read until he typed the complete address: <strong>a 3-register read of 33025–33027 immediately returned a live hh:mm:ss clock value from the inverter</strong>.</p>

<p class="wp-block-paragraph">So in QModMaster: enter <code>33025</code> in the address field — don&#8217;t subtract 1, don&#8217;t strip the leading 3, don&#8217;t convert. If the manual&#8217;s address table says 33000, you read 33000. Trust the manual&#8217;s literal numbers.</p>

<h2 class="wp-block-heading">Baseline settings that must be right first</h2>

<p class="wp-block-paragraph">From the same real-world session, the working baseline for talking to a Solis inverter over its COM connector:</p>

<ul class="wp-block-list"><li><strong>Mode:</strong> Modbus RTU over RS485 (2-core cable to the COM connector&#8217;s A/B pins).</li><li><strong>Serial:</strong> 9600 bps, 8 data bits, 1 stop bit, no parity (8N1).</li><li><strong>Slave address:</strong> must match the address set on the inverter itself. A wrong slave ID gives timeouts; the right ID with a wrong register gives Illegal Address — that difference is actually a useful diagnostic.</li><li><strong>Function code:</strong> 0x04 (Read Input Registers) for the 3xxxx measurement registers.</li></ul>

<p class="wp-block-paragraph"><strong>Always confirm these against your own Solis manual</strong> — settings and pinouts can vary between models and firmware generations.</p>

<h2 class="wp-block-heading">Watch the byte order on multi-register values</h2>

<p class="wp-block-paragraph">The forum session also surfaced a second quirk: some multi-byte values came back looking byte-swapped until interpreted the other way round (the poster saw an unfeasibly large decimal where a small value was expected, and the swap theory led to the breakthrough). If your single-register reads are fine but 32-bit values look wrong, try the swapped byte/word interpretation in QModMaster&#8217;s View menu before assuming the address is wrong — and cross-check the expected byte order in your Solis documentation.</p>

<h2 class="wp-block-heading">The hardware you need</h2>

<p class="wp-block-paragraph"><a href="https://qmodmaster.com/go/usb-rs485" rel="nofollow sponsored">USB-to-RS485 adapter (Amazon)</a> — the forum poster&#8217;s setup used a USB-RS485 serial adapter straight to a laptop. A dependable FTDI-based adapter is the safest first purchase; unstable adapters mimic the exact &#8220;timeout vs Illegal Address&#8221; confusion this page helps you avoid.</p>

<h2 class="wp-block-heading">FAQ</h2>

<p class="wp-block-paragraph"><strong>QModMaster says &#8220;Illegal Address&#8221; on my Solis inverter but the wiring seems fine. What&#8217;s wrong?</strong><br>Almost certainly the address format: type the full address from the Solis manual (e.g. 33025), not a stripped or minus-1 variant. The official Solis documentation states no offset or conversion is required — take it literally.</p>

<p class="wp-block-paragraph"><strong>How do I tell a wiring problem from an addressing problem?</strong><br>Change the slave address to a wrong value: timeouts mean the wiring/serial settings are wrong; the correct slave ID with wrong register addresses gives Illegal Address (exception 02). That distinction tells you which half of the setup to fix.</p>

<p class="wp-block-paragraph"><strong>My 32-bit Solis values are huge nonsense numbers. Offset problem?</strong><br>Probably not an offset — single registers reading fine points to byte/word order instead. Try the swapped interpretation in QModMaster&#8217;s View menu and verify against your manual.</p>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list"><li><a href="https://qmodmaster.com/qmodmaster-tutorial/">QModMaster tutorial: your first register read</a></li><li><a href="https://qmodmaster.com/usb-to-rs485-adapter-buying-guide/">USB-to-RS485 adapter buying guide</a></li></ul>

<p class="wp-block-paragraph"><em>The full-address finding (33025–33027 returning live data) comes from a real owner&#8217;s debugging thread on the DIY Solar Forum (Solis/Ginlong Modbus Comms). Solis register tables, serial settings, and pinouts vary by model — always confirm against your own inverter&#8217;s manual. qmodmaster.com is an independent community resource for the upstream QModMaster project (LGPLv3) and is not affiliated with Solis.</em></p>

<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"QModMaster says Illegal Address on my Solis inverter but the wiring seems fine. What is wrong?","acceptedAnswer":{"@type":"Answer","text":"Almost certainly the address format: type the full address from the Solis manual (for example 33025), not a stripped or minus-1 variant. The official Solis documentation states no offset or conversion is required."}},{"@type":"Question","name":"How do I tell a Solis wiring problem from an addressing problem?","acceptedAnswer":{"@type":"Answer","text":"Set a wrong slave address: timeouts indicate a wiring or serial-settings problem, while the correct slave ID with wrong register addresses returns Illegal Address (exception 02). That distinction tells you which half of the setup to fix."}},{"@type":"Question","name":"My 32-bit Solis values are huge nonsense numbers. Is it an offset problem?","acceptedAnswer":{"@type":"Answer","text":"If single registers read fine, it is more likely byte or word order than an offset. Try the swapped interpretation in QModMaster's View menu and verify the expected byte order against your manual."}}]}</script>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Read Carlo Gavazzi EM24 with QModMaster (Watch the Word Order!)</title>
		<link>https://qmodmaster.com/carlo-gavazzi-em24-qmodmaster/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:15:59 +0000</pubDate>
				<category><![CDATA[Hardware & Devices]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/carlo-gavazzi-em24-qmodmaster/</guid>

					<description><![CDATA[Read Carlo Gavazzi EM24 with QModMaster (Watch the Word Order!) You&#8217;ve got the Carlo Gavazzi EM24 energy meter wired up, QModMaster returns registers without errors — and the numbers are nonsense. Voltage reads as millions of volts, or the power figure is off by a factor of 65,536. Before you rewire anything: the EM24 uses...]]></description>
										<content:encoded><![CDATA[<h1 class="wp-block-heading">Read Carlo Gavazzi EM24 with QModMaster (Watch the Word Order!)</h1>

<p class="wp-block-paragraph">You&#8217;ve got the Carlo Gavazzi EM24 energy meter wired up, QModMaster returns registers without errors — and the numbers are nonsense. Voltage reads as millions of volts, or the power figure is off by a factor of 65,536. Before you rewire anything: <strong>the EM24 uses little-endian word order (low word at the lower address)</strong>, the opposite of what most Modbus devices use. That single reversed assumption is the #1 cause of wrong EM24 readings, and it&#8217;s documented in the EM24 register-map reference used by the <a href="https://github.com/remcom/victron-grid-meter-esphome" rel="nofollow noopener" target="_blank">victron-grid-meter-esphome project</a>, which emulates an EM24 over Modbus TCP: <em>&#8220;All multi-register values use little-endian word order (low word at lower address)&#8221;</em>.</p>

<h2 class="wp-block-heading">What &#8220;little-endian word order&#8221; means in practice</h2>

<p class="wp-block-paragraph">A 32-bit value spans two 16-bit registers. On most devices the <em>high</em> word sits at the lower address (big-endian words: high word first). On the EM24 it&#8217;s flipped — the <em>low</em> word comes first:</p>

<pre class="wp-block-code"><code>Registers at 0x0000, 0x0001 hold a 32-bit voltage value
  0x0000 = LOW word    (EM24: low word at lower address)
  0x0001 = HIGH word

  value = LOW + HIGH × 65536        (then apply the scale)

Wrong assumption (big-endian words):
  value = HIGH + LOW × 65536        → garbage / millions</code></pre>

<p class="wp-block-paragraph">So if you decode EM24 registers the &#8220;normal&#8221; way, every 32-bit reading — voltage, current, power, energy — comes out wrong. It&#8217;s not a wiring problem and it&#8217;s not a bad meter. It&#8217;s the word order.</p>

<h2 class="wp-block-heading">Step 1: Prove your link with the Model ID register</h2>

<p class="wp-block-paragraph">Before touching multi-register values, read a single 16-bit register that has a known answer. The EM24 register map lists <strong>address 0x000B as the Model ID</strong>, which should read <strong>1648</strong> (EM24DINAV23XE1X). In QModMaster:</p>

<ul class="wp-block-list"><li>Function code 0x03 or 0x04 (the EM24 map supports both for reads), Unit ID matching your meter&#8217;s slave address.</li><li>Read <strong>1 register at address 0x000B</strong>.</li><li>Expect <strong>1648</strong>. If you get it, your link, baud rate, and addressing are all correct — anything weird after this point is data interpretation, not communication.</li></ul>

<h2 class="wp-block-heading">Step 2: Read voltage and test both word orders</h2>

<p class="wp-block-paragraph">Now read <strong>2 registers starting at 0x0000</strong> (Voltage L1, int32, scale ÷10 V) and display them as raw hex (QModMaster&#8217;s View menu lets you switch the display format). Then decode both ways by hand:</p>

<pre class="wp-block-code"><code>Example: registers read back as 0x0000 = 0x08FC, 0x0001 = 0x0000

Little-endian words (correct for EM24):
  value = 0x08FC + 0x0000 × 65536 = 2300  →  2300 ÷ 10 = 230.0 V  ✓

Big-endian words (wrong for EM24):
  value = 0x0000 + 0x08FC × 65536 = 587,202,560  → garbage  ✗</code></pre>

<p class="wp-block-paragraph">Whichever decoding matches your multimeter / the meter display is your answer. For the EM24, it will be the little-endian one. Apply the same low-word-first rule to every 32-bit register.</p>

<h2 class="wp-block-heading">EM24 register map (Ethernet model, excerpt)</h2>

<p class="wp-block-paragraph">From the community-documented EM24 register map — <strong>confirm every address against your own Carlo Gavazzi manual</strong>, as variants differ:</p>

<figure class="wp-block-table"><table><thead><tr><th>Address</th><th>Field</th><th>Type</th><th>Scale</th></tr></thead><tbody><tr><td>0x0000–0x0001</td><td>Voltage L1</td><td>int32</td><td>÷10 V</td></tr><tr><td>0x000B</td><td>Model ID</td><td>uint16</td><td>expect 1648</td></tr><tr><td>0x000C–0x000D</td><td>Current L1</td><td>int32</td><td>÷1000 A</td></tr><tr><td>0x0012–0x0013</td><td>Active power L1</td><td>int32</td><td>÷10 W (positive = import)</td></tr><tr><td>0x0028–0x0029</td><td>Total active power</td><td>int32</td><td>÷10 W</td></tr><tr><td>0x0033</td><td>Frequency</td><td>uint16</td><td>÷10 Hz</td></tr><tr><td>0x0034–0x0035</td><td>Energy import total</td><td>int32</td><td>÷10 kWh</td></tr></tbody></table></figure>

<p class="wp-block-paragraph">Per-phase registers step by 2 per phase: L1 at the base address, L2 at base+2, L3 at base+4. Power is signed (negative = exporting); current is always a positive magnitude with direction taken from the power sign.</p>

<h2 class="wp-block-heading">Wiring the meter to your PC</h2>

<p class="wp-block-paragraph"><a href="https://qmodmaster.com/go/usb-rs485" rel="nofollow sponsored">USB-to-RS485 adapter (Amazon)</a> — to read an EM24 over its serial port you&#8217;ll need a USB-to-RS485 adapter on the PC side. Get an FTDI-based one; flaky adapters are the classic source of intermittent Modbus timeouts.</p>

<h2 class="wp-block-heading">FAQ</h2>

<p class="wp-block-paragraph"><strong>My EM24 voltage reads in the millions. Is the meter broken?</strong><br>No — you&#8217;re decoding with big-endian word order. The EM24 puts the low word first. Re-decode as low + high × 65536 and the value will snap to something sensible.</p>

<p class="wp-block-paragraph"><strong>How do I confirm my communication settings are right before worrying about word order?</strong><br>Read address 0x000B (Model ID). It should return 1648 on an EM24DINAV23XE1X. If it does, your link is fine and any wrong values are an interpretation problem.</p>

<p class="wp-block-paragraph"><strong>Does the word order apply to energy registers too?</strong><br>Yes — every multi-register (32-bit) value on the EM24 uses little-endian word order, including power and energy. Single 16-bit registers (like 0x000B and 0x0033) are unaffected.</p>

<h2 class="wp-block-heading">Related Guides</h2>

<ul class="wp-block-list"><li><a href="https://qmodmaster.com/qmodmaster-tutorial/">QModMaster tutorial: your first register read</a></li><li><a href="https://qmodmaster.com/usb-to-rs485-adapter-buying-guide/">USB-to-RS485 adapter buying guide</a></li></ul>

<p class="wp-block-paragraph"><em>The little-endian word order and register map above are documented in the remcom/victron-grid-meter-esphome project (an EM24 Modbus TCP emulation whose register table mirrors the meter). Register addresses, scales, and word order can vary between EM24 variants — always confirm against your Carlo Gavazzi manual. qmodmaster.com is an independent community resource for the upstream QModMaster project (LGPLv3) and is not affiliated with Carlo Gavazzi.</em></p>

<script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"My EM24 voltage reads in the millions. Is the meter broken?","acceptedAnswer":{"@type":"Answer","text":"No. You are decoding with big-endian word order, but the EM24 puts the low word at the lower address. Re-decode as low_word + high_word × 65536, then apply the scale, and the value will be sensible."}},{"@type":"Question","name":"How do I confirm my EM24 communication settings before worrying about word order?","acceptedAnswer":{"@type":"Answer","text":"Read address 0x000B (Model ID). It should return 1648 on an EM24DINAV23XE1X. If it does, your link is fine and any wrong values are a data-interpretation problem, not communication."}},{"@type":"Question","name":"Does the EM24 word order apply to energy registers too?","acceptedAnswer":{"@type":"Answer","text":"Yes. Every multi-register 32-bit value on the EM24 uses little-endian word order, including power and energy. Single 16-bit registers like 0x000B (Model ID) and 0x0033 (frequency) are unaffected."}}]}</script>

<style>.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}</style>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix</title>
		<link>https://qmodmaster.com/modbus-32bit-integer-word-swap/</link>
		
		<dc:creator><![CDATA[Admin]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 03:15:59 +0000</pubDate>
				<category><![CDATA[Troubleshooting]]></category>
		<guid isPermaLink="false">https://qmodmaster.com/modbus-32bit-integer-word-swap/</guid>

					<description><![CDATA[Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix Your energy meter says it exported 1,234 kWh, but QModMaster shows 80,889,344. Or a counter reads fine until it crosses 32,767 and suddenly goes negative. If the raw registers look plausible but the 32-bit value is exactly 65,536× too big (or the sign flips), you are looking...]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading">Modbus 32-bit Integer Wrong? Word Swap (CDAB) Fix</h1>



<p class="wp-block-paragraph">Your energy meter says it exported <strong>1,234 kWh</strong>, but QModMaster shows <strong>80,889,344</strong>. Or a counter reads fine until it crosses 32,767 and suddenly goes negative. If the raw registers look plausible but the 32-bit value is exactly <strong>65,536× too big</strong> (or the sign flips), you are looking at a <strong>word-swap</strong> problem: your device sends the two 16-bit words in the opposite order from what your display format expects.</p>



<h2 class="wp-block-heading">ABCD vs CDAB: what &#8220;word order&#8221; means</h2>



<p class="wp-block-paragraph">A 32-bit integer occupies two consecutive 16-bit Modbus registers. Call the register at the lower address the <strong>high word (AB)</strong> and the next one the <strong>low word (CD)</strong>. Two conventions exist:</p>



<ul class="wp-block-list">

<li><strong>Big-endian words (ABCD):</strong> high word first, then low word. This is the Modbus &#8220;default&#8221; most devices and software assume. Value = <code>high × 65536 + low</code>.</li>



<li><strong>Little-endian words (CDAB):</strong> low word first, then high word. Some devices — the Carlo Gavazzi EM24 energy meter is a well-documented example — transmit multi-register values this way.</li>

</ul>



<p class="wp-block-paragraph"><strong>Worked example.</strong> Suppose the true value is <strong>1,234</strong>, stored as high word = 0, low word = 1234:</p>



<ul class="wp-block-list">

<li>Read as ABCD (correct): 0 × 65536 + 1234 = <strong>1,234</strong> ✓</li>



<li>Read as CDAB-interpreted-as-ABCD (wrong): 1234 × 65536 + 0 = <strong>80,889,344</strong> ✗ — exactly 65,536× too large.</li>

</ul>



<p class="wp-block-paragraph">That 65,536× signature is the giveaway. (And if the value only goes wrong past 32,767 — flipping negative — you are likely reading an unsigned 32-bit value as <em>signed</em> INT32, which is the signed/unsigned half of the same family of problems.)</p>



<h2 class="wp-block-heading">Diagnose it in QModMaster (2 minutes)</h2>



<ul class="wp-block-list">

<li><strong>Step 1 — read the raw words.</strong> Set QModMaster&#8217;s View menu to a plain 16-bit format (Hex or INT16) and read the two registers. Write down both words, e.g. <code>0x0000</code> and <code>0x04D2</code>.</li>



<li><strong>Step 2 — switch to 32-bit.</strong> Change the View menu format to <strong>INT32 / unsigned 32-bit</strong> and read the same pair. If the displayed value is ~65,536× your expected value, the words are swapped relative to what the format expects.</li>



<li><strong>Step 3 — verify by swapping.</strong> Reconstruct it by hand: treat the <em>second</em> word as the high word. In the example: high = 0x0000, low = 0x04D2 → 0 × 65536 + 1234 = <strong>1234</strong>. If the hand-swapped value matches your meter&#8217;s display, you have confirmed CDAB word order.</li>



<li><strong>Step 4 — check the manual.</strong> Look for &#8220;word order,&#8221; &#8220;byte order,&#8221; &#8220;little-endian,&#8221; or &#8220;low word first&#8221; in your device&#8217;s Modbus register map. EM24 documentation, for instance, explicitly states little-endian word order for multi-register values.</li>

</ul>



<h2 class="wp-block-heading">The EM24 counter-example (little-endian in the wild)</h2>



<p class="wp-block-paragraph">The Carlo Gavazzi EM24 is the classic trap: most of the Modbus world defaults to big-endian words, but the EM24 transmits multi-register values <strong>low word first</strong>. Community integrations (e.g. ESPHome-based EM24 grid-meter projects) document this explicitly — you must swap the words before interpreting. If your EM24 energy totals are exactly 65,536× off in QModMaster, do not touch your wiring: it is the word order, and the device manual agrees with the &#8220;wrong&#8221; reading.</p>



<h2 class="wp-block-heading">Word swap vs byte swap vs float problems</h2>



<ul class="wp-block-list">

<li><strong>Word swap (this page):</strong> 32-bit <em>integers</em> off by exactly 65,536×, or sign flips. Fix = swap the two 16-bit words.</li>



<li><strong>Byte swap:</strong> 16-bit values that look like garbage (e.g. 0x1234 read as 0x3412). Fix = swap bytes within each word. Different problem, different fix.</li>



<li><strong>Float byte order:</strong> 32-bit <em>floats</em> showing astronomical or garbage values. Same family, but floats have four possible byte orders (ABCD, BADC, CDAB, DCBA) — covered in <a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows a Wrong Value? Byte-Order Fix</a>.</li>

</ul>



<h2 class="wp-block-heading">FAQ</h2>



<h3 class="wp-block-heading">Why is my Modbus 32-bit value exactly 65536 times too big?</h3>



<p class="wp-block-paragraph">Because the device sends the two 16-bit words low-word-first (CDAB) while your software interprets them high-word-first (ABCD). The low word gets multiplied by 65,536 instead of the high word. Swap the words and the value will be correct.</p>



<h3 class="wp-block-heading">How do I swap words in QModMaster?</h3>



<p class="wp-block-paragraph">Read the two registers in a 16-bit View format (Hex), note both words, then reconstruct the value treating the second word as the high word. Alternatively switch the View format between 32-bit variants and compare against the device&#8217;s own display to identify which interpretation matches.</p>



<h3 class="wp-block-heading">Is the EM24 really little-endian?</h3>



<p class="wp-block-paragraph">Yes — the Carlo Gavazzi EM24 transmits multi-register values low word first, contrary to the Modbus big-endian default. This is documented in the EM24 register documentation and in community integration projects. A 65,536× error on an EM24 is expected behavior, not a fault.</p>


<script type="application/ld+json">
{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[
{"@type":"Question","name":"Why is my Modbus 32-bit integer exactly 65536 times too big?","acceptedAnswer":{"@type":"Answer","text":"The device sends the two 16-bit words low-word-first (CDAB) while the software interprets them high-word-first (ABCD), so the low word is multiplied by 65536. Swapping the words fixes the value."}},
{"@type":"Question","name":"What is CDAB vs ABCD word order in Modbus?","acceptedAnswer":{"@type":"Answer","text":"ABCD (big-endian words) puts the high 16-bit word at the lower register address; CDAB (little-endian words) puts the low word first. The Modbus default is ABCD, but devices like the Carlo Gavazzi EM24 use CDAB."}},
{"@type":"Question","name":"How do I check word order in QModMaster?","acceptedAnswer":{"@type":"Answer","text":"Read the register pair in a 16-bit View format (Hex), note both words, then reconstruct the 32-bit value treating the second word as the high word. If it matches the device display, the device uses CDAB word order."}}
]}
</script>


<h2 class="wp-block-heading">Related Guides</h2>



<ul class="wp-block-list">

<li><a href="/modbus-float-wrong-value-byte-order-fix/">Modbus Float Shows a Wrong Value? Byte-Order Fix</a> — the floating-point sibling of this problem (four byte orders, not two).</li>



<li><a href="/qmodmaster-view-menu-data-format-guide/">QModMaster View Menu: Float/Int/Hex/Binary Explained</a> — which display format to use when.</li>



<li><a href="/modbus-scale-factor-offset-values/">Modbus Values Off by 10x? Scale Factor &amp; Offset</a> — when the value is wrong by 10× instead of 65,536×.</li>



<li><a href="/download/">Download QModMaster</a> — free, open-source (LGPLv3) Modbus master.</li>

</ul>



<p class="wp-block-paragraph"><em>Debugging a meter or inverter? A protocol reference helps: <a href="/go/modbus-book" rel="nofollow">Modbus protocol book</a> covers data encoding in depth.</em></p>


<style>
.content-container.site-container{max-width:var(--global-content-narrow-width,842px)!important;margin:0 auto!important;padding:56px 24px 72px!important}
.related-guides{margin-top:2.5em;border-top:1px solid #e5e5e5;padding-top:1.5em}
</style>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
