<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bhanuka Gamachchige</title>
    <description>The latest articles on DEV Community by Bhanuka Gamachchige (@bhanuka_gamachchige).</description>
    <link>https://dev.to/bhanuka_gamachchige</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3654967%2F9aea17c0-c460-424a-8e2f-b825d917f81a.jpeg</url>
      <title>DEV Community: Bhanuka Gamachchige</title>
      <link>https://dev.to/bhanuka_gamachchige</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bhanuka_gamachchige"/>
    <language>en</language>
    <item>
      <title>Monitoring Water Networks Where There's No Power or Wi-Fi</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Sat, 15 Aug 2026 04:42:13 +0000</pubDate>
      <link>https://dev.to/bhanuka_gamachchige/monitoring-water-networks-where-theres-no-power-or-wi-fi-i2l</link>
      <guid>https://dev.to/bhanuka_gamachchige/monitoring-water-networks-where-theres-no-power-or-wi-fi-i2l</guid>
      <description>&lt;p&gt;Most write-ups on remote water monitoring start with the cloud dashboard. That's the wrong place to start. The dashboard is the easy part. The hard part is getting a reliable, timestamped reading out of a sewer manhole or an unpowered reservoir, every day, for the next five years, without sending anyone out to check on it.&lt;/p&gt;

&lt;p&gt;That constraint (no mains power, no comms cable, no site visits) is really what decides the hardware architecture for water and wastewater monitoring. Here's how that architecture usually gets built, using a real deployment pattern as the reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One: Sort Your Sites by Power, Not by Sensor
&lt;/h2&gt;

&lt;p&gt;Every water or wastewater asset in a network fall into one of two buckets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Powered sites. Pump stations, treatment plant sub-systems, anywhere with a panel and continuous electricity.&lt;/li&gt;
&lt;li&gt;Unpowered sites. Manholes, remote reservoirs, isolated sections of pipe, boreholes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's tempting to pick hardware based on the sensor first, a 4-20mA level transmitter here, an RS-485 flow meter there. But that's the second decision, not the first. The first decision is whether the enclosure needs to survive on batteries or can sit on a DIN rail drawing 9-32VDC all day. Get that wrong and you're either burning through battery replacements on a site that had power the whole time, or you've bolted a mains-only controller onto a pole with no outlet for a mile in any direction.&lt;/p&gt;

&lt;p&gt;NORVI's &lt;a href="https://norvi.io/solutions/water-wastewater-monitoring-system/" rel="noopener noreferrer"&gt;water and wastewater monitoring architecture&lt;/a&gt; is a useful reference for this split. It's an IP67 battery-powered logger for unpowered sites, and a mains-powered cellular controller with relay outputs for sites that need to actuate a pump or valve as well as log a reading.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unpowered Case Is Where It Gets Interesting
&lt;/h2&gt;

&lt;p&gt;Powered sites are the easy end of the job. You can run a beefier MCU, a bigger radio, and not worry much about duty cycle. Unpowered sites are where the actual engineering happens, because every milliamp has to be justified against a battery budget that's supposed to last years, not weeks.&lt;/p&gt;

&lt;p&gt;The pattern that makes five-plus years on non-rechargeable cells realistic looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="nl"&gt;LOOP:&lt;/span&gt;
  &lt;span class="n"&gt;wake_from_deep_sleep&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;read_sensor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;              &lt;span class="c1"&gt;// 4-20mA loop, RS-485, or digital&lt;/span&gt;
  &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rtc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;buffer_to_sd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cellular_window_due&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;modem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="n"&gt;publish_over_nbiot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;modem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;enter_deep_sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anything power-hungry, the cellular radio especially, stays off unless it's genuinely needed. A device built around that idea, like the &lt;a href="https://norvi.io/products/battery-powered-cellular-iot-data-logger/" rel="noopener noreferrer"&gt;NORVI EC-M12 battery-powered cellular data logger&lt;/a&gt;, pairs an ultra-low-power STM32L072 with a SIM7070 modem, so the MCU spends most of its life asleep and only wakes the radio for a short transmit window. With a 38,000mAh dual-cell pack behind it, that sleep-first cycle is what stretches a deployment out to 5-7 years depending on how often it reports.&lt;/p&gt;

&lt;p&gt;Two details tend to matter more than they look at first glance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Local storage isn't optional. A cellular link will drop sooner or later. If a device only transmits and never logs to a microSD card with an onboard RTC timestamp, a signal gap turns into a data gap, and for a utility that needs a defensible record for compliance reporting, that's a real problem rather than a minor inconvenience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model-specific I/O beats a universal board. A logger built with a dual 4-20mA analog front end for a level transmitter is a different product from one wired for RS-485 Modbus or a strain-gauge load cell. Trying to make one board handle all of it usually means extra parts drawing quiescent current on every unit, even the ones that never use them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where Each Pattern Shows Up in the Field
&lt;/h2&gt;

&lt;p&gt;Mapping the two buckets onto real sites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reservoir and tank level. Usually off-grid, so a battery logger with a 4-20mA level transmitter reporting over NB-IoT or LTE-M can cover it for years without a battery change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sewer and manhole level. No power, and the enclosure has to survive a submersion-adjacent environment. IP67 isn't a nice-to-have here, it's the baseline. The job is mostly flagging surcharge risk before an overflow happens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pump stations. These almost always have mains power already, so the interesting move is combining monitoring with control: log wet-well level and use a relay output to start or stop the pump, or raise a high-level alarm, from the same device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Treatment plant sub-systems. Powered, and usually pulling from RS-485 Modbus flow meters and quality sensors that need to be timestamped and stored for later audit.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Minimal Payload Example
&lt;/h2&gt;

&lt;p&gt;If you're prototyping the cloud side before the hardware even arrives, a reasonable NB-IoT/MQTT payload for a level-logging use case might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"device_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecm12-reservoir-04"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-08-12T04:15:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"battery_mv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3612&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"readings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"channel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"level_4_20ma"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value_ma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;12.84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value_eng"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3.21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"unit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"m"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keeping the payload small matters more on NB-IoT than it would on Wi-Fi or Ethernet. Every extra byte over a low-power wide-area network means more radio-on time, and that's usually the single biggest line item in the battery budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Compliance Angle Utilities Actually Care About
&lt;/h2&gt;

&lt;p&gt;For water and wastewater operators, “did we log the reading” isn't really the whole requirement. “Can we prove when it happened, even through a network outage” usually is. That's the practical case for RTC-backed timestamping at the hardware level instead of relying on server-side arrival time. A reading buffered locally during a cellular outage and sent later still carries the correct field timestamp, not just the time it happened to reach the platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;If you're speccing something similar, the full water and &lt;a href="https://norvi.io/solutions/water-wastewater-monitoring-system/" rel="noopener noreferrer"&gt;wastewater monitoring architecture&lt;/a&gt; breaks down the powered versus unpowered hardware split in more detail, and the &lt;a href="https://norvi.io/products/battery-powered-cellular-iot-data-logger/" rel="noopener noreferrer"&gt;EC-M12 data logger page&lt;/a&gt; has the model-by-model I/O and battery specs for the unpowered side of that split.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>stm</category>
      <category>datalogger</category>
    </item>
    <item>
      <title>Monitoring a Borehole With No Power, No Wi-Fi, and Nobody Standing Next to It</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Thu, 30 Jul 2026 03:54:00 +0000</pubDate>
      <link>https://dev.to/bhanuka_gamachchige/monitoring-a-borehole-with-no-power-no-wi-fi-and-nobody-standing-next-to-it-h0k</link>
      <guid>https://dev.to/bhanuka_gamachchige/monitoring-a-borehole-with-no-power-no-wi-fi-and-nobody-standing-next-to-it-h0k</guid>
      <description>&lt;p&gt;A few months back I got pulled into a conversation about instrumenting a wellfield, and it reminded me how different "remote monitoring" looks once there's no mains power or Wi-Fi anywhere nearby. Boreholes are a good example of just how hard that gets. They're usually out in a field somewhere, or scattered across a wellfield, with nothing to plug into and no network to join. And the thing you actually care about, the water level, is happening tens of meters underground where nobody can see it.&lt;/p&gt;

&lt;p&gt;Most sites still handle this the old fashioned way: someone drives out, drops a dip meter down the hole, and writes a number on a clipboard. It works, sort of, but it only tells you what's happening at that exact moment. If a pump has been running dry for three days before the next site visit, nobody finds out until it's already a problem.&lt;/p&gt;

&lt;p&gt;So I wanted to write up how a battery powered, cellular connected logger actually solves this, and what the real engineering trade offs look like: sensor choice, power budgeting, and picking the right radio.&lt;/p&gt;

&lt;p&gt;What's actually in the system&lt;/p&gt;

&lt;p&gt;Strip it down and a remote borehole node is four things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A hydrostatic pressure sensor sitting in or above the water column&lt;/li&gt;
&lt;li&gt;A sealed, battery powered logger at the wellhead&lt;/li&gt;
&lt;li&gt;A cellular radio, NB-IoT, 2G, or 4G LTE depending on the region&lt;/li&gt;
&lt;li&gt;A dashboard and alerting layer, either your own or a vendor's&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sensor reads the level, logger stores and transmits it, network carries it back, and it lands on a dashboard or an SMS. &lt;a href="https://norvi.io/solutions/borehole-groundwater-level-monitoring/" rel="noopener noreferrer"&gt;NORVI's EC-M12 borehole and groundwater monitoring solution&lt;/a&gt; is a good real world example of this, mostly because the interesting decisions are all in how it handles power and connectivity rather than the sensor itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sensor choice matters more than I expected
&lt;/h2&gt;

&lt;p&gt;There are basically two ways to take a hydrostatic reading. You can lower a sealed 316L stainless sensor into the water on a cable, which is the classic direct immersion approach and usually holds up for around two years on battery. Or you can use a tube type sensor, where the sensing head stays up at the wellhead and reads the column through a tube run down the hole. Since the electronics aren't sitting in the water constantly, those tend to run past three years.&lt;/p&gt;

&lt;p&gt;If you're only doing one or two sites it probably doesn't matter much which you pick. But if you're rolling out a fleet of nodes across a wellfield, that extra year or so adds up fast in fewer truck rolls and lower long term cost, and it's worth thinking about upfront rather than after the first round of battery swaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real trick to multi year battery life
&lt;/h2&gt;

&lt;p&gt;Getting years of battery life from a cellular device is not just about using a bigger battery. It is about reducing how often the cellular radio needs to transmit.&lt;/p&gt;

&lt;p&gt;A well-designed data logger wakes up at regular intervals, records sensor readings locally, and only sends data when a meaningful change is detected. It also sends periodic heartbeat messages so you know the device is still online.&lt;/p&gt;

&lt;p&gt;Cellular transmission uses far more power than taking sensor readings or storing data locally. By transmitting only when needed, increasing logging frequency when conditions change, and staying quiet when everything is stable, a battery-powered data logger can operate for years instead of months.&lt;/p&gt;

&lt;p&gt;The table below shows the power consumption of the battery-powered data logger under different operating conditions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpefjwnd1nls1k6x9a64c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpefjwnd1nls1k6x9a64c.png" alt="Power Consumption Table" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://norvi.io/docs/ec-m12-bc-c6-c-low-power-applications-sleep-mode/" rel="noopener noreferrer"&gt;EC-M12-BC-C6-C LOW POWER APPLICATIONS – SLEEP MODE&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One honest caveat here: signal strength matters a lot. A node reaching for a weak signal burns more power per transmission than one sitting under good coverage. So the choice between NB-IoT, which is lower power and reaches deeper into weak coverage areas, and 4G LTE, which draws more power but is available where NB-IoT isn't, really should be made per site rather than as a blanket default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alerts that don't depend on your cloud staying up
&lt;/h2&gt;

&lt;p&gt;Since the cellular modem can send SMS directly, the alerting logic can live right on the device instead of in the cloud. It compares readings against thresholds and fires off a text the moment something crosses a line, whether or not your dashboard backend happens to be reachable at that moment. If you've ever had a cloud outage quietly swallow a critical alert, you'll know why that matters more than it sounds like on paper.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you're building or speccing something similar
&lt;/h2&gt;

&lt;p&gt;If you're a system integrator or just evaluating hardware for a groundwater project, it's worth reading through the &lt;a href="https://norvi.io/solutions/borehole-groundwater-level-monitoring/" rel="noopener noreferrer"&gt;full EC-M12 breakdown&lt;/a&gt;, which covers sensor options, cellular variants, and actual battery numbers from live deployments. Even if you end up building your own logger, the same constraints apply: no mains power, no local network, and a multi year battery target you have to design around from day one.&lt;/p&gt;

&lt;p&gt;Curious what others have run into instrumenting off grid infrastructure like this. Sensor choice, radio choice, or something else entirely that bit you in the field? Have a remote monitoring project in mind? &lt;a href="https://norvi.io/contact-us/" rel="noopener noreferrer"&gt;Contact&lt;/a&gt; the NORVI engineering team for expert guidance or request a &lt;a href="https://norvi.io/free-consultation/" rel="noopener noreferrer"&gt;free consultation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>embedded</category>
      <category>esp32</category>
      <category>cellular</category>
    </item>
    <item>
      <title>Getting Started with Modbus RTU on ESP32</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Fri, 17 Jul 2026 12:50:31 +0000</pubDate>
      <link>https://dev.to/norvi_controllers/getting-started-with-modbus-rtu-on-esp32-4259</link>
      <guid>https://dev.to/norvi_controllers/getting-started-with-modbus-rtu-on-esp32-4259</guid>
      <description>&lt;p&gt;Modbus RTU over RS-485 is the serial workhorse of industrial field wiring — the variant you'll meet when connecting an ESP32 directly to an energy meter, PLC, VFD, or temperature transmitter over a wired bus. This tutorial walks through wiring the hardware, installing a library, and flashing working RTU master code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Modbus RTU master on ESP32 that polls holding registers from an RS-485 slave device over a wired bus.&lt;/li&gt;
&lt;li&gt;An understanding of register types, addressing, and the reliability practices that separate a demo from a production deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Arduino IDE (or PlatformIO) with the ESP32 board package installed.&lt;/li&gt;
&lt;li&gt;An ESP32 dev board, or an industrial ESP32 controller with a built-in RS-485 transceiver such as the NORVI X — this saves you from wiring a separate MAX485 module.&lt;/li&gt;
&lt;li&gt;A Modbus RTU slave device (energy meter, sensor, or PLC).&lt;/li&gt;
&lt;li&gt;Basic familiarity with the Arduino C++ syntax and serial monitor debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A 60-Second Modbus Primer
&lt;/h2&gt;

&lt;p&gt;Modbus is a master–slave protocol dating back to 1979. One master polls up to 247 slave devices, each with a unique address (1–247). Data lives in four register types, and knowing which one you need is half the battle:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Register Type&lt;/th&gt;
&lt;th&gt;Access&lt;/th&gt;
&lt;th&gt;Width&lt;/th&gt;
&lt;th&gt;Typical Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coils (0x)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read/Write&lt;/td&gt;
&lt;td&gt;1-bit&lt;/td&gt;
&lt;td&gt;Relay outputs, digital controls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discrete Inputs (1x)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read only&lt;/td&gt;
&lt;td&gt;1-bit&lt;/td&gt;
&lt;td&gt;Digital sensor inputs, switch states&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Input Registers (3x)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read only&lt;/td&gt;
&lt;td&gt;16-bit&lt;/td&gt;
&lt;td&gt;Analog sensor values, process data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Holding Registers (4x)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Read/Write&lt;/td&gt;
&lt;td&gt;16-bit&lt;/td&gt;
&lt;td&gt;Setpoints, configuration parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Modbus RTU over RS-485
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 — Wire the Hardware
&lt;/h3&gt;

&lt;p&gt;The ESP32's UART pins output 3.3V TTL logic, but RS-485 uses a differential voltage signal — so you need a TTL-to-RS-485 transceiver (typically a MAX485 or MAX3485 chip) between the ESP32 and the bus.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UART TX → transceiver DI (driver input)&lt;/li&gt;
&lt;li&gt;UART RX ← transceiver RO (receiver output)&lt;/li&gt;
&lt;li&gt;A spare GPIO → transceiver DE and RE tied together (direction control)&lt;/li&gt;
&lt;li&gt;Transceiver A/B terminals → the RS-485 A+/B− pair on your slave device&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Skip the transceiver wiring
&lt;/h4&gt;

&lt;p&gt;Industrial controllers like the NORVI X have the TTL-to-RS-485 converter built into the board, so RS-485 slaves connect straight to a screw terminal — no breadboard, no separate module, and DE/RE switching is handled for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Two more wiring details that matter more than they look:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Place a 120Ω termination resistor at each physical end of the RS-485 bus if the run is longer than a few meters.&lt;/li&gt;
&lt;li&gt;Give every slave device a unique address in the 1–247 range — duplicate addresses cause bus conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2 — Install a Modbus Library
&lt;/h3&gt;

&lt;p&gt;For RTU master mode on Arduino, ModbusMaster is the simplest starting point. Install it from the Library Manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Arduino IDE → Sketch → Include Library → Manage Libraries...
Search: "ModbusMaster" by Doc Walker → Install

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other options worth knowing about, depending on your needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modbus-esp32 — supports both RTU and TCP/IP, master and slave modes.&lt;/li&gt;
&lt;li&gt;ArduinoModbus — the official Arduino library, straightforward setup.&lt;/li&gt;
&lt;li&gt;esp32ModbusRTU — interrupt-driven and non-blocking, useful if your loop() is already busy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3 — Write the RTU Master Sketch
&lt;/h3&gt;

&lt;p&gt;This sketch polls two holding registers from slave address 1 every half-second and prints the values to the serial monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ModbusMaster.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define SLAVE_ID 1
#define RXD2 16  // ESP32 UART2 RX → transceiver RO / NORVI X RS-485 header
#define TXD2 17  // ESP32 UART2 TX → transceiver DI / NORVI X RS-485 header
&lt;/span&gt;
&lt;span class="n"&gt;ModbusMaster&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;115200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SERIAL_8N1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RXD2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TXD2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// match your slave's baud/parity&lt;/span&gt;
  &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SLAVE_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serial2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Modbus RTU master ready"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Read 2 holding registers starting at address 0x0000&lt;/span&gt;
  &lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readHoldingRegisters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x0000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ku8MBSuccess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;uint16_t&lt;/span&gt; &lt;span class="n"&gt;reg0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getResponseBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;uint16_t&lt;/span&gt; &lt;span class="n"&gt;reg1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getResponseBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Register 0: %u | Register 1: %u&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reg0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reg1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Modbus read failed — error code: 0x%02X&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// respect the slave's minimum poll interval&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things to adjust for your setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Baud rate, parity, and stop bits in Serial2.begin() must match your slave device exactly — check the datasheet. 9600 8N1 is the most common default.&lt;/li&gt;
&lt;li&gt;The register start address (0x0000) and quantity (2) depend on your device's register map.&lt;/li&gt;
&lt;li&gt;If you're using an external MAX485 module instead of a built-in transceiver, you'll also need to toggle a DE/RE GPIO to HIGH before transmitting and LOW after — libraries like esp32ModbusRTU handle this automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reliability Checklist for Production (RTU)
&lt;/h2&gt;

&lt;p&gt;A working sketch on the bench is not the same as a stable deployment on a factory floor. Before you ship:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Termination: 120Ω resistors at both physical ends of an RS-485 bus longer than a few meters — omitting this causes reflections and intermittent read failures.&lt;/li&gt;
&lt;li&gt;Unique addressing: every RTU slave needs a distinct 1–247 address.&lt;/li&gt;
&lt;li&gt;Retry logic: treat a single failed poll as noise, not a fault. Retry two or three times before flagging an alarm.&lt;/li&gt;
&lt;li&gt;CRC validation: RTU frames carry a CRC checksum — confirm your library validates it (most do by default) rather than trusting raw bytes.&lt;/li&gt;
&lt;li&gt;Poll interval: don't poll faster than the slave's documented response time — 100–500 ms minimum is typical. Hammering the bus causes timeouts, not faster data.&lt;/li&gt;
&lt;li&gt;Floating-point data: Modbus registers are 16-bit integers. Many analog sensors split a float across two consecutive registers in IEEE 754 format — check the datasheet's register map before assuming a raw integer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Troubleshooting Common Issues (RTU)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely Cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reads return &lt;code&gt;0xE2&lt;/code&gt; or timeout errors&lt;/td&gt;
&lt;td&gt;Baud rate, parity, or stop bits mismatch with the slave&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Intermittent garbage on long RS-485 runs&lt;/td&gt;
&lt;td&gt;Missing or incorrect &lt;strong&gt;120 Ω&lt;/strong&gt; termination resistors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bus works with one slave, fails with several&lt;/td&gt;
&lt;td&gt;Duplicate slave addresses on the bus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Values look scrambled or nonsensical&lt;/td&gt;
&lt;td&gt;Register map mismatch — wrong start address or misreading a float as two integers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;The ESP32 handles Modbus RTU comfortably, and the code in this tutorial is enough to get real data flowing from an RS-485 slave device today. RTU is the right call for field-level wiring to sensors, meters, and PLCs where a wired serial bus makes more sense than a network connection.&lt;/p&gt;

&lt;p&gt;From here, the natural next steps are adding retry/backoff logic around each poll, mapping out your specific device's full register table, and — if you're moving from prototype to a real deployment — considering hardware that removes the RS-485 wiring step entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading and Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Original field guide this tutorial is based on: &lt;a href="https://norvi.io/modbus-devices-with-esp32/" rel="noopener noreferrer"&gt;Modbus with ESP32 — RTU &amp;amp; TCP Guide (NORVI Blog)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hardware used in this tutorial: &lt;a href="https://norvi.io/norvi-x/" rel="noopener noreferrer"&gt;NORVI X — ESP32-S3 modular industrial IoT controller&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full technical specs: &lt;a href="https://norvi.io/docs/norvi-x-cpu-esps3-x1-datasheet/" rel="noopener noreferrer"&gt;NORVI X datasheet (PDF)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Related deep-dive: &lt;a href="https://norvi.io/norvi-x-scada-system-integration-modbus-opcua-gateway/" rel="noopener noreferrer"&gt;NORVI X SCADA Integration — Modbus TCP to OPC-UA Gateway Setup&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sample code and firmware: &lt;a href="https://github.com/NORVIControllers" rel="noopener noreferrer"&gt;NORVI Controllers on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full documentation library: &lt;a href="https://norvi.io/docs/" rel="noopener noreferrer"&gt;norvi.io/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Questions about sizing hardware for your project? &lt;a href="https://norvi.io/free-consultation/" rel="noopener noreferrer"&gt;Book a free consultation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>esp32</category>
      <category>modbus</category>
      <category>modbusrtu</category>
    </item>
    <item>
      <title>Build a Smart Building Automation Controller Using NORVI X</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Fri, 27 Mar 2026 11:29:04 +0000</pubDate>
      <link>https://dev.to/norvi_controllers/build-a-smart-building-automation-controller-using-norvi-x-1m17</link>
      <guid>https://dev.to/norvi_controllers/build-a-smart-building-automation-controller-using-norvi-x-1m17</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern buildings are packed with systems — HVAC, lighting, access control, and energy metering — but most of them run on separate proprietary controllers that don't talk to each other. The result is a building that's instrumented but not truly intelligent.&lt;/p&gt;

&lt;p&gt;In this Instructable, you'll learn how to build a flexible, open-source smart building automation controller using the NORVI X platform. It's built on the ESP32-S3 microcontroller, supports industrial I/O, speaks Modbus RTU natively, and connects to the cloud over WiFi, Ethernet, or 4G — all at a fraction of the cost of traditional BMS hardware.&lt;/p&gt;

&lt;p&gt;This guide covers a practical HVAC zone control system with remote monitoring, but the same hardware can handle lighting automation, energy metering, and access control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Understand the Problem With Traditional Building Automation
&lt;/h3&gt;

&lt;p&gt;Before building anything, it's worth knowing why this matters. Traditional Building Management Systems (BMS) come with some frustrating limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Proprietary controllers that need vendor-certified technicians to configure&lt;/li&gt;
&lt;li&gt;No interoperability between subsystems — each zone or floor operates in a silo&lt;/li&gt;
&lt;li&gt;Little to no native cloud/API connectivity&lt;/li&gt;
&lt;li&gt;High licensing costs that price out small-to-medium commercial buildings&lt;/li&gt;
&lt;li&gt;Long lead times and expensive replacement cycles when hardware reaches end-of-life&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of this project is to replace that complexity with a single open platform that any engineer can program, configure, and scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Gather Your Components
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Hardware (per zone controller)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;1x NORVI CPU-ESPS3-X1 (ESP32-S3 with WiFi, Ethernet, RS-485)&lt;/li&gt;
&lt;li&gt;1x NORVI X-AI4 (4x analog inputs, 4–20 mA, 16-bit ADC)&lt;/li&gt;
&lt;li&gt;1x NORVI X-R4 (4x relay outputs)&lt;/li&gt;
&lt;li&gt;1x NORVI X-DI4 (fast digital inputs)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Sensors &amp;amp; Actuators
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Temperature &amp;amp; humidity sensor (4–20 mA output)&lt;/li&gt;
&lt;li&gt;CO2 sensor (for demand-controlled ventilation)&lt;/li&gt;
&lt;li&gt;Fan coil unit (controlled via relay)&lt;/li&gt;
&lt;li&gt;Door/window contact sensors&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Tools &amp;amp; Software
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Arduino IDE or ESP-IDF&lt;/li&gt;
&lt;li&gt;MQTT broker (local or cloud — e.g., HiveMQ, Mosquitto, AWS IoT)&lt;/li&gt;
&lt;li&gt;Optional: Node-RED or Grafana for dashboarding
**
Estimated cost per zone controller: ~$135–145 USD**&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Understand the System Architecture
&lt;/h3&gt;

&lt;p&gt;Here's how the layers of the system fit together:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;NORVI X Module&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sensing&lt;/td&gt;
&lt;td&gt;Temp, Humidity, CO2 sensors&lt;/td&gt;
&lt;td&gt;X-AI4 (4–20 mA)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output Control&lt;/td&gt;
&lt;td&gt;HVAC relays, Fan Coil&lt;/td&gt;
&lt;td&gt;X-R4 relay module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contact Monitoring&lt;/td&gt;
&lt;td&gt;Door/Window Sensors&lt;/td&gt;
&lt;td&gt;X-DI4 digital inputs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Communication&lt;/td&gt;
&lt;td&gt;Modbus RTU to BMS&lt;/td&gt;
&lt;td&gt;Built-in RS-485&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connectivity&lt;/td&gt;
&lt;td&gt;WiFi / Ethernet / 4G&lt;/td&gt;
&lt;td&gt;Built-in on CPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge Logic&lt;/td&gt;
&lt;td&gt;Schedules, Alarms, Setpoints&lt;/td&gt;
&lt;td&gt;ESP32-S3 firmware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Module&lt;/td&gt;
&lt;td&gt;NORVI X Module&lt;/td&gt;
&lt;td&gt;Core processing and integration layer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each CPU module connects to I/O expansion boards via a dedicated expansion bus. You can stack up to 200 I/O points across a single controller — no rewiring, no new CPU needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Wire Up the Hardware
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Mount the NORVI CPU-ESPS3-X1 on a DIN rail in your control panel.&lt;/li&gt;
&lt;li&gt;Attach the X-AI4 expansion module — connect your 4–20 mA temperature, humidity, and CO2 sensors to the analog input terminals.&lt;/li&gt;
&lt;li&gt;Attach the X-R4 relay module — wire your fan coil unit switching circuits to the relay output terminals.&lt;/li&gt;
&lt;li&gt;Attach the X-DI4 — connect door/window contact dry contacts to the digital input terminals.&lt;/li&gt;
&lt;li&gt;Wire RS-485 A/B terminals to your upstream BMS or SCADA system (Modbus RTU).&lt;/li&gt;
&lt;li&gt;Connect Ethernet or configure WiFi for cloud/dashboard access.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tip: For remote plant rooms or retrofit sites with no wired network, use the NORVI CPU-ESPS3-X2 or X3 variant, which adds 2G/4G cellular connectivity. No local network infrastructure needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Program the Controller
&lt;/h3&gt;

&lt;p&gt;All logic runs locally on the ESP32-S3. Use the Arduino framework or ESP-IDF — no proprietary IDE or vendor cloud dependency required. A basic control loop looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ModbusMaster.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;PubSubClient.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nf"&gt;readTemperature&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;analogRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AI4_CH0_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 4-20mA to temperature&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;controlFanCoil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;setpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;setpoint&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RELAY_CH1_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Fan coil ON&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;setpoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RELAY_CH1_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LOW&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Fan coil OFF&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;readTemperature&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;controlFanCoil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;22.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 22.5°C setpoint&lt;/span&gt;
  &lt;span class="n"&gt;publishToMQTT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"building/zone1/temp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define your schedules, setpoints, alarm thresholds, and failsafe behaviour in firmware. Optionally expose configuration parameters over MQTT or a lightweight REST API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Set Up Cloud / Remote Monitoring
&lt;/h3&gt;

&lt;p&gt;One NORVI X CPU isn't limited to HVAC. Add more expansion modules to cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lighting automation — X-Q4/X-Q8 transistor outputs for 0–10 V dimming&lt;/li&gt;
&lt;li&gt;Occupancy sensing — X-DI8/X-DI16 for PIR sensors and pushbutton overrides&lt;/li&gt;
&lt;li&gt;Daylight harvesting — X-AV4 analog inputs for photocell sensors&lt;/li&gt;
&lt;li&gt;Energy metering — RS-485 Modbus RTU to commercial energy meters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A single NORVI X controller can simultaneously manage HVAC zone control, occupancy-based lighting, and access logging — eliminating the need for separate controllers per subsystem.&lt;/p&gt;

&lt;p&gt;For a 12-zone office building across three floors, deploy one NORVI X unit per zone and connect them all to a central data concentrator or SCADA system over Modbus RTU.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Test and Deploy
&lt;/h3&gt;

&lt;p&gt;Before deploying to site, run through this checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify all analog input readings match expected sensor output ranges&lt;/li&gt;
&lt;li&gt;Test relay outputs — confirm fan coil switching responds to setpoint logic&lt;/li&gt;
&lt;li&gt;Verify Modbus RTU communication with your upstream BMS&lt;/li&gt;
&lt;li&gt;Confirm MQTT telemetry is flowing to your dashboard&lt;/li&gt;
&lt;li&gt;Simulate a network outage — confirm local failsafe logic holds&lt;/li&gt;
&lt;li&gt;Test OTA update path before final installation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  NORVI X vs Traditional Smart Building Hardware
&lt;/h2&gt;

&lt;p&gt;Here's how NORVI X compares against the alternatives engineers typically Evaluate:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Traditional BMS&lt;/th&gt;
&lt;th&gt;Dev Boards&lt;/th&gt;
&lt;th&gt;IoT Gateways&lt;/th&gt;
&lt;th&gt;NORVI X&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Industrial I/O (DI/DO/AI/AO)&lt;/td&gt;
&lt;td&gt;✔✔✔&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✖&lt;/td&gt;
&lt;td&gt;✔✔✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Programming (C/C++)&lt;/td&gt;
&lt;td&gt;✖&lt;/td&gt;
&lt;td&gt;✔✔✔&lt;/td&gt;
&lt;td&gt;✖&lt;/td&gt;
&lt;td&gt;✔✔✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RS-485 / Modbus RTU&lt;/td&gt;
&lt;td&gt;✔✔✔&lt;/td&gt;
&lt;td&gt;Manual wiring&lt;/td&gt;
&lt;td&gt;✔✔&lt;/td&gt;
&lt;td&gt;Native built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4G / LTE Cellular Option&lt;/td&gt;
&lt;td&gt;Requires add-on&lt;/td&gt;
&lt;td&gt;DIY&lt;/td&gt;
&lt;td&gt;✔✔&lt;/td&gt;
&lt;td&gt;✔✔✔&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modular I/O Expansion&lt;/td&gt;
&lt;td&gt;Vendor-locked&lt;/td&gt;
&lt;td&gt;✖&lt;/td&gt;
&lt;td&gt;✖&lt;/td&gt;
&lt;td&gt;Up to 200 I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price Point&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Very Low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;$80–$150 USD&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With NORVI X, you get industrial-grade I/O, open ESP32 programming, native Modbus RTU, and cloud connectivity — all in a modular platform that scales from a single zone to hundreds of I/O points&lt;/p&gt;

&lt;p&gt;Estimated hardware cost per zone controller: ~$135–145 USD — a fraction of a traditional BMS controller, with full programming flexibility retained.&lt;/p&gt;

&lt;p&gt;This approach is ideal for system integrators, OEM machine builders, smart building startups, and retrofit projects where legacy BMS hardware needs to be replaced with something open and scalable.&lt;/p&gt;

&lt;p&gt;Note: NORVI X is not suitable for applications requiring strict IEC 61131-3 Ladder Logic compliance or certified safety functions (SIL/PLd). Those applications require dedicated safety PLCs.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NORVI X Product Page: &lt;a href="//norvi.io/norvi-x"&gt;norvi.io/norvi-x&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NORVI Shop: &lt;a href="//shop.norvi.lk"&gt;shop.norvi.lk
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub (code examples): &lt;a href="//github.com/IndustrialArduino"&gt;github.com/IndustrialArduino&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Technical Support: &lt;a href="mailto:support@norvi.io"&gt;support@norvi.io&lt;/a&gt; | +94 77 111 1776&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>iot</category>
    </item>
    <item>
      <title>Building Multi-Year IoT Deployments: Inside the NORVI EC-M12-BC-C6-C-A LTE-M Logger</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Fri, 13 Mar 2026 03:34:59 +0000</pubDate>
      <link>https://dev.to/norvi_controllers/building-multi-year-iot-deployments-inside-the-norvi-ec-m12-bc-c6-c-a-lte-m-logger-46m0</link>
      <guid>https://dev.to/norvi_controllers/building-multi-year-iot-deployments-inside-the-norvi-ec-m12-bc-c6-c-a-lte-m-logger-46m0</guid>
      <description>&lt;p&gt;Deploying a remote IoT data logger sounds straightforward — until you factor in power constraints, unpredictable weather, and the cost of maintenance visits to a location 200 km away.&lt;/p&gt;

&lt;p&gt;For engineers working on industrial remote monitoring, water utilities, environmental sensing, or agricultural automation, battery life and rugged connectivity are the two factors that make or break a deployment.&lt;/p&gt;

&lt;p&gt;This article breaks down how the NORVI EC-M12-BC-C6-C-A solves both — and what hardware decisions actually drive multi-year field life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Remote Loggers Fail in the Field
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth: most IoT sensors consume very little power during operation. The real power draw comes from cellular transmission — and this is where many logger designs fail.&lt;/p&gt;

&lt;p&gt;Older 2G/3G modems draw hundreds of milliamps during data bursts. On a standard 6,000 mAh lithium pack sending readings every 15 minutes, you're looking at months, not years.&lt;/p&gt;

&lt;p&gt;The root problems are almost always:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wrong modem technology — GPRS/3G radios burn 5–10× more power than modern LPWAN alternatives.&lt;/li&gt;
&lt;li&gt;Aggressive MCU idle current — mainstream microcontrollers don't have true ultra-low-power sleep modes&lt;/li&gt;
&lt;li&gt;Wrong battery chemistry — alkaline and lithium-ion both suffer from high self-discharge and poor cold-weather performance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Modern low-power IoT standards like LTE-M (Cat-M1) and NB-IoT were developed precisely to address the modem problem. Combined with the right MCU and battery chemistry, multi-year field life becomes achievable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hardware Stack: Key Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  MCU: STM32L072CZT6TR
&lt;/h3&gt;

&lt;p&gt;The logger runs on the STM32L072 — part of STMicroelectronics' ultra-low-power L0 family. This is a deliberate choice. The L072 is not the fastest or most capable MCU you could put in an IoT device; it's the one that draws the least current between measurement cycles.&lt;/p&gt;

&lt;p&gt;Multiple low-power modes allow the processor to dramatically reduce draw while waiting to take the next reading. For a logger sampling every few minutes and transmitting every hour, the MCU spends the vast majority of its time in deep sleep. That idle current matters far more than clock speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Battery: 38,000 mAh LiSOCl₂
&lt;/h3&gt;

&lt;p&gt;The device uses two ER34615H lithium thionyl chloride cells (19,000 mAh each) for a combined 38,000 mAh capacity.&lt;/p&gt;

&lt;p&gt;LiSOCl₂ is worth understanding if you're specifying hardware for field deployments:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Chemistry&lt;/th&gt;
&lt;th&gt;Self-Discharge / Year&lt;/th&gt;
&lt;th&gt;Cold Weather&lt;/th&gt;
&lt;th&gt;Capacity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alkaline&lt;/td&gt;
&lt;td&gt;~3–5%&lt;/td&gt;
&lt;td&gt;Poor (capacity drops sharply)&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Li-ion&lt;/td&gt;
&lt;td&gt;~2–3%&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiSOCl₂&lt;/td&gt;
&lt;td&gt;~1% or less&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a device that may sit in a field cabinet through 5–10 winters, LiSOCl₂ is the correct answer. The chemistry is non-rechargeable, which some engineers see as a limitation — but for a true low-power deployment, it's a feature: no charging circuitry, no charge cycle degradation, no BMS complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cellular Modem: SIMCOM A7672
&lt;/h2&gt;

&lt;p&gt;The A7672 supports LTE Cat-M1, NB-IoT (NB1 and NB2), and GSM/GPRS fallback — a multi-mode approach that matters for deployments where network availability varies by region or operator.&lt;/p&gt;

&lt;p&gt;Band support covers B1/B2/B3/B4/B5/B8/B12/B13/B18/B19/B20/B26/B28/B39, plus quad-band GSM. In practice, this means you're not locked to a single operator or region.&lt;/p&gt;

&lt;p&gt;Data rates are well-matched to the use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LTE Cat-M1: up to 588 kbps DL / 1,119 kbps UL&lt;/li&gt;
&lt;li&gt;NB-IoT: up to 26 kbps DL / 62.5 kbps UL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a logger sending timestamped sensor readings every 15–60 minutes, NB-IoT bandwidth is more than sufficient. And NB-IoT's deep penetration characteristics make it valuable for underground or basement installations where LTE signal is weak.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4–20 mA Inputs: Industrial Standard, Implemented Properly
&lt;/h2&gt;

&lt;p&gt;The 4–20 mA current loop is the backbone of industrial instrumentation — pressure transmitters, flow meters, level sensors, temperature probes, and hundreds of other field devices. Its noise immunity over long cable runs makes it ideal for outdoor deployments where signal integrity matters.&lt;/p&gt;

&lt;p&gt;The EC-M12-BC-C6-C-A provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 analog inputs (0–20 mA range, 26V DC max)&lt;/li&gt;
&lt;li&gt;ADS1115 16-bit ADC over I2C — high-resolution conversions&lt;/li&gt;
&lt;li&gt;Configurable sensor excitation supply: 12V / 5V / 3.3V outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point is significant. Many loggers require separate field power supplies for 2-wire transmitters. Having a configurable excitation supply built into the logger simplifies wiring considerably and reduces the BoM for a deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local Storage and Time Integrity
&lt;/h2&gt;

&lt;p&gt;Two features that often get overlooked in logger specifications — and that cause real pain in the field:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DS3231 RTC&lt;/strong&gt; — The DS3231 is a temperature-compensated real-time clock with ±2 ppm accuracy. Even through cellular outages or power interruptions, timestamps remain accurate. This matters when you're stitching together time series data from multiple loggers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MicroSD card slot (SPI)&lt;/strong&gt; — When connectivity is lost — due to network outage, coverage gaps, or cellular module failure — the logger buffers readings locally. When connectivity is restored, the buffered data uploads, preserving continuity in your time series. Without local storage, you get gaps. Gaps in environmental or industrial monitoring data are often unacceptable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RS-485 (half-duplex)&lt;/strong&gt; is also available, opening up Modbus RTU integration for deployments where you need to pull data from multiple sensors on a shared bus.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enclosure and Environmental Specs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;IP Rating:&lt;/strong&gt;          IP67 (fully dustproof, 1m immersion)&lt;br&gt;
&lt;strong&gt;Operating Temp:&lt;/strong&gt;    –40°C to +85°C&lt;br&gt;
&lt;strong&gt;Enclosure:&lt;/strong&gt;          ABS + Polycarbonate&lt;br&gt;
&lt;strong&gt;Mounting:&lt;/strong&gt;           Wall / Pole&lt;br&gt;
&lt;strong&gt;Connector:&lt;/strong&gt;          M8 12-pin with cable gland&lt;br&gt;
&lt;strong&gt;Dimensions:&lt;/strong&gt;         146 × 90 × 50 mm&lt;br&gt;
&lt;strong&gt;Shock:&lt;/strong&gt;              30g operating / 50g non-operating (11ms)&lt;br&gt;
&lt;strong&gt;Certifications:&lt;/strong&gt;     CE (EN 61131-2:2007, EN 61010-1:2010)&lt;/p&gt;

&lt;p&gt;IP67 is the minimum you should specify for any outdoor exposed installation. The –40°C lower bound matters for cold-climate deployments — and it's where LiSOCl₂ chemistry earns its place, since alkaline cells lose a significant fraction of their rated capacity at sub-zero temperatures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist: Evaluating Any Long-Life IoT Logger
&lt;/h2&gt;

&lt;p&gt;When you're specifying a logger for a multi-year unattended deployment, five areas determine real-world performance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Battery chemistry — LiSOCl₂ for long life and cold weather; check self-discharge spec&lt;/li&gt;
&lt;li&gt;Total capacity — calculate your expected current budget and verify runtime&lt;/li&gt;
&lt;li&gt;MCU idle current — look for dedicated ultra-low-power MCU families (STM32L0/L4, nRF9160, etc.)&lt;/li&gt;
&lt;li&gt;Modem technology — LTE-M or NB-IoT over GPRS/2G/3G for meaningful power reduction&lt;/li&gt;
&lt;li&gt;Local storage — microSD or equivalent; essential for maintaining data integrity through outages&lt;/li&gt;
&lt;li&gt;IP rating — IP67 minimum for outdoor; check operating temperature range against your environment&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Use Cases Where This Architecture Makes Sense
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Water utilities&lt;/strong&gt; — pressure and flow monitoring across distribution networks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environmental monitoring&lt;/strong&gt; — river level, soil moisture, air quality nodes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agriculture&lt;/strong&gt; — irrigation pump monitoring, tank level sensing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Oil &amp;amp; gas&lt;/strong&gt; — remote well-head pressure and temperature logging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart cities&lt;/strong&gt; — utility metering, infrastructure health monitoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Industrial assets&lt;/strong&gt; — vibration, temperature, pressure on remote plant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread: locations with no mains power, intermittent maintenance access, and a requirement for continuous data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Genuine multi-year battery life in a cellular IoT logger requires every layer of the hardware stack to work together. The NORVI EC-M12-BC-C6-C-A shows what that looks like in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;38,000 mAh LiSOCl₂ capacity (2× ER34615H)&lt;/li&gt;
&lt;li&gt;STM32L072 ultra-low-power MCU&lt;/li&gt;
&lt;li&gt;SIMCOM A7672 LTE-M / NB-IoT modem with GSM fallback&lt;/li&gt;
&lt;li&gt;2 × 4–20 mA industrial analog inputs with ADS1115 16-bit ADC&lt;/li&gt;
&lt;li&gt;1 x RS-485&lt;/li&gt;
&lt;li&gt;Built-in sensor excitation (12V/5V/3.3V)&lt;/li&gt;
&lt;li&gt;DS3231 RTC + microSD local storage&lt;/li&gt;
&lt;li&gt;IP67 enclosure, –40°C to +85°C operating range&lt;/li&gt;
&lt;li&gt;CE certified for industrial environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more details or to request a datasheet: &lt;a href="https://norvi.io/battery-powered-data-logger/" rel="noopener noreferrer"&gt;norvi.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>iot</category>
    </item>
    <item>
      <title>Building a Multi-Year Battery Life IoT Data Logger: A Deep Dive into Ultra-Low-Power Design</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Tue, 10 Feb 2026 08:12:28 +0000</pubDate>
      <link>https://dev.to/norvi_controllers/building-a-multi-year-battery-life-iot-data-logger-a-deep-dive-into-ultra-low-power-design-47gg</link>
      <guid>https://dev.to/norvi_controllers/building-a-multi-year-battery-life-iot-data-logger-a-deep-dive-into-ultra-low-power-design-47gg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Ever wondered how industrial IoT devices achieve multi-year battery life while transmitting data over cellular networks? In this article, I'll walk you through a real-world implementation of an ultra-low-power industrial data logger that monitors diesel fuel levels remotely and achieves an impressive 3-11 year battery life.&lt;/p&gt;

&lt;p&gt;We'll be using the &lt;a href="https://norvi.io/battery-powered-data-logger/" rel="noopener noreferrer"&gt;EC-M12-BC-C6-C-A&lt;/a&gt;, a battery-powered device with an STM32L0 series microcontroller and a SIM7070 LTE modem – a common setup in industrial monitoring applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Remote monitoring systems face a critical tradeoff: you need frequent data updates for real-time insights, but each transmission cycle drains your battery. Cellular modems are particularly power-hungry, with peak currents reaching 840mA during network initialisation.&lt;/p&gt;

&lt;p&gt;The goal? Design a system that can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read analog sensor data accurately&lt;/li&gt;
&lt;li&gt;Transmit to cloud dashboard via 4G/LTE-M&lt;/li&gt;
&lt;li&gt;Operate for years on primary lithium batteries&lt;/li&gt;
&lt;li&gt;Handle harsh industrial environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[4-20mA Fuel Sensor] → [STM32L0 MCU] → [SIM7070 Modem] → [4G Network] → [ThingsBoard Dashboard]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Hardware Components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MCU: STM32L0 &lt;/li&gt;
&lt;li&gt;Cellular: SIM7070 NB-IoT/LTE-M modem&lt;/li&gt;
&lt;li&gt;Power: 2× ER34615H lithium batteries (19,000mAh each)&lt;/li&gt;
&lt;li&gt;Sensor: 4-20mA diesel fuel tank level sensor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Power Consumption Breakdown
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. The system operates in three distinct stages:&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 1: Modem Initialization (60 seconds)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Average Current: 17.71mA&lt;/li&gt;
&lt;li&gt;Peak Current: 840mA (during network registration)&lt;/li&gt;
&lt;li&gt;Energy: 3.93 J&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the power-hungry phase. The SIM7070 needs to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Power up the RF circuitry&lt;/li&gt;
&lt;li&gt;Search for cellular networks&lt;/li&gt;
&lt;li&gt;Register with the tower&lt;/li&gt;
&lt;li&gt;Establish GPRS/LTE connection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Key Design Decision:&lt;/strong&gt; A 1000µF tantalum capacitor placed near the modem acts as a local energy reservoir, smoothing out the 30-40ms current spikes that can exceed 300mA.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 2: Sensor Read + Data Transmission (7.5 seconds)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Average Current: 11.24mA&lt;/li&gt;
&lt;li&gt;Energy: 0.31 J&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During this phase:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read 4-20mA sensor (fuel level)&lt;/li&gt;
&lt;li&gt;Read battery voltage&lt;/li&gt;
&lt;li&gt;Publish telemetry to ThingsBoard via MQTT&lt;/li&gt;
&lt;li&gt;Disable all peripherals&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Stage 3: Deep Sleep (15 minutes)
&lt;/h3&gt;

&lt;p&gt;Average Current: 1.05µA&lt;br&gt;
Energy: 0.0035 J&lt;/p&gt;

&lt;p&gt;This is where the magic happens. The STM32L0 enters shutdown mode:&lt;/p&gt;

&lt;p&gt;All peripherals powered down&lt;br&gt;
Only RTC remains active&lt;br&gt;
Occasional 2-3mA spikes for RTC maintenance (negligible impact)&lt;/p&gt;

&lt;p&gt;The Math Behind Battery Life&lt;/p&gt;

&lt;p&gt;With 38,000mAh capacity, here's the battery life estimation:&lt;/p&gt;

&lt;p&gt;Average Current Formula:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;I_avg = (I_sleep × T_sleep + I_active × T_active) / (T_sleep + T_active)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs5npbuk530q40cx5jbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjs5npbuk530q40cx5jbv.png" alt="Current Usage Data EC-M12-BC-C6-C-A" width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 4× increase in sleep time gives you a 3.4× improvement in battery life. This demonstrates the power of duty cycling in embedded systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  Software Implementation Highlights
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Low-Power Mode Configuration
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// STM32L0 shutdown mode configuration
#include &amp;lt;STM32LowPower.h&amp;gt;
void setup() {
  Serial.begin(9600);
  LowPower.begin();                   //Initiate low power mode
}
void loop() {
  Serial.println("Entering low power mode...");

  SPI.end();
  delay(1000);
  Wire2.end();
  delay(1000);


  digitalWrite(BOOST_EN, LOW);
  delay(1000);

  // === Fully cut power to GSM ===
  digitalWrite(GSM_POWER, HIGH);  // Depending on your wiring,   HIGH disables modem regulator
  delay(2000);

LowPower.shutdown(900000);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Efficient MQTT Publishing
&lt;/h3&gt;

&lt;p&gt;The system uses MQTT over LTE for minimal protocol overhead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void publishTelemetry() {
 int16_t adc0, adc1, adc2, adc3;

  adc1 = ads1.readADC_SingleEnded(1) * mA_Factor;
  adc2 = ads1.readADC_SingleEnded(2);


  float voltage2 = adc2 * 0.125 / 1000.0 / VOLTAGE_DIVIDER_RATIO;

  Serial.print("AIN1: "); Serial.print(adc0); Serial.println("  ");
  Serial.print("AIN2: "); Serial.print(adc1); Serial.println("  ");
  Serial.print("Voltage: "); Serial.print(voltage2); Serial.println("  ");


  float fuel_percent = (adc1 - 4.0) * 100.0 / 16.0;
  fuel_percent = constrain(fuel_percent, 0, 100);

  // Fuel height
  float fuel_level_mm = (fuel_percent / 100.0) * 1000;

  // Fault detection
  bool fuel_sensor_fault = false;
  if (adc1 &amp;lt; 3.6 || adc1 &amp;gt; 22.0) {
    fuel_sensor_fault = true;
  }

  StaticJsonDocument&amp;lt;200&amp;gt; doc;
  doc["fuel_level_percent"] = fuel_percent;
  doc["fuel_level_mm"]      = fuel_level_mm;
  doc["battery_voltage"]    = voltage2;
  doc["fuel_sensor_fault"]  = fuel_sensor_fault;

  String jsonStr;
  serializeJson(doc, jsonStr);

  mqtt.publish("v1/devices/me/telemetry", jsonStr.c_str());
  Serial.print("Published: ");
  Serial.println(jsonStr);

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sensor Fault Detection
&lt;/h3&gt;

&lt;p&gt;The system monitors for open/short circuits in the 4-20mA loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;lt; 3.8mA: Sensor fault (open circuit)&lt;/li&gt;
&lt;li&gt;&amp;gt; 20.5mA: Sensor fault (short circuit)&lt;/li&gt;
&lt;li&gt;4-20mA: Normal operation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Considerations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cellular Signal Strength&lt;br&gt;
Poor signal = higher power consumption. The modem will retry connections and transmit at higher power levels, significantly reducing battery life.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sensor Current Impact&lt;br&gt;
The 4-20mA sensor itself consumes power proportional to the measured value. A full tank (20mA) drains more power than an empty tank (4mA).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Temperature Effects&lt;br&gt;
Lithium batteries lose capacity in extreme cold. Consider temperature-compensated battery life calculations for outdoor installations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network Protocol Choice&lt;br&gt;
NB-IoT and LTE-M are specifically designed for IoT applications with lower power consumption than standard LTE. Choose wisely based on your region's network availability.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Duty cycling is king: The difference between 15-minute and 1-hour intervals is massive (3.36 vs 11.4 years).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modem initialization dominates: Even though it's only 1 minute per cycle, it consumes 85% of the total energy per transmission.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hardware matters: The STM32L0's 1.05µA shutdown current makes multi-year operation possible. A standard MCU would drain batteries in months.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Future Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Implement adaptive transmission intervals based on fuel level change rate&lt;/li&gt;
&lt;li&gt;Implement predictive maintenance alerts based on battery voltage trends&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building ultra-low-power IoT devices requires careful consideration of every milliamp-hour. By combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient duty cycling&lt;/li&gt;
&lt;li&gt;Ultra-low-power MCU sleep modes&lt;/li&gt;
&lt;li&gt;Optimized cellular communication&lt;/li&gt;
&lt;li&gt;Smart peripheral management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We achieved a system that can monitor remote industrial assets for over 3 years on battery power alone, with the potential to extend that to 11+ years with less frequent updates.&lt;/p&gt;

&lt;p&gt;The complete source code and detailed setup instructions are available on &lt;a href="https://github.com/IndustrialArduino/EC-M12-BC-C6-C-A" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check the product (EC-M12-BC-C6-C-A) &lt;a href="https://norvi.io/docs/ec-m12-bc-c6-c-a-datasheet/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>automation</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Introducing the NORVI M12-B: 5+ Years of Maintenance-Free Utility Telemetry</title>
      <dc:creator>Bhanuka Gamachchige</dc:creator>
      <pubDate>Thu, 18 Dec 2025 03:24:15 +0000</pubDate>
      <link>https://dev.to/norvi_controllers/introducing-the-norvi-m12-b-5-years-of-maintenance-free-utility-telemetry-5g88</link>
      <guid>https://dev.to/norvi_controllers/introducing-the-norvi-m12-b-5-years-of-maintenance-free-utility-telemetry-5g88</guid>
      <description>&lt;p&gt;NORVI is proud to announce the launch of the M12-B series battery-powered NB-IoT data logger, a breakthrough in remote utility monitoring. Designed for water, gas, and other utility applications, this device combines long-lasting battery life, rugged design, and reliable connectivity, offering a truly maintenance-free solution for developers and operators.&lt;/p&gt;

&lt;h2&gt;
  
  
  Long-Life Battery: Over 5 Years of Continuous Operation
&lt;/h2&gt;

&lt;p&gt;At the heart of the NORVI M12-B is a high-capacity, energy-optimized battery designed to power the device for more than five years without any maintenance. This means utilities and industrial operators can deploy telemetry devices in remote or hard-to-reach locations without worrying about frequent battery replacements. Developers can explore the life estimation to see real-world battery performance data and plan deployments with confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Power Consumption Analysis: How NORVI Achieves Multi-Year Operation
&lt;/h2&gt;

&lt;p&gt;The long battery life of the M12-B is made possible by careful power optimization across two main stages:&lt;/p&gt;

&lt;h3&gt;
  
  
  Modem Initializing and Data Sending Stage
&lt;/h3&gt;

&lt;p&gt;During the active phase, the device performs critical operations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initializing the NB-IoT modem&lt;/li&gt;
&lt;li&gt;Connecting to the network&lt;/li&gt;
&lt;li&gt;Reading the DJLK ultrasonic level sensor via RS-485&lt;/li&gt;
&lt;li&gt;Transmitting data packets to the ThingsBoard cloud over MQTT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On average, the system draws 31.78 mA for about 70 seconds. The SIM7070 LTE modem generates high-current spikes up to 0.56 A, which are handled by two lithium batteries connected in parallel.&lt;/p&gt;

&lt;p&gt;A 1000 µF tantalum capacitor placed near the modem acts as a local energy reservoir, supplying instantaneous surge current, while the batteries maintain the average load.&lt;/p&gt;

&lt;p&gt;According to the ER34615H(D) lithium battery datasheet, each cell can safely deliver 300 mA pulses for 100 milliseconds every 2 minutes. Observed modem pulses (30–40 milliseconds) stay within this safe operating range, ensuring reliable initialization without battery stress.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2n0a6vq9xfpgdwzrzhy.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2n0a6vq9xfpgdwzrzhy.PNG" alt="Modem Initializing and Data Sending Stage" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  MCU Sleep Mode (Shutdown Mode)
&lt;/h3&gt;

&lt;p&gt;After data transmission, the MCU enters shutdown mode, powering down most peripherals and system clocks. Only the Real-Time Clock (RTC) remains active to track time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F820m8eqk5lusvnnty27k.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F820m8eqk5lusvnnty27k.PNG" alt="MCU Sleep Mode" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this low-power state, the system draws approximately 1.22 µA for a duration of 15 minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1o9s454xqr8l23f4r6zn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1o9s454xqr8l23f4r6zn.PNG" alt="Power Consumption Table" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Battery Life Estimation
&lt;/h2&gt;

&lt;p&gt;EC-M12-BC-C6-C consists of two 19,000 mAh . So it has a total of 38,000 mAh battery power. As for the above collected data we have obtained battery life estimation when data is sent every 15 minutes and every 1 hour.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dy42n4klpbce9mf8w7t.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dy42n4klpbce9mf8w7t.PNG" alt="Battery Life Estimation Table" width="800" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below shows the formula to calculate average current and battery life for different intervals which help you to estimate the battery life for your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa20yvln24leohujhze9c.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa20yvln24leohujhze9c.PNG" alt="Battery Life Estimation Calculation Formular" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overall System Power Profile
&lt;/h2&gt;

&lt;p&gt;The average current flow across the full duty cycle is about 2.39 mA, with a charge consumption of 2.24 C, supporting multi-year operation on battery without maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliable NB-IoT Connectivity
&lt;/h2&gt;

&lt;p&gt;The M12-B leverages NB-IoT Cat NB1/NB2 connectivity, providing stable and secure data transmission even in challenging environments. Its deep coverage ensures that basements, underground meters, and remote infrastructure remain connected, while its low-power design ensures long-term operational efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rugged and Flexible Design
&lt;/h2&gt;

&lt;p&gt;Built for demanding utility environments, the NORVI M12-B is IP67-rated, fully protected against dust and water. It supports a wide range of sensors, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flow meters and pressure sensors&lt;/li&gt;
&lt;li&gt;Pulse counters&lt;/li&gt;
&lt;li&gt;Analog voltage/current inputs&lt;/li&gt;
&lt;li&gt;RS-485 Modbus RTU devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This flexibility allows developers to integrate the device with existing infrastructure or design custom telemetry solutions with ease.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maintenance-Free Deployment
&lt;/h2&gt;

&lt;p&gt;The combination of long-life battery, rugged housing, and NB-IoT connectivity enables true maintenance-free deployments. Once installed, the M12-B operates autonomously for 5+ years, transmitting real-time data without the need for field intervention. This drastically reduces operational costs and human resources, making it ideal for large-scale utility networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom IoT Solutions and White-Labeling
&lt;/h2&gt;

&lt;p&gt;Looking to bring your own IoT product to market? NORVI offers end-to-end &lt;a href="https://norvi.io/iot-custom-product-development-industry-automation-solutions/" rel="noopener noreferrer"&gt;custom IoT product development&lt;/a&gt;, from hardware design to cloud integration. Whether it’s a smart water meter, gas monitoring solution, or industrial controller, our team can turn your ideas into reliable, ready-to-market products with NB-IoT, LoRaWAN, or Wi-Fi connectivity.&lt;/p&gt;

&lt;p&gt;Need a white-label solution? NORVI’s offerings let you launch branded IoT devices quickly, while we handle engineering, design, and manufacturing. Focus on your business, while we provide proven, maintenance-free devices optimized for long-term performance.&lt;/p&gt;

&lt;p&gt;Accelerate your projects further with rapid prototyping, flexible sensor interfaces, and developer-friendly platforms, ensuring seamless integration and faster time-to-market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The NORVI M12-B NB-IoT Data Logger sets a new standard for utility telemetry. With 5+ years of maintenance-free operation, rugged IP67 design, and optimized power consumption, it empowers developers and businesses to deploy scalable, reliable, and long-term monitoring solutions.&lt;/p&gt;

&lt;p&gt;Explore the life estimation for battery performance and plan your deployments with confidence. NORVI makes smart utility monitoring maintenance-free, developer-friendly, and ready for real-world applications.&lt;/p&gt;

</description>
      <category>news</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
